Compare commits

..

99 Commits

Author SHA1 Message Date
Mario Campos
7c73de0e3c Merge pull request #22059 from github/release-prep/2.26.0
Release preparation for version 2.26.0
2026-06-25 10:31:50 -05:00
github-actions[bot]
237c5639e2 Release preparation for version 2.26.0 2026-06-25 15:27:00 +00:00
Asger F
73ad826d44 Merge pull request #22016 from asgerf/commonast-rebased5
Unified/swift: new AST spec and Swift mappings
2026-06-25 16:59:29 +02:00
Michael B. Gale
cc83856c5e Merge pull request #22058 from github/codeql-cli-2.25.6
Mergeback #21947 into `main`
2026-06-25 15:57:19 +01:00
Geoffrey White
0fbab225ce Merge pull request #22056 from geoffw0/codequal
Rust: Remove some redundant imports / casts
2026-06-25 15:52:15 +01:00
Geoffrey White
ca09327384 Rust: Remove more pointless imports. 2026-06-25 14:51:13 +01:00
Jeroen Ketema
969ab78225 Merge pull request #22048 from github/jketema/kotlin1-pytest
Kotlin: Update tests to use new `kotlin_2_3_20` fixture
2026-06-25 15:01:33 +02:00
Paolo Tranquilli
b67644c127 Merge pull request #21986 from JarLob/userpermissions
Actions: Fix dominates() false positive in reusable workflows
2026-06-25 14:44:17 +02:00
Geoffrey White
20b4cbe72e Rust: Remove pointless imports of codeql.util.Unit. 2026-06-25 12:51:43 +01:00
Tom Hvitved
b582844f96 Merge pull request #22049 from hvitved/csharp/dead-store-cleanup
C#: Remove redundant code from `DeadStoreOfLocal.ql`
2026-06-25 13:51:21 +02:00
Geoffrey White
b9a132dac6 Rust: Remove redundant cast. 2026-06-25 12:51:18 +01:00
Asger F
89cd6770ae Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-25 13:18:27 +02:00
Jeroen Ketema
9b2e6077f1 Kotlin: Address review comments 2026-06-25 12:58:27 +02:00
Tom Hvitved
929fa1e977 C#: Remove redundant code from DeadStoreOfLocal.ql 2026-06-25 08:50:40 +02:00
Mario Campos
3324d07985 Merge pull request #22046 from github/mario-campos/mirror-maven-central/maven
Use Maven Central mirror in Java Maven integration tests
2026-06-24 16:42:29 -05:00
Jeroen Ketema
f6b3d1eade Kotlin: Remove unneeded pytest imports 2026-06-24 23:34:39 +02:00
Jeroen Ketema
402c0f89bc Kotlin: Update tests to use new kotlin_2_3_20 fixture 2026-06-24 22:50:32 +02:00
Mario Campos
af11f6e618 Use Maven Central mirror in Java Maven integration tests 2026-06-24 17:45:27 +00:00
Jaroslav Lobačevski
7fc4b4856e Fix formatting 2026-06-24 17:17:16 +00:00
Paolo Tranquilli
4b8cb3ffac Fix false negative for branching nested reusable workflows
The previous fix required all outermost callers of a reusable workflow to
be protected, which collapsed distinct safe/unsafe inner paths that share
the same outermost caller. Track protection per caller chain instead: a
node inside a reusable workflow is only considered protected if there is
no unprotected caller path up to an outer workflow.

Adds a branching nested regression test where one inner job is protected
by a permission check and a sibling inner job is not.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-24 18:22:01 +02:00
Jeroen Ketema
b8c78fdcb7 Merge pull request #21970 from github/andersfugmann/kotlin-2.4-v2
Kotlin: add Kotlin 2.4.0 support
2026-06-24 16:40:40 +02:00
Anders Schack-Mulligen
bcf71d0db6 Merge pull request #22043 from github/copilot/tweak-ruby-ast-caseexpr
Ruby: synthesize implicit `true` value for valueless `CaseExpr`
2026-06-24 15:43:04 +02:00
Anders Schack-Mulligen
5047bee432 Ruby: Adjust qldoc. 2026-06-24 13:36:54 +02:00
Anders Schack-Mulligen
29eba2f38e Merge pull request #22017 from aschackmull/cfg/catchclause-pattern
Cfg: Change AST/CFG for CatchClauses to use a pattern.
2026-06-24 13:21:54 +02:00
copilot-swe-agent[bot]
4fa8a9fb1d Synthesize true value for valueless Ruby CaseExpr 2026-06-24 10:36:23 +00:00
Michael Nebel
a24d222d96 Merge pull request #22011 from michaelnebel/csharp/removeafallback
C#: Re-factor feed handling logic into its own component.
2026-06-24 11:58:56 +02:00
Anders Schack-Mulligen
bcfee987f0 Apply suggestion from @aschackmull 2026-06-24 10:26:26 +02:00
Anders Schack-Mulligen
e1d4fe8605 C#: Accept test changes. 2026-06-23 14:42:20 +02:00
Anders Schack-Mulligen
11725e8921 Java: Accept test changes. 2026-06-23 14:28:44 +02:00
Anders Schack-Mulligen
41297c588c Cfg: Change AST/CFG for CatchClauses to use a pattern. 2026-06-23 14:28:44 +02:00
yoff
53cae687f7 Merge pull request #21931 from github/yoff/python-shared-cfg-loop-else
Shared CFG: add defaulted getWhileElse/getForeachElse to AstSig
2026-06-23 14:25:16 +02:00
Anders Schack-Mulligen
cfbf4a3927 Merge pull request #22037 from github/copilot/update-csharp-extractor-catch-clause
C# extractor: extract `catch(ExceptionType)` type as `TypeAccess` instead of `TypeMention`
2026-06-23 14:21:43 +02:00
Jaroslav Lobačevski
31f6e713c5 Fix "The variable event is only used in one side of disjunct." 2026-06-23 12:06:01 +00:00
copilot-swe-agent[bot]
b254aa7e0b C#: Extract catch(Ex) type as TypeAccess instead of TypeMention 2026-06-23 13:55:39 +02:00
Jaroslav Lobačevski
e2347a5c7d Fix for independent checks 2026-06-23 11:52:11 +00:00
yoff
d26102b263 Merge pull request #21920 from github/yoff/python-flow-py-namespace
Python: qualify Flow.qll's AST references with Py:: prefix
2026-06-23 13:20:26 +02:00
yoff
73ab3e6888 Update shared/controlflow/codeql/controlflow/ControlFlowGraph.qll
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2026-06-23 12:41:02 +02:00
yoff
15cbbb82eb Shared CFG: add defaulted getLoopElse to AstSig
Adds a new defaulted signature predicates to the shared CFG library:

- getLoopElse: `else` block of a loop statement, if
  any (used by Python's `while-else` / `for-else` constructs).

The predicate defaults to `none()`, so behaviour is unchanged for any
language that doesn't override it (verified by re-running
java/ql/test/library-tests/controlflow/).

The Make0 succession rules are extended:
- WhileStmt/ForeachStmt: route the loop-exit edge through the else
  block before reaching the after-position.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 12:41:02 +02:00
yoff
7d95024487 Apply suggestions from code review
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-23 12:36:53 +02:00
Copilot
06fa46f664 Python: qualify Flow.qll's AST references with Py:: prefix
Preparatory refactor for the shared-CFG dataflow migration. Switches
'import python' to 'import python as Py' inside Flow.qll, and qualifies
every AST-class reference (Expr, Bytes, Dict, AssignExpr, Compare,
Module, Scope, Call, Attribute, SsaVariable, AugAssign, etc.) with the
Py:: prefix.

Flow.qll's own CFG types (ControlFlowNode, BasicBlock, CallNode,
NameNode, DefinitionNode, CompareNode, ...) keep their unqualified
names — they remain the public CFG API exported from this file.

This is a semantic noop: the qualification was applied mechanically by
script and no name resolution changes. Verified by:
- All 361 lib/ + src/ queries compile clean.
- All 186 ControlFlow + PointsTo + dataflow library-tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 12:36:53 +02:00
Geoffrey White
f6dce466a0 Merge pull request #22009 from geoffw0/rust-crypto
Rust: Additional test cases for rust/weak-sensitive-data-hashing
2026-06-23 10:53:45 +01:00
Jeroen Ketema
cd23341dab Merge branch 'main' into andersfugmann/kotlin-2.4-v2 2026-06-23 11:45:17 +02:00
Idriss Riouak
ec91865a7f Merge pull request #22030 from github/idrissrio/cpp/update-stats-file
C/C++: Update stats file
2026-06-23 10:26:52 +02:00
Owen Mansel-Chan
f0576046b1 Merge pull request #22027 from owen-mc/go/improve-tests
Go: Improve two tests
2026-06-22 17:19:40 +01:00
Geoffrey White
9e0e1bde28 Rust: Use Copilot suggested comment phrasing. 2026-06-22 16:12:54 +01:00
Geoffrey White
8c24acc99d Fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-22 16:10:57 +01:00
Michael Nebel
18f49ed1a2 C#: Fix spelling error. 2026-06-22 13:04:38 +02:00
Michael Nebel
5f31632445 C#: Move GetAllFeeds to the feed manager. 2026-06-22 12:45:53 +02:00
Michael Nebel
6a2a337ffe C#: Move the nuget.config diagnostics out of the GetAllFeeds method. 2026-06-22 11:03:40 +02:00
Michael Nebel
cf896f243f C#: Re-factor more the feed related methods into the FeedManager. 2026-06-22 11:03:38 +02:00
Michael Nebel
bae2d18446 C#: Refactor some of the feed logic into a separate class. 2026-06-22 11:03:35 +02:00
Michael Nebel
2fb5321a50 C#: NoOpPackageRestore only needs the PackageConfigs collection and not the entire FileProvider. 2026-06-22 11:03:33 +02:00
idrissrio
0a41157d77 C/C++: update stats file 2026-06-22 10:27:21 +02:00
Owen Mansel-Chan
07cf89568f Test CFG for function epilogue (read-result nodes and calls to defered functions) 2026-06-20 22:04:45 +01:00
Owen Mansel-Chan
42ebe56023 Make all lines in logging tests reachable 2026-06-20 22:04:43 +01:00
Anders Fugmann
0f83586757 Kotlin 2.4.0: Address peer review
* Update documentation to only claim support for 2.4.0x
* Python test code; remove newlines between imports.
* Sync comments between kotlin 1.8 and 1.9
* Update code comments to attach where actually relevant,
  and improve comments on IrMemberAccessExpression<*>.extensionReceiverParameterIndex()
2026-06-19 13:45:28 +02:00
Asger F
66c1f037f5 Add TODO 2026-06-19 12:19:51 +02:00
Asger F
2675070291 unified/swift: Clean up translation of patterns
Patterns have an unusual parse tree, but now the matching should
at least be a bit easier to follow.

The TODO regarding not being able to pass down context to handle
var/let is still relevant, and can't be solved in the mapping alone.
2026-06-19 11:35:06 +02:00
Asger F
c01264d05c Coerce pattern_element.key to be an identifier 2026-06-19 10:31:34 +02:00
Asger F
63e1cc90e9 Test: add corpus test for switch case patterns with labeled arguments
Adds a test case 'Switch with labeled case pattern arguments' covering:
- case .implicit(isAcknowledged: false) — labeled bool literal
- case .thread(threadRowId: _, let rowId) — labeled wildcard + binding

The current output contains type errors: pattern_element::key is being
produced as name_expr instead of identifier. These will be fixed in the
following commit.
2026-06-19 10:27:20 +02:00
Geoffrey White
721070a191 Rust: Make the Seed case a tiny bit more realistic. 2026-06-18 23:43:18 +01:00
Geoffrey White
b86cb6df63 Rust: Additional test cases for weak sensitive data hashing. 2026-06-18 23:32:38 +01:00
Geoffrey White
3aaeb68553 Rust: Make the new test inline expectations. 2026-06-18 22:57:15 +01:00
Geoffrey White
e8923b7688 Rust: Output cryptographic operations in the weak sensitive data hashing query test. 2026-06-18 17:07:28 +01:00
Asger F
2182265120 unified/swift: Better source range for inferred_type_expr 2026-06-18 14:57:55 +02:00
Asger F
0b666d47db Preserve the dot token in case patterns 2026-06-18 14:55:54 +02:00
Asger F
142ac47166 Refactor: map switch case patterns to constructor_pattern instead of tuple_pattern
Changed the desugaring rules to properly map case patterns with binding (e.g.,
'case .circle(let r):') to constructor_pattern nodes instead of tuple_pattern.

New rules added:
- tuple_pattern_item → pattern_element (preserves optional name/key)
- pattern.kind: binding_pattern → name_pattern (extracts bound identifier)
- pattern.kind: case_pattern → constructor_pattern (creates proper constructor
  with bound arguments as pattern_elements)

This provides a more semantically correct AST representation:
- Constructor name: name_expr identifier 'circle'
- Elements: pattern_element containing name_pattern identifier 'r'

Instead of the previous tuple_pattern string representation.

Updated control-flow.txt corpus outputs.
2026-06-18 14:54:59 +02:00
Asger F
2470c1388a Fix: preserve switch case patterns in desugared output
The switch_entry rule was capturing switch_pattern wrapper nodes instead of
drilling into them to extract the actual pattern nodes. This caused patterns
from switch cases to be lost during desugaring.

Changed the pattern match from:
  (switch_entry pattern: (switch_pattern)* @pats ...)
to:
  (switch_entry pattern: (switch_pattern pattern: @pats)* ...)

This now correctly extracts the pattern field from each switch_pattern node,
ensuring that patterns from cases like 'case 1:' and 'case .circle(let r):'
are preserved in the switch_case AST nodes.

Updated control-flow.txt corpus outputs to reflect the new behavior.
2026-06-18 14:37:42 +02:00
Asger F
fa98557dd9 Update QL test output 2026-06-18 14:26:49 +02:00
Asger F
1e167dfa6b unified/swift: add type and declaration-family mappings 2026-06-18 14:26:47 +02:00
Asger F
f362707493 unified/swift: Imports 2026-06-18 14:26:45 +02:00
Asger F
15208b70aa Unified: Add import_declaration.scoped_import_kind 2026-06-18 14:26:43 +02:00
Asger F
3522f35ab2 unified/swift: add collections, optionals/errors 2026-06-18 14:26:42 +02:00
Asger F
938396a751 unified/swift: add control-flow and loop mappings 2026-06-18 14:26:40 +02:00
Asger F
790d4f11be unified/swift: add closure and capture mappings 2026-06-18 14:26:38 +02:00
Asger F
8f747a355c unified/swift: add function and parameter mappings 2026-06-18 14:26:37 +02:00
Asger F
d17fd2d964 unified/swift: add variable/property/accessor and enum mappings 2026-06-18 14:26:35 +02:00
Asger F
4e9c3fb436 unified/swift: add literals, names, and operator expression mappings 2026-06-18 14:26:33 +02:00
Asger F
0e9d17b59c unified/swift: add top-level normalization and fallback scaffold 2026-06-18 14:26:31 +02:00
Asger F
6c74cd31e4 Yeast: use child locations instead of rule target
Previously, when a node was synthesized it would always take the
location from the node that matched the current rule. This resulted
in overly broad locations however.

For (foo #{bar}) we now take the location of the 'bar' node.

For non-leaf nodes we merge all its child node locations.
2026-06-18 14:26:30 +02:00
Asger F
166406acbb Unified: Elaborate a bit more on AGENTS.md 2026-06-18 14:26:28 +02:00
Asger F
b40cb5dedd Regenerate QL 2026-06-18 14:26:26 +02:00
Asger F
6dd7dedc19 Rewrite AST 2026-06-18 14:26:22 +02:00
Jaroslav Lobačevski
7f16853715 Remove trailing white space 2026-06-18 12:11:18 +00:00
Jaroslav Lobačevski
2d6feb1255 Fix false negatives when one of the jobs had proper checks and the other didn't 2026-06-18 12:02:56 +00:00
Anders Fugmann
1b785a8ff6 Kotlin: mark kotlin1 integration tests
Mark the integration tests that require a Kotlin 1.x language version
with @pytest.mark.kotlin1 so CI can run them on a pinned pre-2.4
compiler (Kotlin 2.4 no longer accepts -language-version 1.9).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-16 16:24:43 +02:00
Anders Fugmann
e10743bd08 Kotlin: add extractor support for 2.4.0
Add the Kotlin 2.4.0 compiler plugin variant (component registrar,
IR compatibility shims, and version-specific utilities), bundle the
2.4.0 compiler dependencies, and update the build wiring, supported
version metadata and the too-new diagnostic bound.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-16 16:24:42 +02:00
Asger F
1d8e682e5f Reset mappings 2026-06-15 10:49:37 +02:00
Asger F
0baa126473 Add ability to prepend fields in Yeast 2026-06-15 10:49:35 +02:00
Asger F
d11b428292 yeast-macros: desugar 'field: @cap' to 'field: _ @cap'
When a field pattern has a bare capture with no preceding pattern
atom (i.e. `foo: @bar`), implicitly use a true wildcard (`_`,
match_unnamed: true) as the node pattern, making it equivalent to
`foo: _ @bar`.

This is a convenience shorthand: in practice every `field: _ @cap`
in the Swift rules can now be written more concisely as `field: @cap`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-15 10:49:33 +02:00
Asger F
ddc9516e92 Yeast: better support for rewriting unnamed nodes
- Ensure the full wildcard _ supports quantifiers
- Also rewrite unnamed nodes in one-shot phases
2026-06-15 10:49:31 +02:00
Asger F
00068948c1 yeast-macros: add .reduce_left(first -> init, acc, elem -> fold) chain
A left fold over an iterable where the first element seeds the accumulator:
- first -> init  : converts the first element to the initial accumulator
- acc, elem -> fold : fold step; acc = current accumulator, elem = next element
- Empty iterable produces nothing (0-element splice)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-15 10:49:29 +02:00
Asger F
28c879f58c yeast-macros: add .map(p -> tpl) chain syntax for tree templates
After a {expr} or {..expr} placeholder, an optional chain of
.<builtin>() calls may follow. Currently the only builtin is:

  .map(param -> template)

which applies the template to each element of the iterable and
collects the resulting node IDs. A chain auto-splices into the
enclosing field/child position.

Example:
  path: {parts}.map(p -> (identifier #{p}))

The framework is extensible: additional builtins can be added by
matching on the method name in parse_chain_suffix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-15 10:49:27 +02:00
Jaroslav Lobačevski
d51a9a3e1a Support nested reusable workflows 2026-06-15 06:52:13 +00:00
Jaroslav Lobačevski
048884bb78 Remove redundant cast 2026-06-15 06:12:45 +00:00
Jaroslav Lobačevski
2eed6c1736 Fix dominates() false positive in reusable workflows 2026-06-15 05:42:59 +00:00
Jon Janego
2a8f295a65 Merge pull request #21947 from github/copilot/codeql-cli-2256
Fix changelog copy errors in change-notes and CHANGELOG.md files (codeql-cli-2.25.6)
2026-06-04 14:29:33 -05:00
copilot-swe-agent[bot]
b8501f1ec5 Fix changelog copy errors in change-notes and CHANGELOG.md files (codeql-cli-2.25.6) 2026-06-04 18:35:06 +00:00
copilot-swe-agent[bot]
3214253adb Initial plan 2026-06-04 18:29:50 +00:00
726 changed files with 19517 additions and 16882 deletions

View File

@@ -248,6 +248,7 @@ use_repo(
"kotlin-compiler-2.2.20-Beta2",
"kotlin-compiler-2.3.0",
"kotlin-compiler-2.3.20",
"kotlin-compiler-2.4.0",
"kotlin-compiler-embeddable-1.8.0",
"kotlin-compiler-embeddable-1.9.0-Beta",
"kotlin-compiler-embeddable-1.9.20-Beta",
@@ -259,6 +260,7 @@ use_repo(
"kotlin-compiler-embeddable-2.2.20-Beta2",
"kotlin-compiler-embeddable-2.3.0",
"kotlin-compiler-embeddable-2.3.20",
"kotlin-compiler-embeddable-2.4.0",
"kotlin-stdlib-1.8.0",
"kotlin-stdlib-1.9.0-Beta",
"kotlin-stdlib-1.9.20-Beta",
@@ -270,6 +272,7 @@ use_repo(
"kotlin-stdlib-2.2.20-Beta2",
"kotlin-stdlib-2.3.0",
"kotlin-stdlib-2.3.20",
"kotlin-stdlib-2.4.0",
)
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")

View File

@@ -1,3 +1,10 @@
## 0.4.38
### Bug Fixes
* GitHub Actions queries now better account for permission checks on jobs that call reusable workflows.
* The query `actions/pr-on-self-hosted-runner` was updated to the latest standard runner labels reducing false positive results.
## 0.4.37
### Minor Analysis Improvements

View File

@@ -1,4 +0,0 @@
---
category: fix
---
* The query `actions/pr-on-self-hosted-runner` was updated to the latest standard runner labels reducing false positive results.

View File

@@ -0,0 +1,6 @@
## 0.4.38
### Bug Fixes
* GitHub Actions queries now better account for permission checks on jobs that call reusable workflows.
* The query `actions/pr-on-self-hosted-runner` was updated to the latest standard runner labels reducing false positive results.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.37
lastReleaseVersion: 0.4.38

View File

@@ -42,6 +42,15 @@ string actor_not_attacker_event() {
]
}
/**
* Gets the outer caller of `ej`, i.e. the `ExternalJob` that calls the
* reusable workflow containing `ej`. Used with transitive closure to
* walk up nested reusable workflow chains.
*/
private ExternalJob getAnOuterCaller(ExternalJob ej) {
result = ej.getEnclosingWorkflow().(ReusableWorkflow).getACaller()
}
/** An If node that contains an actor, user or label check */
abstract class ControlCheck extends AstNode {
ControlCheck() {
@@ -53,43 +62,170 @@ abstract class ControlCheck extends AstNode {
predicate protects(AstNode node, Event event, string category) {
// The check dominates the step it should protect
this.dominates(node) and
this.dominates(node, event) and
// The check is effective against the event and category
this.protectsCategoryAndEvent(category, event.getName()) and
// The check can be triggered by the event
this.getATriggerEvent() = event
this.getATriggerEvent() = event and
// For reusable workflows, there must be no unprotected caller chain for this event.
(
not node.getEnclosingWorkflow() instanceof ReusableWorkflow
or
this.dominatesSameWorkflow(node, event)
or
not exists(ExternalJob directCaller |
directCaller = node.getEnclosingWorkflow().(ReusableWorkflow).getACaller() and
unprotectedCallerChain(directCaller, event, category)
)
)
}
predicate dominates(AstNode node) {
/**
* Holds if this control check must execute and pass before `node` can run.
*/
predicate dominates(AstNode node, Event event) {
this.dominatesSameWorkflow(node, event)
or
// When the node is inside a reusable workflow,
// this check dominates via at least one caller chain.
this.dominatesViaCaller(node, event, _)
}
/**
* Holds if this control check dominates `node` within the same workflow.
*/
predicate dominatesSameWorkflow(AstNode node, Event event) {
this.getATriggerEvent() = event and
(
// Step-level: the check is an `if:` on the step containing `node`,
// or on the enclosing job, or on a needed job/step.
this instanceof If and
(
node.getEnclosingStep().getIf() = this or
node.getEnclosingJob().getIf() = this or
node.getEnclosingJob().getANeededJob().(LocalJob).getAStep().getIf() = this or
node.getEnclosingJob().getANeededJob().(LocalJob).getIf() = this
)
or
// Job-level: the check is an environment on the enclosing job or a needed job.
this instanceof Environment and
(
node.getEnclosingJob().getEnvironment() = this
or
node.getEnclosingJob().getANeededJob().getEnvironment() = this
)
or
// Step-level: the check is a Run/UsesStep that precedes `node`'s step
// in the same job, or is a step in a needed job.
(
this instanceof Run or
this instanceof UsesStep
) and
(
this.(Step).getAFollowingStep() = node.getEnclosingStep()
or
node.getEnclosingJob().getANeededJob().(LocalJob).getAStep() = this
)
)
}
/**
* Holds if this control check dominates `node` in a reusable workflow
* via the caller chain starting at `directCaller`.
*/
predicate dominatesViaCaller(AstNode node, Event event, ExternalJob directCaller) {
directCaller = node.getEnclosingWorkflow().(ReusableWorkflow).getACaller() and
directCaller.getATriggerEvent() = event and
exists(ExternalJob caller |
caller = getAnOuterCaller*(directCaller) and
this.dominatesCaller(caller)
)
}
/**
* Holds if this control check directly dominates `caller`.
*/
predicate dominatesCaller(ExternalJob caller) {
this instanceof If and
(
node.getEnclosingStep().getIf() = this or
node.getEnclosingJob().getIf() = this or
node.getEnclosingJob().getANeededJob().(LocalJob).getAStep().getIf() = this or
node.getEnclosingJob().getANeededJob().(LocalJob).getIf() = this
caller.getIf() = this or
caller.getANeededJob().(LocalJob).getIf() = this or
caller.getANeededJob().(LocalJob).getAStep().getIf() = this
)
or
this instanceof Environment and
(
node.getEnclosingJob().getEnvironment() = this
or
node.getEnclosingJob().getANeededJob().getEnvironment() = this
caller.getEnvironment() = this or
caller.getANeededJob().getEnvironment() = this
)
or
(
this instanceof Run or
this instanceof UsesStep
) and
(
this.(Step).getAFollowingStep() = node.getEnclosingStep()
or
node.getEnclosingJob().getANeededJob().(LocalJob).getAStep() = this.(Step)
)
(this instanceof Run or this instanceof UsesStep) and
caller.getANeededJob().(LocalJob).getAStep() = this
}
abstract predicate protectsCategoryAndEvent(string category, string event);
}
/**
* Holds if this control check directly protects `caller`.
*/
bindingset[caller, event, category]
private predicate protectedCaller(ExternalJob caller, Event event, string category) {
exists(ControlCheck check |
check.protectsCategoryAndEvent(category, event.getName()) and
check.getATriggerEvent() = event and
check.dominatesCaller(caller)
)
}
cached
private newtype TCallerState =
MkCallerState(ExternalJob caller, Event event, string category) {
caller.getATriggerEvent() = event and
category = any_category()
}
private class CallerState extends TCallerState, MkCallerState {
ExternalJob caller;
Event event;
string category;
CallerState() { this = MkCallerState(caller, event, category) }
ExternalJob getCaller() { result = caller }
Event getEvent() { result = event }
string getCategory() { result = category }
/**
* Gets an outer caller state if this caller is not protected.
*/
CallerState getUnprotectedOuterState() {
not protectedCaller(this.getCaller(), this.getEvent(), this.getCategory()) and
result = MkCallerState(getAnOuterCaller(this.getCaller()), this.getEvent(), this.getCategory())
}
predicate isUnprotectedOutermost() {
not protectedCaller(this.getCaller(), this.getEvent(), this.getCategory()) and
not exists(getAnOuterCaller(this.getCaller()))
}
string toString() { result = caller + " / " + event + " / " + category }
}
/**
* Holds if there is a caller path from `caller` to an outer workflow that has no protection.
*/
bindingset[caller, event, category]
private predicate unprotectedCallerChain(ExternalJob caller, Event event, string category) {
exists(CallerState start, CallerState outermost |
start = MkCallerState(caller, event, category) and
outermost = start.getUnprotectedOuterState*() and
outermost.isUnprotectedOutermost()
)
}
abstract class AssociationCheck extends ControlCheck {
// Checks if the actor is a MEMBER/OWNER the repo
// - they are effective against pull requests and workflow_run (since these are triggered by pull_requests) since they can control who is making the PR

View File

@@ -1,5 +1,5 @@
name: codeql/actions-all
version: 0.4.38-dev
version: 0.4.38
library: true
warnOnImplicitThis: true
dependencies:

View File

@@ -1,3 +1,9 @@
## 0.6.30
### Query Metadata Changes
* The name, description, and alert message of `actions/untrusted-checkout/medium` have been corrected to describe a non-privileged context.
## 0.6.29
### Query Metadata Changes

View File

@@ -18,7 +18,7 @@ from LocalJob job, LabelCheck check, MutableRefCheckoutStep checkout, Event even
where
job.isPrivileged() and
job.getAStep() = checkout and
check.dominates(checkout) and
check.dominates(checkout, event) and
(
job.getATriggerEvent() = event and
event.getName() = "pull_request_target" and

View File

@@ -34,8 +34,8 @@ where
check instanceof AssociationCheck or
check instanceof PermissionCheck
) and
check.dominates(checkout) and
date_check.dominates(checkout)
check.dominates(checkout, event) and
date_check.dominates(checkout, event)
)
or
// not issue_comment triggered workflows

View File

@@ -1,4 +1,5 @@
---
category: queryMetadata
---
## 0.6.30
### Query Metadata Changes
* The name, description, and alert message of `actions/untrusted-checkout/medium` have been corrected to describe a non-privileged context.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.6.29
lastReleaseVersion: 0.6.30

View File

@@ -1,5 +1,5 @@
name: codeql/actions-queries
version: 0.6.30-dev
version: 0.6.30
library: false
warnOnImplicitThis: true
groups: [actions, queries]

View File

@@ -0,0 +1,17 @@
on:
workflow_call:
inputs:
COMMIT_SHA:
type: string
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
ref: ${{ inputs.COMMIT_SHA }}
- run: |
npm install
npm run lint

View File

@@ -0,0 +1,13 @@
on:
workflow_call:
inputs:
COMMIT_SHA:
type: string
jobs:
build:
uses: TestOrg/TestRepo/.github/workflows/build.yml@main
with:
COMMIT_SHA: ${{ inputs.COMMIT_SHA }}

View File

@@ -0,0 +1,33 @@
on:
workflow_call:
inputs:
COMMIT_SHA:
type: string
jobs:
is-collaborator:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
build_safe:
needs: is-collaborator
uses: TestOrg/TestRepo/.github/workflows/build_nested.yml@main
with:
COMMIT_SHA: ${{ inputs.COMMIT_SHA }}
build_unsafe:
uses: TestOrg/TestRepo/.github/workflows/build_nested.yml@main
with:
COMMIT_SHA: ${{ inputs.COMMIT_SHA }}

View File

@@ -0,0 +1,31 @@
on:
pull_request_target:
jobs:
is-collaborator:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
build:
runs-on: ubuntu-latest
#needs: is-collaborator Mistake, doesn't wait for the collaborator - no security check
steps:
- name: Checkout repo
uses: actions/checkout@4
with:
ref: ${{ github.event.pull_request.head.sha }} # should alert
fetch-depth: 2
- run: yarn test

View File

@@ -0,0 +1,26 @@
on:
pull_request_target:
jobs:
is-collaborator:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
build:
needs: is-collaborator
uses: TestOrg/TestRepo/.github/workflows/build.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }} # shouldn't alert since permission check

View File

@@ -0,0 +1,31 @@
on:
pull_request_target:
jobs:
is-collaborator:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
build_unsafe:
# needs: is-collaborator
uses: TestOrg/TestRepo/.github/workflows/build.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }} # should alert since no permission check
build_safe:
needs: is-collaborator
uses: TestOrg/TestRepo/.github/workflows/build.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }} # shouldn't alert since permission check

View File

@@ -0,0 +1,8 @@
on:
pull_request_target:
jobs:
build:
uses: TestOrg/TestRepo/.github/workflows/build_nested_branching.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }}

