diff --git a/config/identical-files.json b/config/identical-files.json
index a33dbb1997b..bdaf567ae17 100644
--- a/config/identical-files.json
+++ b/config/identical-files.json
@@ -282,6 +282,7 @@
"java/ql/lib/semmle/code/java/internal/OverlayXml.qll",
"go/ql/lib/semmle/go/internal/OverlayXml.qll",
"python/ql/lib/semmle/python/internal/OverlayXml.qll",
- "csharp/ql/lib/semmle/code/csharp/internal/OverlayXml.qll"
+ "csharp/ql/lib/semmle/code/csharp/internal/OverlayXml.qll",
+ "cpp/ql/lib/semmle/code/cpp/internal/OverlayXml.qll"
]
}
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll
index d89ab06ed82..a1d9dd86c40 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll
@@ -148,6 +148,19 @@ module SourceSinkInterpretationInput implements
)
}
+ predicate barrierElement(
+ Element n, string output, string kind, Public::Provenance provenance, string model
+ ) {
+ none()
+ }
+
+ predicate barrierGuardElement(
+ Element n, string input, Public::AcceptingValue acceptingvalue, string kind,
+ Public::Provenance provenance, string model
+ ) {
+ none()
+ }
+
private newtype TInterpretNode =
TElement_(Element n) or
TNode_(Node n)
diff --git a/cpp/ql/lib/semmle/code/cpp/internal/Overlay.qll b/cpp/ql/lib/semmle/code/cpp/internal/Overlay.qll
index 64bfb7a8f17..b870bbfb9f6 100644
--- a/cpp/ql/lib/semmle/code/cpp/internal/Overlay.qll
+++ b/cpp/ql/lib/semmle/code/cpp/internal/Overlay.qll
@@ -2,6 +2,8 @@
* Defines entity discard predicates for C++ overlay analysis.
*/
+private import OverlayXml
+
/**
* Holds always for the overlay variant and never for the base variant.
* This local predicate is used to define local predicates that behave
diff --git a/cpp/ql/lib/semmle/code/cpp/internal/OverlayXml.qll b/cpp/ql/lib/semmle/code/cpp/internal/OverlayXml.qll
new file mode 100644
index 00000000000..95d49f2d611
--- /dev/null
+++ b/cpp/ql/lib/semmle/code/cpp/internal/OverlayXml.qll
@@ -0,0 +1,46 @@
+overlay[local]
+module;
+
+/**
+ * A local predicate that always holds for the overlay variant and never holds for the base variant.
+ * This is used to define local predicates that behave differently for the base and overlay variant.
+ */
+private predicate isOverlay() { databaseMetadata("isOverlay", "true") }
+
+private string getXmlFile(@xmllocatable locatable) {
+ exists(@location_default location, @file file | xmllocations(locatable, location) |
+ locations_default(location, file, _, _, _, _) and
+ files(file, result)
+ )
+}
+
+private string getXmlFileInBase(@xmllocatable locatable) {
+ not isOverlay() and
+ result = getXmlFile(locatable)
+}
+
+/**
+ * Holds if the given `file` was extracted as part of the overlay and was extracted by the HTML/XML
+ * extractor.
+ */
+private predicate overlayXmlExtracted(string file) {
+ isOverlay() and
+ exists(@xmllocatable locatable |
+ not files(locatable, _) and not xmlNs(locatable, _, _, _) and file = getXmlFile(locatable)
+ )
+}
+
+/**
+ * Holds if the given XML `locatable` should be discarded, because it is part of the overlay base
+ * and is in a file that was also extracted as part of the overlay database.
+ */
+overlay[discard_entity]
+private predicate discardXmlLocatable(@xmllocatable locatable) {
+ exists(string file | file = getXmlFileInBase(locatable) |
+ overlayChangedFiles(file)
+ or
+ // The HTML/XML extractor is currently not incremental and may extract more files than those
+ // included in overlayChangedFiles.
+ overlayXmlExtracted(file)
+ )
+}
diff --git a/csharp/documentation/library-coverage/coverage.csv b/csharp/documentation/library-coverage/coverage.csv
index 4713679cd23..d71bc79b3c0 100644
--- a/csharp/documentation/library-coverage/coverage.csv
+++ b/csharp/documentation/library-coverage/coverage.csv
@@ -40,6 +40,7 @@ Microsoft.VisualBasic,,,6,,,,,,,,,,,,,,,,,,,1,5
Microsoft.Win32,,4,2,,,,,,,,,,,,,,,,,,4,,2
Mono.Linker,,,278,,,,,,,,,,,,,,,,,,,127,151
MySql.Data.MySqlClient,48,,,,,,,,,,,,48,,,,,,,,,,
+NHibernate,3,,,,,,,,,,,,3,,,,,,,,,,
Newtonsoft.Json,,,91,,,,,,,,,,,,,,,,,,,73,18
ServiceStack,194,,7,27,,,,,75,,,,92,,,,,,,,,7,
SourceGenerators,,,5,,,,,,,,,,,,,,,,,,,,5
diff --git a/csharp/documentation/library-coverage/coverage.rst b/csharp/documentation/library-coverage/coverage.rst
index 061662f9714..8128c27dccd 100644
--- a/csharp/documentation/library-coverage/coverage.rst
+++ b/csharp/documentation/library-coverage/coverage.rst
@@ -9,6 +9,6 @@ C# framework & library support
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting`
`ServiceStack `_,"``ServiceStack.*``, ``ServiceStack``",,7,194,
System,"``System.*``, ``System``",47,12241,54,5
- Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.AspNetCore.Components``, ``Microsoft.AspNetCore.Http``, ``Microsoft.AspNetCore.Mvc``, ``Microsoft.AspNetCore.WebUtilities``, ``Microsoft.CSharp``, ``Microsoft.Data.SqlClient``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.DotNet.Build.Tasks``, ``Microsoft.DotNet.PlatformAbstractions``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.JSInterop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.VisualBasic``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",60,2257,159,4
- Totals,,107,14505,407,9
+ Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.AspNetCore.Components``, ``Microsoft.AspNetCore.Http``, ``Microsoft.AspNetCore.Mvc``, ``Microsoft.AspNetCore.WebUtilities``, ``Microsoft.CSharp``, ``Microsoft.Data.SqlClient``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.DotNet.Build.Tasks``, ``Microsoft.DotNet.PlatformAbstractions``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.JSInterop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.VisualBasic``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``NHibernate``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",60,2257,162,4
+ Totals,,107,14505,410,9
diff --git a/csharp/ql/lib/change-notes/2025-12-03-implicit-map-value-reads.md b/csharp/ql/lib/change-notes/2025-12-03-implicit-map-value-reads.md
new file mode 100644
index 00000000000..2b7f47fe98d
--- /dev/null
+++ b/csharp/ql/lib/change-notes/2025-12-03-implicit-map-value-reads.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* Added implicit reads of `System.Collections.Generic.KeyValuePair.Value` at taint-tracking sinks and at inputs to additional taint steps. As a result, taint-tracking queries will now produce more results when a container is tainted.
\ No newline at end of file
diff --git a/csharp/ql/lib/ext/NHibernate.model.yml b/csharp/ql/lib/ext/NHibernate.model.yml
new file mode 100644
index 00000000000..472374cfbc3
--- /dev/null
+++ b/csharp/ql/lib/ext/NHibernate.model.yml
@@ -0,0 +1,8 @@
+extensions:
+ - addsTo:
+ pack: codeql/csharp-all
+ extensible: sinkModel
+ data:
+ - ["NHibernate", "ISession", True, "CreateSQLQuery", "(System.String)", "", "Argument[0]", "sql-injection", "manual"]
+ - ["NHibernate", "IStatelessSession", True, "CreateSQLQuery", "(System.String)", "", "Argument[0]", "sql-injection", "manual"]
+ - ["NHibernate.Impl", "AbstractSessionImpl", True, "CreateSQLQuery", "(System.String)", "", "Argument[0]", "sql-injection", "manual"]
\ No newline at end of file
diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll
index f61d7f9c3a7..414cfc2d50a 100644
--- a/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll
+++ b/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll
@@ -842,6 +842,40 @@ module Internal {
e3 = any(NullCoalescingExpr nce | e1 = nce.getLeftOperand() and e2 = nce.getRightOperand())
}
+ predicate nullValueImplied(Expr e) {
+ nullValue(e)
+ or
+ exists(Expr e1 | nullValueImplied(e1) and nullValueImpliedUnary(e1, e))
+ or
+ exists(Expr e1, Expr e2 |
+ nullValueImplied(e1) and nullValueImplied(e2) and nullValueImpliedBinary(e1, e2, e)
+ )
+ or
+ e =
+ any(Ssa::Definition def |
+ forex(Ssa::Definition u | u = def.getAnUltimateDefinition() | nullDef(u))
+ ).getARead()
+ }
+
+ private predicate nullDef(Ssa::ExplicitDefinition def) {
+ nullValueImplied(def.getADefinition().getSource())
+ }
+
+ predicate nonNullValueImplied(Expr e) {
+ nonNullValue(e)
+ or
+ exists(Expr e1 | nonNullValueImplied(e1) and nonNullValueImpliedUnary(e1, e))
+ or
+ e =
+ any(Ssa::Definition def |
+ forex(Ssa::Definition u | u = def.getAnUltimateDefinition() | nonNullDef(u))
+ ).getARead()
+ }
+
+ private predicate nonNullDef(Ssa::ExplicitDefinition def) {
+ nonNullValueImplied(def.getADefinition().getSource())
+ }
+
/** A callable that always returns a non-`null` value. */
private class NonNullCallable extends Callable {
NonNullCallable() { this = any(SystemObjectClass c).getGetTypeMethod() }
@@ -936,154 +970,21 @@ module Internal {
e = any(BinaryArithmeticOperation bao | result = bao.getAnOperand())
}
- // The predicates in this module should be evaluated in the same stage as the CFG
- // construction stage. This is to avoid recomputation of pre-basic-blocks and
- // pre-SSA predicates
- private module PreCfg {
- private import semmle.code.csharp.controlflow.internal.PreBasicBlocks as PreBasicBlocks
- private import semmle.code.csharp.controlflow.internal.PreSsa
-
- private predicate nullDef(PreSsa::Definition def) {
- nullValueImplied(def.getDefinition().getSource())
- }
-
- private predicate nonNullDef(PreSsa::Definition def) {
- nonNullValueImplied(def.getDefinition().getSource())
- }
-
- private predicate emptyDef(PreSsa::Definition def) {
- emptyValue(def.getDefinition().getSource())
- }
-
- private predicate nonEmptyDef(PreSsa::Definition def) {
- nonEmptyValue(def.getDefinition().getSource())
- }
-
- deprecated predicate isGuard(Expr e, GuardValue val) {
- (
- e.getType() instanceof BoolType and
- not e instanceof BoolLiteral and
- not e instanceof SwitchCaseExpr and
- not e instanceof PatternExpr and
- exists(val.asBooleanValue())
- or
- e instanceof DereferenceableExpr and
- val.isNullness(_)
- ) and
- not e = any(ExprStmt es).getExpr() and
- not e = any(LocalVariableDeclStmt s).getAVariableDeclExpr()
- }
-
- cached
- private module CachedWithCfg {
- private import semmle.code.csharp.Caching
-
- private predicate firstReadSameVarUniquePredecessor(
- PreSsa::Definition def, AssignableRead read
- ) {
- read = def.getAFirstRead() and
- (
- not PreSsa::adjacentReadPairSameVar(_, read)
- or
- read = unique(AssignableRead read0 | PreSsa::adjacentReadPairSameVar(read0, read))
- )
- }
-
- cached
- predicate nullValueImplied(Expr e) {
- nullValue(e)
- or
- exists(Expr e1 | nullValueImplied(e1) and nullValueImpliedUnary(e1, e))
- or
- exists(Expr e1, Expr e2 |
- nullValueImplied(e1) and nullValueImplied(e2) and nullValueImpliedBinary(e1, e2, e)
- )
- or
- e =
- any(PreSsa::Definition def |
- forex(PreSsa::Definition u | u = def.getAnUltimateDefinition() | nullDef(u))
- ).getARead()
- }
-
- cached
- predicate nonNullValueImplied(Expr e) {
- nonNullValue(e)
- or
- exists(Expr e1 | nonNullValueImplied(e1) and nonNullValueImpliedUnary(e1, e))
- or
- e =
- any(PreSsa::Definition def |
- forex(PreSsa::Definition u | u = def.getAnUltimateDefinition() | nonNullDef(u))
- ).getARead()
- }
-
- private predicate adjacentReadPairSameVarUniquePredecessor(
- AssignableRead read1, AssignableRead read2
- ) {
- PreSsa::adjacentReadPairSameVar(read1, read2) and
- (
- read1 = read2 and
- read1 = unique(AssignableRead other | PreSsa::adjacentReadPairSameVar(other, read2))
- or
- read1 =
- unique(AssignableRead other |
- PreSsa::adjacentReadPairSameVar(other, read2) and other != read2
- )
- )
- }
-
- cached
- predicate emptyValue(Expr e) {
- e.(ArrayCreation).getALengthArgument().getValue().toInt() = 0
- or
- e.(ArrayInitializer).hasNoElements()
- or
- exists(Expr mid | emptyValue(mid) |
- mid = e.(AssignExpr).getRValue()
- or
- mid = e.(Cast).getExpr()
- )
- or
- exists(PreSsa::Definition def | emptyDef(def) | firstReadSameVarUniquePredecessor(def, e))
- or
- exists(MethodCall mc |
- mc.getTarget().getAnUltimateImplementee().getUnboundDeclaration() =
- any(SystemCollectionsGenericICollectionInterface c).getClearMethod() and
- adjacentReadPairSameVarUniquePredecessor(mc.getQualifier(), e)
- )
- }
-
- cached
- predicate nonEmptyValue(Expr e) {
- forex(Expr length | length = e.(ArrayCreation).getALengthArgument() |
- length.getValue().toInt() != 0
- )
- or
- e.(ArrayInitializer).getNumberOfElements() > 0
- or
- exists(Expr mid | nonEmptyValue(mid) |
- mid = e.(AssignExpr).getRValue()
- or
- mid = e.(Cast).getExpr()
- )
- or
- exists(PreSsa::Definition def | nonEmptyDef(def) |
- firstReadSameVarUniquePredecessor(def, e)
- )
- or
- exists(MethodCall mc |
- mc.getTarget().getAnUltimateImplementee().getUnboundDeclaration() =
- any(SystemCollectionsGenericICollectionInterface c).getAddMethod() and
- adjacentReadPairSameVarUniquePredecessor(mc.getQualifier(), e)
- )
- }
- }
-
- import CachedWithCfg
+ deprecated predicate isGuard(Expr e, GuardValue val) {
+ (
+ e.getType() instanceof BoolType and
+ not e instanceof BoolLiteral and
+ not e instanceof SwitchCaseExpr and
+ not e instanceof PatternExpr and
+ exists(val.asBooleanValue())
+ or
+ e instanceof DereferenceableExpr and
+ val.isNullness(_)
+ ) and
+ not e = any(ExprStmt es).getExpr() and
+ not e = any(LocalVariableDeclStmt s).getAVariableDeclExpr()
}
- import PreCfg
-
private predicate interestingDescendantCandidate(Expr e) {
guardControls(e, _, _)
or
diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/PreSsa.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/PreSsa.qll
deleted file mode 100644
index 4921e692623..00000000000
--- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/PreSsa.qll
+++ /dev/null
@@ -1,221 +0,0 @@
-import csharp
-
-/**
- * Provides an SSA implementation based on "pre-basic-blocks", restricted
- * to local scope variables and fields/properties that behave like local
- * scope variables.
- */
-module PreSsa {
- private import AssignableDefinitions
- private import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl
- private import semmle.code.csharp.controlflow.internal.PreBasicBlocks as PreBasicBlocks
- private import codeql.ssa.Ssa as SsaImplCommon
-
- private predicate definitionAt(
- AssignableDefinition def, PreBasicBlocks::PreBasicBlock bb, int i, SsaInput::SourceVariable v
- ) {
- bb.getNode(i) = def.getExpr() and
- v = def.getTarget() and
- // In cases like `(x, x) = (0, 1)`, we discard the first (dead) definition of `x`
- not exists(TupleAssignmentDefinition first, TupleAssignmentDefinition second | first = def |
- second.getAssignment() = first.getAssignment() and
- second.getEvaluationOrder() > first.getEvaluationOrder() and
- second.getTarget() = v
- )
- or
- def.(ImplicitParameterDefinition).getParameter() = v and
- exists(Callable c | v = c.getAParameter() |
- scopeFirst(c, bb) and
- i = -1
- )
- }
-
- predicate implicitEntryDef(
- Callable c, PreBasicBlocks::PreBasicBlock bb, SsaInput::SourceVariable v
- ) {
- c = v.getACallable() and
- scopeFirst(c, bb) and
- (
- not v instanceof LocalScopeVariable
- or
- v.(SimpleLocalScopeVariable).isReadonlyCapturedBy(c)
- )
- }
-
- /** Holds if `a` is assigned in callable `c`. */
- pragma[nomagic]
- private predicate assignableDefinition(Assignable a, Callable c) {
- exists(AssignableDefinition def |
- def.getTarget() = a and
- c = def.getEnclosingCallable()
- |
- not c instanceof Constructor or
- a instanceof LocalScopeVariable
- )
- }
-
- pragma[nomagic]
- private predicate assignableUniqueWriter(Assignable a, Callable c) {
- c = unique(Callable c0 | assignableDefinition(a, c0) | c0)
- }
-
- /** Holds if `a` is accessed in callable `c`. */
- pragma[nomagic]
- private predicate assignableAccess(Assignable a, Callable c) {
- exists(AssignableAccess aa | aa.getTarget() = a | c = aa.getEnclosingCallable())
- }
-
- /**
- * A local scope variable that is amenable to SSA analysis.
- *
- * This is either a local variable that is not captured, or one
- * where all writes happen in the defining callable.
- */
- class SimpleLocalScopeVariable extends LocalScopeVariable {
- SimpleLocalScopeVariable() { assignableUniqueWriter(this, this.getCallable()) }
-
- /** Holds if this local scope variable is read-only captured by `c`. */
- predicate isReadonlyCapturedBy(Callable c) {
- assignableAccess(this, c) and
- c != this.getCallable()
- }
- }
-
- module SsaInput implements SsaImplCommon::InputSig {
- private import semmle.code.csharp.Caching
-
- private class ExitBasicBlock extends PreBasicBlocks::PreBasicBlock {
- ExitBasicBlock() { scopeLast(_, this.getLastNode(), _) }
- }
-
- pragma[noinline]
- private predicate assignableNoComplexQualifiers(Assignable a) {
- forall(QualifiableExpr qe | qe.(AssignableAccess).getTarget() = a | qe.targetIsThisInstance())
- }
-
- /**
- * A simple assignable. Either a local scope variable or a field/property
- * that behaves like a local scope variable.
- */
- class SourceVariable extends Assignable {
- private Callable c;
-
- SourceVariable() {
- assignableAccess(this, c) and
- (
- this instanceof SimpleLocalScopeVariable
- or
- (
- this = any(Field f | not f.isVolatile())
- or
- this = any(TrivialProperty tp | not tp.isOverridableOrImplementable())
- ) and
- (
- not assignableDefinition(this, _)
- or
- assignableUniqueWriter(this, c)
- ) and
- assignableNoComplexQualifiers(this)
- )
- }
-
- /** Gets a callable in which this simple assignable can be analyzed. */
- Callable getACallable() { result = c }
- }
-
- predicate variableWrite(
- PreBasicBlocks::PreBasicBlock bb, int i, SourceVariable v, boolean certain
- ) {
- Stages::ControlFlowStage::forceCachingInSameStage() and
- exists(AssignableDefinition def |
- definitionAt(def, bb, i, v) and
- if def.getTargetAccess().isRefArgument() then certain = false else certain = true
- )
- or
- implicitEntryDef(_, bb, v) and
- i = -1 and
- certain = true
- }
-
- predicate variableRead(
- PreBasicBlocks::PreBasicBlock bb, int i, SourceVariable v, boolean certain
- ) {
- exists(AssignableRead read |
- read = bb.getNode(i) and
- read.getTarget() = v and
- certain = true
- )
- or
- v =
- any(LocalScopeVariable lsv |
- lsv.getCallable() = bb.(ExitBasicBlock).getEnclosingCallable() and
- i = bb.length() and
- (lsv.isRef() or v.(Parameter).isOut()) and
- certain = false
- )
- }
- }
-
- private module SsaImpl = SsaImplCommon::Make;
-
- class Definition extends SsaImpl::Definition {
- final AssignableRead getARead() {
- exists(PreBasicBlocks::PreBasicBlock bb, int i |
- SsaImpl::ssaDefReachesRead(_, this, bb, i) and
- result = bb.getNode(i)
- )
- }
-
- final AssignableDefinition getDefinition() {
- exists(PreBasicBlocks::PreBasicBlock bb, int i, SsaInput::SourceVariable v |
- this.definesAt(v, bb, i) and
- definitionAt(result, bb, i, v)
- )
- }
-
- final AssignableRead getAFirstRead() {
- exists(PreBasicBlocks::PreBasicBlock bb, int i |
- SsaImpl::firstUse(this, bb, i, true) and
- result = bb.getNode(i)
- )
- }
-
- private Definition getAPhiInputOrPriorDefinition() {
- result = this.(PhiNode).getAnInput() or
- SsaImpl::uncertainWriteDefinitionInput(this, result)
- }
-
- final Definition getAnUltimateDefinition() {
- result = this.getAPhiInputOrPriorDefinition*() and
- not result instanceof PhiNode
- }
-
- final predicate isLiveAtEndOfBlock(PreBasicBlocks::PreBasicBlock bb) {
- SsaImpl::ssaDefReachesEndOfBlock(bb, this, _)
- }
-
- override Location getLocation() {
- result = this.getDefinition().getLocation()
- or
- exists(Callable c, PreBasicBlocks::PreBasicBlock bb, SsaInput::SourceVariable v |
- this.definesAt(v, bb, -1) and
- implicitEntryDef(c, bb, v) and
- result = c.getLocation()
- )
- }
- }
-
- class PhiNode extends SsaImpl::PhiNode, Definition {
- final override Location getLocation() { result = this.getBasicBlock().getLocation() }
-
- final Definition getAnInput() { SsaImpl::phiHasInputFromBlock(this, result, _) }
- }
-
- predicate adjacentReadPairSameVar(AssignableRead read1, AssignableRead read2) {
- exists(PreBasicBlocks::PreBasicBlock bb1, int i1, PreBasicBlocks::PreBasicBlock bb2, int i2 |
- read1 = bb1.getNode(i1) and
- SsaImpl::adjacentUseUse(bb1, i1, bb2, i2, _, true) and
- read2 = bb2.getNode(i2)
- )
- }
-}
diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Splitting.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Splitting.qll
index 87579a075f9..55b75ed31a7 100644
--- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Splitting.qll
+++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Splitting.qll
@@ -9,18 +9,11 @@ private import Completion as Comp
private import Comp
private import ControlFlowGraphImpl
private import semmle.code.csharp.controlflow.ControlFlowGraph::ControlFlow as Cfg
-private import semmle.code.csharp.controlflow.internal.PreSsa
cached
private module Cached {
private import semmle.code.csharp.Caching
- cached
- newtype TBooleanSplitSubKind =
- TSsaBooleanSplitSubKind(PreSsa::Definition def) {
- Stages::ControlFlowStage::forceCachingInSameStage()
- }
-
cached
newtype TSplitKind = TConditionalCompletionSplitKind()
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/BaseSSA.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/BaseSSA.qll
index 747cf790d91..a994873274a 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/BaseSSA.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/BaseSSA.qll
@@ -43,10 +43,47 @@ module BaseSsa {
)
}
- private module SsaInput implements SsaImplCommon::InputSig {
- private import semmle.code.csharp.controlflow.internal.PreSsa
+ /** Holds if `a` is assigned in callable `c`. */
+ pragma[nomagic]
+ private predicate assignableDefinition(Assignable a, Callable c) {
+ exists(AssignableDefinition def |
+ def.getTarget() = a and
+ c = def.getEnclosingCallable()
+ |
+ not c instanceof Constructor or
+ a instanceof LocalScopeVariable
+ )
+ }
- class SourceVariable = PreSsa::SimpleLocalScopeVariable;
+ pragma[nomagic]
+ private predicate assignableUniqueWriter(Assignable a, Callable c) {
+ c = unique(Callable c0 | assignableDefinition(a, c0) | c0)
+ }
+
+ /** Holds if `a` is accessed in callable `c`. */
+ pragma[nomagic]
+ private predicate assignableAccess(Assignable a, Callable c) {
+ exists(AssignableAccess aa | aa.getTarget() = a | c = aa.getEnclosingCallable())
+ }
+
+ /**
+ * A local scope variable that is amenable to SSA analysis.
+ *
+ * This is either a local variable that is not captured, or one
+ * where all writes happen in the defining callable.
+ */
+ class SimpleLocalScopeVariable extends LocalScopeVariable {
+ SimpleLocalScopeVariable() { assignableUniqueWriter(this, this.getCallable()) }
+
+ /** Holds if this local scope variable is read-only captured by `c`. */
+ predicate isReadonlyCapturedBy(Callable c) {
+ assignableAccess(this, c) and
+ c != this.getCallable()
+ }
+ }
+
+ private module SsaInput implements SsaImplCommon::InputSig {
+ class SourceVariable = SimpleLocalScopeVariable;
predicate variableWrite(ControlFlow::BasicBlock bb, int i, SourceVariable v, boolean certain) {
exists(AssignableDefinition def |
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll
index 3ee16f21489..842c28ac75b 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll
@@ -235,6 +235,19 @@ module SourceSinkInterpretationInput implements
)
}
+ predicate barrierElement(
+ Element n, string output, string kind, Public::Provenance provenance, string model
+ ) {
+ none()
+ }
+
+ predicate barrierGuardElement(
+ Element n, string input, Public::AcceptingValue acceptingvalue, string kind,
+ Public::Provenance provenance, string model
+ ) {
+ none()
+ }
+
class SourceOrSinkElement = Element;
private newtype TInterpretNode =
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll
index 70fda2b1296..277abd1d26e 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll
@@ -5,9 +5,9 @@
import csharp
private import codeql.ssa.Ssa as SsaImplCommon
private import AssignableDefinitions
-private import semmle.code.csharp.controlflow.internal.PreSsa
private import semmle.code.csharp.controlflow.BasicBlocks as BasicBlocks
private import semmle.code.csharp.controlflow.Guards as Guards
+private import semmle.code.csharp.dataflow.internal.BaseSSA
private module SsaInput implements SsaImplCommon::InputSig {
class SourceVariable = Ssa::SourceVariable;
@@ -783,7 +783,7 @@ cached
private module Cached {
cached
newtype TSourceVariable =
- TLocalVar(Callable c, PreSsa::SimpleLocalScopeVariable v) {
+ TLocalVar(Callable c, BaseSsa::SimpleLocalScopeVariable v) {
c = v.getCallable()
or
// Local scope variables can be captured
@@ -967,18 +967,22 @@ private module Cached {
cached // nothing is actually cached
module BarrierGuard {
- private predicate guardChecksAdjTypes(
- DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e,
- DataFlowIntegrationInput::GuardValue branch
+ private import codeql.util.Unit
+
+ private predicate guardChecksAdjTypes(Guards::Guards::Guard g, Expr e, Guards::GuardValue v) {
+ guardChecks(g, e, v)
+ }
+
+ private predicate guardChecksWithWrappers(
+ Guards::Guard g, Definition def, Guards::GuardValue val, Unit state
) {
- exists(Guards::GuardValue v |
- guardChecks(g, e.getAstNode(), v) and
- branch = v.asBooleanValue()
- )
+ Guards::Guards::ValidationWrapper::guardChecksDef(g, def, val) and
+ exists(state)
}
private Node getABarrierNodeImpl() {
- result = DataFlowIntegrationImpl::BarrierGuard::getABarrierNode()
+ result =
+ DataFlowIntegrationImpl::BarrierGuardDefWithState::getABarrierNode(_)
}
predicate getABarrierNode = getABarrierNodeImpl/0;
@@ -1037,38 +1041,18 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
)
}
- class GuardValue = Boolean;
+ class GuardValue = Guards::GuardValue;
- class Guard extends Guards::Guard {
- /**
- * Holds if the evaluation of this guard to `branch` corresponds to the edge
- * from `bb1` to `bb2`.
- */
- predicate hasValueBranchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue branch) {
- exists(ControlFlow::ConditionalSuccessor s |
- this.getAControlFlowNode() = bb1.getLastNode() and
- bb2 = bb1.getASuccessor(s) and
- s.getValue() = branch
- )
- }
+ class Guard = Guards::Guard;
- /**
- * Holds if this guard evaluating to `branch` controls the control-flow
- * branch edge from `bb1` to `bb2`. That is, following the edge from
- * `bb1` to `bb2` implies that this guard evaluated to `branch`.
- */
- predicate valueControlsBranchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue branch) {
- this.hasValueBranchEdge(bb1, bb2, branch)
- }
+ /** Holds if the guard `guard` directly controls block `bb` upon evaluating to `val`. */
+ predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, GuardValue val) {
+ guard.directlyValueControls(bb, val)
}
- /** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
- predicate guardDirectlyControlsBlock(Guard guard, ControlFlow::BasicBlock bb, GuardValue branch) {
- exists(ConditionBlock conditionBlock, ControlFlow::ConditionalSuccessor s |
- guard.getAControlFlowNode() = conditionBlock.getLastNode() and
- s.getValue() = branch and
- conditionBlock.edgeDominates(bb, s)
- )
+ /** Holds if the guard `guard` controls block `bb` upon evaluating to `val`. */
+ predicate guardControlsBlock(Guard guard, BasicBlock bb, GuardValue val) {
+ guard.valueControls(bb, val)
}
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll
index 3146720efe8..b24a104d388 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll
@@ -24,6 +24,13 @@ predicate defaultTaintSanitizer(DataFlow::Node node) {
)
}
+/**
+ * Gets the (unbound) property `System.Collections.Generic.KeyValuePair.Value`.
+ */
+private Property keyValuePairValue() {
+ result.hasFullyQualifiedName("System.Collections.Generic", "KeyValuePair`2", "Value")
+}
+
/**
* Holds if default `TaintTracking::Configuration`s should allow implicit reads
* of `c` at sinks and inputs to additional taint steps.
@@ -31,7 +38,11 @@ predicate defaultTaintSanitizer(DataFlow::Node node) {
bindingset[node]
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) {
exists(node) and
- c.isElement()
+ (
+ c.isElement()
+ or
+ c.isProperty(keyValuePairValue())
+ )
}
private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityConfiguration {
diff --git a/csharp/ql/src/change-notes/2025-12-11-nhibernate-sql-sinks.md b/csharp/ql/src/change-notes/2025-12-11-nhibernate-sql-sinks.md
new file mode 100644
index 00000000000..c2ce476dd7a
--- /dev/null
+++ b/csharp/ql/src/change-notes/2025-12-11-nhibernate-sql-sinks.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* Added `NHibernate.ISession.CreateSQLQuery`, `NHibernate.IStatelessSession.CreateSQLQuery` and `NHibernate.Impl.AbstractSessionImpl.CreateSQLQuery` as SQL injection sinks.
\ No newline at end of file
diff --git a/csharp/ql/test/library-tests/dataflow/collections/CollectionDataFlow.expected b/csharp/ql/test/library-tests/dataflow/collections/CollectionDataFlow.expected
new file mode 100644
index 00000000000..373e8938b91
--- /dev/null
+++ b/csharp/ql/test/library-tests/dataflow/collections/CollectionDataFlow.expected
@@ -0,0 +1,840 @@
+models
+| 1 | Summary: System.Collections.Generic; Dictionary; false; get_Keys; (); ; Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Key]; ReturnValue.Element; value; manual |
+| 2 | Summary: System.Collections.Generic; Dictionary; false; get_Values; (); ; Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]; ReturnValue.Element; value; manual |
+| 3 | Summary: System.Collections.Generic; ICollection; true; Add; (T); ; Argument[0]; Argument[this].Element; value; manual |
+| 4 | Summary: System.Collections.Generic; IDictionary; true; Add; (TKey,TValue); ; Argument[0]; Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Key]; value; manual |
+| 5 | Summary: System.Collections.Generic; IDictionary; true; Add; (TKey,TValue); ; Argument[1]; Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]; value; manual |
+| 6 | Summary: System.Collections.Generic; IDictionary; true; get_Item; (TKey); ; Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]; ReturnValue; value; manual |
+| 7 | Summary: System.Collections.Generic; IDictionary; true; get_Keys; (); ; Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Key]; ReturnValue.Element; value; manual |
+| 8 | Summary: System.Collections.Generic; IDictionary; true; get_Values; (); ; Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]; ReturnValue.Element; value; manual |
+| 9 | Summary: System.Collections.Generic; IDictionary; true; set_Item; (TKey,TValue); ; Argument[0]; Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Key]; value; manual |
+| 10 | Summary: System.Collections.Generic; IDictionary; true; set_Item; (TKey,TValue); ; Argument[1]; Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]; value; manual |
+| 11 | Summary: System.Collections.Generic; IList; true; get_Item; (System.Int32); ; Argument[this].Element; ReturnValue; value; manual |
+| 12 | Summary: System.Collections.Generic; IList; true; set_Item; (System.Int32,T); ; Argument[1]; Argument[this].Element; value; manual |
+| 13 | Summary: System.Collections.Generic; KeyValuePair; false; KeyValuePair; (TKey,TValue); ; Argument[0]; Argument[this].Property[System.Collections.Generic.KeyValuePair`2.Key]; value; manual |
+| 14 | Summary: System.Collections.Generic; List+Enumerator; false; get_Current; (); ; Argument[this].Property[System.Collections.Generic.List`1+Enumerator.Current]; ReturnValue; value; dfc-generated |
+| 15 | Summary: System.Collections.Generic; List; false; GetEnumerator; (); ; Argument[this].Element; ReturnValue.Property[System.Collections.Generic.List`1+Enumerator.Current]; value; manual |
+| 16 | Summary: System.Collections; IEnumerable; true; GetEnumerator; (); ; Argument[this].Element; ReturnValue.Property[System.Collections.IEnumerator.Current]; value; manual |
+| 17 | Summary: System.Linq; Enumerable; false; First; (System.Collections.Generic.IEnumerable); ; Argument[0].Element; ReturnValue; value; manual |
+| 18 | Summary: System.Linq; Enumerable; false; Select; (System.Collections.Generic.IEnumerable,System.Func); ; Argument[0].Element; Argument[1].Parameter[0]; value; manual |
+| 19 | Summary: System; ReadOnlySpan; false; ReadOnlySpan; (T[]); ; Argument[0].Element; Argument[this].Element; value; manual |
+| 20 | Summary: System; ReadOnlySpan; false; get_Item; (System.Int32); ; Argument[this].Element; ReturnValue; value; manual |
+| 21 | Summary: System; Span; false; CopyTo; (System.Span); ; Argument[this].Element; Argument[0].Element; value; manual |
+| 22 | Summary: System; Span; false; Fill; (T); ; Argument[0]; Argument[this].Element; value; manual |
+| 23 | Summary: System; Span; false; Span; (T); ; Argument[0]; Argument[this].Element; value; manual |
+| 24 | Summary: System; Span; false; Span; (T[]); ; Argument[0].Element; Argument[this].Element; value; manual |
+| 25 | Summary: System; Span; false; ToArray; (); ; Argument[this].Element; ReturnValue.Element; value; manual |
+| 26 | Summary: System; Span; false; get_Item; (System.Int32); ; Argument[this].Element; ReturnValue; value; manual |
+edges
+| CollectionFlow.cs:14:40:14:41 | ts : A[] [element] : A | CollectionFlow.cs:14:52:14:53 | access to parameter ts : A[] [element] : A | provenance | |
+| CollectionFlow.cs:14:40:14:41 | ts : null [element] : A | CollectionFlow.cs:14:52:14:53 | access to parameter ts : null [element] : A | provenance | |
+| CollectionFlow.cs:14:52:14:53 | access to parameter ts : A[] [element] : A | CollectionFlow.cs:14:52:14:56 | access to array element | provenance | |
+| CollectionFlow.cs:14:52:14:53 | access to parameter ts : null [element] : A | CollectionFlow.cs:14:52:14:56 | access to array element | provenance | |
+| CollectionFlow.cs:16:44:16:45 | ts : A[] [element] : A | CollectionFlow.cs:16:56:16:57 | access to parameter ts : A[] [element] : A | provenance | |
+| CollectionFlow.cs:16:56:16:57 | access to parameter ts : A[] [element] : A | CollectionFlow.cs:16:56:16:61 | access to array element | provenance | |
+| CollectionFlow.cs:18:49:18:52 | list : List [element] : A | CollectionFlow.cs:18:63:18:66 | access to parameter list : List [element] : A | provenance | |
+| CollectionFlow.cs:18:63:18:66 | access to parameter list : List [element] : A | CollectionFlow.cs:18:63:18:69 | access to indexer | provenance | MaD:11 |
+| CollectionFlow.cs:20:61:20:64 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:20:75:20:78 | access to parameter dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:20:75:20:78 | access to parameter dict : Dictionary [element, property Value] : A | CollectionFlow.cs:20:75:20:81 | access to indexer | provenance | MaD:6 |
+| CollectionFlow.cs:22:59:22:62 | dict : Dictionary [element, property Key] : A | CollectionFlow.cs:22:73:22:76 | access to parameter dict : Dictionary [element, property Key] : A | provenance | |
+| CollectionFlow.cs:22:73:22:76 | access to parameter dict : Dictionary [element, property Key] : A | CollectionFlow.cs:22:73:22:81 | access to property Keys : ICollection [element] : A | provenance | MaD:1 |
+| CollectionFlow.cs:22:73:22:76 | access to parameter dict : Dictionary [element, property Key] : A | CollectionFlow.cs:22:73:22:81 | access to property Keys : ICollection [element] : A | provenance | MaD:7 |
+| CollectionFlow.cs:22:73:22:81 | access to property Keys : ICollection [element] : A | CollectionFlow.cs:22:73:22:89 | call to method First | provenance | MaD:17 |
+| CollectionFlow.cs:24:34:24:35 | ts : A[] [element] : A | CollectionFlow.cs:24:41:24:42 | access to parameter ts : A[] [element] : A | provenance | |
+| CollectionFlow.cs:24:34:24:35 | ts : null [element] : A | CollectionFlow.cs:24:41:24:42 | access to parameter ts : null [element] : A | provenance | |
+| CollectionFlow.cs:24:41:24:42 | access to parameter ts : A[] [element] : A | CollectionFlow.cs:24:41:24:45 | access to array element : A | provenance | |
+| CollectionFlow.cs:24:41:24:42 | access to parameter ts : null [element] : A | CollectionFlow.cs:24:41:24:45 | access to array element : A | provenance | |
+| CollectionFlow.cs:26:33:26:34 | ts : A[] [element] : A | CollectionFlow.cs:26:40:26:41 | access to parameter ts : A[] [element] : A | provenance | |
+| CollectionFlow.cs:26:40:26:41 | access to parameter ts : A[] [element] : A | CollectionFlow.cs:26:40:26:45 | access to array element : A | provenance | |
+| CollectionFlow.cs:28:43:28:46 | list : List [element] : A | CollectionFlow.cs:28:52:28:55 | access to parameter list : List [element] : A | provenance | |
+| CollectionFlow.cs:28:52:28:55 | access to parameter list : List [element] : A | CollectionFlow.cs:28:52:28:58 | access to indexer : A | provenance | MaD:11 |
+| CollectionFlow.cs:30:58:30:61 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:67:30:70 | access to parameter dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:30:67:30:70 | access to parameter dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:67:30:73 | access to indexer : A | provenance | MaD:6 |
+| CollectionFlow.cs:32:59:32:62 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:32:68:32:71 | access to parameter dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:32:68:32:71 | access to parameter dict : Dictionary [element, property Value] : A | CollectionFlow.cs:32:68:32:79 | call to method First> : KeyValuePair [property Value] : A | provenance | MaD:17 |
+| CollectionFlow.cs:32:68:32:79 | call to method First> : KeyValuePair [property Value] : A | CollectionFlow.cs:32:68:32:85 | access to property Value : A | provenance | |
+| CollectionFlow.cs:34:60:34:63 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:34:69:34:72 | access to parameter dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:34:69:34:72 | access to parameter dict : Dictionary [element, property Value] : A | CollectionFlow.cs:34:69:34:79 | access to property Values : ICollection [element] : A | provenance | MaD:2 |
+| CollectionFlow.cs:34:69:34:72 | access to parameter dict : Dictionary [element, property Value] : A | CollectionFlow.cs:34:69:34:79 | access to property Values : ICollection [element] : A | provenance | MaD:8 |
+| CollectionFlow.cs:34:69:34:79 | access to property Values : ICollection [element] : A | CollectionFlow.cs:34:69:34:87 | call to method First : A | provenance | MaD:17 |
+| CollectionFlow.cs:36:58:36:61 | dict : Dictionary [element, property Key] : A | CollectionFlow.cs:36:67:36:70 | access to parameter dict : Dictionary [element, property Key] : A | provenance | |
+| CollectionFlow.cs:36:67:36:70 | access to parameter dict : Dictionary [element, property Key] : A | CollectionFlow.cs:36:67:36:75 | access to property Keys : ICollection [element] : A | provenance | MaD:1 |
+| CollectionFlow.cs:36:67:36:70 | access to parameter dict : Dictionary [element, property Key] : A | CollectionFlow.cs:36:67:36:75 | access to property Keys : ICollection [element] : A | provenance | MaD:7 |
+| CollectionFlow.cs:36:67:36:75 | access to property Keys : ICollection [element] : A | CollectionFlow.cs:36:67:36:83 | call to method First : A | provenance | MaD:17 |
+| CollectionFlow.cs:38:57:38:60 | dict : Dictionary [element, property Key] : A | CollectionFlow.cs:38:66:38:69 | access to parameter dict : Dictionary [element, property Key] : A | provenance | |
+| CollectionFlow.cs:38:66:38:69 | access to parameter dict : Dictionary [element, property Key] : A | CollectionFlow.cs:38:66:38:77 | call to method First> : KeyValuePair [property Key] : A | provenance | MaD:17 |
+| CollectionFlow.cs:38:66:38:77 | call to method First> : KeyValuePair [property Key] : A | CollectionFlow.cs:38:66:38:81 | access to property Key : A | provenance | |
+| CollectionFlow.cs:40:49:40:52 | args : A[] [element] : A | CollectionFlow.cs:40:63:40:66 | access to parameter args : A[] [element] : A | provenance | |
+| CollectionFlow.cs:40:49:40:52 | args : null [element] : A | CollectionFlow.cs:40:63:40:66 | access to parameter args : null [element] : A | provenance | |
+| CollectionFlow.cs:40:63:40:66 | access to parameter args : A[] [element] : A | CollectionFlow.cs:40:63:40:69 | access to array element | provenance | |
+| CollectionFlow.cs:40:63:40:66 | access to parameter args : null [element] : A | CollectionFlow.cs:40:63:40:69 | access to array element | provenance | |
+| CollectionFlow.cs:42:70:42:73 | args : IEnumerable [element] : A | CollectionFlow.cs:42:84:42:87 | access to parameter args : IEnumerable [element] : A | provenance | |
+| CollectionFlow.cs:42:84:42:87 | access to parameter args : IEnumerable [element] : A | CollectionFlow.cs:42:84:42:95 | call to method First | provenance | MaD:17 |
+| CollectionFlow.cs:46:13:46:13 | access to local variable a : A | CollectionFlow.cs:47:27:47:27 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:46:17:46:23 | object creation of type A : A | CollectionFlow.cs:46:13:46:13 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:47:13:47:15 | access to local variable as : null [element] : A | CollectionFlow.cs:48:14:48:16 | access to local variable as : null [element] : A | provenance | |
+| CollectionFlow.cs:47:13:47:15 | access to local variable as : null [element] : A | CollectionFlow.cs:49:18:49:20 | access to local variable as : null [element] : A | provenance | |
+| CollectionFlow.cs:47:13:47:15 | access to local variable as : null [element] : A | CollectionFlow.cs:50:20:50:22 | access to local variable as : null [element] : A | provenance | |
+| CollectionFlow.cs:47:25:47:29 | { ..., ... } : null [element] : A | CollectionFlow.cs:47:13:47:15 | access to local variable as : null [element] : A | provenance | |
+| CollectionFlow.cs:47:27:47:27 | access to local variable a : A | CollectionFlow.cs:47:25:47:29 | { ..., ... } : null [element] : A | provenance | |
+| CollectionFlow.cs:48:14:48:16 | access to local variable as : null [element] : A | CollectionFlow.cs:48:14:48:19 | access to array element | provenance | |
+| CollectionFlow.cs:49:18:49:20 | access to local variable as : null [element] : A | CollectionFlow.cs:14:40:14:41 | ts : null [element] : A | provenance | |
+| CollectionFlow.cs:50:20:50:22 | access to local variable as : null [element] : A | CollectionFlow.cs:24:34:24:35 | ts : null [element] : A | provenance | |
+| CollectionFlow.cs:50:20:50:22 | access to local variable as : null [element] : A | CollectionFlow.cs:50:14:50:23 | call to method First | provenance | |
+| CollectionFlow.cs:64:13:64:13 | access to local variable a : A | CollectionFlow.cs:65:53:65:53 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:64:17:64:23 | object creation of type A : A | CollectionFlow.cs:64:13:64:13 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:65:13:65:13 | access to local variable c : CollectionFlow [field As, element] : A | CollectionFlow.cs:66:14:66:14 | access to local variable c : CollectionFlow [field As, element] : A | provenance | |
+| CollectionFlow.cs:65:13:65:13 | access to local variable c : CollectionFlow [field As, element] : A | CollectionFlow.cs:67:18:67:18 | access to local variable c : CollectionFlow [field As, element] : A | provenance | |
+| CollectionFlow.cs:65:13:65:13 | access to local variable c : CollectionFlow [field As, element] : A | CollectionFlow.cs:68:20:68:20 | access to local variable c : CollectionFlow [field As, element] : A | provenance | |
+| CollectionFlow.cs:65:38:65:57 | { ..., ... } : CollectionFlow [field As, element] : A | CollectionFlow.cs:65:13:65:13 | access to local variable c : CollectionFlow [field As, element] : A | provenance | |
+| CollectionFlow.cs:65:45:65:55 | { ..., ... } : A[] [element] : A | CollectionFlow.cs:65:38:65:57 | { ..., ... } : CollectionFlow [field As, element] : A | provenance | |
+| CollectionFlow.cs:65:53:65:53 | access to local variable a : A | CollectionFlow.cs:65:45:65:55 | { ..., ... } : A[] [element] : A | provenance | |
+| CollectionFlow.cs:66:14:66:14 | access to local variable c : CollectionFlow [field As, element] : A | CollectionFlow.cs:66:14:66:17 | access to field As : A[] [element] : A | provenance | |
+| CollectionFlow.cs:66:14:66:17 | access to field As : A[] [element] : A | CollectionFlow.cs:66:14:66:20 | access to array element | provenance | |
+| CollectionFlow.cs:67:18:67:18 | access to local variable c : CollectionFlow [field As, element] : A | CollectionFlow.cs:67:18:67:21 | access to field As : A[] [element] : A | provenance | |
+| CollectionFlow.cs:67:18:67:21 | access to field As : A[] [element] : A | CollectionFlow.cs:14:40:14:41 | ts : A[] [element] : A | provenance | |
+| CollectionFlow.cs:68:20:68:20 | access to local variable c : CollectionFlow [field As, element] : A | CollectionFlow.cs:68:20:68:23 | access to field As : A[] [element] : A | provenance | |
+| CollectionFlow.cs:68:20:68:23 | access to field As : A[] [element] : A | CollectionFlow.cs:24:34:24:35 | ts : A[] [element] : A | provenance | |
+| CollectionFlow.cs:68:20:68:23 | access to field As : A[] [element] : A | CollectionFlow.cs:68:14:68:24 | call to method First | provenance | |
+| CollectionFlow.cs:82:13:82:13 | access to local variable a : A | CollectionFlow.cs:83:54:83:54 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:82:17:82:23 | object creation of type A : A | CollectionFlow.cs:82:13:82:13 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:83:13:83:13 | access to local variable c : CollectionFlow [field As, element] : A | CollectionFlow.cs:84:14:84:14 | access to local variable c : CollectionFlow [field As, element] : A | provenance | |
+| CollectionFlow.cs:83:13:83:13 | access to local variable c : CollectionFlow [field As, element] : A | CollectionFlow.cs:85:22:85:22 | access to local variable c : CollectionFlow [field As, element] : A | provenance | |
+| CollectionFlow.cs:83:13:83:13 | access to local variable c : CollectionFlow [field As, element] : A | CollectionFlow.cs:86:19:86:19 | access to local variable c : CollectionFlow [field As, element] : A | provenance | |
+| CollectionFlow.cs:83:38:83:58 | { ..., ... } : CollectionFlow [field As, element] : A | CollectionFlow.cs:83:13:83:13 | access to local variable c : CollectionFlow [field As, element] : A | provenance | |
+| CollectionFlow.cs:83:45:83:56 | { ..., ... } : A[] [element] : A | CollectionFlow.cs:83:38:83:58 | { ..., ... } : CollectionFlow [field As, element] : A | provenance | |
+| CollectionFlow.cs:83:54:83:54 | access to local variable a : A | CollectionFlow.cs:83:45:83:56 | { ..., ... } : A[] [element] : A | provenance | |
+| CollectionFlow.cs:84:14:84:14 | access to local variable c : CollectionFlow [field As, element] : A | CollectionFlow.cs:84:14:84:17 | access to field As : A[] [element] : A | provenance | |
+| CollectionFlow.cs:84:14:84:17 | access to field As : A[] [element] : A | CollectionFlow.cs:84:14:84:21 | access to array element | provenance | |
+| CollectionFlow.cs:85:22:85:22 | access to local variable c : CollectionFlow [field As, element] : A | CollectionFlow.cs:85:22:85:25 | access to field As : A[] [element] : A | provenance | |
+| CollectionFlow.cs:85:22:85:25 | access to field As : A[] [element] : A | CollectionFlow.cs:16:44:16:45 | ts : A[] [element] : A | provenance | |
+| CollectionFlow.cs:86:19:86:19 | access to local variable c : CollectionFlow [field As, element] : A | CollectionFlow.cs:86:19:86:22 | access to field As : A[] [element] : A | provenance | |
+| CollectionFlow.cs:86:19:86:22 | access to field As : A[] [element] : A | CollectionFlow.cs:26:33:26:34 | ts : A[] [element] : A | provenance | |
+| CollectionFlow.cs:86:19:86:22 | access to field As : A[] [element] : A | CollectionFlow.cs:86:14:86:23 | call to method Last | provenance | |
+| CollectionFlow.cs:91:13:91:13 | access to local variable a : A | CollectionFlow.cs:93:18:93:18 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:91:17:91:23 | object creation of type A : A | CollectionFlow.cs:91:13:91:13 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:93:9:93:11 | [post] access to local variable as : A[] [element] : A | CollectionFlow.cs:94:14:94:16 | access to local variable as : A[] [element] : A | provenance | |
+| CollectionFlow.cs:93:9:93:11 | [post] access to local variable as : A[] [element] : A | CollectionFlow.cs:95:18:95:20 | access to local variable as : A[] [element] : A | provenance | |
+| CollectionFlow.cs:93:9:93:11 | [post] access to local variable as : A[] [element] : A | CollectionFlow.cs:96:20:96:22 | access to local variable as : A[] [element] : A | provenance | |
+| CollectionFlow.cs:93:18:93:18 | access to local variable a : A | CollectionFlow.cs:93:9:93:11 | [post] access to local variable as : A[] [element] : A | provenance | |
+| CollectionFlow.cs:94:14:94:16 | access to local variable as : A[] [element] : A | CollectionFlow.cs:94:14:94:19 | access to array element | provenance | |
+| CollectionFlow.cs:95:18:95:20 | access to local variable as : A[] [element] : A | CollectionFlow.cs:14:40:14:41 | ts : A[] [element] : A | provenance | |
+| CollectionFlow.cs:96:20:96:22 | access to local variable as : A[] [element] : A | CollectionFlow.cs:24:34:24:35 | ts : A[] [element] : A | provenance | |
+| CollectionFlow.cs:96:20:96:22 | access to local variable as : A[] [element] : A | CollectionFlow.cs:96:14:96:23 | call to method First | provenance | |
+| CollectionFlow.cs:111:13:111:13 | access to local variable a : A | CollectionFlow.cs:113:19:113:19 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:111:17:111:23 | object creation of type A : A | CollectionFlow.cs:111:13:111:13 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:113:9:113:11 | [post] access to local variable as : A[] [element] : A | CollectionFlow.cs:114:14:114:16 | access to local variable as : A[] [element] : A | provenance | |
+| CollectionFlow.cs:113:9:113:11 | [post] access to local variable as : A[] [element] : A | CollectionFlow.cs:115:22:115:24 | access to local variable as : A[] [element] : A | provenance | |
+| CollectionFlow.cs:113:9:113:11 | [post] access to local variable as : A[] [element] : A | CollectionFlow.cs:116:19:116:21 | access to local variable as : A[] [element] : A | provenance | |
+| CollectionFlow.cs:113:19:113:19 | access to local variable a : A | CollectionFlow.cs:113:9:113:11 | [post] access to local variable as : A[] [element] : A | provenance | |
+| CollectionFlow.cs:114:14:114:16 | access to local variable as : A[] [element] : A | CollectionFlow.cs:114:14:114:20 | access to array element | provenance | |
+| CollectionFlow.cs:115:22:115:24 | access to local variable as : A[] [element] : A | CollectionFlow.cs:16:44:16:45 | ts : A[] [element] : A | provenance | |
+| CollectionFlow.cs:116:19:116:21 | access to local variable as : A[] [element] : A | CollectionFlow.cs:26:33:26:34 | ts : A[] [element] : A | provenance | |
+| CollectionFlow.cs:116:19:116:21 | access to local variable as : A[] [element] : A | CollectionFlow.cs:116:14:116:22 | call to method Last | provenance | |
+| CollectionFlow.cs:121:13:121:13 | access to local variable a : A | CollectionFlow.cs:123:19:123:19 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:121:17:121:23 | object creation of type A : A | CollectionFlow.cs:121:13:121:13 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:123:9:123:12 | [post] access to local variable list : List [element] : A | CollectionFlow.cs:124:14:124:17 | access to local variable list : List [element] : A | provenance | |
+| CollectionFlow.cs:123:9:123:12 | [post] access to local variable list : List [element] : A | CollectionFlow.cs:125:22:125:25 | access to local variable list : List [element] : A | provenance | |
+| CollectionFlow.cs:123:9:123:12 | [post] access to local variable list : List [element] : A | CollectionFlow.cs:126:24:126:27 | access to local variable list : List [element] : A | provenance | |
+| CollectionFlow.cs:123:19:123:19 | access to local variable a : A | CollectionFlow.cs:123:9:123:12 | [post] access to local variable list : List [element] : A | provenance | MaD:12 |
+| CollectionFlow.cs:124:14:124:17 | access to local variable list : List [element] : A | CollectionFlow.cs:124:14:124:20 | access to indexer | provenance | MaD:11 |
+| CollectionFlow.cs:125:22:125:25 | access to local variable list : List [element] : A | CollectionFlow.cs:18:49:18:52 | list : List [element] : A | provenance | |
+| CollectionFlow.cs:126:24:126:27 | access to local variable list : List [element] : A | CollectionFlow.cs:28:43:28:46 | list : List [element] : A | provenance | |
+| CollectionFlow.cs:126:24:126:27 | access to local variable list : List [element] : A | CollectionFlow.cs:126:14:126:28 | call to method ListFirst | provenance | MaD:11 |
+| CollectionFlow.cs:140:13:140:13 | access to local variable a : A | CollectionFlow.cs:141:36:141:36 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:140:17:140:23 | object creation of type A : A | CollectionFlow.cs:140:13:140:13 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:141:13:141:16 | access to local variable list : List [element] : A | CollectionFlow.cs:142:14:142:17 | access to local variable list : List [element] : A | provenance | |
+| CollectionFlow.cs:141:13:141:16 | access to local variable list : List [element] : A | CollectionFlow.cs:143:22:143:25 | access to local variable list : List [element] : A | provenance | |
+| CollectionFlow.cs:141:13:141:16 | access to local variable list : List [element] : A | CollectionFlow.cs:144:24:144:27 | access to local variable list : List [element] : A | provenance | |
+| CollectionFlow.cs:141:20:141:38 | object creation of type List : List [element] : A | CollectionFlow.cs:141:13:141:16 | access to local variable list : List [element] : A | provenance | |
+| CollectionFlow.cs:141:36:141:36 | access to local variable a : A | CollectionFlow.cs:141:20:141:38 | object creation of type List : List [element] : A | provenance | MaD:3 |
+| CollectionFlow.cs:142:14:142:17 | access to local variable list : List [element] : A | CollectionFlow.cs:142:14:142:20 | access to indexer | provenance | MaD:11 |
+| CollectionFlow.cs:143:22:143:25 | access to local variable list : List [element] : A | CollectionFlow.cs:18:49:18:52 | list : List [element] : A | provenance | |
+| CollectionFlow.cs:144:24:144:27 | access to local variable list : List [element] : A | CollectionFlow.cs:28:43:28:46 | list : List [element] : A | provenance | |
+| CollectionFlow.cs:144:24:144:27 | access to local variable list : List [element] : A | CollectionFlow.cs:144:14:144:28 | call to method ListFirst | provenance | MaD:11 |
+| CollectionFlow.cs:157:13:157:13 | access to local variable a : A | CollectionFlow.cs:159:18:159:18 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:157:17:157:23 | object creation of type A : A | CollectionFlow.cs:157:13:157:13 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:159:9:159:12 | [post] access to local variable list : List [element] : A | CollectionFlow.cs:160:14:160:17 | access to local variable list : List [element] : A | provenance | |
+| CollectionFlow.cs:159:9:159:12 | [post] access to local variable list : List [element] : A | CollectionFlow.cs:161:22:161:25 | access to local variable list : List [element] : A | provenance | |
+| CollectionFlow.cs:159:9:159:12 | [post] access to local variable list : List [element] : A | CollectionFlow.cs:162:24:162:27 | access to local variable list : List [element] : A | provenance | |
+| CollectionFlow.cs:159:18:159:18 | access to local variable a : A | CollectionFlow.cs:159:9:159:12 | [post] access to local variable list : List [element] : A | provenance | MaD:3 |
+| CollectionFlow.cs:160:14:160:17 | access to local variable list : List [element] : A | CollectionFlow.cs:160:14:160:20 | access to indexer | provenance | MaD:11 |
+| CollectionFlow.cs:161:22:161:25 | access to local variable list : List [element] : A | CollectionFlow.cs:18:49:18:52 | list : List [element] : A | provenance | |
+| CollectionFlow.cs:162:24:162:27 | access to local variable list : List [element] : A | CollectionFlow.cs:28:43:28:46 | list : List [element] : A | provenance | |
+| CollectionFlow.cs:162:24:162:27 | access to local variable list : List [element] : A | CollectionFlow.cs:162:14:162:28 | call to method ListFirst | provenance | MaD:11 |
+| CollectionFlow.cs:176:13:176:13 | access to local variable a : A | CollectionFlow.cs:178:19:178:19 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:176:17:176:23 | object creation of type A : A | CollectionFlow.cs:176:13:176:13 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:178:9:178:12 | [post] access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:179:14:179:17 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:178:9:178:12 | [post] access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:180:23:180:26 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:178:9:178:12 | [post] access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:181:28:181:31 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:178:9:178:12 | [post] access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:182:29:182:32 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:178:9:178:12 | [post] access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:183:30:183:33 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:178:19:178:19 | access to local variable a : A | CollectionFlow.cs:178:9:178:12 | [post] access to local variable dict : Dictionary [element, property Value] : A | provenance | MaD:10 |
+| CollectionFlow.cs:179:14:179:17 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:179:14:179:20 | access to indexer | provenance | MaD:6 |
+| CollectionFlow.cs:180:23:180:26 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:20:61:20:64 | dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:181:28:181:31 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:58:30:61 | dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:181:28:181:31 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:181:14:181:32 | call to method DictIndexZero | provenance | MaD:6 |
+| CollectionFlow.cs:182:29:182:32 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:32:59:32:62 | dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:182:29:182:32 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:182:14:182:33 | call to method DictFirstValue | provenance | MaD:17 |
+| CollectionFlow.cs:183:30:183:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:34:60:34:63 | dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:183:30:183:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:183:14:183:34 | call to method DictValuesFirst | provenance | MaD:2 |
+| CollectionFlow.cs:183:30:183:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:183:14:183:34 | call to method DictValuesFirst | provenance | MaD:8 |
+| CollectionFlow.cs:199:13:199:13 | access to local variable a : A | CollectionFlow.cs:200:52:200:52 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:199:17:199:23 | object creation of type A : A | CollectionFlow.cs:199:13:199:13 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:200:13:200:16 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:201:14:201:17 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:200:13:200:16 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:202:23:202:26 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:200:13:200:16 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:203:28:203:31 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:200:13:200:16 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:204:29:204:32 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:200:13:200:16 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:205:30:205:33 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:200:20:200:56 | object creation of type Dictionary : Dictionary [element, property Value] : A | CollectionFlow.cs:200:13:200:16 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:200:52:200:52 | access to local variable a : A | CollectionFlow.cs:200:20:200:56 | object creation of type Dictionary : Dictionary [element, property Value] : A | provenance | MaD:5 |
+| CollectionFlow.cs:201:14:201:17 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:201:14:201:20 | access to indexer | provenance | MaD:6 |
+| CollectionFlow.cs:202:23:202:26 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:20:61:20:64 | dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:203:28:203:31 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:58:30:61 | dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:203:28:203:31 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:203:14:203:32 | call to method DictIndexZero | provenance | MaD:6 |
+| CollectionFlow.cs:204:29:204:32 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:32:59:32:62 | dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:204:29:204:32 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:204:14:204:33 | call to method DictFirstValue | provenance | MaD:17 |
+| CollectionFlow.cs:205:30:205:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:34:60:34:63 | dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:205:30:205:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:205:14:205:34 | call to method DictValuesFirst | provenance | MaD:2 |
+| CollectionFlow.cs:205:30:205:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:205:14:205:34 | call to method DictValuesFirst | provenance | MaD:8 |
+| CollectionFlow.cs:220:13:220:13 | access to local variable a : A | CollectionFlow.cs:221:53:221:53 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:220:17:220:23 | object creation of type A : A | CollectionFlow.cs:220:13:220:13 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:221:13:221:16 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:222:14:222:17 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:221:13:221:16 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:223:23:223:26 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:221:13:221:16 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:224:28:224:31 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:221:13:221:16 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:225:29:225:32 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:221:13:221:16 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:226:30:226:33 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:221:20:221:55 | object creation of type Dictionary : Dictionary [element, property Value] : A | CollectionFlow.cs:221:13:221:16 | access to local variable dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:221:53:221:53 | access to local variable a : A | CollectionFlow.cs:221:20:221:55 | object creation of type Dictionary : Dictionary [element, property Value] : A | provenance | MaD:10 |
+| CollectionFlow.cs:222:14:222:17 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:222:14:222:20 | access to indexer | provenance | MaD:6 |
+| CollectionFlow.cs:223:23:223:26 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:20:61:20:64 | dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:224:28:224:31 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:58:30:61 | dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:224:28:224:31 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:224:14:224:32 | call to method DictIndexZero | provenance | MaD:6 |
+| CollectionFlow.cs:225:29:225:32 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:32:59:32:62 | dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:225:29:225:32 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:225:14:225:33 | call to method DictFirstValue | provenance | MaD:17 |
+| CollectionFlow.cs:226:30:226:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:34:60:34:63 | dict : Dictionary [element, property Value] : A | provenance | |
+| CollectionFlow.cs:226:30:226:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:226:14:226:34 | call to method DictValuesFirst | provenance | MaD:2 |
+| CollectionFlow.cs:226:30:226:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:226:14:226:34 | call to method DictValuesFirst | provenance | MaD:8 |
+| CollectionFlow.cs:242:13:242:13 | access to local variable a : A | CollectionFlow.cs:243:49:243:49 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:242:17:242:23 | object creation of type A : A | CollectionFlow.cs:242:13:242:13 | access to local variable a : A | provenance | |
+| CollectionFlow.cs:243:13:243:16 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:244:14:244:17 | access to local variable dict : Dictionary [element, property Key] : A | provenance | |
+| CollectionFlow.cs:243:13:243:16 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:245:21:245:24 | access to local variable dict : Dictionary [element, property Key] : A | provenance | |
+| CollectionFlow.cs:243:13:243:16 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:246:28:246:31 | access to local variable dict : Dictionary [element, property Key] : A | provenance | |
+| CollectionFlow.cs:243:13:243:16 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:247:27:247:30 | access to local variable dict : Dictionary [element, property Key] : A | provenance | |
+| CollectionFlow.cs:243:20:243:56 | object creation of type Dictionary : Dictionary [element, property Key] : A | CollectionFlow.cs:243:13:243:16 | access to local variable dict : Dictionary [element, property Key] : A | provenance | |
+| CollectionFlow.cs:243:49:243:49 | access to local variable a : A | CollectionFlow.cs:243:20:243:56 | object creation of type Dictionary : Dictionary [element, property Key] : A | provenance | MaD:4 |
+| CollectionFlow.cs:244:14:244:17 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:244:14:244:22 | access to property Keys : Dictionary.KeyCollection [element] : A | provenance | MaD:1 |
+| CollectionFlow.cs:244:14:244:22 | access to property Keys : Dictionary.KeyCollection [element] : A | CollectionFlow.cs:244:14:244:30 | call to method First | provenance | MaD:17 |
+| CollectionFlow.cs:245:21:245:24 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:22:59:22:62 | dict : Dictionary [element, property Key] : A | provenance | |
+| CollectionFlow.cs:246:28:246:31 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:36:58:36:61 | dict : Dictionary [element, property Key] : A | provenance | |
+| CollectionFlow.cs:246:28:246:31 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:246:14:246:32 | call to method DictKeysFirst | provenance | MaD:1 |
+| CollectionFlow.cs:246:28:246:31 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:246:14:246:32 | call to method DictKeysFirst | provenance | MaD:7 |
+| CollectionFlow.cs:247:27:247:30 | access to local variable dict : Dictionary