View File

@@ -0,0 +1,26 @@
on:
pull_request_target:
jobs:
is-collaborator:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
build:
needs: is-collaborator
uses: TestOrg/TestRepo/.github/workflows/build_nested.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }} # shouldn't alert since permission check

View File

@@ -0,0 +1,26 @@
on:
pull_request_target:
jobs:
is-collaborator:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
build:
# needs: is-collaborator
uses: TestOrg/TestRepo/.github/workflows/build_nested.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }}

View File

@@ -0,0 +1,41 @@
on:
pull_request_target:
jobs:
is-collaborator:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
build:
runs-on: ubuntu-latest
needs: is-collaborator
steps:
- name: Checkout repo
uses: actions/checkout@4
with:
ref: ${{ github.event.pull_request.head.sha }} # shouldn't alert since permission check
fetch-depth: 2
- run: yarn test
build_unsafe:
runs-on: ubuntu-latest
# needs: is-collaborator
steps:
- name: Checkout repo
uses: actions/checkout@4
with:
ref: ${{ github.event.pull_request.head.sha }} # should alert since no permission check
fetch-depth: 2
- run: yarn test

View File

@@ -0,0 +1,48 @@
on:
pull_request_target:
jobs:
is-collaborator-a:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
caller-a:
needs: is-collaborator-a
uses: TestOrg/TestRepo/.github/workflows/build.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
is-collaborator-b:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
caller-b:
needs: is-collaborator-b
uses: TestOrg/TestRepo/.github/workflows/build.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }}

View File

@@ -93,6 +93,8 @@ edges
| .github/workflows/dependabot3.yml:15:9:20:6 | Uses Step | .github/workflows/dependabot3.yml:20:9:25:6 | Uses Step |
| .github/workflows/dependabot3.yml:20:9:25:6 | Uses Step | .github/workflows/dependabot3.yml:25:9:48:6 | Run Step: set-milestone |
| .github/workflows/dependabot3.yml:25:9:48:6 | Run Step: set-milestone | .github/workflows/dependabot3.yml:48:9:52:57 | Run Step |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:14:9:17:7 | Run Step |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/build_nested_branching.yml:11:9:19:6 | Uses Step: checkAccess | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build_nested_branching.yml:19:9:25:2 | Run Step |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/formal.yml:14:9:19:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/formal.yml:19:9:25:6 | Run Step |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/formal.yml:19:9:25:6 | Run Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/formal.yml:25:9:70:20 | Run Step |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:23:9:26:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:26:9:29:7 | Run Step |
@@ -334,6 +336,17 @@ edges
| .github/workflows/untrusted_checkout_6.yml:11:9:14:6 | Uses Step | .github/workflows/untrusted_checkout_6.yml:14:9:17:6 | Uses Step |
| .github/workflows/untrusted_checkout_6.yml:14:9:17:6 | Uses Step | .github/workflows/untrusted_checkout_6.yml:17:9:21:6 | Uses Step |
| .github/workflows/untrusted_checkout_6.yml:17:9:21:6 | Uses Step | .github/workflows/untrusted_checkout_6.yml:21:9:23:23 | Run Step |
| .github/workflows/untrusted_checkout_no_needs.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_no_needs.yml:16:9:22:2 | Run Step |
| .github/workflows/untrusted_checkout_no_needs.yml:26:9:31:6 | Uses Step | .github/workflows/untrusted_checkout_no_needs.yml:31:9:31:23 | Run Step |
| .github/workflows/untrusted_checkout_permission_check_reusable2.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permission_check_reusable2.yml:16:9:22:2 | Run Step |
| .github/workflows/untrusted_checkout_permission_check_reusable.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permission_check_reusable.yml:16:9:22:2 | Run Step |
| .github/workflows/untrusted_checkout_permission_check_reusable_level2.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permission_check_reusable_level2.yml:16:9:22:2 | Run Step |
| .github/workflows/untrusted_checkout_permission_check_reusable_no_needs.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permission_check_reusable_no_needs.yml:16:9:22:2 | Run Step |
| .github/workflows/untrusted_checkout_permissions_check.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permissions_check.yml:16:9:22:2 | Run Step |
| .github/workflows/untrusted_checkout_permissions_check.yml:26:9:31:6 | Uses Step | .github/workflows/untrusted_checkout_permissions_check.yml:31:9:32:2 | Run Step |
| .github/workflows/untrusted_checkout_permissions_check.yml:36:9:41:6 | Uses Step | .github/workflows/untrusted_checkout_permissions_check.yml:41:9:41:22 | Run Step |
| .github/workflows/untrusted_checkout_two_callers_both_protected.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_two_callers_both_protected.yml:16:9:22:2 | Run Step |
| .github/workflows/untrusted_checkout_two_callers_both_protected.yml:30:9:38:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_two_callers_both_protected.yml:38:9:44:2 | Run Step |
| .github/workflows/workflow_run_untrusted_checkout.yml:13:9:16:6 | Uses Step | .github/workflows/workflow_run_untrusted_checkout.yml:16:9:18:31 | Uses Step |
| .github/workflows/workflow_run_untrusted_checkout_2.yml:13:9:16:6 | Uses Step | .github/workflows/workflow_run_untrusted_checkout_2.yml:16:9:18:31 | Uses Step |
| .github/workflows/workflow_run_untrusted_checkout_3.yml:13:9:16:6 | Uses Step | .github/workflows/workflow_run_untrusted_checkout_3.yml:16:9:18:31 | Uses Step |
@@ -344,6 +357,9 @@ edges
| .github/workflows/auto_ci.yml:67:9:74:6 | Uses Step | .github/workflows/auto_ci.yml:67:9:74:6 | Uses Step | .github/workflows/auto_ci.yml:79:9:84:6 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/auto_ci.yml:6:3:6:21 | pull_request_target | pull_request_target |
| .github/workflows/auto_ci.yml:67:9:74:6 | Uses Step | .github/workflows/auto_ci.yml:67:9:74:6 | Uses Step | .github/workflows/auto_ci.yml:84:9:93:6 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/auto_ci.yml:6:3:6:21 | pull_request_target | pull_request_target |
| .github/workflows/dependabot3.yml:15:9:20:6 | Uses Step | .github/workflows/dependabot3.yml:15:9:20:6 | Uses Step | .github/workflows/dependabot3.yml:25:9:48:6 | Run Step: set-milestone | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/dependabot3.yml:3:5:3:23 | pull_request_target | pull_request_target |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:14:9:17:7 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout_permission_check_reusable2.yml:2:3:2:21 | pull_request_target | pull_request_target |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:14:9:17:7 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout_permission_check_reusable_branching_nested.yml:2:3:2:21 | pull_request_target | pull_request_target |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:14:9:17:7 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout_permission_check_reusable_no_needs.yml:2:3:2:21 | pull_request_target | pull_request_target |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:23:9:26:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:23:9:26:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:26:9:29:7 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/reusable_caller1.yaml:4:3:4:21 | pull_request_target | pull_request_target |
| .github/workflows/gitcheckout.yml:10:11:18:8 | Run Step | .github/workflows/gitcheckout.yml:10:11:18:8 | Run Step | .github/workflows/gitcheckout.yml:21:11:23:22 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/gitcheckout.yml:2:3:2:21 | pull_request_target | pull_request_target |
| .github/workflows/label_trusted_checkout2.yml:12:7:16:4 | Uses Step | .github/workflows/label_trusted_checkout2.yml:12:7:16:4 | Uses Step | .github/workflows/label_trusted_checkout2.yml:17:7:21:4 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/label_trusted_checkout2.yml:2:3:2:21 | pull_request_target | pull_request_target |
@@ -377,3 +393,5 @@ edges
| .github/workflows/untrusted_checkout4.yml:29:7:35:4 | Uses Step | .github/workflows/untrusted_checkout4.yml:29:7:35:4 | Uses Step | .github/workflows/untrusted_checkout4.yml:47:7:51:46 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout4.yml:2:3:2:15 | issue_comment | issue_comment |
| .github/workflows/untrusted_checkout.yml:8:9:11:6 | Uses Step | .github/workflows/untrusted_checkout.yml:8:9:11:6 | Uses Step | .github/workflows/untrusted_checkout.yml:15:9:18:2 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout.yml:2:3:2:21 | pull_request_target | pull_request_target |
| .github/workflows/untrusted_checkout.yml:23:9:26:6 | Uses Step | .github/workflows/untrusted_checkout.yml:23:9:26:6 | Uses Step | .github/workflows/untrusted_checkout.yml:30:9:32:23 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout.yml:2:3:2:21 | pull_request_target | pull_request_target |
| .github/workflows/untrusted_checkout_no_needs.yml:26:9:31:6 | Uses Step | .github/workflows/untrusted_checkout_no_needs.yml:26:9:31:6 | Uses Step | .github/workflows/untrusted_checkout_no_needs.yml:31:9:31:23 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout_no_needs.yml:2:3:2:21 | pull_request_target | pull_request_target |
| .github/workflows/untrusted_checkout_permissions_check.yml:36:9:41:6 | Uses Step | .github/workflows/untrusted_checkout_permissions_check.yml:36:9:41:6 | Uses Step | .github/workflows/untrusted_checkout_permissions_check.yml:41:9:41:22 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout_permissions_check.yml:2:3:2:21 | pull_request_target | pull_request_target |

View File

@@ -1,3 +1,20 @@
## 11.0.0
### Breaking Changes
* Removed the deprecated `overrideReturnsNull` predicate from `Options.qll`. Use `CustomOptions.overrideReturnsNull` instead.
* Removed the deprecated `returnsNull` predicate from `Options.qll`. Use `CustomOptions.returnsNull` instead.
* Removed the deprecated `exits` predicate from `Options.qll`. Use `CustomOptions.exits` instead.
* Removed the deprecated `exprExits` predicate from `Options.qll`. Use `CustomOptions.exprExits` instead.
* Removed the deprecated `alwaysCheckReturnValue` predicate from `Options.qll`. Use `CustomOptions.alwaysCheckReturnValue` instead.
* Removed the deprecated `okToIgnoreReturnValue` predicate from `Options.qll`. Use `CustomOptions.okToIgnoreReturnValue` instead.
* Removed the deprecated `semmle.code.cpp.Member`. Import `semmle.code.cpp.Element` and/or `semmle.code.cpp.Type` directly.
* Removed the deprecated `UnknownDefaultLocation` class. Use `UnknownLocation` instead.
* Removed the deprecated `UnknownExprLocation` class. Use `UnknownLocation` instead.
* Removed the deprecated `UnknownStmtLocation` class. Use `UnknownLocation` instead.
* Removed the deprecated `TemplateParameter` class. Use `TypeTemplateParameter` instead.
* Support for class resolution across link targets has been removed for databases which were created with CodeQL versions before 1.23.0.
## 10.2.0
### Deprecated APIs

View File

@@ -1,6 +1,7 @@
---
category: breaking
---
## 11.0.0
### Breaking Changes
* Removed the deprecated `overrideReturnsNull` predicate from `Options.qll`. Use `CustomOptions.overrideReturnsNull` instead.
* Removed the deprecated `returnsNull` predicate from `Options.qll`. Use `CustomOptions.returnsNull` instead.
* Removed the deprecated `exits` predicate from `Options.qll`. Use `CustomOptions.exits` instead.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 10.2.0
lastReleaseVersion: 11.0.0

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 10.2.1-dev
version: 11.0.0
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,7 @@
## 1.6.5
No user-facing changes.
## 1.6.4
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.6.5
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.6.4
lastReleaseVersion: 1.6.5

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 1.6.5-dev
version: 1.6.5
groups:
- cpp
- queries

View File

@@ -0,0 +1,413 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Semmle.Util;
using Semmle.Util.Logging;
namespace Semmle.Extraction.CSharp.DependencyFetching
{
internal sealed partial class FeedManager : IDisposable
{
internal const string PublicNugetOrgFeed = "https://api.nuget.org/v3/index.json";
private readonly ILogger logger;
private readonly IDotNet dotnet;
private readonly FileProvider fileProvider;
private readonly DependabotProxy? dependabotProxy;
private readonly DependencyDirectory emptyPackageDirectory;
public ImmutableHashSet<string> PrivateRegistryFeeds { get; }
public bool HasPrivateRegistryFeeds { get; }
public bool CheckNugetFeedResponsiveness { get; } = EnvironmentVariables.GetBooleanOptOut(EnvironmentVariableNames.CheckNugetFeedResponsiveness);
public FeedManager(ILogger logger, IDotNet dotnet, DependabotProxy? dependabotProxy, FileProvider fileProvider)
{
this.logger = logger;
this.dotnet = dotnet;
this.dependabotProxy = dependabotProxy;
this.fileProvider = fileProvider;
PrivateRegistryFeeds = dependabotProxy?.RegistryURLs.ToImmutableHashSet() ?? [];
HasPrivateRegistryFeeds = PrivateRegistryFeeds.Count > 0;
emptyPackageDirectory = new DependencyDirectory("empty", "empty package", logger);
}
private string? GetDirectoryName(string path)
{
try
{
return new FileInfo(path).Directory?.FullName;
}
catch (Exception exc)
{
logger.LogWarning($"Failed to get directory of '{path}': {exc}");
}
return null;
}
private IEnumerable<string> GetFeeds(Func<IList<string>> getNugetFeeds)
{
var results = getNugetFeeds();
var regex = EnabledNugetFeed();
foreach (var result in results)
{
var match = regex.Match(result);
if (!match.Success)
{
logger.LogError($"Failed to parse feed from '{result}'");
continue;
}
var url = match.Groups[1].Value;
if (!url.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase) &&
!url.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase))
{
logger.LogInfo($"Skipping feed '{url}' as it is not a valid URL.");
continue;
}
if (!string.IsNullOrWhiteSpace(url))
{
yield return url;
}
}
}
private IEnumerable<string> GetFeedsFromFolder(string folderPath) =>
GetFeeds(() => dotnet.GetNugetFeedsFromFolder(folderPath));
private IEnumerable<string> GetFeedsFromNugetConfig(string nugetConfigPath) =>
GetFeeds(() => dotnet.GetNugetFeeds(nugetConfigPath));
private string FeedsToRestoreArgument(IEnumerable<string> feeds)
{
// If there are no feeds, we want to override any default feeds that `dotnet restore` would use by passing a dummy source argument.
if (!feeds.Any())
{
return $" -s \"{emptyPackageDirectory.DirInfo.FullName}\"";
}
// Add package sources. If any are present, they override all sources specified in
// the configuration file(s).
var feedArgs = new StringBuilder();
foreach (var feed in feeds)
{
feedArgs.Append($" -s \"{feed}\"");
}
return feedArgs.ToString();
}
/// <summary>
/// Constructs the list of NuGet sources to use for this restore.
/// (1) Use the feeds we get from `dotnet nuget list source`
/// (2) Use private registries, if they are configured
/// </summary>
/// <param name="path">Path to project/solution</param>
/// <param name="reachableFeeds">The set of reachable NuGet feeds.</param>
/// <returns>A string representing the NuGet sources argument for the restore command.</returns>
public string? MakeRestoreSourcesArgument(string path, HashSet<string> reachableFeeds)
{
// Do not construct a set of explicit NuGet sources to use for restore.
if (!CheckNugetFeedResponsiveness && !HasPrivateRegistryFeeds)
{
return null;
}
// Find the path specific feeds.
var folder = GetDirectoryName(path);
var feedsToConsider = folder is not null ? GetFeedsFromFolder(folder).ToHashSet() : new HashSet<string>();
if (HasPrivateRegistryFeeds)
{
feedsToConsider.UnionWith(PrivateRegistryFeeds);
}
var feedsToUse = CheckNugetFeedResponsiveness
? feedsToConsider.Where(reachableFeeds.Contains)
: feedsToConsider;
return FeedsToRestoreArgument(feedsToUse);
}
private (int initialTimeout, int tryCount) GetFeedRequestSettings(bool isFallback)
{
int timeoutMilliSeconds = isFallback && int.TryParse(Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetFeedResponsivenessInitialTimeoutForFallback), out timeoutMilliSeconds)
? timeoutMilliSeconds
: int.TryParse(Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetFeedResponsivenessInitialTimeout), out timeoutMilliSeconds)
? timeoutMilliSeconds
: 1000;
logger.LogDebug($"Initial timeout for NuGet feed reachability check is {timeoutMilliSeconds}ms.");
int tryCount = isFallback && int.TryParse(Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetFeedResponsivenessRequestCountForFallback), out tryCount)
? tryCount
: int.TryParse(Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetFeedResponsivenessRequestCount), out tryCount)
? tryCount
: 4;
logger.LogDebug($"Number of tries for NuGet feed reachability check is {tryCount}.");
return (timeoutMilliSeconds, tryCount);
}
private static async Task<HttpResponseMessage> ExecuteGetRequest(string address, HttpClient httpClient, CancellationToken cancellationToken)
{
return await httpClient.GetAsync(address, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
}
private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, out bool isTimeout)
{
logger.LogInfo($"Checking if NuGet feed '{feed}' is reachable...");
// Configure the HttpClient to be aware of the Dependabot Proxy, if used.
HttpClientHandler httpClientHandler = new();
if (dependabotProxy != null)
{
httpClientHandler.Proxy = new WebProxy(dependabotProxy.Address);
if (dependabotProxy.Certificate != null)
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, _) =>
{
if (chain is null || cert is null)
{
var msg = cert is null && chain is null
? "certificate and chain"
: chain is null
? "chain"
: "certificate";
logger.LogWarning($"Dependabot proxy certificate validation failed due to missing {msg}");
return false;
}
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
chain.ChainPolicy.CustomTrustStore.Add(dependabotProxy.Certificate);
return chain.Build(cert);
};
}
}
using HttpClient client = new(httpClientHandler);
isTimeout = false;
for (var i = 0; i < tryCount; i++)
{
using var cts = new CancellationTokenSource();
cts.CancelAfter(timeoutMilliSeconds);
try
{
logger.LogInfo($"Attempt {i + 1}/{tryCount} to reach NuGet feed '{feed}'.");
using var response = ExecuteGetRequest(feed, client, cts.Token).GetAwaiter().GetResult();
response.EnsureSuccessStatusCode();
logger.LogInfo($"Querying NuGet feed '{feed}' succeeded.");
return true;
}
catch (Exception exc)
{
if (exc is TaskCanceledException tce &&
tce.CancellationToken == cts.Token &&
cts.Token.IsCancellationRequested)
{
logger.LogInfo($"Didn't receive answer from NuGet feed '{feed}' in {timeoutMilliSeconds}ms.");
timeoutMilliSeconds *= 2;
continue;
}
logger.LogInfo($"Querying NuGet feed '{feed}' failed. The reason for the failure: {exc.Message}");
return false;
}
}
logger.LogWarning($"Didn't receive answer from NuGet feed '{feed}'. Tried it {tryCount} times.");
isTimeout = true;
return false;
}
/// <summary>
/// Retrieves a list of excluded NuGet feeds from the corresponding environment variable.
/// </summary>
private HashSet<string> GetExcludedFeeds()
{
var excludedFeeds = EnvironmentVariables.GetURLs(EnvironmentVariableNames.ExcludedNugetFeedsFromResponsivenessCheck)
.ToHashSet();
if (excludedFeeds.Count > 0)
{
logger.LogInfo($"Excluded NuGet feeds from responsiveness check: {string.Join(", ", excludedFeeds.OrderBy(f => f))}");
}
return excludedFeeds;
}
/// <summary>
/// Checks that we can connect to the specified NuGet feeds.
/// </summary>
/// <param name="feeds">The set of package feeds to check.</param>
/// <param name="reachableFeeds">The list of feeds that were reachable.</param>
/// <returns>
/// True if there is a timeout when trying to reach the feeds (excluding any feeds that are configured
/// to be excluded from the check) or false otherwise.
/// </returns>
public bool CheckSpecifiedFeeds(HashSet<string> feeds, out HashSet<string> reachableFeeds)
{
// Exclude any feeds from the feed check that are configured by the corresponding environment variable.
// These feeds are always assumed to be reachable.
var excludedFeeds = GetExcludedFeeds();
HashSet<string> feedsToCheck = feeds.Where(feed =>
{
if (excludedFeeds.Contains(feed))
{
logger.LogInfo($"Not checking reachability of NuGet feed '{feed}' as it is in the list of excluded feeds.");
return false;
}
return true;
}).ToHashSet();
reachableFeeds = GetReachableNuGetFeeds(feedsToCheck, isFallback: false, out var isTimeout).ToHashSet();
// Always consider feeds excluded for the reachability check as reachable.
reachableFeeds.UnionWith(feeds.Where(feed => excludedFeeds.Contains(feed)));
return isTimeout;
}
public bool IsDefaultFeedReachable()
{
if (CheckNugetFeedResponsiveness)
{
var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback: false);
return IsFeedReachable(PublicNugetOrgFeed, initialTimeout, tryCount, out var _);
}
return true;
}
/// <summary>
/// Tests which of the feeds given by <paramref name="feedsToCheck"/> are reachable.
/// </summary>
/// <param name="feedsToCheck">The feeds to check.</param>
/// <param name="isFallback">Whether the feeds are fallback feeds or not.</param>
/// <param name="isTimeout">Whether a timeout occurred while checking the feeds.</param>
/// <returns>The list of feeds that could be reached.</returns>
private List<string> GetReachableNuGetFeeds(HashSet<string> feedsToCheck, bool isFallback, out bool isTimeout)
{
var fallbackStr = isFallback ? "fallback " : "";
logger.LogInfo($"Checking {fallbackStr}NuGet feed reachability on feeds: {string.Join(", ", feedsToCheck.OrderBy(f => f))}");
var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback);
var timeout = false;
var reachableFeeds = feedsToCheck
.Where(feed =>
{
var reachable = IsFeedReachable(feed, initialTimeout, tryCount, out var feedTimeout);
timeout |= feedTimeout;
return reachable;
})
.ToList();
if (reachableFeeds.Count == 0)
{
logger.LogWarning($"No {fallbackStr}NuGet feeds are reachable.");
}
else
{
logger.LogInfo($"Reachable {fallbackStr}NuGet feeds: {string.Join(", ", reachableFeeds.OrderBy(f => f))}");
}
isTimeout = timeout;
return reachableFeeds;
}
public List<string> GetReachableFallbackNugetFeeds(HashSet<string>? feedsFromNugetConfigs)
{
var fallbackFeeds = EnvironmentVariables.GetURLs(EnvironmentVariableNames.FallbackNugetFeeds).ToHashSet();
if (fallbackFeeds.Count == 0)
{
fallbackFeeds.Add(PublicNugetOrgFeed);
logger.LogInfo($"No fallback NuGet feeds specified. Adding default feed: {PublicNugetOrgFeed}");
var shouldAddNugetConfigFeeds = EnvironmentVariables.GetBooleanOptOut(EnvironmentVariableNames.AddNugetConfigFeedsToFallback);
logger.LogInfo($"Adding feeds from nuget.config to fallback restore: {shouldAddNugetConfigFeeds}");
if (shouldAddNugetConfigFeeds && feedsFromNugetConfigs?.Count > 0)
{
// There are some feeds in `feedsFromNugetConfigs` that have already been checked for reachability, we could skip those.
// But we might use different responsiveness testing settings when we try them in the fallback logic, so checking them again is safer.
fallbackFeeds.UnionWith(feedsFromNugetConfigs);
logger.LogInfo($"Using NuGet feeds from nuget.config files as fallback feeds: {string.Join(", ", feedsFromNugetConfigs.OrderBy(f => f))}");
}
}
return GetReachableNuGetFeeds(fallbackFeeds, isFallback: true, out var _);
}
public (HashSet<string> explicitFeeds, HashSet<string> allFeeds) GetAllFeeds()
{
var nugetConfigs = fileProvider.NugetConfigs;
// Find feeds that are explicitly configured in the NuGet configuration files that we found.
var explicitFeeds = nugetConfigs
.SelectMany(GetFeedsFromNugetConfig)
.ToHashSet();
if (explicitFeeds.Count > 0)
{
logger.LogInfo($"Found {explicitFeeds.Count} NuGet feeds in nuget.config files: {string.Join(", ", explicitFeeds.OrderBy(f => f))}");
}
else
{
logger.LogDebug("No NuGet feeds found in nuget.config files.");
}
// If private package registries are configured for C#, then consider those
// in addition to the ones that are configured in `nuget.config` files.
if (HasPrivateRegistryFeeds)
{
logger.LogInfo($"Found {PrivateRegistryFeeds.Count} private registry feeds configured for C#: {string.Join(", ", PrivateRegistryFeeds.OrderBy(f => f))}");
explicitFeeds.UnionWith(PrivateRegistryFeeds);
}
HashSet<string> allFeeds = [];
// Add all explicitFeeds to the set of all feeds.
allFeeds.UnionWith(explicitFeeds);
// Obtain the list of feeds from the root source directory.
// If a NuGet file is present it will be respected, otherwise we will just get the machine/environment specific feeds.
var nugetFeedsFromRoot = GetFeedsFromFolder(fileProvider.SourceDir.FullName);
allFeeds.UnionWith(nugetFeedsFromRoot);
if (nugetConfigs.Count > 0)
{
var nugetConfigFeeds = nugetConfigs
.Select(GetDirectoryName)
.Where(folder => folder != null)
.SelectMany(folder => GetFeedsFromFolder(folder!))
.ToHashSet();
allFeeds.UnionWith(nugetConfigFeeds);
}
logger.LogInfo($"Found {allFeeds.Count} NuGet feeds (with inherited ones) in nuget.config files: {string.Join(", ", allFeeds.OrderBy(f => f))}");
return (explicitFeeds, allFeeds);
}
[GeneratedRegex(@"^E\s(.*)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
private static partial Regex EnabledNugetFeed();
public void Dispose()
{
emptyPackageDirectory.Dispose();
}
}
}

View File

@@ -4,9 +4,6 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
@@ -19,24 +16,19 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
{
internal sealed partial class NugetPackageRestorer : IDisposable
{
internal const string PublicNugetOrgFeed = "https://api.nuget.org/v3/index.json";
private readonly FileProvider fileProvider;
private readonly FileContent fileContent;
private readonly IDotNet dotnet;
private readonly DependabotProxy? dependabotProxy;
private readonly IDiagnosticsWriter diagnosticsWriter;
private readonly DependencyDirectory legacyPackageDirectory;
private readonly DependencyDirectory missingPackageDirectory;
private readonly DependencyDirectory emptyPackageDirectory;
private readonly ILogger logger;
private readonly ICompilationInfoContainer compilationInfoContainer;
private readonly bool checkNugetFeedResponsiveness = EnvironmentVariables.GetBooleanOptOut(EnvironmentVariableNames.CheckNugetFeedResponsiveness);
private readonly ImmutableHashSet<string> privateRegistryFeeds;
private readonly bool hasPrivateRegistryFeeds;
private readonly FeedManager feedManager;
public DependencyDirectory PackageDirectory { get; }
public NugetPackageRestorer(
FileProvider fileProvider,
FileContent fileContent,
@@ -49,9 +41,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
this.fileProvider = fileProvider;
this.fileContent = fileContent;
this.dotnet = dotnet;
this.dependabotProxy = dependabotProxy;
this.privateRegistryFeeds = dependabotProxy?.RegistryURLs.ToImmutableHashSet() ?? [];
this.hasPrivateRegistryFeeds = privateRegistryFeeds.Count > 0;
this.diagnosticsWriter = diagnosticsWriter;
this.logger = logger;
this.compilationInfoContainer = compilationInfoContainer;
@@ -59,7 +48,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
PackageDirectory = new DependencyDirectory("packages", "package", logger);
legacyPackageDirectory = new DependencyDirectory("legacypackages", "legacy package", logger);
missingPackageDirectory = new DependencyDirectory("missingpackages", "missing package", logger);
emptyPackageDirectory = new DependencyDirectory("empty", "empty package", logger);
feedManager = new FeedManager(logger, dotnet, dependabotProxy, fileProvider);
}
public string? TryRestore(string package)
@@ -118,20 +107,22 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
public HashSet<AssemblyLookupLocation> Restore()
{
var assemblyLookupLocations = new HashSet<AssemblyLookupLocation>();
logger.LogInfo($"Checking NuGet feed responsiveness: {checkNugetFeedResponsiveness}");
compilationInfoContainer.CompilationInfos.Add(("NuGet feed responsiveness checked", checkNugetFeedResponsiveness ? "1" : "0"));
logger.LogInfo($"Checking NuGet feed responsiveness: {feedManager.CheckNugetFeedResponsiveness}");
compilationInfoContainer.CompilationInfos.Add(("NuGet feed responsiveness checked", feedManager.CheckNugetFeedResponsiveness ? "1" : "0"));
HashSet<string> explicitFeeds = [];
HashSet<string> reachableFeeds = [];
try
{
EmitNugetConfigDiagnostics();
// Find feeds that are configured in NuGet.config files and divide them into ones that
// are explicitly configured for the project or by a private registry, and "all feeds"
// (including inherited ones) from other locations on the host outside of the working directory.
(explicitFeeds, var allFeeds) = GetAllFeeds();
(explicitFeeds, var allFeeds) = feedManager.GetAllFeeds();
if (checkNugetFeedResponsiveness)
if (feedManager.CheckNugetFeedResponsiveness)
{
var inheritedFeeds = allFeeds.Except(explicitFeeds).ToHashSet();
@@ -140,7 +131,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
compilationInfoContainer.CompilationInfos.Add(("Inherited NuGet feed count", inheritedFeeds.Count.ToString()));
}
var timeout = CheckSpecifiedFeeds(explicitFeeds, out var reachableExplicitFeeds);
var timeout = feedManager.CheckSpecifiedFeeds(explicitFeeds, out var reachableExplicitFeeds);
reachableFeeds.UnionWith(reachableExplicitFeeds);
var allExplicitReachable = explicitFeeds.Count == reachableExplicitFeeds.Count;
@@ -157,11 +148,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
// Inherited feeds should only be used, if they are indeed reachable (as they may be environment specific).
CheckSpecifiedFeeds(inheritedFeeds, out var reachableInheritedFeeds);
feedManager.CheckSpecifiedFeeds(inheritedFeeds, out var reachableInheritedFeeds);
reachableFeeds.UnionWith(reachableInheritedFeeds);
}
using (var packagesConfigRestore = PackagesConfigRestoreFactory.Create(fileProvider, legacyPackageDirectory, logger, IsDefaultFeedReachable))
using (var packagesConfigRestore = PackagesConfigRestoreFactory.Create(fileProvider, legacyPackageDirectory, logger, feedManager.IsDefaultFeedReachable))
{
var count = packagesConfigRestore.InstallPackages();
@@ -215,7 +206,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var usedPackageNames = GetAllUsedPackageDirNames(dependencies);
var missingPackageLocation = checkNugetFeedResponsiveness
var missingPackageLocation = feedManager.CheckNugetFeedResponsiveness
? DownloadMissingPackagesFromSpecificFeeds(usedPackageNames, explicitFeeds)
: DownloadMissingPackages(usedPackageNames);
@@ -226,79 +217,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
return assemblyLookupLocations;
}
/// <summary>
/// Tests which of the feeds given by <paramref name="feedsToCheck"/> are reachable.
/// </summary>
/// <param name="feedsToCheck">The feeds to check.</param>
/// <param name="isFallback">Whether the feeds are fallback feeds or not.</param>
/// <param name="isTimeout">Whether a timeout occurred while checking the feeds.</param>
/// <returns>The list of feeds that could be reached.</returns>
private List<string> GetReachableNuGetFeeds(HashSet<string> feedsToCheck, bool isFallback, out bool isTimeout)
{
var fallbackStr = isFallback ? "fallback " : "";
logger.LogInfo($"Checking {fallbackStr}NuGet feed reachability on feeds: {string.Join(", ", feedsToCheck.OrderBy(f => f))}");
var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback);
var timeout = false;
var reachableFeeds = feedsToCheck
.Where(feed =>
{
var reachable = IsFeedReachable(feed, initialTimeout, tryCount, out var feedTimeout);
timeout |= feedTimeout;
return reachable;
})
.ToList();
if (reachableFeeds.Count == 0)
{
logger.LogWarning($"No {fallbackStr}NuGet feeds are reachable.");
}
else
{
logger.LogInfo($"Reachable {fallbackStr}NuGet feeds: {string.Join(", ", reachableFeeds.OrderBy(f => f))}");
}
isTimeout = timeout;
return reachableFeeds;
}
private bool IsDefaultFeedReachable()
{
if (checkNugetFeedResponsiveness)
{
var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback: false);
return IsFeedReachable(PublicNugetOrgFeed, initialTimeout, tryCount, out var _);
}
return true;
}
private List<string> GetReachableFallbackNugetFeeds(HashSet<string>? feedsFromNugetConfigs)
{
var fallbackFeeds = EnvironmentVariables.GetURLs(EnvironmentVariableNames.FallbackNugetFeeds).ToHashSet();
if (fallbackFeeds.Count == 0)
{
fallbackFeeds.Add(PublicNugetOrgFeed);
logger.LogInfo($"No fallback NuGet feeds specified. Adding default feed: {PublicNugetOrgFeed}");
var shouldAddNugetConfigFeeds = EnvironmentVariables.GetBooleanOptOut(EnvironmentVariableNames.AddNugetConfigFeedsToFallback);
logger.LogInfo($"Adding feeds from nuget.config to fallback restore: {shouldAddNugetConfigFeeds}");
if (shouldAddNugetConfigFeeds && feedsFromNugetConfigs?.Count > 0)
{
// There are some feeds in `feedsFromNugetConfigs` that have already been checked for reachability, we could skip those.
// But we might use different responsiveness testing settings when we try them in the fallback logic, so checking them again is safer.
fallbackFeeds.UnionWith(feedsFromNugetConfigs);
logger.LogInfo($"Using NuGet feeds from nuget.config files as fallback feeds: {string.Join(", ", feedsFromNugetConfigs.OrderBy(f => f))}");
}
}
var reachableFallbackFeeds = GetReachableNuGetFeeds(fallbackFeeds, isFallback: true, out var _);
compilationInfoContainer.CompilationInfos.Add(("Reachable fallback NuGet feed count", reachableFallbackFeeds.Count.ToString()));
return reachableFallbackFeeds;
}
/// <summary>
/// Executes `dotnet restore` on all solution files in solutions.
@@ -321,7 +239,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var projects = fileProvider.Solutions.SelectMany(solution =>
{
logger.LogInfo($"Restoring solution {solution}...");
var nugetSources = MakeRestoreSourcesArgument(solution, reachableFeeds);
var nugetSources = feedManager.MakeRestoreSourcesArgument(solution, reachableFeeds);
var res = dotnet.Restore(new(solution, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, NugetSources: nugetSources, TargetWindows: isWindows));
if (res.Success)
{
@@ -346,57 +264,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
return projects;
}
private string FeedsToRestoreArgument(IEnumerable<string> feeds)
{
// If there are no feeds, we want to override any default feeds that `dotnet restore` would use by passing a dummy source argument.
if (!feeds.Any())
{
return $" -s \"{emptyPackageDirectory.DirInfo.FullName}\"";
}
// Add package sources. If any are present, they override all sources specified in
// the configuration file(s).
var feedArgs = new StringBuilder();
foreach (var feed in feeds)
{
feedArgs.Append($" -s \"{feed}\"");
}
return feedArgs.ToString();
}
/// <summary>
/// Constructs the list of NuGet sources to use for this restore.
/// (1) Use the feeds we get from `dotnet nuget list source`
/// (2) Use private registries, if they are configured
/// </summary>
/// <param name="path">Path to project/solution</param>
/// <param name="reachableFeeds">The set of reachable NuGet feeds.</param>
/// <returns>A string representing the NuGet sources argument for the restore command.</returns>
private string? MakeRestoreSourcesArgument(string path, HashSet<string> reachableFeeds)
{
// Do not construct an set of explicit NuGet sources to use for restore.
if (!checkNugetFeedResponsiveness && !hasPrivateRegistryFeeds)
{
return null;
}
// Find the path specific feeds.
var folder = GetDirectoryName(path);
var feedsToConsider = folder is not null ? GetFeeds(() => dotnet.GetNugetFeedsFromFolder(folder)).ToHashSet() : [];
if (hasPrivateRegistryFeeds)
{
feedsToConsider.UnionWith(privateRegistryFeeds);
}
var feedsToUse = checkNugetFeedResponsiveness
? feedsToConsider.Where(reachableFeeds.Contains)
: feedsToConsider;
return FeedsToRestoreArgument(feedsToUse);
}
/// <summary>
/// Executes `dotnet restore` on all projects in projects.
/// This is done in parallel for performance reasons.
@@ -421,7 +288,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
foreach (var project in projectGroup)
{
logger.LogInfo($"Restoring project {project}...");
var nugetSources = MakeRestoreSourcesArgument(project, reachableFeeds);
var nugetSources = feedManager.MakeRestoreSourcesArgument(project, reachableFeeds);
var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, NugetSources: nugetSources, TargetWindows: isWindows));
assets.AddDependenciesRange(res.AssetsFilePaths);
lock (sync)
@@ -450,7 +317,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private AssemblyLookupLocation? DownloadMissingPackagesFromSpecificFeeds(IEnumerable<string> usedPackageNames, HashSet<string>? feedsFromNugetConfigs)
{
var reachableFallbackFeeds = GetReachableFallbackNugetFeeds(feedsFromNugetConfigs);
var reachableFallbackFeeds = feedManager.GetReachableFallbackNugetFeeds(feedsFromNugetConfigs);
compilationInfoContainer.CompilationInfos.Add(("Reachable fallback NuGet feed count", reachableFallbackFeeds.Count.ToString()));
if (reachableFallbackFeeds.Count > 0)
{
return DownloadMissingPackages(usedPackageNames, fallbackNugetFeeds: reachableFallbackFeeds);
@@ -736,147 +605,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
}
private static async Task<HttpResponseMessage> ExecuteGetRequest(string address, HttpClient httpClient, CancellationToken cancellationToken)
{
return await httpClient.GetAsync(address, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
}
private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, out bool isTimeout)
{
logger.LogInfo($"Checking if NuGet feed '{feed}' is reachable...");
// Configure the HttpClient to be aware of the Dependabot Proxy, if used.
HttpClientHandler httpClientHandler = new();
if (dependabotProxy != null)
{
httpClientHandler.Proxy = new WebProxy(dependabotProxy.Address);
if (dependabotProxy.Certificate != null)
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, _) =>
{
if (chain is null || cert is null)
{
var msg = cert is null && chain is null
? "certificate and chain"
: chain is null
? "chain"
: "certificate";
logger.LogWarning($"Dependabot proxy certificate validation failed due to missing {msg}");
return false;
}
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
chain.ChainPolicy.CustomTrustStore.Add(dependabotProxy.Certificate);
return chain.Build(cert);
};
}
}
using HttpClient client = new(httpClientHandler);
isTimeout = false;
for (var i = 0; i < tryCount; i++)
{
using var cts = new CancellationTokenSource();
cts.CancelAfter(timeoutMilliSeconds);
try
{
logger.LogInfo($"Attempt {i + 1}/{tryCount} to reach NuGet feed '{feed}'.");
using var response = ExecuteGetRequest(feed, client, cts.Token).GetAwaiter().GetResult();
response.EnsureSuccessStatusCode();
logger.LogInfo($"Querying NuGet feed '{feed}' succeeded.");
return true;
}
catch (Exception exc)
{
if (exc is TaskCanceledException tce &&
tce.CancellationToken == cts.Token &&
cts.Token.IsCancellationRequested)
{
logger.LogInfo($"Didn't receive answer from NuGet feed '{feed}' in {timeoutMilliSeconds}ms.");
timeoutMilliSeconds *= 2;
continue;
}
logger.LogInfo($"Querying NuGet feed '{feed}' failed. The reason for the failure: {exc.Message}");
return false;
}
}
logger.LogWarning($"Didn't receive answer from NuGet feed '{feed}'. Tried it {tryCount} times.");
isTimeout = true;
return false;
}
private (int initialTimeout, int tryCount) GetFeedRequestSettings(bool isFallback)
{
int timeoutMilliSeconds = isFallback && int.TryParse(Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetFeedResponsivenessInitialTimeoutForFallback), out timeoutMilliSeconds)
? timeoutMilliSeconds
: int.TryParse(Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetFeedResponsivenessInitialTimeout), out timeoutMilliSeconds)
? timeoutMilliSeconds
: 1000;
logger.LogDebug($"Initial timeout for NuGet feed reachability check is {timeoutMilliSeconds}ms.");
int tryCount = isFallback && int.TryParse(Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetFeedResponsivenessRequestCountForFallback), out tryCount)
? tryCount
: int.TryParse(Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetFeedResponsivenessRequestCount), out tryCount)
? tryCount
: 4;
logger.LogDebug($"Number of tries for NuGet feed reachability check is {tryCount}.");
return (timeoutMilliSeconds, tryCount);
}
/// <summary>
/// Retrieves a list of excluded NuGet feeds from the corresponding environment variable.
/// </summary>
private HashSet<string> GetExcludedFeeds()
{
var excludedFeeds = EnvironmentVariables.GetURLs(EnvironmentVariableNames.ExcludedNugetFeedsFromResponsivenessCheck)
.ToHashSet();
if (excludedFeeds.Count > 0)
{
logger.LogInfo($"Excluded NuGet feeds from responsiveness check: {string.Join(", ", excludedFeeds.OrderBy(f => f))}");
}
return excludedFeeds;
}
/// <summary>
/// Checks that we can connect to the specified NuGet feeds.
/// </summary>
/// <param name="feeds">The set of package feeds to check.</param>
/// <param name="reachableFeeds">The list of feeds that were reachable.</param>
/// <returns>
/// True if there is a timeout when trying to reach the feeds (excluding any feeds that are configured
/// to be excluded from the check) or false otherwise.
/// </returns>
private bool CheckSpecifiedFeeds(HashSet<string> feeds, out HashSet<string> reachableFeeds)
{
// Exclude any feeds from the feed check that are configured by the corresponding environment variable.
// These feeds are always assumed to be reachable.
var excludedFeeds = GetExcludedFeeds();
HashSet<string> feedsToCheck = feeds.Where(feed =>
{
if (excludedFeeds.Contains(feed))
{
logger.LogInfo($"Not checking reachability of NuGet feed '{feed}' as it is in the list of excluded feeds.");
return false;
}
return true;
}).ToHashSet();
reachableFeeds = GetReachableNuGetFeeds(feedsToCheck, isFallback: false, out var isTimeout).ToHashSet();
// Always consider feeds excluded for the reachability check as reachable.
reachableFeeds.UnionWith(feeds.Where(feed => excludedFeeds.Contains(feed)));
return isTimeout;
}
/// <summary>
/// If <paramref name="allFeedsReachable"/> is `false`, logs this and emits a diagnostic.
/// Adds a `CompilationInfos` entry either way.
@@ -899,56 +627,15 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
compilationInfoContainer.CompilationInfos.Add(("All NuGet feeds reachable", allFeedsReachable ? "1" : "0"));
}
private IEnumerable<string> GetFeeds(Func<IList<string>> getNugetFeeds)
private void EmitNugetConfigDiagnostics()
{
var results = getNugetFeeds();
var regex = EnabledNugetFeed();
foreach (var result in results)
{
var match = regex.Match(result);
if (!match.Success)
{
logger.LogError($"Failed to parse feed from '{result}'");
continue;
}
var url = match.Groups[1].Value;
if (!url.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase) &&
!url.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase))
{
logger.LogInfo($"Skipping feed '{url}' as it is not a valid URL.");
continue;
}
if (!string.IsNullOrWhiteSpace(url))
{
yield return url;
}
}
}
private string? GetDirectoryName(string path)
{
try
{
return new FileInfo(path).Directory?.FullName;
}
catch (Exception exc)
{
logger.LogWarning($"Failed to get directory of '{path}': {exc}");
}
return null;
}
private (HashSet<string> explicitFeeds, HashSet<string> allFeeds) GetAllFeeds()
{
var nugetConfigs = fileProvider.NugetConfigs;
// On systems with case-sensitive file systems (for simplicity, we assume that is Linux), the
// filenames of NuGet configuration files must be named correctly. For compatibility with projects
// that are typically built on Windows or macOS where this doesn't matter, we accept all variants
// of `nuget.config` ourselves. However, `dotnet` does not. If we detect that incorrectly-named
// files are present, we emit a diagnostic to warn the user.
var nugetConfigs = fileProvider.NugetConfigs;
if (SystemBuildActions.Instance.IsLinux())
{
string[] acceptedNugetConfigNames = ["nuget.config", "NuGet.config", "NuGet.Config"];
@@ -978,53 +665,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
));
}
}
// Find feeds that are explicitly configured in the NuGet configuration files that we found.
var explicitFeeds = nugetConfigs
.SelectMany(config => GetFeeds(() => dotnet.GetNugetFeeds(config)))
.ToHashSet();
if (explicitFeeds.Count > 0)
{
logger.LogInfo($"Found {explicitFeeds.Count} NuGet feeds in nuget.config files: {string.Join(", ", explicitFeeds.OrderBy(f => f))}");
}
else
{
logger.LogDebug("No NuGet feeds found in nuget.config files.");
}
// If private package registries are configured for C#, then consider those
// in addition to the ones that are configured in `nuget.config` files.
if (hasPrivateRegistryFeeds)
{
logger.LogInfo($"Found {privateRegistryFeeds.Count} private registry feeds configured for C#: {string.Join(", ", privateRegistryFeeds.OrderBy(f => f))}");
explicitFeeds.UnionWith(privateRegistryFeeds);
}
HashSet<string> allFeeds = [];
// Add all explicitFeeds to the set of all feeds.
allFeeds.UnionWith(explicitFeeds);
// Obtain the list of feeds from the root source directory.
// If a NuGet file is present it will be respected, otherwise we will just get the machine/environment specific feeds.
var nugetFeedsFromRoot = GetFeeds(() => dotnet.GetNugetFeedsFromFolder(fileProvider.SourceDir.FullName));
allFeeds.UnionWith(nugetFeedsFromRoot);
if (nugetConfigs.Count > 0)
{
var nugetConfigFeeds = nugetConfigs
.Select(GetDirectoryName)
.Where(folder => folder != null)
.SelectMany(folder => GetFeeds(() => dotnet.GetNugetFeedsFromFolder(folder!)))
.ToHashSet();
allFeeds.UnionWith(nugetConfigFeeds);
}
logger.LogInfo($"Found {allFeeds.Count} NuGet feeds (with inherited ones) in nuget.config files: {string.Join(", ", allFeeds.OrderBy(f => f))}");
return (explicitFeeds, allFeeds);
}
[GeneratedRegex(@"<TargetFramework>.*</TargetFramework>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
@@ -1036,15 +676,12 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
[GeneratedRegex(@"^(.+)\.(\d+\.\d+\.\d+(-(.+))?)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
private static partial Regex LegacyNugetPackage();
[GeneratedRegex(@"^E\s(.*)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
private static partial Regex EnabledNugetFeed();
public void Dispose()
{
PackageDirectory?.Dispose();
legacyPackageDirectory?.Dispose();
missingPackageDirectory?.Dispose();
emptyPackageDirectory?.Dispose();
feedManager.Dispose();
}
/// <summary>

View File

@@ -40,7 +40,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
return new NugetExeWrapper(fileProvider, packageDirectory, logger, useDefaultFeed);
}
return new NoOpPackagesConfig(fileProvider, logger);
return new NoOpPackagesConfig(fileProvider.PackagesConfigs, logger);
}
/// <summary>
@@ -302,7 +302,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private void AddDefaultPackageSource(string nugetConfig)
{
logger.LogInfo("Adding default package source...");
RunMonoNugetCommand($"sources add -Name DefaultNugetOrg -Source {NugetPackageRestorer.PublicNugetOrgFeed} -ConfigFile \"{nugetConfig}\"", out _);
RunMonoNugetCommand($"sources add -Name DefaultNugetOrg -Source {FeedManager.PublicNugetOrgFeed} -ConfigFile \"{nugetConfig}\"", out _);
}
public void Dispose()
@@ -343,15 +343,15 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private class NoOpPackagesConfig : IPackagesConfigRestore
{
private readonly Semmle.Util.Logging.ILogger logger;
private readonly FileProvider fileProvider;
private readonly ICollection<string> packagesConfigs;
public NoOpPackagesConfig(FileProvider fileProvider, Semmle.Util.Logging.ILogger logger)
public NoOpPackagesConfig(ICollection<string> packagesConfigs, Semmle.Util.Logging.ILogger logger)
{
this.fileProvider = fileProvider;
this.packagesConfigs = packagesConfigs;
this.logger = logger;
}
public int PackageCount => fileProvider.PackagesConfigs.Count;
public int PackageCount => packagesConfigs.Count;
public int InstallPackages()
{

View File

@@ -25,7 +25,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
{
var type = Type.Create(Context, Context.GetType(Stmt.Declaration!.Type));
trapFile.catch_type(this, type.TypeRef, true);
TypeMention.Create(Context, Stmt.Declaration!.Type, this, type);
Expression.Create(Context, Stmt.Declaration!.Type, this, 0);
}
else // A catch clause of the form 'catch { ... }'
{

View File

@@ -1,3 +1,7 @@
## 1.7.69
No user-facing changes.
## 1.7.68
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.7.69
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.7.68
lastReleaseVersion: 1.7.69

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all
version: 1.7.69-dev
version: 1.7.69
groups:
- csharp
- solorigate

View File

@@ -1,3 +1,7 @@
## 1.7.69
No user-facing changes.
## 1.7.68
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.7.69
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.7.68
lastReleaseVersion: 1.7.69

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries
version: 1.7.69-dev
version: 1.7.69
groups:
- csharp
- solorigate

View File

@@ -1,3 +1,19 @@
## 7.0.0
### Breaking Changes
* Renamed types related to *operation* expressions. The QL classes `BinaryArithmeticOperation`, `BinaryBitwiseOperation`, and `BinaryLogicalOperation` now include compound assignments; for example, `BinaryArithmeticOperation` now includes `a += b`.
### Major Analysis Improvements
* Added Razor Page handler method parameters (e.g., `OnGet`, `OnPost`, `OnPostAsync`) as remote flow sources, enabling security queries such as `cs/sql-injection` to detect vulnerabilities in `PageModel` subclasses.
### Minor Analysis Improvements
* Improved property and indexer call target resolution for partially overridden properties and indexers.
* Improved extraction of range-access expressions on spans and strings (for example, `a[0..3]`). These expressions are now extracted as `Slice` (span) or `Substring` (string) calls.
* Improved call target resolution for ref-return properties and indexers.
## 6.0.2
### Minor Analysis Improvements

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Improved call target resolution for ref-return properties and indexers.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Improved extraction of range-access expressions on spans and strings (for example, `a[0..3]`). These expressions are now extracted as `Slice` (span) or `Substring` (string) calls.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Improved property and indexer call target resolution for partially overridden properties and indexers.

View File

@@ -1,4 +0,0 @@
---
category: majorAnalysis
---
* Added Razor Page handler method parameters (e.g., `OnGet`, `OnPost`, `OnPostAsync`) as remote flow sources, enabling security queries such as `cs/sql-injection` to detect vulnerabilities in `PageModel` subclasses.

View File

@@ -1,4 +0,0 @@
---
category: breaking
---
* Renamed types related to *operation* expressions. The QL classes `BinaryArithmeticOperation`, `BinaryBitwiseOperation`, and `BinaryLogicalOperation` now include compound assignments; for example, `BinaryArithmeticOperation` now includes `a += b`.

View File

@@ -0,0 +1,15 @@
## 7.0.0
### Breaking Changes
* Renamed types related to *operation* expressions. The QL classes `BinaryArithmeticOperation`, `BinaryBitwiseOperation`, and `BinaryLogicalOperation` now include compound assignments; for example, `BinaryArithmeticOperation` now includes `a += b`.
### Major Analysis Improvements
* Added Razor Page handler method parameters (e.g., `OnGet`, `OnPost`, `OnPostAsync`) as remote flow sources, enabling security queries such as `cs/sql-injection` to detect vulnerabilities in `PageModel` subclasses.
### Minor Analysis Improvements
* Improved property and indexer call target resolution for partially overridden properties and indexers.
* Improved extraction of range-access expressions on spans and strings (for example, `a[0..3]`). These expressions are now extracted as `Slice` (span) or `Substring` (string) calls.
* Improved call target resolution for ref-return properties and indexers.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 6.0.2
lastReleaseVersion: 7.0.0

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-all
version: 6.0.3-dev
version: 7.0.0
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp

View File

@@ -995,6 +995,23 @@ class SpecificCatchClause extends CatchClause {
/** Gets the local variable declaration of this catch clause, if any. */
LocalVariableDeclExpr getVariableDeclExpr() { result.getParent() = this }
/**
* Gets the type access of this catch clause, if it has no variable declaration.
*
* For example, the type access in
*
* ```csharp
* try { ... }
* catch (IOException) { ... }
* ```
*
* is `IOException`.
*/
TypeAccess getTypeAccess() {
not exists(this.getVariableDeclExpr()) and
result = this.getChild(0)
}
override string toString() { result = "catch (...) {...}" }
override string getAPrimaryQlClass() { result = "SpecificCatchClause" }

View File

@@ -75,7 +75,8 @@ module Ast implements AstSig<Location> {
additional predicate skipControlFlow(AstNode e) {
e instanceof TypeAccess and
not e instanceof TypeAccessPatternExpr
not e instanceof TypeAccessPatternExpr and
not any(CS::SpecificCatchClause sc).getTypeAccess() = e
or
not e.getFile().fromSource()
}
@@ -90,6 +91,7 @@ module Ast implements AstSig<Location> {
private AstNode getStmtChild0(Stmt s, int i) {
not s instanceof FixedStmt and
not s instanceof UsingBlockStmt and
not skipControlFlow(result) and
result = s.getChild(i)
or
s =
@@ -219,7 +221,12 @@ module Ast implements AstSig<Location> {
final private class FinalCatchClause = CS::CatchClause;
class CatchClause extends FinalCatchClause {
AstNode getVariable() { result = this.(CS::SpecificCatchClause).getVariableDeclExpr() }
AstNode getPattern() {
result = this.(CS::SpecificCatchClause).getVariableDeclExpr() or
result = this.(CS::SpecificCatchClause).getTypeAccess()
}
AstNode getVariable() { none() }
Expr getCondition() { result = this.getFilterClause() }

View File

@@ -1,3 +1,7 @@
## 1.7.5
No user-facing changes.
## 1.7.4
No user-facing changes.

View File

@@ -14,54 +14,6 @@
import csharp
/**
* Gets a callable that either directly captures local variable `v`, or which
* is enclosed by the callable that declares `v` and encloses a callable that
* captures `v`.
*/
Callable getACapturingCallableAncestor(LocalVariable v) {
result = v.getACapturingCallable()
or
exists(Callable mid | mid = getACapturingCallableAncestor(v) |
result = mid.getEnclosingCallable() and
not v.getEnclosingCallable() = result
)
}
Expr getADelegateExpr(Callable c) {
c = result.(CallableAccess).getTarget()
or
result = c.(AnonymousFunctionExpr)
}
/**
* Holds if `c` is a call where any delegate argument is evaluated immediately.
*/
predicate nonEscapingCall(Call c) {
exists(string name | c.getTarget().hasName(name) |
name =
[
"ForEach", "Count", "Any", "All", "Average", "Aggregate", "First", "Last", "FirstOrDefault",
"LastOrDefault", "LongCount", "Max", "Single", "SingleOrDefault", "Sum"
]
)
}
/**
* Holds if `v` is a captured local variable, and one of the callables capturing
* `v` may escape the local scope.
*/
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).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()
)
}
class RelevantDefinition extends AssignableDefinition {
RelevantDefinition() {
this.(AssignableDefinitions::AssignmentDefinition).getAssignment() =
@@ -94,8 +46,6 @@ class RelevantDefinition extends AssignableDefinition {
// SSA definitions are only created for live variables
this = any(SsaExplicitWrite ssaDef).getDefinition()
or
mayEscape(v)
or
v.isCaptured()
)
}

View File

@@ -0,0 +1,3 @@
## 1.7.5
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.7.4
lastReleaseVersion: 1.7.5

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-queries
version: 1.7.5-dev
version: 1.7.5
groups:
- csharp
- queries

View File

@@ -447,13 +447,13 @@
| ExitMethods.cs:20:10:20:11 | Entry | ExitMethods.cs:20:10:20:11 | Exit | 8 |
| ExitMethods.cs:26:10:26:11 | Entry | ExitMethods.cs:26:10:26:11 | Exit | 8 |
| ExitMethods.cs:32:10:32:11 | Entry | ExitMethods.cs:32:10:32:11 | Exit | 8 |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:44:9:47:9 | catch (...) {...} | 9 |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:44:16:44:32 | access to type ArgumentException | 10 |
| ExitMethods.cs:38:10:38:11 | Exit | ExitMethods.cs:38:10:38:11 | Exit | 1 |
| ExitMethods.cs:38:10:38:11 | Normal Exit | ExitMethods.cs:38:10:38:11 | Normal Exit | 1 |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] | ExitMethods.cs:46:13:46:19 | return ...; | 4 |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | ExitMethods.cs:48:9:51:9 | catch (...) {...} | 2 |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] | ExitMethods.cs:50:13:50:19 | return ...; | 4 |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] | ExitMethods.cs:38:10:38:11 | Exceptional Exit | 2 |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] | ExitMethods.cs:46:13:46:19 | return ...; | 4 |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] | ExitMethods.cs:48:16:48:24 | access to type Exception | 4 |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [match] | ExitMethods.cs:50:13:50:19 | return ...; | 4 |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] | ExitMethods.cs:38:10:38:11 | Exceptional Exit | 3 |
| ExitMethods.cs:54:10:54:11 | Entry | ExitMethods.cs:54:10:54:11 | Exit | 7 |
| ExitMethods.cs:60:10:60:11 | Entry | ExitMethods.cs:60:10:60:11 | Exit | 7 |
| ExitMethods.cs:66:17:66:26 | Entry | ExitMethods.cs:68:13:68:13 | access to parameter b | 5 |
@@ -508,13 +508,13 @@
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:19:10:19:11 | Normal Exit | 1 |
| Finally.cs:21:9:51:9 | After try {...} ... | Finally.cs:20:5:52:5 | After {...} | 2 |
| Finally.cs:23:13:23:37 | After call to method WriteLine | Finally.cs:24:13:24:19 | return ...; | 4 |
| Finally.cs:26:9:29:9 | After catch (...) {...} [match] | Finally.cs:28:13:28:18 | throw ...; | 7 |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:30:9:40:9 | catch (...) {...} | 2 |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:9:29:9 | catch (...) {...} | 1 |
| Finally.cs:30:9:40:9 | After catch (...) {...} [match] | Finally.cs:38:17:38:44 | throw ...; | 17 |
| Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | Finally.cs:41:9:43:9 | catch (...) {...} | 2 |
| Finally.cs:41:9:43:9 | After catch (...) {...} [match] | Finally.cs:42:9:43:9 | {...} | 2 |
| Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] | Finally.cs:46:13:46:19 | return ...; | 6 |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:38:26:39 | IOException ex | 2 |
| Finally.cs:26:38:26:39 | After IOException ex [match] | Finally.cs:28:13:28:18 | throw ...; | 6 |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:30:41:30:42 | ArgumentException ex | 4 |
| Finally.cs:30:41:30:42 | After ArgumentException ex [match] | Finally.cs:38:17:38:44 | throw ...; | 16 |
| Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] | Finally.cs:41:16:41:24 | access to type Exception | 4 |
| Finally.cs:41:16:41:24 | After access to type Exception [match] | Finally.cs:42:9:43:9 | {...} | 2 |
| Finally.cs:41:16:41:24 | After access to type Exception [no-match] | Finally.cs:46:13:46:19 | return ...; | 6 |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:49:9:51:9 | After {...} | 8 |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:58:13:58:37 | call to method WriteLine | 8 |
| Finally.cs:54:10:54:11 | Exceptional Exit | Finally.cs:54:10:54:11 | Exceptional Exit | 1 |
@@ -522,11 +522,12 @@
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:54:10:54:11 | Normal Exit | 1 |
| Finally.cs:56:9:71:9 | After try {...} ... | Finally.cs:55:5:72:5 | After {...} | 2 |
| Finally.cs:58:13:58:37 | After call to method WriteLine | Finally.cs:59:13:59:19 | return ...; | 4 |
| Finally.cs:61:9:64:9 | After catch (...) {...} [match] | Finally.cs:63:13:63:18 | throw ...; | 7 |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:65:9:67:9 | catch (...) {...} | 2 |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:9:64:9 | catch (...) {...} | 1 |
| Finally.cs:65:9:67:9 | After catch (...) {...} [match] | Finally.cs:65:35:65:51 | ... != ... | 9 |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:38:61:39 | IOException ex | 2 |
| Finally.cs:61:38:61:39 | After IOException ex [match] | Finally.cs:63:13:63:18 | throw ...; | 6 |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:65:26:65:26 | Exception e | 4 |
| Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] | Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] | 1 |
| Finally.cs:65:26:65:26 | After Exception e [match] | Finally.cs:65:35:65:51 | ... != ... | 8 |
| Finally.cs:65:26:65:26 | After Exception e [no-match] | Finally.cs:65:26:65:26 | After Exception e [no-match] | 1 |
| Finally.cs:65:35:65:51 | After ... != ... [false] | Finally.cs:65:35:65:51 | After ... != ... [false] | 1 |
| Finally.cs:65:35:65:51 | After ... != ... [true] | Finally.cs:66:9:67:9 | {...} | 2 |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:69:9:71:9 | After {...} | 8 |
@@ -589,9 +590,10 @@
| Finally.cs:158:21:158:36 | After ... == ... [false] | Finally.cs:157:13:160:13 | After {...} | 3 |
| Finally.cs:158:21:158:36 | After ... == ... [true] | Finally.cs:159:27:159:44 | object creation of type Exception | 5 |
| Finally.cs:159:27:159:44 | After object creation of type Exception | Finally.cs:159:21:159:45 | throw ...; | 2 |
| Finally.cs:161:13:164:13 | After catch (...) {...} [match] | Finally.cs:161:39:161:54 | ... == ... | 9 |
| Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] | Finally.cs:166:13:168:13 | After {...} | 11 |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:13:164:13 | catch (...) {...} | 1 |
| Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] | Finally.cs:166:13:168:13 | After {...} | 10 |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:30:161:30 | Exception e | 2 |
| Finally.cs:161:30:161:30 | After Exception e [match] | Finally.cs:161:39:161:54 | ... == ... | 8 |
| Finally.cs:161:30:161:30 | After Exception e [no-match] | Finally.cs:161:30:161:30 | After Exception e [no-match] | 1 |
| Finally.cs:161:39:161:54 | After ... == ... [false] | Finally.cs:161:39:161:54 | After ... == ... [false] | 1 |
| Finally.cs:161:39:161:54 | After ... == ... [true] | Finally.cs:162:13:164:13 | After {...} | 13 |
| Finally.cs:172:11:172:20 | Entry | Finally.cs:172:11:172:20 | Exit | 11 |
@@ -609,9 +611,10 @@
| Finally.cs:186:21:186:22 | After access to parameter b2 [false] | Finally.cs:185:13:187:13 | After {...} | 3 |
| Finally.cs:186:21:186:22 | After access to parameter b2 [true] | Finally.cs:186:31:186:46 | object creation of type ExceptionB | 4 |
| Finally.cs:186:31:186:46 | After object creation of type ExceptionB | Finally.cs:186:25:186:47 | throw ...; | 2 |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:188:38:188:39 | access to parameter b2 | 2 |
| Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] | Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] | 1 |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | catch (...) {...} | 1 |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:20:188:29 | access to type ExceptionB | 2 |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:188:38:188:39 | access to parameter b2 | 2 |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] | Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] | 1 |
| Finally.cs:188:38:188:39 | After access to parameter b2 [false] | Finally.cs:188:38:188:39 | After access to parameter b2 [false] | 1 |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:190:21:190:22 | access to parameter b1 | 4 |
| Finally.cs:190:21:190:22 | After access to parameter b1 [false] | Finally.cs:189:13:191:13 | After {...} | 3 |
@@ -633,7 +636,7 @@
| Finally.cs:209:21:209:22 | After access to parameter b3 [true] | Finally.cs:209:25:209:47 | throw ...; | 6 |
| Finally.cs:216:10:216:12 | Entry | Finally.cs:220:13:220:36 | call to method WriteLine | 8 |
| Finally.cs:220:13:220:36 | After call to method WriteLine | Finally.cs:219:9:221:9 | After {...} | 3 |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:223:9:225:9 | After {...} | 10 |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:223:9:225:9 | After {...} | 9 |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:216:10:216:12 | Exit | 18 |
| Finally.cs:233:10:233:12 | Entry | Finally.cs:239:21:239:22 | access to parameter b1 | 10 |
| Finally.cs:233:10:233:12 | Exceptional Exit | Finally.cs:233:10:233:12 | Exceptional Exit | 1 |

View File

@@ -264,12 +264,12 @@ conditionBlock
| DefaultParam.cs:3:12:3:13 | Entry | DefaultParam.cs:3:30:3:30 | After s [no-match] | false |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:3:42:3:42 | After i [match] | true |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:3:42:3:42 | After i [no-match] | false |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] | true |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | false |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] | false |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] | false |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] | true |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] | false |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] | true |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] | false |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:48:16:48:24 | After access to type Exception [match] | false |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] | false |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] | ExitMethods.cs:48:16:48:24 | After access to type Exception [match] | true |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] | ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] | false |
| ExitMethods.cs:66:17:66:26 | Entry | ExitMethods.cs:68:13:68:13 | After access to parameter b [false] | false |
| ExitMethods.cs:66:17:66:26 | Entry | ExitMethods.cs:68:13:68:13 | After access to parameter b [true] | true |
| ExitMethods.cs:72:17:72:27 | Entry | ExitMethods.cs:74:13:74:13 | After access to parameter b [false] | false |
@@ -280,29 +280,31 @@ conditionBlock
| ExitMethods.cs:115:16:115:34 | Entry | ExitMethods.cs:117:16:117:30 | After call to method Contains [true] | true |
| ExitMethods.cs:140:17:140:42 | Entry | ExitMethods.cs:142:13:142:13 | After access to parameter b [false] | false |
| ExitMethods.cs:140:17:140:42 | Entry | ExitMethods.cs:142:13:142:13 | After access to parameter b [true] | true |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:30:9:40:9 | After catch (...) {...} [match] | true |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | false |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:41:9:43:9 | After catch (...) {...} [match] | false |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] | false |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:9:29:9 | After catch (...) {...} [match] | true |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | false |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:30:9:40:9 | After catch (...) {...} [match] | false |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | false |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:41:9:43:9 | After catch (...) {...} [match] | false |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] | false |
| Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | Finally.cs:41:9:43:9 | After catch (...) {...} [match] | true |
| Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] | false |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:65:9:67:9 | After catch (...) {...} [match] | true |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:65:35:65:51 | After ... != ... [false] | true |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:65:35:65:51 | After ... != ... [true] | true |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:9:64:9 | After catch (...) {...} [match] | true |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | false |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:65:9:67:9 | After catch (...) {...} [match] | false |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:38:26:39 | After IOException ex [match] | true |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:38:26:39 | After IOException ex [no-match] | false |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:30:41:30:42 | After ArgumentException ex [match] | false |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] | false |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:41:16:41:24 | After access to type Exception [match] | false |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:41:16:41:24 | After access to type Exception [no-match] | false |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:30:41:30:42 | After ArgumentException ex [match] | true |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] | false |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:41:16:41:24 | After access to type Exception [match] | false |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:41:16:41:24 | After access to type Exception [no-match] | false |
| Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] | Finally.cs:41:16:41:24 | After access to type Exception [match] | true |
| Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] | Finally.cs:41:16:41:24 | After access to type Exception [no-match] | false |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:38:61:39 | After IOException ex [match] | true |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:38:61:39 | After IOException ex [no-match] | false |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] | false |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:65:26:65:26 | After Exception e [match] | false |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:65:26:65:26 | After Exception e [no-match] | false |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:65:35:65:51 | After ... != ... [false] | false |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:65:35:65:51 | After ... != ... [true] | false |
| Finally.cs:65:9:67:9 | After catch (...) {...} [match] | Finally.cs:65:35:65:51 | After ... != ... [false] | false |
| Finally.cs:65:9:67:9 | After catch (...) {...} [match] | Finally.cs:65:35:65:51 | After ... != ... [true] | true |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:65:26:65:26 | After Exception e [match] | true |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:65:26:65:26 | After Exception e [no-match] | false |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:65:35:65:51 | After ... != ... [false] | true |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:65:35:65:51 | After ... != ... [true] | true |
| Finally.cs:65:26:65:26 | After Exception e [match] | Finally.cs:65:35:65:51 | After ... != ... [false] | false |
| Finally.cs:65:26:65:26 | After Exception e [match] | Finally.cs:65:35:65:51 | After ... != ... [true] | true |
| Finally.cs:77:9:100:9 | [LoopHeader] while (...) ... | Finally.cs:74:10:74:11 | Exceptional Exit | true |
| Finally.cs:77:9:100:9 | [LoopHeader] while (...) ... | Finally.cs:77:16:77:20 | After ... > ... [false] | false |
| Finally.cs:77:9:100:9 | [LoopHeader] while (...) ... | Finally.cs:77:16:77:20 | After ... > ... [true] | true |
@@ -354,33 +356,36 @@ conditionBlock
| Finally.cs:158:21:158:31 | After access to property Length | Finally.cs:158:21:158:36 | After ... == ... [false] | false |
| Finally.cs:158:21:158:31 | After access to property Length | Finally.cs:158:21:158:36 | After ... == ... [true] | true |
| Finally.cs:158:21:158:31 | After access to property Length | Finally.cs:159:27:159:44 | After object creation of type Exception | true |
| Finally.cs:161:13:164:13 | After catch (...) {...} [match] | Finally.cs:161:39:161:54 | After ... == ... [false] | false |
| Finally.cs:161:13:164:13 | After catch (...) {...} [match] | Finally.cs:161:39:161:54 | After ... == ... [true] | true |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:13:164:13 | After catch (...) {...} [match] | true |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:30:161:30 | After Exception e [match] | true |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:30:161:30 | After Exception e [no-match] | false |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:39:161:54 | After ... == ... [false] | true |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:39:161:54 | After ... == ... [true] | true |
| Finally.cs:161:30:161:30 | After Exception e [match] | Finally.cs:161:39:161:54 | After ... == ... [false] | false |
| Finally.cs:161:30:161:30 | After Exception e [match] | Finally.cs:161:39:161:54 | After ... == ... [true] | true |
| Finally.cs:176:10:176:11 | Entry | Finally.cs:180:17:180:18 | After access to parameter b1 [false] | false |
| Finally.cs:176:10:176:11 | Entry | Finally.cs:180:17:180:18 | After access to parameter b1 [true] | true |
| Finally.cs:176:10:176:11 | Entry | Finally.cs:180:27:180:42 | After object creation of type ExceptionA | true |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:186:21:186:22 | After access to parameter b2 [false] | false |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:186:21:186:22 | After access to parameter b2 [true] | true |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:186:31:186:46 | After object creation of type ExceptionB | true |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:13:191:13 | After catch (...) {...} [match] | true |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] | true |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:13:191:13 | catch (...) {...} | true |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | true |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] | true |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:38:188:39 | After access to parameter b2 [false] | true |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:38:188:39 | After access to parameter b2 [true] | true |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:190:21:190:22 | After access to parameter b1 [false] | true |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:190:21:190:22 | After access to parameter b1 [true] | true |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:188:38:188:39 | After access to parameter b2 [false] | false |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:188:38:188:39 | After access to parameter b2 [true] | true |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:190:21:190:22 | After access to parameter b1 [false] | true |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:190:21:190:22 | After access to parameter b1 [true] | true |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | After catch (...) {...} [match] | true |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | true |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] | false |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:38:188:39 | After access to parameter b2 [false] | true |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:38:188:39 | After access to parameter b2 [true] | true |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:190:21:190:22 | After access to parameter b1 [false] | true |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:190:21:190:22 | After access to parameter b1 [true] | true |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:188:38:188:39 | After access to parameter b2 [false] | false |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:188:38:188:39 | After access to parameter b2 [true] | true |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:190:21:190:22 | After access to parameter b1 [false] | true |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:190:21:190:22 | After access to parameter b1 [true] | true |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:190:21:190:22 | After access to parameter b1 [false] | false |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:190:21:190:22 | After access to parameter b1 [true] | true |
| Finally.cs:195:10:195:12 | Entry | Finally.cs:199:17:199:18 | After access to parameter b1 [false] | false |

View File

@@ -2816,16 +2816,20 @@ dominance
| ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | ExitMethods.cs:44:9:47:9 | catch (...) {...} |
| ExitMethods.cs:42:13:42:31 | ...; | ExitMethods.cs:42:13:42:30 | Before call to method ErrorAlways |
| ExitMethods.cs:42:25:42:29 | false | ExitMethods.cs:42:13:42:30 | call to method ErrorAlways |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] | ExitMethods.cs:45:9:47:9 | {...} |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | ExitMethods.cs:48:9:51:9 | catch (...) {...} |
| ExitMethods.cs:44:9:47:9 | catch (...) {...} | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] |
| ExitMethods.cs:44:9:47:9 | catch (...) {...} | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] |
| ExitMethods.cs:44:9:47:9 | catch (...) {...} | ExitMethods.cs:44:16:44:32 | access to type ArgumentException |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] | ExitMethods.cs:45:9:47:9 | {...} |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] |
| ExitMethods.cs:44:16:44:32 | access to type ArgumentException | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] |
| ExitMethods.cs:44:16:44:32 | access to type ArgumentException | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] |
| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:46:13:46:19 | Before return ...; |
| ExitMethods.cs:46:13:46:19 | Before return ...; | ExitMethods.cs:46:13:46:19 | return ...; |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] | ExitMethods.cs:49:9:51:9 | {...} |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] | ExitMethods.cs:38:10:38:11 | Exceptional Exit |
| ExitMethods.cs:48:9:51:9 | catch (...) {...} | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] |
| ExitMethods.cs:48:9:51:9 | catch (...) {...} | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] |
| ExitMethods.cs:48:9:51:9 | catch (...) {...} | ExitMethods.cs:48:16:48:24 | access to type Exception |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [match] | ExitMethods.cs:49:9:51:9 | {...} |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] |
| ExitMethods.cs:48:16:48:24 | access to type Exception | ExitMethods.cs:48:16:48:24 | After access to type Exception [match] |
| ExitMethods.cs:48:16:48:24 | access to type Exception | ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] |
| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:50:13:50:19 | Before return ...; |
| ExitMethods.cs:50:13:50:19 | Before return ...; | ExitMethods.cs:50:13:50:19 | return ...; |
| ExitMethods.cs:54:10:54:11 | Entry | ExitMethods.cs:55:5:58:5 | {...} |
@@ -3124,20 +3128,22 @@ dominance
| Finally.cs:23:13:23:38 | After ...; | Finally.cs:24:13:24:19 | Before return ...; |
| Finally.cs:23:31:23:36 | "Try2" | Finally.cs:23:13:23:37 | call to method WriteLine |
| Finally.cs:24:13:24:19 | Before return ...; | Finally.cs:24:13:24:19 | return ...; |
| Finally.cs:26:9:29:9 | After catch (...) {...} [match] | Finally.cs:26:38:26:39 | IOException ex |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:30:9:40:9 | catch (...) {...} |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:9:29:9 | After catch (...) {...} [match] |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] |
| Finally.cs:26:38:26:39 | IOException ex | Finally.cs:26:48:26:51 | true |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:38:26:39 | IOException ex |
| Finally.cs:26:38:26:39 | After IOException ex [match] | Finally.cs:26:48:26:51 | true |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] |
| Finally.cs:26:38:26:39 | IOException ex | Finally.cs:26:38:26:39 | After IOException ex [match] |
| Finally.cs:26:38:26:39 | IOException ex | Finally.cs:26:38:26:39 | After IOException ex [no-match] |
| Finally.cs:26:48:26:51 | After true [true] | Finally.cs:27:9:29:9 | {...} |
| Finally.cs:26:48:26:51 | true | Finally.cs:26:48:26:51 | After true [true] |
| Finally.cs:27:9:29:9 | {...} | Finally.cs:28:13:28:18 | Before throw ...; |
| Finally.cs:28:13:28:18 | Before throw ...; | Finally.cs:28:13:28:18 | throw ...; |
| Finally.cs:30:9:40:9 | After catch (...) {...} [match] | Finally.cs:30:41:30:42 | ArgumentException ex |
| Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | Finally.cs:41:9:43:9 | catch (...) {...} |
| Finally.cs:30:9:40:9 | catch (...) {...} | Finally.cs:30:9:40:9 | After catch (...) {...} [match] |
| Finally.cs:30:9:40:9 | catch (...) {...} | Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] |
| Finally.cs:30:41:30:42 | ArgumentException ex | Finally.cs:31:9:40:9 | {...} |
| Finally.cs:30:9:40:9 | catch (...) {...} | Finally.cs:30:41:30:42 | ArgumentException ex |
| Finally.cs:30:41:30:42 | After ArgumentException ex [match] | Finally.cs:31:9:40:9 | {...} |
| Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] | Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] |
| Finally.cs:30:41:30:42 | ArgumentException ex | Finally.cs:30:41:30:42 | After ArgumentException ex [match] |
| Finally.cs:30:41:30:42 | ArgumentException ex | Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] |
| 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 | {...} |
| Finally.cs:33:13:35:13 | {...} | Finally.cs:34:17:34:32 | if (...) ... |
@@ -3152,12 +3158,13 @@ dominance
| Finally.cs:38:23:38:43 | Before object creation of type Exception | Finally.cs:38:37:38:42 | "Boo!" |
| Finally.cs:38:23:38:43 | object creation of type Exception | Finally.cs:38:23:38:43 | After object creation of type Exception |
| Finally.cs:38:37:38:42 | "Boo!" | Finally.cs:38:23:38:43 | object creation of type Exception |
| Finally.cs:41:9:43:9 | After catch (...) {...} [match] | Finally.cs:42:9:43:9 | {...} |
| Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] | Finally.cs:44:9:47:9 | catch {...} |
| Finally.cs:41:9:43:9 | catch (...) {...} | Finally.cs:41:9:43:9 | After catch (...) {...} [match] |
| Finally.cs:41:9:43:9 | catch (...) {...} | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] |
| Finally.cs:44:9:47:9 | After catch {...} [match] | Finally.cs:45:9:47:9 | {...} |
| Finally.cs:44:9:47:9 | catch {...} | Finally.cs:44:9:47:9 | After catch {...} [match] |
| Finally.cs:41:9:43:9 | catch (...) {...} | Finally.cs:41:16:41:24 | access to type Exception |
| Finally.cs:41:16:41:24 | After access to type Exception [match] | Finally.cs:42:9:43:9 | {...} |
| Finally.cs:41:16:41:24 | After access to type Exception [no-match] | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] |
| Finally.cs:41:16:41:24 | access to type Exception | Finally.cs:41:16:41:24 | After access to type Exception [match] |
| Finally.cs:41:16:41:24 | access to type Exception | Finally.cs:41:16:41:24 | After access to type Exception [no-match] |
| Finally.cs:44:9:47:9 | catch {...} | Finally.cs:45:9:47:9 | {...} |
| Finally.cs:45:9:47:9 | {...} | Finally.cs:46:13:46:19 | Before return ...; |
| Finally.cs:46:13:46:19 | Before return ...; | Finally.cs:46:13:46:19 | return ...; |
| Finally.cs:49:9:51:9 | After {...} | Finally.cs:19:10:19:11 | Exceptional Exit |
@@ -3183,19 +3190,20 @@ dominance
| Finally.cs:58:13:58:38 | After ...; | Finally.cs:59:13:59:19 | Before return ...; |
| Finally.cs:58:31:58:36 | "Try3" | Finally.cs:58:13:58:37 | call to method WriteLine |
| Finally.cs:59:13:59:19 | Before return ...; | Finally.cs:59:13:59:19 | return ...; |
| Finally.cs:61:9:64:9 | After catch (...) {...} [match] | Finally.cs:61:38:61:39 | IOException ex |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:65:9:67:9 | catch (...) {...} |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:9:64:9 | After catch (...) {...} [match] |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] |
| Finally.cs:61:38:61:39 | IOException ex | Finally.cs:61:48:61:51 | true |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:38:61:39 | IOException ex |
| Finally.cs:61:38:61:39 | After IOException ex [match] | Finally.cs:61:48:61:51 | true |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] |
| Finally.cs:61:38:61:39 | IOException ex | Finally.cs:61:38:61:39 | After IOException ex [match] |
| Finally.cs:61:38:61:39 | IOException ex | Finally.cs:61:38:61:39 | After IOException ex [no-match] |
| Finally.cs:61:48:61:51 | After true [true] | Finally.cs:62:9:64:9 | {...} |
| Finally.cs:61:48:61:51 | true | Finally.cs:61:48:61:51 | After true [true] |
| Finally.cs:62:9:64:9 | {...} | Finally.cs:63:13:63:18 | Before throw ...; |
| Finally.cs:63:13:63:18 | Before throw ...; | Finally.cs:63:13:63:18 | throw ...; |
| Finally.cs:65:9:67:9 | After catch (...) {...} [match] | Finally.cs:65:26:65:26 | Exception e |
| Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:65:9:67:9 | After catch (...) {...} [match] |
| Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] |
| Finally.cs:65:26:65:26 | Exception e | Finally.cs:65:35:65:51 | Before ... != ... |
| Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:65:26:65:26 | Exception e |
| Finally.cs:65:26:65:26 | After Exception e [match] | Finally.cs:65:35:65:51 | Before ... != ... |
| Finally.cs:65:26:65:26 | Exception e | Finally.cs:65:26:65:26 | After Exception e [match] |
| Finally.cs:65:26:65:26 | Exception e | Finally.cs:65:26:65:26 | After Exception e [no-match] |
| Finally.cs:65:35:65:35 | access to local variable e | Finally.cs:65:35:65:43 | access to property Message |
| Finally.cs:65:35:65:43 | After access to property Message | Finally.cs:65:48:65:51 | null |
| Finally.cs:65:35:65:43 | Before access to property Message | Finally.cs:65:35:65:35 | access to local variable e |
@@ -3468,11 +3476,11 @@ dominance
| Finally.cs:159:27:159:44 | Before object creation of type Exception | Finally.cs:159:41:159:43 | "1" |
| Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:159:27:159:44 | After object creation of type Exception |
| Finally.cs:159:41:159:43 | "1" | Finally.cs:159:27:159:44 | object creation of type Exception |
| Finally.cs:161:13:164:13 | After catch (...) {...} [match] | Finally.cs:161:30:161:30 | Exception e |
| Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] | Finally.cs:165:13:168:13 | catch {...} |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:13:164:13 | After catch (...) {...} [match] |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] |
| Finally.cs:161:30:161:30 | Exception e | Finally.cs:161:39:161:54 | Before ... == ... |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:30:161:30 | Exception e |
| Finally.cs:161:30:161:30 | After Exception e [match] | Finally.cs:161:39:161:54 | Before ... == ... |
| Finally.cs:161:30:161:30 | Exception e | Finally.cs:161:30:161:30 | After Exception e [match] |
| Finally.cs:161:30:161:30 | Exception e | Finally.cs:161:30:161:30 | After Exception e [no-match] |
| Finally.cs:161:39:161:39 | access to local variable e | Finally.cs:161:39:161:47 | access to property Message |
| Finally.cs:161:39:161:47 | After access to property Message | Finally.cs:161:52:161:54 | "1" |
| Finally.cs:161:39:161:47 | Before access to property Message | Finally.cs:161:39:161:39 | access to local variable e |
@@ -3493,8 +3501,7 @@ dominance
| Finally.cs:163:35:163:41 | Before access to array element | Finally.cs:163:35:163:38 | access to parameter args |
| Finally.cs:163:35:163:41 | access to array element | Finally.cs:163:35:163:41 | After access to array element |
| Finally.cs:163:40:163:40 | 0 | Finally.cs:163:35:163:41 | access to array element |
| Finally.cs:165:13:168:13 | After catch {...} [match] | Finally.cs:166:13:168:13 | {...} |
| Finally.cs:165:13:168:13 | catch {...} | Finally.cs:165:13:168:13 | After catch {...} [match] |
| Finally.cs:165:13:168:13 | catch {...} | Finally.cs:166:13:168:13 | {...} |
| Finally.cs:166:13:168:13 | {...} | Finally.cs:167:17:167:38 | ...; |
| Finally.cs:167:17:167:37 | After call to method WriteLine | Finally.cs:167:17:167:38 | After ...; |
| Finally.cs:167:17:167:37 | Before call to method WriteLine | Finally.cs:167:35:167:36 | "" |
@@ -3566,9 +3573,10 @@ dominance
| Finally.cs:186:31:186:46 | Before object creation of type ExceptionB | Finally.cs:186:31:186:46 | object creation of type ExceptionB |
| Finally.cs:186:31:186:46 | object creation of type ExceptionB | Finally.cs:186:31:186:46 | After object creation of type ExceptionB |
| Finally.cs:186:31:186:46 | object creation of type ExceptionB | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:188:38:188:39 | access to parameter b2 |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | After catch (...) {...} [match] |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:20:188:29 | access to type ExceptionB |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:188:38:188:39 | access to parameter b2 |
| Finally.cs:188:20:188:29 | access to type ExceptionB | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] |
| Finally.cs:188:20:188:29 | access to type ExceptionB | Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:189:13:191:13 | {...} |
| Finally.cs:188:38:188:39 | access to parameter b2 | Finally.cs:188:38:188:39 | After access to parameter b2 [false] |
| Finally.cs:188:38:188:39 | access to parameter b2 | Finally.cs:188:38:188:39 | After access to parameter b2 [true] |
@@ -3663,8 +3671,7 @@ dominance
| Finally.cs:220:13:220:37 | ...; | Finally.cs:220:13:220:36 | Before call to method WriteLine |
| Finally.cs:220:13:220:37 | After ...; | Finally.cs:219:9:221:9 | After {...} |
| Finally.cs:220:31:220:35 | "Try" | Finally.cs:220:13:220:36 | call to method WriteLine |
| Finally.cs:222:9:225:9 | After catch {...} [match] | Finally.cs:223:9:225:9 | {...} |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:222:9:225:9 | After catch {...} [match] |
| 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:38 | After call to method WriteLine | Finally.cs:224:13:224:39 | After ...; |
| Finally.cs:224:13:224:38 | Before call to method WriteLine | Finally.cs:224:31:224:37 | "Catch" |
@@ -10615,13 +10622,17 @@ postDominance
| 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:30 | Before call to method ErrorAlways |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] |
| ExitMethods.cs:44:9:47:9 | catch (...) {...} | ExitMethods.cs:42:13:42:30 | call to method ErrorAlways |
| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] |
| ExitMethods.cs:44:16:44:32 | access to type ArgumentException | ExitMethods.cs:44:9:47:9 | catch (...) {...} |
| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] |
| ExitMethods.cs:46:13:46:19 | Before return ...; | ExitMethods.cs:45:9:47:9 | {...} |
| ExitMethods.cs:46:13:46:19 | return ...; | ExitMethods.cs:46:13:46:19 | Before return ...; |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] | ExitMethods.cs:48:9:51:9 | catch (...) {...} |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] | ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] |
| ExitMethods.cs:48:9:51:9 | catch (...) {...} | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] |
| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [match] | ExitMethods.cs:48:16:48:24 | access to type Exception |
| ExitMethods.cs:48:16:48:24 | access to type Exception | ExitMethods.cs:48:9:51:9 | catch (...) {...} |
| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:48:16:48:24 | After access to type Exception [match] |
| ExitMethods.cs:50:13:50:19 | Before return ...; | ExitMethods.cs:49:9:51:9 | {...} |
| ExitMethods.cs:50:13:50:19 | return ...; | ExitMethods.cs:50:13:50:19 | Before return ...; |
| ExitMethods.cs:54:10:54:11 | Exceptional Exit | ExitMethods.cs:56:9:56:22 | call to method ErrorAlways2 |
@@ -10911,15 +10922,17 @@ postDominance
| Finally.cs:23:31:23:36 | "Try2" | Finally.cs:23:13:23:37 | Before call to method WriteLine |
| Finally.cs:24:13:24:19 | Before return ...; | Finally.cs:23:13:23:38 | After ...; |
| Finally.cs:24:13:24:19 | return ...; | Finally.cs:24:13:24:19 | Before return ...; |
| Finally.cs:26:38:26:39 | IOException ex | Finally.cs:26:9:29:9 | After catch (...) {...} [match] |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:26:38:26:39 | After IOException ex [no-match] |
| Finally.cs:26:38:26:39 | IOException ex | Finally.cs:26:9:29:9 | catch (...) {...} |
| Finally.cs:26:48:26:51 | After true [true] | Finally.cs:26:48:26:51 | true |
| Finally.cs:26:48:26:51 | true | Finally.cs:26:38:26:39 | IOException ex |
| Finally.cs:26:48:26:51 | true | Finally.cs:26:38:26:39 | After IOException ex [match] |
| Finally.cs:27:9:29:9 | {...} | Finally.cs:26:48:26:51 | After true [true] |
| Finally.cs:28:13:28:18 | Before throw ...; | Finally.cs:27:9:29:9 | {...} |
| Finally.cs:28:13:28:18 | throw ...; | Finally.cs:28:13:28:18 | Before throw ...; |
| Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] |
| Finally.cs:30:9:40:9 | catch (...) {...} | Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] |
| Finally.cs:30:41:30:42 | ArgumentException ex | Finally.cs:30:9:40:9 | After catch (...) {...} [match] |
| Finally.cs:31:9:40:9 | {...} | Finally.cs:30:41:30:42 | ArgumentException ex |
| Finally.cs:30:41:30:42 | ArgumentException ex | Finally.cs:30:9:40:9 | catch (...) {...} |
| Finally.cs:31:9:40:9 | {...} | Finally.cs:30:41:30:42 | After ArgumentException ex [match] |
| 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 {...} ... |
| Finally.cs:34:17:34:32 | if (...) ... | Finally.cs:33:13:35:13 | {...} |
@@ -10934,11 +10947,12 @@ postDominance
| Finally.cs:38:23:38:43 | Before object creation of type Exception | Finally.cs:38:17:38:44 | Before throw ...; |
| Finally.cs:38:23:38:43 | object creation of type Exception | Finally.cs:38:37:38:42 | "Boo!" |
| Finally.cs:38:37:38:42 | "Boo!" | Finally.cs:38:23:38:43 | Before object creation of type Exception |
| Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] | Finally.cs:41:16:41:24 | After access to type Exception [no-match] |
| Finally.cs:41:9:43:9 | catch (...) {...} | Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] |
| Finally.cs:42:9:43:9 | {...} | Finally.cs:41:9:43:9 | After catch (...) {...} [match] |
| Finally.cs:44:9:47:9 | After catch {...} [match] | Finally.cs:44:9:47:9 | catch {...} |
| Finally.cs:41:16:41:24 | access to type Exception | Finally.cs:41:9:43:9 | catch (...) {...} |
| Finally.cs:42:9:43:9 | {...} | Finally.cs:41:16:41:24 | After access to type Exception [match] |
| Finally.cs:44:9:47:9 | catch {...} | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] |
| Finally.cs:45:9:47:9 | {...} | Finally.cs:44:9:47:9 | After catch {...} [match] |
| Finally.cs:45:9:47:9 | {...} | Finally.cs:44:9:47:9 | catch {...} |
| Finally.cs:46:13:46:19 | Before return ...; | Finally.cs:45:9:47:9 | {...} |
| Finally.cs:46:13:46:19 | return ...; | Finally.cs:46:13:46:19 | Before return ...; |
| Finally.cs:49:9:51:9 | After {...} | Finally.cs:50:13:50:41 | After ...; |
@@ -10966,21 +10980,23 @@ postDominance
| Finally.cs:58:31:58:36 | "Try3" | Finally.cs:58:13:58:37 | Before call to method WriteLine |
| Finally.cs:59:13:59:19 | Before return ...; | Finally.cs:58:13:58:38 | After ...; |
| Finally.cs:59:13:59:19 | return ...; | Finally.cs:59:13:59:19 | Before return ...; |
| Finally.cs:61:38:61:39 | IOException ex | Finally.cs:61:9:64:9 | After catch (...) {...} [match] |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:61:38:61:39 | After IOException ex [no-match] |
| Finally.cs:61:38:61:39 | IOException ex | Finally.cs:61:9:64:9 | catch (...) {...} |
| Finally.cs:61:48:61:51 | After true [true] | Finally.cs:61:48:61:51 | true |
| Finally.cs:61:48:61:51 | true | Finally.cs:61:38:61:39 | IOException ex |
| Finally.cs:61:48:61:51 | true | Finally.cs:61:38:61:39 | After IOException ex [match] |
| Finally.cs:62:9:64:9 | {...} | Finally.cs:61:48:61:51 | After true [true] |
| Finally.cs:63:13:63:18 | Before throw ...; | Finally.cs:62:9:64:9 | {...} |
| Finally.cs:63:13:63:18 | throw ...; | Finally.cs:63:13:63:18 | Before throw ...; |
| Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] | Finally.cs:65:26:65:26 | After Exception e [no-match] |
| Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] | Finally.cs:65:35:65:51 | After ... != ... [false] |
| Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] |
| Finally.cs:65:26:65:26 | Exception e | Finally.cs:65:9:67:9 | After catch (...) {...} [match] |
| Finally.cs:65:26:65:26 | Exception e | Finally.cs:65:9:67:9 | catch (...) {...} |
| Finally.cs:65:35:65:35 | access to local variable e | Finally.cs:65:35:65:43 | Before access to property Message |
| Finally.cs:65:35:65:43 | After access to property Message | Finally.cs:65:35:65:43 | access to property Message |
| Finally.cs:65:35:65:43 | Before access to property Message | Finally.cs:65:35:65:51 | Before ... != ... |
| Finally.cs:65:35:65:43 | access to property Message | Finally.cs:65:35:65:35 | access to local variable e |
| Finally.cs:65:35:65:51 | ... != ... | Finally.cs:65:48:65:51 | null |
| Finally.cs:65:35:65:51 | Before ... != ... | Finally.cs:65:26:65:26 | Exception e |
| Finally.cs:65:35:65:51 | Before ... != ... | Finally.cs:65:26:65:26 | After Exception e [match] |
| Finally.cs:65:48:65:51 | null | Finally.cs:65:35:65:43 | After access to property Message |
| Finally.cs:66:9:67:9 | {...} | Finally.cs:65:35:65:51 | After ... != ... [true] |
| Finally.cs:69:9:71:9 | After {...} | Finally.cs:70:13:70:41 | After ...; |
@@ -11237,16 +11253,17 @@ postDominance
| Finally.cs:159:27:159:44 | Before object creation of type Exception | Finally.cs:159:21:159:45 | Before throw ...; |
| 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:27:159:44 | Before object creation of type Exception |
| Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] | Finally.cs:161:30:161:30 | After Exception e [no-match] |
| Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] | Finally.cs:161:39:161:54 | After ... == ... [false] |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:159:21:159:45 | throw ...; |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:159:27:159:44 | object creation of type Exception |
| Finally.cs:161:30:161:30 | Exception e | Finally.cs:161:13:164:13 | After catch (...) {...} [match] |
| Finally.cs:161:30:161:30 | Exception e | Finally.cs:161:13:164:13 | catch (...) {...} |
| Finally.cs:161:39:161:39 | access to local variable e | Finally.cs:161:39:161:47 | Before access to property Message |
| Finally.cs:161:39:161:47 | After access to property Message | Finally.cs:161:39:161:47 | access to property Message |
| Finally.cs:161:39:161:47 | Before access to property Message | Finally.cs:161:39:161:54 | Before ... == ... |
| Finally.cs:161:39:161:47 | access to property Message | Finally.cs:161:39:161:39 | access to local variable e |
| Finally.cs:161:39:161:54 | ... == ... | Finally.cs:161:52:161:54 | "1" |
| Finally.cs:161:39:161:54 | Before ... == ... | Finally.cs:161:30:161:30 | Exception e |
| Finally.cs:161:39:161:54 | Before ... == ... | Finally.cs:161:30:161:30 | After Exception e [match] |
| Finally.cs:161:52:161:54 | "1" | Finally.cs:161:39:161:47 | After access to property Message |
| Finally.cs:162:13:164:13 | After {...} | Finally.cs:163:17:163:43 | After ...; |
| Finally.cs:162:13:164:13 | {...} | Finally.cs:161:39:161:54 | After ... == ... [true] |
@@ -11260,10 +11277,9 @@ postDominance
| Finally.cs:163:35:163:41 | Before access to array element | Finally.cs:163:17:163:42 | Before call to method WriteLine |
| Finally.cs:163:35:163:41 | access to array element | Finally.cs:163:40:163:40 | 0 |
| Finally.cs:163:40:163:40 | 0 | Finally.cs:163:35:163:38 | access to parameter args |
| Finally.cs:165:13:168:13 | After catch {...} [match] | Finally.cs:165:13:168:13 | catch {...} |
| Finally.cs:165:13:168:13 | catch {...} | Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] |
| Finally.cs:166:13:168:13 | After {...} | Finally.cs:167:17:167:38 | After ...; |
| Finally.cs:166:13:168:13 | {...} | Finally.cs:165:13:168:13 | After catch {...} [match] |
| Finally.cs:166:13:168:13 | {...} | Finally.cs:165:13:168:13 | catch {...} |
| Finally.cs:167:17:167:37 | After call to method WriteLine | Finally.cs:167:17:167:37 | call to method WriteLine |
| Finally.cs:167:17:167:37 | Before call to method WriteLine | Finally.cs:167:17:167:38 | ...; |
| Finally.cs:167:17:167:37 | call to method WriteLine | Finally.cs:167:35:167:36 | "" |
@@ -11332,11 +11348,12 @@ postDominance
| Finally.cs:186:25:186:47 | throw ...; | Finally.cs:186:31:186:46 | After object creation of type ExceptionB |
| Finally.cs:186:31:186:46 | Before object creation of type ExceptionB | Finally.cs:186:25:186:47 | Before throw ...; |
| Finally.cs:186:31:186:46 | object creation of type ExceptionB | Finally.cs:186:31:186:46 | Before object creation of type ExceptionB |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:186:25:186:47 | throw ...; |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:186:31:186:46 | object creation of type ExceptionB |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:188:20:188:29 | access to type ExceptionB |
| Finally.cs:188:20:188:29 | access to type ExceptionB | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:188:38:188:39 | access to parameter b2 |
| Finally.cs:188:38:188:39 | access to parameter b2 | Finally.cs:188:13:191:13 | After catch (...) {...} [match] |
| Finally.cs:188:38:188:39 | access to parameter b2 | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] |
| Finally.cs:189:13:191:13 | After {...} | Finally.cs:190:17:190:47 | After if (...) ... |
| Finally.cs:189:13:191:13 | {...} | Finally.cs:188:38:188:39 | After access to parameter b2 [true] |
| Finally.cs:190:17:190:47 | After if (...) ... | Finally.cs:190:21:190:22 | After access to parameter b1 [false] |
@@ -11426,9 +11443,8 @@ postDominance
| Finally.cs:220:13:220:37 | ...; | Finally.cs:219:9:221:9 | {...} |
| Finally.cs:220:13:220:37 | After ...; | Finally.cs:220:13:220:36 | After call to method WriteLine |
| Finally.cs:220:31:220:35 | "Try" | Finally.cs:220:13:220:36 | Before call to method WriteLine |
| Finally.cs:222:9:225:9 | After catch {...} [match] | Finally.cs:222:9:225:9 | catch {...} |
| Finally.cs:223:9:225:9 | After {...} | Finally.cs:224:13:224:39 | After ...; |
| Finally.cs:223:9:225:9 | {...} | Finally.cs:222:9:225:9 | After catch {...} [match] |
| Finally.cs:223:9:225:9 | {...} | Finally.cs:222:9:225:9 | catch {...} |
| Finally.cs:224:13:224:38 | After call to method WriteLine | Finally.cs:224:13:224:38 | call to method WriteLine |
| Finally.cs:224:13:224:38 | Before call to method WriteLine | Finally.cs:224:13:224:39 | ...; |
| Finally.cs:224:13:224:38 | call to method WriteLine | Finally.cs:224:31:224:37 | "Catch" |
@@ -17407,18 +17423,18 @@ blockDominance
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:38:10:38:11 | Entry |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:38:10:38:11 | Exit |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:38:10:38:11 | Normal Exit |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:48:16:48:24 | After access to type Exception [match] |
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] |
| ExitMethods.cs:38:10:38:11 | Exit | ExitMethods.cs:38:10:38:11 | Exit |
| ExitMethods.cs:38:10:38:11 | Normal Exit | ExitMethods.cs:38:10:38:11 | Normal Exit |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] | ExitMethods.cs:48:16:48:24 | After access to type Exception [match] |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] | ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [match] | ExitMethods.cs:48:16:48:24 | After access to type Exception [match] |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] | ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] |
| ExitMethods.cs:54:10:54:11 | Entry | ExitMethods.cs:54:10:54:11 | Entry |
| ExitMethods.cs:60:10:60:11 | Entry | ExitMethods.cs:60:10:60:11 | Entry |
| ExitMethods.cs:66:17:66:26 | Entry | ExitMethods.cs:66:17:66:26 | Entry |
@@ -17502,38 +17518,38 @@ blockDominance
| Finally.cs:19:10:19:11 | Entry | Finally.cs:19:10:19:11 | Normal Exit |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:21:9:51:9 | After try {...} ... |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:23:13:23:37 | After call to method WriteLine |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:26:9:29:9 | After catch (...) {...} [match] |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:26:9:29:9 | catch (...) {...} |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:30:9:40:9 | After catch (...) {...} [match] |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:41:9:43:9 | After catch (...) {...} [match] |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:26:38:26:39 | After IOException ex [match] |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:26:38:26:39 | After IOException ex [no-match] |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:30:41:30:42 | After ArgumentException ex [match] |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:41:16:41:24 | After access to type Exception [match] |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:41:16:41:24 | After access to type Exception [no-match] |
| Finally.cs:19:10:19:11 | Entry | Finally.cs:49:9:51:9 | {...} |
| Finally.cs:19:10:19:11 | Exceptional Exit | Finally.cs:19:10:19:11 | Exceptional Exit |
| Finally.cs:19:10:19:11 | Exit | Finally.cs:19:10:19:11 | Exit |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:19:10:19:11 | Normal Exit |
| Finally.cs:21:9:51:9 | After try {...} ... | Finally.cs:21:9:51:9 | After try {...} ... |
| Finally.cs:23:13:23:37 | After call to method WriteLine | Finally.cs:23:13:23:37 | After call to method WriteLine |
| Finally.cs:26:9:29:9 | After catch (...) {...} [match] | Finally.cs:26:9:29:9 | After catch (...) {...} [match] |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:30:9:40:9 | After catch (...) {...} [match] |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:41:9:43:9 | After catch (...) {...} [match] |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:9:29:9 | After catch (...) {...} [match] |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:9:29:9 | catch (...) {...} |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:30:9:40:9 | After catch (...) {...} [match] |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:41:9:43:9 | After catch (...) {...} [match] |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] |
| Finally.cs:30:9:40:9 | After catch (...) {...} [match] | Finally.cs:30:9:40:9 | After catch (...) {...} [match] |
| Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] |
| Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | Finally.cs:41:9:43:9 | After catch (...) {...} [match] |
| Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] |
| Finally.cs:41:9:43:9 | After catch (...) {...} [match] | Finally.cs:41:9:43:9 | After catch (...) {...} [match] |
| Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:38:26:39 | After IOException ex [match] |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:38:26:39 | After IOException ex [no-match] |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:30:41:30:42 | After ArgumentException ex [match] |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:41:16:41:24 | After access to type Exception [match] |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:41:16:41:24 | After access to type Exception [no-match] |
| Finally.cs:26:38:26:39 | After IOException ex [match] | Finally.cs:26:38:26:39 | After IOException ex [match] |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:26:38:26:39 | After IOException ex [no-match] |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:30:41:30:42 | After ArgumentException ex [match] |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:41:16:41:24 | After access to type Exception [match] |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:41:16:41:24 | After access to type Exception [no-match] |
| Finally.cs:30:41:30:42 | After ArgumentException ex [match] | Finally.cs:30:41:30:42 | After ArgumentException ex [match] |
| Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] | Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] |
| Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] | Finally.cs:41:16:41:24 | After access to type Exception [match] |
| Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] | Finally.cs:41:16:41:24 | After access to type Exception [no-match] |
| Finally.cs:41:16:41:24 | After access to type Exception [match] | Finally.cs:41:16:41:24 | After access to type Exception [match] |
| Finally.cs:41:16:41:24 | After access to type Exception [no-match] | Finally.cs:41:16:41:24 | After access to type Exception [no-match] |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:19:10:19:11 | Exceptional Exit |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:19:10:19:11 | Exit |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:19:10:19:11 | Normal Exit |
@@ -17545,11 +17561,12 @@ blockDominance
| Finally.cs:54:10:54:11 | Entry | Finally.cs:54:10:54:11 | Normal Exit |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:56:9:71:9 | After try {...} ... |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:58:13:58:37 | After call to method WriteLine |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:61:9:64:9 | After catch (...) {...} [match] |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:61:9:64:9 | catch (...) {...} |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:65:9:67:9 | After catch (...) {...} [match] |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:61:38:61:39 | After IOException ex [match] |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:61:38:61:39 | After IOException ex [no-match] |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:65:26:65:26 | After Exception e [match] |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:65:26:65:26 | After Exception e [no-match] |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:65:35:65:51 | After ... != ... [false] |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:65:35:65:51 | After ... != ... [true] |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:69:9:71:9 | {...} |
@@ -17558,23 +17575,26 @@ blockDominance
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:54:10:54:11 | Normal Exit |
| Finally.cs:56:9:71:9 | After try {...} ... | Finally.cs:56:9:71:9 | After try {...} ... |
| Finally.cs:58:13:58:37 | After call to method WriteLine | Finally.cs:58:13:58:37 | After call to method WriteLine |
| Finally.cs:61:9:64:9 | After catch (...) {...} [match] | Finally.cs:61:9:64:9 | After catch (...) {...} [match] |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:65:9:67:9 | After catch (...) {...} [match] |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:65:35:65:51 | After ... != ... [false] |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:65:35:65:51 | After ... != ... [true] |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:9:64:9 | After catch (...) {...} [match] |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:9:64:9 | catch (...) {...} |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:65:9:67:9 | After catch (...) {...} [match] |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:38:61:39 | After IOException ex [match] |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:38:61:39 | After IOException ex [no-match] |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:65:26:65:26 | After Exception e [match] |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:65:26:65:26 | After Exception e [no-match] |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:65:35:65:51 | After ... != ... [false] |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:65:35:65:51 | After ... != ... [true] |
| Finally.cs:65:9:67:9 | After catch (...) {...} [match] | Finally.cs:65:9:67:9 | After catch (...) {...} [match] |
| Finally.cs:65:9:67:9 | After catch (...) {...} [match] | Finally.cs:65:35:65:51 | After ... != ... [false] |
| Finally.cs:65:9:67:9 | After catch (...) {...} [match] | Finally.cs:65:35:65:51 | After ... != ... [true] |
| Finally.cs:61:38:61:39 | After IOException ex [match] | Finally.cs:61:38:61:39 | After IOException ex [match] |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:61:38:61:39 | After IOException ex [no-match] |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:65:26:65:26 | After Exception e [match] |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:65:26:65:26 | After Exception e [no-match] |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:65:35:65:51 | After ... != ... [false] |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:65:35:65:51 | After ... != ... [true] |
| Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] | Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] |
| Finally.cs:65:26:65:26 | After Exception e [match] | Finally.cs:65:26:65:26 | After Exception e [match] |
| Finally.cs:65:26:65:26 | After Exception e [match] | Finally.cs:65:35:65:51 | After ... != ... [false] |
| Finally.cs:65:26:65:26 | After Exception e [match] | Finally.cs:65:35:65:51 | After ... != ... [true] |
| Finally.cs:65:26:65:26 | After Exception e [no-match] | Finally.cs:65:26:65:26 | After Exception e [no-match] |
| Finally.cs:65:35:65:51 | After ... != ... [false] | Finally.cs:65:35:65:51 | After ... != ... [false] |
| Finally.cs:65:35:65:51 | After ... != ... [true] | Finally.cs:65:35:65:51 | After ... != ... [true] |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:54:10:54:11 | Exceptional Exit |
@@ -17783,9 +17803,10 @@ blockDominance
| Finally.cs:147:10:147:11 | Entry | Finally.cs:158:21:158:36 | After ... == ... [false] |
| Finally.cs:147:10:147:11 | Entry | Finally.cs:158:21:158:36 | After ... == ... [true] |
| Finally.cs:147:10:147:11 | Entry | Finally.cs:159:27:159:44 | After object creation of type Exception |
| Finally.cs:147:10:147:11 | Entry | Finally.cs:161:13:164:13 | After catch (...) {...} [match] |
| Finally.cs:147:10:147:11 | Entry | Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] |
| Finally.cs:147:10:147:11 | Entry | Finally.cs:161:13:164:13 | catch (...) {...} |
| Finally.cs:147:10:147:11 | Entry | Finally.cs:161:30:161:30 | After Exception e [match] |
| Finally.cs:147:10:147:11 | Entry | Finally.cs:161:30:161:30 | After Exception e [no-match] |
| Finally.cs:147:10:147:11 | Entry | Finally.cs:161:39:161:54 | After ... == ... [false] |
| Finally.cs:147:10:147:11 | Entry | Finally.cs:161:39:161:54 | After ... == ... [true] |
| Finally.cs:147:10:147:11 | Exceptional Exit | Finally.cs:147:10:147:11 | Exceptional Exit |
@@ -17804,9 +17825,10 @@ blockDominance
| Finally.cs:155:9:169:9 | {...} | Finally.cs:158:21:158:36 | After ... == ... [false] |
| Finally.cs:155:9:169:9 | {...} | Finally.cs:158:21:158:36 | After ... == ... [true] |
| Finally.cs:155:9:169:9 | {...} | Finally.cs:159:27:159:44 | After object creation of type Exception |
| Finally.cs:155:9:169:9 | {...} | Finally.cs:161:13:164:13 | After catch (...) {...} [match] |
| Finally.cs:155:9:169:9 | {...} | Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] |
| Finally.cs:155:9:169:9 | {...} | Finally.cs:161:13:164:13 | catch (...) {...} |
| Finally.cs:155:9:169:9 | {...} | Finally.cs:161:30:161:30 | After Exception e [match] |
| Finally.cs:155:9:169:9 | {...} | Finally.cs:161:30:161:30 | After Exception e [no-match] |
| Finally.cs:155:9:169:9 | {...} | Finally.cs:161:39:161:54 | After ... == ... [false] |
| Finally.cs:155:9:169:9 | {...} | Finally.cs:161:39:161:54 | After ... == ... [true] |
| Finally.cs:156:13:168:13 | After try {...} ... | Finally.cs:147:10:147:11 | Exceptional Exit |
@@ -17821,15 +17843,17 @@ blockDominance
| Finally.cs:158:21:158:36 | After ... == ... [true] | Finally.cs:158:21:158:36 | After ... == ... [true] |
| Finally.cs:158:21:158:36 | After ... == ... [true] | Finally.cs:159:27:159:44 | After object creation of type Exception |
| Finally.cs:159:27:159:44 | After object creation of type Exception | Finally.cs:159:27:159:44 | After object creation of type Exception |
| Finally.cs:161:13:164:13 | After catch (...) {...} [match] | Finally.cs:161:13:164:13 | After catch (...) {...} [match] |
| Finally.cs:161:13:164:13 | After catch (...) {...} [match] | Finally.cs:161:39:161:54 | After ... == ... [false] |
| Finally.cs:161:13:164:13 | After catch (...) {...} [match] | Finally.cs:161:39:161:54 | After ... == ... [true] |
| Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] | Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:13:164:13 | After catch (...) {...} [match] |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:13:164:13 | catch (...) {...} |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:30:161:30 | After Exception e [match] |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:30:161:30 | After Exception e [no-match] |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:39:161:54 | After ... == ... [false] |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:39:161:54 | After ... == ... [true] |
| Finally.cs:161:30:161:30 | After Exception e [match] | Finally.cs:161:30:161:30 | After Exception e [match] |
| Finally.cs:161:30:161:30 | After Exception e [match] | Finally.cs:161:39:161:54 | After ... == ... [false] |
| Finally.cs:161:30:161:30 | After Exception e [match] | Finally.cs:161:39:161:54 | After ... == ... [true] |
| Finally.cs:161:30:161:30 | After Exception e [no-match] | Finally.cs:161:30:161:30 | After Exception e [no-match] |
| Finally.cs:161:39:161:54 | After ... == ... [false] | Finally.cs:161:39:161:54 | After ... == ... [false] |
| Finally.cs:161:39:161:54 | After ... == ... [true] | Finally.cs:161:39:161:54 | After ... == ... [true] |
| Finally.cs:172:11:172:20 | Entry | Finally.cs:172:11:172:20 | Entry |
@@ -17847,9 +17871,10 @@ blockDominance
| Finally.cs:176:10:176:11 | Entry | Finally.cs:186:21:186:22 | After access to parameter b2 [false] |
| Finally.cs:176:10:176:11 | Entry | Finally.cs:186:21:186:22 | After access to parameter b2 [true] |
| Finally.cs:176:10:176:11 | Entry | Finally.cs:186:31:186:46 | After object creation of type ExceptionB |
| Finally.cs:176:10:176:11 | Entry | Finally.cs:188:13:191:13 | After catch (...) {...} [match] |
| Finally.cs:176:10:176:11 | Entry | Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] |
| Finally.cs:176:10:176:11 | Entry | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:176:10:176:11 | Entry | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] |
| Finally.cs:176:10:176:11 | Entry | Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] |
| Finally.cs:176:10:176:11 | Entry | Finally.cs:188:38:188:39 | After access to parameter b2 [false] |
| Finally.cs:176:10:176:11 | Entry | Finally.cs:188:38:188:39 | After access to parameter b2 [true] |
| Finally.cs:176:10:176:11 | Entry | Finally.cs:190:21:190:22 | After access to parameter b1 [false] |
@@ -17869,9 +17894,10 @@ blockDominance
| Finally.cs:183:9:192:9 | {...} | Finally.cs:186:21:186:22 | After access to parameter b2 [false] |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:186:21:186:22 | After access to parameter b2 [true] |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:186:31:186:46 | After object creation of type ExceptionB |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:13:191:13 | After catch (...) {...} [match] |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:38:188:39 | After access to parameter b2 [false] |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:38:188:39 | After access to parameter b2 [true] |
| Finally.cs:183:9:192:9 | {...} | Finally.cs:190:21:190:22 | After access to parameter b1 [false] |
@@ -17881,27 +17907,30 @@ blockDominance
| Finally.cs:186:21:186:22 | After access to parameter b2 [false] | Finally.cs:186:21:186:22 | After access to parameter b2 [false] |
| Finally.cs:186:21:186:22 | After access to parameter b2 [true] | Finally.cs:186:21:186:22 | After access to parameter b2 [true] |
| Finally.cs:186:21:186:22 | After access to parameter b2 [true] | Finally.cs:186:31:186:46 | After object creation of type ExceptionB |
| Finally.cs:186:21:186:22 | After access to parameter b2 [true] | Finally.cs:188:13:191:13 | After catch (...) {...} [match] |
| Finally.cs:186:21:186:22 | After access to parameter b2 [true] | Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] |
| Finally.cs:186:21:186:22 | After access to parameter b2 [true] | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:186:21:186:22 | After access to parameter b2 [true] | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] |
| Finally.cs:186:21:186:22 | After access to parameter b2 [true] | Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] |
| Finally.cs:186:21:186:22 | After access to parameter b2 [true] | Finally.cs:188:38:188:39 | After access to parameter b2 [false] |
| Finally.cs:186:21:186:22 | After access to parameter b2 [true] | Finally.cs:188:38:188:39 | After access to parameter b2 [true] |
| Finally.cs:186:21:186:22 | After access to parameter b2 [true] | Finally.cs:190:21:190:22 | After access to parameter b1 [false] |
| Finally.cs:186:21:186:22 | After access to parameter b2 [true] | Finally.cs:190:21:190:22 | After access to parameter b1 [true] |
| Finally.cs:186:31:186:46 | After object creation of type ExceptionB | Finally.cs:186:31:186:46 | After object creation of type ExceptionB |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:188:13:191:13 | After catch (...) {...} [match] |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:188:38:188:39 | After access to parameter b2 [false] |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:188:38:188:39 | After access to parameter b2 [true] |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:190:21:190:22 | After access to parameter b1 [false] |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:190:21:190:22 | After access to parameter b1 [true] |
| Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] | Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | After catch (...) {...} [match] |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:38:188:39 | After access to parameter b2 [false] |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:38:188:39 | After access to parameter b2 [true] |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:190:21:190:22 | After access to parameter b1 [false] |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:190:21:190:22 | After access to parameter b1 [true] |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:188:38:188:39 | After access to parameter b2 [false] |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:188:38:188:39 | After access to parameter b2 [true] |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:190:21:190:22 | After access to parameter b1 [false] |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:190:21:190:22 | After access to parameter b1 [true] |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] | Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] |
| Finally.cs:188:38:188:39 | After access to parameter b2 [false] | Finally.cs:188:38:188:39 | After access to parameter b2 [false] |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:188:38:188:39 | After access to parameter b2 [true] |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:190:21:190:22 | After access to parameter b1 [false] |
@@ -21668,14 +21697,14 @@ postBlockDominance
| ExitMethods.cs:38:10:38:11 | Exit | ExitMethods.cs:38:10:38:11 | Exit |
| ExitMethods.cs:38:10:38:11 | Normal Exit | ExitMethods.cs:38:10:38:11 | Entry |
| ExitMethods.cs:38:10:38:11 | Normal Exit | ExitMethods.cs:38:10:38:11 | Normal Exit |
| ExitMethods.cs:38:10:38:11 | Normal Exit | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] |
| ExitMethods.cs:38:10:38:11 | Normal Exit | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] |
| ExitMethods.cs:38:10:38:11 | Normal Exit | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] |
| ExitMethods.cs:38:10:38:11 | Normal Exit | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] |
| ExitMethods.cs:38:10:38:11 | Normal Exit | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] |
| ExitMethods.cs:38:10:38:11 | Normal Exit | ExitMethods.cs:48:16:48:24 | After access to type Exception [match] |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [match] | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [match] | ExitMethods.cs:48:16:48:24 | After access to type Exception [match] |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] | ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] |
| ExitMethods.cs:54:10:54:11 | Entry | ExitMethods.cs:54:10:54:11 | Entry |
| ExitMethods.cs:60:10:60:11 | Entry | ExitMethods.cs:60:10:60:11 | Entry |
| ExitMethods.cs:66:17:66:26 | Entry | ExitMethods.cs:66:17:66:26 | Entry |
@@ -21743,32 +21772,32 @@ postBlockDominance
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:19:10:19:11 | Normal Exit |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:21:9:51:9 | After try {...} ... |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:23:13:23:37 | After call to method WriteLine |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:26:9:29:9 | After catch (...) {...} [match] |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:26:9:29:9 | catch (...) {...} |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:30:9:40:9 | After catch (...) {...} [match] |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:41:9:43:9 | After catch (...) {...} [match] |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:26:38:26:39 | After IOException ex [match] |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:26:38:26:39 | After IOException ex [no-match] |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:30:41:30:42 | After ArgumentException ex [match] |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:41:16:41:24 | After access to type Exception [match] |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:41:16:41:24 | After access to type Exception [no-match] |
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:49:9:51:9 | {...} |
| Finally.cs:21:9:51:9 | After try {...} ... | Finally.cs:21:9:51:9 | After try {...} ... |
| Finally.cs:23:13:23:37 | After call to method WriteLine | Finally.cs:23:13:23:37 | After call to method WriteLine |
| Finally.cs:26:9:29:9 | After catch (...) {...} [match] | Finally.cs:26:9:29:9 | After catch (...) {...} [match] |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:9:29:9 | catch (...) {...} |
| Finally.cs:30:9:40:9 | After catch (...) {...} [match] | Finally.cs:30:9:40:9 | After catch (...) {...} [match] |
| Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] |
| Finally.cs:41:9:43:9 | After catch (...) {...} [match] | Finally.cs:41:9:43:9 | After catch (...) {...} [match] |
| Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] |
| Finally.cs:26:38:26:39 | After IOException ex [match] | Finally.cs:26:38:26:39 | After IOException ex [match] |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:26:38:26:39 | After IOException ex [no-match] |
| Finally.cs:30:41:30:42 | After ArgumentException ex [match] | Finally.cs:30:41:30:42 | After ArgumentException ex [match] |
| Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] | Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] |
| Finally.cs:41:16:41:24 | After access to type Exception [match] | Finally.cs:41:16:41:24 | After access to type Exception [match] |
| Finally.cs:41:16:41:24 | After access to type Exception [no-match] | Finally.cs:41:16:41:24 | After access to type Exception [no-match] |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:19:10:19:11 | Entry |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:23:13:23:37 | After call to method WriteLine |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:26:9:29:9 | After catch (...) {...} [match] |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:26:9:29:9 | catch (...) {...} |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:30:9:40:9 | After catch (...) {...} [match] |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:41:9:43:9 | After catch (...) {...} [match] |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:26:38:26:39 | After IOException ex [match] |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:26:38:26:39 | After IOException ex [no-match] |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:30:41:30:42 | After ArgumentException ex [match] |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:41:16:41:24 | After access to type Exception [match] |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:41:16:41:24 | After access to type Exception [no-match] |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:49:9:51:9 | {...} |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:54:10:54:11 | Entry |
| Finally.cs:54:10:54:11 | Exceptional Exit | Finally.cs:54:10:54:11 | Exceptional Exit |
@@ -21777,31 +21806,35 @@ postBlockDominance
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:54:10:54:11 | Normal Exit |
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:56:9:71:9 | After try {...} ... |
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:58:13:58:37 | After call to method WriteLine |
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:61:9:64:9 | After catch (...) {...} [match] |
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] |
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:61:9:64:9 | catch (...) {...} |
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:65:9:67:9 | After catch (...) {...} [match] |
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:61:38:61:39 | After IOException ex [match] |
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:61:38:61:39 | After IOException ex [no-match] |
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] |
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:65:26:65:26 | After Exception e [match] |
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:65:26:65:26 | After Exception e [no-match] |
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:65:35:65:51 | After ... != ... [false] |
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:65:35:65:51 | After ... != ... [true] |
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:69:9:71:9 | {...} |
| Finally.cs:56:9:71:9 | After try {...} ... | Finally.cs:56:9:71:9 | After try {...} ... |
| Finally.cs:58:13:58:37 | After call to method WriteLine | Finally.cs:58:13:58:37 | After call to method WriteLine |
| Finally.cs:61:9:64:9 | After catch (...) {...} [match] | Finally.cs:61:9:64:9 | After catch (...) {...} [match] |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:9:64:9 | catch (...) {...} |
| Finally.cs:65:9:67:9 | After catch (...) {...} [match] | Finally.cs:65:9:67:9 | After catch (...) {...} [match] |
| Finally.cs:61:38:61:39 | After IOException ex [match] | Finally.cs:61:38:61:39 | After IOException ex [match] |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:61:38:61:39 | After IOException ex [no-match] |
| Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] | Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] |
| Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] | Finally.cs:65:26:65:26 | After Exception e [no-match] |
| Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] | Finally.cs:65:35:65:51 | After ... != ... [false] |
| Finally.cs:65:26:65:26 | After Exception e [match] | Finally.cs:65:26:65:26 | After Exception e [match] |
| Finally.cs:65:26:65:26 | After Exception e [no-match] | Finally.cs:65:26:65:26 | After Exception e [no-match] |
| Finally.cs:65:35:65:51 | After ... != ... [false] | Finally.cs:65:35:65:51 | After ... != ... [false] |
| Finally.cs:65:35:65:51 | After ... != ... [true] | Finally.cs:65:35:65:51 | After ... != ... [true] |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:54:10:54:11 | Entry |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:58:13:58:37 | After call to method WriteLine |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:61:9:64:9 | After catch (...) {...} [match] |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:61:9:64:9 | catch (...) {...} |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:65:9:67:9 | After catch (...) {...} [match] |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:61:38:61:39 | After IOException ex [match] |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:61:38:61:39 | After IOException ex [no-match] |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:65:26:65:26 | After Exception e [match] |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:65:26:65:26 | After Exception e [no-match] |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:65:35:65:51 | After ... != ... [false] |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:65:35:65:51 | After ... != ... [true] |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:69:9:71:9 | {...} |
@@ -21973,9 +22006,10 @@ postBlockDominance
| Finally.cs:149:9:169:9 | After try {...} ... | Finally.cs:158:21:158:36 | After ... == ... [false] |
| Finally.cs:149:9:169:9 | After try {...} ... | Finally.cs:158:21:158:36 | After ... == ... [true] |
| Finally.cs:149:9:169:9 | After try {...} ... | Finally.cs:159:27:159:44 | After object creation of type Exception |
| Finally.cs:149:9:169:9 | After try {...} ... | Finally.cs:161:13:164:13 | After catch (...) {...} [match] |
| Finally.cs:149:9:169:9 | After try {...} ... | Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] |
| Finally.cs:149:9:169:9 | After try {...} ... | Finally.cs:161:13:164:13 | catch (...) {...} |
| Finally.cs:149:9:169:9 | After try {...} ... | Finally.cs:161:30:161:30 | After Exception e [match] |
| Finally.cs:149:9:169:9 | After try {...} ... | Finally.cs:161:30:161:30 | After Exception e [no-match] |
| Finally.cs:149:9:169:9 | After try {...} ... | Finally.cs:161:39:161:54 | After ... == ... [false] |
| Finally.cs:149:9:169:9 | After try {...} ... | Finally.cs:161:39:161:54 | After ... == ... [true] |
| Finally.cs:151:17:151:28 | After ... == ... [false] | Finally.cs:151:17:151:28 | After ... == ... [false] |
@@ -21996,21 +22030,24 @@ postBlockDominance
| Finally.cs:156:13:168:13 | After try {...} ... | Finally.cs:158:21:158:36 | After ... == ... [false] |
| Finally.cs:156:13:168:13 | After try {...} ... | Finally.cs:158:21:158:36 | After ... == ... [true] |
| Finally.cs:156:13:168:13 | After try {...} ... | Finally.cs:159:27:159:44 | After object creation of type Exception |
| Finally.cs:156:13:168:13 | After try {...} ... | Finally.cs:161:13:164:13 | After catch (...) {...} [match] |
| Finally.cs:156:13:168:13 | After try {...} ... | Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] |
| Finally.cs:156:13:168:13 | After try {...} ... | Finally.cs:161:13:164:13 | catch (...) {...} |
| Finally.cs:156:13:168:13 | After try {...} ... | Finally.cs:161:30:161:30 | After Exception e [match] |
| Finally.cs:156:13:168:13 | After try {...} ... | Finally.cs:161:30:161:30 | After Exception e [no-match] |
| Finally.cs:156:13:168:13 | After try {...} ... | Finally.cs:161:39:161:54 | After ... == ... [false] |
| Finally.cs:156:13:168:13 | After try {...} ... | Finally.cs:161:39:161:54 | After ... == ... [true] |
| Finally.cs:158:21:158:31 | After access to property Length | Finally.cs:158:21:158:31 | After access to property Length |
| Finally.cs:158:21:158:36 | After ... == ... [false] | Finally.cs:158:21:158:36 | After ... == ... [false] |
| Finally.cs:158:21:158:36 | After ... == ... [true] | Finally.cs:158:21:158:36 | After ... == ... [true] |
| Finally.cs:159:27:159:44 | After object creation of type Exception | Finally.cs:159:27:159:44 | After object creation of type Exception |
| Finally.cs:161:13:164:13 | After catch (...) {...} [match] | Finally.cs:161:13:164:13 | After catch (...) {...} [match] |
| Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] | Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] |
| Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] | Finally.cs:161:30:161:30 | After Exception e [no-match] |
| Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] | Finally.cs:161:39:161:54 | After ... == ... [false] |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:158:21:158:36 | After ... == ... [true] |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:159:27:159:44 | After object creation of type Exception |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:13:164:13 | catch (...) {...} |
| Finally.cs:161:30:161:30 | After Exception e [match] | Finally.cs:161:30:161:30 | After Exception e [match] |
| Finally.cs:161:30:161:30 | After Exception e [no-match] | Finally.cs:161:30:161:30 | After Exception e [no-match] |
| Finally.cs:161:39:161:54 | After ... == ... [false] | Finally.cs:161:39:161:54 | After ... == ... [false] |
| Finally.cs:161:39:161:54 | After ... == ... [true] | Finally.cs:161:39:161:54 | After ... == ... [true] |
| Finally.cs:172:11:172:20 | Entry | Finally.cs:172:11:172:20 | Entry |
@@ -22029,8 +22066,8 @@ postBlockDominance
| Finally.cs:178:9:192:9 | After try {...} ... | Finally.cs:186:21:186:22 | After access to parameter b2 [false] |
| Finally.cs:178:9:192:9 | After try {...} ... | Finally.cs:186:21:186:22 | After access to parameter b2 [true] |
| Finally.cs:178:9:192:9 | After try {...} ... | Finally.cs:186:31:186:46 | After object creation of type ExceptionB |
| Finally.cs:178:9:192:9 | After try {...} ... | Finally.cs:188:13:191:13 | After catch (...) {...} [match] |
| Finally.cs:178:9:192:9 | After try {...} ... | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:178:9:192:9 | After try {...} ... | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] |
| Finally.cs:178:9:192:9 | After try {...} ... | Finally.cs:188:38:188:39 | After access to parameter b2 [true] |
| Finally.cs:178:9:192:9 | After try {...} ... | Finally.cs:190:21:190:22 | After access to parameter b1 [false] |
| Finally.cs:180:17:180:18 | After access to parameter b1 [false] | Finally.cs:180:17:180:18 | After access to parameter b1 [false] |
@@ -22050,31 +22087,32 @@ postBlockDominance
| Finally.cs:184:13:191:13 | After try {...} ... | Finally.cs:186:21:186:22 | After access to parameter b2 [false] |
| Finally.cs:184:13:191:13 | After try {...} ... | Finally.cs:186:21:186:22 | After access to parameter b2 [true] |
| Finally.cs:184:13:191:13 | After try {...} ... | Finally.cs:186:31:186:46 | After object creation of type ExceptionB |
| Finally.cs:184:13:191:13 | After try {...} ... | Finally.cs:188:13:191:13 | After catch (...) {...} [match] |
| Finally.cs:184:13:191:13 | After try {...} ... | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:184:13:191:13 | After try {...} ... | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] |
| Finally.cs:184:13:191:13 | After try {...} ... | Finally.cs:188:38:188:39 | After access to parameter b2 [true] |
| Finally.cs:184:13:191:13 | After try {...} ... | Finally.cs:190:21:190:22 | After access to parameter b1 [false] |
| Finally.cs:186:21:186:22 | After access to parameter b2 [false] | Finally.cs:186:21:186:22 | After access to parameter b2 [false] |
| Finally.cs:186:21:186:22 | After access to parameter b2 [true] | Finally.cs:186:21:186:22 | After access to parameter b2 [true] |
| Finally.cs:186:31:186:46 | After object creation of type ExceptionB | Finally.cs:186:31:186:46 | After object creation of type ExceptionB |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:186:21:186:22 | After access to parameter b2 [true] |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:186:31:186:46 | After object creation of type ExceptionB |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:188:13:191:13 | After catch (...) {...} [match] |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] | Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:186:21:186:22 | After access to parameter b2 [true] |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:186:31:186:46 | After object creation of type ExceptionB |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:186:21:186:22 | After access to parameter b2 [true] |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:186:31:186:46 | After object creation of type ExceptionB |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] | Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] |
| Finally.cs:188:38:188:39 | After access to parameter b2 [false] | Finally.cs:188:38:188:39 | After access to parameter b2 [false] |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:186:21:186:22 | After access to parameter b2 [true] |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:186:31:186:46 | After object creation of type ExceptionB |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:188:13:191:13 | After catch (...) {...} [match] |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:188:38:188:39 | After access to parameter b2 [true] |
| Finally.cs:190:21:190:22 | After access to parameter b1 [false] | Finally.cs:186:21:186:22 | After access to parameter b2 [true] |
| Finally.cs:190:21:190:22 | After access to parameter b1 [false] | Finally.cs:186:31:186:46 | After object creation of type ExceptionB |
| Finally.cs:190:21:190:22 | After access to parameter b1 [false] | Finally.cs:188:13:191:13 | After catch (...) {...} [match] |
| Finally.cs:190:21:190:22 | After access to parameter b1 [false] | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:190:21:190:22 | After access to parameter b1 [false] | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] |
| Finally.cs:190:21:190:22 | After access to parameter b1 [false] | Finally.cs:188:38:188:39 | After access to parameter b2 [true] |
| Finally.cs:190:21:190:22 | After access to parameter b1 [false] | Finally.cs:190:21:190:22 | After access to parameter b1 [false] |
| Finally.cs:190:21:190:22 | After access to parameter b1 [true] | Finally.cs:190:21:190:22 | After access to parameter b1 [true] |

View File

@@ -3016,15 +3016,19 @@ nodeEnclosing
| 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 | After catch (...) {...} [match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:44:9:47:9 | catch (...) {...} | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:44:16:44:32 | access to type ArgumentException | 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 | Before return ...; | 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 | After catch (...) {...} [match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:48:9:51:9 | catch (...) {...} | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:48:16:48:24 | access to type Exception | 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 | Before return ...; | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:50:13:50:19 | return ...; | ExitMethods.cs:38:10:38:11 | M6 |
@@ -3358,18 +3362,20 @@ nodeEnclosing
| Finally.cs:23:31:23:36 | "Try2" | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:24:13:24:19 | Before return ...; | 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 | After catch (...) {...} [match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:26:38:26:39 | After IOException ex [match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:26:38:26:39 | IOException ex | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:26:48:26:51 | After true [true] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:26:48:26:51 | 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 | Before throw ...; | 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 | After catch (...) {...} [match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:30:9:40:9 | catch (...) {...} | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:30:41:30:42 | After ArgumentException ex [match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:30:41:30:42 | 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 |
@@ -3386,11 +3392,12 @@ nodeEnclosing
| Finally.cs:38:23:38:43 | Before object creation of type Exception | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:38:23:38:43 | object creation of type Exception | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:38:37:38:42 | "Boo!" | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:41:9:43:9 | After catch (...) {...} [match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:41:9:43:9 | catch (...) {...} | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:41:16:41:24 | After access to type Exception [match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:41:16:41:24 | After access to type Exception [no-match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:41:16:41:24 | access to type Exception | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:42:9:43:9 | {...} | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:44:9:47:9 | After catch {...} [match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:44:9:47:9 | catch {...} | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:45:9:47:9 | {...} | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:46:13:46:19 | Before return ...; | Finally.cs:19:10:19:11 | M2 |
@@ -3420,18 +3427,20 @@ nodeEnclosing
| Finally.cs:58:31:58:36 | "Try3" | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:59:13:59:19 | Before return ...; | 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 | After catch (...) {...} [match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:61:38:61:39 | After IOException ex [match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:61:38:61:39 | IOException ex | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:61:48:61:51 | After true [true] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:61:48:61:51 | 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 | Before throw ...; | 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 | After catch (...) {...} [match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:65:26:65:26 | After Exception e [match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:65:26:65:26 | After Exception e [no-match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:65:26:65:26 | Exception e | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:65:35:65:35 | access to local variable e | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:65:35:65:43 | After access to property Message | Finally.cs:54:10:54:11 | M3 |
@@ -3719,9 +3728,10 @@ nodeEnclosing
| Finally.cs:159:27:159:44 | Before 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:161:13:164:13 | After catch (...) {...} [match] | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:161:30:161:30 | After Exception e [match] | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:161:30:161:30 | After Exception e [no-match] | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:161:30:161:30 | Exception e | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:161:39:161:39 | access to local variable e | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:161:39:161:47 | After access to property Message | Finally.cs:147:10:147:11 | M8 |
@@ -3744,7 +3754,6 @@ nodeEnclosing
| Finally.cs:163:35:163:41 | Before access to array element | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:163:35:163:41 | access to array element | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:163:40:163:40 | 0 | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:165:13:168:13 | After catch {...} [match] | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:165:13:168:13 | catch {...} | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:166:13:168:13 | After {...} | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:166:13:168:13 | {...} | Finally.cs:147:10:147:11 | M8 |
@@ -3825,9 +3834,11 @@ nodeEnclosing
| Finally.cs:186:31:186:46 | After object creation of type ExceptionB | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:186:31:186:46 | Before object creation of type ExceptionB | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:186:31:186:46 | object creation of type ExceptionB | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:20:188:29 | access to type ExceptionB | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:38:188:39 | After access to parameter b2 [false] | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:38:188:39 | access to parameter b2 | Finally.cs:176:10:176:11 | M9 |
@@ -3929,7 +3940,6 @@ nodeEnclosing
| Finally.cs:220:13:220:37 | ...; | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:220:13:220:37 | After ...; | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:220:31:220:35 | "Try" | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:222:9:225:9 | After catch {...} [match] | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:223:9:225:9 | After {...} | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:223:9:225:9 | {...} | Finally.cs:216:10:216:12 | M11 |
@@ -8830,10 +8840,10 @@ blockEnclosing
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:38:10:38:11 | Exit | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:38:10:38:11 | Normal Exit | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] | ExitMethods.cs:38:10:38:11 | M6 |
| ExitMethods.cs:54:10:54:11 | Entry | ExitMethods.cs:54:10:54:11 | M7 |
| ExitMethods.cs:60:10:60:11 | Entry | ExitMethods.cs:60:10:60:11 | M8 |
| ExitMethods.cs:66:17:66:26 | Entry | ExitMethods.cs:66:17:66:26 | ErrorMaybe |
@@ -8888,13 +8898,13 @@ blockEnclosing
| Finally.cs:19:10:19:11 | Normal Exit | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:21:9:51:9 | After try {...} ... | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:23:13:23:37 | After call to method WriteLine | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:26:9:29:9 | After catch (...) {...} [match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:30:9:40:9 | After catch (...) {...} [match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:41:9:43:9 | After catch (...) {...} [match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:26:38:26:39 | After IOException ex [match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:30:41:30:42 | After ArgumentException ex [match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:41:16:41:24 | After access to type Exception [match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:41:16:41:24 | After access to type Exception [no-match] | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:49:9:51:9 | {...} | Finally.cs:19:10:19:11 | M2 |
| Finally.cs:54:10:54:11 | Entry | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:54:10:54:11 | Exceptional Exit | Finally.cs:54:10:54:11 | M3 |
@@ -8902,11 +8912,12 @@ blockEnclosing
| Finally.cs:54:10:54:11 | Normal Exit | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:56:9:71:9 | After try {...} ... | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:58:13:58:37 | After call to method WriteLine | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:61:9:64:9 | After catch (...) {...} [match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:65:9:67:9 | After catch (...) {...} [match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:61:38:61:39 | After IOException ex [match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:65:26:65:26 | After Exception e [match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:65:26:65:26 | After Exception e [no-match] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:65:35:65:51 | After ... != ... [false] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:65:35:65:51 | After ... != ... [true] | Finally.cs:54:10:54:11 | M3 |
| Finally.cs:69:9:71:9 | {...} | Finally.cs:54:10:54:11 | M3 |
@@ -8969,9 +8980,10 @@ blockEnclosing
| Finally.cs:158:21:158:36 | After ... == ... [false] | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:158:21:158:36 | After ... == ... [true] | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:159:27:159:44 | After object creation of type Exception | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:161:13:164:13 | After catch (...) {...} [match] | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:161:30:161:30 | After Exception e [match] | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:161:30:161:30 | After Exception e [no-match] | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:161:39:161:54 | After ... == ... [false] | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:161:39:161:54 | After ... == ... [true] | Finally.cs:147:10:147:11 | M8 |
| Finally.cs:172:11:172:20 | Entry | Finally.cs:172:11:172:20 | ExceptionA |
@@ -8989,9 +9001,10 @@ blockEnclosing
| Finally.cs:186:21:186:22 | After access to parameter b2 [false] | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:186:21:186:22 | After access to parameter b2 [true] | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:186:31:186:46 | After object creation of type ExceptionB | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:38:188:39 | After access to parameter b2 [false] | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:176:10:176:11 | M9 |
| Finally.cs:190:21:190:22 | After access to parameter b1 [false] | Finally.cs:176:10:176:11 | M9 |

View File

@@ -1398,9 +1398,11 @@
| 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:44:16:44:32 | access to type ArgumentException | ExitMethods.cs:44:16:44:32 | access to type ArgumentException |
| 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:48:16:48:24 | access to type Exception | ExitMethods.cs:48:16:48:24 | access to type Exception |
| 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 | {...} |
@@ -1569,6 +1571,7 @@
| Finally.cs:38:23:38:43 | object creation of type Exception | Finally.cs:38:37:38:42 | "Boo!" |
| Finally.cs:38:37:38:42 | "Boo!" | Finally.cs:38:37:38:42 | "Boo!" |
| Finally.cs:41:9:43:9 | catch (...) {...} | Finally.cs:41:9:43:9 | catch (...) {...} |
| Finally.cs:41:16:41:24 | access to type Exception | Finally.cs:41:16:41:24 | access to type Exception |
| Finally.cs:42:9:43:9 | {...} | Finally.cs:42:9:43:9 | {...} |
| Finally.cs:44:9:47:9 | catch {...} | Finally.cs:44:9:47:9 | catch {...} |
| Finally.cs:45:9:47:9 | {...} | Finally.cs:45:9:47:9 | {...} |
@@ -1766,6 +1769,7 @@
| Finally.cs:186:25:186:47 | throw ...; | Finally.cs:186:31:186:46 | object creation of type ExceptionB |
| Finally.cs:186:31:186:46 | object creation of type ExceptionB | Finally.cs:186:31:186:46 | object creation of type ExceptionB |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | catch (...) {...} |
| Finally.cs:188:20:188:29 | access to type ExceptionB | Finally.cs:188:20:188:29 | access to type ExceptionB |
| Finally.cs:188:38:188:39 | access to parameter b2 | Finally.cs:188:38:188:39 | access to parameter b2 |
| Finally.cs:189:13:191:13 | {...} | Finally.cs:189:13:191:13 | {...} |
| Finally.cs:190:17:190:47 | if (...) ... | Finally.cs:190:17:190:47 | if (...) ... |

View File

@@ -3062,17 +3062,21 @@
| ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | ExitMethods.cs:44:9:47:9 | catch (...) {...} | exception |
| ExitMethods.cs:42:13:42:31 | ...; | ExitMethods.cs:42:13:42:30 | Before call to method ErrorAlways | |
| ExitMethods.cs:42:25:42:29 | false | ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] | ExitMethods.cs:45:9:47:9 | {...} | |
| ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | ExitMethods.cs:48:9:51:9 | catch (...) {...} | |
| ExitMethods.cs:44:9:47:9 | catch (...) {...} | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] | match |
| ExitMethods.cs:44:9:47:9 | catch (...) {...} | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | no-match |
| ExitMethods.cs:44:9:47:9 | catch (...) {...} | ExitMethods.cs:44:16:44:32 | access to type ArgumentException | |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] | ExitMethods.cs:45:9:47:9 | {...} | |
| ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | no-match |
| ExitMethods.cs:44:16:44:32 | access to type ArgumentException | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [match] | match |
| ExitMethods.cs:44:16:44:32 | access to type ArgumentException | ExitMethods.cs:44:16:44:32 | After access to type ArgumentException [no-match] | no-match |
| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:46:13:46:19 | Before return ...; | |
| ExitMethods.cs:46:13:46:19 | Before return ...; | ExitMethods.cs:46:13:46:19 | return ...; | |
| ExitMethods.cs:46:13:46:19 | return ...; | ExitMethods.cs:38:10:38:11 | Normal Exit | return |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] | ExitMethods.cs:49:9:51:9 | {...} | |
| ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] | ExitMethods.cs:38:10:38:11 | Exceptional Exit | exception |
| ExitMethods.cs:48:9:51:9 | catch (...) {...} | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] | match |
| ExitMethods.cs:48:9:51:9 | catch (...) {...} | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] | no-match |
| ExitMethods.cs:48:9:51:9 | catch (...) {...} | ExitMethods.cs:48:16:48:24 | access to type Exception | |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [match] | ExitMethods.cs:49:9:51:9 | {...} | |
| ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [no-match] | no-match |
| ExitMethods.cs:48:16:48:24 | access to type Exception | ExitMethods.cs:48:16:48:24 | After access to type Exception [match] | match |
| ExitMethods.cs:48:16:48:24 | access to type Exception | ExitMethods.cs:48:16:48:24 | After access to type Exception [no-match] | no-match |
| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:50:13:50:19 | Before return ...; | |
| ExitMethods.cs:50:13:50:19 | Before return ...; | ExitMethods.cs:50:13:50:19 | return ...; | |
| ExitMethods.cs:50:13:50:19 | return ...; | ExitMethods.cs:38:10:38:11 | Normal Exit | return |
@@ -3393,21 +3397,23 @@
| Finally.cs:23:31:23:36 | "Try2" | Finally.cs:23:13:23:37 | call to method WriteLine | |
| Finally.cs:24:13:24:19 | Before return ...; | Finally.cs:24:13:24:19 | return ...; | |
| Finally.cs:24:13:24:19 | return ...; | Finally.cs:49:9:51:9 | {...} | return |
| Finally.cs:26:9:29:9 | After catch (...) {...} [match] | Finally.cs:26:38:26:39 | IOException ex | |
| Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | Finally.cs:30:9:40:9 | catch (...) {...} | |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:9:29:9 | After catch (...) {...} [match] | match |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:26:38:26:39 | IOException ex | Finally.cs:26:48:26:51 | true | |
| Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:38:26:39 | IOException ex | |
| Finally.cs:26:38:26:39 | After IOException ex [match] | Finally.cs:26:48:26:51 | true | |
| Finally.cs:26:38:26:39 | After IOException ex [no-match] | Finally.cs:26:9:29:9 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:26:38:26:39 | IOException ex | Finally.cs:26:38:26:39 | After IOException ex [match] | match |
| Finally.cs:26:38:26:39 | IOException ex | Finally.cs:26:38:26:39 | After IOException ex [no-match] | no-match |
| Finally.cs:26:48:26:51 | After true [true] | Finally.cs:27:9:29:9 | {...} | |
| Finally.cs:26:48:26:51 | true | Finally.cs:26:48:26:51 | After true [true] | true |
| Finally.cs:27:9:29:9 | {...} | Finally.cs:28:13:28:18 | Before throw ...; | |
| Finally.cs:28:13:28:18 | Before throw ...; | Finally.cs:28:13:28:18 | throw ...; | |
| Finally.cs:28:13:28:18 | throw ...; | Finally.cs:49:9:51:9 | {...} | exception |
| Finally.cs:30:9:40:9 | After catch (...) {...} [match] | Finally.cs:30:41:30:42 | ArgumentException ex | |
| Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | Finally.cs:41:9:43:9 | catch (...) {...} | |
| Finally.cs:30:9:40:9 | catch (...) {...} | Finally.cs:30:9:40:9 | After catch (...) {...} [match] | match |
| Finally.cs:30:9:40:9 | catch (...) {...} | Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:30:41:30:42 | ArgumentException ex | Finally.cs:31:9:40:9 | {...} | |
| Finally.cs:30:9:40:9 | catch (...) {...} | Finally.cs:30:41:30:42 | ArgumentException ex | |
| Finally.cs:30:41:30:42 | After ArgumentException ex [match] | Finally.cs:31:9:40:9 | {...} | |
| Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] | Finally.cs:30:9:40:9 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:30:41:30:42 | ArgumentException ex | Finally.cs:30:41:30:42 | After ArgumentException ex [match] | match |
| Finally.cs:30:41:30:42 | ArgumentException ex | Finally.cs:30:41:30:42 | After ArgumentException ex [no-match] | no-match |
| 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 | {...} | |
| Finally.cs:33:13:35:13 | {...} | Finally.cs:34:17:34:32 | if (...) ... | |
@@ -3423,13 +3429,14 @@
| Finally.cs:38:23:38:43 | Before object creation of type Exception | Finally.cs:38:37:38:42 | "Boo!" | |
| Finally.cs:38:23:38:43 | object creation of type Exception | Finally.cs:38:23:38:43 | After object creation of type Exception | |
| Finally.cs:38:37:38:42 | "Boo!" | Finally.cs:38:23:38:43 | object creation of type Exception | |
| Finally.cs:41:9:43:9 | After catch (...) {...} [match] | Finally.cs:42:9:43:9 | {...} | |
| Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] | Finally.cs:44:9:47:9 | catch {...} | |
| Finally.cs:41:9:43:9 | catch (...) {...} | Finally.cs:41:9:43:9 | After catch (...) {...} [match] | match |
| Finally.cs:41:9:43:9 | catch (...) {...} | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:41:9:43:9 | catch (...) {...} | Finally.cs:41:16:41:24 | access to type Exception | |
| Finally.cs:41:16:41:24 | After access to type Exception [match] | Finally.cs:42:9:43:9 | {...} | |
| Finally.cs:41:16:41:24 | After access to type Exception [no-match] | Finally.cs:41:9:43:9 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:41:16:41:24 | access to type Exception | Finally.cs:41:16:41:24 | After access to type Exception [match] | match |
| Finally.cs:41:16:41:24 | access to type Exception | Finally.cs:41:16:41:24 | After access to type Exception [no-match] | no-match |
| Finally.cs:42:9:43:9 | {...} | Finally.cs:49:9:51:9 | {...} | |
| Finally.cs:44:9:47:9 | After catch {...} [match] | Finally.cs:45:9:47:9 | {...} | |
| Finally.cs:44:9:47:9 | catch {...} | Finally.cs:44:9:47:9 | After catch {...} [match] | match |
| Finally.cs:44:9:47:9 | catch {...} | Finally.cs:45:9:47:9 | {...} | |
| Finally.cs:45:9:47:9 | {...} | Finally.cs:46:13:46:19 | Before return ...; | |
| Finally.cs:46:13:46:19 | Before return ...; | Finally.cs:46:13:46:19 | return ...; | |
| Finally.cs:46:13:46:19 | return ...; | Finally.cs:49:9:51:9 | {...} | return |
@@ -3460,21 +3467,23 @@
| Finally.cs:58:31:58:36 | "Try3" | Finally.cs:58:13:58:37 | call to method WriteLine | |
| Finally.cs:59:13:59:19 | Before return ...; | Finally.cs:59:13:59:19 | return ...; | |
| Finally.cs:59:13:59:19 | return ...; | Finally.cs:69:9:71:9 | {...} | return |
| Finally.cs:61:9:64:9 | After catch (...) {...} [match] | Finally.cs:61:38:61:39 | IOException ex | |
| Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | Finally.cs:65:9:67:9 | catch (...) {...} | |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:9:64:9 | After catch (...) {...} [match] | match |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:61:38:61:39 | IOException ex | Finally.cs:61:48:61:51 | true | |
| Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:38:61:39 | IOException ex | |
| Finally.cs:61:38:61:39 | After IOException ex [match] | Finally.cs:61:48:61:51 | true | |
| Finally.cs:61:38:61:39 | After IOException ex [no-match] | Finally.cs:61:9:64:9 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:61:38:61:39 | IOException ex | Finally.cs:61:38:61:39 | After IOException ex [match] | match |
| Finally.cs:61:38:61:39 | IOException ex | Finally.cs:61:38:61:39 | After IOException ex [no-match] | no-match |
| Finally.cs:61:48:61:51 | After true [true] | Finally.cs:62:9:64:9 | {...} | |
| Finally.cs:61:48:61:51 | true | Finally.cs:61:48:61:51 | After true [true] | true |
| Finally.cs:62:9:64:9 | {...} | Finally.cs:63:13:63:18 | Before throw ...; | |
| Finally.cs:63:13:63:18 | Before throw ...; | Finally.cs:63:13:63:18 | throw ...; | |
| Finally.cs:63:13:63:18 | throw ...; | Finally.cs:69:9:71:9 | {...} | exception |
| Finally.cs:65:9:67:9 | After catch (...) {...} [match] | Finally.cs:65:26:65:26 | Exception e | |
| Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] | Finally.cs:69:9:71:9 | {...} | exception |
| Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:65:9:67:9 | After catch (...) {...} [match] | match |
| Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:65:26:65:26 | Exception e | Finally.cs:65:35:65:51 | Before ... != ... | |
| Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:65:26:65:26 | Exception e | |
| Finally.cs:65:26:65:26 | After Exception e [match] | Finally.cs:65:35:65:51 | Before ... != ... | |
| Finally.cs:65:26:65:26 | After Exception e [no-match] | Finally.cs:65:9:67:9 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:65:26:65:26 | Exception e | Finally.cs:65:26:65:26 | After Exception e [match] | match |
| Finally.cs:65:26:65:26 | Exception e | Finally.cs:65:26:65:26 | After Exception e [no-match] | no-match |
| Finally.cs:65:35:65:35 | access to local variable e | Finally.cs:65:35:65:43 | access to property Message | |
| Finally.cs:65:35:65:43 | After access to property Message | Finally.cs:65:48:65:51 | null | |
| Finally.cs:65:35:65:43 | Before access to property Message | Finally.cs:65:35:65:35 | access to local variable e | |
@@ -3787,11 +3796,12 @@
| Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:159:27:159:44 | After object creation of type Exception | |
| Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:161:13:164:13 | catch (...) {...} | exception |
| Finally.cs:159:41:159:43 | "1" | Finally.cs:159:27:159:44 | object creation of type Exception | |
| Finally.cs:161:13:164:13 | After catch (...) {...} [match] | Finally.cs:161:30:161:30 | Exception e | |
| Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] | Finally.cs:165:13:168:13 | catch {...} | |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:13:164:13 | After catch (...) {...} [match] | match |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:161:30:161:30 | Exception e | Finally.cs:161:39:161:54 | Before ... == ... | |
| Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:30:161:30 | Exception e | |
| Finally.cs:161:30:161:30 | After Exception e [match] | Finally.cs:161:39:161:54 | Before ... == ... | |
| Finally.cs:161:30:161:30 | After Exception e [no-match] | Finally.cs:161:13:164:13 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:161:30:161:30 | Exception e | Finally.cs:161:30:161:30 | After Exception e [match] | match |
| Finally.cs:161:30:161:30 | Exception e | Finally.cs:161:30:161:30 | After Exception e [no-match] | no-match |
| Finally.cs:161:39:161:39 | access to local variable e | Finally.cs:161:39:161:47 | access to property Message | |
| Finally.cs:161:39:161:47 | After access to property Message | Finally.cs:161:52:161:54 | "1" | |
| Finally.cs:161:39:161:47 | Before access to property Message | Finally.cs:161:39:161:39 | access to local variable e | |
@@ -3814,8 +3824,7 @@
| Finally.cs:163:35:163:41 | Before access to array element | Finally.cs:163:35:163:38 | access to parameter args | |
| Finally.cs:163:35:163:41 | access to array element | Finally.cs:163:35:163:41 | After access to array element | |
| Finally.cs:163:40:163:40 | 0 | Finally.cs:163:35:163:41 | access to array element | |
| Finally.cs:165:13:168:13 | After catch {...} [match] | Finally.cs:166:13:168:13 | {...} | |
| Finally.cs:165:13:168:13 | catch {...} | Finally.cs:165:13:168:13 | After catch {...} [match] | match |
| Finally.cs:165:13:168:13 | catch {...} | Finally.cs:166:13:168:13 | {...} | |
| Finally.cs:166:13:168:13 | After {...} | Finally.cs:156:13:168:13 | After try {...} ... | |
| Finally.cs:166:13:168:13 | {...} | Finally.cs:167:17:167:38 | ...; | |
| Finally.cs:167:17:167:37 | After call to method WriteLine | Finally.cs:167:17:167:38 | After ...; | |
@@ -3896,10 +3905,12 @@
| Finally.cs:186:31:186:46 | Before object creation of type ExceptionB | Finally.cs:186:31:186:46 | object creation of type ExceptionB | |
| Finally.cs:186:31:186:46 | object creation of type ExceptionB | Finally.cs:186:31:186:46 | After object creation of type ExceptionB | |
| Finally.cs:186:31:186:46 | object creation of type ExceptionB | Finally.cs:188:13:191:13 | catch (...) {...} | exception |
| Finally.cs:188:13:191:13 | After catch (...) {...} [match] | Finally.cs:188:38:188:39 | access to parameter b2 | |
| Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] | Finally.cs:176:10:176:11 | Exceptional Exit | exception |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | After catch (...) {...} [match] | match |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:20:188:29 | access to type ExceptionB | |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | Finally.cs:188:38:188:39 | access to parameter b2 | |
| Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] | Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:188:20:188:29 | access to type ExceptionB | Finally.cs:188:20:188:29 | After access to type ExceptionB [match] | match |
| Finally.cs:188:20:188:29 | access to type ExceptionB | Finally.cs:188:20:188:29 | After access to type ExceptionB [no-match] | no-match |
| Finally.cs:188:38:188:39 | After access to parameter b2 [false] | Finally.cs:188:13:191:13 | After catch (...) {...} [no-match] | no-match |
| Finally.cs:188:38:188:39 | After access to parameter b2 [true] | Finally.cs:189:13:191:13 | {...} | |
| Finally.cs:188:38:188:39 | access to parameter b2 | Finally.cs:188:38:188:39 | After access to parameter b2 [false] | false |
@@ -4009,8 +4020,7 @@
| Finally.cs:220:13:220:37 | ...; | Finally.cs:220:13:220:36 | Before call to method WriteLine | |
| Finally.cs:220:13:220:37 | After ...; | Finally.cs:219:9:221:9 | After {...} | |
| Finally.cs:220:31:220:35 | "Try" | Finally.cs:220:13:220:36 | call to method WriteLine | |
| Finally.cs:222:9:225:9 | After catch {...} [match] | Finally.cs:223:9:225:9 | {...} | |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:222:9:225:9 | After catch {...} [match] | match |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:223:9:225:9 | {...} | |
| Finally.cs:223:9:225:9 | After {...} | Finally.cs:227:9:229:9 | {...} | |
| Finally.cs:223:9:225:9 | {...} | Finally.cs:224:13:224:39 | ...; | |
| Finally.cs:224:13:224:38 | After call to method WriteLine | Finally.cs:224:13:224:39 | After ...; | |

View File

@@ -101,7 +101,8 @@ csharp6.cs:
# 32| 0: [IntLiteral] 2
# 32| 0: [IntLiteral] 1
# 34| 1: [SpecificCatchClause] catch (...) {...}
# 34| 0: [TypeMention] IndexOutOfRangeException
# 34| 0: [TypeAccess] access to type IndexOutOfRangeException
# 34| 0: [TypeMention] IndexOutOfRangeException
# 35| 1: [BlockStmt] {...}
# 34| 2: [EQExpr] ... == ...
# 34| 0: [PropertyCall] access to property Value

View File

@@ -336,11 +336,12 @@
| patterns.cs:142:26:142:34 | { ... } | patterns.cs:142:26:142:34 | After { ... } | semmle.label | successor |
| patterns.cs:142:31:142:32 | 10 | patterns.cs:142:26:142:34 | { ... } | semmle.label | successor |
| patterns.cs:142:41:142:41 | 6 | patterns.cs:136:17:143:13 | After ... switch { ... } | semmle.label | successor |
| patterns.cs:145:9:148:9 | After catch (...) {...} [match] | patterns.cs:145:41:145:42 | InvalidOperationException ex | semmle.label | successor |
| patterns.cs:145:9:148:9 | After catch (...) {...} [no-match] | patterns.cs:123:10:123:21 | Exceptional Exit | semmle.label | exception |
| patterns.cs:145:9:148:9 | catch (...) {...} | patterns.cs:145:9:148:9 | After catch (...) {...} [match] | semmle.label | match |
| patterns.cs:145:9:148:9 | catch (...) {...} | patterns.cs:145:9:148:9 | After catch (...) {...} [no-match] | semmle.label | no-match |
| patterns.cs:145:41:145:42 | InvalidOperationException ex | patterns.cs:146:9:148:9 | {...} | semmle.label | successor |
| patterns.cs:145:9:148:9 | catch (...) {...} | patterns.cs:145:41:145:42 | InvalidOperationException ex | semmle.label | successor |
| patterns.cs:145:41:145:42 | After InvalidOperationException ex [match] | patterns.cs:146:9:148:9 | {...} | semmle.label | successor |
| patterns.cs:145:41:145:42 | After InvalidOperationException ex [no-match] | patterns.cs:145:9:148:9 | After catch (...) {...} [no-match] | semmle.label | no-match |
| patterns.cs:145:41:145:42 | InvalidOperationException ex | patterns.cs:145:41:145:42 | After InvalidOperationException ex [match] | semmle.label | match |
| patterns.cs:145:41:145:42 | InvalidOperationException ex | patterns.cs:145:41:145:42 | After InvalidOperationException ex [no-match] | semmle.label | no-match |
| patterns.cs:146:9:148:9 | After {...} | patterns.cs:134:9:148:9 | After try {...} ... | semmle.label | successor |
| patterns.cs:146:9:148:9 | {...} | patterns.cs:147:13:147:51 | ...; | semmle.label | successor |
| patterns.cs:147:13:147:50 | After call to method WriteLine | patterns.cs:147:13:147:51 | After ...; | semmle.label | successor |

View File

@@ -21,7 +21,7 @@
Java,"Java 7 to 26 [6]_","javac (OpenJDK and Oracle JDK),
Eclipse compiler for Java (ECJ) [7]_",``.java``
Kotlin,"Kotlin 1.8.0 to 2.3.2\ *x*","kotlinc",``.kt``
Kotlin,"Kotlin 1.8.0 to 2.4.0\ *x*","kotlinc",``.kt``
JavaScript,ECMAScript 2022 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [8]_"
Python [9]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13",Not applicable,``.py``
Ruby [10]_,"up to 3.3",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``"

View File

@@ -1,3 +1,7 @@
## 1.0.52
No user-facing changes.
## 1.0.51
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.0.52
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.0.51
lastReleaseVersion: 1.0.52

View File

@@ -1,5 +1,5 @@
name: codeql-go-consistency-queries
version: 1.0.52-dev
version: 1.0.52
groups:
- go
- queries

View File

@@ -1,3 +1,20 @@
## 7.2.0
### Deprecated APIs
* `FuncTypeExpr.getResultDecl()` has been deprecated. Use `FuncTypeExpr.getResultDecl(int i)` instead.
### Minor Analysis Improvements
* Added models for the `log/slog` package (Go 1.21+). Its logging functions and
`*slog.Logger` methods (`Debug`/`Info`/`Warn`/`Error`, their `Context`
variants, and `Log`/`LogAttrs`) are now recognized as logging sinks, so the
`go/log-injection` and `go/clear-text-logging` queries cover code that logs
through `slog`.
* `DataFlow::ResultNode`s are no longer created for returned expressions in functions with named result parameters. In this case there are already result nodes corresponding to `IR::ReadResultInstruction`s at the end of the function body.
* `FuncTypeExpr.getNumResult()` now gets the number of result parameters. It previously got the number of result declarations, which is different when one result declaration declares more than one variable, as in `x, y int`. All uses of it expected the number of result parameters. Its QLDoc has been updated.
* More logging functions are now recognized as not returning or panicking.
## 7.1.2
No user-facing changes.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* More logging functions are now recognized as not returning or panicking.

View File

@@ -1,4 +0,0 @@
---
category: deprecated
---
* `FuncTypeExpr.getResultDecl()` has been deprecated. Use `FuncTypeExpr.getResultDecl(int i)` instead.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* `DataFlow::ResultNode`s are no longer created for returned expressions in functions with named result parameters. In this case there are already result nodes corresponding to `IR::ReadResultInstruction`s at the end of the function body.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* `FuncTypeExpr.getNumResult()` now gets the number of result parameters. It previously got the number of result declarations, which is different when one result declaration declares more than one variable, as in `x, y int`. All uses of it expected the number of result parameters. Its QLDoc has been updated.

View File

@@ -1,8 +0,0 @@
---
category: minorAnalysis
---
* Added models for the `log/slog` package (Go 1.21+). Its logging functions and
`*slog.Logger` methods (`Debug`/`Info`/`Warn`/`Error`, their `Context`
variants, and `Log`/`LogAttrs`) are now recognized as logging sinks, so the
`go/log-injection` and `go/clear-text-logging` queries cover code that logs
through `slog`.

View File

@@ -0,0 +1,16 @@
## 7.2.0
### Deprecated APIs
* `FuncTypeExpr.getResultDecl()` has been deprecated. Use `FuncTypeExpr.getResultDecl(int i)` instead.
### Minor Analysis Improvements
* Added models for the `log/slog` package (Go 1.21+). Its logging functions and
`*slog.Logger` methods (`Debug`/`Info`/`Warn`/`Error`, their `Context`
variants, and `Log`/`LogAttrs`) are now recognized as logging sinks, so the
`go/log-injection` and `go/clear-text-logging` queries cover code that logs
through `slog`.
* `DataFlow::ResultNode`s are no longer created for returned expressions in functions with named result parameters. In this case there are already result nodes corresponding to `IR::ReadResultInstruction`s at the end of the function body.
* `FuncTypeExpr.getNumResult()` now gets the number of result parameters. It previously got the number of result declarations, which is different when one result declaration declares more than one variable, as in `x, y int`. All uses of it expected the number of result parameters. Its QLDoc has been updated.
* More logging functions are now recognized as not returning or panicking.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 7.1.2
lastReleaseVersion: 7.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/go-all
version: 7.1.3-dev
version: 7.2.0
groups: go
dbscheme: go.dbscheme
extractor: go

View File

@@ -1,3 +1,9 @@
## 1.6.5
### Minor Analysis Improvements
* The query `go/unhandled-writable-file-close` ("Writable file handle closed without error handling") now produces fewer false positives. A deferred call to `Close` that is preceded on every execution path by a handled call to `Sync` on the same file handle is no longer flagged.
## 1.6.4
No user-facing changes.

View File

@@ -1,4 +1,5 @@
---
category: minorAnalysis
---
## 1.6.5
### Minor Analysis Improvements
* The query `go/unhandled-writable-file-close` ("Writable file handle closed without error handling") now produces fewer false positives. A deferred call to `Close` that is preceded on every execution path by a handled call to `Sync` on the same file handle is no longer flagged.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.6.4
lastReleaseVersion: 1.6.5

View File

@@ -1,5 +1,5 @@
name: codeql/go-queries
version: 1.6.5-dev
version: 1.6.5
groups:
- go
- queries

View File

@@ -13,7 +13,7 @@ func logSomething(entry *logrus.Entry) {
entry.Traceln(text) // $ logger=text
}
func logrusCalls() {
func logrusCalls(selector int) {
err := errors.New("Error")
var fields logrus.Fields = nil
var fn logrus.LogFunction = nil
@@ -27,11 +27,15 @@ func logrusCalls() {
tmp = logrus.WithFields(fields) // $ logger=fields
logSomething(tmp)
logrus.Error(text) // $ logger=text
logrus.Fatalf(fmt, text) // $ logger=fmt logger=text
logrus.Panicln(text) // $ logger=text
logrus.Infof(fmt, text) // $ logger=fmt logger=text
logrus.FatalFn(fn) // $ logger=fn
logrus.Error(text) // $ logger=text
logrus.Infof(fmt, text) // $ logger=fmt logger=text
if selector == 0 {
logrus.Fatalf(fmt, text) // $ logger=fmt logger=text
} else if selector == 1 {
logrus.Panicln(text) // $ logger=text
} else if selector == 2 {
logrus.FatalFn(fn) // $ logger=fn
}
// components corresponding to the format specifier "%T" are not considered vulnerable
logrus.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v

View File

@@ -8,6 +8,6 @@ var v []byte
func main() {
glogTest(len(v))
stdlib()
stdlib(len(v))
slogTest()
}

View File

@@ -4,37 +4,69 @@ import (
"log"
)
func stdlib() {
func stdlib(selector int) {
var logger log.Logger
logger.SetPrefix("prefix: ")
logger.Fatal(text) // $ logger=text
logger.Fatalf(fmt, text) // $ logger=fmt logger=text
logger.Fatalln(text) // $ logger=text
logger.Panic(text) // $ logger=text
logger.Panicf(fmt, text) // $ logger=fmt logger=text
logger.Panicln(text) // $ logger=text
logger.Print(text) // $ logger=text
logger.Printf(fmt, text) // $ logger=fmt logger=text
logger.Println(text) // $ logger=text
switch selector {
case 0:
logger.Fatal(text) // $ logger=text
case 1:
logger.Fatalf(fmt, text) // $ logger=fmt logger=text
case 2:
logger.Fatalln(text) // $ logger=text
case 3:
logger.Panic(text) // $ logger=text
case 4:
logger.Panicf(fmt, text) // $ logger=fmt logger=text
case 5:
logger.Panicln(text) // $ logger=text
case 6:
logger.Print(text) // $ logger=text
case 7:
logger.Printf(fmt, text) // $ logger=fmt logger=text
case 8:
logger.Println(text) // $ logger=text
}
// components corresponding to the format specifier "%T" are not considered vulnerable
logger.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
logger.Panicf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
logger.Printf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
switch selector {
case 9:
logger.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
case 10:
logger.Panicf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
case 11:
logger.Printf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
}
log.SetPrefix("prefix: ")
log.Fatal(text) // $ logger=text
log.Fatalf(fmt, text) // $ logger=fmt logger=text
log.Fatalln(text) // $ logger=text
log.Panic(text) // $ logger=text
log.Panicf(fmt, text) // $ logger=fmt logger=text
log.Panicln(text) // $ logger=text
log.Print(text) // $ logger=text
log.Printf(fmt, text) // $ logger=fmt logger=text
log.Println(text) // $ logger=text
switch selector {
case 12:
log.Fatal(text) // $ logger=text
case 13:
log.Fatalf(fmt, text) // $ logger=fmt logger=text
case 14:
log.Fatalln(text) // $ logger=text
case 15:
log.Panic(text) // $ logger=text
case 16:
log.Panicf(fmt, text) // $ logger=fmt logger=text
case 17:
log.Panicln(text) // $ logger=text
case 18:
log.Print(text) // $ logger=text
case 19:
log.Printf(fmt, text) // $ logger=fmt logger=text
case 20:
log.Println(text) // $ logger=text
}
// components corresponding to the format specifier "%T" are not considered vulnerable
log.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
log.Panicf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
log.Printf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
switch selector {
case 21:
log.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
case 22:
log.Panicf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
case 23:
log.Printf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
}
}

View File

@@ -34,6 +34,265 @@
| DuplicateSwitchCase.go:16:1:16:14 | function declaration | DuplicateSwitchCase.go:0:0:0:0 | exit |
| DuplicateSwitchCase.go:16:6:16:9 | skip | DuplicateSwitchCase.go:16:1:16:14 | function declaration |
| DuplicateSwitchCase.go:16:13:16:14 | skip | DuplicateSwitchCase.go:16:1:16:14 | exit |
| epilogues.go:0:0:0:0 | entry | epilogues.go:3:1:3:12 | skip |
| epilogues.go:3:1:3:12 | skip | epilogues.go:8:1:10:1 | skip |
| epilogues.go:8:1:10:1 | skip | epilogues.go:12:21:12:23 | skip |
| epilogues.go:12:1:14:1 | entry | epilogues.go:12:7:12:7 | argument corresponding to l |
| epilogues.go:12:1:14:1 | function declaration | epilogues.go:16:20:16:27 | skip |
| epilogues.go:12:7:12:7 | argument corresponding to l | epilogues.go:12:7:12:7 | initialization of l |
| epilogues.go:12:7:12:7 | initialization of l | epilogues.go:12:25:12:27 | argument corresponding to msg |
| epilogues.go:12:21:12:23 | skip | epilogues.go:12:1:14:1 | function declaration |
| epilogues.go:12:25:12:27 | argument corresponding to msg | epilogues.go:12:25:12:27 | initialization of msg |
| epilogues.go:12:25:12:27 | initialization of msg | epilogues.go:12:37:12:40 | argument corresponding to code |
| epilogues.go:12:37:12:40 | argument corresponding to code | epilogues.go:12:37:12:40 | initialization of code |
| epilogues.go:12:37:12:40 | initialization of code | epilogues.go:13:2:13:12 | selection of Println |
| epilogues.go:13:2:13:12 | selection of Println | epilogues.go:13:14:13:14 | l |
| epilogues.go:13:2:13:33 | call to Println | epilogues.go:12:1:14:1 | exit |
| epilogues.go:13:14:13:14 | implicit dereference | epilogues.go:12:1:14:1 | exit |
| epilogues.go:13:14:13:14 | implicit dereference | epilogues.go:13:14:13:21 | selection of prefix |
| epilogues.go:13:14:13:14 | l | epilogues.go:13:14:13:14 | implicit dereference |
| epilogues.go:13:14:13:21 | selection of prefix | epilogues.go:13:24:13:26 | msg |
| epilogues.go:13:24:13:26 | msg | epilogues.go:13:29:13:32 | code |
| epilogues.go:13:29:13:32 | code | epilogues.go:13:2:13:33 | call to Println |
| epilogues.go:16:1:18:1 | entry | epilogues.go:16:7:16:7 | argument corresponding to l |
| epilogues.go:16:1:18:1 | function declaration | epilogues.go:23:6:23:15 | skip |
| epilogues.go:16:7:16:7 | argument corresponding to l | epilogues.go:16:7:16:7 | initialization of l |
| epilogues.go:16:7:16:7 | initialization of l | epilogues.go:16:29:16:31 | argument corresponding to msg |
| epilogues.go:16:20:16:27 | skip | epilogues.go:16:1:18:1 | function declaration |
| epilogues.go:16:29:16:31 | argument corresponding to msg | epilogues.go:16:29:16:31 | initialization of msg |
| epilogues.go:16:29:16:31 | initialization of msg | epilogues.go:17:2:17:12 | selection of Println |
| epilogues.go:17:2:17:12 | selection of Println | epilogues.go:17:14:17:14 | l |
| epilogues.go:17:2:17:27 | call to Println | epilogues.go:16:1:18:1 | exit |
| epilogues.go:17:14:17:14 | l | epilogues.go:17:14:17:21 | selection of prefix |
| epilogues.go:17:14:17:21 | selection of prefix | epilogues.go:17:24:17:26 | msg |
| epilogues.go:17:24:17:26 | msg | epilogues.go:17:2:17:27 | call to Println |
| epilogues.go:23:1:27:1 | entry | epilogues.go:24:5:24:5 | skip |
| epilogues.go:23:1:27:1 | function declaration | epilogues.go:31:6:31:13 | skip |
| epilogues.go:23:6:23:15 | skip | epilogues.go:23:1:27:1 | function declaration |
| epilogues.go:24:5:24:5 | assignment to r | epilogues.go:24:21:24:21 | r |
| epilogues.go:24:5:24:5 | skip | epilogues.go:24:10:24:16 | recover |
| epilogues.go:24:10:24:16 | recover | epilogues.go:24:10:24:18 | call to recover |
| epilogues.go:24:10:24:18 | call to recover | epilogues.go:24:5:24:5 | assignment to r |
| epilogues.go:24:21:24:21 | r | epilogues.go:24:26:24:28 | nil |
| epilogues.go:24:21:24:28 | ...!=... | epilogues.go:23:1:27:1 | exit |
| epilogues.go:24:21:24:28 | ...!=... | epilogues.go:24:21:24:28 | ...!=... is false |
| epilogues.go:24:21:24:28 | ...!=... | epilogues.go:24:21:24:28 | ...!=... is true |
| epilogues.go:24:21:24:28 | ...!=... is false | epilogues.go:23:1:27:1 | exit |
| epilogues.go:24:21:24:28 | ...!=... is true | epilogues.go:25:3:25:13 | selection of Println |
| epilogues.go:24:26:24:28 | nil | epilogues.go:24:21:24:28 | ...!=... |
| epilogues.go:25:3:25:13 | selection of Println | epilogues.go:25:15:25:26 | "recovered:" |
| epilogues.go:25:3:25:30 | call to Println | epilogues.go:23:1:27:1 | exit |
| epilogues.go:25:15:25:26 | "recovered:" | epilogues.go:25:29:25:29 | r |
| epilogues.go:25:29:25:29 | r | epilogues.go:25:3:25:30 | call to Println |
| epilogues.go:31:1:33:1 | entry | epilogues.go:31:15:31:15 | argument corresponding to x |
| epilogues.go:31:1:33:1 | function declaration | epilogues.go:36:6:36:12 | skip |
| epilogues.go:31:6:31:13 | skip | epilogues.go:31:1:33:1 | function declaration |
| epilogues.go:31:15:31:15 | argument corresponding to x | epilogues.go:31:15:31:15 | initialization of x |
| epilogues.go:31:15:31:15 | initialization of x | epilogues.go:32:9:32:9 | x |
| epilogues.go:32:2:32:13 | return statement | epilogues.go:31:1:33:1 | exit |
| epilogues.go:32:9:32:9 | x | epilogues.go:32:13:32:13 | 2 |
| epilogues.go:32:9:32:13 | ...*... | epilogues.go:32:2:32:13 | return statement |
| epilogues.go:32:13:32:13 | 2 | epilogues.go:32:9:32:13 | ...*... |
| epilogues.go:36:1:38:1 | entry | epilogues.go:37:2:37:12 | selection of Println |
| epilogues.go:36:1:38:1 | function declaration | epilogues.go:42:6:42:18 | skip |
| epilogues.go:36:6:36:12 | skip | epilogues.go:36:1:38:1 | function declaration |
| epilogues.go:37:2:37:12 | selection of Println | epilogues.go:37:14:37:19 | "void" |
| epilogues.go:37:2:37:20 | call to Println | epilogues.go:36:1:38:1 | exit |
| epilogues.go:37:14:37:19 | "void" | epilogues.go:37:2:37:20 | call to Println |
| epilogues.go:42:1:48:1 | entry | epilogues.go:42:20:42:20 | argument corresponding to x |
| epilogues.go:42:1:48:1 | function declaration | epilogues.go:51:6:51:21 | skip |
| epilogues.go:42:6:42:18 | skip | epilogues.go:42:1:48:1 | function declaration |
| epilogues.go:42:20:42:20 | argument corresponding to x | epilogues.go:42:20:42:20 | initialization of x |
| epilogues.go:42:20:42:20 | initialization of x | epilogues.go:42:28:42:33 | zero value for result |
| epilogues.go:42:28:42:33 | implicit read of result | epilogues.go:42:40:42:42 | implicit read of err |
| epilogues.go:42:28:42:33 | initialization of result | epilogues.go:42:40:42:42 | zero value for err |
| epilogues.go:42:28:42:33 | zero value for result | epilogues.go:42:28:42:33 | initialization of result |
| epilogues.go:42:40:42:42 | implicit read of err | epilogues.go:42:1:48:1 | exit |
| epilogues.go:42:40:42:42 | initialization of err | epilogues.go:43:5:43:5 | x |
| epilogues.go:42:40:42:42 | zero value for err | epilogues.go:42:40:42:42 | initialization of err |
| epilogues.go:43:5:43:5 | x | epilogues.go:43:9:43:9 | 0 |
| epilogues.go:43:5:43:9 | ...<... | epilogues.go:43:5:43:9 | ...<... is false |
| epilogues.go:43:5:43:9 | ...<... | epilogues.go:43:5:43:9 | ...<... is true |
| epilogues.go:43:5:43:9 | ...<... is false | epilogues.go:47:9:47:9 | x |
| epilogues.go:43:5:43:9 | ...<... is true | epilogues.go:44:3:44:8 | skip |
| epilogues.go:43:9:43:9 | 0 | epilogues.go:43:5:43:9 | ...<... |
| epilogues.go:44:3:44:8 | assignment to result | epilogues.go:45:3:45:8 | return statement |
| epilogues.go:44:3:44:8 | skip | epilogues.go:44:13:44:13 | x |
| epilogues.go:44:12:44:13 | -... | epilogues.go:44:3:44:8 | assignment to result |
| epilogues.go:44:13:44:13 | x | epilogues.go:44:12:44:13 | -... |
| epilogues.go:45:3:45:8 | return statement | epilogues.go:42:28:42:33 | implicit read of result |
| epilogues.go:47:2:47:14 | return statement | epilogues.go:42:28:42:33 | implicit read of result |
| epilogues.go:47:9:47:9 | implicit write of result | epilogues.go:47:12:47:14 | nil |
| epilogues.go:47:9:47:9 | x | epilogues.go:47:9:47:9 | implicit write of result |
| epilogues.go:47:12:47:14 | implicit write of err | epilogues.go:47:2:47:14 | return statement |
| epilogues.go:47:12:47:14 | nil | epilogues.go:47:12:47:14 | implicit write of err |
| epilogues.go:51:1:54:1 | entry | epilogues.go:51:23:51:23 | argument corresponding to x |
| epilogues.go:51:1:54:1 | function declaration | epilogues.go:59:6:59:25 | skip |
| epilogues.go:51:6:51:21 | skip | epilogues.go:51:1:54:1 | function declaration |
| epilogues.go:51:23:51:23 | argument corresponding to x | epilogues.go:51:23:51:23 | initialization of x |
| epilogues.go:51:23:51:23 | initialization of x | epilogues.go:51:31:51:31 | zero value for n |
| epilogues.go:51:31:51:31 | implicit read of n | epilogues.go:51:1:54:1 | exit |
| epilogues.go:51:31:51:31 | initialization of n | epilogues.go:52:2:52:2 | skip |
| epilogues.go:51:31:51:31 | zero value for n | epilogues.go:51:31:51:31 | initialization of n |
| epilogues.go:52:2:52:2 | assignment to n | epilogues.go:53:2:53:7 | return statement |
| epilogues.go:52:2:52:2 | skip | epilogues.go:52:6:52:6 | x |
| epilogues.go:52:6:52:6 | x | epilogues.go:52:10:52:10 | 1 |
| epilogues.go:52:6:52:10 | ...+... | epilogues.go:52:2:52:2 | assignment to n |
| epilogues.go:52:10:52:10 | 1 | epilogues.go:52:6:52:10 | ...+... |
| epilogues.go:53:2:53:7 | return statement | epilogues.go:51:31:51:31 | implicit read of n |
| epilogues.go:59:1:62:1 | entry | epilogues.go:59:27:59:27 | argument corresponding to l |
| epilogues.go:59:1:62:1 | function declaration | epilogues.go:66:6:66:26 | skip |
| epilogues.go:59:6:59:25 | skip | epilogues.go:59:1:62:1 | function declaration |
| epilogues.go:59:27:59:27 | argument corresponding to l | epilogues.go:59:27:59:27 | initialization of l |
| epilogues.go:59:27:59:27 | initialization of l | epilogues.go:59:41:59:45 | argument corresponding to items |
| epilogues.go:59:41:59:45 | argument corresponding to items | epilogues.go:59:41:59:45 | initialization of items |
| epilogues.go:59:41:59:45 | initialization of items | epilogues.go:60:8:60:8 | l |
| epilogues.go:60:2:60:33 | defer statement | epilogues.go:61:2:61:12 | selection of Println |
| epilogues.go:60:8:60:8 | l | epilogues.go:60:8:60:12 | selection of log |
| epilogues.go:60:8:60:12 | selection of log | epilogues.go:60:14:60:20 | "count" |
| epilogues.go:60:8:60:33 | call to log | epilogues.go:59:1:62:1 | exit |
| epilogues.go:60:14:60:20 | "count" | epilogues.go:60:23:60:25 | len |
| epilogues.go:60:23:60:25 | len | epilogues.go:60:27:60:31 | items |
| epilogues.go:60:23:60:32 | call to len | epilogues.go:60:2:60:33 | defer statement |
| epilogues.go:60:27:60:31 | items | epilogues.go:60:23:60:32 | call to len |
| epilogues.go:61:2:61:12 | selection of Println | epilogues.go:61:14:61:25 | "processing" |
| epilogues.go:61:2:61:38 | call to Println | epilogues.go:60:8:60:33 | call to log |
| epilogues.go:61:14:61:25 | "processing" | epilogues.go:61:28:61:30 | len |
| epilogues.go:61:28:61:30 | len | epilogues.go:61:32:61:36 | items |
| epilogues.go:61:28:61:37 | call to len | epilogues.go:61:2:61:38 | call to Println |
| epilogues.go:61:32:61:36 | items | epilogues.go:61:28:61:37 | call to len |
| epilogues.go:66:1:71:1 | entry | epilogues.go:66:28:66:33 | argument corresponding to prefix |
| epilogues.go:66:1:71:1 | function declaration | epilogues.go:77:6:77:20 | skip |
| epilogues.go:66:6:66:26 | skip | epilogues.go:66:1:71:1 | function declaration |
| epilogues.go:66:28:66:33 | argument corresponding to prefix | epilogues.go:66:28:66:33 | initialization of prefix |
| epilogues.go:66:28:66:33 | initialization of prefix | epilogues.go:67:2:67:2 | skip |
| epilogues.go:67:2:67:2 | assignment to l | epilogues.go:68:8:68:8 | l |
| epilogues.go:67:2:67:2 | skip | epilogues.go:67:7:67:31 | struct literal |
| epilogues.go:67:7:67:31 | struct literal | epilogues.go:67:25:67:30 | prefix |
| epilogues.go:67:17:67:30 | init of key-value pair | epilogues.go:67:2:67:2 | assignment to l |
| epilogues.go:67:25:67:30 | prefix | epilogues.go:67:17:67:30 | init of key-value pair |
| epilogues.go:68:2:68:24 | defer statement | epilogues.go:69:10:69:10 | l |
| epilogues.go:68:8:68:8 | l | epilogues.go:68:8:68:17 | selection of logValue |
| epilogues.go:68:8:68:17 | selection of logValue | epilogues.go:68:19:68:23 | "bye" |
| epilogues.go:68:8:68:24 | call to logValue | epilogues.go:66:1:71:1 | exit |
| epilogues.go:68:19:68:23 | "bye" | epilogues.go:68:2:68:24 | defer statement |
| epilogues.go:69:2:69:25 | defer statement | epilogues.go:70:2:70:12 | selection of Println |
| epilogues.go:69:8:69:15 | selection of log | epilogues.go:69:17:69:21 | "ptr" |
| epilogues.go:69:8:69:25 | call to log | epilogues.go:68:8:68:24 | call to logValue |
| epilogues.go:69:9:69:10 | &... | epilogues.go:69:8:69:15 | selection of log |
| epilogues.go:69:10:69:10 | l | epilogues.go:69:9:69:10 | &... |
| epilogues.go:69:17:69:21 | "ptr" | epilogues.go:69:24:69:24 | 7 |
| epilogues.go:69:24:69:24 | 7 | epilogues.go:69:2:69:25 | defer statement |
| epilogues.go:70:2:70:12 | selection of Println | epilogues.go:70:14:70:19 | "body" |
| epilogues.go:70:2:70:20 | call to Println | epilogues.go:69:8:69:25 | call to log |
| epilogues.go:70:14:70:19 | "body" | epilogues.go:70:2:70:20 | call to Println |
| epilogues.go:77:1:82:1 | entry | epilogues.go:77:22:77:22 | argument corresponding to x |
| epilogues.go:77:1:82:1 | function declaration | epilogues.go:87:6:87:20 | skip |
| epilogues.go:77:6:77:20 | skip | epilogues.go:77:1:82:1 | function declaration |
| epilogues.go:77:22:77:22 | argument corresponding to x | epilogues.go:77:22:77:22 | initialization of x |
| epilogues.go:77:22:77:22 | initialization of x | epilogues.go:78:8:80:2 | function literal |
| epilogues.go:78:2:80:15 | defer statement | epilogues.go:81:2:81:12 | selection of Println |
| epilogues.go:78:8:80:2 | entry | epilogues.go:78:13:78:17 | argument corresponding to label |
| epilogues.go:78:8:80:2 | function literal | epilogues.go:80:4:80:9 | "done" |
| epilogues.go:78:8:80:15 | function call | epilogues.go:77:1:82:1 | exit |
| epilogues.go:78:13:78:17 | argument corresponding to label | epilogues.go:78:13:78:17 | initialization of label |
| epilogues.go:78:13:78:17 | initialization of label | epilogues.go:78:27:78:27 | argument corresponding to n |
| epilogues.go:78:27:78:27 | argument corresponding to n | epilogues.go:78:27:78:27 | initialization of n |
| epilogues.go:78:27:78:27 | initialization of n | epilogues.go:79:3:79:13 | selection of Println |
| epilogues.go:79:3:79:13 | selection of Println | epilogues.go:79:15:79:19 | label |
| epilogues.go:79:3:79:23 | call to Println | epilogues.go:78:8:80:2 | exit |
| epilogues.go:79:15:79:19 | label | epilogues.go:79:22:79:22 | n |
| epilogues.go:79:22:79:22 | n | epilogues.go:79:3:79:23 | call to Println |
| epilogues.go:80:4:80:9 | "done" | epilogues.go:80:12:80:12 | x |
| epilogues.go:80:12:80:12 | x | epilogues.go:80:14:80:14 | 1 |
| epilogues.go:80:12:80:14 | ...+... | epilogues.go:78:2:80:15 | defer statement |
| epilogues.go:80:14:80:14 | 1 | epilogues.go:80:12:80:14 | ...+... |
| epilogues.go:81:2:81:12 | selection of Println | epilogues.go:81:14:81:19 | "body" |
| epilogues.go:81:2:81:23 | call to Println | epilogues.go:78:8:80:15 | function call |
| epilogues.go:81:14:81:19 | "body" | epilogues.go:81:22:81:22 | x |
| epilogues.go:81:22:81:22 | x | epilogues.go:81:2:81:23 | call to Println |
| epilogues.go:87:1:98:1 | entry | epilogues.go:87:22:87:22 | argument corresponding to x |
| epilogues.go:87:1:98:1 | function declaration | epilogues.go:102:6:102:24 | skip |
| epilogues.go:87:6:87:20 | skip | epilogues.go:87:1:98:1 | function declaration |
| epilogues.go:87:22:87:22 | argument corresponding to x | epilogues.go:87:22:87:22 | initialization of x |
| epilogues.go:87:22:87:22 | initialization of x | epilogues.go:87:30:87:35 | zero value for result |
| epilogues.go:87:30:87:35 | implicit read of result | epilogues.go:87:1:98:1 | exit |
| epilogues.go:87:30:87:35 | initialization of result | epilogues.go:88:8:92:2 | function literal |
| epilogues.go:87:30:87:35 | zero value for result | epilogues.go:87:30:87:35 | initialization of result |
| epilogues.go:88:2:92:4 | defer statement | epilogues.go:93:5:93:5 | x |
| epilogues.go:88:8:92:2 | entry | epilogues.go:89:6:89:6 | skip |
| epilogues.go:88:8:92:2 | function literal | epilogues.go:88:2:92:4 | defer statement |
| epilogues.go:88:8:92:4 | function call | epilogues.go:87:1:98:1 | exit |
| epilogues.go:88:8:92:4 | function call | epilogues.go:87:30:87:35 | implicit read of result |
| epilogues.go:89:6:89:6 | assignment to r | epilogues.go:89:22:89:22 | r |
| epilogues.go:89:6:89:6 | skip | epilogues.go:89:11:89:17 | recover |
| epilogues.go:89:11:89:17 | recover | epilogues.go:89:11:89:19 | call to recover |
| epilogues.go:89:11:89:19 | call to recover | epilogues.go:89:6:89:6 | assignment to r |
| epilogues.go:89:22:89:22 | r | epilogues.go:89:27:89:29 | nil |
| epilogues.go:89:22:89:29 | ...!=... | epilogues.go:88:8:92:2 | exit |
| epilogues.go:89:22:89:29 | ...!=... | epilogues.go:89:22:89:29 | ...!=... is false |
| epilogues.go:89:22:89:29 | ...!=... | epilogues.go:89:22:89:29 | ...!=... is true |
| epilogues.go:89:22:89:29 | ...!=... is false | epilogues.go:88:8:92:2 | exit |
| epilogues.go:89:22:89:29 | ...!=... is true | epilogues.go:90:4:90:9 | skip |
| epilogues.go:89:27:89:29 | nil | epilogues.go:89:22:89:29 | ...!=... |
| epilogues.go:90:4:90:9 | assignment to result | epilogues.go:88:8:92:2 | exit |
| epilogues.go:90:4:90:9 | skip | epilogues.go:90:13:90:14 | -... |
| epilogues.go:90:13:90:14 | -... | epilogues.go:90:4:90:9 | assignment to result |
| epilogues.go:93:5:93:5 | x | epilogues.go:93:9:93:9 | 0 |
| epilogues.go:93:5:93:9 | ...<... | epilogues.go:93:5:93:9 | ...<... is false |
| epilogues.go:93:5:93:9 | ...<... | epilogues.go:93:5:93:9 | ...<... is true |
| epilogues.go:93:5:93:9 | ...<... is false | epilogues.go:96:2:96:7 | skip |
| epilogues.go:93:5:93:9 | ...<... is true | epilogues.go:94:3:94:7 | panic |
| epilogues.go:93:9:93:9 | 0 | epilogues.go:93:5:93:9 | ...<... |
| epilogues.go:94:3:94:7 | panic | epilogues.go:94:9:94:13 | "neg" |
| epilogues.go:94:3:94:14 | call to panic | epilogues.go:88:8:92:4 | function call |
| epilogues.go:94:9:94:13 | "neg" | epilogues.go:94:3:94:14 | call to panic |
| epilogues.go:96:2:96:7 | assignment to result | epilogues.go:97:9:97:14 | result |
| epilogues.go:96:2:96:7 | skip | epilogues.go:96:11:96:11 | x |
| epilogues.go:96:11:96:11 | x | epilogues.go:96:15:96:15 | x |
| epilogues.go:96:11:96:15 | ...*... | epilogues.go:96:2:96:7 | assignment to result |
| epilogues.go:96:15:96:15 | x | epilogues.go:96:11:96:15 | ...*... |
| epilogues.go:97:2:97:14 | return statement | epilogues.go:88:8:92:4 | function call |
| epilogues.go:97:9:97:14 | implicit write of result | epilogues.go:97:2:97:14 | return statement |
| epilogues.go:97:9:97:14 | result | epilogues.go:97:9:97:14 | implicit write of result |
| epilogues.go:102:1:110:1 | entry | epilogues.go:102:26:102:26 | argument corresponding to x |
| epilogues.go:102:1:110:1 | function declaration | epilogues.go:115:6:115:22 | skip |
| epilogues.go:102:6:102:24 | skip | epilogues.go:102:1:110:1 | function declaration |
| epilogues.go:102:26:102:26 | argument corresponding to x | epilogues.go:102:26:102:26 | initialization of x |
| epilogues.go:102:26:102:26 | initialization of x | epilogues.go:102:34:102:35 | zero value for ok |
| epilogues.go:102:34:102:35 | implicit read of ok | epilogues.go:102:43:102:43 | implicit read of n |
| epilogues.go:102:34:102:35 | initialization of ok | epilogues.go:102:43:102:43 | zero value for n |
| epilogues.go:102:34:102:35 | zero value for ok | epilogues.go:102:34:102:35 | initialization of ok |
| epilogues.go:102:43:102:43 | implicit read of n | epilogues.go:102:1:110:1 | exit |
| epilogues.go:102:43:102:43 | initialization of n | epilogues.go:103:8:103:17 | epiRecover |
| epilogues.go:102:43:102:43 | zero value for n | epilogues.go:102:43:102:43 | initialization of n |
| epilogues.go:103:2:103:19 | defer statement | epilogues.go:104:5:104:5 | x |
| epilogues.go:103:8:103:17 | epiRecover | epilogues.go:103:2:103:19 | defer statement |
| epilogues.go:103:8:103:19 | call to epiRecover | epilogues.go:102:1:110:1 | exit |
| epilogues.go:103:8:103:19 | call to epiRecover | epilogues.go:102:34:102:35 | implicit read of ok |
| epilogues.go:104:5:104:5 | x | epilogues.go:104:10:104:10 | 0 |
| epilogues.go:104:5:104:10 | ...==... | epilogues.go:104:5:104:10 | ...==... is false |
| epilogues.go:104:5:104:10 | ...==... | epilogues.go:104:5:104:10 | ...==... is true |
| epilogues.go:104:5:104:10 | ...==... is false | epilogues.go:107:2:107:2 | skip |
| epilogues.go:104:5:104:10 | ...==... is true | epilogues.go:105:3:105:8 | return statement |
| epilogues.go:104:10:104:10 | 0 | epilogues.go:104:5:104:10 | ...==... |
| epilogues.go:105:3:105:8 | return statement | epilogues.go:103:8:103:19 | call to epiRecover |
| epilogues.go:107:2:107:2 | assignment to n | epilogues.go:108:2:108:3 | skip |
| epilogues.go:107:2:107:2 | skip | epilogues.go:107:6:107:6 | x |
| epilogues.go:107:6:107:6 | x | epilogues.go:107:2:107:2 | assignment to n |
| epilogues.go:108:2:108:3 | assignment to ok | epilogues.go:109:2:109:7 | return statement |
| epilogues.go:108:2:108:3 | skip | epilogues.go:108:7:108:10 | true |
| epilogues.go:108:7:108:10 | true | epilogues.go:108:2:108:3 | assignment to ok |
| epilogues.go:109:2:109:7 | return statement | epilogues.go:103:8:103:19 | call to epiRecover |
| epilogues.go:115:1:118:1 | entry | epilogues.go:116:8:116:17 | epiRecover |
| epilogues.go:115:1:118:1 | function declaration | epilogues.go:0:0:0:0 | exit |
| epilogues.go:115:6:115:22 | skip | epilogues.go:115:1:118:1 | function declaration |
| epilogues.go:116:2:116:19 | defer statement | epilogues.go:117:2:117:6 | panic |
| epilogues.go:116:8:116:17 | epiRecover | epilogues.go:116:2:116:19 | defer statement |
| epilogues.go:116:8:116:19 | call to epiRecover | epilogues.go:115:1:118:1 | exit |
| epilogues.go:117:2:117:6 | panic | epilogues.go:117:8:117:13 | "boom" |
| epilogues.go:117:2:117:14 | call to panic | epilogues.go:116:8:116:19 | call to epiRecover |
| epilogues.go:117:8:117:13 | "boom" | epilogues.go:117:2:117:14 | call to panic |
| equalitytests.go:0:0:0:0 | entry | equalitytests.go:3:1:5:1 | skip |
| equalitytests.go:3:1:5:1 | skip | equalitytests.go:7:1:9:1 | skip |
| equalitytests.go:7:1:9:1 | skip | equalitytests.go:11:6:11:18 | skip |

View File

@@ -1,3 +1,4 @@
| epilogues.go:115:6:115:22 | epiRecoverUnnamed | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.epiRecoverUnnamed |
| file://:0:0:0:0 | Exit | os.Exit |
| file://:0:0:0:0 | Fatal | log.Fatal |
| file://:0:0:0:0 | Fatal | log.Logger.Fatal |

View File

@@ -0,0 +1,118 @@
package main
import "fmt"
// epiLogger has methods with both pointer and value receivers, used to check
// that the receiver and arguments of a deferred call are evaluated at the
// `defer` statement rather than in the function epilogue.
type epiLogger struct {
prefix string
}
func (l *epiLogger) log(msg string, code int) {
fmt.Println(l.prefix, msg, code)
}
func (l epiLogger) logValue(msg string) {
fmt.Println(l.prefix, msg)
}
// epiRecover recovers from a panic. It is used as a deferred function so we can
// check that control flow returns to the result-read nodes and the normal exit
// node after recovering.
func epiRecover() {
if r := recover(); r != nil {
fmt.Println("recovered:", r)
}
}
// epiPlain has no named result variable and a single `return` with a child
// expression.
func epiPlain(x int) int {
return x * 2
}
// epiVoid has no named result variable and no `return` statement at all.
func epiVoid() {
fmt.Println("void")
}
// epiNamedMixed has named result variables and a mix of a bare `return` (no
// child expressions) and a `return` with child expressions.
func epiNamedMixed(x int) (result int, err error) {
if x < 0 {
result = -x
return
}
return x, nil
}
// epiNamedBareOnly has a named result variable and only a bare `return`.
func epiNamedBareOnly(x int) (n int) {
n = x + 1
return
}
// epiDeferReceiverArgs has a deferred call with a (pointer) receiver and
// arguments that are expressions, so we can check the receiver `l` and the
// arguments `"count"` and `len(items)` are evaluated at the `defer` statement.
func epiDeferReceiverArgs(l *epiLogger, items []int) {
defer l.log("count", len(items))
fmt.Println("processing", len(items))
}
// epiDeferValueReceiver has deferred calls with a value receiver and an
// address-of receiver, both with arguments evaluated at the `defer` statement.
func epiDeferValueReceiver(prefix string) {
l := epiLogger{prefix: prefix}
defer l.logValue("bye")
defer (&l).log("ptr", 7)
fmt.Println("body")
}
// epiDeferFuncLit has a deferred function literal with parameters, so we can
// check that the arguments `"done"` and `x+1` are evaluated at the `defer`
// statement and that control flow enters the function literal body when it is
// invoked at the function epilogue.
func epiDeferFuncLit(x int) {
defer func(label string, n int) {
fmt.Println(label, n)
}("done", x+1)
fmt.Println("body", x)
}
// epiRecoverNamed has a named result variable and a deferred closure containing
// `recover()`. After recovering on the panic path, control flow should return
// to the result-read nodes and the normal exit node.
func epiRecoverNamed(x int) (result int) {
defer func() {
if r := recover(); r != nil {
result = -1
}
}()
if x < 0 {
panic("neg")
}
result = x * x
return result
}
// epiRecoverNamedBare has named result variables, a deferred function
// containing `recover()`, and only bare `return` statements.
func epiRecoverNamedBare(x int) (ok bool, n int) {
defer epiRecover()
if x == 0 {
return
}
n = x
ok = true
return
}
// epiRecoverUnnamed has no named result variables and a deferred function
// containing `recover()`; after recovering, control flow should reach the
// normal exit node directly (there are no result-read nodes).
func epiRecoverUnnamed() {
defer epiRecover()
panic("boom")
}

View File

@@ -53,6 +53,10 @@ _extractor_name_prefix = "%s-%s" % (
"embeddable" if _for_embeddable else "standalone",
)
_compiler_plugin_registrar_service_source = "src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar"
_compiler_plugin_registrar_service_target = "META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar"
py_binary(
name = "generate_dbscheme",
srcs = ["generate_dbscheme.py"],
@@ -64,8 +68,14 @@ _resources = [
r[len("src/main/resources/"):],
)
for r in glob(["src/main/resources/**"])
if r != _compiler_plugin_registrar_service_source
]
_compiler_plugin_registrar_service = (
_compiler_plugin_registrar_service_source,
_compiler_plugin_registrar_service_target,
)
kt_javac_options(
name = "javac-options",
release = "8",
@@ -91,19 +101,32 @@ kt_javac_options(
# * `resource_strip_prefix` is unique per jar, so we must also put other resources under the same version prefix
genrule(
name = "resources-%s" % v,
srcs = [src for src, _ in _resources],
srcs = [src for src, _ in _resources] + (
[_compiler_plugin_registrar_service[0]] if not version_less(v, "2.4.0") else []
),
outs = [
"%s/com/github/codeql/extractor.name" % v,
] + [
"%s/%s" % (v, target)
for _, target in _resources
],
] + (
["%s/%s" % (
v,
_compiler_plugin_registrar_service[1],
)] if not version_less(v, "2.4.0") else []
),
cmd = "\n".join([
"echo %s-%s > $(RULEDIR)/%s/com/github/codeql/extractor.name" % (_extractor_name_prefix, v, v),
] + [
"cp $(execpath %s) $(RULEDIR)/%s/%s" % (source, v, target)
for source, target in _resources
]),
] + (
["cp $(execpath %s) $(RULEDIR)/%s/%s" % (
_compiler_plugin_registrar_service[0],
v,
_compiler_plugin_registrar_service[1],
)] if not version_less(v, "2.4.0") else []
)),
),
kt_jvm_library(
name = "%s-%s" % (_extractor_name_prefix, v),

BIN
java/kotlin-extractor/deps/kotlin-compiler-2.4.0.jar (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
java/kotlin-extractor/deps/kotlin-stdlib-2.4.0.jar (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -27,7 +27,7 @@ import shutil
import io
import os
DEFAULT_VERSION = "2.3.20"
DEFAULT_VERSION = "2.4.0"
def options():

View File

@@ -3,32 +3,21 @@
package com.github.codeql
import com.intellij.mock.MockProject
import com.intellij.openapi.extensions.LoadingOrder
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.config.CompilerConfiguration
class KotlinExtractorComponentRegistrar : Kotlin2ComponentRegistrar() {
override fun registerProjectComponents(
project: MockProject,
configuration: CompilerConfiguration
) {
override fun doRegisterExtensions(configuration: CompilerConfiguration) {
val invocationTrapFile = configuration[KEY_INVOCATION_TRAP_FILE]
if (invocationTrapFile == null) {
throw Exception("Required argument for TRAP invocation file not given")
}
// Register with LoadingOrder.LAST to ensure the extractor runs after other
// IR generation plugins (like kotlinx.serialization) have generated their code.
val extensionPoint = project.extensionArea.getExtensionPoint(IrGenerationExtension.extensionPointName)
extensionPoint.registerExtension(
registerExtractorExtension(
KotlinExtractorExtension(
invocationTrapFile,
configuration[KEY_CHECK_TRAP_IDENTICAL] ?: false,
configuration[KEY_COMPILATION_STARTTIME],
configuration[KEY_EXIT_AFTER_EXTRACTION] ?: false
),
LoadingOrder.LAST,
project
)
)
}
}

Some files were not shown because too many files have changed in this diff Show More