diff --git a/.bazelrc b/.bazelrc index 12232b4bbd68..c2b4d3b7f03e 100644 --- a/.bazelrc +++ b/.bazelrc @@ -14,4 +14,11 @@ build:linux --cxxopt=-std=c++20 build:macos --cxxopt=-std=c++20 --cpu=darwin_x86_64 build:windows --cxxopt=/std:c++20 --cxxopt=/Zc:preprocessor +# this requires developer mode, but is required to have pack installer functioning +startup --windows_enable_symlinks +common --enable_runfiles + +common --registry=file:///%workspace%/misc/bazel/registry +common --registry=https://bcr.bazel.build + try-import %workspace%/local.bazelrc diff --git a/.bazelrc.internal b/.bazelrc.internal new file mode 100644 index 000000000000..cdffa9ccdea6 --- /dev/null +++ b/.bazelrc.internal @@ -0,0 +1,4 @@ +# this file should contain bazel settings required to build things from `semmle-code` + +common --registry=file:///%workspace%/ql/misc/bazel/registry +common --registry=https://bcr.bazel.build diff --git a/.github/workflows/buildifier.yml b/.github/workflows/buildifier.yml new file mode 100644 index 000000000000..b5d1e2244d5c --- /dev/null +++ b/.github/workflows/buildifier.yml @@ -0,0 +1,28 @@ +name: Check bazel formatting + +on: + pull_request: + paths: + - "**.bazel" + - "**.bzl" + branches: + - main + - "rc/*" + +permissions: + contents: read + +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Check bazel formatting + uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507 + with: + extra_args: > + buildifier --all-files 2>&1 || + ( + echo -e "In order to format all bazel files, please run:\n bazel run //misc/bazel:buildifier"; exit 1 + ) diff --git a/.lfsconfig b/.lfsconfig new file mode 100644 index 000000000000..cb0a8e352e86 --- /dev/null +++ b/.lfsconfig @@ -0,0 +1,5 @@ +[lfs] +# codeql is publicly forked by many users, and we don't want any LFS file polluting their working +# copies. We therefore exclude everything by default. +# For files required by bazel builds, use rules in `misc/bazel/lfs.bzl` to download them on demand. +fetchinclude = /nothing diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 383bc1103837..051044904686 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,13 +20,22 @@ repos: - id: autopep8 files: ^misc/codegen/.*\.py - - repo: https://github.com/warchant/pre-commit-buildifier - rev: 0.0.2 + - repo: local hooks: - id: buildifier + name: Format bazel files + files: \.(bazel|bzl) + language: system + entry: bazel run //misc/bazel:buildifier + pass_filenames: false + + - id: go-gen + name: Check checked in generated files in go + files: ^go/.* + language: system + entry: bazel run //go:gen + pass_filenames: false - - repo: local - hooks: - id: codeql-format name: Fix QL file formatting files: \.qll?$ diff --git a/MODULE.bazel b/MODULE.bazel index 4e1fe0d9f7cb..27479e1978f7 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -13,7 +13,8 @@ local_path_override( # see https://registry.bazel.build/ for a list of available packages -bazel_dep(name = "platforms", version = "0.0.8") +bazel_dep(name = "platforms", version = "0.0.9") +bazel_dep(name = "rules_go", version = "0.47.0") bazel_dep(name = "rules_pkg", version = "0.10.1") bazel_dep(name = "rules_nodejs", version = "6.0.3") bazel_dep(name = "rules_python", version = "0.31.0") @@ -21,6 +22,9 @@ bazel_dep(name = "bazel_skylib", version = "1.5.0") bazel_dep(name = "abseil-cpp", version = "20240116.0", repo_name = "absl") bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json") bazel_dep(name = "fmt", version = "10.0.0") +bazel_dep(name = "gazelle", version = "0.36.0") + +bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True) pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") pip.parse( @@ -50,6 +54,9 @@ node.toolchain( ) use_repo(node, "nodejs", "nodejs_toolchains") +go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") +go_sdk.download(version = "1.22.2") + register_toolchains( "@nodejs_toolchains//:all", ) diff --git a/config/identical-files.json b/config/identical-files.json index a8b1368f1af4..d810e30c0c8e 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -362,7 +362,7 @@ "java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll" ], "Python model summaries test extension": [ - "python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ext.yml", - "python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ext.yml" + "python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml", + "python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml" ] -} \ No newline at end of file +} diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index e480b46a279d..bcb7d30a2ed9 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,20 @@ +## 0.13.0 + +### Breaking Changes + +* Deleted the deprecated `GlobalValueNumberingImpl.qll` implementation. + +### New Features + +* Models-as-Data support has been added for C/C++. This feature allows flow sources, sinks and summaries to be expressed in compact strings as an alternative to modelling each source / sink / summary with explicit QL. See `dataflow/ExternalFlow.qll` for documentation and specification of the model format, and `models/implementations/ZMQ.qll` for a simple example of models. Importing models from `.yml` is not yet supported. + +### Minor Analysis Improvements + +* Source models have been added for the standard library function `getc` (and variations). +* Source, sink and flow models for the ZeroMQ (ZMQ) networking library have been added. +* Parameters of functions without definitions now have `ParameterNode`s. +* The alias analysis used internally by various libraries has been improved to answer alias questions more conservatively. As a result, some queries may report fewer false positives. + ## 0.12.11 No user-facing changes. diff --git a/cpp/ql/lib/change-notes/2024-04-05-sound-ir.md b/cpp/ql/lib/change-notes/2024-04-05-sound-ir.md deleted file mode 100644 index 0bb930934168..000000000000 --- a/cpp/ql/lib/change-notes/2024-04-05-sound-ir.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The alias analysis used internally by various libraries has been improved to answer alias questions more conservatively. As a result, some queries may report fewer false positives. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2024-04-18-param-nodes.md b/cpp/ql/lib/change-notes/2024-04-18-param-nodes.md deleted file mode 100644 index 1911af38d8a0..000000000000 --- a/cpp/ql/lib/change-notes/2024-04-18-param-nodes.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Parameters of functions without definitions now have `ParameterNode`s. diff --git a/cpp/ql/lib/change-notes/2024-10-04-getc.md b/cpp/ql/lib/change-notes/2024-10-04-getc.md deleted file mode 100644 index 9174b7a11848..000000000000 --- a/cpp/ql/lib/change-notes/2024-10-04-getc.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Source models have been added for the standard library function `getc` (and variations). diff --git a/cpp/ql/lib/change-notes/2024-10-04-models-as-data.md b/cpp/ql/lib/change-notes/2024-10-04-models-as-data.md deleted file mode 100644 index 83e660cdb649..000000000000 --- a/cpp/ql/lib/change-notes/2024-10-04-models-as-data.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Models-as-Data support has been added for C/C++. This feature allows flow sources, sinks and summaries to be expressed in compact strings as an alternative to modelling each source / sink / summary with explicit QL. See `dataflow/ExternalFlow.qll` for documentation and specification of the model format, and `models/implementations/ZMQ.qll` for a simple example of models. Importing models from `.yml` is not yet supported. diff --git a/cpp/ql/lib/change-notes/2024-10-04-zmq.md b/cpp/ql/lib/change-notes/2024-10-04-zmq.md deleted file mode 100644 index 2800a4d55b34..000000000000 --- a/cpp/ql/lib/change-notes/2024-10-04-zmq.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Source, sink and flow models for the ZeroMQ (ZMQ) networking library have been added. diff --git a/cpp/ql/lib/change-notes/released/0.13.0.md b/cpp/ql/lib/change-notes/released/0.13.0.md new file mode 100644 index 000000000000..84dc06b699cb --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.13.0.md @@ -0,0 +1,16 @@ +## 0.13.0 + +### Breaking Changes + +* Deleted the deprecated `GlobalValueNumberingImpl.qll` implementation. + +### New Features + +* Models-as-Data support has been added for C/C++. This feature allows flow sources, sinks and summaries to be expressed in compact strings as an alternative to modelling each source / sink / summary with explicit QL. See `dataflow/ExternalFlow.qll` for documentation and specification of the model format, and `models/implementations/ZMQ.qll` for a simple example of models. Importing models from `.yml` is not yet supported. + +### Minor Analysis Improvements + +* Source models have been added for the standard library function `getc` (and variations). +* Source, sink and flow models for the ZeroMQ (ZMQ) networking library have been added. +* Parameters of functions without definitions now have `ParameterNode`s. +* The alias analysis used internally by various libraries has been improved to answer alias questions more conservatively. As a result, some queries may report fewer false positives. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 18a7ef452ef3..5a1b274ee587 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.12.11 +lastReleaseVersion: 0.13.0 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 4691c2b2a9af..b87cf42fb6fb 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.12.12-dev +version: 0.13.1-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/lib/semmle/code/cpp/PrintAST.qll b/cpp/ql/lib/semmle/code/cpp/PrintAST.qll index beabef322d20..b515a346bf3b 100644 --- a/cpp/ql/lib/semmle/code/cpp/PrintAST.qll +++ b/cpp/ql/lib/semmle/code/cpp/PrintAST.qll @@ -463,6 +463,25 @@ class StmtNode extends AstNode { } } +/** + * A node representing a child of a `Stmt` that is itself a `Stmt`. + */ +class ChildStmtNode extends StmtNode { + Stmt childStmt; + + ChildStmtNode() { exists(Stmt parent | parent.getAChild() = childStmt and childStmt = ast) } + + override BaseAstNode getChildInternal(int childIndex) { + result = super.getChildInternal(childIndex) + or + exists(int destructorIndex | + result.getAst() = childStmt.getImplicitDestructorCall(destructorIndex) and + childIndex = + destructorIndex + max(int index | exists(childStmt.getChild(index)) or index = 0) + 1 + ) + } +} + /** * A node representing a `DeclStmt`. */ @@ -674,6 +693,13 @@ class FunctionNode extends FunctionOrGlobalOrNamespaceVariableNode { private string getChildAccessorWithoutConversions(Locatable parent, Element child) { shouldPrintDeclaration(getAnEnclosingDeclaration(parent)) and ( + exists(Stmt s, int i | s.getChild(i) = parent | + exists(int n | + s.getChild(i).(Stmt).getImplicitDestructorCall(n) = child and + result = "getImplicitDestructorCall(" + n + ")" + ) + ) + or exists(Stmt s | s = parent | namedStmtChildPredicates(s, child, result) or diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index ee419dd70249..83f8dc8b3bc7 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -790,6 +790,27 @@ private predicate simple_comparison_eq(Instruction test, Operand op, int k, Abst exists(switch.getSuccessor(case)) and case.getValue().toInt() = k ) + or + // There's no implicit CompareInstruction in files compiled as C since C + // doesn't have implicit boolean conversions. So instead we check whether + // there's a branch on a value of pointer or integer type. + exists(ConditionalBranchInstruction branch, IRType type | + not test instanceof CompareInstruction and + type = test.getResultIRType() and + (type instanceof IRAddressType or type instanceof IRIntegerType) and + test = branch.getCondition() and + op.getDef() = test + | + // We'd like to also include a case such as: + // ``` + // k = 1 and + // value.(BooleanValue).getValue() = true + // ``` + // but all we know is that the value is non-zero in the true branch. + // So we can only conclude something in the false branch. + k = 0 and + value.(BooleanValue).getValue() = false + ) } private predicate complex_eq( @@ -1156,5 +1177,14 @@ private predicate add_eq( ) } +private class IntegerOrPointerConstantInstruction extends ConstantInstruction { + IntegerOrPointerConstantInstruction() { + this instanceof IntegerConstantInstruction or + this instanceof PointerConstantInstruction + } +} + /** The int value of integer constant expression. */ -private int int_value(Instruction i) { result = i.(IntegerConstantInstruction).getValue().toInt() } +private int int_value(Instruction i) { + result = i.(IntegerOrPointerConstantInstruction).getValue().toInt() +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index e6ad9c86c9bd..bc6ebf2c2958 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -1665,3 +1665,311 @@ class DataFlowSecondLevelScope extends TDataFlowSecondLevelScope { /** Gets the second-level scope containing the node `n`, if any. */ DataFlowSecondLevelScope getSecondLevelScope(Node n) { result.getANode() = n } + +/** + * Module that defines flow through iterators. + * For example, + * ```cpp + * auto it = v.begin(); + * *it = source(); + * ... + * sink(v[0]); + * ``` + */ +module IteratorFlow { + private import codeql.ssa.Ssa as SsaImpl + private import semmle.code.cpp.models.interfaces.Iterator as Interface + private import semmle.code.cpp.models.implementations.Iterator as Impl + + /** + * A variable of some type that can produce an iterator. + */ + class SourceVariable extends Ssa::SourceVariable { + SourceVariable() { + exists(Interface::GetIteratorFunction gets, Cpp::FunctionInput input, int i | + input.isParameterDerefOrQualifierObject(i) and + gets.getsIterator(input, _) + | + this.getType().stripType() = gets.getParameter(i).getType().stripType() + or + i = -1 and + this.getType().stripType() = gets.getDeclaringType() + ) + } + } + + private module SsaInput implements SsaImpl::InputSig { + import Ssa::InputSigCommon + + class SourceVariable = IteratorFlow::SourceVariable; + + /** A call to function that dereferences an iterator. */ + private class IteratorPointerDereferenceCall extends CallInstruction { + IteratorPointerDereferenceCall() { + this.getStaticCallTarget() instanceof Impl::IteratorPointerDereferenceOperator + } + } + + /** A call to a function that obtains an iterator. */ + private class GetsIteratorCall extends CallInstruction { + GetsIteratorCall() { this.getStaticCallTarget() instanceof Impl::GetIteratorFunction } + } + + /** A call to `operator++` or `operator--` on an iterator. */ + private class IteratorCrementCall extends CallInstruction { + IteratorCrementCall() { this.getStaticCallTarget() instanceof Impl::IteratorCrementOperator } + } + + /** + * Gets an ultimate definition of `def`. + * + * Note: Unlike `def.getAnUltimateDefinition()` this predicate also + * traverses back through iterator increment and decrement operations. + */ + private Ssa::Def getAnUltimateDefinition(Ssa::Def def) { + result = def.getAnUltimateDefinition() + or + exists(IRBlock bb, int i, IteratorCrementCall crementCall, Ssa::SourceVariable sv | + crementCall = def.getValue().asInstruction().(StoreInstruction).getSourceValue() and + sv = def.getSourceVariable() and + bb.getInstruction(i) = crementCall and + Ssa::ssaDefReachesRead(sv, result.asDef(), bb, i) + ) + } + + /** + * Holds if `write` is an instruction that writes to address `address` + */ + private predicate isIteratorWrite(Instruction write, Operand address) { + exists(Ssa::DefImpl writeDef, IRBlock bb, int i | + writeDef.hasIndexInBlock(bb, i, _) and + bb.getInstruction(i) = write and + address = writeDef.getAddressOperand() + ) + } + + /** + * Holds if `writeToDeref` is a write to an iterator that was obtained + * by `beginCall`. That is, the following instruction sequence holds: + * ```cpp + * it = container.begin(); // or a similar iterator-obtaining function call + * ... + * *it = value; + * ``` + */ + private predicate isIteratorStoreInstruction( + GetsIteratorCall beginCall, Instruction writeToDeref + ) { + exists( + StoreInstruction beginStore, IRBlock bbStar, int iStar, Ssa::Def def, + IteratorPointerDereferenceCall starCall, Ssa::Def ultimate, Operand address + | + isIteratorWrite(writeToDeref, address) and + operandForFullyConvertedCall(address, starCall) and + bbStar.getInstruction(iStar) = starCall and + Ssa::ssaDefReachesRead(_, def.asDef(), bbStar, iStar) and + ultimate = getAnUltimateDefinition*(def) and + beginStore = ultimate.getValue().asInstruction() and + operandForFullyConvertedCall(beginStore.getSourceValueOperand(), beginCall) + ) + } + + /** + * Holds if `(bb, i)` contains a write to an iterator that may have been obtained + * by calling `begin` (or related functions) on the variable `v`. + */ + predicate variableWrite(IRBlock bb, int i, SourceVariable v, boolean certain) { + certain = false and + exists(GetsIteratorCall beginCall, Instruction writeToDeref, IRBlock bbQual, int iQual | + isIteratorStoreInstruction(beginCall, writeToDeref) and + bb.getInstruction(i) = writeToDeref and + bbQual.getInstruction(iQual) = beginCall and + Ssa::variableRead(bbQual, iQual, v, _) + ) + } + + /** Holds if `(bb, i)` reads the container variable `v`. */ + predicate variableRead(IRBlock bb, int i, SourceVariable v, boolean certain) { + Ssa::variableRead(bb, i, v, certain) + } + } + + private module IteratorSsa = SsaImpl::Make; + + cached + private newtype TSsaDef = + TDef(IteratorSsa::DefinitionExt def) or + TPhi(PhiNode phi) + + abstract private class SsaDef extends TSsaDef { + /** Gets a textual representation of this element. */ + string toString() { none() } + + /** Gets the underlying non-phi definition or use. */ + IteratorSsa::DefinitionExt asDef() { none() } + + /** Gets the underlying phi node. */ + PhiNode asPhi() { none() } + + /** Gets the location of this element. */ + abstract Location getLocation(); + } + + private class Def extends TDef, SsaDef { + IteratorSsa::DefinitionExt def; + + Def() { this = TDef(def) } + + final override IteratorSsa::DefinitionExt asDef() { result = def } + + final override Location getLocation() { result = this.getImpl().getLocation() } + + /** Gets the variable written to by this definition. */ + final SourceVariable getSourceVariable() { result = def.getSourceVariable() } + + override string toString() { result = def.toString() } + + /** + * Holds if this definition (or use) has index `index` in block `block`, + * and is a definition (or use) of the variable `sv`. + */ + predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) { + def.definesAt(sv, block, index, _) + } + + private Ssa::DefImpl getImpl() { + exists(IRBlock bb, int i | + this.hasIndexInBlock(bb, i, _) and + result.hasIndexInBlock(bb, i) + ) + } + + /** Gets the value written by this definition (i.e., the "right-hand side"). */ + Node0Impl getValue() { result = this.getImpl().getValue() } + + /** Gets the indirection index of this definition. */ + int getIndirectionIndex() { result = this.getImpl().getIndirectionIndex() } + } + + private class Phi extends TPhi, SsaDef { + PhiNode phi; + + Phi() { this = TPhi(phi) } + + final override PhiNode asPhi() { result = phi } + + final override Location getLocation() { result = phi.getBasicBlock().getLocation() } + + override string toString() { result = phi.toString() } + + SsaIteratorNode getNode() { result.getIteratorFlowNode() = phi } + } + + private class PhiNode extends IteratorSsa::DefinitionExt { + PhiNode() { + this instanceof IteratorSsa::PhiNode or + this instanceof IteratorSsa::PhiReadNode + } + + SsaIteratorNode getNode() { result.getIteratorFlowNode() = this } + } + + cached + private module IteratorSsaCached { + cached + predicate adjacentDefRead(IRBlock bb1, int i1, SourceVariable sv, IRBlock bb2, int i2) { + IteratorSsa::adjacentDefReadExt(_, sv, bb1, i1, bb2, i2) + or + exists(PhiNode phi | + IteratorSsa::lastRefRedefExt(_, sv, bb1, i1, phi) and + phi.definesAt(sv, bb2, i2, _) + ) + } + + cached + Node getAPriorDefinition(IteratorSsa::DefinitionExt next) { + exists(IRBlock bb, int i, SourceVariable sv, IteratorSsa::DefinitionExt def | + IteratorSsa::lastRefRedefExt(pragma[only_bind_into](def), pragma[only_bind_into](sv), + pragma[only_bind_into](bb), pragma[only_bind_into](i), next) and + nodeToDefOrUse(result, sv, bb, i, _) + ) + } + } + + /** The set of nodes necessary for iterator flow. */ + class IteratorFlowNode instanceof PhiNode { + /** Gets a textual representation of this node. */ + string toString() { result = super.toString() } + + /** Gets the type of this node. */ + DataFlowType getType() { + exists(Ssa::SourceVariable sv | + super.definesAt(sv, _, _, _) and + result = sv.getType() + ) + } + + /** Gets the `Declaration` that contains this block. */ + Declaration getFunction() { result = super.getBasicBlock().getEnclosingFunction() } + + /** Gets the locatino of this node. */ + Location getLocation() { result = super.getBasicBlock().getLocation() } + } + + private import IteratorSsaCached + + private predicate defToNode(Node node, Def def, boolean uncertain) { + ( + nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex()) + or + nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex()) + ) and + uncertain = false + } + + private predicate nodeToDefOrUse( + Node node, SourceVariable sv, IRBlock bb, int i, boolean uncertain + ) { + exists(Def def | + def.hasIndexInBlock(bb, i, sv) and + defToNode(node, def, uncertain) + ) + or + useToNode(bb, i, sv, node) and + uncertain = false + } + + private predicate useToNode(IRBlock bb, int i, SourceVariable sv, Node nodeTo) { + exists(PhiNode phi | + phi.definesAt(sv, bb, i, _) and + nodeTo = phi.getNode() + ) + or + exists(Ssa::UseImpl use | + use.hasIndexInBlock(bb, i, sv) and + nodeTo = use.getNode() + ) + } + + /** + * Holds if `nodeFrom` flows to `nodeTo` in a single step. + */ + predicate localFlowStep(Node nodeFrom, Node nodeTo) { + exists( + Node nFrom, SourceVariable sv, IRBlock bb1, int i1, IRBlock bb2, int i2, boolean uncertain + | + adjacentDefRead(bb1, i1, sv, bb2, i2) and + nodeToDefOrUse(nFrom, sv, bb1, i1, uncertain) and + useToNode(bb2, i2, sv, nodeTo) + | + if uncertain = true + then + nodeFrom = + [ + nFrom, + getAPriorDefinition(any(IteratorSsa::DefinitionExt next | next.definesAt(sv, bb1, i1, _))) + ] + else nFrom = nodeFrom + ) + } +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 94729c47fcb3..dc591dccbb98 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -46,6 +46,7 @@ private newtype TIRDataFlowNode = Ssa::isModifiableByCall(operand, indirectionIndex) } or TSsaPhiNode(Ssa::PhiNode phi) or + TSsaIteratorNode(IteratorFlow::IteratorFlowNode n) or TRawIndirectOperand0(Node0Impl node, int indirectionIndex) { Ssa::hasRawIndirectOperand(node.asOperand(), indirectionIndex) } or @@ -653,6 +654,30 @@ class SsaPhiNode extends Node, TSsaPhiNode { predicate isPhiRead() { phi.isPhiRead() } } +/** + * INTERNAL: do not use. + * + * Dataflow nodes necessary for iterator flow + */ +class SsaIteratorNode extends Node, TSsaIteratorNode { + IteratorFlow::IteratorFlowNode node; + + SsaIteratorNode() { this = TSsaIteratorNode(node) } + + /** Gets the phi node associated with this node. */ + IteratorFlow::IteratorFlowNode getIteratorFlowNode() { result = node } + + override Declaration getEnclosingCallable() { result = this.getFunction() } + + override Declaration getFunction() { result = node.getFunction() } + + override DataFlowType getType() { result = node.getType() } + + final override Location getLocationImpl() { result = node.getLocation() } + + override string toStringImpl() { result = node.toString() } +} + /** * INTERNAL: do not use. * @@ -1190,11 +1215,11 @@ class UninitializedNode extends Node { LocalVariable v; UninitializedNode() { - exists(Ssa::Def def | + exists(Ssa::Def def, Ssa::SourceVariable sv | def.getIndirectionIndex() = 0 and def.getValue().asInstruction() instanceof UninitializedInstruction and - Ssa::nodeToDefOrUse(this, def, _) and - v = def.getSourceVariable().getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst() + Ssa::defToNode(this, def, sv, _, _, _) and + v = sv.getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst() ) } @@ -2151,6 +2176,8 @@ private module Cached { // Def-use/Use-use flow Ssa::ssaFlow(nodeFrom, nodeTo) or + IteratorFlow::localFlowStep(nodeFrom, nodeTo) + or // Operand -> Instruction flow simpleInstructionLocalFlowStep(nodeFrom.asOperand(), nodeTo.asInstruction()) or diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index 7eb84aefe3f4..e1512366c709 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -9,6 +9,7 @@ private import semmle.code.cpp.models.interfaces.PartialFlow as PartialFlow private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs as FIO private import semmle.code.cpp.ir.internal.IRCppLanguage private import semmle.code.cpp.ir.dataflow.internal.ModelUtil +private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedInitialization private import DataFlowPrivate import SsaInternalsCommon @@ -102,12 +103,20 @@ predicate hasRawIndirectInstruction(Instruction instr, int indirectionIndex) { } cached -private newtype TDefOrUseImpl = +private newtype TDefImpl = TDefAddressImpl(BaseIRVariable v) or - TDefImpl(BaseSourceVariableInstruction base, Operand address, int indirectionIndex) { + TDirectDefImpl(BaseSourceVariableInstruction base, Operand address, int indirectionIndex) { isDef(_, _, address, base, _, indirectionIndex) } or - TUseImpl(BaseSourceVariableInstruction base, Operand operand, int indirectionIndex) { + TGlobalDefImpl(GlobalLikeVariable v, IRFunction f, int indirectionIndex) { + // Represents the initial "definition" of a global variable when entering + // a function body. + isGlobalDefImpl(v, f, _, indirectionIndex) + } + +cached +private newtype TUseImpl = + TDirectUseImpl(BaseSourceVariableInstruction base, Operand operand, int indirectionIndex) { isUse(_, operand, base, _, indirectionIndex) and not isDef(true, _, operand, _, _, _) } or @@ -116,21 +125,6 @@ private newtype TDefOrUseImpl = // the assignment to a global variable isn't ruled out as dead. isGlobalUse(v, f, _, indirectionIndex) } or - TGlobalDefImpl(GlobalLikeVariable v, IRFunction f, int indirectionIndex) { - // Represents the initial "definition" of a global variable when entering - // a function body. - isGlobalDefImpl(v, f, _, indirectionIndex) - } or - TIteratorDef( - Operand iteratorDerefAddress, BaseSourceVariableInstruction container, int indirectionIndex - ) { - isIteratorDef(container, iteratorDerefAddress, _, _, indirectionIndex) - } or - TIteratorUse( - Operand iteratorAddress, BaseSourceVariableInstruction container, int indirectionIndex - ) { - isIteratorUse(container, iteratorAddress, _, indirectionIndex) - } or TFinalParameterUse(Parameter p, int indirectionIndex) { underlyingTypeIsModifiableAt(p.getUnderlyingType(), indirectionIndex) and // Only create an SSA read for the final use of a parameter if there's @@ -177,7 +171,12 @@ private predicate underlyingTypeIsModifiableAt(Type underlying, int indirectionI private Indirection getIndirectionForUnspecifiedType(Type t) { result.getType() = t } -abstract private class DefOrUseImpl extends TDefOrUseImpl { +abstract class DefImpl extends TDefImpl { + int indirectionIndex; + + bindingset[indirectionIndex] + DefImpl() { any() } + /** Gets a textual representation of this element. */ abstract string toString(); @@ -199,6 +198,9 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl { /** Gets the location of this element. */ abstract Cpp::Location getLocation(); + /** Gets the indirection index of this definition. */ + final int getIndirectionIndex() { result = indirectionIndex } + /** * Gets the index (i.e., the number of loads required) of this * definition or use. @@ -207,7 +209,7 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl { * the enclosing basic block. To obtain this index, use * `DefOrUseImpl::hasIndexInBlock/2` or `DefOrUseImpl::hasIndexInBlock/3`. */ - abstract int getIndirectionIndex(); + abstract int getIndirection(); /** * Gets the instruction that computes the base of this definition or use. @@ -225,17 +227,89 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl { /** Gets the variable that is defined or used. */ SourceVariable getSourceVariable() { - exists(BaseSourceVariable v, int ind | - sourceVariableHasBaseAndIndex(result, v, ind) and - defOrUseHasSourceVariable(this, v, ind) + exists(BaseSourceVariable v, int indirection | + sourceVariableHasBaseAndIndex(result, v, indirection) and + defHasSourceVariable(this, v, indirection) ) } + + abstract predicate isCertain(); + + abstract Node0Impl getValue(); + + Operand getAddressOperand() { none() } } -private predicate defOrUseHasSourceVariable(DefOrUseImpl defOrUse, BaseSourceVariable bv, int ind) { - defHasSourceVariable(defOrUse, bv, ind) - or - useHasSourceVariable(defOrUse, bv, ind) +abstract class UseImpl extends TUseImpl { + int indirectionIndex; + + bindingset[indirectionIndex] + UseImpl() { any() } + + /** Gets the node associated with this use. */ + abstract Node getNode(); + + /** Gets a textual representation of this element. */ + abstract string toString(); + + /** Gets the block of this definition or use. */ + final IRBlock getBlock() { this.hasIndexInBlock(result, _) } + + /** Holds if this definition or use has index `index` in block `block`. */ + abstract predicate hasIndexInBlock(IRBlock block, int index); + + /** + * Holds if this definition (or use) has index `index` in block `block`, + * and is a definition (or use) of the variable `sv` + */ + final predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) { + this.hasIndexInBlock(block, index) and + sv = this.getSourceVariable() + } + + /** Gets the location of this element. */ + abstract Cpp::Location getLocation(); + + /** + * Gets the index (i.e., the number of loads required) of this + * definition or use. + * + * Note that this is _not_ the definition's (or use's) index in + * the enclosing basic block. To obtain this index, use + * `DefOrUseImpl::hasIndexInBlock/2` or `DefOrUseImpl::hasIndexInBlock/3`. + */ + abstract int getIndirection(); + + /** Gets the indirection index of this use. */ + final int getIndirectionIndex() { result = indirectionIndex } + + /** + * Gets the instruction that computes the base of this definition or use. + * This is always a `VariableAddressInstruction` or an `CallInstruction`. + */ + abstract BaseSourceVariableInstruction getBase(); + + /** + * Gets the base source variable (i.e., the variable without + * any indirection) of this definition or use. + */ + final BaseSourceVariable getBaseSourceVariable() { + this.getBase().getBaseSourceVariable() = result + } + + /** Gets the variable that is defined or used. */ + SourceVariable getSourceVariable() { + exists(BaseSourceVariable v, int indirection | + sourceVariableHasBaseAndIndex(result, v, indirection) and + useHasSourceVariable(this, v, indirection) + ) + } + + /** + * Holds if this use is guaranteed to read the + * associated variable. + */ + abstract predicate isCertain(); } pragma[noinline] @@ -256,21 +330,15 @@ private predicate sourceVariableHasBaseAndIndex(SourceVariable v, BaseSourceVari v.getIndirection() = ind } -abstract class DefImpl extends DefOrUseImpl { - int ind; - - bindingset[ind] - DefImpl() { any() } - - override int getIndirectionIndex() { result = ind } - - override string toString() { result = "Def of " + this.getSourceVariable() } - - abstract int getIndirection(); - - abstract predicate isCertain(); - - abstract Node0Impl getValue(); +/** + * Gets the instruction that computes the address that's used to + * initialize `v`. + */ +private Instruction getInitializationTargetAddress(IRVariable v) { + exists(TranslatedVariableInitialization init | + init.getIRVariable() = v and + result = init.getTargetAddress() + ) } /** An initial definition of an `IRVariable`'s address. */ @@ -279,9 +347,11 @@ private class DefAddressImpl extends DefImpl, TDefAddressImpl { DefAddressImpl() { this = TDefAddressImpl(v) and - ind = 0 + indirectionIndex = 0 } + override string toString() { result = "Def of &" + v.toString() } + final override int getIndirection() { result = 0 } final override predicate isCertain() { any() } @@ -289,8 +359,15 @@ private class DefAddressImpl extends DefImpl, TDefAddressImpl { final override Node0Impl getValue() { none() } final override predicate hasIndexInBlock(IRBlock block, int index) { - block = v.getIRVariable().getEnclosingIRFunction().getEntryBlock() and - index = 0 + exists(IRVariable var | var = v.getIRVariable() | + block.getInstruction(index) = getInitializationTargetAddress(var) + or + // If there is no translatated element that does initialization of the + // variable we place the SSA definition at the entry block of the function. + not exists(getInitializationTargetAddress(var)) and + block = var.getEnclosingIRFunction().getEntryBlock() and + index = 0 + ) } override Cpp::Location getLocation() { result = v.getIRVariable().getLocation() } @@ -303,91 +380,45 @@ private class DefAddressImpl extends DefImpl, TDefAddressImpl { final override BaseSourceVariableInstruction getBase() { none() } } -/** - * An SSA definition that has an associated `Operand` representing the address - * that is being written to. - */ -abstract private class OperandBasedDef extends DefImpl { +private class DirectDef extends DefImpl, TDirectDefImpl { Operand address; + BaseSourceVariableInstruction base; - bindingset[ind] - OperandBasedDef() { any() } - - Operand getAddressOperand() { result = address } + DirectDef() { this = TDirectDefImpl(base, address, indirectionIndex) } override Cpp::Location getLocation() { result = this.getAddressOperand().getUse().getLocation() } final override predicate hasIndexInBlock(IRBlock block, int index) { this.getAddressOperand().getUse() = block.getInstruction(index) } -} -private class DirectDef extends OperandBasedDef, TDefImpl { - BaseSourceVariableInstruction base; + override string toString() { result = "Def of " + this.getSourceVariable() } - DirectDef() { this = TDefImpl(base, address, ind) } + override Operand getAddressOperand() { result = address } override BaseSourceVariableInstruction getBase() { result = base } - override int getIndirection() { isDef(_, _, address, base, result, ind) } + override int getIndirection() { isDef(_, _, address, base, result, indirectionIndex) } override Node0Impl getValue() { isDef(_, result, address, base, _, _) } - override predicate isCertain() { isDef(true, _, address, base, _, ind) } + override predicate isCertain() { isDef(true, _, address, base, _, indirectionIndex) } } -private class IteratorDef extends OperandBasedDef, TIteratorDef { - BaseSourceVariableInstruction container; - - IteratorDef() { this = TIteratorDef(address, container, ind) } - - override BaseSourceVariableInstruction getBase() { result = container } - - override int getIndirection() { isIteratorDef(container, address, _, result, ind) } - - override Node0Impl getValue() { isIteratorDef(container, address, result, _, _) } - - override predicate isCertain() { none() } -} - -abstract class UseImpl extends DefOrUseImpl { - int ind; - - bindingset[ind] - UseImpl() { any() } - - /** Gets the node associated with this use. */ - abstract Node getNode(); - - override string toString() { result = "Use of " + this.getSourceVariable() } - - /** Gets the indirection index of this use. */ - final override int getIndirectionIndex() { result = ind } - - /** Gets the number of loads that precedence this use. */ - abstract int getIndirection(); - - /** - * Holds if this use is guaranteed to read the - * associated variable. - */ - abstract predicate isCertain(); -} - -abstract private class OperandBasedUse extends UseImpl { +private class DirectUseImpl extends UseImpl, TDirectUseImpl { Operand operand; BaseSourceVariableInstruction base; - bindingset[ind] - OperandBasedUse() { any() } + DirectUseImpl() { this = TDirectUseImpl(base, operand, indirectionIndex) } + + override string toString() { result = "Use of " + this.getSourceVariable() } final override predicate hasIndexInBlock(IRBlock block, int index) { // See the comment in `ssa0`'s `OperandBasedUse` for an explanation of this // predicate's implementation. if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand() then - exists(Operand op, int indirectionIndex, int indirection | - indirectionIndex = this.getIndirectionIndex() and + exists(Operand op, int indirection | indirection = this.getIndirection() and op = min(Operand cand, int i | @@ -406,26 +437,12 @@ abstract private class OperandBasedUse extends UseImpl { final Operand getOperand() { result = operand } final override Cpp::Location getLocation() { result = operand.getLocation() } -} -private class DirectUse extends OperandBasedUse, TUseImpl { - DirectUse() { this = TUseImpl(base, operand, ind) } + override int getIndirection() { isUse(_, operand, base, result, indirectionIndex) } - override int getIndirection() { isUse(_, operand, base, result, ind) } + override predicate isCertain() { isUse(true, operand, base, _, indirectionIndex) } - override predicate isCertain() { isUse(true, operand, base, _, ind) } - - override Node getNode() { nodeHasOperand(result, operand, ind) } -} - -private class IteratorUse extends OperandBasedUse, TIteratorUse { - IteratorUse() { this = TIteratorUse(operand, base, ind) } - - override int getIndirection() { isIteratorUse(base, operand, result, ind) } - - override predicate isCertain() { none() } - - override Node getNode() { nodeHasOperand(result, operand, ind) } + override Node getNode() { nodeHasOperand(result, operand, indirectionIndex) } } pragma[nomagic] @@ -439,15 +456,17 @@ private predicate finalParameterNodeHasParameterAndIndex( class FinalParameterUse extends UseImpl, TFinalParameterUse { Parameter p; - FinalParameterUse() { this = TFinalParameterUse(p, ind) } + FinalParameterUse() { this = TFinalParameterUse(p, indirectionIndex) } + + override string toString() { result = "Use of " + p.toString() } Parameter getParameter() { result = p } int getArgumentIndex() { result = p.getIndex() } - override Node getNode() { finalParameterNodeHasParameterAndIndex(result, p, ind) } + override Node getNode() { finalParameterNodeHasParameterAndIndex(result, p, indirectionIndex) } - override int getIndirection() { result = ind + 1 } + override int getIndirection() { result = indirectionIndex + 1 } override predicate isCertain() { any() } @@ -544,11 +563,13 @@ class GlobalUse extends UseImpl, TGlobalUse { GlobalLikeVariable global; IRFunction f; - GlobalUse() { this = TGlobalUse(global, f, ind) } + GlobalUse() { this = TGlobalUse(global, f, indirectionIndex) } + + override string toString() { result = "Use of " + global } override FinalGlobalValue getNode() { result.getGlobalUse() = this } - override int getIndirection() { isGlobalUse(global, f, result, ind) } + override int getIndirection() { isGlobalUse(global, f, result, indirectionIndex) } /** Gets the global variable associated with this use. */ GlobalLikeVariable getVariable() { result = global } @@ -598,10 +619,9 @@ class GlobalUse extends UseImpl, TGlobalUse { * * See the QLDoc for `GlobalUse` for how this is used. */ -class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl { +class GlobalDefImpl extends DefImpl, TGlobalDefImpl { GlobalLikeVariable global; IRFunction f; - int indirectionIndex; GlobalDefImpl() { this = TGlobalDefImpl(global, f, indirectionIndex) } @@ -611,9 +631,6 @@ class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl { /** Gets the `IRFunction` whose body is evaluated after this definition. */ IRFunction getIRFunction() { result = f } - /** Gets the global variable associated with this definition. */ - override int getIndirectionIndex() { result = indirectionIndex } - /** Holds if this definition or use has index `index` in block `block`. */ final override predicate hasIndexInBlock(IRBlock block, int index) { exists(EnterFunctionInstruction enter | @@ -627,7 +644,11 @@ class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl { sourceVariableIsGlobal(result, global, f, this.getIndirection()) } - int getIndirection() { result = indirectionIndex } + override int getIndirection() { result = indirectionIndex } + + override Node0Impl getValue() { none() } + + override predicate isCertain() { any() } /** * Gets the type of this definition after specifiers have been deeply @@ -648,60 +669,30 @@ class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl { } /** - * Holds if `defOrUse1` is a definition which is first read by `use`, - * or if `defOrUse1` is a use and `use` is a next subsequent use. - * - * In both cases, `use` can either be an explicit use written in the - * source file, or it can be a phi node as computed by the SSA library. + * Holds if there is a definition or access at index `i1` in basic block `bb1` + * and the next subsequent read is at index `i2` in basic block `bb2`. */ -predicate adjacentDefRead(DefOrUse defOrUse1, UseOrPhi use) { - exists(IRBlock bb1, int i1, SourceVariable v | - defOrUse1 - .asDefOrUse() - .hasIndexInBlock(pragma[only_bind_out](bb1), pragma[only_bind_out](i1), - pragma[only_bind_out](v)) - | - exists(IRBlock bb2, int i2, DefinitionExt def | - adjacentDefReadExt(pragma[only_bind_into](def), pragma[only_bind_into](bb1), - pragma[only_bind_into](i1), pragma[only_bind_into](bb2), pragma[only_bind_into](i2)) and - def.getSourceVariable() = v and - use.asDefOrUse().(UseImpl).hasIndexInBlock(bb2, i2, v) - ) - or - exists(PhiNode phi | - lastRefRedefExt(_, bb1, i1, phi) and - use.asPhi() = phi and - phi.getSourceVariable() = pragma[only_bind_into](v) - ) +predicate adjacentDefRead(IRBlock bb1, int i1, SourceVariable sv, IRBlock bb2, int i2) { + adjacentDefReadExt(_, sv, bb1, i1, bb2, i2) + or + exists(PhiNode phi | + lastRefRedefExt(_, sv, bb1, i1, phi) and + phi.definesAt(sv, bb2, i2, _) ) } -/** - * Holds if `globalDef` represents the initial definition of a global variable that - * flows to `useOrPhi`. - */ -private predicate globalDefToUse(GlobalDef globalDef, UseOrPhi useOrPhi) { - exists(IRBlock bb1, int i1, SourceVariable v | - globalDef - .hasIndexInBlock(pragma[only_bind_out](bb1), pragma[only_bind_out](i1), - pragma[only_bind_out](v)) - | - exists(IRBlock bb2, int i2 | - adjacentDefReadExt(_, pragma[only_bind_into](bb1), pragma[only_bind_into](i1), - pragma[only_bind_into](bb2), pragma[only_bind_into](i2)) and - useOrPhi.asDefOrUse().hasIndexInBlock(bb2, i2, v) - ) - or - exists(PhiNode phi | - lastRefRedefExt(_, bb1, i1, phi) and - useOrPhi.asPhi() = phi and - phi.getSourceVariable() = pragma[only_bind_into](v) - ) +predicate useToNode(IRBlock bb, int i, SourceVariable sv, Node nodeTo) { + exists(Phi phi | + phi.asPhi().definesAt(sv, bb, i, _) and + nodeTo = phi.getNode() + ) + or + exists(UseImpl use | + use.hasIndexInBlock(bb, i, sv) and + nodeTo = use.getNode() ) } -private predicate useToNode(UseOrPhi use, Node nodeTo) { use.getNode() = nodeTo } - pragma[noinline] predicate outNodeHasAddressAndIndex( IndirectArgumentOutNode out, Operand address, int indirectionIndex @@ -710,11 +701,19 @@ predicate outNodeHasAddressAndIndex( out.getIndirectionIndex() = indirectionIndex } -private predicate defToNode(Node nodeFrom, Def def, boolean uncertain) { +/** + * INTERNAL: Do not use. + * + * Holds if `node` is the node that corresponds to the definition of `def`. + */ +predicate defToNode(Node node, Def def, SourceVariable sv, IRBlock bb, int i, boolean uncertain) { + def.hasIndexInBlock(bb, i, sv) and ( - nodeHasOperand(nodeFrom, def.getValue().asOperand(), def.getIndirectionIndex()) + nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex()) or - nodeHasInstruction(nodeFrom, def.getValue().asInstruction(), def.getIndirectionIndex()) + nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex()) + or + node.(InitialGlobalValue).getGlobalDef() = def ) and if def.isCertain() then uncertain = false else uncertain = true } @@ -722,14 +721,16 @@ private predicate defToNode(Node nodeFrom, Def def, boolean uncertain) { /** * INTERNAL: Do not use. * - * Holds if `nodeFrom` is the node that correspond to the definition or use `defOrUse`. + * Holds if `node` is the node that corresponds to the definition or use at + * index `i` in block `bb` of `sv`. + * + * `uncertain` is `true` if this is an uncertain definition. */ -predicate nodeToDefOrUse(Node nodeFrom, SsaDefOrUse defOrUse, boolean uncertain) { - // Node -> Def - defToNode(nodeFrom, defOrUse, uncertain) +predicate nodeToDefOrUse(Node node, SourceVariable sv, IRBlock bb, int i, boolean uncertain) { + defToNode(node, _, sv, bb, i, uncertain) or // Node -> Use - useToNode(defOrUse, nodeFrom) and + useToNode(bb, i, sv, node) and uncertain = false } @@ -738,9 +739,9 @@ predicate nodeToDefOrUse(Node nodeFrom, SsaDefOrUse defOrUse, boolean uncertain) * only holds when there is no use-use relation out of `nTo`. */ private predicate indirectConversionFlowStep(Node nFrom, Node nTo) { - not exists(UseOrPhi defOrUse | - nodeToDefOrUse(nTo, defOrUse, _) and - adjacentDefRead(defOrUse, _) + not exists(SourceVariable sv, IRBlock bb2, int i2 | + nodeToDefOrUse(nTo, sv, bb2, i2, _) and + adjacentDefRead(bb2, i2, sv, _, _) ) and ( exists(Operand op1, Operand op2, int indirectionIndex, Instruction instr | @@ -774,60 +775,39 @@ private predicate indirectConversionFlowStep(Node nFrom, Node nTo) { * So this predicate recurses back along conversions and `PointerArithmeticInstruction`s to find the * first use that has provides use-use flow, and uses that target as the target of the `nodeFrom`. */ -private predicate adjustForPointerArith(PostUpdateNode pun, UseOrPhi use) { - exists(DefOrUse defOrUse, Node adjusted | +private predicate adjustForPointerArith(PostUpdateNode pun, SourceVariable sv, IRBlock bb2, int i2) { + exists(IRBlock bb1, int i1, Node adjusted | indirectConversionFlowStep*(adjusted, pun.getPreUpdateNode()) and - nodeToDefOrUse(adjusted, defOrUse, _) and - adjacentDefRead(defOrUse, use) + nodeToDefOrUse(adjusted, sv, bb1, i1, _) and + adjacentDefRead(bb1, i1, sv, bb2, i2) ) } /** - * Holds if `nodeFrom` flows to `nodeTo` because there is `def-use` or - * `use-use` flow from `defOrUse` to `use`. + * Holds if there should be flow from `nodeFrom` to `nodeTo` because + * `nodeFrom` is a definition or use of `sv` at index `i1` at basic + * block `bb1`. * - * `uncertain` is `true` if the `defOrUse` is an uncertain definition. + * `uncertain` is `true` if `(bb1, i1)` is a definition, and that definition + * is _not_ guaranteed to overwrite the entire allocation. */ -private predicate localSsaFlow( - SsaDefOrUse defOrUse, Node nodeFrom, UseOrPhi use, Node nodeTo, boolean uncertain +private predicate ssaFlowImpl( + IRBlock bb1, int i1, SourceVariable sv, Node nodeFrom, Node nodeTo, boolean uncertain ) { - nodeToDefOrUse(nodeFrom, defOrUse, uncertain) and - adjacentDefRead(defOrUse, use) and - useToNode(use, nodeTo) and + exists(IRBlock bb2, int i2 | + nodeToDefOrUse(nodeFrom, sv, bb1, i1, uncertain) and + adjacentDefRead(bb1, i1, sv, bb2, i2) and + useToNode(bb2, i2, sv, nodeTo) + ) and nodeFrom != nodeTo } -private predicate ssaFlowImpl(SsaDefOrUse defOrUse, Node nodeFrom, Node nodeTo, boolean uncertain) { - exists(UseOrPhi use | - localSsaFlow(defOrUse, nodeFrom, use, nodeTo, uncertain) - or - // Initial global variable value to a first use - nodeFrom.(InitialGlobalValue).getGlobalDef() = defOrUse and - globalDefToUse(defOrUse, use) and - useToNode(use, nodeTo) and - uncertain = false - ) -} - -/** - * Holds if `def` is the corresponding definition of - * the SSA library's `definition`. - */ -private DefinitionExt ssaDefinition(Def def) { - exists(IRBlock block, int i, SourceVariable sv | - def.hasIndexInBlock(block, i, sv) and - result.definesAt(sv, block, i, _) - ) -} - /** Gets a node that represents the prior definition of `node`. */ -private Node getAPriorDefinition(SsaDefOrUse defOrUse) { - exists(IRBlock bb, int i, SourceVariable sv, DefinitionExt def, DefOrUse defOrUse0 | - lastRefRedefExt(pragma[only_bind_into](def), pragma[only_bind_into](bb), - pragma[only_bind_into](i), ssaDefinition(defOrUse)) and - def.getSourceVariable() = sv and - defOrUse0.hasIndexInBlock(bb, i, sv) and - nodeToDefOrUse(result, defOrUse0, _) +private Node getAPriorDefinition(DefinitionExt next) { + exists(IRBlock bb, int i, SourceVariable sv | + lastRefRedefExt(_, pragma[only_bind_into](sv), pragma[only_bind_into](bb), + pragma[only_bind_into](i), next) and + nodeToDefOrUse(result, sv, bb, i, _) ) } @@ -879,12 +859,16 @@ private predicate modeledFlowBarrier(Node n) { /** Holds if there is def-use or use-use flow from `nodeFrom` to `nodeTo`. */ predicate ssaFlow(Node nodeFrom, Node nodeTo) { - exists(Node nFrom, boolean uncertain, SsaDefOrUse defOrUse | - ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and + exists(Node nFrom, boolean uncertain, IRBlock bb, int i, SourceVariable sv | + ssaFlowImpl(bb, i, sv, nFrom, nodeTo, uncertain) and not modeledFlowBarrier(nFrom) and nodeFrom != nodeTo | - if uncertain = true then nodeFrom = [nFrom, getAPriorDefinition(defOrUse)] else nodeFrom = nFrom + if uncertain = true + then + nodeFrom = + [nFrom, getAPriorDefinition(any(DefinitionExt next | next.definesAt(sv, bb, i, _)))] + else nodeFrom = nFrom ) } @@ -929,15 +913,15 @@ private predicate isArgumentOfCallable(DataFlowCall call, Node n) { * Holds if there is use-use flow from `pun`'s pre-update node to `n`. */ private predicate postUpdateNodeToFirstUse(PostUpdateNode pun, Node n) { - exists(UseOrPhi use | - adjustForPointerArith(pun, use) and - useToNode(use, n) + exists(SourceVariable sv, IRBlock bb2, int i2 | + adjustForPointerArith(pun, sv, bb2, i2) and + useToNode(bb2, i2, sv, n) ) } private predicate stepUntilNotInCall(DataFlowCall call, Node n1, Node n2) { isArgumentOfCallable(call, n1) and - exists(Node mid | localSsaFlow(_, n1, _, mid, _) | + exists(Node mid | ssaFlowImpl(_, _, _, n1, mid, _) | isArgumentOfCallable(call, mid) and stepUntilNotInCall(call, mid, n2) or @@ -984,35 +968,13 @@ predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) { ) } -/** - * Holds if `use` is a use of `sv` and is a next adjacent use of `phi` in - * index `i1` in basic block `bb1`. - * - * This predicate exists to prevent an early join of `adjacentDefRead` with `definesAt`. - */ -pragma[nomagic] -private predicate fromPhiNodeToUse(PhiNode phi, SourceVariable sv, IRBlock bb1, int i1, UseOrPhi use) { - exists(IRBlock bb2, int i2 | - use.asDefOrUse().hasIndexInBlock(bb2, i2, sv) and - adjacentDefReadExt(pragma[only_bind_into](phi), pragma[only_bind_into](bb1), - pragma[only_bind_into](i1), pragma[only_bind_into](bb2), pragma[only_bind_into](i2)) - ) -} - /** Holds if `nodeTo` receives flow from the phi node `nodeFrom`. */ predicate fromPhiNode(SsaPhiNode nodeFrom, Node nodeTo) { - exists(PhiNode phi, SourceVariable sv, IRBlock bb1, int i1, UseOrPhi use | + exists(PhiNode phi, SourceVariable sv, IRBlock bb1, int i1, IRBlock bb2, int i2 | phi = nodeFrom.getPhiNode() and phi.definesAt(sv, bb1, i1, _) and - useToNode(use, nodeTo) - | - fromPhiNodeToUse(phi, sv, bb1, i1, use) - or - exists(PhiNode phiTo | - phi != phiTo and - lastRefRedefExt(phi, bb1, i1, phiTo) and - nodeTo.(SsaPhiNode).getPhiNode() = phiTo - ) + adjacentDefRead(bb1, i1, sv, bb2, i2) and + useToNode(bb2, i2, sv, nodeTo) ) } @@ -1077,8 +1039,10 @@ module SsaCached { * path between them without any read of `def`. */ cached - predicate adjacentDefReadExt(DefinitionExt def, IRBlock bb1, int i1, IRBlock bb2, int i2) { - SsaImpl::adjacentDefReadExt(def, _, bb1, i1, bb2, i2) + predicate adjacentDefReadExt( + DefinitionExt def, SourceVariable sv, IRBlock bb1, int i1, IRBlock bb2, int i2 + ) { + SsaImpl::adjacentDefReadExt(def, sv, bb1, i1, bb2, i2) } /** @@ -1087,32 +1051,38 @@ module SsaCached { * without passing through another read or write. */ cached - predicate lastRefRedefExt(DefinitionExt def, IRBlock bb, int i, DefinitionExt next) { - SsaImpl::lastRefRedefExt(def, _, bb, i, next) + predicate lastRefRedefExt( + DefinitionExt def, SourceVariable sv, IRBlock bb, int i, DefinitionExt next + ) { + SsaImpl::lastRefRedefExt(def, sv, bb, i, next) } + + cached + Definition phiHasInputFromBlock(PhiNode phi, IRBlock bb) { + SsaImpl::phiHasInputFromBlock(phi, result, bb) + } + + cached + predicate ssaDefReachesRead(SourceVariable v, Definition def, IRBlock bb, int i) { + SsaImpl::ssaDefReachesRead(v, def, bb, i) + } + + predicate variableRead = SsaInput::variableRead/4; + + predicate variableWrite = SsaInput::variableWrite/4; } cached -private newtype TSsaDefOrUse = - TDefOrUse(DefOrUseImpl defOrUse) { - defOrUse instanceof UseImpl - or - // Like in the pruning stage, we only include definition that's live after the - // write as the final definitions computed by SSA. - exists(DefinitionExt def, SourceVariable sv, IRBlock bb, int i | - def.definesAt(sv, bb, i, _) and - defOrUse.(DefImpl).hasIndexInBlock(bb, i, sv) - ) - } or - TPhi(PhiNode phi) or - TGlobalDef(GlobalDefImpl global) +private newtype TSsaDef = + TDef(DefinitionExt def) or + TPhi(PhiNode phi) -abstract private class SsaDefOrUse extends TSsaDefOrUse { +abstract private class SsaDef extends TSsaDef { /** Gets a textual representation of this element. */ string toString() { none() } /** Gets the underlying non-phi definition or use. */ - DefOrUseImpl asDefOrUse() { none() } + DefinitionExt asDef() { none() } /** Gets the underlying phi node. */ PhiNode asPhi() { none() } @@ -1121,52 +1091,97 @@ abstract private class SsaDefOrUse extends TSsaDefOrUse { abstract Location getLocation(); } -class DefOrUse extends TDefOrUse, SsaDefOrUse { - DefOrUseImpl defOrUse; - - DefOrUse() { this = TDefOrUse(defOrUse) } +abstract class Def extends SsaDef, TDef { + DefinitionExt def; - final override DefOrUseImpl asDefOrUse() { result = defOrUse } + Def() { this = TDef(def) } - final override Location getLocation() { result = defOrUse.getLocation() } + final override DefinitionExt asDef() { result = def } - final SourceVariable getSourceVariable() { result = defOrUse.getSourceVariable() } + /** Gets the source variable underlying this SSA definition. */ + final SourceVariable getSourceVariable() { result = def.getSourceVariable() } - override string toString() { result = defOrUse.toString() } + override string toString() { result = def.toString() } /** * Holds if this definition (or use) has index `index` in block `block`, * and is a definition (or use) of the variable `sv`. */ predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) { - defOrUse.hasIndexInBlock(block, index, sv) + def.definesAt(sv, block, index, _) } -} -class GlobalDef extends TGlobalDef, SsaDefOrUse { - GlobalDefImpl global; + /** Gets the value written by this definition, if any. */ + Node0Impl getValue() { none() } - GlobalDef() { this = TGlobalDef(global) } + /** + * Holds if this definition is guaranteed to overwrite the entire + * destination's allocation. + */ + abstract predicate isCertain(); - /** Gets the location of this definition. */ - final override Location getLocation() { result = global.getLocation() } + /** Gets the address operand written to by this definition. */ + Operand getAddressOperand() { none() } - /** Gets a textual representation of this definition. */ - override string toString() { result = global.toString() } + /** Gets the address written to by this definition. */ + final Instruction getAddress() { result = this.getAddressOperand().getDef() } + + /** Gets the indirection index of this definition. */ + abstract int getIndirectionIndex(); /** - * Holds if this definition has index `index` in block `block`, and - * is a definition of the variable `sv`. + * Gets the indirection level that this definition is writing to. + * For instance, `x = y` is a definition of `x` at indirection level 1 and + * `*x = y` is a definition of `x` at indirection level 2. */ - predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) { - global.hasIndexInBlock(block, index, sv) + abstract int getIndirection(); + + /** + * Gets a definition that ultimately defines this SSA definition and is not + * itself a phi node. + */ + Def getAnUltimateDefinition() { result.asDef() = def.getAnUltimateDefinition() } +} + +private predicate isGlobal(DefinitionExt def, GlobalDefImpl global) { + exists(SourceVariable sv, IRBlock bb, int i | + def.definesAt(sv, bb, i, _) and + global.hasIndexInBlock(bb, i, sv) + ) +} + +private class NonGlobalDef extends Def { + NonGlobalDef() { not isGlobal(def, _) } + + final override Location getLocation() { result = this.getImpl().getLocation() } + + private DefImpl getImpl() { + exists(SourceVariable sv, IRBlock bb, int i | + this.hasIndexInBlock(bb, i, sv) and + result.hasIndexInBlock(bb, i, sv) + ) } - /** Gets the indirection index of this definition. */ - int getIndirection() { result = global.getIndirection() } + override Node0Impl getValue() { result = this.getImpl().getValue() } - /** Gets the indirection index of this definition. */ - int getIndirectionIndex() { result = global.getIndirectionIndex() } + override predicate isCertain() { this.getImpl().isCertain() } + + override Operand getAddressOperand() { result = this.getImpl().getAddressOperand() } + + override int getIndirectionIndex() { result = this.getImpl().getIndirectionIndex() } + + override int getIndirection() { result = this.getImpl().getIndirection() } +} + +class GlobalDef extends Def { + GlobalDefImpl global; + + GlobalDef() { isGlobal(def, global) } + + /** Gets a textual representation of this definition. */ + override string toString() { result = global.toString() } + + final override Location getLocation() { result = global.getLocation() } /** * Gets the type of this definition after specifiers have been deeply stripped @@ -1184,9 +1199,15 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse { /** Gets the global variable associated with this definition. */ GlobalLikeVariable getVariable() { result = global.getVariable() } + + override predicate isCertain() { any() } + + final override int getIndirectionIndex() { result = global.getIndirectionIndex() } + + final override int getIndirection() { result = global.getIndirection() } } -class Phi extends TPhi, SsaDefOrUse { +class Phi extends TPhi, SsaDef { PhiNode phi; Phi() { this = TPhi(phi) } @@ -1198,64 +1219,19 @@ class Phi extends TPhi, SsaDefOrUse { override string toString() { result = "Phi" } SsaPhiNode getNode() { result.getPhiNode() = phi } -} -class UseOrPhi extends SsaDefOrUse { - UseOrPhi() { - this.asDefOrUse() instanceof UseImpl - or - this instanceof Phi - } - - final override Location getLocation() { - result = this.asDefOrUse().getLocation() or result = this.(Phi).getLocation() - } + predicate hasInputFromBlock(Definition inp, IRBlock bb) { inp = phiHasInputFromBlock(phi, bb) } - final Node getNode() { - result = this.(Phi).getNode() - or - result = this.asDefOrUse().(UseImpl).getNode() - } -} - -class Def extends DefOrUse { - override DefImpl defOrUse; - - Operand getAddressOperand() { result = defOrUse.(OperandBasedDef).getAddressOperand() } - - Instruction getAddress() { result = this.getAddressOperand().getDef() } - - /** - * Gets the indirection index of this definition. - * - * This predicate ensures that joins go from `defOrUse` to the result - * instead of the other way around. - */ - pragma[inline] - int getIndirectionIndex() { - pragma[only_bind_into](result) = pragma[only_bind_out](defOrUse).getIndirectionIndex() - } - - /** - * Gets the indirection level that this definition is writing to. - * For instance, `x = y` is a definition of `x` at indirection level 1 and - * `*x = y` is a definition of `x` at indirection level 2. - * - * This predicate ensures that joins go from `defOrUse` to the result - * instead of the other way around. - */ - pragma[inline] - int getIndirection() { - pragma[only_bind_into](result) = pragma[only_bind_out](defOrUse).getIndirection() - } - - Node0Impl getValue() { result = defOrUse.getValue() } - - predicate isCertain() { defOrUse.isCertain() } + final Definition getAnInput() { this.hasInputFromBlock(result, _) } } private module SsaImpl = SsaImplCommon::Make; +/** + * An static single assignment (SSA) phi node. + * + * This is either a normal phi node or a phi-read node. + */ class PhiNode extends SsaImpl::DefinitionExt { PhiNode() { this instanceof SsaImpl::PhiNode or @@ -1269,10 +1245,30 @@ class PhiNode extends SsaImpl::DefinitionExt { * on reads instead of writes. */ predicate isPhiRead() { this instanceof SsaImpl::PhiReadNode } + + /** Holds if `inp` is an input to this phi node along the edge originating in `bb`. */ + predicate hasInputFromBlock(Definition inp, IRBlock bb) { + inp = SsaCached::phiHasInputFromBlock(this, bb) + } + + /** Gets a definition that is an input to this phi node. */ + final Definition getAnInput() { this.hasInputFromBlock(result, _) } } -class DefinitionExt = SsaImpl::DefinitionExt; +/** An static single assignment (SSA) definition. */ +class DefinitionExt extends SsaImpl::DefinitionExt { + private Definition getAPhiInputOrPriorDefinition() { result = this.(PhiNode).getAnInput() } + + /** + * Gets a definition that ultimately defines this SSA definition and is + * not itself a phi node. + */ + final DefinitionExt getAnUltimateDefinition() { + result = this.getAPhiInputOrPriorDefinition*() and + not result instanceof PhiNode + } +} -class UncertainWriteDefinition = SsaImpl::UncertainWriteDefinition; +class Definition = SsaImpl::Definition; import SsaCached diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll index 7e5b4de8122c..0920e5a38657 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll @@ -246,14 +246,6 @@ private module IteratorIndirections { baseType = super.getValueType() } - override predicate isAdditionalDereference(Instruction deref, Operand address) { - exists(CallInstruction call | - operandForFullyConvertedCall(getAUse(deref), call) and - this = call.getStaticCallTarget().getClassAndName("operator*") and - address = call.getThisArgumentOperand() - ) - } - override predicate isAdditionalWrite(Node0Impl value, Operand address, boolean certain) { exists(CallInstruction call | call.getArgumentOperand(0) = value.asOperand() | this = call.getStaticCallTarget().getClassAndName("operator=") and @@ -262,16 +254,6 @@ private module IteratorIndirections { ) } - override predicate isAdditionalTaintStep(Node node1, Node node2) { - exists(CallInstruction call | - // Taint through `operator+=` and `operator-=` on iterators. - call.getStaticCallTarget() instanceof Iterator::IteratorAssignArithmeticOperator and - node2.(IndirectArgumentOutNode).getPreUpdateNode() = node1 and - node1.(IndirectOperand).hasOperandAndIndirectionIndex(call.getArgumentOperand(0), _) and - node1.getType().getUnspecifiedType() = this - ) - } - override predicate isAdditionalConversionFlow(Operand opFrom, Instruction instrTo) { // This is a bit annoying: Consider the following snippet: // ``` @@ -589,230 +571,6 @@ private class BaseCallInstruction extends BaseSourceVariableInstruction, CallIns cached private module Cached { - private import semmle.code.cpp.models.interfaces.Iterator as Interfaces - private import semmle.code.cpp.models.implementations.Iterator as Iterator - private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs as IO - - /** - * Holds if `next` is a instruction with a memory result that potentially - * updates the memory produced by `prev`. - */ - private predicate memorySucc(Instruction prev, Instruction next) { - prev = next.(ChiInstruction).getTotal() - or - // Phi inputs can be inexact. - prev = next.(PhiInstruction).getAnInputOperand().getAnyDef() - or - prev = next.(CopyInstruction).getSourceValue() - or - exists(ReadSideEffectInstruction read | - next = read.getPrimaryInstruction() and - isAdditionalConversionFlow(_, next) and - prev = read.getSideEffectOperand().getAnyDef() - ) - } - - /** - * Holds if `iteratorDerefAddress` is an address of an iterator dereference (i.e., `*it`) - * that is used for a write operation that writes the value `value`. The `memory` instruction - * represents the memory that the IR's SSA analysis determined was read by the call to `operator*`. - * - * The `numberOfLoads` integer represents the number of dereferences this write corresponds to - * on the underlying container that produced the iterator. - */ - private predicate isChiAfterIteratorDef( - Instruction memory, Operand iteratorDerefAddress, Node0Impl value, int numberOfLoads - ) { - exists( - BaseSourceVariableInstruction iteratorBase, ReadSideEffectInstruction read, - Operand iteratorAddress - | - numberOfLoads >= 0 and - isDef(_, value, iteratorDerefAddress, iteratorBase, numberOfLoads + 2, 0) and - isUse(_, iteratorAddress, iteratorBase, numberOfLoads + 1, 0) and - iteratorBase.getResultType() instanceof Interfaces::Iterator and - isDereference(iteratorAddress.getDef(), read.getArgumentDef().getAUse(), _) and - memory = read.getSideEffectOperand().getAnyDef() - ) - } - - private predicate isSource(Instruction instr, Operand iteratorAddress, int numberOfLoads) { - getAUse(instr) = iteratorAddress and - exists(BaseSourceVariableInstruction iteratorBase | - iteratorBase.getResultType() instanceof Interfaces::Iterator and - not iteratorBase.getResultType() instanceof Cpp::PointerType and - isUse(_, iteratorAddress, iteratorBase, numberOfLoads - 1, 0) - ) - } - - private predicate isSink(Instruction instr, CallInstruction call) { - getAUse(instr).(ArgumentOperand).getCall() = call and - // Only include operations that may modify the object that the iterator points to. - // The following is a non-exhaustive list of things that may modify the value of the - // iterator, but never the value of what the iterator points to. - // The more things we can exclude here, the faster the small dataflow-like analysis - // done by `convertsIntoArgument` will converge. - not exists(Function f | f = call.getStaticCallTarget() | - f instanceof Iterator::IteratorCrementOperator or - f instanceof Iterator::IteratorBinaryArithmeticOperator or - f instanceof Iterator::IteratorAssignArithmeticOperator or - f instanceof Iterator::IteratorCrementMemberOperator or - f instanceof Iterator::IteratorBinaryArithmeticMemberOperator or - f instanceof Iterator::IteratorAssignArithmeticMemberOperator or - f instanceof Iterator::IteratorAssignmentMemberOperator - ) - } - - private predicate convertsIntoArgumentFwd(Instruction instr) { - isSource(instr, _, _) - or - exists(Instruction prev | convertsIntoArgumentFwd(prev) | - conversionFlow(unique( | | getAUse(prev)), instr, false, _) - ) - } - - private predicate convertsIntoArgumentRev(Instruction instr) { - convertsIntoArgumentFwd(instr) and - ( - isSink(instr, _) - or - exists(Instruction next | convertsIntoArgumentRev(next) | - conversionFlow(unique( | | getAUse(instr)), next, false, _) - ) - ) - } - - private predicate convertsIntoArgument( - Operand iteratorAddress, CallInstruction call, int numberOfLoads - ) { - exists(Instruction iteratorAddressDef | - isSource(iteratorAddressDef, iteratorAddress, numberOfLoads) and - isSink(iteratorAddressDef, call) and - convertsIntoArgumentRev(pragma[only_bind_into](iteratorAddressDef)) - ) - } - - private predicate isChiAfterIteratorArgument( - Instruction memory, Operand iteratorAddress, int numberOfLoads - ) { - // Ideally, `iteratorAddress` would be an `ArgumentOperand`, but there might be - // various conversions applied to it before it becomes an argument. - // So we do a small amount of flow to find the call that the iterator is passed to. - exists(CallInstruction call | convertsIntoArgument(iteratorAddress, call, numberOfLoads) | - exists(ReadSideEffectInstruction read | - read.getPrimaryInstruction() = call and - read.getSideEffectOperand().getAnyDef() = memory - ) - or - exists(LoadInstruction load | - iteratorAddress.getDef() = load and - memory = load.getSourceValueOperand().getAnyDef() - ) - ) - } - - /** - * Holds if `iterator` is a `StoreInstruction` that stores the result of some function - * returning an iterator into an address computed started at `containerBase`. - * - * For example, given a declaration like `std::vector::iterator it = v.begin()`, - * the `iterator` will be the `StoreInstruction` generated by the write to `it`, and - * `containerBase` will be the address of `v`. - */ - private predicate isChiAfterBegin( - BaseSourceVariableInstruction containerBase, StoreInstruction iterator - ) { - exists( - CallInstruction getIterator, Iterator::GetIteratorFunction getIteratorFunction, - IO::FunctionInput input, int i - | - getIterator = iterator.getSourceValue() and - getIteratorFunction = getIterator.getStaticCallTarget() and - getIteratorFunction.getsIterator(input, _) and - isDef(_, any(Node0Impl n | n.asInstruction() = iterator), _, _, 1, 0) and - input.isParameterDerefOrQualifierObject(i) and - isUse(_, getIterator.getArgumentOperand(i), containerBase, 0, 0) - ) - } - - /** - * Holds if `iteratorAddress` is an address of an iterator that is used for - * a read operation. The `memory` instruction represents the memory that - * the IR's SSA analysis determined was read by the call to `operator*`. - * - * Finally, the `numberOfLoads` integer represents the number of dereferences - * this read corresponds to on the underlying container that produced the iterator. - */ - private predicate isChiBeforeIteratorUse( - Operand iteratorAddress, Instruction memory, int numberOfLoads - ) { - exists( - BaseSourceVariableInstruction iteratorBase, LoadInstruction load, - ReadSideEffectInstruction read, Operand iteratorDerefAddress - | - numberOfLoads >= 0 and - isUse(_, iteratorAddress, iteratorBase, numberOfLoads + 1, 0) and - isUse(_, iteratorDerefAddress, iteratorBase, numberOfLoads + 2, 0) and - iteratorBase.getResultType() instanceof Interfaces::Iterator and - load.getSourceAddressOperand() = iteratorDerefAddress and - read.getPrimaryInstruction() = load.getSourceAddress() and - memory = read.getSideEffectOperand().getAnyDef() - ) - } - - /** - * Holds if `iteratorDerefAddress` is an address of an iterator dereference (i.e., `*it`) - * that is used for a write operation that writes the value `value` to a container that - * created the iterator. `container` represents the base of the address of the container - * that was used to create the iterator. - */ - cached - predicate isIteratorDef( - BaseSourceVariableInstruction container, Operand iteratorDerefAddress, Node0Impl value, - int numberOfLoads, int indirectionIndex - ) { - exists(Instruction memory, Instruction begin, int upper, int ind | - isChiAfterIteratorDef(memory, iteratorDerefAddress, value, numberOfLoads) and - memorySucc*(begin, memory) and - isChiAfterBegin(container, begin) and - upper = countIndirectionsForCppType(getResultLanguageType(container)) and - ind = numberOfLoads + [1 .. upper] and - indirectionIndex = ind - (numberOfLoads + 1) - ) - } - - /** - * Holds if `iteratorAddress` is an address of an iterator that is used for a - * read operation to read a value from a container that created the iterator. - * `container` represents the base of the address of the container that was used - * to create the iterator. - */ - cached - predicate isIteratorUse( - BaseSourceVariableInstruction container, Operand iteratorAddress, int numberOfLoads, - int indirectionIndex - ) { - // Direct use - exists(Instruction begin, Instruction memory, int upper, int ind | - isChiBeforeIteratorUse(iteratorAddress, memory, numberOfLoads) and - memorySucc*(begin, memory) and - isChiAfterBegin(container, begin) and - upper = countIndirectionsForCppType(getResultLanguageType(container)) and - ind = numberOfLoads + [1 .. upper] and - indirectionIndex = ind - (numberOfLoads + 1) - ) - or - // Use through function output - exists(Instruction memory, Instruction begin, int upper, int ind | - isChiAfterIteratorArgument(memory, iteratorAddress, numberOfLoads) and - memorySucc*(begin, memory) and - isChiAfterBegin(container, begin) and - upper = countIndirectionsForCppType(getResultLanguageType(container)) and - ind = numberOfLoads + [1 .. upper] and - indirectionIndex = ind - (numberOfLoads - 1) - ) - } - /** Holds if `op` is the only use of its defining instruction, and that op is used in a conversation */ private predicate isConversion(Operand op) { exists(Instruction def, Operand use | diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll index b31c7898ba72..24135820ab8b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll @@ -17,18 +17,11 @@ private import Imports::IRType * The variable may be a user-declared variable (`IRUserVariable`) or a temporary variable generated * by the AST-to-IR translation (`IRTempVariable`). */ -class IRVariable extends TIRVariable { +abstract private class AbstractIRVariable extends TIRVariable { Language::Declaration func; - IRVariable() { - this = TIRUserVariable(_, _, func) or - this = TIRTempVariable(func, _, _, _) or - this = TIRStringLiteral(func, _, _, _) or - this = TIRDynamicInitializationFlag(func, _, _) - } - /** Gets a textual representation of this element. */ - string toString() { none() } + abstract string toString(); /** * Holds if this variable's value cannot be changed within a function. Currently used for string @@ -49,13 +42,13 @@ class IRVariable extends TIRVariable { /** * Gets the type of the variable. */ - Language::LanguageType getLanguageType() { none() } + abstract Language::LanguageType getLanguageType(); /** * Gets the AST node that declared this variable, or that introduced this * variable as part of the AST-to-IR translation. */ - Language::AST getAst() { none() } + abstract Language::AST getAst(); /** DEPRECATED: Alias for getAst */ deprecated Language::AST getAST() { result = this.getAst() } @@ -64,7 +57,7 @@ class IRVariable extends TIRVariable { * Gets an identifier string for the variable. This identifier is unique * within the function. */ - string getUniqueId() { none() } + abstract string getUniqueId(); /** * Gets the source location of this variable. @@ -74,7 +67,7 @@ class IRVariable extends TIRVariable { /** * Gets the IR for the function that references this variable. */ - final IRFunction getEnclosingIRFunction() { result.getFunction() = func } + final IRFunction getEnclosingIRFunction() { result.getFunction() = this.getEnclosingFunction() } /** * Gets the function that references this variable. @@ -82,10 +75,18 @@ class IRVariable extends TIRVariable { final Language::Declaration getEnclosingFunction() { result = func } } +/** + * A variable referenced by the IR for a function. + * + * The variable may be a user-declared variable (`IRUserVariable`) or a temporary variable generated + * by the AST-to-IR translation (`IRTempVariable`). + */ +final class IRVariable = AbstractIRVariable; + /** * A user-declared variable referenced by the IR for a function. */ -class IRUserVariable extends IRVariable, TIRUserVariable { +class IRUserVariable extends AbstractIRVariable, TIRUserVariable { Language::Variable var; Language::LanguageType type; @@ -114,27 +115,30 @@ class IRUserVariable extends IRVariable, TIRUserVariable { * A variable (user-declared or temporary) that is allocated on the stack. This includes all * parameters, non-static local variables, and temporary variables. */ -class IRAutomaticVariable extends IRVariable { - IRAutomaticVariable() { - exists(Language::Variable var | - this = TIRUserVariable(var, _, func) and - Language::isVariableAutomatic(var) - ) - or - this = TIRTempVariable(func, _, _, _) - } -} +abstract private class AbstractIRAutomaticVariable extends AbstractIRVariable { } + +/** + * A variable (user-declared or temporary) that is allocated on the stack. This includes all + * parameters, non-static local variables, and temporary variables. + */ +final class IRAutomaticVariable = AbstractIRAutomaticVariable; /** * A user-declared variable that is allocated on the stack. This includes all parameters and * non-static local variables. */ -class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { +private class AbstractIRAutomaticUserVariable extends IRUserVariable, AbstractIRAutomaticVariable { override Language::AutomaticVariable var; final override Language::AutomaticVariable getVariable() { result = var } } +/** + * A user-declared variable that is allocated on the stack. This includes all parameters and + * non-static local variables. + */ +final class IRAutomaticUserVariable = AbstractIRAutomaticUserVariable; + /** * A user-declared variable that is not allocated on the stack. This includes all global variables, * namespace-scope variables, static fields, and static local variables. @@ -151,16 +155,10 @@ class IRStaticUserVariable extends IRUserVariable { * A variable that is not user-declared. This includes temporary variables generated as part of IR * construction, as well as string literals. */ -class IRGeneratedVariable extends IRVariable { +abstract private class AbstractIRGeneratedVariable extends AbstractIRVariable { Language::AST ast; Language::LanguageType type; - IRGeneratedVariable() { - this = TIRTempVariable(func, ast, _, type) or - this = TIRStringLiteral(func, ast, type, _) or - this = TIRDynamicInitializationFlag(func, ast, type) - } - final override Language::LanguageType getLanguageType() { result = type } final override Language::AST getAst() { result = ast } @@ -196,12 +194,20 @@ class IRGeneratedVariable extends IRVariable { string getBaseString() { none() } } +/** + * A variable that is not user-declared. This includes temporary variables generated as part of IR + * construction, as well as string literals. + */ +final class IRGeneratedVariable = AbstractIRGeneratedVariable; + /** * A temporary variable introduced by IR construction. The most common examples are the variable * generated to hold the return value of a function, or the variable generated to hold the result of * a condition operator (`a ? b : c`). */ -class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { +class IRTempVariable extends AbstractIRGeneratedVariable, AbstractIRAutomaticVariable, + TIRTempVariable +{ TempVariableTag tag; IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) } @@ -241,7 +247,7 @@ class IRThrowVariable extends IRTempVariable { * A temporary variable generated to hold the contents of all arguments passed to the `...` of a * function that accepts a variable number of arguments. */ -class IREllipsisVariable extends IRTempVariable, IRParameter { +class IREllipsisVariable extends IRTempVariable, AbstractIRParameter { IREllipsisVariable() { tag = EllipsisTempVar() } final override string toString() { result = "#ellipsis" } @@ -252,7 +258,7 @@ class IREllipsisVariable extends IRTempVariable, IRParameter { /** * A temporary variable generated to hold the `this` pointer. */ -class IRThisVariable extends IRTempVariable, IRParameter { +class IRThisVariable extends IRTempVariable, AbstractIRParameter { IRThisVariable() { tag = ThisTempVar() } final override string toString() { result = "#this" } @@ -264,7 +270,7 @@ class IRThisVariable extends IRTempVariable, IRParameter { * A variable generated to represent the contents of a string literal. This variable acts much like * a read-only global variable. */ -class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { +class IRStringLiteral extends AbstractIRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; IRStringLiteral() { this = TIRStringLiteral(func, ast, type, literal) } @@ -288,7 +294,7 @@ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { * used to model the runtime initialization of static local variables in C++, as well as static * fields in C#. */ -class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitializationFlag { +class IRDynamicInitializationFlag extends AbstractIRGeneratedVariable, TIRDynamicInitializationFlag { Language::Variable var; IRDynamicInitializationFlag() { @@ -314,24 +320,24 @@ class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitial * An IR variable which acts like a function parameter, including positional parameters and the * temporary variables generated for `this` and ellipsis parameters. */ -class IRParameter extends IRAutomaticVariable { - IRParameter() { - this.(IRAutomaticUserVariable).getVariable() instanceof Language::Parameter - or - this = TIRTempVariable(_, _, ThisTempVar(), _) - or - this = TIRTempVariable(_, _, EllipsisTempVar(), _) - } - +abstract private class AbstractIRParameter extends AbstractIRAutomaticVariable { /** * Gets the zero-based index of this parameter. The `this` parameter has index -1. */ int getIndex() { none() } } +/** + * An IR variable which acts like a function parameter, including positional parameters and the + * temporary variables generated for `this` and ellipsis parameters. + */ +final class IRParameter = AbstractIRParameter; + /** * An IR variable representing a positional parameter. */ -class IRPositionalParameter extends IRParameter, IRAutomaticUserVariable { +class IRPositionalParameter extends AbstractIRParameter, AbstractIRAutomaticUserVariable { + IRPositionalParameter() { this.getVariable() instanceof Language::Parameter } + final override int getIndex() { result = this.getVariable().(Language::Parameter).getIndex() } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index 189ffce2903e..c7e40da1e17c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -247,8 +247,7 @@ class Instruction extends Construction::TStageInstruction { * Gets the type of the result produced by this instruction. If the instruction does not produce * a result, its result type will be `IRVoidType`. */ - cached - final IRType getResultIRType() { result = this.getResultLanguageType().getIRType() } + final IRType getResultIRType() { result = Construction::getInstructionResultIRType(this) } /** * Gets the type of the result produced by this instruction. If the @@ -995,9 +994,8 @@ class ConstantInstruction extends ConstantValueInstruction { */ class IntegerConstantInstruction extends ConstantInstruction { IntegerConstantInstruction() { - exists(IRType resultType | - resultType = this.getResultIRType() and - (resultType instanceof IRIntegerType or resultType instanceof IRBooleanType) + exists(IRType resultType | resultType = this.getResultIRType() | + resultType instanceof IRIntegerType or resultType instanceof IRBooleanType ) } } @@ -1009,6 +1007,17 @@ class FloatConstantInstruction extends ConstantInstruction { FloatConstantInstruction() { this.getResultIRType() instanceof IRFloatingPointType } } +/** + * An instruction whose result is a constant value of a pointer type. + */ +class PointerConstantInstruction extends ConstantInstruction { + PointerConstantInstruction() { + exists(IRType resultType | resultType = this.getResultIRType() | + resultType instanceof IRAddressType or resultType instanceof IRFunctionAddressType + ) + } +} + /** * An instruction whose result is the address of a string literal. */ diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll index 209c42726b7d..d2e68c733041 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll @@ -429,6 +429,11 @@ private module Cached { instr = unreachedInstruction(_) and result = Language::getVoidType() } + cached + IRType getInstructionResultIRType(Instruction instr) { + result = instr.getResultLanguageType().getIRType() + } + /** * Holds if `opcode` is the opcode that specifies the operation performed by `instr`. * diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRVariable.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRVariable.qll index b31c7898ba72..24135820ab8b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRVariable.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRVariable.qll @@ -17,18 +17,11 @@ private import Imports::IRType * The variable may be a user-declared variable (`IRUserVariable`) or a temporary variable generated * by the AST-to-IR translation (`IRTempVariable`). */ -class IRVariable extends TIRVariable { +abstract private class AbstractIRVariable extends TIRVariable { Language::Declaration func; - IRVariable() { - this = TIRUserVariable(_, _, func) or - this = TIRTempVariable(func, _, _, _) or - this = TIRStringLiteral(func, _, _, _) or - this = TIRDynamicInitializationFlag(func, _, _) - } - /** Gets a textual representation of this element. */ - string toString() { none() } + abstract string toString(); /** * Holds if this variable's value cannot be changed within a function. Currently used for string @@ -49,13 +42,13 @@ class IRVariable extends TIRVariable { /** * Gets the type of the variable. */ - Language::LanguageType getLanguageType() { none() } + abstract Language::LanguageType getLanguageType(); /** * Gets the AST node that declared this variable, or that introduced this * variable as part of the AST-to-IR translation. */ - Language::AST getAst() { none() } + abstract Language::AST getAst(); /** DEPRECATED: Alias for getAst */ deprecated Language::AST getAST() { result = this.getAst() } @@ -64,7 +57,7 @@ class IRVariable extends TIRVariable { * Gets an identifier string for the variable. This identifier is unique * within the function. */ - string getUniqueId() { none() } + abstract string getUniqueId(); /** * Gets the source location of this variable. @@ -74,7 +67,7 @@ class IRVariable extends TIRVariable { /** * Gets the IR for the function that references this variable. */ - final IRFunction getEnclosingIRFunction() { result.getFunction() = func } + final IRFunction getEnclosingIRFunction() { result.getFunction() = this.getEnclosingFunction() } /** * Gets the function that references this variable. @@ -82,10 +75,18 @@ class IRVariable extends TIRVariable { final Language::Declaration getEnclosingFunction() { result = func } } +/** + * A variable referenced by the IR for a function. + * + * The variable may be a user-declared variable (`IRUserVariable`) or a temporary variable generated + * by the AST-to-IR translation (`IRTempVariable`). + */ +final class IRVariable = AbstractIRVariable; + /** * A user-declared variable referenced by the IR for a function. */ -class IRUserVariable extends IRVariable, TIRUserVariable { +class IRUserVariable extends AbstractIRVariable, TIRUserVariable { Language::Variable var; Language::LanguageType type; @@ -114,27 +115,30 @@ class IRUserVariable extends IRVariable, TIRUserVariable { * A variable (user-declared or temporary) that is allocated on the stack. This includes all * parameters, non-static local variables, and temporary variables. */ -class IRAutomaticVariable extends IRVariable { - IRAutomaticVariable() { - exists(Language::Variable var | - this = TIRUserVariable(var, _, func) and - Language::isVariableAutomatic(var) - ) - or - this = TIRTempVariable(func, _, _, _) - } -} +abstract private class AbstractIRAutomaticVariable extends AbstractIRVariable { } + +/** + * A variable (user-declared or temporary) that is allocated on the stack. This includes all + * parameters, non-static local variables, and temporary variables. + */ +final class IRAutomaticVariable = AbstractIRAutomaticVariable; /** * A user-declared variable that is allocated on the stack. This includes all parameters and * non-static local variables. */ -class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { +private class AbstractIRAutomaticUserVariable extends IRUserVariable, AbstractIRAutomaticVariable { override Language::AutomaticVariable var; final override Language::AutomaticVariable getVariable() { result = var } } +/** + * A user-declared variable that is allocated on the stack. This includes all parameters and + * non-static local variables. + */ +final class IRAutomaticUserVariable = AbstractIRAutomaticUserVariable; + /** * A user-declared variable that is not allocated on the stack. This includes all global variables, * namespace-scope variables, static fields, and static local variables. @@ -151,16 +155,10 @@ class IRStaticUserVariable extends IRUserVariable { * A variable that is not user-declared. This includes temporary variables generated as part of IR * construction, as well as string literals. */ -class IRGeneratedVariable extends IRVariable { +abstract private class AbstractIRGeneratedVariable extends AbstractIRVariable { Language::AST ast; Language::LanguageType type; - IRGeneratedVariable() { - this = TIRTempVariable(func, ast, _, type) or - this = TIRStringLiteral(func, ast, type, _) or - this = TIRDynamicInitializationFlag(func, ast, type) - } - final override Language::LanguageType getLanguageType() { result = type } final override Language::AST getAst() { result = ast } @@ -196,12 +194,20 @@ class IRGeneratedVariable extends IRVariable { string getBaseString() { none() } } +/** + * A variable that is not user-declared. This includes temporary variables generated as part of IR + * construction, as well as string literals. + */ +final class IRGeneratedVariable = AbstractIRGeneratedVariable; + /** * A temporary variable introduced by IR construction. The most common examples are the variable * generated to hold the return value of a function, or the variable generated to hold the result of * a condition operator (`a ? b : c`). */ -class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { +class IRTempVariable extends AbstractIRGeneratedVariable, AbstractIRAutomaticVariable, + TIRTempVariable +{ TempVariableTag tag; IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) } @@ -241,7 +247,7 @@ class IRThrowVariable extends IRTempVariable { * A temporary variable generated to hold the contents of all arguments passed to the `...` of a * function that accepts a variable number of arguments. */ -class IREllipsisVariable extends IRTempVariable, IRParameter { +class IREllipsisVariable extends IRTempVariable, AbstractIRParameter { IREllipsisVariable() { tag = EllipsisTempVar() } final override string toString() { result = "#ellipsis" } @@ -252,7 +258,7 @@ class IREllipsisVariable extends IRTempVariable, IRParameter { /** * A temporary variable generated to hold the `this` pointer. */ -class IRThisVariable extends IRTempVariable, IRParameter { +class IRThisVariable extends IRTempVariable, AbstractIRParameter { IRThisVariable() { tag = ThisTempVar() } final override string toString() { result = "#this" } @@ -264,7 +270,7 @@ class IRThisVariable extends IRTempVariable, IRParameter { * A variable generated to represent the contents of a string literal. This variable acts much like * a read-only global variable. */ -class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { +class IRStringLiteral extends AbstractIRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; IRStringLiteral() { this = TIRStringLiteral(func, ast, type, literal) } @@ -288,7 +294,7 @@ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { * used to model the runtime initialization of static local variables in C++, as well as static * fields in C#. */ -class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitializationFlag { +class IRDynamicInitializationFlag extends AbstractIRGeneratedVariable, TIRDynamicInitializationFlag { Language::Variable var; IRDynamicInitializationFlag() { @@ -314,24 +320,24 @@ class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitial * An IR variable which acts like a function parameter, including positional parameters and the * temporary variables generated for `this` and ellipsis parameters. */ -class IRParameter extends IRAutomaticVariable { - IRParameter() { - this.(IRAutomaticUserVariable).getVariable() instanceof Language::Parameter - or - this = TIRTempVariable(_, _, ThisTempVar(), _) - or - this = TIRTempVariable(_, _, EllipsisTempVar(), _) - } - +abstract private class AbstractIRParameter extends AbstractIRAutomaticVariable { /** * Gets the zero-based index of this parameter. The `this` parameter has index -1. */ int getIndex() { none() } } +/** + * An IR variable which acts like a function parameter, including positional parameters and the + * temporary variables generated for `this` and ellipsis parameters. + */ +final class IRParameter = AbstractIRParameter; + /** * An IR variable representing a positional parameter. */ -class IRPositionalParameter extends IRParameter, IRAutomaticUserVariable { +class IRPositionalParameter extends AbstractIRParameter, AbstractIRAutomaticUserVariable { + IRPositionalParameter() { this.getVariable() instanceof Language::Parameter } + final override int getIndex() { result = this.getVariable().(Language::Parameter).getIndex() } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll index 189ffce2903e..c7e40da1e17c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -247,8 +247,7 @@ class Instruction extends Construction::TStageInstruction { * Gets the type of the result produced by this instruction. If the instruction does not produce * a result, its result type will be `IRVoidType`. */ - cached - final IRType getResultIRType() { result = this.getResultLanguageType().getIRType() } + final IRType getResultIRType() { result = Construction::getInstructionResultIRType(this) } /** * Gets the type of the result produced by this instruction. If the @@ -995,9 +994,8 @@ class ConstantInstruction extends ConstantValueInstruction { */ class IntegerConstantInstruction extends ConstantInstruction { IntegerConstantInstruction() { - exists(IRType resultType | - resultType = this.getResultIRType() and - (resultType instanceof IRIntegerType or resultType instanceof IRBooleanType) + exists(IRType resultType | resultType = this.getResultIRType() | + resultType instanceof IRIntegerType or resultType instanceof IRBooleanType ) } } @@ -1009,6 +1007,17 @@ class FloatConstantInstruction extends ConstantInstruction { FloatConstantInstruction() { this.getResultIRType() instanceof IRFloatingPointType } } +/** + * An instruction whose result is a constant value of a pointer type. + */ +class PointerConstantInstruction extends ConstantInstruction { + PointerConstantInstruction() { + exists(IRType resultType | resultType = this.getResultIRType() | + resultType instanceof IRAddressType or resultType instanceof IRFunctionAddressType + ) + } +} + /** * An instruction whose result is the address of a string literal. */ diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll index 96a01954d17f..7bea8178d141 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll @@ -377,6 +377,10 @@ CppType getInstructionResultType(TStageInstruction instr) { result = getVoidType() } +IRType getInstructionResultIRType(Instruction instr) { + result = instr.getResultLanguageType().getIRType() +} + predicate getInstructionOpcode(Opcode opcode, TStageInstruction instr) { getInstructionTranslatedElement(instr).hasInstruction(opcode, getInstructionTag(instr), _) or diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index 3f4039ebb346..a43595b08e08 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -538,6 +538,11 @@ class TranslatedResultCopy extends TranslatedExpr, TTranslatedResultCopy { final override predicate producesExprResult() { any() } private TranslatedCoreExpr getOperand() { result.getExpr() = expr } + + override predicate handlesDestructorsExplicitly() { + // The destructor calls will already have been generated by the translation of `expr`. + any() + } } class TranslatedCommaExpr extends TranslatedNonConstantExpr { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll index fab2dacc8a78..3f77a2b0b45e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll @@ -1163,6 +1163,8 @@ class TranslatedForStmt extends TranslatedLoop { class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext { override RangeBasedForStmt stmt; + override predicate handlesDestructorsExplicitly() { any() } + override TranslatedElement getChildInternal(int id) { id = 0 and result = this.getInitialization() or @@ -1216,6 +1218,19 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext { or child = this.getUpdate() and result = this.getCondition().getFirstInstruction(kind) + or + exists(int destructorId | + destructorId >= this.getFirstDestructorCallIndex() and + child = this.getChild(destructorId) and + result = this.getChild(destructorId + 1).getFirstInstruction(kind) + ) + or + exists(int lastDestructorIndex | + lastDestructorIndex = + max(int n | exists(this.getChild(n)) and n >= this.getFirstDestructorCallIndex()) and + child = this.getChild(lastDestructorIndex) and + result = this.getParent().getChildSuccessor(this, kind) + ) } override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { @@ -1231,7 +1246,9 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext { override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) { child = this.getCondition() and - result = this.getParent().getChildSuccessor(this, kind) + if this.hasAnImplicitDestructorCall() + then result = this.getChild(this.getFirstDestructorCallIndex()).getFirstInstruction(kind) + else result = this.getParent().getChildSuccessor(this, kind) } private TranslatedDeclStmt getRangeVariableDeclStmt() { @@ -1276,6 +1293,11 @@ class TranslatedJumpStmt extends TranslatedStmt { override JumpStmt stmt; override Instruction getFirstInstruction(EdgeKind kind) { + // The first instruction is a destructor call, if any. + result = this.getChildInternal(0).getFirstInstruction(kind) + or + // Otherwise, the first (and only) instruction is a `NoOp` + not exists(this.getChildInternal(0)) and result = this.getInstruction(OnlyInstructionTag()) and kind instanceof GotoEdge } @@ -1284,7 +1306,20 @@ class TranslatedJumpStmt extends TranslatedStmt { result = this.getInstruction(OnlyInstructionTag()) } - override TranslatedElement getChildInternal(int id) { none() } + private TranslatedCall getTranslatedImplicitDestructorCall(int id) { + result.getExpr() = stmt.getImplicitDestructorCall(id) + } + + override TranslatedElement getLastChild() { + result = + this.getTranslatedImplicitDestructorCall(max(int id | + exists(stmt.getImplicitDestructorCall(id)) + )) + } + + override TranslatedElement getChildInternal(int id) { + result = this.getTranslatedImplicitDestructorCall(id) + } override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { tag = OnlyInstructionTag() and @@ -1297,7 +1332,19 @@ class TranslatedJumpStmt extends TranslatedStmt { result = getTranslatedStmt(stmt.getTarget()).getFirstInstruction(kind) } - override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() } + final override predicate handlesDestructorsExplicitly() { any() } + + override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { + exists(int id | child = this.getChildInternal(id) | + // Transition to the next destructor call, if any. + result = this.getChildInternal(id + 1).getFirstInstruction(kind) + or + // And otherwise, exit this element by flowing to the target of the jump. + not exists(this.getChildInternal(id + 1)) and + kind instanceof GotoEdge and + result = this.getInstruction(OnlyInstructionTag()) + ) + } } private EdgeKind getCaseEdge(SwitchCase switchCase) { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll index b31c7898ba72..24135820ab8b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll @@ -17,18 +17,11 @@ private import Imports::IRType * The variable may be a user-declared variable (`IRUserVariable`) or a temporary variable generated * by the AST-to-IR translation (`IRTempVariable`). */ -class IRVariable extends TIRVariable { +abstract private class AbstractIRVariable extends TIRVariable { Language::Declaration func; - IRVariable() { - this = TIRUserVariable(_, _, func) or - this = TIRTempVariable(func, _, _, _) or - this = TIRStringLiteral(func, _, _, _) or - this = TIRDynamicInitializationFlag(func, _, _) - } - /** Gets a textual representation of this element. */ - string toString() { none() } + abstract string toString(); /** * Holds if this variable's value cannot be changed within a function. Currently used for string @@ -49,13 +42,13 @@ class IRVariable extends TIRVariable { /** * Gets the type of the variable. */ - Language::LanguageType getLanguageType() { none() } + abstract Language::LanguageType getLanguageType(); /** * Gets the AST node that declared this variable, or that introduced this * variable as part of the AST-to-IR translation. */ - Language::AST getAst() { none() } + abstract Language::AST getAst(); /** DEPRECATED: Alias for getAst */ deprecated Language::AST getAST() { result = this.getAst() } @@ -64,7 +57,7 @@ class IRVariable extends TIRVariable { * Gets an identifier string for the variable. This identifier is unique * within the function. */ - string getUniqueId() { none() } + abstract string getUniqueId(); /** * Gets the source location of this variable. @@ -74,7 +67,7 @@ class IRVariable extends TIRVariable { /** * Gets the IR for the function that references this variable. */ - final IRFunction getEnclosingIRFunction() { result.getFunction() = func } + final IRFunction getEnclosingIRFunction() { result.getFunction() = this.getEnclosingFunction() } /** * Gets the function that references this variable. @@ -82,10 +75,18 @@ class IRVariable extends TIRVariable { final Language::Declaration getEnclosingFunction() { result = func } } +/** + * A variable referenced by the IR for a function. + * + * The variable may be a user-declared variable (`IRUserVariable`) or a temporary variable generated + * by the AST-to-IR translation (`IRTempVariable`). + */ +final class IRVariable = AbstractIRVariable; + /** * A user-declared variable referenced by the IR for a function. */ -class IRUserVariable extends IRVariable, TIRUserVariable { +class IRUserVariable extends AbstractIRVariable, TIRUserVariable { Language::Variable var; Language::LanguageType type; @@ -114,27 +115,30 @@ class IRUserVariable extends IRVariable, TIRUserVariable { * A variable (user-declared or temporary) that is allocated on the stack. This includes all * parameters, non-static local variables, and temporary variables. */ -class IRAutomaticVariable extends IRVariable { - IRAutomaticVariable() { - exists(Language::Variable var | - this = TIRUserVariable(var, _, func) and - Language::isVariableAutomatic(var) - ) - or - this = TIRTempVariable(func, _, _, _) - } -} +abstract private class AbstractIRAutomaticVariable extends AbstractIRVariable { } + +/** + * A variable (user-declared or temporary) that is allocated on the stack. This includes all + * parameters, non-static local variables, and temporary variables. + */ +final class IRAutomaticVariable = AbstractIRAutomaticVariable; /** * A user-declared variable that is allocated on the stack. This includes all parameters and * non-static local variables. */ -class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { +private class AbstractIRAutomaticUserVariable extends IRUserVariable, AbstractIRAutomaticVariable { override Language::AutomaticVariable var; final override Language::AutomaticVariable getVariable() { result = var } } +/** + * A user-declared variable that is allocated on the stack. This includes all parameters and + * non-static local variables. + */ +final class IRAutomaticUserVariable = AbstractIRAutomaticUserVariable; + /** * A user-declared variable that is not allocated on the stack. This includes all global variables, * namespace-scope variables, static fields, and static local variables. @@ -151,16 +155,10 @@ class IRStaticUserVariable extends IRUserVariable { * A variable that is not user-declared. This includes temporary variables generated as part of IR * construction, as well as string literals. */ -class IRGeneratedVariable extends IRVariable { +abstract private class AbstractIRGeneratedVariable extends AbstractIRVariable { Language::AST ast; Language::LanguageType type; - IRGeneratedVariable() { - this = TIRTempVariable(func, ast, _, type) or - this = TIRStringLiteral(func, ast, type, _) or - this = TIRDynamicInitializationFlag(func, ast, type) - } - final override Language::LanguageType getLanguageType() { result = type } final override Language::AST getAst() { result = ast } @@ -196,12 +194,20 @@ class IRGeneratedVariable extends IRVariable { string getBaseString() { none() } } +/** + * A variable that is not user-declared. This includes temporary variables generated as part of IR + * construction, as well as string literals. + */ +final class IRGeneratedVariable = AbstractIRGeneratedVariable; + /** * A temporary variable introduced by IR construction. The most common examples are the variable * generated to hold the return value of a function, or the variable generated to hold the result of * a condition operator (`a ? b : c`). */ -class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { +class IRTempVariable extends AbstractIRGeneratedVariable, AbstractIRAutomaticVariable, + TIRTempVariable +{ TempVariableTag tag; IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) } @@ -241,7 +247,7 @@ class IRThrowVariable extends IRTempVariable { * A temporary variable generated to hold the contents of all arguments passed to the `...` of a * function that accepts a variable number of arguments. */ -class IREllipsisVariable extends IRTempVariable, IRParameter { +class IREllipsisVariable extends IRTempVariable, AbstractIRParameter { IREllipsisVariable() { tag = EllipsisTempVar() } final override string toString() { result = "#ellipsis" } @@ -252,7 +258,7 @@ class IREllipsisVariable extends IRTempVariable, IRParameter { /** * A temporary variable generated to hold the `this` pointer. */ -class IRThisVariable extends IRTempVariable, IRParameter { +class IRThisVariable extends IRTempVariable, AbstractIRParameter { IRThisVariable() { tag = ThisTempVar() } final override string toString() { result = "#this" } @@ -264,7 +270,7 @@ class IRThisVariable extends IRTempVariable, IRParameter { * A variable generated to represent the contents of a string literal. This variable acts much like * a read-only global variable. */ -class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { +class IRStringLiteral extends AbstractIRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; IRStringLiteral() { this = TIRStringLiteral(func, ast, type, literal) } @@ -288,7 +294,7 @@ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { * used to model the runtime initialization of static local variables in C++, as well as static * fields in C#. */ -class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitializationFlag { +class IRDynamicInitializationFlag extends AbstractIRGeneratedVariable, TIRDynamicInitializationFlag { Language::Variable var; IRDynamicInitializationFlag() { @@ -314,24 +320,24 @@ class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitial * An IR variable which acts like a function parameter, including positional parameters and the * temporary variables generated for `this` and ellipsis parameters. */ -class IRParameter extends IRAutomaticVariable { - IRParameter() { - this.(IRAutomaticUserVariable).getVariable() instanceof Language::Parameter - or - this = TIRTempVariable(_, _, ThisTempVar(), _) - or - this = TIRTempVariable(_, _, EllipsisTempVar(), _) - } - +abstract private class AbstractIRParameter extends AbstractIRAutomaticVariable { /** * Gets the zero-based index of this parameter. The `this` parameter has index -1. */ int getIndex() { none() } } +/** + * An IR variable which acts like a function parameter, including positional parameters and the + * temporary variables generated for `this` and ellipsis parameters. + */ +final class IRParameter = AbstractIRParameter; + /** * An IR variable representing a positional parameter. */ -class IRPositionalParameter extends IRParameter, IRAutomaticUserVariable { +class IRPositionalParameter extends AbstractIRParameter, AbstractIRAutomaticUserVariable { + IRPositionalParameter() { this.getVariable() instanceof Language::Parameter } + final override int getIndex() { result = this.getVariable().(Language::Parameter).getIndex() } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index 189ffce2903e..c7e40da1e17c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -247,8 +247,7 @@ class Instruction extends Construction::TStageInstruction { * Gets the type of the result produced by this instruction. If the instruction does not produce * a result, its result type will be `IRVoidType`. */ - cached - final IRType getResultIRType() { result = this.getResultLanguageType().getIRType() } + final IRType getResultIRType() { result = Construction::getInstructionResultIRType(this) } /** * Gets the type of the result produced by this instruction. If the @@ -995,9 +994,8 @@ class ConstantInstruction extends ConstantValueInstruction { */ class IntegerConstantInstruction extends ConstantInstruction { IntegerConstantInstruction() { - exists(IRType resultType | - resultType = this.getResultIRType() and - (resultType instanceof IRIntegerType or resultType instanceof IRBooleanType) + exists(IRType resultType | resultType = this.getResultIRType() | + resultType instanceof IRIntegerType or resultType instanceof IRBooleanType ) } } @@ -1009,6 +1007,17 @@ class FloatConstantInstruction extends ConstantInstruction { FloatConstantInstruction() { this.getResultIRType() instanceof IRFloatingPointType } } +/** + * An instruction whose result is a constant value of a pointer type. + */ +class PointerConstantInstruction extends ConstantInstruction { + PointerConstantInstruction() { + exists(IRType resultType | resultType = this.getResultIRType() | + resultType instanceof IRAddressType or resultType instanceof IRFunctionAddressType + ) + } +} + /** * An instruction whose result is the address of a string literal. */ diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index 209c42726b7d..d2e68c733041 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -429,6 +429,11 @@ private module Cached { instr = unreachedInstruction(_) and result = Language::getVoidType() } + cached + IRType getInstructionResultIRType(Instruction instr) { + result = instr.getResultLanguageType().getIRType() + } + /** * Holds if `opcode` is the opcode that specifies the operation performed by `instr`. * diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll index 8e527c7e6947..a016210de5a0 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll @@ -560,7 +560,7 @@ private class IteratorAssignmentMemberOperatorModel extends IteratorAssignmentMe TaintFunction, SideEffectFunction, AliasFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isParameterDeref(0) and + (input.isParameterDeref(0) or input.isParameter(0)) and output.isQualifierObject() } @@ -579,17 +579,34 @@ private class IteratorAssignmentMemberOperatorModel extends IteratorAssignmentMe override predicate parameterEscapesOnlyViaReturn(int index) { index = -1 } } +/** + * A `begin` member function, or a related function, that returns an iterator. + */ +class BeginFunction extends MemberFunction { + BeginFunction() { + this.hasName(["begin", "cbegin", "rbegin", "crbegin", "before_begin", "cbefore_begin"]) and + this.getType().getUnspecifiedType() instanceof Iterator + } +} + +/** + * An `end` member function, or a related function, that returns an iterator. + */ +class EndFunction extends MemberFunction { + EndFunction() { + this.hasName(["end", "cend", "rend", "crend"]) and + this.getType().getUnspecifiedType() instanceof Iterator + } +} + /** * A `begin` or `end` member function, or a related member function, that * returns an iterator. */ class BeginOrEndFunction extends MemberFunction { BeginOrEndFunction() { - this.hasName([ - "begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend", "before_begin", - "cbefore_begin" - ]) and - this.getType().getUnspecifiedType() instanceof Iterator + this instanceof BeginFunction or + this instanceof EndFunction } } diff --git a/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll b/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll deleted file mode 100644 index 8f43e19c7b55..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll +++ /dev/null @@ -1,616 +0,0 @@ -/** - * DEPRECATED: This library has been replaced with a newer version which - * provides better performance and precision. Use - * `semmle.code.cpp.valuenumbering.GlobalValueNumbering` instead. - * - * Provides an implementation of Global Value Numbering. - * See https://en.wikipedia.org/wiki/Global_value_numbering - * - * The predicate `globalValueNumber` converts an expression into a `GVN`, - * which is an abstract type representing the value of the expression. If - * two expressions have the same `GVN` then they compute the same value. - * For example: - * - * ``` - * void f(int x, int y) { - * g(x+y, x+y); - * } - * ``` - * - * In this example, both arguments in the call to `g` compute the same value, - * so both arguments have the same `GVN`. In other words, we can find - * this call with the following query: - * - * ``` - * from FunctionCall call, GVN v - * where v = globalValueNumber(call.getArgument(0)) - * and v = globalValueNumber(call.getArgument(1)) - * select call - * ``` - * - * The analysis is conservative, so two expressions might have different - * `GVN`s even though the actually always compute the same value. The most - * common reason for this is that the analysis cannot prove that there - * are no side-effects that might cause the computed value to change. - */ - -/* - * Note to developers: the correctness of this module depends on the - * definitions of GVN, globalValueNumber, and analyzableExpr being kept in - * sync with each other. If you change this module then make sure that the - * change is symmetric across all three. - */ - -import cpp -private import semmle.code.cpp.controlflow.SSA - -/** - * Holds if the result is a control flow node that might change the - * value of any global variable. This is used in the implementation - * of `GVN_OtherVariable`, because we need to be quite conservative when - * we assign a value number to a global variable. For example: - * - * ``` - * x = g+1; - * dosomething(); - * y = g+1; - * ``` - * - * It is not safe to assign the same value number to both instances - * of `g+1` in this example, because the call to `dosomething` might - * change the value of `g`. - */ -private ControlFlowNode nodeWithPossibleSideEffect() { - result instanceof Call - or - // If the lhs of an assignment is not analyzable by SSA, then - // we need to treat the assignment as having a possible side-effect. - result instanceof Assignment and not result instanceof SsaDefinition - or - result instanceof CrementOperation and not result instanceof SsaDefinition - or - exists(LocalVariable v | - result = v.getInitializer().getExpr() and not result instanceof SsaDefinition - ) - or - result instanceof AsmStmt -} - -/** - * Gets the entry node of the control flow graph of which `node` is a - * member. - */ -cached -private ControlFlowNode getControlFlowEntry(ControlFlowNode node) { - result = node.getControlFlowScope().getEntryPoint() and - result.getASuccessor*() = node -} - -/** - * Holds if there is a control flow edge from `src` to `dst` or - * if `dst` is an expression with a possible side-effect. The idea - * is to treat side effects as entry points in the control flow - * graph so that we can use the dominator tree to find the most recent - * side-effect. - */ -private predicate sideEffectCfg(ControlFlowNode src, ControlFlowNode dst) { - src.getASuccessor() = dst - or - // Add an edge from the entry point to any node that might have a side - // effect. - dst = nodeWithPossibleSideEffect() and - src = getControlFlowEntry(dst) -} - -/** - * Holds if `dominator` is the immediate dominator of `node` in - * the side-effect CFG. - */ -private predicate iDomEffect(ControlFlowNode dominator, ControlFlowNode node) = - idominance(functionEntry/1, sideEffectCfg/2)(_, dominator, node) - -/** - * Gets the most recent side effect. To be more precise, `result` is a - * dominator of `node` and no side-effects can occur between `result` and - * `node`. - * - * `sideEffectCFG` has an edge from the function entry to every node with a - * side-effect. This means that every node with a side-effect has the - * function entry as its immediate dominator. So if node `x` dominates node - * `y` then there can be no side effects between `x` and `y` unless `x` is - * the function entry. So the optimal choice for `result` has the function - * entry as its immediate dominator. - * - * Example: - * - * ``` - * 000: int f(int a, int b, int *p) { - * 001: int r = 0; - * 002: if (a) { - * 003: if (b) { - * 004: sideEffect1(); - * 005: } - * 006: } else { - * 007: sideEffect2(); - * 008: } - * 009: if (a) { - * 010: r++; // Not a side-effect, because r is an SSA variable. - * 011: } - * 012: if (b) { - * 013: r++; // Not a side-effect, because r is an SSA variable. - * 014: } - * 015: return *p; - * 016: } - * ``` - * - * Suppose we want to find the most recent side-effect for the dereference - * of `p` on line 015. The `sideEffectCFG` has an edge from the function - * entry (line 000) to the side effects at lines 004 and 007. Therefore, - * the immediate dominator tree looks like this: - * - * 000 - 001 - 002 - 003 - * - 004 - * - 007 - * - 009 - 010 - * - 012 - 013 - * - 015 - * - * The immediate dominator path to line 015 is 000 - 009 - 012 - 015. - * Therefore, the most recent side effect for line 015 is line 009. - */ -cached -private ControlFlowNode mostRecentSideEffect(ControlFlowNode node) { - exists(ControlFlowNode entry | - functionEntry(entry) and - iDomEffect(entry, result) and - iDomEffect*(result, node) - ) -} - -/** Used to represent the "global value number" of an expression. */ -cached -private newtype GvnBase = - GVN_IntConst(int val, Type t) { mk_IntConst(val, t, _) } or - GVN_FloatConst(float val, Type t) { mk_FloatConst(val, t, _) } or - // If the local variable does not have a defining value, then - // we use the SsaDefinition as its global value number. - GVN_UndefinedStackVariable(StackVariable x, SsaDefinition def) { - mk_UndefinedStackVariable(x, def, _) - } or - // Variables with no SSA information. As a crude (but safe) - // approximation, we use `mostRecentSideEffect` to compute a definition - // location for the variable. This ensures that two instances of the same - // global variable will only get the same value number if they are - // guaranteed to have the same value. - GVN_OtherVariable(Variable x, ControlFlowNode dominator) { mk_OtherVariable(x, dominator, _) } or - deprecated GVN_FieldAccess(GVN s, Field f) { - mk_DotFieldAccess(s, f, _) or - mk_PointerFieldAccess_with_deref(s, f, _) or - mk_ImplicitThisFieldAccess_with_deref(s, f, _) - } or - // Dereference a pointer. The value might have changed since the last - // time the pointer was dereferenced, so we need to include a definition - // location. As a crude (but safe) approximation, we use - // `mostRecentSideEffect` to compute a definition location. - deprecated GVN_Deref(GVN p, ControlFlowNode dominator) { - mk_Deref(p, dominator, _) or - mk_PointerFieldAccess(p, _, dominator, _) or - mk_ImplicitThisFieldAccess_with_qualifier(p, _, dominator, _) - } or - GVN_ThisExpr(Function fcn) { - mk_ThisExpr(fcn, _) or - mk_ImplicitThisFieldAccess(fcn, _, _, _) - } or - deprecated GVN_Conversion(Type t, GVN child) { mk_Conversion(t, child, _) } or - deprecated GVN_BinaryOp(GVN lhs, GVN rhs, string opname) { mk_BinaryOp(lhs, rhs, opname, _) } or - deprecated GVN_UnaryOp(GVN child, string opname) { mk_UnaryOp(child, opname, _) } or - deprecated GVN_ArrayAccess(GVN x, GVN i, ControlFlowNode dominator) { - mk_ArrayAccess(x, i, dominator, _) - } or - // Any expression that is not handled by the cases above is - // given a unique number based on the expression itself. - GVN_Unanalyzable(Expr e) { not analyzableExpr(e) } - -/** - * A Global Value Number. A GVN is an abstract representation of the value - * computed by an expression. The relationship between `Expr` and `GVN` is - * many-to-one: every `Expr` has exactly one `GVN`, but multiple - * expressions can have the same `GVN`. If two expressions have the same - * `GVN`, it means that they compute the same value at run time. The `GVN` - * is an opaque value, so you cannot deduce what the run-time value of an - * expression will be from its `GVN`. The only use for the `GVN` of an - * expression is to find other expressions that compute the same value. - * Use the predicate `globalValueNumber` to get the `GVN` for an `Expr`. - * - * Note: `GVN` has `toString` and `getLocation` methods, so that it can be - * displayed in a results list. These work by picking an arbitrary - * expression with this `GVN` and using its `toString` and `getLocation` - * methods. - */ -deprecated class GVN extends GvnBase { - GVN() { this instanceof GvnBase } - - /** Gets an expression that has this GVN. */ - Expr getAnExpr() { this = globalValueNumber(result) } - - /** Gets the kind of the GVN. This can be useful for debugging. */ - string getKind() { - if this instanceof GVN_IntConst - then result = "IntConst" - else - if this instanceof GVN_FloatConst - then result = "FloatConst" - else - if this instanceof GVN_UndefinedStackVariable - then result = "UndefinedStackVariable" - else - if this instanceof GVN_OtherVariable - then result = "OtherVariable" - else - if this instanceof GVN_FieldAccess - then result = "FieldAccess" - else - if this instanceof GVN_Deref - then result = "Deref" - else - if this instanceof GVN_ThisExpr - then result = "ThisExpr" - else - if this instanceof GVN_Conversion - then result = "Conversion" - else - if this instanceof GVN_BinaryOp - then result = "BinaryOp" - else - if this instanceof GVN_UnaryOp - then result = "UnaryOp" - else - if this instanceof GVN_ArrayAccess - then result = "ArrayAccess" - else - if this instanceof GVN_Unanalyzable - then result = "Unanalyzable" - else result = "error" - } - - /** - * Gets an example of an expression with this GVN. - * This is useful for things like implementing toString(). - */ - private Expr exampleExpr() { - // Pick the expression with the minimum source location string. This is - // just an arbitrary way to pick an expression with this `GVN`. - result = min(Expr e | this = globalValueNumber(e) | e order by e.getLocation().toString()) - } - - /** Gets a textual representation of this element. */ - string toString() { result = this.exampleExpr().toString() } - - /** Gets the primary location of this element. */ - Location getLocation() { result = this.exampleExpr().getLocation() } -} - -private predicate analyzableIntConst(Expr e) { - strictcount(e.getValue().toInt()) = 1 and - strictcount(e.getUnspecifiedType()) = 1 -} - -private predicate mk_IntConst(int val, Type t, Expr e) { - analyzableIntConst(e) and - val = e.getValue().toInt() and - t = e.getUnspecifiedType() -} - -private predicate analyzableFloatConst(Expr e) { - strictcount(e.getValue().toFloat()) = 1 and - strictcount(e.getUnspecifiedType()) = 1 and - not analyzableIntConst(e) -} - -private predicate mk_FloatConst(float val, Type t, Expr e) { - analyzableFloatConst(e) and - val = e.getValue().toFloat() and - t = e.getUnspecifiedType() -} - -private predicate analyzableStackVariable(VariableAccess access) { - strictcount(SsaDefinition def | def.getAUse(_) = access | def) = 1 and - strictcount(SsaDefinition def, Variable v | def.getAUse(v) = access | v) = 1 and - count(SsaDefinition def, Variable v | - def.getAUse(v) = access - | - def.getDefiningValue(v).getFullyConverted() - ) <= 1 and - not analyzableConst(access) -} - -// Note: this predicate only has a result if the access has no -// defining value. If there is a defining value, then there is no -// need to generate a fresh `GVN` for the access because `globalValueNumber` -// will follow the chain and use the GVN of the defining value. -private predicate mk_UndefinedStackVariable( - StackVariable x, SsaDefinition def, VariableAccess access -) { - analyzableStackVariable(access) and - access = def.getAUse(x) and - not exists(def.getDefiningValue(x)) -} - -private predicate analyzableDotFieldAccess(DotFieldAccess access) { - strictcount(access.getTarget()) = 1 and - strictcount(access.getQualifier().getFullyConverted()) = 1 and - not analyzableConst(access) -} - -deprecated private predicate mk_DotFieldAccess(GVN qualifier, Field target, DotFieldAccess access) { - analyzableDotFieldAccess(access) and - target = access.getTarget() and - qualifier = globalValueNumber(access.getQualifier().getFullyConverted()) -} - -private predicate analyzablePointerFieldAccess(PointerFieldAccess access) { - strictcount(mostRecentSideEffect(access)) = 1 and - strictcount(access.getTarget()) = 1 and - strictcount(access.getQualifier().getFullyConverted()) = 1 and - not analyzableConst(access) -} - -deprecated private predicate mk_PointerFieldAccess( - GVN qualifier, Field target, ControlFlowNode dominator, PointerFieldAccess access -) { - analyzablePointerFieldAccess(access) and - dominator = mostRecentSideEffect(access) and - target = access.getTarget() and - qualifier = globalValueNumber(access.getQualifier().getFullyConverted()) -} - -/** - * `obj->field` is equivalent to `(*obj).field`, so we need to wrap an - * extra `GVN_Deref` around the qualifier. - */ -deprecated private predicate mk_PointerFieldAccess_with_deref( - GVN new_qualifier, Field target, PointerFieldAccess access -) { - exists(GVN qualifier, ControlFlowNode dominator | - mk_PointerFieldAccess(qualifier, target, dominator, access) and - new_qualifier = GVN_Deref(qualifier, dominator) - ) -} - -private predicate analyzableImplicitThisFieldAccess(ImplicitThisFieldAccess access) { - strictcount(mostRecentSideEffect(access)) = 1 and - strictcount(access.getTarget()) = 1 and - strictcount(access.getEnclosingFunction()) = 1 and - not analyzableConst(access) -} - -private predicate mk_ImplicitThisFieldAccess( - Function fcn, Field target, ControlFlowNode dominator, ImplicitThisFieldAccess access -) { - analyzableImplicitThisFieldAccess(access) and - dominator = mostRecentSideEffect(access) and - target = access.getTarget() and - fcn = access.getEnclosingFunction() -} - -deprecated private predicate mk_ImplicitThisFieldAccess_with_qualifier( - GVN qualifier, Field target, ControlFlowNode dominator, ImplicitThisFieldAccess access -) { - exists(Function fcn | - mk_ImplicitThisFieldAccess(fcn, target, dominator, access) and - qualifier = GVN_ThisExpr(fcn) - ) -} - -deprecated private predicate mk_ImplicitThisFieldAccess_with_deref( - GVN new_qualifier, Field target, ImplicitThisFieldAccess access -) { - exists(GVN qualifier, ControlFlowNode dominator | - mk_ImplicitThisFieldAccess_with_qualifier(qualifier, target, dominator, access) and - new_qualifier = GVN_Deref(qualifier, dominator) - ) -} - -/** - * Holds if `access` is an access of a variable that does - * not have SSA information. (For example, because the variable - * is global.) - */ -private predicate analyzableOtherVariable(VariableAccess access) { - not access instanceof FieldAccess and - not exists(SsaDefinition def | access = def.getAUse(_)) and - strictcount(access.getTarget()) = 1 and - strictcount(mostRecentSideEffect(access)) = 1 and - not analyzableConst(access) -} - -private predicate mk_OtherVariable(Variable x, ControlFlowNode dominator, VariableAccess access) { - analyzableOtherVariable(access) and - x = access.getTarget() and - dominator = mostRecentSideEffect(access) -} - -private predicate analyzableConversion(Conversion conv) { - strictcount(conv.getUnspecifiedType()) = 1 and - strictcount(conv.getExpr()) = 1 and - not analyzableConst(conv) -} - -deprecated private predicate mk_Conversion(Type t, GVN child, Conversion conv) { - analyzableConversion(conv) and - t = conv.getUnspecifiedType() and - child = globalValueNumber(conv.getExpr()) -} - -private predicate analyzableBinaryOp(BinaryOperation op) { - op.isPure() and - strictcount(op.getLeftOperand().getFullyConverted()) = 1 and - strictcount(op.getRightOperand().getFullyConverted()) = 1 and - strictcount(op.getOperator()) = 1 and - not analyzableConst(op) -} - -deprecated private predicate mk_BinaryOp(GVN lhs, GVN rhs, string opname, BinaryOperation op) { - analyzableBinaryOp(op) and - lhs = globalValueNumber(op.getLeftOperand().getFullyConverted()) and - rhs = globalValueNumber(op.getRightOperand().getFullyConverted()) and - opname = op.getOperator() -} - -private predicate analyzableUnaryOp(UnaryOperation op) { - not op instanceof PointerDereferenceExpr and - op.isPure() and - strictcount(op.getOperand().getFullyConverted()) = 1 and - strictcount(op.getOperator()) = 1 and - not analyzableConst(op) -} - -deprecated private predicate mk_UnaryOp(GVN child, string opname, UnaryOperation op) { - analyzableUnaryOp(op) and - child = globalValueNumber(op.getOperand().getFullyConverted()) and - opname = op.getOperator() -} - -private predicate analyzableThisExpr(ThisExpr thisExpr) { - strictcount(thisExpr.getEnclosingFunction()) = 1 and - not analyzableConst(thisExpr) -} - -private predicate mk_ThisExpr(Function fcn, ThisExpr thisExpr) { - analyzableThisExpr(thisExpr) and - fcn = thisExpr.getEnclosingFunction() -} - -private predicate analyzableArrayAccess(ArrayExpr ae) { - strictcount(ae.getArrayBase().getFullyConverted()) = 1 and - strictcount(ae.getArrayOffset().getFullyConverted()) = 1 and - strictcount(mostRecentSideEffect(ae)) = 1 and - not analyzableConst(ae) -} - -deprecated private predicate mk_ArrayAccess( - GVN base, GVN offset, ControlFlowNode dominator, ArrayExpr ae -) { - analyzableArrayAccess(ae) and - base = globalValueNumber(ae.getArrayBase().getFullyConverted()) and - offset = globalValueNumber(ae.getArrayOffset().getFullyConverted()) and - dominator = mostRecentSideEffect(ae) -} - -private predicate analyzablePointerDereferenceExpr(PointerDereferenceExpr deref) { - strictcount(deref.getOperand().getFullyConverted()) = 1 and - strictcount(mostRecentSideEffect(deref)) = 1 and - not analyzableConst(deref) -} - -deprecated private predicate mk_Deref(GVN p, ControlFlowNode dominator, PointerDereferenceExpr deref) { - analyzablePointerDereferenceExpr(deref) and - p = globalValueNumber(deref.getOperand().getFullyConverted()) and - dominator = mostRecentSideEffect(deref) -} - -/** Gets the global value number of expression `e`. */ -cached -deprecated GVN globalValueNumber(Expr e) { - exists(int val, Type t | - mk_IntConst(val, t, e) and - result = GVN_IntConst(val, t) - ) - or - exists(float val, Type t | - mk_FloatConst(val, t, e) and - result = GVN_FloatConst(val, t) - ) - or - // Local variable with a defining value. - exists(StackVariable x, SsaDefinition def | - analyzableStackVariable(e) and - e = def.getAUse(x) and - result = globalValueNumber(def.getDefiningValue(x).getFullyConverted()) - ) - or - // Local variable without a defining value. - exists(StackVariable x, SsaDefinition def | - mk_UndefinedStackVariable(x, def, e) and - result = GVN_UndefinedStackVariable(x, def) - ) - or - // Variable with no SSA information. - exists(Variable x, ControlFlowNode dominator | - mk_OtherVariable(x, dominator, e) and - result = GVN_OtherVariable(x, dominator) - ) - or - exists(GVN qualifier, Field target | - mk_DotFieldAccess(qualifier, target, e) and - result = GVN_FieldAccess(qualifier, target) - ) - or - exists(GVN qualifier, Field target | - mk_PointerFieldAccess_with_deref(qualifier, target, e) and - result = GVN_FieldAccess(qualifier, target) - ) - or - exists(GVN qualifier, Field target | - mk_ImplicitThisFieldAccess_with_deref(qualifier, target, e) and - result = GVN_FieldAccess(qualifier, target) - ) - or - exists(Function fcn | - mk_ThisExpr(fcn, e) and - result = GVN_ThisExpr(fcn) - ) - or - exists(Type t, GVN child | - mk_Conversion(t, child, e) and - result = GVN_Conversion(t, child) - ) - or - exists(GVN lhs, GVN rhs, string opname | - mk_BinaryOp(lhs, rhs, opname, e) and - result = GVN_BinaryOp(lhs, rhs, opname) - ) - or - exists(GVN child, string opname | - mk_UnaryOp(child, opname, e) and - result = GVN_UnaryOp(child, opname) - ) - or - exists(GVN x, GVN i, ControlFlowNode dominator | - mk_ArrayAccess(x, i, dominator, e) and - result = GVN_ArrayAccess(x, i, dominator) - ) - or - exists(GVN p, ControlFlowNode dominator | - mk_Deref(p, dominator, e) and - result = GVN_Deref(p, dominator) - ) - or - not analyzableExpr(e) and result = GVN_Unanalyzable(e) -} - -private predicate analyzableConst(Expr e) { - analyzableIntConst(e) or - analyzableFloatConst(e) -} - -/** - * Holds if the expression is explicitly handled by `globalValueNumber`. - * Unanalyzable expressions still need to be given a global value number, - * but it will be a unique number that is not shared with any other - * expression. - */ -private predicate analyzableExpr(Expr e) { - analyzableConst(e) or - analyzableStackVariable(e) or - analyzableDotFieldAccess(e) or - analyzablePointerFieldAccess(e) or - analyzableImplicitThisFieldAccess(e) or - analyzableOtherVariable(e) or - analyzableConversion(e) or - analyzableBinaryOp(e) or - analyzableUnaryOp(e) or - analyzableThisExpr(e) or - analyzableArrayAccess(e) or - analyzablePointerDereferenceExpr(e) -} diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index ab33b22360c1..52ce33161a75 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.9.11 + +### Minor Analysis Improvements + +* The "Uncontrolled data used in path expression" query (`cpp/path-injection`) query produces fewer near-duplicate results. +* The "Global variable may be used before initialization" query (`cpp/global-use-before-init`) no longer raises an alert on global variables that are initialized when they are declared. +* The "Inconsistent null check of pointer" query (`cpp/inconsistent-nullness-testing`) query no longer raises an alert when the guarded check is in a macro expansion. + ## 0.9.10 No user-facing changes. diff --git a/cpp/ql/src/Likely Bugs/Format/TooManyFormatArguments.qhelp b/cpp/ql/src/Likely Bugs/Format/TooManyFormatArguments.qhelp index bbd64254d54c..b4df60cbac72 100644 --- a/cpp/ql/src/Likely Bugs/Format/TooManyFormatArguments.qhelp +++ b/cpp/ql/src/Likely Bugs/Format/TooManyFormatArguments.qhelp @@ -22,10 +22,8 @@ function. -
  • cplusplus.com: C++ Functions.
  • +
  • CERT C Coding Standard: FIO47-C. Use valid format strings.
  • Microsoft C Runtime Library Reference: printf, wprintf.
  • - -
    diff --git a/cpp/ql/src/Likely Bugs/Format/WrongNumberOfFormatArguments.qhelp b/cpp/ql/src/Likely Bugs/Format/WrongNumberOfFormatArguments.qhelp index 66344e93f22d..bb4687b2d9a7 100644 --- a/cpp/ql/src/Likely Bugs/Format/WrongNumberOfFormatArguments.qhelp +++ b/cpp/ql/src/Likely Bugs/Format/WrongNumberOfFormatArguments.qhelp @@ -19,8 +19,8 @@ contents. -

    Review the format and arguments expected by the highlighted function calls. Update either -the format or the arguments so that the expected number of arguments are passed to the +

    Review the format and arguments expected by the highlighted function calls. Update either +the format or the arguments so that the expected number of arguments are passed to the function.

    @@ -30,11 +30,8 @@ function. -
  • CERT C Coding -Standard: FIO30-C. Exclude user input from format strings.
  • -
  • cplusplus.com: C++ Functions.
  • +
  • CERT C Coding Standard: FIO47-C. Use valid format strings.
  • Microsoft C Runtime Library Reference: printf, wprintf.
  • -
    diff --git a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.cpp b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.cpp deleted file mode 100644 index c3dd09c30719..000000000000 --- a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.cpp +++ /dev/null @@ -1,4 +0,0 @@ -int main() { - printf("%s\n", 42); //printf will treat 42 as a char*, will most likely segfault - return 0; -} diff --git a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp index 02bfd391a330..055adeb741f3 100644 --- a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp +++ b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp @@ -4,29 +4,33 @@

    Each call to the printf function or a related function should include -the type and sequence of arguments defined by the format. If the function is passed arguments +the type and sequence of arguments defined by the format. If the function is passed arguments of a different type or in a different sequence then the arguments are reinterpreted to fit the type and sequence expected, resulting in unpredictable behavior.

    -

    Review the format and arguments expected by the highlighted function calls. Update either -the format or the arguments so that the expected type and sequence of arguments are passed to +

    Review the format and arguments expected by the highlighted function calls. Update either +the format or the arguments so that the expected type and sequence of arguments are passed to the function.

    - + - - +

    In the following example, the wrong format specifier is given for an integer format argument:

    + + -
  • CERT C Coding -Standard: FIO30-C. Exclude user input from format strings.
  • -
  • cplusplus.com: C++ Functions.
  • -
  • CRT Alphabetical Function Reference: printf, _printf_l, wprintf, _wprintf_l.
  • +

    The corrected version uses %i as the format specifier for the integer format argument:

    + +
    + +
  • Microsoft Learn: Format specification syntax: printf and wprintf functions.
  • +
  • cplusplus.com:printf
  • +
  • CERT C Coding Standard: FIO47-C. Use valid format strings.
  • diff --git a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsBad.cpp b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsBad.cpp new file mode 100644 index 000000000000..046233af1b00 --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsBad.cpp @@ -0,0 +1,4 @@ +int main() { + printf("%s\n", 42); // BAD: printf will treat 42 as a char*, will most likely segfault + return 0; +} diff --git a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsGood.cpp b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsGood.cpp new file mode 100644 index 000000000000..0bd3fb5c4391 --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsGood.cpp @@ -0,0 +1,4 @@ +int main() { + printf("%i\n", 42); // GOOD: printf will treat 42 as an int + return 0; +} diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.cpp b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.cpp index c3640a66ab6f..29eef7c2b1f5 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.cpp +++ b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.cpp @@ -2,19 +2,18 @@ void f_warning(int i) { - // The usage of the logical not operator in this case is unlikely to be correct + // BAD: the usage of the logical not operator in this case is unlikely to be correct // as the output is being used as an operator for a bit-wise and operation - if (i & !FLAGS) + if (i & !FLAGS) { // code } } - void f_fixed(int i) { - if (i & ~FLAGS) // Changing the logical not operator for the bit-wise not operator would fix this logic + if (i & ~FLAGS) // GOOD: Changing the logical not operator for the bit-wise not operator would fix this logic { // code } -} \ No newline at end of file +} diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp index bac09fe9cf17..3b5824c314a3 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp +++ b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp @@ -16,7 +16,13 @@

    Carefully inspect the flagged expressions. Consider the intent in the code logic, and decide whether it is necessary to change the not operator.

    - + +

    Here is an example of this issue and how it can be fixed:

    + + + +

    In other cases, particularly when the expressions have bool type, the fix may instead be of the form a && !b.

    +
  • diff --git a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.cpp b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.cpp deleted file mode 100644 index 07acc91cd5ac..000000000000 --- a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.cpp +++ /dev/null @@ -1,2 +0,0 @@ -strncpy(dest, src, sizeof(src)); //wrong: size of dest should be used -strncpy(dest, src, strlen(src)); //wrong: size of dest should be used diff --git a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp index 2e297116710f..201b9057499a 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp +++ b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp @@ -3,7 +3,7 @@ "qhelp.dtd"> -

    The standard library function strncpy copies a source string to a destination buffer. The third argument defines the maximum number of characters to copy and should be less than +

    The standard library function strncpy copies a source string to a destination buffer. The third argument defines the maximum number of characters to copy and should be less than or equal to the size of the destination buffer. Calls of the form strncpy(dest, src, strlen(src)) or strncpy(dest, src, sizeof(src)) incorrectly set the third argument to the size of the source buffer. Executing a call of this type may cause a buffer overflow. Buffer overflows can lead to anything from a segmentation fault to a security vulnerability.

    @@ -12,14 +12,20 @@ or equal to the size of the destination buffer. Calls of the form strncpy( not the source buffer.

    - + +

    In the following examples, the size of the source buffer is incorrectly used as a parameter to strncpy:

    + +

    The corrected version uses the size of the destination buffer, or a variable containing the size of the destination buffer as the size parameter to strncpy:

    + +
    + -
  • cplusplus.com: strncpy.
  • +
  • cplusplus.com: strncpy.
  • I. Gerg. An Overview and Example of the Buffer-Overflow Exploit. IANewsletter vol 7 no 4. 2005.
  • diff --git a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsBad.cpp b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsBad.cpp new file mode 100644 index 000000000000..952550b26382 --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsBad.cpp @@ -0,0 +1,9 @@ +char src[256]; +char dest1[128]; + +... + +strncpy(dest1, src, sizeof(src)); // wrong: size of dest should be used + +char *dest2 = (char *)malloc(sz1 + sz2 + sz3); +strncpy(dest2, src, strlen(src)); // wrong: size of dest should be used diff --git a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsGood.cpp b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsGood.cpp new file mode 100644 index 000000000000..22fc4ebd2220 --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsGood.cpp @@ -0,0 +1,10 @@ +char src[256]; +char dest1[128]; + +... + +strncpy(dest1, src, sizeof(dest1)); // correct + +size_t destSize = sz1 + sz2 + sz3; +char *dest2 = (char *)malloc(destSize); +strncpy(dest2, src, destSize); // correct diff --git a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql index 4e626d0bc773..94a9cacf9f49 100644 --- a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql +++ b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql @@ -88,6 +88,11 @@ module TaintedPathConfig implements DataFlow::ConfigSig { hasUpperBoundsCheck(checkedVar) ) } + + predicate isBarrierOut(DataFlow::Node node) { + // make sinks barriers so that we only report the closest instance + isSink(node) + } } module TaintedPath = TaintTracking::Global; diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp similarity index 84% rename from cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp rename to cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp index 19975b174932..87cc75c5f019 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp +++ b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp @@ -30,6 +30,12 @@ This is because the temporary container is not bound to a rvalue reference.

    +

    +To fix lifetime_of_temp_not_extended, consider rewriting the code so that the lifetime of the temporary object is extended. +In fixed_lifetime_of_temp_not_extended, the lifetime of the temporary object has been extended by storing it in an rvalue reference. +

    + + diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.ql b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql similarity index 72% rename from cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.ql rename to cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql index a36e54070bbe..139555cfa1d6 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.ql +++ b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql @@ -2,9 +2,10 @@ * @name Iterator to expired container * @description Using an iterator owned by a container whose lifetime has expired may lead to unexpected behavior. * @kind problem - * @precision high + * @precision medium * @id cpp/iterator-to-expired-container * @problem.severity warning + * @security-severity 8.8 * @tags reliability * security * external/cwe/cwe-416 @@ -61,14 +62,38 @@ DataFlow::Node getADestroyedNode(DataFlow::Node n) { ) } -predicate destroyedToBeginSink(DataFlow::Node sink, FunctionCall fc) { +predicate destroyedToBeginSink(DataFlow::Node sink) { exists(CallInstruction call | call = sink.asOperand().(ThisArgumentOperand).getCall() and - fc = call.getUnconvertedResultExpression() and call.getStaticCallTarget() instanceof BeginOrEndFunction ) } +/** + * Holds if `node1` is the node corresponding to a qualifier of a destructor + * call and `node2` is a node that is destroyed as a result of `node1` being + * destroyed. + */ +private predicate qualifierToDestroyed(DataFlow::Node node1, DataFlow::Node node2) { + tempToDestructorSink(node1, _) and + node2 = getADestroyedNode(node1) +} + +/** + * A configuration to track flow from a destroyed node to a qualifier of + * a `begin` or `end` function call. + * + * This configuration exists to prevent a cartesian product between all sinks and + * all states in `Config::isSink`. + */ +module Config0 implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { qualifierToDestroyed(_, source) } + + predicate isSink(DataFlow::Node sink) { destroyedToBeginSink(sink) } +} + +module Flow0 = DataFlow::Global; + /** * A configuration to track flow from a temporary variable to the qualifier of * a destructor call, and subsequently to a qualifier of a call to `begin` or @@ -78,12 +103,15 @@ module Config implements DataFlow::StateConfigSig { newtype FlowState = additional TempToDestructor() or additional DestroyedToBegin(DataFlow::Node n) { - exists(DataFlow::Node thisOperand | - tempToDestructorSink(thisOperand, _) and - n = getADestroyedNode(thisOperand) - ) + any(Flow0::PathNode pn | pn.isSource()).getNode() = n } + /** + * Holds if `sink` is a qualifier to a call to `begin`, and `mid` is an + * object that is destroyed. + */ + private predicate relevant(DataFlow::Node mid, DataFlow::Node sink) { Flow0::flow(mid, sink) } + predicate isSource(DataFlow::Node source, FlowState state) { source.asInstruction().(VariableAddressInstruction).getIRVariable() instanceof IRTempVariable and state = TempToDestructor() @@ -92,16 +120,16 @@ module Config implements DataFlow::StateConfigSig { predicate isAdditionalFlowStep( DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 ) { - tempToDestructorSink(node1, _) and state1 = TempToDestructor() and state2 = DestroyedToBegin(node2) and - node2 = getADestroyedNode(node1) + qualifierToDestroyed(node1, node2) } predicate isSink(DataFlow::Node sink, FlowState state) { - // Note: This is a non-trivial cartesian product! - // Hopefully, both of these sets are quite small in practice - destroyedToBeginSink(sink, _) and state instanceof DestroyedToBegin + exists(DataFlow::Node mid | + relevant(mid, sink) and + state = DestroyedToBegin(mid) + ) } DataFlow::FlowFeature getAFeature() { @@ -121,9 +149,9 @@ module Config implements DataFlow::StateConfigSig { module Flow = DataFlow::GlobalWithState; -from Flow::PathNode source, Flow::PathNode sink, FunctionCall beginOrEnd, DataFlow::Node mid +from Flow::PathNode source, Flow::PathNode sink, DataFlow::Node mid where Flow::flowPath(source, sink) and - destroyedToBeginSink(sink.getNode(), beginOrEnd) and + destroyedToBeginSink(sink.getNode()) and sink.getState() = Config::DestroyedToBegin(mid) -select mid, "This object is destroyed before $@ is called.", beginOrEnd, beginOrEnd.toString() +select mid, "This object is destroyed at the end of the full-expression." diff --git a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime-fixed.cpp b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime-fixed.cpp new file mode 100644 index 000000000000..d113b4165ff7 --- /dev/null +++ b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime-fixed.cpp @@ -0,0 +1,6 @@ +void fixed_lifetime_of_temp_not_extended() { + auto&& v = get_vector(); + for(auto x : log_and_return_argument(v)) { + use(x); // GOOD: The lifetime of the container returned by `get_vector()` has been extended to the lifetime of `v`. + } +} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime.cpp b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime.cpp similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime.cpp rename to cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime.cpp diff --git a/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp b/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp index e0678c0beff2..3a449b4c38c3 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp +++ b/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp @@ -8,6 +8,12 @@ When the std::string object is destroyed, the pointer returned by c_str is no longer valid. If the pointer is used after the std::string object is destroyed, then the behavior is undefined.

    + +

    Typically, this problem occurs when a std::string is returned by a function call (or overloaded operator) +by value, and the result is not immediately stored in a variable by value or reference in a way that extends the lifetime of +the temporary object. The resulting temporary std::string object is destroyed at the end of the containing expression +statement, along with any memory returned by a call to c_str. +

    @@ -39,6 +45,8 @@ points to valid memory.
  • MEM50-CPP. Do not access freed memory.
  • +
  • Microsoft Learn: Temporary objects.
  • +
  • cppreference.com: Lifetime of a temporary.
  • diff --git a/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql b/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql index 7d776280f917..982486759082 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql +++ b/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql @@ -23,4 +23,5 @@ where (c.getTarget() instanceof StdStringCStr or c.getTarget() instanceof StdStringData) and isTemporary(c.getQualifier().getFullyConverted()) select c, - "The underlying string object is destroyed after the call to '" + c.getTarget() + "' returns." + "The underlying temporary string object is destroyed after the call to '" + c.getTarget() + + "' returns." diff --git a/cpp/ql/src/change-notes/2024-04-29-iterator-to-expired-container.md b/cpp/ql/src/change-notes/2024-04-29-iterator-to-expired-container.md new file mode 100644 index 000000000000..ce06805a8f37 --- /dev/null +++ b/cpp/ql/src/change-notes/2024-04-29-iterator-to-expired-container.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `cpp/iterator-to-expired-container`, to detect the creation of iterators owned by a temporary objects that are about to be destroyed. diff --git a/cpp/ql/src/change-notes/2024-04-09-reduce-FP.md b/cpp/ql/src/change-notes/released/0.9.11.md similarity index 60% rename from cpp/ql/src/change-notes/2024-04-09-reduce-FP.md rename to cpp/ql/src/change-notes/released/0.9.11.md index d2d104d59cd8..41ffd2f0d06b 100644 --- a/cpp/ql/src/change-notes/2024-04-09-reduce-FP.md +++ b/cpp/ql/src/change-notes/released/0.9.11.md @@ -1,5 +1,7 @@ ---- -category: minorAnalysis ---- +## 0.9.11 + +### Minor Analysis Improvements + +* The "Uncontrolled data used in path expression" query (`cpp/path-injection`) query produces fewer near-duplicate results. * The "Global variable may be used before initialization" query (`cpp/global-use-before-init`) no longer raises an alert on global variables that are initialized when they are declared. -* The "Inconsistent null check of pointer" query (`cpp/inconsistent-nullness-testing`) query no longer raises an alert when the guarded check is in a macro expansion. \ No newline at end of file +* The "Inconsistent null check of pointer" query (`cpp/inconsistent-nullness-testing`) query no longer raises an alert when the guarded check is in a macro expansion. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index d086ed69541d..47eb8b55bab8 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.9.10 +lastReleaseVersion: 0.9.11 diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.cpp b/cpp/ql/src/experimental/Best Practices/GuardedFree.cpp new file mode 100644 index 000000000000..5242e3da8f5e --- /dev/null +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.cpp @@ -0,0 +1,11 @@ +void test() +{ + char *foo = malloc(100); + + // BAD + if (foo) + free(foo); + + // GOOD + free(foo); +} \ No newline at end of file diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.qhelp b/cpp/ql/src/experimental/Best Practices/GuardedFree.qhelp new file mode 100644 index 000000000000..77fdd4670008 --- /dev/null +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.qhelp @@ -0,0 +1,18 @@ + + + +

    The free function, which deallocates heap memory, may accept a NULL pointer and take no action. Therefore, it is unnecessary to check its argument for the value of NULL before a function call to free. As such, these guards may hinder performance and readability.

    +
    + +

    A function call to free should not depend upon the value of its argument. Delete the if condition preceeding a function call to free when its only purpose is to check the value of the pointer to be freed.

    +
    + + + + +
  • + The Open Group Base Specifications Issue 7, 2018 Edition: + free - free allocated memory +
  • +
    +
    \ No newline at end of file diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql new file mode 100644 index 000000000000..2d504d9bc057 --- /dev/null +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql @@ -0,0 +1,26 @@ +/** + * @name Guarded Free + * @description NULL-condition guards before function calls to the memory-deallocation + * function free(3) are unnecessary, because passing NULL to free(3) is a no-op. + * @kind problem + * @problem.severity recommendation + * @precision very-high + * @id cpp/guarded-free + * @tags maintainability + * readability + * experimental + */ + +import cpp +import semmle.code.cpp.controlflow.Guards + +class FreeCall extends FunctionCall { + FreeCall() { this.getTarget().hasGlobalName("free") } +} + +from GuardCondition gc, FreeCall fc, Variable v, BasicBlock bb +where + gc.ensuresEq(v.getAnAccess(), 0, bb, false) and + fc.getArgument(0) = v.getAnAccess() and + bb = fc.getEnclosingStmt() +select gc, "unnecessary NULL check before call to $@", fc, "free" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-125/DangerousWorksWithMultibyteOrWideCharacters.ql b/cpp/ql/src/experimental/Security/CWE/CWE-125/DangerousWorksWithMultibyteOrWideCharacters.ql index 12a44be0d1fc..6529bf6cdf89 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-125/DangerousWorksWithMultibyteOrWideCharacters.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-125/DangerousWorksWithMultibyteOrWideCharacters.ql @@ -24,7 +24,7 @@ predicate exprMayBeString(Expr exp) { fctmp.getAnArgument().(VariableAccess).getTarget() = exp.(VariableAccess).getTarget() or globalValueNumber(fctmp.getAnArgument()) = globalValueNumber(exp) ) and - fctmp.getTarget().hasName(["strlen", "strcat", "strncat", "strcpy", "sptintf", "printf"]) + fctmp.getTarget().hasName(["strlen", "strcat", "strncat", "strcpy", "sprintf", "printf"]) ) or exists(AssignExpr astmp | diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 3fe23a7cbbad..e3f87e5a6356 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.9.11-dev +version: 0.9.12-dev groups: - cpp - queries diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/IteratorToExpiredContainer.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/IteratorToExpiredContainer.expected deleted file mode 100644 index c29e7953ea64..000000000000 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/IteratorToExpiredContainer.expected +++ /dev/null @@ -1,11 +0,0 @@ -| test.cpp:680:30:680:30 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:680:17:680:17 | call to begin | call to begin | -| test.cpp:680:30:680:30 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:680:17:680:17 | call to end | call to end | -| test.cpp:683:31:683:32 | call to at | This object is destroyed before $@ is called. | test.cpp:683:17:683:17 | call to begin | call to begin | -| test.cpp:683:31:683:32 | call to at | This object is destroyed before $@ is called. | test.cpp:683:17:683:17 | call to end | call to end | -| test.cpp:689:46:689:58 | pointer to ~vector output argument | This object is destroyed before $@ is called. | test.cpp:689:60:689:62 | call to end | call to end | -| test.cpp:702:27:702:27 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:703:19:703:23 | call to begin | call to begin | -| test.cpp:702:27:702:27 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:703:36:703:38 | call to end | call to end | -| test.cpp:727:23:727:23 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:750:17:750:17 | call to begin | call to begin | -| test.cpp:727:23:727:23 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:750:17:750:17 | call to end | call to end | -| test.cpp:735:23:735:23 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:759:17:759:17 | call to begin | call to begin | -| test.cpp:735:23:735:23 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:759:17:759:17 | call to end | call to end | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/IteratorToExpiredContainer.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/IteratorToExpiredContainer.qlref deleted file mode 100644 index 5f86bb26ff09..000000000000 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/IteratorToExpiredContainer.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.ql diff --git a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected index cc29559d5d31..d50ca1609163 100644 --- a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected +++ b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected @@ -56,6 +56,8 @@ astGuardsCompare | 17 | y < 1+1 when ... > ... is false | | 17 | y >= 1+1 when ... && ... is true | | 17 | y >= 1+1 when ... > ... is true | +| 18 | call to get != 0 when call to get is true | +| 18 | call to get == 0 when call to get is false | | 26 | 0 < x+0 when ... > ... is true | | 26 | 0 >= x+0 when ... > ... is false | | 26 | x < 0+1 when ... > ... is false | @@ -146,6 +148,24 @@ astGuardsCompare | 109 | y < 0+0 when ... < ... is true | | 109 | y >= 0+0 when ... < ... is false | | 109 | y >= 0+0 when ... \|\| ... is false | +| 126 | 1 != 0 when 1 is true | +| 126 | 1 != 0 when ... && ... is true | +| 126 | 1 == 0 when 1 is false | +| 126 | call to test3_condition != 0 when ... && ... is true | +| 126 | call to test3_condition != 0 when call to test3_condition is true | +| 126 | call to test3_condition == 0 when call to test3_condition is false | +| 131 | b != 0 when b is true | +| 131 | b == 0 when b is false | +| 137 | 0 != 0 when 0 is true | +| 137 | 0 == 0 when 0 is false | +| 146 | ! ... != 0 when ! ... is true | +| 146 | ! ... == 0 when ! ... is false | +| 152 | x != 0 when ... && ... is true | +| 152 | x != 0 when x is true | +| 152 | x == 0 when x is false | +| 152 | y != 0 when ... && ... is true | +| 152 | y != 0 when y is true | +| 152 | y == 0 when y is false | | 156 | ... + ... != x+0 when ... == ... is false | | 156 | ... + ... == x+0 when ... == ... is true | | 156 | x != ... + ...+0 when ... == ... is false | @@ -184,6 +204,8 @@ astGuardsCompare | 175 | call to foo != 0+0 when ... == ... is false | | 175 | call to foo == 0 when ... == ... is true | | 175 | call to foo == 0+0 when ... == ... is true | +| 181 | x != 0 when x is true | +| 181 | x == 0 when x is false | astGuardsControl | test.c:7:9:7:13 | ... > ... | false | 10 | 11 | | test.c:7:9:7:13 | ... > ... | true | 7 | 9 | @@ -485,8 +507,28 @@ astGuardsEnsure_const | test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | 0 | 109 | 109 | | test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 | | test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 126 | 126 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 131 | 131 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 131 | 132 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 134 | 123 | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 | +| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 | +| test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | != | 0 | 131 | 132 | +| test.c:137:7:137:7 | 0 | test.c:137:7:137:7 | 0 | == | 0 | 142 | 136 | +| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | != | 0 | 146 | 147 | +| test.c:152:10:152:10 | x | test.c:152:10:152:10 | x | != | 0 | 151 | 152 | +| test.c:152:10:152:10 | x | test.c:152:10:152:10 | x | != | 0 | 152 | 152 | +| test.c:152:10:152:15 | ... && ... | test.c:152:10:152:10 | x | != | 0 | 151 | 152 | +| test.c:152:10:152:15 | ... && ... | test.c:152:15:152:15 | y | != | 0 | 151 | 152 | +| test.c:152:15:152:15 | y | test.c:152:15:152:15 | y | != | 0 | 151 | 152 | | test.c:175:13:175:32 | ... == ... | test.c:175:13:175:15 | call to foo | != | 0 | 175 | 175 | | test.c:175:13:175:32 | ... == ... | test.c:175:13:175:15 | call to foo | == | 0 | 175 | 175 | +| test.c:181:9:181:9 | x | test.c:181:9:181:9 | x | != | 0 | 181 | 182 | +| test.c:181:9:181:9 | x | test.c:181:9:181:9 | x | != | 0 | 186 | 180 | +| test.c:181:9:181:9 | x | test.c:181:9:181:9 | x | == | 0 | 183 | 184 | +| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 30 | 30 | @@ -545,6 +587,8 @@ irGuardsCompare | 17 | y < 2 when CompareGT: ... > ... is false | | 17 | y >= 1+1 when CompareGT: ... > ... is true | | 17 | y >= 2 when CompareGT: ... > ... is true | +| 18 | call to get != 0 when CompareNE: (bool)... is true | +| 18 | call to get == 0 when CompareNE: (bool)... is false | | 26 | 0 < x+0 when CompareGT: ... > ... is true | | 26 | 0 >= x+0 when CompareGT: ... > ... is false | | 26 | x < 0+1 when CompareGT: ... > ... is false | @@ -635,6 +679,20 @@ irGuardsCompare | 109 | y < 0+0 when CompareLT: ... < ... is true | | 109 | y >= 0 when CompareLT: ... < ... is false | | 109 | y >= 0+0 when CompareLT: ... < ... is false | +| 126 | 1 != 0 when Constant: 1 is true | +| 126 | 1 == 0 when Constant: 1 is false | +| 126 | call to test3_condition != 0 when Call: call to test3_condition is true | +| 126 | call to test3_condition == 0 when Call: call to test3_condition is false | +| 131 | b != 0 when Load: b is true | +| 131 | b == 0 when Load: b is false | +| 137 | 0 != 0 when Constant: 0 is true | +| 137 | 0 == 0 when Constant: 0 is false | +| 146 | ! ... != 0 when LogicalNot: ! ... is true | +| 146 | ! ... == 0 when LogicalNot: ! ... is false | +| 152 | x != 0 when Load: x is true | +| 152 | x == 0 when Load: x is false | +| 152 | y != 0 when Load: y is true | +| 152 | y == 0 when Load: y is false | | 156 | ... + ... != x+0 when CompareEQ: ... == ... is false | | 156 | ... + ... == x+0 when CompareEQ: ... == ... is true | | 156 | x != ... + ...+0 when CompareEQ: ... == ... is false | @@ -673,6 +731,8 @@ irGuardsCompare | 175 | call to foo != 0+0 when CompareEQ: ... == ... is false | | 175 | call to foo == 0 when CompareEQ: ... == ... is true | | 175 | call to foo == 0+0 when CompareEQ: ... == ... is true | +| 181 | x != 0 when Load: x is true | +| 181 | x == 0 when Load: x is false | irGuardsControl | test.c:7:9:7:13 | CompareGT: ... > ... | false | 11 | 11 | | test.c:7:9:7:13 | CompareGT: ... > ... | true | 8 | 8 | @@ -994,8 +1054,22 @@ irGuardsEnsure_const | test.c:109:9:109:14 | CompareEQ: ... == ... | test.c:109:9:109:9 | Load: x | != | 0 | 109 | 109 | | test.c:109:9:109:14 | CompareEQ: ... == ... | test.c:109:9:109:9 | Load: x | != | 0 | 113 | 113 | | test.c:109:19:109:23 | CompareLT: ... < ... | test.c:109:19:109:19 | Load: y | >= | 0 | 113 | 113 | +| test.c:126:7:126:7 | Constant: 1 | test.c:126:7:126:7 | Constant: 1 | != | 0 | 126 | 126 | +| test.c:126:7:126:7 | Constant: 1 | test.c:126:7:126:7 | Constant: 1 | != | 0 | 127 | 127 | +| test.c:126:7:126:7 | Constant: 1 | test.c:126:7:126:7 | Constant: 1 | != | 0 | 131 | 131 | +| test.c:126:7:126:7 | Constant: 1 | test.c:126:7:126:7 | Constant: 1 | != | 0 | 132 | 132 | +| test.c:126:7:126:7 | Constant: 1 | test.c:126:7:126:7 | Constant: 1 | != | 0 | 134 | 134 | +| test.c:126:12:126:26 | Call: call to test3_condition | test.c:126:12:126:26 | Call: call to test3_condition | != | 0 | 127 | 127 | +| test.c:131:7:131:7 | Load: b | test.c:131:7:131:7 | Load: b | != | 0 | 132 | 132 | +| test.c:137:7:137:7 | Constant: 0 | test.c:137:7:137:7 | Constant: 0 | == | 0 | 142 | 142 | +| test.c:146:7:146:8 | LogicalNot: ! ... | test.c:146:7:146:8 | LogicalNot: ! ... | != | 0 | 147 | 147 | +| test.c:152:10:152:10 | Load: x | test.c:152:10:152:10 | Load: x | != | 0 | 152 | 152 | +| test.c:152:15:152:15 | Load: y | test.c:152:15:152:15 | Load: y | != | 0 | 152 | 152 | | test.c:175:13:175:32 | CompareEQ: ... == ... | test.c:175:13:175:15 | Call: call to foo | != | 0 | 175 | 175 | | test.c:175:13:175:32 | CompareEQ: ... == ... | test.c:175:13:175:15 | Call: call to foo | == | 0 | 175 | 175 | +| test.c:181:9:181:9 | Load: x | test.c:181:9:181:9 | Load: x | != | 0 | 182 | 182 | +| test.c:181:9:181:9 | Load: x | test.c:181:9:181:9 | Load: x | == | 0 | 184 | 184 | +| test.cpp:18:8:18:12 | CompareNE: (bool)... | test.cpp:18:8:18:10 | Call: call to get | != | 0 | 19 | 19 | | test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | != | -1 | 34 | 34 | | test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | == | -1 | 30 | 30 | | test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | == | -1 | 32 | 32 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected index 6eebc960ce3c..13d6c2b654ff 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected @@ -26,9 +26,19 @@ | test.c:137:7:137:7 | 0 | | test.c:146:7:146:8 | ! ... | | test.c:146:8:146:8 | x | +| test.c:152:8:152:8 | p | +| test.c:158:8:158:9 | ! ... | +| test.c:158:9:158:9 | p | +| test.c:164:8:164:8 | s | +| test.c:170:8:170:9 | ! ... | +| test.c:170:9:170:9 | s | | test.cpp:18:8:18:10 | call to get | | test.cpp:31:7:31:13 | ... == ... | | test.cpp:42:13:42:20 | call to getABool | | test.cpp:61:10:61:10 | i | | test.cpp:74:10:74:10 | i | | test.cpp:84:10:84:10 | i | +| test.cpp:93:6:93:6 | c | +| test.cpp:99:6:99:6 | f | +| test.cpp:105:6:105:14 | ... != ... | +| test.cpp:111:6:111:14 | ... != ... | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected index b88856d90cf0..a2f418b3d7bb 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected @@ -22,6 +22,8 @@ | 17 | y >= 1+1 when ... > ... is true | | 17 | y >= 2 when ... && ... is true | | 17 | y >= 2 when ... > ... is true | +| 18 | call to get != 0 when call to get is true | +| 18 | call to get == 0 when call to get is false | | 26 | 0 < x+0 when ... > ... is true | | 26 | 0 >= x+0 when ... > ... is false | | 26 | x < 0+1 when ... > ... is false | @@ -107,6 +109,8 @@ | 85 | y != 0+0 when ... && ... is true | | 85 | y == 0 when ... != ... is false | | 85 | y == 0+0 when ... != ... is false | +| 93 | c != 0 when c is true | +| 93 | c == 0 when c is false | | 94 | 0 != x+0 when ... != ... is true | | 94 | 0 == x+0 when ... != ... is false | | 94 | x != 0 when ... != ... is true | @@ -119,6 +123,10 @@ | 102 | j < 10+0 when ... < ... is true | | 102 | j >= 10 when ... < ... is false | | 102 | j >= 10+0 when ... < ... is false | +| 105 | 0.0 != f+0 when ... != ... is true | +| 105 | 0.0 == f+0 when ... != ... is false | +| 105 | f != 0.0+0 when ... != ... is true | +| 105 | f == 0.0+0 when ... != ... is false | | 109 | 0 != x+0 when ... == ... is false | | 109 | 0 != x+0 when ... \|\| ... is false | | 109 | 0 < y+1 when ... < ... is false | @@ -137,3 +145,27 @@ | 109 | y >= 0 when ... \|\| ... is false | | 109 | y >= 0+0 when ... < ... is false | | 109 | y >= 0+0 when ... \|\| ... is false | +| 111 | 0.0 != i+0 when ... != ... is true | +| 111 | 0.0 == i+0 when ... != ... is false | +| 111 | i != 0.0+0 when ... != ... is true | +| 111 | i == 0.0+0 when ... != ... is false | +| 126 | 1 != 0 when 1 is true | +| 126 | 1 != 0 when ... && ... is true | +| 126 | 1 == 0 when 1 is false | +| 126 | call to test3_condition != 0 when ... && ... is true | +| 126 | call to test3_condition != 0 when call to test3_condition is true | +| 126 | call to test3_condition == 0 when call to test3_condition is false | +| 131 | b != 0 when b is true | +| 131 | b == 0 when b is false | +| 137 | 0 != 0 when 0 is true | +| 137 | 0 == 0 when 0 is false | +| 146 | ! ... != 0 when ! ... is true | +| 146 | ! ... == 0 when ! ... is false | +| 152 | p != 0 when p is true | +| 152 | p == 0 when p is false | +| 158 | ! ... != 0 when ! ... is true | +| 158 | ! ... == 0 when ! ... is false | +| 164 | s != 0 when s is true | +| 164 | s == 0 when s is false | +| 170 | ! ... != 0 when ! ... is true | +| 170 | ! ... == 0 when ! ... is false | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected index fbfaff9acf6b..cf36a58a515b 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected @@ -79,6 +79,12 @@ | test.c:137:7:137:7 | 0 | false | 142 | 136 | | test.c:146:7:146:8 | ! ... | true | 146 | 147 | | test.c:146:8:146:8 | x | false | 146 | 147 | +| test.c:152:8:152:8 | p | true | 152 | 154 | +| test.c:158:8:158:9 | ! ... | true | 158 | 160 | +| test.c:158:9:158:9 | p | false | 158 | 160 | +| test.c:164:8:164:8 | s | true | 164 | 166 | +| test.c:170:8:170:9 | ! ... | true | 170 | 172 | +| test.c:170:9:170:9 | s | false | 170 | 172 | | test.cpp:18:8:18:10 | call to get | true | 19 | 19 | | test.cpp:31:7:31:13 | ... == ... | false | 30 | 30 | | test.cpp:31:7:31:13 | ... == ... | false | 34 | 34 | @@ -90,3 +96,7 @@ | test.cpp:61:10:61:10 | i | Case[1] | 65 | 66 | | test.cpp:74:10:74:10 | i | Case[0..10] | 75 | 77 | | test.cpp:74:10:74:10 | i | Case[11..20] | 78 | 79 | +| test.cpp:93:6:93:6 | c | true | 93 | 94 | +| test.cpp:99:6:99:6 | f | true | 99 | 100 | +| test.cpp:105:6:105:14 | ... != ... | true | 105 | 106 | +| test.cpp:111:6:111:14 | ... != ... | true | 111 | 112 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected index e5328aefa629..45d63f6dd536 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected @@ -1,3 +1,4 @@ +binary | test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | test.c:7:13:7:13 | 0 | 1 | 10 | 11 | | test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | test.c:7:13:7:13 | 0 | 1 | 7 | 9 | | test.c:7:9:7:13 | ... > ... | test.c:7:13:7:13 | 0 | < | test.c:7:9:7:9 | x | 0 | 7 | 9 | @@ -154,3 +155,109 @@ | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | 34 | 34 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 30 | 30 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 31 | 32 | +| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:6:105:6 | f | != | test.cpp:105:11:105:14 | 0.0 | 0 | 105 | 106 | +| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:11:105:14 | 0.0 | != | test.cpp:105:6:105:6 | f | 0 | 105 | 106 | +| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:6:111:6 | i | != | test.cpp:111:11:111:14 | 0.0 | 0 | 111 | 112 | +| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:11:111:14 | 0.0 | != | test.cpp:111:6:111:6 | i | 0 | 111 | 112 | +unary +| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | 1 | 10 | 11 | +| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | 1 | 7 | 9 | +| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | 0 | 17 | 17 | +| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | 0 | 18 | 18 | +| test.c:17:8:17:21 | ... && ... | test.c:17:8:17:8 | x | < | 0 | 18 | 18 | +| test.c:17:8:17:21 | ... && ... | test.c:17:17:17:17 | y | >= | 2 | 18 | 18 | +| test.c:17:17:17:21 | ... > ... | test.c:17:17:17:17 | y | >= | 2 | 18 | 18 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 2 | 2 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 31 | 34 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 34 | 34 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 39 | 42 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 42 | 42 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 42 | 44 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 45 | 45 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 45 | 47 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 51 | 53 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 56 | 58 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 58 | 58 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 58 | 66 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 62 | 62 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | >= | 1 | 26 | 28 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | < | 10 | 34 | 34 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 2 | 2 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 39 | 42 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 42 | 42 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 42 | 44 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 45 | 45 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 45 | 47 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 51 | 53 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 56 | 58 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 58 | 58 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 58 | 66 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 62 | 62 | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 42 | 42 | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 42 | 44 | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 45 | 45 | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 45 | 47 | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 51 | 53 | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | 1 | 42 | 42 | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | 1 | 51 | 53 | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | 1 | 45 | 45 | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | 1 | 45 | 47 | +| test.c:45:16:45:20 | ... > ... | test.c:45:16:45:16 | y | >= | 1 | 45 | 47 | +| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | 0 | 58 | 58 | +| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | 0 | 62 | 62 | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:9:58:9 | x | != | 0 | 62 | 62 | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:19:58:19 | y | >= | 0 | 62 | 62 | +| test.c:58:19:58:23 | ... < ... | test.c:58:19:58:19 | y | >= | 0 | 62 | 62 | +| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | != | 0 | 78 | 79 | +| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | == | 0 | 75 | 77 | +| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | 0 | 85 | 85 | +| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | 0 | 86 | 86 | +| test.c:85:8:85:23 | ... && ... | test.c:85:8:85:8 | x | == | 0 | 86 | 86 | +| test.c:85:8:85:23 | ... && ... | test.c:85:18:85:18 | y | != | 0 | 86 | 86 | +| test.c:85:18:85:23 | ... != ... | test.c:85:18:85:18 | y | != | 0 | 86 | 86 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | != | 0 | 94 | 96 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 70 | 70 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 99 | 102 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 102 | 102 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 107 | 109 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 109 | 109 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 109 | 117 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 113 | 113 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | < | 10 | 102 | 102 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 70 | 70 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 107 | 109 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 109 | 109 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 109 | 117 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 113 | 113 | +| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | 0 | 109 | 109 | +| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:19:109:19 | y | >= | 0 | 113 | 113 | +| test.c:109:19:109:23 | ... < ... | test.c:109:19:109:19 | y | >= | 0 | 113 | 113 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 126 | 126 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 131 | 131 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 131 | 132 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 134 | 123 | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 | +| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 | +| test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | != | 0 | 131 | 132 | +| test.c:137:7:137:7 | 0 | test.c:137:7:137:7 | 0 | == | 0 | 142 | 136 | +| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | != | 0 | 146 | 147 | +| test.c:152:8:152:8 | p | test.c:152:8:152:8 | p | != | 0 | 152 | 154 | +| test.c:158:8:158:9 | ! ... | test.c:158:8:158:9 | ! ... | != | 0 | 158 | 160 | +| test.c:164:8:164:8 | s | test.c:164:8:164:8 | s | != | 0 | 164 | 166 | +| test.c:170:8:170:9 | ! ... | test.c:170:8:170:9 | ! ... | != | 0 | 170 | 172 | +| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 30 | 30 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 31 | 32 | +| test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 0 | 62 | 64 | +| test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 1 | 65 | 66 | +| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | < | 11 | 75 | 77 | +| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | < | 21 | 78 | 79 | +| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 0 | 75 | 77 | +| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 11 | 78 | 79 | +| test.cpp:93:6:93:6 | c | test.cpp:93:6:93:6 | c | != | 0 | 93 | 94 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.ql b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.ql index 94aaade03ed5..59f8a399c6d4 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.ql +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.ql @@ -7,8 +7,9 @@ import cpp import semmle.code.cpp.controlflow.Guards -from GuardCondition guard, Expr left, Expr right, int k, int start, int end, string op -where +query predicate binary( + GuardCondition guard, Expr left, string op, Expr right, int k, int start, int end +) { exists(BasicBlock block | guard.ensuresLt(left, right, k, block, true) and op = "<" or @@ -20,4 +21,18 @@ where | block.hasLocationInfo(_, start, _, end, _) ) -select guard, left, op, right, k, start, end +} + +query predicate unary(GuardCondition guard, Expr left, string op, int k, int start, int end) { + exists(BasicBlock block | + guard.ensuresLt(left, k, block, true) and op = "<" + or + guard.ensuresLt(left, k, block, false) and op = ">=" + or + guard.ensuresEq(left, k, block, true) and op = "==" + or + guard.ensuresEq(left, k, block, false) and op = "!=" + | + block.hasLocationInfo(_, start, _, end, _) + ) +} diff --git a/cpp/ql/test/library-tests/controlflow/guards/test.c b/cpp/ql/test/library-tests/controlflow/guards/test.c index 186244d4fca2..207e23baa0e3 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/test.c +++ b/cpp/ql/test/library-tests/controlflow/guards/test.c @@ -147,3 +147,27 @@ void test5(int x) { test3(); } } + +void test6(char* p) { + if(p) { + + } +} + +void test7(char* p) { + if(!p) { + + } +} + +void test8(short s) { + if(s) { + + } +} + +void test9(short s) { + if(!s) { + + } +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/controlflow/guards/test.cpp b/cpp/ql/test/library-tests/controlflow/guards/test.cpp index 3a60f5f026e7..84d02ca4efa5 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/test.cpp +++ b/cpp/ql/test/library-tests/controlflow/guards/test.cpp @@ -85,4 +85,30 @@ void test_switches_default(int i) { default: use1(i); } -} \ No newline at end of file +} + +void use(...); + +void pointer_comparison(char* c) { + if(c) { + use(c); + } +} + +void implicit_float_comparison(float f) { + if(f) { + use(f); + } +} + +void explicit_float_comparison(float f) { + if(f != 0.0f) { + use(f); + } +} + +void int_float_comparison(int i) { + if(i != 0.0f) { + use(i); + } +} diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected index e03ee68b8a35..e8afa785492f 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected @@ -228,7 +228,6 @@ irFlow | test.cpp:333:17:333:22 | call to source | test.cpp:337:10:337:18 | globalVar | | test.cpp:333:17:333:22 | call to source | test.cpp:339:10:339:18 | globalVar | | test.cpp:333:17:333:22 | call to source | test.cpp:343:10:343:18 | globalVar | -| test.cpp:333:17:333:22 | call to source | test.cpp:349:10:349:18 | globalVar | | test.cpp:347:17:347:22 | call to source | test.cpp:337:10:337:18 | globalVar | | test.cpp:347:17:347:22 | call to source | test.cpp:339:10:339:18 | globalVar | | test.cpp:347:17:347:22 | call to source | test.cpp:343:10:343:18 | globalVar | @@ -260,7 +259,6 @@ irFlow | test.cpp:562:17:562:31 | *call to indirect_source | test.cpp:566:10:566:19 | * ... | | test.cpp:562:17:562:31 | *call to indirect_source | test.cpp:568:10:568:19 | * ... | | test.cpp:562:17:562:31 | *call to indirect_source | test.cpp:572:10:572:19 | * ... | -| test.cpp:562:17:562:31 | *call to indirect_source | test.cpp:578:10:578:19 | * ... | | test.cpp:576:17:576:31 | *call to indirect_source | test.cpp:566:10:566:19 | * ... | | test.cpp:576:17:576:31 | *call to indirect_source | test.cpp:568:10:568:19 | * ... | | test.cpp:576:17:576:31 | *call to indirect_source | test.cpp:572:10:572:19 | * ... | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp index af9e18034edd..c1c84c71e3bf 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp @@ -346,7 +346,7 @@ namespace FlowThroughGlobals { void taintAndCall() { globalVar = source(); calledAfterTaint(); - sink(globalVar); // $ ast ir=333:17 ir=347:17 + sink(globalVar); // $ ast ir } } @@ -575,7 +575,7 @@ namespace IndirectFlowThroughGlobals { void taintAndCall() { globalInt = indirect_source(); calledAfterTaint(); - sink(*globalInt); // $ ir=562:17 ir=576:17 MISSING: ast=562:17 ast=576:17 + sink(*globalInt); // $ ir MISSING: ast=562:17 ast=576:17 } } diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp index 7265cb175426..a39e06988065 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp @@ -66,8 +66,8 @@ class insert_iterator_by_trait { insert_iterator_by_trait operator++(int); insert_iterator_by_trait &operator--(); insert_iterator_by_trait operator--(int); - insert_iterator_by_trait operator*(); - insert_iterator_by_trait operator=(int x); + insert_iterator_by_trait& operator*(); + insert_iterator_by_trait& operator=(int x); }; template<> diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp index 179c5eb6b199..c26eef5176ce 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -389,7 +389,7 @@ void test_vector_output_iterator(int b) { *i9 = source(); taint_vector_output_iterator(i9); - sink(v9); // $ ast=330:10 MISSING: ir SPURIOUS: ast=389:8 + sink(v9); // $ ast=330:10 ir SPURIOUS: ast=389:8 std::vector::iterator i10 = v10.begin(); vector_iterator_assign_wrapper(i10, 10); @@ -440,14 +440,14 @@ void test_vector_inserter(char *source_string) { std::vector out; auto it = std::back_inserter(out); *++it = std::string(source_string); - sink(out); // $ ast MISSING: ir + sink(out); // $ ast,ir } { std::vector out; auto it = std::back_inserter(out); *++it = source(); - sink(out); // $ ast MISSING: ir + sink(out); // $ ast,ir } } diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 1f6a29b57ed6..d7b240c8949a 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -12159,8 +12159,12 @@ ir.cpp: # 1109| Type = [IntType] int # 1110| [Destructor] void std::vector::~vector() # 1110| : +# 1110| [Destructor] void std::vector::~vector() +# 1110| : # 1110| [Destructor] void std::vector::~vector() # 1110| : +# 1110| [Destructor] void std::vector::~vector() +# 1110| : # 1110| [Destructor] void std::vector::~vector() # 1110| : # 1115| [ConstMemberFunction] std::vector::iterator std::vector::begin() const @@ -19307,181 +19311,195 @@ ir.cpp: # 2193| getQualifier(): [ThisExpr] this # 2193| Type = [PointerType] ClassWithDestructor * # 2193| ValueCategory = prvalue(load) -# 2196| [GlobalVariable] bool initialization_with_destructor_bool -# 2196| getInitializer(): [Initializer] initializer for initialization_with_destructor_bool -# 2196| getExpr(): [Literal] 1 -# 2196| Type = [BoolType] bool -# 2196| Value = [Literal] 1 -# 2196| ValueCategory = prvalue -# 2198| [TopLevelFunction] void initialization_with_destructor(bool, char) -# 2198| : -# 2198| getParameter(0): [Parameter] b -# 2198| Type = [BoolType] bool -# 2198| getParameter(1): [Parameter] c -# 2198| Type = [PlainCharType] char -# 2198| getEntryPoint(): [BlockStmt] { ... } -# 2199| getStmt(0): [IfStmt] if (...) ... -# 2199| getInitialization(): [DeclStmt] declaration -# 2199| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2199| Type = [Class] ClassWithDestructor -# 2199| getVariable().getInitializer(): [Initializer] initializer for x -# 2199| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2199| Type = [VoidType] void -# 2199| ValueCategory = prvalue -# 2199| getCondition(): [VariableAccess] b -# 2199| Type = [BoolType] bool -# 2199| ValueCategory = prvalue(load) -# 2200| getThen(): [ExprStmt] ExprStmt -# 2200| getExpr(): [FunctionCall] call to set_x -# 2200| Type = [VoidType] void -# 2200| ValueCategory = prvalue -# 2200| getQualifier(): [VariableAccess] x -# 2200| Type = [Class] ClassWithDestructor -# 2200| ValueCategory = lvalue -# 2200| getArgument(0): [CharLiteral] 97 -# 2200| Type = [PlainCharType] char -# 2200| Value = [CharLiteral] 97 -# 2200| ValueCategory = prvalue -# 2200| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2200| Type = [VoidType] void -# 2200| ValueCategory = prvalue -# 2200| getQualifier(): [VariableAccess] x +# 2194| [ConstMemberFunction,ConversionOperator] bool ClassWithDestructor::operator bool() const +# 2194| : +# 2197| [GlobalVariable] bool initialization_with_destructor_bool +# 2197| getInitializer(): [Initializer] initializer for initialization_with_destructor_bool +# 2197| getExpr(): [Literal] 1 +# 2197| Type = [BoolType] bool +# 2197| Value = [Literal] 1 +# 2197| ValueCategory = prvalue +# 2199| [TopLevelFunction] void initialization_with_destructor(bool, char) +# 2199| : +# 2199| getParameter(0): [Parameter] b +# 2199| Type = [BoolType] bool +# 2199| getParameter(1): [Parameter] c +# 2199| Type = [PlainCharType] char +# 2199| getEntryPoint(): [BlockStmt] { ... } +# 2200| getStmt(0): [IfStmt] if (...) ... +# 2200| getInitialization(): [DeclStmt] declaration +# 2200| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x # 2200| Type = [Class] ClassWithDestructor -# 2200| ValueCategory = lvalue -# 2202| getStmt(1): [ConstexprIfStmt] if constexpr (...) ... -# 2202| getInitialization(): [DeclStmt] declaration -# 2202| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2202| Type = [Class] ClassWithDestructor -# 2202| getVariable().getInitializer(): [Initializer] initializer for x -# 2202| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2202| Type = [VoidType] void -# 2202| ValueCategory = prvalue -# 2202| getCondition(): [VariableAccess] initialization_with_destructor_bool -# 2202| Type = [BoolType] bool -# 2202| Value = [VariableAccess] 1 -# 2202| ValueCategory = prvalue(load) -# 2203| getThen(): [ExprStmt] ExprStmt -# 2203| getExpr(): [FunctionCall] call to set_x -# 2203| Type = [VoidType] void -# 2203| ValueCategory = prvalue -# 2203| getQualifier(): [VariableAccess] x -# 2203| Type = [Class] ClassWithDestructor -# 2203| ValueCategory = lvalue -# 2203| getArgument(0): [CharLiteral] 97 -# 2203| Type = [PlainCharType] char -# 2203| Value = [CharLiteral] 97 -# 2203| ValueCategory = prvalue -# 2203| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2203| Type = [VoidType] void -# 2203| ValueCategory = prvalue -# 2203| getQualifier(): [VariableAccess] x +# 2200| getVariable().getInitializer(): [Initializer] initializer for x +# 2200| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2200| Type = [VoidType] void +# 2200| ValueCategory = prvalue +# 2200| getCondition(): [VariableAccess] b +# 2200| Type = [BoolType] bool +# 2200| ValueCategory = prvalue(load) +# 2201| getThen(): [ExprStmt] ExprStmt +# 2201| getExpr(): [FunctionCall] call to set_x +# 2201| Type = [VoidType] void +# 2201| ValueCategory = prvalue +# 2201| getQualifier(): [VariableAccess] x +# 2201| Type = [Class] ClassWithDestructor +# 2201| ValueCategory = lvalue +# 2201| getArgument(0): [CharLiteral] 97 +# 2201| Type = [PlainCharType] char +# 2201| Value = [CharLiteral] 97 +# 2201| ValueCategory = prvalue +# 2201| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2201| Type = [VoidType] void +# 2201| ValueCategory = prvalue +# 2201| getQualifier(): [VariableAccess] x +# 2201| Type = [Class] ClassWithDestructor +# 2201| ValueCategory = lvalue +# 2203| getStmt(1): [ConstexprIfStmt] if constexpr (...) ... +# 2203| getInitialization(): [DeclStmt] declaration +# 2203| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x # 2203| Type = [Class] ClassWithDestructor -# 2203| ValueCategory = lvalue -# 2205| getStmt(2): [SwitchStmt] switch (...) ... -# 2205| getInitialization(): [DeclStmt] declaration -# 2205| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2205| Type = [Class] ClassWithDestructor -# 2205| getVariable().getInitializer(): [Initializer] initializer for x -# 2205| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2205| Type = [VoidType] void -# 2205| ValueCategory = prvalue -# 2205| getExpr(): [VariableAccess] c -# 2205| Type = [PlainCharType] char -# 2205| ValueCategory = prvalue(load) -# 2205| getStmt(): [BlockStmt] { ... } -# 2206| getStmt(0): [SwitchCase] case ...: -# 2206| getExpr(): [CharLiteral] 97 -# 2206| Type = [PlainCharType] char -# 2206| Value = [CharLiteral] 97 -# 2206| ValueCategory = prvalue -# 2206| getExpr().getFullyConverted(): [CStyleCast] (int)... -# 2206| Conversion = [IntegralConversion] integral conversion -# 2206| Type = [IntType] int -# 2206| Value = [CStyleCast] 97 -# 2206| ValueCategory = prvalue -# 2207| getStmt(1): [ExprStmt] ExprStmt -# 2207| getExpr(): [FunctionCall] call to set_x -# 2207| Type = [VoidType] void +# 2203| getVariable().getInitializer(): [Initializer] initializer for x +# 2203| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2203| Type = [VoidType] void +# 2203| ValueCategory = prvalue +# 2203| getCondition(): [VariableAccess] initialization_with_destructor_bool +# 2203| Type = [BoolType] bool +# 2203| Value = [VariableAccess] 1 +# 2203| ValueCategory = prvalue(load) +# 2204| getThen(): [ExprStmt] ExprStmt +# 2204| getExpr(): [FunctionCall] call to set_x +# 2204| Type = [VoidType] void +# 2204| ValueCategory = prvalue +# 2204| getQualifier(): [VariableAccess] x +# 2204| Type = [Class] ClassWithDestructor +# 2204| ValueCategory = lvalue +# 2204| getArgument(0): [CharLiteral] 97 +# 2204| Type = [PlainCharType] char +# 2204| Value = [CharLiteral] 97 +# 2204| ValueCategory = prvalue +# 2204| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2204| Type = [VoidType] void +# 2204| ValueCategory = prvalue +# 2204| getQualifier(): [VariableAccess] x +# 2204| Type = [Class] ClassWithDestructor +# 2204| ValueCategory = lvalue +# 2206| getStmt(2): [SwitchStmt] switch (...) ... +# 2206| getInitialization(): [DeclStmt] declaration +# 2206| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2206| Type = [Class] ClassWithDestructor +# 2206| getVariable().getInitializer(): [Initializer] initializer for x +# 2206| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2206| Type = [VoidType] void +# 2206| ValueCategory = prvalue +# 2206| getExpr(): [VariableAccess] c +# 2206| Type = [PlainCharType] char +# 2206| ValueCategory = prvalue(load) +# 2206| getStmt(): [BlockStmt] { ... } +# 2207| getStmt(0): [SwitchCase] case ...: +# 2207| getExpr(): [CharLiteral] 97 +# 2207| Type = [PlainCharType] char +# 2207| Value = [CharLiteral] 97 +# 2207| ValueCategory = prvalue +# 2207| getExpr().getFullyConverted(): [CStyleCast] (int)... +# 2207| Conversion = [IntegralConversion] integral conversion +# 2207| Type = [IntType] int +# 2207| Value = [CStyleCast] 97 # 2207| ValueCategory = prvalue -# 2207| getQualifier(): [VariableAccess] x -# 2207| Type = [Class] ClassWithDestructor -# 2207| ValueCategory = lvalue -# 2207| getArgument(0): [CharLiteral] 97 -# 2207| Type = [PlainCharType] char -# 2207| Value = [CharLiteral] 97 -# 2207| ValueCategory = prvalue -# 2208| getStmt(2): [BreakStmt] break; -# 2209| getStmt(3): [SwitchCase] default: -# 2210| getStmt(4): [ExprStmt] ExprStmt -# 2210| getExpr(): [FunctionCall] call to set_x -# 2210| Type = [VoidType] void -# 2210| ValueCategory = prvalue -# 2210| getQualifier(): [VariableAccess] x -# 2210| Type = [Class] ClassWithDestructor -# 2210| ValueCategory = lvalue -# 2210| getArgument(0): [CharLiteral] 98 -# 2210| Type = [PlainCharType] char -# 2210| Value = [CharLiteral] 98 -# 2210| ValueCategory = prvalue -# 2211| getStmt(5): [BreakStmt] break; -# 2212| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2212| Type = [VoidType] void -# 2212| ValueCategory = prvalue -# 2212| getQualifier(): [VariableAccess] x -# 2212| Type = [Class] ClassWithDestructor -# 2212| ValueCategory = lvalue -# 2205| getExpr().getFullyConverted(): [CStyleCast] (int)... -# 2205| Conversion = [IntegralConversion] integral conversion -# 2205| Type = [IntType] int -# 2205| ValueCategory = prvalue -# 2212| getStmt(3): [LabelStmt] label ...: -# 2214| getStmt(4): [DeclStmt] declaration -# 2214| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2214| Type = [Class] ClassWithDestructor -# 2214| getVariable().getInitializer(): [Initializer] initializer for x -# 2214| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2214| Type = [VoidType] void -# 2214| ValueCategory = prvalue -# 2215| getStmt(5): [RangeBasedForStmt] for(...:...) ... -# 2215| getInitialization(): [DeclStmt] declaration -# 2215| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys -# 2215| Type = [ClassTemplateInstantiation,Struct] vector -# 2215| getVariable().getInitializer(): [Initializer] initializer for ys -# 2215| getExpr(): [ConstructorCall] call to vector -# 2215| Type = [VoidType] void -# 2215| ValueCategory = prvalue -# 2215| getArgument(0): [VariableAccess] x -# 2215| Type = [Class] ClassWithDestructor -# 2215| ValueCategory = prvalue(load) -# 2215| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2215| Type = [VoidType] void -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [ReuseExpr] reuse of temporary object -# 2215| Type = [Class] ClassWithDestructor -# 2215| ValueCategory = xvalue -# 2215| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2215| Type = [Class] ClassWithDestructor -# 2215| ValueCategory = lvalue -# 2215| getChild(1): [DeclStmt] declaration -# 2215| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) -# 2215| Type = [LValueReferenceType] vector & +# 2208| getStmt(1): [ExprStmt] ExprStmt +# 2208| getExpr(): [FunctionCall] call to set_x +# 2208| Type = [VoidType] void +# 2208| ValueCategory = prvalue +# 2208| getQualifier(): [VariableAccess] x +# 2208| Type = [Class] ClassWithDestructor +# 2208| ValueCategory = lvalue +# 2208| getArgument(0): [CharLiteral] 97 +# 2208| Type = [PlainCharType] char +# 2208| Value = [CharLiteral] 97 +# 2208| ValueCategory = prvalue +# 2209| getStmt(2): [BreakStmt] break; +# 2213| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2213| Type = [VoidType] void +# 2213| ValueCategory = prvalue +# 2213| getQualifier(): [VariableAccess] x +# 2213| Type = [Class] ClassWithDestructor +# 2213| ValueCategory = lvalue +# 2210| getStmt(3): [SwitchCase] default: +# 2211| getStmt(4): [ExprStmt] ExprStmt +# 2211| getExpr(): [FunctionCall] call to set_x +# 2211| Type = [VoidType] void +# 2211| ValueCategory = prvalue +# 2211| getQualifier(): [VariableAccess] x +# 2211| Type = [Class] ClassWithDestructor +# 2211| ValueCategory = lvalue +# 2211| getArgument(0): [CharLiteral] 98 +# 2211| Type = [PlainCharType] char +# 2211| Value = [CharLiteral] 98 +# 2211| ValueCategory = prvalue +# 2212| getStmt(5): [BreakStmt] break; +# 2213| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2213| Type = [VoidType] void +# 2213| ValueCategory = prvalue +# 2213| getQualifier(): [VariableAccess] x +# 2213| Type = [Class] ClassWithDestructor +# 2213| ValueCategory = lvalue +# 2213| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2213| Type = [VoidType] void +# 2213| ValueCategory = prvalue +# 2213| getQualifier(): [VariableAccess] x +# 2213| Type = [Class] ClassWithDestructor +# 2213| ValueCategory = lvalue +# 2206| getExpr().getFullyConverted(): [CStyleCast] (int)... +# 2206| Conversion = [IntegralConversion] integral conversion +# 2206| Type = [IntType] int +# 2206| ValueCategory = prvalue +# 2213| getStmt(3): [LabelStmt] label ...: +# 2215| getStmt(4): [DeclStmt] declaration +# 2215| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2215| Type = [Class] ClassWithDestructor +# 2215| getVariable().getInitializer(): [Initializer] initializer for x +# 2215| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2215| Type = [VoidType] void +# 2215| ValueCategory = prvalue +# 2216| getStmt(5): [RangeBasedForStmt] for(...:...) ... +# 2216| getInitialization(): [DeclStmt] declaration +# 2216| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys +# 2216| Type = [ClassTemplateInstantiation,Struct] vector +# 2216| getVariable().getInitializer(): [Initializer] initializer for ys +# 2216| getExpr(): [ConstructorCall] call to vector +# 2216| Type = [VoidType] void +# 2216| ValueCategory = prvalue +# 2216| getArgument(0): [VariableAccess] x +# 2216| Type = [Class] ClassWithDestructor +# 2216| ValueCategory = prvalue(load) +# 2216| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2216| Type = [VoidType] void +# 2216| ValueCategory = prvalue +# 2216| getQualifier(): [ReuseExpr] reuse of temporary object +# 2216| Type = [Class] ClassWithDestructor +# 2216| ValueCategory = xvalue +# 2216| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2216| Type = [Class] ClassWithDestructor +# 2216| ValueCategory = lvalue +# 2216| getChild(1): [DeclStmt] declaration +# 2216| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) +# 2216| Type = [LValueReferenceType] vector & #-----| getVariable().getInitializer(): [Initializer] initializer for (__range) -# 2215| getExpr(): [VariableAccess] ys -# 2215| Type = [ClassTemplateInstantiation,Struct] vector -# 2215| ValueCategory = lvalue -# 2215| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2215| Type = [LValueReferenceType] vector & -# 2215| ValueCategory = prvalue -# 2215| getBeginEndDeclaration(): [DeclStmt] declaration -# 2215| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| getExpr(): [VariableAccess] ys +# 2216| Type = [ClassTemplateInstantiation,Struct] vector +# 2216| ValueCategory = lvalue +# 2216| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2216| Type = [LValueReferenceType] vector & +# 2216| ValueCategory = prvalue +# 2216| getBeginEndDeclaration(): [DeclStmt] declaration +# 2216| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__begin) -# 2215| getExpr(): [FunctionCall] call to begin -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] (__range) -# 2215| Type = [LValueReferenceType] vector & -# 2215| ValueCategory = prvalue(load) +# 2216| getExpr(): [FunctionCall] call to begin +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| ValueCategory = prvalue +# 2216| getQualifier(): [VariableAccess] (__range) +# 2216| Type = [LValueReferenceType] vector & +# 2216| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19489,15 +19507,15 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2215| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__end) -# 2215| getExpr(): [FunctionCall] call to end -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] (__range) -# 2215| Type = [LValueReferenceType] vector & -# 2215| ValueCategory = prvalue(load) +# 2216| getExpr(): [FunctionCall] call to end +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| ValueCategory = prvalue +# 2216| getQualifier(): [VariableAccess] (__range) +# 2216| Type = [LValueReferenceType] vector & +# 2216| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19505,18 +19523,18 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2215| getCondition(): [FunctionCall] call to operator!= -# 2215| Type = [BoolType] bool -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] (__begin) -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2215| ValueCategory = lvalue -# 2215| getArgument(0): [ConstructorCall] call to iterator -# 2215| Type = [VoidType] void -# 2215| ValueCategory = prvalue -# 2215| getArgument(0): [VariableAccess] (__end) -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2215| ValueCategory = lvalue +# 2216| getCondition(): [FunctionCall] call to operator!= +# 2216| Type = [BoolType] bool +# 2216| ValueCategory = prvalue +# 2216| getQualifier(): [VariableAccess] (__begin) +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| ValueCategory = lvalue +# 2216| getArgument(0): [ConstructorCall] call to iterator +# 2216| Type = [VoidType] void +# 2216| ValueCategory = prvalue +# 2216| getArgument(0): [VariableAccess] (__end) +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| ValueCategory = lvalue #-----| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) #-----| Type = [LValueReferenceType] const iterator & #-----| ValueCategory = prvalue @@ -19531,95 +19549,95 @@ ir.cpp: #-----| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object #-----| Type = [ClassTemplateInstantiation,Struct] iterator #-----| ValueCategory = lvalue -# 2215| getUpdate(): [FunctionCall] call to operator++ -# 2215| Type = [LValueReferenceType] iterator & -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] (__begin) -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2215| ValueCategory = lvalue -# 2215| getChild(5): [DeclStmt] declaration -# 2215| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y -# 2215| Type = [Class] ClassWithDestructor -# 2215| getVariable().getInitializer(): [Initializer] initializer for y -# 2215| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* -# 2215| Type = [LValueReferenceType] ClassWithDestructor & -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] (__begin) -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2215| ValueCategory = lvalue +# 2216| getUpdate(): [FunctionCall] call to operator++ +# 2216| Type = [LValueReferenceType] iterator & +# 2216| ValueCategory = prvalue +# 2216| getQualifier(): [VariableAccess] (__begin) +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| ValueCategory = lvalue +# 2216| getChild(5): [DeclStmt] declaration +# 2216| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2216| Type = [Class] ClassWithDestructor +# 2216| getVariable().getInitializer(): [Initializer] initializer for y +# 2216| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* +# 2216| Type = [LValueReferenceType] ClassWithDestructor & +# 2216| ValueCategory = prvalue +# 2216| getQualifier(): [VariableAccess] (__begin) +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| ValueCategory = lvalue #-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const iterator #-----| ValueCategory = lvalue -# 2215| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2215| Type = [Class] ClassWithDestructor -# 2215| ValueCategory = prvalue(load) -# 2216| getStmt(): [ExprStmt] ExprStmt -# 2216| getExpr(): [FunctionCall] call to set_x +# 2216| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2216| Type = [Class] ClassWithDestructor +# 2216| ValueCategory = prvalue(load) +# 2217| getStmt(): [ExprStmt] ExprStmt +# 2217| getExpr(): [FunctionCall] call to set_x +# 2217| Type = [VoidType] void +# 2217| ValueCategory = prvalue +# 2217| getQualifier(): [VariableAccess] y +# 2217| Type = [Class] ClassWithDestructor +# 2217| ValueCategory = lvalue +# 2217| getArgument(0): [CharLiteral] 97 +# 2217| Type = [PlainCharType] char +# 2217| Value = [CharLiteral] 97 +# 2217| ValueCategory = prvalue +# 2216| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2216| Type = [VoidType] void +# 2216| ValueCategory = prvalue +# 2216| getQualifier(): [VariableAccess] ys +# 2216| Type = [ClassTemplateInstantiation,Struct] vector +# 2216| ValueCategory = lvalue +# 2216| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2216| Type = [ClassTemplateInstantiation,Struct] iterator +# 2216| ValueCategory = lvalue +# 2216| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor # 2216| Type = [VoidType] void # 2216| ValueCategory = prvalue # 2216| getQualifier(): [VariableAccess] y # 2216| Type = [Class] ClassWithDestructor # 2216| ValueCategory = lvalue -# 2216| getArgument(0): [CharLiteral] 97 -# 2216| Type = [PlainCharType] char -# 2216| Value = [CharLiteral] 97 -# 2216| ValueCategory = prvalue -# 2215| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2215| Type = [VoidType] void -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] y -# 2215| Type = [Class] ClassWithDestructor -# 2215| ValueCategory = lvalue -# 2215| getImplicitDestructorCall(0): [DestructorCall] call to ~vector -# 2215| Type = [VoidType] void -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] ys -# 2215| Type = [ClassTemplateInstantiation,Struct] vector -# 2215| ValueCategory = lvalue -# 2215| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2215| Type = [ClassTemplateInstantiation,Struct] iterator -# 2215| ValueCategory = lvalue -# 2218| getStmt(6): [RangeBasedForStmt] for(...:...) ... -# 2218| getInitialization(): [DeclStmt] declaration -# 2218| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys -# 2218| Type = [ClassTemplateInstantiation,Struct] vector -# 2218| getVariable().getInitializer(): [Initializer] initializer for ys -# 2218| getExpr(): [ConstructorCall] call to vector -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getArgument(0): [VariableAccess] x -# 2218| Type = [Class] ClassWithDestructor -# 2218| ValueCategory = prvalue(load) -# 2218| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [ReuseExpr] reuse of temporary object -# 2218| Type = [Class] ClassWithDestructor -# 2218| ValueCategory = xvalue -# 2218| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2218| Type = [Class] ClassWithDestructor -# 2218| ValueCategory = lvalue -# 2218| getChild(1): [DeclStmt] declaration -# 2218| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) -# 2218| Type = [LValueReferenceType] vector & +# 2219| getStmt(6): [RangeBasedForStmt] for(...:...) ... +# 2219| getInitialization(): [DeclStmt] declaration +# 2219| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys +# 2219| Type = [ClassTemplateInstantiation,Struct] vector +# 2219| getVariable().getInitializer(): [Initializer] initializer for ys +# 2219| getExpr(): [ConstructorCall] call to vector +# 2219| Type = [VoidType] void +# 2219| ValueCategory = prvalue +# 2219| getArgument(0): [VariableAccess] x +# 2219| Type = [Class] ClassWithDestructor +# 2219| ValueCategory = prvalue(load) +# 2219| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2219| Type = [VoidType] void +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [ReuseExpr] reuse of temporary object +# 2219| Type = [Class] ClassWithDestructor +# 2219| ValueCategory = xvalue +# 2219| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2219| Type = [Class] ClassWithDestructor +# 2219| ValueCategory = lvalue +# 2219| getChild(1): [DeclStmt] declaration +# 2219| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) +# 2219| Type = [LValueReferenceType] vector & #-----| getVariable().getInitializer(): [Initializer] initializer for (__range) -# 2218| getExpr(): [VariableAccess] ys -# 2218| Type = [ClassTemplateInstantiation,Struct] vector -# 2218| ValueCategory = lvalue -# 2218| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2218| Type = [LValueReferenceType] vector & -# 2218| ValueCategory = prvalue -# 2218| getBeginEndDeclaration(): [DeclStmt] declaration -# 2218| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| getExpr(): [VariableAccess] ys +# 2219| Type = [ClassTemplateInstantiation,Struct] vector +# 2219| ValueCategory = lvalue +# 2219| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2219| Type = [LValueReferenceType] vector & +# 2219| ValueCategory = prvalue +# 2219| getBeginEndDeclaration(): [DeclStmt] declaration +# 2219| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__begin) -# 2218| getExpr(): [FunctionCall] call to begin -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] (__range) -# 2218| Type = [LValueReferenceType] vector & -# 2218| ValueCategory = prvalue(load) +# 2219| getExpr(): [FunctionCall] call to begin +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] (__range) +# 2219| Type = [LValueReferenceType] vector & +# 2219| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19627,15 +19645,15 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2218| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__end) -# 2218| getExpr(): [FunctionCall] call to end -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] (__range) -# 2218| Type = [LValueReferenceType] vector & -# 2218| ValueCategory = prvalue(load) +# 2219| getExpr(): [FunctionCall] call to end +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] (__range) +# 2219| Type = [LValueReferenceType] vector & +# 2219| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19643,18 +19661,18 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2218| getCondition(): [FunctionCall] call to operator!= -# 2218| Type = [BoolType] bool -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] (__begin) -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2218| ValueCategory = lvalue -# 2218| getArgument(0): [ConstructorCall] call to iterator -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getArgument(0): [VariableAccess] (__end) -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2218| ValueCategory = lvalue +# 2219| getCondition(): [FunctionCall] call to operator!= +# 2219| Type = [BoolType] bool +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] (__begin) +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| ValueCategory = lvalue +# 2219| getArgument(0): [ConstructorCall] call to iterator +# 2219| Type = [VoidType] void +# 2219| ValueCategory = prvalue +# 2219| getArgument(0): [VariableAccess] (__end) +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| ValueCategory = lvalue #-----| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) #-----| Type = [LValueReferenceType] const iterator & #-----| ValueCategory = prvalue @@ -19669,130 +19687,130 @@ ir.cpp: #-----| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object #-----| Type = [ClassTemplateInstantiation,Struct] iterator #-----| ValueCategory = lvalue -# 2218| getUpdate(): [FunctionCall] call to operator++ -# 2218| Type = [LValueReferenceType] iterator & -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] (__begin) -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2218| ValueCategory = lvalue -# 2218| getChild(5): [DeclStmt] declaration -# 2218| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y -# 2218| Type = [Class] ClassWithDestructor -# 2218| getVariable().getInitializer(): [Initializer] initializer for y -# 2218| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* -# 2218| Type = [LValueReferenceType] ClassWithDestructor & -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] (__begin) -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2218| ValueCategory = lvalue +# 2219| getUpdate(): [FunctionCall] call to operator++ +# 2219| Type = [LValueReferenceType] iterator & +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] (__begin) +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| ValueCategory = lvalue +# 2219| getChild(5): [DeclStmt] declaration +# 2219| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2219| Type = [Class] ClassWithDestructor +# 2219| getVariable().getInitializer(): [Initializer] initializer for y +# 2219| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* +# 2219| Type = [LValueReferenceType] ClassWithDestructor & +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] (__begin) +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| ValueCategory = lvalue #-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const iterator #-----| ValueCategory = lvalue -# 2218| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2218| Type = [Class] ClassWithDestructor -# 2218| ValueCategory = prvalue(load) -# 2218| getStmt(): [BlockStmt] { ... } -# 2219| getStmt(0): [ExprStmt] ExprStmt -# 2219| getExpr(): [FunctionCall] call to set_x -# 2219| Type = [VoidType] void -# 2219| ValueCategory = prvalue -# 2219| getQualifier(): [VariableAccess] y +# 2219| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) # 2219| Type = [Class] ClassWithDestructor -# 2219| ValueCategory = lvalue -# 2219| getArgument(0): [CharLiteral] 97 -# 2219| Type = [PlainCharType] char -# 2219| Value = [CharLiteral] 97 -# 2219| ValueCategory = prvalue -# 2220| getStmt(1): [IfStmt] if (...) ... -# 2220| getCondition(): [EQExpr] ... == ... -# 2220| Type = [BoolType] bool +# 2219| ValueCategory = prvalue(load) +# 2219| getStmt(): [BlockStmt] { ... } +# 2220| getStmt(0): [ExprStmt] ExprStmt +# 2220| getExpr(): [FunctionCall] call to set_x +# 2220| Type = [VoidType] void # 2220| ValueCategory = prvalue -# 2220| getLeftOperand(): [FunctionCall] call to get_x +# 2220| getQualifier(): [VariableAccess] y +# 2220| Type = [Class] ClassWithDestructor +# 2220| ValueCategory = lvalue +# 2220| getArgument(0): [CharLiteral] 97 # 2220| Type = [PlainCharType] char +# 2220| Value = [CharLiteral] 97 # 2220| ValueCategory = prvalue -# 2220| getQualifier(): [VariableAccess] y -# 2220| Type = [Class] ClassWithDestructor -# 2220| ValueCategory = lvalue -# 2220| getRightOperand(): [CharLiteral] 98 -# 2220| Type = [PlainCharType] char -# 2220| Value = [CharLiteral] 98 -# 2220| ValueCategory = prvalue -# 2220| getLeftOperand().getFullyConverted(): [CStyleCast] (int)... -# 2220| Conversion = [IntegralConversion] integral conversion -# 2220| Type = [IntType] int -# 2220| ValueCategory = prvalue -# 2220| getRightOperand().getFullyConverted(): [CStyleCast] (int)... -# 2220| Conversion = [IntegralConversion] integral conversion -# 2220| Type = [IntType] int -# 2220| Value = [CStyleCast] 98 -# 2220| ValueCategory = prvalue -# 2221| getThen(): [ReturnStmt] return ... -# 2218| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] y -# 2218| Type = [Class] ClassWithDestructor -# 2218| ValueCategory = lvalue -# 2218| getImplicitDestructorCall(1): [DestructorCall] call to ~vector -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] ys -# 2218| Type = [ClassTemplateInstantiation,Struct] vector -# 2218| ValueCategory = lvalue -# 2233| getImplicitDestructorCall(2): [DestructorCall] call to ~ClassWithDestructor -# 2233| Type = [VoidType] void -# 2233| ValueCategory = prvalue -# 2233| getQualifier(): [VariableAccess] x -# 2233| Type = [Class] ClassWithDestructor -# 2233| ValueCategory = lvalue -# 2218| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] y -# 2218| Type = [Class] ClassWithDestructor -# 2218| ValueCategory = lvalue -# 2218| getImplicitDestructorCall(0): [DestructorCall] call to ~vector -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] ys -# 2218| Type = [ClassTemplateInstantiation,Struct] vector -# 2218| ValueCategory = lvalue -# 2218| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2218| Type = [ClassTemplateInstantiation,Struct] iterator -# 2218| ValueCategory = lvalue -# 2224| getStmt(7): [RangeBasedForStmt] for(...:...) ... -# 2224| getInitialization(): [DeclStmt] declaration -# 2224| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys -# 2224| Type = [ClassTemplateInstantiation,Struct] vector -# 2224| getVariable().getInitializer(): [Initializer] initializer for ys -# 2224| getExpr(): [ConstructorCall] call to vector -# 2224| Type = [VoidType] void -# 2224| ValueCategory = prvalue -# 2224| getArgument(0): [Literal] 1 -# 2224| Type = [IntType] int -# 2224| Value = [Literal] 1 -# 2224| ValueCategory = prvalue -# 2224| getChild(1): [DeclStmt] declaration -# 2224| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) -# 2224| Type = [LValueReferenceType] vector & +# 2221| getStmt(1): [IfStmt] if (...) ... +# 2221| getCondition(): [EQExpr] ... == ... +# 2221| Type = [BoolType] bool +# 2221| ValueCategory = prvalue +# 2221| getLeftOperand(): [FunctionCall] call to get_x +# 2221| Type = [PlainCharType] char +# 2221| ValueCategory = prvalue +# 2221| getQualifier(): [VariableAccess] y +# 2221| Type = [Class] ClassWithDestructor +# 2221| ValueCategory = lvalue +# 2221| getRightOperand(): [CharLiteral] 98 +# 2221| Type = [PlainCharType] char +# 2221| Value = [CharLiteral] 98 +# 2221| ValueCategory = prvalue +# 2221| getLeftOperand().getFullyConverted(): [CStyleCast] (int)... +# 2221| Conversion = [IntegralConversion] integral conversion +# 2221| Type = [IntType] int +# 2221| ValueCategory = prvalue +# 2221| getRightOperand().getFullyConverted(): [CStyleCast] (int)... +# 2221| Conversion = [IntegralConversion] integral conversion +# 2221| Type = [IntType] int +# 2221| Value = [CStyleCast] 98 +# 2221| ValueCategory = prvalue +# 2222| getThen(): [ReturnStmt] return ... +# 2219| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2219| Type = [VoidType] void +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] y +# 2219| Type = [Class] ClassWithDestructor +# 2219| ValueCategory = lvalue +# 2219| getImplicitDestructorCall(1): [DestructorCall] call to ~vector +# 2219| Type = [VoidType] void +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] ys +# 2219| Type = [ClassTemplateInstantiation,Struct] vector +# 2219| ValueCategory = lvalue +# 2234| getImplicitDestructorCall(2): [DestructorCall] call to ~ClassWithDestructor +# 2234| Type = [VoidType] void +# 2234| ValueCategory = prvalue +# 2234| getQualifier(): [VariableAccess] x +# 2234| Type = [Class] ClassWithDestructor +# 2234| ValueCategory = lvalue +# 2219| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2219| Type = [VoidType] void +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] ys +# 2219| Type = [ClassTemplateInstantiation,Struct] vector +# 2219| ValueCategory = lvalue +# 2219| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2219| Type = [ClassTemplateInstantiation,Struct] iterator +# 2219| ValueCategory = lvalue +# 2219| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2219| Type = [VoidType] void +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] y +# 2219| Type = [Class] ClassWithDestructor +# 2219| ValueCategory = lvalue +# 2225| getStmt(7): [RangeBasedForStmt] for(...:...) ... +# 2225| getInitialization(): [DeclStmt] declaration +# 2225| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys +# 2225| Type = [ClassTemplateInstantiation,Struct] vector +# 2225| getVariable().getInitializer(): [Initializer] initializer for ys +# 2225| getExpr(): [ConstructorCall] call to vector +# 2225| Type = [VoidType] void +# 2225| ValueCategory = prvalue +# 2225| getArgument(0): [Literal] 1 +# 2225| Type = [IntType] int +# 2225| Value = [Literal] 1 +# 2225| ValueCategory = prvalue +# 2225| getChild(1): [DeclStmt] declaration +# 2225| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) +# 2225| Type = [LValueReferenceType] vector & #-----| getVariable().getInitializer(): [Initializer] initializer for (__range) -# 2224| getExpr(): [VariableAccess] ys -# 2224| Type = [ClassTemplateInstantiation,Struct] vector -# 2224| ValueCategory = lvalue -# 2224| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2224| Type = [LValueReferenceType] vector & -# 2224| ValueCategory = prvalue -# 2224| getBeginEndDeclaration(): [DeclStmt] declaration -# 2224| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| getExpr(): [VariableAccess] ys +# 2225| Type = [ClassTemplateInstantiation,Struct] vector +# 2225| ValueCategory = lvalue +# 2225| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2225| Type = [LValueReferenceType] vector & +# 2225| ValueCategory = prvalue +# 2225| getBeginEndDeclaration(): [DeclStmt] declaration +# 2225| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__begin) -# 2224| getExpr(): [FunctionCall] call to begin -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2224| ValueCategory = prvalue -# 2224| getQualifier(): [VariableAccess] (__range) -# 2224| Type = [LValueReferenceType] vector & -# 2224| ValueCategory = prvalue(load) +# 2225| getExpr(): [FunctionCall] call to begin +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| ValueCategory = prvalue +# 2225| getQualifier(): [VariableAccess] (__range) +# 2225| Type = [LValueReferenceType] vector & +# 2225| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19800,15 +19818,15 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2224| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__end) -# 2224| getExpr(): [FunctionCall] call to end -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2224| ValueCategory = prvalue -# 2224| getQualifier(): [VariableAccess] (__range) -# 2224| Type = [LValueReferenceType] vector & -# 2224| ValueCategory = prvalue(load) +# 2225| getExpr(): [FunctionCall] call to end +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| ValueCategory = prvalue +# 2225| getQualifier(): [VariableAccess] (__range) +# 2225| Type = [LValueReferenceType] vector & +# 2225| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19816,18 +19834,18 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2224| getCondition(): [FunctionCall] call to operator!= -# 2224| Type = [BoolType] bool -# 2224| ValueCategory = prvalue -# 2224| getQualifier(): [VariableAccess] (__begin) -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2224| ValueCategory = lvalue -# 2224| getArgument(0): [ConstructorCall] call to iterator -# 2224| Type = [VoidType] void -# 2224| ValueCategory = prvalue -# 2224| getArgument(0): [VariableAccess] (__end) -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2224| ValueCategory = lvalue +# 2225| getCondition(): [FunctionCall] call to operator!= +# 2225| Type = [BoolType] bool +# 2225| ValueCategory = prvalue +# 2225| getQualifier(): [VariableAccess] (__begin) +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| ValueCategory = lvalue +# 2225| getArgument(0): [ConstructorCall] call to iterator +# 2225| Type = [VoidType] void +# 2225| ValueCategory = prvalue +# 2225| getArgument(0): [VariableAccess] (__end) +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| ValueCategory = lvalue #-----| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) #-----| Type = [LValueReferenceType] const iterator & #-----| ValueCategory = prvalue @@ -19842,103 +19860,103 @@ ir.cpp: #-----| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object #-----| Type = [ClassTemplateInstantiation,Struct] iterator #-----| ValueCategory = lvalue -# 2224| getUpdate(): [FunctionCall] call to operator++ -# 2224| Type = [LValueReferenceType] iterator & -# 2224| ValueCategory = prvalue -# 2224| getQualifier(): [VariableAccess] (__begin) -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2224| ValueCategory = lvalue -# 2224| getChild(5): [DeclStmt] declaration -# 2224| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y -# 2224| Type = [IntType] int -# 2224| getVariable().getInitializer(): [Initializer] initializer for y -# 2224| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* -# 2224| Type = [LValueReferenceType] int & -# 2224| ValueCategory = prvalue -# 2224| getQualifier(): [VariableAccess] (__begin) -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2224| ValueCategory = lvalue +# 2225| getUpdate(): [FunctionCall] call to operator++ +# 2225| Type = [LValueReferenceType] iterator & +# 2225| ValueCategory = prvalue +# 2225| getQualifier(): [VariableAccess] (__begin) +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| ValueCategory = lvalue +# 2225| getChild(5): [DeclStmt] declaration +# 2225| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2225| Type = [IntType] int +# 2225| getVariable().getInitializer(): [Initializer] initializer for y +# 2225| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* +# 2225| Type = [LValueReferenceType] int & +# 2225| ValueCategory = prvalue +# 2225| getQualifier(): [VariableAccess] (__begin) +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| ValueCategory = lvalue #-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const iterator #-----| ValueCategory = lvalue -# 2224| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2224| Type = [IntType] int -# 2224| ValueCategory = prvalue(load) -# 2224| getStmt(): [BlockStmt] { ... } -# 2225| getStmt(0): [IfStmt] if (...) ... -# 2225| getCondition(): [EQExpr] ... == ... -# 2225| Type = [BoolType] bool -# 2225| ValueCategory = prvalue -# 2225| getLeftOperand(): [VariableAccess] y +# 2225| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) # 2225| Type = [IntType] int # 2225| ValueCategory = prvalue(load) -# 2225| getRightOperand(): [Literal] 1 -# 2225| Type = [IntType] int -# 2225| Value = [Literal] 1 +# 2225| getStmt(): [BlockStmt] { ... } +# 2226| getStmt(0): [IfStmt] if (...) ... +# 2226| getCondition(): [EQExpr] ... == ... +# 2226| Type = [BoolType] bool +# 2226| ValueCategory = prvalue +# 2226| getLeftOperand(): [VariableAccess] y +# 2226| Type = [IntType] int +# 2226| ValueCategory = prvalue(load) +# 2226| getRightOperand(): [Literal] 1 +# 2226| Type = [IntType] int +# 2226| Value = [Literal] 1 +# 2226| ValueCategory = prvalue +# 2227| getThen(): [ReturnStmt] return ... +# 2225| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2225| Type = [VoidType] void # 2225| ValueCategory = prvalue -# 2226| getThen(): [ReturnStmt] return ... -# 2224| getImplicitDestructorCall(0): [DestructorCall] call to ~vector -# 2224| Type = [VoidType] void -# 2224| ValueCategory = prvalue -# 2224| getQualifier(): [VariableAccess] ys -# 2224| Type = [ClassTemplateInstantiation,Struct] vector -# 2224| ValueCategory = lvalue -# 2233| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor -# 2233| Type = [VoidType] void -# 2233| ValueCategory = prvalue -# 2233| getQualifier(): [VariableAccess] x -# 2233| Type = [Class] ClassWithDestructor -# 2233| ValueCategory = lvalue -# 2224| getImplicitDestructorCall(0): [DestructorCall] call to ~vector -# 2224| Type = [VoidType] void -# 2224| ValueCategory = prvalue -# 2224| getQualifier(): [VariableAccess] ys -# 2224| Type = [ClassTemplateInstantiation,Struct] vector -# 2224| ValueCategory = lvalue -# 2224| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2224| Type = [ClassTemplateInstantiation,Struct] iterator -# 2224| ValueCategory = lvalue -# 2229| getStmt(8): [RangeBasedForStmt] for(...:...) ... -# 2229| getInitialization(): [DeclStmt] declaration -# 2229| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys -# 2229| Type = [ClassTemplateInstantiation,Struct] vector -# 2229| getVariable().getInitializer(): [Initializer] initializer for ys -# 2229| getExpr(): [ConstructorCall] call to vector -# 2229| Type = [VoidType] void -# 2229| ValueCategory = prvalue -# 2229| getArgument(0): [VariableAccess] x -# 2229| Type = [Class] ClassWithDestructor -# 2229| ValueCategory = prvalue(load) -# 2229| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2229| Type = [VoidType] void -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [ReuseExpr] reuse of temporary object -# 2229| Type = [Class] ClassWithDestructor -# 2229| ValueCategory = xvalue -# 2229| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2229| Type = [Class] ClassWithDestructor -# 2229| ValueCategory = lvalue -# 2229| getChild(1): [DeclStmt] declaration -# 2229| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) -# 2229| Type = [LValueReferenceType] vector & +# 2225| getQualifier(): [VariableAccess] ys +# 2225| Type = [ClassTemplateInstantiation,Struct] vector +# 2225| ValueCategory = lvalue +# 2234| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor +# 2234| Type = [VoidType] void +# 2234| ValueCategory = prvalue +# 2234| getQualifier(): [VariableAccess] x +# 2234| Type = [Class] ClassWithDestructor +# 2234| ValueCategory = lvalue +# 2225| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2225| Type = [VoidType] void +# 2225| ValueCategory = prvalue +# 2225| getQualifier(): [VariableAccess] ys +# 2225| Type = [ClassTemplateInstantiation,Struct] vector +# 2225| ValueCategory = lvalue +# 2225| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2225| Type = [ClassTemplateInstantiation,Struct] iterator +# 2225| ValueCategory = lvalue +# 2230| getStmt(8): [RangeBasedForStmt] for(...:...) ... +# 2230| getInitialization(): [DeclStmt] declaration +# 2230| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys +# 2230| Type = [ClassTemplateInstantiation,Struct] vector +# 2230| getVariable().getInitializer(): [Initializer] initializer for ys +# 2230| getExpr(): [ConstructorCall] call to vector +# 2230| Type = [VoidType] void +# 2230| ValueCategory = prvalue +# 2230| getArgument(0): [VariableAccess] x +# 2230| Type = [Class] ClassWithDestructor +# 2230| ValueCategory = prvalue(load) +# 2230| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2230| Type = [VoidType] void +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [ReuseExpr] reuse of temporary object +# 2230| Type = [Class] ClassWithDestructor +# 2230| ValueCategory = xvalue +# 2230| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2230| Type = [Class] ClassWithDestructor +# 2230| ValueCategory = lvalue +# 2230| getChild(1): [DeclStmt] declaration +# 2230| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) +# 2230| Type = [LValueReferenceType] vector & #-----| getVariable().getInitializer(): [Initializer] initializer for (__range) -# 2229| getExpr(): [VariableAccess] ys -# 2229| Type = [ClassTemplateInstantiation,Struct] vector -# 2229| ValueCategory = lvalue -# 2229| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2229| Type = [LValueReferenceType] vector & -# 2229| ValueCategory = prvalue -# 2229| getBeginEndDeclaration(): [DeclStmt] declaration -# 2229| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| getExpr(): [VariableAccess] ys +# 2230| Type = [ClassTemplateInstantiation,Struct] vector +# 2230| ValueCategory = lvalue +# 2230| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2230| Type = [LValueReferenceType] vector & +# 2230| ValueCategory = prvalue +# 2230| getBeginEndDeclaration(): [DeclStmt] declaration +# 2230| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__begin) -# 2229| getExpr(): [FunctionCall] call to begin -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] (__range) -# 2229| Type = [LValueReferenceType] vector & -# 2229| ValueCategory = prvalue(load) +# 2230| getExpr(): [FunctionCall] call to begin +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [VariableAccess] (__range) +# 2230| Type = [LValueReferenceType] vector & +# 2230| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19946,15 +19964,15 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2229| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__end) -# 2229| getExpr(): [FunctionCall] call to end -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] (__range) -# 2229| Type = [LValueReferenceType] vector & -# 2229| ValueCategory = prvalue(load) +# 2230| getExpr(): [FunctionCall] call to end +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [VariableAccess] (__range) +# 2230| Type = [LValueReferenceType] vector & +# 2230| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19962,18 +19980,18 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2229| getCondition(): [FunctionCall] call to operator!= -# 2229| Type = [BoolType] bool -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] (__begin) -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2229| ValueCategory = lvalue -# 2229| getArgument(0): [ConstructorCall] call to iterator -# 2229| Type = [VoidType] void -# 2229| ValueCategory = prvalue -# 2229| getArgument(0): [VariableAccess] (__end) -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2229| ValueCategory = lvalue +# 2230| getCondition(): [FunctionCall] call to operator!= +# 2230| Type = [BoolType] bool +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [VariableAccess] (__begin) +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| ValueCategory = lvalue +# 2230| getArgument(0): [ConstructorCall] call to iterator +# 2230| Type = [VoidType] void +# 2230| ValueCategory = prvalue +# 2230| getArgument(0): [VariableAccess] (__end) +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| ValueCategory = lvalue #-----| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) #-----| Type = [LValueReferenceType] const iterator & #-----| ValueCategory = prvalue @@ -19988,584 +20006,584 @@ ir.cpp: #-----| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object #-----| Type = [ClassTemplateInstantiation,Struct] iterator #-----| ValueCategory = lvalue -# 2229| getUpdate(): [FunctionCall] call to operator++ -# 2229| Type = [LValueReferenceType] iterator & -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] (__begin) -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2229| ValueCategory = lvalue -# 2229| getChild(5): [DeclStmt] declaration -# 2229| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y -# 2229| Type = [Class] ClassWithDestructor -# 2229| getVariable().getInitializer(): [Initializer] initializer for y -# 2229| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* -# 2229| Type = [LValueReferenceType] ClassWithDestructor & -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] (__begin) -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2229| ValueCategory = lvalue +# 2230| getUpdate(): [FunctionCall] call to operator++ +# 2230| Type = [LValueReferenceType] iterator & +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [VariableAccess] (__begin) +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| ValueCategory = lvalue +# 2230| getChild(5): [DeclStmt] declaration +# 2230| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2230| Type = [Class] ClassWithDestructor +# 2230| getVariable().getInitializer(): [Initializer] initializer for y +# 2230| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* +# 2230| Type = [LValueReferenceType] ClassWithDestructor & +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [VariableAccess] (__begin) +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| ValueCategory = lvalue #-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const iterator #-----| ValueCategory = lvalue -# 2229| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2229| Type = [Class] ClassWithDestructor -# 2229| ValueCategory = prvalue(load) -# 2229| getStmt(): [BlockStmt] { ... } -# 2230| getStmt(0): [DeclStmt] declaration -# 2230| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z1 -# 2230| Type = [Class] ClassWithDestructor -# 2230| getVariable().getInitializer(): [Initializer] initializer for z1 -# 2230| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2230| Type = [VoidType] void -# 2230| ValueCategory = prvalue -# 2231| getStmt(1): [DeclStmt] declaration -# 2231| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z2 +# 2230| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2230| Type = [Class] ClassWithDestructor +# 2230| ValueCategory = prvalue(load) +# 2230| getStmt(): [BlockStmt] { ... } +# 2231| getStmt(0): [DeclStmt] declaration +# 2231| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z1 # 2231| Type = [Class] ClassWithDestructor -# 2231| getVariable().getInitializer(): [Initializer] initializer for z2 +# 2231| getVariable().getInitializer(): [Initializer] initializer for z1 # 2231| getExpr(): [ConstructorCall] call to ClassWithDestructor # 2231| Type = [VoidType] void # 2231| ValueCategory = prvalue -# 2232| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2232| Type = [VoidType] void -# 2232| ValueCategory = prvalue -# 2232| getQualifier(): [VariableAccess] z2 +# 2232| getStmt(1): [DeclStmt] declaration +# 2232| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z2 # 2232| Type = [Class] ClassWithDestructor -# 2232| ValueCategory = lvalue -# 2232| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor -# 2232| Type = [VoidType] void -# 2232| ValueCategory = prvalue -# 2232| getQualifier(): [VariableAccess] z1 -# 2232| Type = [Class] ClassWithDestructor -# 2232| ValueCategory = lvalue -# 2229| getImplicitDestructorCall(2): [DestructorCall] call to ~ClassWithDestructor -# 2229| Type = [VoidType] void -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] y -# 2229| Type = [Class] ClassWithDestructor -# 2229| ValueCategory = lvalue -# 2229| getImplicitDestructorCall(0): [DestructorCall] call to ~vector -# 2229| Type = [VoidType] void -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] ys -# 2229| Type = [ClassTemplateInstantiation,Struct] vector -# 2229| ValueCategory = lvalue -# 2229| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2229| Type = [ClassTemplateInstantiation,Struct] iterator -# 2229| ValueCategory = lvalue -# 2233| getStmt(9): [ReturnStmt] return ... -# 2233| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2233| Type = [VoidType] void -# 2233| ValueCategory = prvalue -# 2233| getQualifier(): [VariableAccess] x -# 2233| Type = [Class] ClassWithDestructor -# 2233| ValueCategory = lvalue -# 2235| [TopLevelFunction] void static_variable_with_destructor_1() -# 2235| : -# 2235| getEntryPoint(): [BlockStmt] { ... } -# 2236| getStmt(0): [DeclStmt] declaration -# 2236| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a -# 2236| Type = [Class] ClassWithDestructor -# 2236| getVariable().getInitializer(): [Initializer] initializer for a -# 2236| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2236| Type = [VoidType] void -# 2236| ValueCategory = prvalue -# 2237| getStmt(1): [DeclStmt] declaration -# 2237| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b +# 2232| getVariable().getInitializer(): [Initializer] initializer for z2 +# 2232| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2232| Type = [VoidType] void +# 2232| ValueCategory = prvalue +# 2233| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2233| Type = [VoidType] void +# 2233| ValueCategory = prvalue +# 2233| getQualifier(): [VariableAccess] z2 +# 2233| Type = [Class] ClassWithDestructor +# 2233| ValueCategory = lvalue +# 2233| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor +# 2233| Type = [VoidType] void +# 2233| ValueCategory = prvalue +# 2233| getQualifier(): [VariableAccess] z1 +# 2233| Type = [Class] ClassWithDestructor +# 2233| ValueCategory = lvalue +# 2230| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2230| Type = [VoidType] void +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [VariableAccess] ys +# 2230| Type = [ClassTemplateInstantiation,Struct] vector +# 2230| ValueCategory = lvalue +# 2230| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2230| Type = [ClassTemplateInstantiation,Struct] iterator +# 2230| ValueCategory = lvalue +# 2230| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2230| Type = [VoidType] void +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [VariableAccess] y +# 2230| Type = [Class] ClassWithDestructor +# 2230| ValueCategory = lvalue +# 2234| getStmt(9): [ReturnStmt] return ... +# 2234| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2234| Type = [VoidType] void +# 2234| ValueCategory = prvalue +# 2234| getQualifier(): [VariableAccess] x +# 2234| Type = [Class] ClassWithDestructor +# 2234| ValueCategory = lvalue +# 2236| [TopLevelFunction] void static_variable_with_destructor_1() +# 2236| : +# 2236| getEntryPoint(): [BlockStmt] { ... } +# 2237| getStmt(0): [DeclStmt] declaration +# 2237| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a # 2237| Type = [Class] ClassWithDestructor +# 2237| getVariable().getInitializer(): [Initializer] initializer for a +# 2237| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2237| Type = [VoidType] void +# 2237| ValueCategory = prvalue +# 2238| getStmt(1): [DeclStmt] declaration +# 2238| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b +# 2238| Type = [Class] ClassWithDestructor #-----| getVariable().getInitializer(): [Initializer] initializer for b #-----| getExpr(): [ConstructorCall] call to ClassWithDestructor #-----| Type = [VoidType] void #-----| ValueCategory = prvalue -# 2238| getStmt(2): [ReturnStmt] return ... -# 2238| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2238| Type = [VoidType] void -# 2238| ValueCategory = prvalue -# 2238| getQualifier(): [VariableAccess] a -# 2238| Type = [Class] ClassWithDestructor -# 2238| ValueCategory = lvalue -# 2240| [TopLevelFunction] void static_variable_with_destructor_2() -# 2240| : -# 2240| getEntryPoint(): [BlockStmt] { ... } -# 2241| getStmt(0): [DeclStmt] declaration -# 2241| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a -# 2241| Type = [Class] ClassWithDestructor +# 2239| getStmt(2): [ReturnStmt] return ... +# 2239| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2239| Type = [VoidType] void +# 2239| ValueCategory = prvalue +# 2239| getQualifier(): [VariableAccess] a +# 2239| Type = [Class] ClassWithDestructor +# 2239| ValueCategory = lvalue +# 2241| [TopLevelFunction] void static_variable_with_destructor_2() +# 2241| : +# 2241| getEntryPoint(): [BlockStmt] { ... } +# 2242| getStmt(0): [DeclStmt] declaration +# 2242| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a +# 2242| Type = [Class] ClassWithDestructor #-----| getVariable().getInitializer(): [Initializer] initializer for a #-----| getExpr(): [ConstructorCall] call to ClassWithDestructor #-----| Type = [VoidType] void #-----| ValueCategory = prvalue -# 2242| getStmt(1): [DeclStmt] declaration -# 2242| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b -# 2242| Type = [Class] ClassWithDestructor -# 2242| getVariable().getInitializer(): [Initializer] initializer for b -# 2242| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2242| Type = [VoidType] void -# 2242| ValueCategory = prvalue -# 2243| getStmt(2): [ReturnStmt] return ... -# 2243| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2243| Type = [VoidType] void -# 2243| ValueCategory = prvalue -# 2243| getQualifier(): [VariableAccess] b -# 2243| Type = [Class] ClassWithDestructor -# 2243| ValueCategory = lvalue -# 2245| [TopLevelFunction] void static_variable_with_destructor_3() -# 2245| : -# 2245| getEntryPoint(): [BlockStmt] { ... } -# 2246| getStmt(0): [DeclStmt] declaration -# 2246| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a -# 2246| Type = [Class] ClassWithDestructor -# 2246| getVariable().getInitializer(): [Initializer] initializer for a -# 2246| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2246| Type = [VoidType] void -# 2246| ValueCategory = prvalue -# 2247| getStmt(1): [DeclStmt] declaration -# 2247| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b +# 2243| getStmt(1): [DeclStmt] declaration +# 2243| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b +# 2243| Type = [Class] ClassWithDestructor +# 2243| getVariable().getInitializer(): [Initializer] initializer for b +# 2243| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2243| Type = [VoidType] void +# 2243| ValueCategory = prvalue +# 2244| getStmt(2): [ReturnStmt] return ... +# 2244| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2244| Type = [VoidType] void +# 2244| ValueCategory = prvalue +# 2244| getQualifier(): [VariableAccess] b +# 2244| Type = [Class] ClassWithDestructor +# 2244| ValueCategory = lvalue +# 2246| [TopLevelFunction] void static_variable_with_destructor_3() +# 2246| : +# 2246| getEntryPoint(): [BlockStmt] { ... } +# 2247| getStmt(0): [DeclStmt] declaration +# 2247| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a # 2247| Type = [Class] ClassWithDestructor -# 2247| getVariable().getInitializer(): [Initializer] initializer for b +# 2247| getVariable().getInitializer(): [Initializer] initializer for a # 2247| getExpr(): [ConstructorCall] call to ClassWithDestructor # 2247| Type = [VoidType] void # 2247| ValueCategory = prvalue -# 2248| getStmt(2): [DeclStmt] declaration -# 2248| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c +# 2248| getStmt(1): [DeclStmt] declaration +# 2248| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b # 2248| Type = [Class] ClassWithDestructor +# 2248| getVariable().getInitializer(): [Initializer] initializer for b +# 2248| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2248| Type = [VoidType] void +# 2248| ValueCategory = prvalue +# 2249| getStmt(2): [DeclStmt] declaration +# 2249| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c +# 2249| Type = [Class] ClassWithDestructor #-----| getVariable().getInitializer(): [Initializer] initializer for c #-----| getExpr(): [ConstructorCall] call to ClassWithDestructor #-----| Type = [VoidType] void #-----| ValueCategory = prvalue -# 2249| getStmt(3): [ReturnStmt] return ... -# 2249| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2249| Type = [VoidType] void -# 2249| ValueCategory = prvalue -# 2249| getQualifier(): [VariableAccess] b -# 2249| Type = [Class] ClassWithDestructor -# 2249| ValueCategory = lvalue -# 2249| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor -# 2249| Type = [VoidType] void -# 2249| ValueCategory = prvalue -# 2249| getQualifier(): [VariableAccess] a -# 2249| Type = [Class] ClassWithDestructor -# 2249| ValueCategory = lvalue -# 2251| [GlobalVariable] ClassWithDestructor global_class_with_destructor -# 2251| getInitializer(): [Initializer] initializer for global_class_with_destructor -# 2251| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2251| Type = [VoidType] void -# 2251| ValueCategory = prvalue -# 2255| [FunctionTemplateInstantiation,TopLevelFunction] ClassWithDestructor& vacuous_destructor_call::get(ClassWithDestructor&) -# 2255| : -# 2255| getParameter(0): [Parameter] t -# 2255| Type = [LValueReferenceType] ClassWithDestructor & -# 2255| getEntryPoint(): [BlockStmt] { ... } -# 2255| getStmt(0): [ReturnStmt] return ... -# 2255| getExpr(): [VariableAccess] t -# 2255| Type = [LValueReferenceType] ClassWithDestructor & -# 2255| ValueCategory = prvalue(load) -# 2255| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2255| Type = [LValueReferenceType] ClassWithDestructor & -# 2255| ValueCategory = prvalue -# 2255| getExpr(): [ReferenceDereferenceExpr] (reference dereference) -# 2255| Type = [Class] ClassWithDestructor -# 2255| ValueCategory = lvalue -# 2255| [TemplateFunction,TopLevelFunction] T& vacuous_destructor_call::get(T&) -# 2255| : -# 2255| getParameter(0): [Parameter] t -# 2255| Type = [LValueReferenceType] T & -# 2255| getEntryPoint(): [BlockStmt] { ... } -# 2255| getStmt(0): [ReturnStmt] return ... -# 2255| getExpr(): [VariableAccess] t -# 2255| Type = [LValueReferenceType] T & -# 2255| ValueCategory = prvalue(load) -# 2255| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2255| Type = [TemplateParameter] T -# 2255| ValueCategory = lvalue -# 2255| [FunctionTemplateInstantiation,TopLevelFunction] int& vacuous_destructor_call::get(int&) -# 2255| : -# 2255| getParameter(0): [Parameter] t -# 2255| Type = [LValueReferenceType] int & -# 2255| getEntryPoint(): [BlockStmt] { ... } -# 2255| getStmt(0): [ReturnStmt] return ... -# 2255| getExpr(): [VariableAccess] t -# 2255| Type = [LValueReferenceType] int & -# 2255| ValueCategory = prvalue(load) -# 2255| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2255| Type = [LValueReferenceType] int & -# 2255| ValueCategory = prvalue -# 2255| getExpr(): [ReferenceDereferenceExpr] (reference dereference) -# 2255| Type = [IntType] int -# 2255| ValueCategory = lvalue -# 2258| [FunctionTemplateInstantiation,TopLevelFunction] void vacuous_destructor_call::call_destructor(ClassWithDestructor&) -# 2258| : -# 2258| getParameter(0): [Parameter] t -# 2258| Type = [LValueReferenceType] ClassWithDestructor & -# 2258| getEntryPoint(): [BlockStmt] { ... } -# 2259| getStmt(0): [ExprStmt] ExprStmt -# 2259| getExpr(): [DestructorCall] call to ~ClassWithDestructor -# 2259| Type = [VoidType] void -# 2259| ValueCategory = prvalue -# 2259| getQualifier(): [FunctionCall] call to get -# 2259| Type = [LValueReferenceType] ClassWithDestructor & -# 2259| ValueCategory = prvalue -# 2259| getArgument(0): [VariableAccess] t -# 2259| Type = [LValueReferenceType] ClassWithDestructor & -# 2259| ValueCategory = prvalue(load) -# 2259| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) -# 2259| Type = [LValueReferenceType] ClassWithDestructor & -# 2259| ValueCategory = prvalue -# 2259| getExpr(): [ReferenceDereferenceExpr] (reference dereference) -# 2259| Type = [Class] ClassWithDestructor -# 2259| ValueCategory = lvalue -# 2259| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2259| Type = [Class] ClassWithDestructor -# 2259| ValueCategory = lvalue -# 2260| getStmt(1): [ReturnStmt] return ... -# 2258| [TemplateFunction,TopLevelFunction] void vacuous_destructor_call::call_destructor(T&) -# 2258| : -# 2258| getParameter(0): [Parameter] t -# 2258| Type = [LValueReferenceType] T & -# 2258| getEntryPoint(): [BlockStmt] { ... } -# 2259| getStmt(0): [ExprStmt] ExprStmt -# 2259| getExpr(): [ExprCall] call to expression -# 2259| Type = [UnknownType] unknown -# 2259| ValueCategory = prvalue -# 2259| getExpr(): [Literal] Unknown literal -# 2259| Type = [UnknownType] unknown -# 2259| ValueCategory = prvalue -# 2259| getChild(-1): [ExprCall] call to expression -# 2259| Type = [UnknownType] unknown -# 2259| ValueCategory = prvalue -# 2259| getExpr(): [Literal] Unknown literal -# 2259| Type = [UnknownType] unknown -# 2259| ValueCategory = prvalue -# 2259| getArgument(0): [VariableAccess] t -# 2259| Type = [LValueReferenceType] T & -# 2259| ValueCategory = prvalue(load) -# 2259| getArgument(0).getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2259| Type = [TemplateParameter] T -# 2259| ValueCategory = lvalue -# 2260| getStmt(1): [ReturnStmt] return ... -# 2258| [FunctionTemplateInstantiation,TopLevelFunction] void vacuous_destructor_call::call_destructor(int&) -# 2258| : -# 2258| getParameter(0): [Parameter] t -# 2258| Type = [LValueReferenceType] int & -# 2258| getEntryPoint(): [BlockStmt] { ... } -# 2259| getStmt(0): [ExprStmt] ExprStmt -# 2259| getExpr(): [VacuousDestructorCall] (vacuous destructor call) -# 2259| Type = [VoidType] void -# 2259| ValueCategory = prvalue -# 2259| getChild(0): [FunctionCall] call to get -# 2259| Type = [LValueReferenceType] int & -# 2259| ValueCategory = prvalue -# 2259| getArgument(0): [VariableAccess] t -# 2259| Type = [LValueReferenceType] int & -# 2259| ValueCategory = prvalue(load) -# 2259| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) -# 2259| Type = [LValueReferenceType] int & -# 2259| ValueCategory = prvalue -# 2259| getExpr(): [ReferenceDereferenceExpr] (reference dereference) -# 2259| Type = [IntType] int -# 2259| ValueCategory = lvalue -# 2259| getChild(0).getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2259| Type = [IntType] int -# 2259| ValueCategory = lvalue -# 2260| getStmt(1): [ReturnStmt] return ... -# 2262| [TopLevelFunction] void vacuous_destructor_call::non_vacuous_destructor_call() -# 2262| : -# 2262| getEntryPoint(): [BlockStmt] { ... } -# 2263| getStmt(0): [DeclStmt] declaration -# 2263| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c -# 2263| Type = [Class] ClassWithDestructor -# 2263| getVariable().getInitializer(): [Initializer] initializer for c -# 2263| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2263| Type = [VoidType] void -# 2263| ValueCategory = prvalue -# 2264| getStmt(1): [ExprStmt] ExprStmt -# 2264| getExpr(): [FunctionCall] call to call_destructor -# 2264| Type = [VoidType] void -# 2264| ValueCategory = prvalue -# 2264| getArgument(0): [VariableAccess] c -# 2264| Type = [Class] ClassWithDestructor -# 2264| ValueCategory = lvalue -# 2264| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) -# 2264| Type = [LValueReferenceType] ClassWithDestructor & -# 2264| ValueCategory = prvalue -# 2265| getStmt(2): [ReturnStmt] return ... -# 2265| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2250| getStmt(3): [ReturnStmt] return ... +# 2250| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2250| Type = [VoidType] void +# 2250| ValueCategory = prvalue +# 2250| getQualifier(): [VariableAccess] b +# 2250| Type = [Class] ClassWithDestructor +# 2250| ValueCategory = lvalue +# 2250| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor +# 2250| Type = [VoidType] void +# 2250| ValueCategory = prvalue +# 2250| getQualifier(): [VariableAccess] a +# 2250| Type = [Class] ClassWithDestructor +# 2250| ValueCategory = lvalue +# 2252| [GlobalVariable] ClassWithDestructor global_class_with_destructor +# 2252| getInitializer(): [Initializer] initializer for global_class_with_destructor +# 2252| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2252| Type = [VoidType] void +# 2252| ValueCategory = prvalue +# 2256| [FunctionTemplateInstantiation,TopLevelFunction] ClassWithDestructor& vacuous_destructor_call::get(ClassWithDestructor&) +# 2256| : +# 2256| getParameter(0): [Parameter] t +# 2256| Type = [LValueReferenceType] ClassWithDestructor & +# 2256| getEntryPoint(): [BlockStmt] { ... } +# 2256| getStmt(0): [ReturnStmt] return ... +# 2256| getExpr(): [VariableAccess] t +# 2256| Type = [LValueReferenceType] ClassWithDestructor & +# 2256| ValueCategory = prvalue(load) +# 2256| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2256| Type = [LValueReferenceType] ClassWithDestructor & +# 2256| ValueCategory = prvalue +# 2256| getExpr(): [ReferenceDereferenceExpr] (reference dereference) +# 2256| Type = [Class] ClassWithDestructor +# 2256| ValueCategory = lvalue +# 2256| [TemplateFunction,TopLevelFunction] T& vacuous_destructor_call::get(T&) +# 2256| : +# 2256| getParameter(0): [Parameter] t +# 2256| Type = [LValueReferenceType] T & +# 2256| getEntryPoint(): [BlockStmt] { ... } +# 2256| getStmt(0): [ReturnStmt] return ... +# 2256| getExpr(): [VariableAccess] t +# 2256| Type = [LValueReferenceType] T & +# 2256| ValueCategory = prvalue(load) +# 2256| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2256| Type = [TemplateParameter] T +# 2256| ValueCategory = lvalue +# 2256| [FunctionTemplateInstantiation,TopLevelFunction] int& vacuous_destructor_call::get(int&) +# 2256| : +# 2256| getParameter(0): [Parameter] t +# 2256| Type = [LValueReferenceType] int & +# 2256| getEntryPoint(): [BlockStmt] { ... } +# 2256| getStmt(0): [ReturnStmt] return ... +# 2256| getExpr(): [VariableAccess] t +# 2256| Type = [LValueReferenceType] int & +# 2256| ValueCategory = prvalue(load) +# 2256| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2256| Type = [LValueReferenceType] int & +# 2256| ValueCategory = prvalue +# 2256| getExpr(): [ReferenceDereferenceExpr] (reference dereference) +# 2256| Type = [IntType] int +# 2256| ValueCategory = lvalue +# 2259| [FunctionTemplateInstantiation,TopLevelFunction] void vacuous_destructor_call::call_destructor(ClassWithDestructor&) +# 2259| : +# 2259| getParameter(0): [Parameter] t +# 2259| Type = [LValueReferenceType] ClassWithDestructor & +# 2259| getEntryPoint(): [BlockStmt] { ... } +# 2260| getStmt(0): [ExprStmt] ExprStmt +# 2260| getExpr(): [DestructorCall] call to ~ClassWithDestructor +# 2260| Type = [VoidType] void +# 2260| ValueCategory = prvalue +# 2260| getQualifier(): [FunctionCall] call to get +# 2260| Type = [LValueReferenceType] ClassWithDestructor & +# 2260| ValueCategory = prvalue +# 2260| getArgument(0): [VariableAccess] t +# 2260| Type = [LValueReferenceType] ClassWithDestructor & +# 2260| ValueCategory = prvalue(load) +# 2260| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) +# 2260| Type = [LValueReferenceType] ClassWithDestructor & +# 2260| ValueCategory = prvalue +# 2260| getExpr(): [ReferenceDereferenceExpr] (reference dereference) +# 2260| Type = [Class] ClassWithDestructor +# 2260| ValueCategory = lvalue +# 2260| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2260| Type = [Class] ClassWithDestructor +# 2260| ValueCategory = lvalue +# 2261| getStmt(1): [ReturnStmt] return ... +# 2259| [TemplateFunction,TopLevelFunction] void vacuous_destructor_call::call_destructor(T&) +# 2259| : +# 2259| getParameter(0): [Parameter] t +# 2259| Type = [LValueReferenceType] T & +# 2259| getEntryPoint(): [BlockStmt] { ... } +# 2260| getStmt(0): [ExprStmt] ExprStmt +# 2260| getExpr(): [ExprCall] call to expression +# 2260| Type = [UnknownType] unknown +# 2260| ValueCategory = prvalue +# 2260| getExpr(): [Literal] Unknown literal +# 2260| Type = [UnknownType] unknown +# 2260| ValueCategory = prvalue +# 2260| getChild(-1): [ExprCall] call to expression +# 2260| Type = [UnknownType] unknown +# 2260| ValueCategory = prvalue +# 2260| getExpr(): [Literal] Unknown literal +# 2260| Type = [UnknownType] unknown +# 2260| ValueCategory = prvalue +# 2260| getArgument(0): [VariableAccess] t +# 2260| Type = [LValueReferenceType] T & +# 2260| ValueCategory = prvalue(load) +# 2260| getArgument(0).getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2260| Type = [TemplateParameter] T +# 2260| ValueCategory = lvalue +# 2261| getStmt(1): [ReturnStmt] return ... +# 2259| [FunctionTemplateInstantiation,TopLevelFunction] void vacuous_destructor_call::call_destructor(int&) +# 2259| : +# 2259| getParameter(0): [Parameter] t +# 2259| Type = [LValueReferenceType] int & +# 2259| getEntryPoint(): [BlockStmt] { ... } +# 2260| getStmt(0): [ExprStmt] ExprStmt +# 2260| getExpr(): [VacuousDestructorCall] (vacuous destructor call) +# 2260| Type = [VoidType] void +# 2260| ValueCategory = prvalue +# 2260| getChild(0): [FunctionCall] call to get +# 2260| Type = [LValueReferenceType] int & +# 2260| ValueCategory = prvalue +# 2260| getArgument(0): [VariableAccess] t +# 2260| Type = [LValueReferenceType] int & +# 2260| ValueCategory = prvalue(load) +# 2260| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) +# 2260| Type = [LValueReferenceType] int & +# 2260| ValueCategory = prvalue +# 2260| getExpr(): [ReferenceDereferenceExpr] (reference dereference) +# 2260| Type = [IntType] int +# 2260| ValueCategory = lvalue +# 2260| getChild(0).getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2260| Type = [IntType] int +# 2260| ValueCategory = lvalue +# 2261| getStmt(1): [ReturnStmt] return ... +# 2263| [TopLevelFunction] void vacuous_destructor_call::non_vacuous_destructor_call() +# 2263| : +# 2263| getEntryPoint(): [BlockStmt] { ... } +# 2264| getStmt(0): [DeclStmt] declaration +# 2264| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c +# 2264| Type = [Class] ClassWithDestructor +# 2264| getVariable().getInitializer(): [Initializer] initializer for c +# 2264| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2264| Type = [VoidType] void +# 2264| ValueCategory = prvalue +# 2265| getStmt(1): [ExprStmt] ExprStmt +# 2265| getExpr(): [FunctionCall] call to call_destructor # 2265| Type = [VoidType] void # 2265| ValueCategory = prvalue -# 2265| getQualifier(): [VariableAccess] c +# 2265| getArgument(0): [VariableAccess] c # 2265| Type = [Class] ClassWithDestructor # 2265| ValueCategory = lvalue -# 2267| [TopLevelFunction] void vacuous_destructor_call::vacuous_destructor_call() -# 2267| : -# 2267| getEntryPoint(): [BlockStmt] { ... } -# 2268| getStmt(0): [DeclStmt] declaration -# 2268| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i -# 2268| Type = [IntType] int -# 2269| getStmt(1): [ExprStmt] ExprStmt -# 2269| getExpr(): [FunctionCall] call to call_destructor -# 2269| Type = [VoidType] void -# 2269| ValueCategory = prvalue -# 2269| getArgument(0): [VariableAccess] i -# 2269| Type = [IntType] int -# 2269| ValueCategory = lvalue -# 2269| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) -# 2269| Type = [LValueReferenceType] int & -# 2269| ValueCategory = prvalue -# 2270| getStmt(2): [ReturnStmt] return ... -# 2273| [TopLevelFunction] void TryCatchDestructors(bool) -# 2273| : -# 2273| getParameter(0): [Parameter] b -# 2273| Type = [BoolType] bool -# 2273| getEntryPoint(): [BlockStmt] { ... } -# 2274| getStmt(0): [TryStmt] try { ... } -# 2274| getStmt(): [BlockStmt] { ... } -# 2275| getStmt(0): [DeclStmt] declaration -# 2275| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2275| Type = [Struct] String -# 2275| getVariable().getInitializer(): [Initializer] initializer for s -# 2275| getExpr(): [ConstructorCall] call to String -# 2275| Type = [VoidType] void -# 2275| ValueCategory = prvalue -# 2276| getStmt(1): [IfStmt] if (...) ... -# 2276| getCondition(): [VariableAccess] b -# 2276| Type = [BoolType] bool -# 2276| ValueCategory = prvalue(load) -# 2276| getThen(): [BlockStmt] { ... } -# 2277| getStmt(0): [ExprStmt] ExprStmt -# 2277| getExpr(): [ThrowExpr] throw ... -# 2277| Type = [PointerType] const char * -# 2277| ValueCategory = prvalue -# 2277| getExpr(): string literal -# 2277| Type = [ArrayType] const char[15] -# 2277| Value = [StringLiteral] "string literal" -# 2277| ValueCategory = lvalue -# 2280| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2280| Type = [VoidType] void -# 2280| ValueCategory = prvalue -# 2280| getQualifier(): [VariableAccess] s -# 2280| Type = [Struct] String -# 2280| ValueCategory = lvalue -# 2277| getExpr().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion -# 2277| Type = [PointerType] const char * -# 2277| ValueCategory = prvalue -# 2279| getStmt(2): [DeclStmt] declaration -# 2279| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 -# 2279| Type = [Struct] String -# 2279| getVariable().getInitializer(): [Initializer] initializer for s2 -# 2279| getExpr(): [ConstructorCall] call to String -# 2279| Type = [VoidType] void -# 2279| ValueCategory = prvalue -# 2280| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2280| Type = [VoidType] void -# 2280| ValueCategory = prvalue -# 2280| getQualifier(): [VariableAccess] s2 +# 2265| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) +# 2265| Type = [LValueReferenceType] ClassWithDestructor & +# 2265| ValueCategory = prvalue +# 2266| getStmt(2): [ReturnStmt] return ... +# 2266| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2266| Type = [VoidType] void +# 2266| ValueCategory = prvalue +# 2266| getQualifier(): [VariableAccess] c +# 2266| Type = [Class] ClassWithDestructor +# 2266| ValueCategory = lvalue +# 2268| [TopLevelFunction] void vacuous_destructor_call::vacuous_destructor_call() +# 2268| : +# 2268| getEntryPoint(): [BlockStmt] { ... } +# 2269| getStmt(0): [DeclStmt] declaration +# 2269| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i +# 2269| Type = [IntType] int +# 2270| getStmt(1): [ExprStmt] ExprStmt +# 2270| getExpr(): [FunctionCall] call to call_destructor +# 2270| Type = [VoidType] void +# 2270| ValueCategory = prvalue +# 2270| getArgument(0): [VariableAccess] i +# 2270| Type = [IntType] int +# 2270| ValueCategory = lvalue +# 2270| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) +# 2270| Type = [LValueReferenceType] int & +# 2270| ValueCategory = prvalue +# 2271| getStmt(2): [ReturnStmt] return ... +# 2274| [TopLevelFunction] void TryCatchDestructors(bool) +# 2274| : +# 2274| getParameter(0): [Parameter] b +# 2274| Type = [BoolType] bool +# 2274| getEntryPoint(): [BlockStmt] { ... } +# 2275| getStmt(0): [TryStmt] try { ... } +# 2275| getStmt(): [BlockStmt] { ... } +# 2276| getStmt(0): [DeclStmt] declaration +# 2276| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2276| Type = [Struct] String +# 2276| getVariable().getInitializer(): [Initializer] initializer for s +# 2276| getExpr(): [ConstructorCall] call to String +# 2276| Type = [VoidType] void +# 2276| ValueCategory = prvalue +# 2277| getStmt(1): [IfStmt] if (...) ... +# 2277| getCondition(): [VariableAccess] b +# 2277| Type = [BoolType] bool +# 2277| ValueCategory = prvalue(load) +# 2277| getThen(): [BlockStmt] { ... } +# 2278| getStmt(0): [ExprStmt] ExprStmt +# 2278| getExpr(): [ThrowExpr] throw ... +# 2278| Type = [PointerType] const char * +# 2278| ValueCategory = prvalue +# 2278| getExpr(): string literal +# 2278| Type = [ArrayType] const char[15] +# 2278| Value = [StringLiteral] "string literal" +# 2278| ValueCategory = lvalue +# 2281| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2281| Type = [VoidType] void +# 2281| ValueCategory = prvalue +# 2281| getQualifier(): [VariableAccess] s +# 2281| Type = [Struct] String +# 2281| ValueCategory = lvalue +# 2278| getExpr().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 2278| Type = [PointerType] const char * +# 2278| ValueCategory = prvalue +# 2280| getStmt(2): [DeclStmt] declaration +# 2280| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 # 2280| Type = [Struct] String -# 2280| ValueCategory = lvalue -# 2280| getImplicitDestructorCall(1): [DestructorCall] call to ~String -# 2280| Type = [VoidType] void -# 2280| ValueCategory = prvalue -# 2280| getQualifier(): [VariableAccess] s -# 2280| Type = [Struct] String -# 2280| ValueCategory = lvalue -# 2281| getChild(1): [Handler] -# 2281| getBlock(): [CatchBlock] { ... } -# 2282| getStmt(0): [ExprStmt] ExprStmt -# 2282| getExpr(): [ThrowExpr] throw ... -# 2282| Type = [Struct] String -# 2282| ValueCategory = prvalue -# 2282| getExpr(): [ConstructorCall] call to String -# 2282| Type = [VoidType] void -# 2282| ValueCategory = prvalue -# 2282| getArgument(0): [VariableAccess] s -# 2282| Type = [PointerType] const char * -# 2282| ValueCategory = prvalue(load) -# 2284| getChild(2): [Handler] -# 2284| getBlock(): [CatchBlock] { ... } -# 2286| getChild(3): [Handler] -# 2286| getBlock(): [CatchAnyBlock] { ... } -# 2287| getStmt(0): [ExprStmt] ExprStmt -# 2287| getExpr(): [ReThrowExpr] re-throw exception -# 2287| Type = [VoidType] void -# 2287| ValueCategory = prvalue -# 2289| getStmt(1): [ReturnStmt] return ... -# 2291| [TopLevelFunction] void IfDestructors(bool) -# 2291| : -# 2291| getParameter(0): [Parameter] b -# 2291| Type = [BoolType] bool -# 2291| getEntryPoint(): [BlockStmt] { ... } -# 2292| getStmt(0): [DeclStmt] declaration -# 2292| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s1 -# 2292| Type = [Struct] String -# 2292| getVariable().getInitializer(): [Initializer] initializer for s1 -# 2292| getExpr(): [ConstructorCall] call to String -# 2292| Type = [VoidType] void -# 2292| ValueCategory = prvalue -# 2293| getStmt(1): [IfStmt] if (...) ... -# 2293| getCondition(): [VariableAccess] b -# 2293| Type = [BoolType] bool -# 2293| ValueCategory = prvalue(load) -# 2293| getThen(): [BlockStmt] { ... } -# 2294| getStmt(0): [DeclStmt] declaration -# 2294| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 -# 2294| Type = [Struct] String -# 2294| getVariable().getInitializer(): [Initializer] initializer for s2 -# 2294| getExpr(): [ConstructorCall] call to String -# 2294| Type = [VoidType] void -# 2294| ValueCategory = prvalue -# 2295| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2295| Type = [VoidType] void -# 2295| ValueCategory = prvalue -# 2295| getQualifier(): [VariableAccess] s2 +# 2280| getVariable().getInitializer(): [Initializer] initializer for s2 +# 2280| getExpr(): [ConstructorCall] call to String +# 2280| Type = [VoidType] void +# 2280| ValueCategory = prvalue +# 2281| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2281| Type = [VoidType] void +# 2281| ValueCategory = prvalue +# 2281| getQualifier(): [VariableAccess] s2 +# 2281| Type = [Struct] String +# 2281| ValueCategory = lvalue +# 2281| getImplicitDestructorCall(1): [DestructorCall] call to ~String +# 2281| Type = [VoidType] void +# 2281| ValueCategory = prvalue +# 2281| getQualifier(): [VariableAccess] s +# 2281| Type = [Struct] String +# 2281| ValueCategory = lvalue +# 2282| getChild(1): [Handler] +# 2282| getBlock(): [CatchBlock] { ... } +# 2283| getStmt(0): [ExprStmt] ExprStmt +# 2283| getExpr(): [ThrowExpr] throw ... +# 2283| Type = [Struct] String +# 2283| ValueCategory = prvalue +# 2283| getExpr(): [ConstructorCall] call to String +# 2283| Type = [VoidType] void +# 2283| ValueCategory = prvalue +# 2283| getArgument(0): [VariableAccess] s +# 2283| Type = [PointerType] const char * +# 2283| ValueCategory = prvalue(load) +# 2285| getChild(2): [Handler] +# 2285| getBlock(): [CatchBlock] { ... } +# 2287| getChild(3): [Handler] +# 2287| getBlock(): [CatchAnyBlock] { ... } +# 2288| getStmt(0): [ExprStmt] ExprStmt +# 2288| getExpr(): [ReThrowExpr] re-throw exception +# 2288| Type = [VoidType] void +# 2288| ValueCategory = prvalue +# 2290| getStmt(1): [ReturnStmt] return ... +# 2292| [TopLevelFunction] void IfDestructors(bool) +# 2292| : +# 2292| getParameter(0): [Parameter] b +# 2292| Type = [BoolType] bool +# 2292| getEntryPoint(): [BlockStmt] { ... } +# 2293| getStmt(0): [DeclStmt] declaration +# 2293| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s1 +# 2293| Type = [Struct] String +# 2293| getVariable().getInitializer(): [Initializer] initializer for s1 +# 2293| getExpr(): [ConstructorCall] call to String +# 2293| Type = [VoidType] void +# 2293| ValueCategory = prvalue +# 2294| getStmt(1): [IfStmt] if (...) ... +# 2294| getCondition(): [VariableAccess] b +# 2294| Type = [BoolType] bool +# 2294| ValueCategory = prvalue(load) +# 2294| getThen(): [BlockStmt] { ... } +# 2295| getStmt(0): [DeclStmt] declaration +# 2295| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 # 2295| Type = [Struct] String -# 2295| ValueCategory = lvalue -# 2295| getElse(): [BlockStmt] { ... } -# 2296| getStmt(0): [DeclStmt] declaration -# 2296| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s3 +# 2295| getVariable().getInitializer(): [Initializer] initializer for s2 +# 2295| getExpr(): [ConstructorCall] call to String +# 2295| Type = [VoidType] void +# 2295| ValueCategory = prvalue +# 2296| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2296| Type = [VoidType] void +# 2296| ValueCategory = prvalue +# 2296| getQualifier(): [VariableAccess] s2 # 2296| Type = [Struct] String -# 2296| getVariable().getInitializer(): [Initializer] initializer for s3 -# 2296| getExpr(): [ConstructorCall] call to String -# 2296| Type = [VoidType] void -# 2296| ValueCategory = prvalue -# 2297| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2297| Type = [VoidType] void -# 2297| ValueCategory = prvalue -# 2297| getQualifier(): [VariableAccess] s3 +# 2296| ValueCategory = lvalue +# 2296| getElse(): [BlockStmt] { ... } +# 2297| getStmt(0): [DeclStmt] declaration +# 2297| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s3 # 2297| Type = [Struct] String -# 2297| ValueCategory = lvalue -# 2298| getStmt(2): [DeclStmt] declaration -# 2298| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s4 -# 2298| Type = [Struct] String -# 2298| getVariable().getInitializer(): [Initializer] initializer for s4 -# 2298| getExpr(): [ConstructorCall] call to String -# 2298| Type = [VoidType] void -# 2298| ValueCategory = prvalue -# 2299| getStmt(3): [ReturnStmt] return ... -# 2299| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2299| Type = [VoidType] void -# 2299| ValueCategory = prvalue -# 2299| getQualifier(): [VariableAccess] s4 -# 2299| Type = [Struct] String -# 2299| ValueCategory = lvalue -# 2299| getImplicitDestructorCall(1): [DestructorCall] call to ~String -# 2299| Type = [VoidType] void -# 2299| ValueCategory = prvalue -# 2299| getQualifier(): [VariableAccess] s1 -# 2299| Type = [Struct] String -# 2299| ValueCategory = lvalue -# 2301| [TopLevelFunction] void ForDestructors() -# 2301| : -# 2301| getEntryPoint(): [BlockStmt] { ... } -# 2302| getStmt(0): [DeclStmt] declaration -# 2302| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c -# 2302| Type = [PlainCharType] char -# 2302| getVariable().getInitializer(): [Initializer] initializer for c -# 2302| getExpr(): [CharLiteral] 97 -# 2302| Type = [PlainCharType] char -# 2302| Value = [CharLiteral] 97 -# 2302| ValueCategory = prvalue -# 2303| getStmt(1): [ForStmt] for(...;...;...) ... -# 2303| getInitialization(): [DeclStmt] declaration -# 2303| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2303| Type = [Struct] String -# 2303| getVariable().getInitializer(): [Initializer] initializer for s -# 2303| getExpr(): [ConstructorCall] call to String -# 2303| Type = [VoidType] void -# 2303| ValueCategory = prvalue -# 2303| getArgument(0): hello -# 2303| Type = [ArrayType] const char[6] -# 2303| Value = [StringLiteral] "hello" -# 2303| ValueCategory = lvalue -# 2303| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion -# 2303| Type = [PointerType] const char * -# 2303| ValueCategory = prvalue -# 2303| getCondition(): [NEExpr] ... != ... -# 2303| Type = [BoolType] bool -# 2303| ValueCategory = prvalue -# 2303| getLeftOperand(): [VariableAccess] c -# 2303| Type = [PlainCharType] char -# 2303| ValueCategory = prvalue(load) -# 2303| getRightOperand(): [Literal] 0 -# 2303| Type = [IntType] int -# 2303| Value = [Literal] 0 -# 2303| ValueCategory = prvalue -# 2303| getLeftOperand().getFullyConverted(): [CStyleCast] (int)... -# 2303| Conversion = [IntegralConversion] integral conversion -# 2303| Type = [IntType] int -# 2303| ValueCategory = prvalue -# 2303| getUpdate(): [AssignExpr] ... = ... +# 2297| getVariable().getInitializer(): [Initializer] initializer for s3 +# 2297| getExpr(): [ConstructorCall] call to String +# 2297| Type = [VoidType] void +# 2297| ValueCategory = prvalue +# 2298| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2298| Type = [VoidType] void +# 2298| ValueCategory = prvalue +# 2298| getQualifier(): [VariableAccess] s3 +# 2298| Type = [Struct] String +# 2298| ValueCategory = lvalue +# 2299| getStmt(2): [DeclStmt] declaration +# 2299| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s4 +# 2299| Type = [Struct] String +# 2299| getVariable().getInitializer(): [Initializer] initializer for s4 +# 2299| getExpr(): [ConstructorCall] call to String +# 2299| Type = [VoidType] void +# 2299| ValueCategory = prvalue +# 2300| getStmt(3): [ReturnStmt] return ... +# 2300| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2300| Type = [VoidType] void +# 2300| ValueCategory = prvalue +# 2300| getQualifier(): [VariableAccess] s4 +# 2300| Type = [Struct] String +# 2300| ValueCategory = lvalue +# 2300| getImplicitDestructorCall(1): [DestructorCall] call to ~String +# 2300| Type = [VoidType] void +# 2300| ValueCategory = prvalue +# 2300| getQualifier(): [VariableAccess] s1 +# 2300| Type = [Struct] String +# 2300| ValueCategory = lvalue +# 2302| [TopLevelFunction] void ForDestructors() +# 2302| : +# 2302| getEntryPoint(): [BlockStmt] { ... } +# 2303| getStmt(0): [DeclStmt] declaration +# 2303| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c # 2303| Type = [PlainCharType] char -# 2303| ValueCategory = lvalue -# 2303| getLValue(): [VariableAccess] c -# 2303| Type = [PlainCharType] char -# 2303| ValueCategory = lvalue -# 2303| getRValue(): [FunctionCall] call to pop_back -# 2303| Type = [PlainCharType] char -# 2303| ValueCategory = prvalue -# 2303| getQualifier(): [VariableAccess] s -# 2303| Type = [Struct] String -# 2303| ValueCategory = lvalue -# 2303| getStmt(): [BlockStmt] { ... } -# 2304| getStmt(0): [DeclStmt] declaration -# 2304| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 -# 2304| Type = [Struct] String -# 2304| getVariable().getInitializer(): [Initializer] initializer for s2 -# 2304| getExpr(): [ConstructorCall] call to String -# 2304| Type = [VoidType] void +# 2303| getVariable().getInitializer(): [Initializer] initializer for c +# 2303| getExpr(): [CharLiteral] 97 +# 2303| Type = [PlainCharType] char +# 2303| Value = [CharLiteral] 97 +# 2303| ValueCategory = prvalue +# 2304| getStmt(1): [ForStmt] for(...;...;...) ... +# 2304| getInitialization(): [DeclStmt] declaration +# 2304| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2304| Type = [Struct] String +# 2304| getVariable().getInitializer(): [Initializer] initializer for s +# 2304| getExpr(): [ConstructorCall] call to String +# 2304| Type = [VoidType] void +# 2304| ValueCategory = prvalue +# 2304| getArgument(0): hello +# 2304| Type = [ArrayType] const char[6] +# 2304| Value = [StringLiteral] "hello" +# 2304| ValueCategory = lvalue +# 2304| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 2304| Type = [PointerType] const char * # 2304| ValueCategory = prvalue -# 2305| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2305| Type = [VoidType] void -# 2305| ValueCategory = prvalue -# 2305| getQualifier(): [VariableAccess] s2 +# 2304| getCondition(): [NEExpr] ... != ... +# 2304| Type = [BoolType] bool +# 2304| ValueCategory = prvalue +# 2304| getLeftOperand(): [VariableAccess] c +# 2304| Type = [PlainCharType] char +# 2304| ValueCategory = prvalue(load) +# 2304| getRightOperand(): [Literal] 0 +# 2304| Type = [IntType] int +# 2304| Value = [Literal] 0 +# 2304| ValueCategory = prvalue +# 2304| getLeftOperand().getFullyConverted(): [CStyleCast] (int)... +# 2304| Conversion = [IntegralConversion] integral conversion +# 2304| Type = [IntType] int +# 2304| ValueCategory = prvalue +# 2304| getUpdate(): [AssignExpr] ... = ... +# 2304| Type = [PlainCharType] char +# 2304| ValueCategory = lvalue +# 2304| getLValue(): [VariableAccess] c +# 2304| Type = [PlainCharType] char +# 2304| ValueCategory = lvalue +# 2304| getRValue(): [FunctionCall] call to pop_back +# 2304| Type = [PlainCharType] char +# 2304| ValueCategory = prvalue +# 2304| getQualifier(): [VariableAccess] s +# 2304| Type = [Struct] String +# 2304| ValueCategory = lvalue +# 2304| getStmt(): [BlockStmt] { ... } +# 2305| getStmt(0): [DeclStmt] declaration +# 2305| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 # 2305| Type = [Struct] String -# 2305| ValueCategory = lvalue -# 2303| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2303| Type = [VoidType] void -# 2303| ValueCategory = prvalue -# 2303| getQualifier(): [VariableAccess] s -# 2303| Type = [Struct] String -# 2303| ValueCategory = lvalue -# 2307| getStmt(2): [RangeBasedForStmt] for(...:...) ... -# 2307| getChild(1): [DeclStmt] declaration -# 2307| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) -# 2307| Type = [RValueReferenceType] vector && +# 2305| getVariable().getInitializer(): [Initializer] initializer for s2 +# 2305| getExpr(): [ConstructorCall] call to String +# 2305| Type = [VoidType] void +# 2305| ValueCategory = prvalue +# 2306| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2306| Type = [VoidType] void +# 2306| ValueCategory = prvalue +# 2306| getQualifier(): [VariableAccess] s2 +# 2306| Type = [Struct] String +# 2306| ValueCategory = lvalue +# 2304| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2304| Type = [VoidType] void +# 2304| ValueCategory = prvalue +# 2304| getQualifier(): [VariableAccess] s +# 2304| Type = [Struct] String +# 2304| ValueCategory = lvalue +# 2308| getStmt(2): [RangeBasedForStmt] for(...:...) ... +# 2308| getChild(1): [DeclStmt] declaration +# 2308| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) +# 2308| Type = [RValueReferenceType] vector && #-----| getVariable().getInitializer(): [Initializer] initializer for (__range) -# 2307| getExpr(): [ConstructorCall] call to vector -# 2307| Type = [VoidType] void -# 2307| ValueCategory = prvalue -# 2307| getArgument(0): [ConstructorCall] call to String -# 2307| Type = [VoidType] void -# 2307| ValueCategory = prvalue -# 2307| getArgument(0): hello -# 2307| Type = [ArrayType] const char[6] -# 2307| Value = [StringLiteral] "hello" -# 2307| ValueCategory = lvalue -# 2307| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion -# 2307| Type = [PointerType] const char * -# 2307| ValueCategory = prvalue -# 2307| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2307| Type = [Struct] String -# 2307| ValueCategory = lvalue -# 2307| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2307| Type = [LValueReferenceType] vector & -# 2307| ValueCategory = prvalue -# 2307| getExpr(): [TemporaryObjectExpr] temporary object -# 2307| Type = [ClassTemplateInstantiation,Struct] vector -# 2307| ValueCategory = xvalue -# 2307| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2307| Type = [VoidType] void -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [ReuseExpr] reuse of temporary object -# 2307| Type = [Struct] String -# 2307| ValueCategory = xvalue -# 2307| getBeginEndDeclaration(): [DeclStmt] declaration -# 2307| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| getExpr(): [ConstructorCall] call to vector +# 2308| Type = [VoidType] void +# 2308| ValueCategory = prvalue +# 2308| getArgument(0): [ConstructorCall] call to String +# 2308| Type = [VoidType] void +# 2308| ValueCategory = prvalue +# 2308| getArgument(0): hello +# 2308| Type = [ArrayType] const char[6] +# 2308| Value = [StringLiteral] "hello" +# 2308| ValueCategory = lvalue +# 2308| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 2308| Type = [PointerType] const char * +# 2308| ValueCategory = prvalue +# 2308| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2308| Type = [Struct] String +# 2308| ValueCategory = lvalue +# 2308| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2308| Type = [LValueReferenceType] vector & +# 2308| ValueCategory = prvalue +# 2308| getExpr(): [TemporaryObjectExpr] temporary object +# 2308| Type = [ClassTemplateInstantiation,Struct] vector +# 2308| ValueCategory = xvalue +# 2308| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2308| Type = [VoidType] void +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [ReuseExpr] reuse of temporary object +# 2308| Type = [Struct] String +# 2308| ValueCategory = xvalue +# 2308| getBeginEndDeclaration(): [DeclStmt] declaration +# 2308| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__begin) -# 2307| getExpr(): [FunctionCall] call to begin -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [VariableAccess] (__range) -# 2307| Type = [RValueReferenceType] vector && -# 2307| ValueCategory = prvalue(load) +# 2308| getExpr(): [FunctionCall] call to begin +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [VariableAccess] (__range) +# 2308| Type = [RValueReferenceType] vector && +# 2308| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -20573,15 +20591,15 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2307| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__end) -# 2307| getExpr(): [FunctionCall] call to end -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [VariableAccess] (__range) -# 2307| Type = [RValueReferenceType] vector && -# 2307| ValueCategory = prvalue(load) +# 2308| getExpr(): [FunctionCall] call to end +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [VariableAccess] (__range) +# 2308| Type = [RValueReferenceType] vector && +# 2308| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -20589,18 +20607,18 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2307| getCondition(): [FunctionCall] call to operator!= -# 2307| Type = [BoolType] bool -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [VariableAccess] (__begin) -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2307| ValueCategory = lvalue -# 2307| getArgument(0): [ConstructorCall] call to iterator -# 2307| Type = [VoidType] void -# 2307| ValueCategory = prvalue -# 2307| getArgument(0): [VariableAccess] (__end) -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2307| ValueCategory = lvalue +# 2308| getCondition(): [FunctionCall] call to operator!= +# 2308| Type = [BoolType] bool +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [VariableAccess] (__begin) +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| ValueCategory = lvalue +# 2308| getArgument(0): [ConstructorCall] call to iterator +# 2308| Type = [VoidType] void +# 2308| ValueCategory = prvalue +# 2308| getArgument(0): [VariableAccess] (__end) +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| ValueCategory = lvalue #-----| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) #-----| Type = [LValueReferenceType] const iterator & #-----| ValueCategory = prvalue @@ -20615,1491 +20633,1497 @@ ir.cpp: #-----| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object #-----| Type = [ClassTemplateInstantiation,Struct] iterator #-----| ValueCategory = lvalue -# 2307| getUpdate(): [FunctionCall] call to operator++ -# 2307| Type = [LValueReferenceType] iterator & -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [VariableAccess] (__begin) -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2307| ValueCategory = lvalue -# 2307| getChild(5): [DeclStmt] declaration -# 2307| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2307| Type = [Struct] String -# 2307| getVariable().getInitializer(): [Initializer] initializer for s -# 2307| getExpr(): [ConstructorCall] call to String -# 2307| Type = [VoidType] void -# 2307| ValueCategory = prvalue -# 2307| getArgument(0): [OverloadedPointerDereferenceExpr] call to operator* -# 2307| Type = [LValueReferenceType] String & -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [VariableAccess] (__begin) -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2307| ValueCategory = lvalue +# 2308| getUpdate(): [FunctionCall] call to operator++ +# 2308| Type = [LValueReferenceType] iterator & +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [VariableAccess] (__begin) +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| ValueCategory = lvalue +# 2308| getChild(5): [DeclStmt] declaration +# 2308| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2308| Type = [Struct] String +# 2308| getVariable().getInitializer(): [Initializer] initializer for s +# 2308| getExpr(): [ConstructorCall] call to String +# 2308| Type = [VoidType] void +# 2308| ValueCategory = prvalue +# 2308| getArgument(0): [OverloadedPointerDereferenceExpr] call to operator* +# 2308| Type = [LValueReferenceType] String & +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [VariableAccess] (__begin) +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| ValueCategory = lvalue #-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const iterator #-----| ValueCategory = lvalue -# 2307| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) -# 2307| Type = [LValueReferenceType] const String & -# 2307| ValueCategory = prvalue -# 2307| getExpr(): [CStyleCast] (const String)... -# 2307| Conversion = [GlvalueConversion] glvalue conversion -# 2307| Type = [SpecifiedType] const String -# 2307| ValueCategory = lvalue -# 2307| getExpr(): [ReferenceDereferenceExpr] (reference dereference) -# 2307| Type = [Struct] String -# 2307| ValueCategory = lvalue -# 2307| getStmt(): [BlockStmt] { ... } -# 2308| getStmt(0): [DeclStmt] declaration -# 2308| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 -# 2308| Type = [Struct] String -# 2308| getVariable().getInitializer(): [Initializer] initializer for s2 -# 2308| getExpr(): [ConstructorCall] call to String -# 2308| Type = [VoidType] void +# 2308| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) +# 2308| Type = [LValueReferenceType] const String & # 2308| ValueCategory = prvalue -# 2309| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2309| Type = [VoidType] void -# 2309| ValueCategory = prvalue -# 2309| getQualifier(): [VariableAccess] s2 +# 2308| getExpr(): [CStyleCast] (const String)... +# 2308| Conversion = [GlvalueConversion] glvalue conversion +# 2308| Type = [SpecifiedType] const String +# 2308| ValueCategory = lvalue +# 2308| getExpr(): [ReferenceDereferenceExpr] (reference dereference) +# 2308| Type = [Struct] String +# 2308| ValueCategory = lvalue +# 2308| getStmt(): [BlockStmt] { ... } +# 2309| getStmt(0): [DeclStmt] declaration +# 2309| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 # 2309| Type = [Struct] String -# 2309| ValueCategory = lvalue -# 2307| getImplicitDestructorCall(1): [DestructorCall] call to ~String -# 2307| Type = [VoidType] void -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [VariableAccess] s -# 2307| Type = [Struct] String -# 2307| ValueCategory = lvalue -# 2307| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2307| Type = [ClassTemplateInstantiation,Struct] iterator -# 2307| ValueCategory = lvalue -# 2311| getStmt(3): [ForStmt] for(...;...;...) ... -# 2311| getInitialization(): [DeclStmt] declaration -# 2311| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2311| Type = [Struct] String -# 2311| getVariable().getInitializer(): [Initializer] initializer for s -# 2311| getExpr(): [ConstructorCall] call to String -# 2311| Type = [VoidType] void -# 2311| ValueCategory = prvalue -# 2311| getArgument(0): hello -# 2311| Type = [ArrayType] const char[6] -# 2311| Value = [StringLiteral] "hello" -# 2311| ValueCategory = lvalue -# 2311| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion -# 2311| Type = [PointerType] const char * -# 2311| ValueCategory = prvalue -# 2311| getDeclarationEntry(1): [VariableDeclarationEntry] definition of s2 -# 2311| Type = [Struct] String -# 2311| getVariable().getInitializer(): [Initializer] initializer for s2 -# 2311| getExpr(): [ConstructorCall] call to String -# 2311| Type = [VoidType] void -# 2311| ValueCategory = prvalue -# 2311| getArgument(0): world -# 2311| Type = [ArrayType] const char[6] -# 2311| Value = [StringLiteral] "world" -# 2311| ValueCategory = lvalue -# 2311| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion -# 2311| Type = [PointerType] const char * -# 2311| ValueCategory = prvalue -# 2311| getCondition(): [NEExpr] ... != ... -# 2311| Type = [BoolType] bool -# 2311| ValueCategory = prvalue -# 2311| getLeftOperand(): [VariableAccess] c -# 2311| Type = [PlainCharType] char -# 2311| ValueCategory = prvalue(load) -# 2311| getRightOperand(): [Literal] 0 -# 2311| Type = [IntType] int -# 2311| Value = [Literal] 0 -# 2311| ValueCategory = prvalue -# 2311| getLeftOperand().getFullyConverted(): [CStyleCast] (int)... -# 2311| Conversion = [IntegralConversion] integral conversion -# 2311| Type = [IntType] int -# 2311| ValueCategory = prvalue -# 2311| getUpdate(): [AssignExpr] ... = ... -# 2311| Type = [PlainCharType] char -# 2311| ValueCategory = lvalue -# 2311| getLValue(): [VariableAccess] c -# 2311| Type = [PlainCharType] char -# 2311| ValueCategory = lvalue -# 2311| getRValue(): [FunctionCall] call to pop_back -# 2311| Type = [PlainCharType] char -# 2311| ValueCategory = prvalue -# 2311| getQualifier(): [VariableAccess] s -# 2311| Type = [Struct] String -# 2311| ValueCategory = lvalue -# 2311| getStmt(): [BlockStmt] { ... } -# 2312| getStmt(0): [ExprStmt] ExprStmt -# 2312| getExpr(): [AssignExpr] ... = ... -# 2312| Type = [PlainCharType] char -# 2312| ValueCategory = lvalue -# 2312| getLValue(): [VariableAccess] c -# 2312| Type = [PlainCharType] char -# 2312| ValueCategory = lvalue -# 2312| getRValue(): [Literal] 0 -# 2312| Type = [IntType] int -# 2312| Value = [Literal] 0 +# 2309| getVariable().getInitializer(): [Initializer] initializer for s2 +# 2309| getExpr(): [ConstructorCall] call to String +# 2309| Type = [VoidType] void +# 2309| ValueCategory = prvalue +# 2310| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2310| Type = [VoidType] void +# 2310| ValueCategory = prvalue +# 2310| getQualifier(): [VariableAccess] s2 +# 2310| Type = [Struct] String +# 2310| ValueCategory = lvalue +# 2308| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2308| Type = [VoidType] void +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [ReuseExpr] reuse of temporary object +# 2308| Type = [ClassTemplateInstantiation,Struct] vector +# 2308| ValueCategory = xvalue +# 2308| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2308| Type = [ClassTemplateInstantiation,Struct] iterator +# 2308| ValueCategory = lvalue +# 2308| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2308| Type = [VoidType] void +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [VariableAccess] s +# 2308| Type = [Struct] String +# 2308| ValueCategory = lvalue +# 2312| getStmt(3): [ForStmt] for(...;...;...) ... +# 2312| getInitialization(): [DeclStmt] declaration +# 2312| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2312| Type = [Struct] String +# 2312| getVariable().getInitializer(): [Initializer] initializer for s +# 2312| getExpr(): [ConstructorCall] call to String +# 2312| Type = [VoidType] void # 2312| ValueCategory = prvalue -# 2312| getRValue().getFullyConverted(): [CStyleCast] (char)... -# 2312| Conversion = [IntegralConversion] integral conversion -# 2312| Type = [PlainCharType] char -# 2312| Value = [CStyleCast] 0 +# 2312| getArgument(0): hello +# 2312| Type = [ArrayType] const char[6] +# 2312| Value = [StringLiteral] "hello" +# 2312| ValueCategory = lvalue +# 2312| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 2312| Type = [PointerType] const char * +# 2312| ValueCategory = prvalue +# 2312| getDeclarationEntry(1): [VariableDeclarationEntry] definition of s2 +# 2312| Type = [Struct] String +# 2312| getVariable().getInitializer(): [Initializer] initializer for s2 +# 2312| getExpr(): [ConstructorCall] call to String +# 2312| Type = [VoidType] void # 2312| ValueCategory = prvalue -# 2311| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2311| Type = [VoidType] void -# 2311| ValueCategory = prvalue -# 2311| getQualifier(): [VariableAccess] s2 -# 2311| Type = [Struct] String -# 2311| ValueCategory = lvalue -# 2311| getImplicitDestructorCall(1): [DestructorCall] call to ~String -# 2311| Type = [VoidType] void -# 2311| ValueCategory = prvalue -# 2311| getQualifier(): [VariableAccess] s -# 2311| Type = [Struct] String -# 2311| ValueCategory = lvalue -# 2314| getStmt(4): [ReturnStmt] return ... -# 2316| [TopLevelFunction] void IfDestructors2(bool) -# 2316| : -# 2316| getParameter(0): [Parameter] b -# 2316| Type = [BoolType] bool -# 2316| getEntryPoint(): [BlockStmt] { ... } -# 2317| getStmt(0): [IfStmt] if (...) ... -# 2317| getInitialization(): [DeclStmt] declaration -# 2317| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2317| Type = [Struct] String -# 2317| getVariable().getInitializer(): [Initializer] initializer for s -# 2317| getExpr(): [ConstructorCall] call to String -# 2317| Type = [VoidType] void -# 2317| ValueCategory = prvalue -# 2317| getArgument(0): hello -# 2317| Type = [ArrayType] const char[6] -# 2317| Value = [StringLiteral] "hello" -# 2317| ValueCategory = lvalue -# 2317| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion -# 2317| Type = [PointerType] const char * -# 2317| ValueCategory = prvalue -# 2317| getCondition(): [VariableAccess] b -# 2317| Type = [BoolType] bool -# 2317| ValueCategory = prvalue(load) -# 2317| getThen(): [BlockStmt] { ... } -# 2318| getStmt(0): [DeclStmt] declaration -# 2318| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2318| Type = [IntType] int -# 2318| getVariable().getInitializer(): [Initializer] initializer for x -# 2318| getExpr(): [Literal] 0 -# 2318| Type = [IntType] int -# 2318| Value = [Literal] 0 +# 2312| getArgument(0): world +# 2312| Type = [ArrayType] const char[6] +# 2312| Value = [StringLiteral] "world" +# 2312| ValueCategory = lvalue +# 2312| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 2312| Type = [PointerType] const char * +# 2312| ValueCategory = prvalue +# 2312| getCondition(): [NEExpr] ... != ... +# 2312| Type = [BoolType] bool +# 2312| ValueCategory = prvalue +# 2312| getLeftOperand(): [VariableAccess] c +# 2312| Type = [PlainCharType] char +# 2312| ValueCategory = prvalue(load) +# 2312| getRightOperand(): [Literal] 0 +# 2312| Type = [IntType] int +# 2312| Value = [Literal] 0 +# 2312| ValueCategory = prvalue +# 2312| getLeftOperand().getFullyConverted(): [CStyleCast] (int)... +# 2312| Conversion = [IntegralConversion] integral conversion +# 2312| Type = [IntType] int +# 2312| ValueCategory = prvalue +# 2312| getUpdate(): [AssignExpr] ... = ... +# 2312| Type = [PlainCharType] char +# 2312| ValueCategory = lvalue +# 2312| getLValue(): [VariableAccess] c +# 2312| Type = [PlainCharType] char +# 2312| ValueCategory = lvalue +# 2312| getRValue(): [FunctionCall] call to pop_back +# 2312| Type = [PlainCharType] char +# 2312| ValueCategory = prvalue +# 2312| getQualifier(): [VariableAccess] s +# 2312| Type = [Struct] String +# 2312| ValueCategory = lvalue +# 2312| getStmt(): [BlockStmt] { ... } +# 2313| getStmt(0): [ExprStmt] ExprStmt +# 2313| getExpr(): [AssignExpr] ... = ... +# 2313| Type = [PlainCharType] char +# 2313| ValueCategory = lvalue +# 2313| getLValue(): [VariableAccess] c +# 2313| Type = [PlainCharType] char +# 2313| ValueCategory = lvalue +# 2313| getRValue(): [Literal] 0 +# 2313| Type = [IntType] int +# 2313| Value = [Literal] 0 +# 2313| ValueCategory = prvalue +# 2313| getRValue().getFullyConverted(): [CStyleCast] (char)... +# 2313| Conversion = [IntegralConversion] integral conversion +# 2313| Type = [PlainCharType] char +# 2313| Value = [CStyleCast] 0 +# 2313| ValueCategory = prvalue +# 2312| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2312| Type = [VoidType] void +# 2312| ValueCategory = prvalue +# 2312| getQualifier(): [VariableAccess] s2 +# 2312| Type = [Struct] String +# 2312| ValueCategory = lvalue +# 2312| getImplicitDestructorCall(1): [DestructorCall] call to ~String +# 2312| Type = [VoidType] void +# 2312| ValueCategory = prvalue +# 2312| getQualifier(): [VariableAccess] s +# 2312| Type = [Struct] String +# 2312| ValueCategory = lvalue +# 2315| getStmt(4): [ReturnStmt] return ... +# 2317| [TopLevelFunction] void IfDestructors2(bool) +# 2317| : +# 2317| getParameter(0): [Parameter] b +# 2317| Type = [BoolType] bool +# 2317| getEntryPoint(): [BlockStmt] { ... } +# 2318| getStmt(0): [IfStmt] if (...) ... +# 2318| getInitialization(): [DeclStmt] declaration +# 2318| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2318| Type = [Struct] String +# 2318| getVariable().getInitializer(): [Initializer] initializer for s +# 2318| getExpr(): [ConstructorCall] call to String +# 2318| Type = [VoidType] void +# 2318| ValueCategory = prvalue +# 2318| getArgument(0): hello +# 2318| Type = [ArrayType] const char[6] +# 2318| Value = [StringLiteral] "hello" +# 2318| ValueCategory = lvalue +# 2318| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 2318| Type = [PointerType] const char * # 2318| ValueCategory = prvalue -# 2319| getElse(): [BlockStmt] { ... } -# 2320| getStmt(0): [DeclStmt] declaration -# 2320| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y -# 2320| Type = [IntType] int -# 2320| getVariable().getInitializer(): [Initializer] initializer for y -# 2320| getExpr(): [Literal] 0 -# 2320| Type = [IntType] int -# 2320| Value = [Literal] 0 -# 2320| ValueCategory = prvalue -# 2321| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2321| Type = [VoidType] void -# 2321| ValueCategory = prvalue -# 2321| getQualifier(): [VariableAccess] s -# 2321| Type = [Struct] String -# 2321| ValueCategory = lvalue -# 2322| getStmt(1): [ReturnStmt] return ... -# 2324| [CopyAssignmentOperator] Bool& Bool::operator=(Bool const&) -# 2324| : +# 2318| getCondition(): [VariableAccess] b +# 2318| Type = [BoolType] bool +# 2318| ValueCategory = prvalue(load) +# 2318| getThen(): [BlockStmt] { ... } +# 2319| getStmt(0): [DeclStmt] declaration +# 2319| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2319| Type = [IntType] int +# 2319| getVariable().getInitializer(): [Initializer] initializer for x +# 2319| getExpr(): [Literal] 0 +# 2319| Type = [IntType] int +# 2319| Value = [Literal] 0 +# 2319| ValueCategory = prvalue +# 2320| getElse(): [BlockStmt] { ... } +# 2321| getStmt(0): [DeclStmt] declaration +# 2321| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2321| Type = [IntType] int +# 2321| getVariable().getInitializer(): [Initializer] initializer for y +# 2321| getExpr(): [Literal] 0 +# 2321| Type = [IntType] int +# 2321| Value = [Literal] 0 +# 2321| ValueCategory = prvalue +# 2322| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2322| Type = [VoidType] void +# 2322| ValueCategory = prvalue +# 2322| getQualifier(): [VariableAccess] s +# 2322| Type = [Struct] String +# 2322| ValueCategory = lvalue +# 2323| getStmt(1): [ReturnStmt] return ... +# 2325| [CopyAssignmentOperator] Bool& Bool::operator=(Bool const&) +# 2325| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [LValueReferenceType] const Bool & -# 2324| [CopyConstructor] void Bool::Bool(Bool const&) -# 2324| : +# 2325| [CopyConstructor] void Bool::Bool(Bool const&) +# 2325| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [LValueReferenceType] const Bool & -# 2326| [Constructor] void Bool::Bool(bool) -# 2326| : -# 2326| getParameter(0): [Parameter] b_ -# 2326| Type = [BoolType] bool -# 2327| [ConversionOperator] bool Bool::operator bool() +# 2327| [Constructor] void Bool::Bool(bool) # 2327| : -# 2328| [Destructor] void Bool::~Bool() +# 2327| getParameter(0): [Parameter] b_ +# 2327| Type = [BoolType] bool +# 2328| [ConversionOperator] bool Bool::operator bool() # 2328| : -# 2331| [TopLevelFunction] void IfDestructors3(bool) -# 2331| : -# 2331| getParameter(0): [Parameter] b -# 2331| Type = [BoolType] bool -# 2331| getEntryPoint(): [BlockStmt] { ... } -# 2332| getStmt(0): [IfStmt] if (...) ... -# 2332| getCondition(): [ConditionDeclExpr] (condition decl) -# 2332| Type = [BoolType] bool -# 2332| ValueCategory = prvalue -# 2332| getChild(0): [FunctionCall] call to operator bool -# 2332| Type = [BoolType] bool -# 2332| ValueCategory = prvalue -# 2332| getQualifier(): [VariableAccess] B -# 2332| Type = [Class] Bool -# 2332| ValueCategory = prvalue(load) -# 2332| getInitializingExpr(): [ConstructorCall] call to Bool -# 2332| Type = [VoidType] void -# 2332| ValueCategory = prvalue -# 2332| getArgument(0): [VariableAccess] b -# 2332| Type = [BoolType] bool -# 2332| ValueCategory = prvalue(load) -# 2332| getThen(): [BlockStmt] { ... } -# 2333| getStmt(0): [DeclStmt] declaration -# 2333| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s1 -# 2333| Type = [Struct] String -# 2333| getVariable().getInitializer(): [Initializer] initializer for s1 -# 2333| getExpr(): [ConstructorCall] call to String -# 2333| Type = [VoidType] void -# 2333| ValueCategory = prvalue -# 2334| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2334| Type = [VoidType] void -# 2334| ValueCategory = prvalue -# 2334| getQualifier(): [VariableAccess] s1 +# 2329| [Destructor] void Bool::~Bool() +# 2329| : +# 2332| [TopLevelFunction] void IfDestructors3(bool) +# 2332| : +# 2332| getParameter(0): [Parameter] b +# 2332| Type = [BoolType] bool +# 2332| getEntryPoint(): [BlockStmt] { ... } +# 2333| getStmt(0): [IfStmt] if (...) ... +# 2333| getCondition(): [ConditionDeclExpr] (condition decl) +# 2333| Type = [BoolType] bool +# 2333| ValueCategory = prvalue +# 2333| getChild(0): [FunctionCall] call to operator bool +# 2333| Type = [BoolType] bool +# 2333| ValueCategory = prvalue +# 2333| getQualifier(): [VariableAccess] B +# 2333| Type = [Class] Bool +# 2333| ValueCategory = prvalue(load) +# 2333| getInitializingExpr(): [ConstructorCall] call to Bool +# 2333| Type = [VoidType] void +# 2333| ValueCategory = prvalue +# 2333| getArgument(0): [VariableAccess] b +# 2333| Type = [BoolType] bool +# 2333| ValueCategory = prvalue(load) +# 2333| getThen(): [BlockStmt] { ... } +# 2334| getStmt(0): [DeclStmt] declaration +# 2334| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s1 # 2334| Type = [Struct] String -# 2334| ValueCategory = lvalue -# 2334| getElse(): [BlockStmt] { ... } -# 2335| getStmt(0): [DeclStmt] declaration -# 2335| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 +# 2334| getVariable().getInitializer(): [Initializer] initializer for s1 +# 2334| getExpr(): [ConstructorCall] call to String +# 2334| Type = [VoidType] void +# 2334| ValueCategory = prvalue +# 2335| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2335| Type = [VoidType] void +# 2335| ValueCategory = prvalue +# 2335| getQualifier(): [VariableAccess] s1 # 2335| Type = [Struct] String -# 2335| getVariable().getInitializer(): [Initializer] initializer for s2 -# 2335| getExpr(): [ConstructorCall] call to String -# 2335| Type = [VoidType] void -# 2335| ValueCategory = prvalue -# 2336| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2336| Type = [VoidType] void -# 2336| ValueCategory = prvalue -# 2336| getQualifier(): [VariableAccess] s2 +# 2335| ValueCategory = lvalue +# 2335| getElse(): [BlockStmt] { ... } +# 2336| getStmt(0): [DeclStmt] declaration +# 2336| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 # 2336| Type = [Struct] String -# 2336| ValueCategory = lvalue -# 2336| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool -# 2336| Type = [VoidType] void -# 2336| ValueCategory = prvalue -# 2336| getQualifier(): [VariableAccess] B -# 2336| Type = [Class] Bool -# 2336| ValueCategory = lvalue -# 2337| getStmt(1): [ReturnStmt] return ... -# 2339| [TopLevelFunction] void WhileLoopDestructors(bool) -# 2339| : -# 2339| getParameter(0): [Parameter] b -# 2339| Type = [BoolType] bool -# 2339| getEntryPoint(): [BlockStmt] { ... } -# 2340| getStmt(0): [BlockStmt] { ... } -# 2341| getStmt(0): [DeclStmt] declaration -# 2341| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2341| Type = [Struct] String -# 2341| getVariable().getInitializer(): [Initializer] initializer for s -# 2341| getExpr(): [ConstructorCall] call to String -# 2341| Type = [VoidType] void -# 2341| ValueCategory = prvalue -# 2342| getStmt(1): [WhileStmt] while (...) ... -# 2342| getCondition(): [VariableAccess] b -# 2342| Type = [BoolType] bool -# 2342| ValueCategory = prvalue(load) -# 2342| getStmt(): [BlockStmt] { ... } -# 2343| getStmt(0): [ExprStmt] ExprStmt -# 2343| getExpr(): [AssignExpr] ... = ... -# 2343| Type = [BoolType] bool -# 2343| ValueCategory = lvalue -# 2343| getLValue(): [VariableAccess] b -# 2343| Type = [BoolType] bool -# 2343| ValueCategory = lvalue -# 2343| getRValue(): [Literal] 0 -# 2343| Type = [BoolType] bool -# 2343| Value = [Literal] 0 -# 2343| ValueCategory = prvalue -# 2345| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2345| Type = [VoidType] void -# 2345| ValueCategory = prvalue -# 2345| getQualifier(): [VariableAccess] s -# 2345| Type = [Struct] String -# 2345| ValueCategory = lvalue -# 2347| getStmt(1): [BlockStmt] { ... } -# 2348| getStmt(0): [WhileStmt] while (...) ... -# 2348| getCondition(): [ConditionDeclExpr] (condition decl) -# 2348| Type = [BoolType] bool -# 2348| ValueCategory = prvalue -# 2348| getChild(0): [FunctionCall] call to operator bool -# 2348| Type = [BoolType] bool -# 2348| ValueCategory = prvalue -# 2348| getQualifier(): [VariableAccess] B -# 2348| Type = [Class] Bool -# 2348| ValueCategory = prvalue(load) -# 2348| getInitializingExpr(): [ConstructorCall] call to Bool -# 2348| Type = [VoidType] void -# 2348| ValueCategory = prvalue -# 2348| getArgument(0): [VariableAccess] b -# 2348| Type = [BoolType] bool -# 2348| ValueCategory = prvalue(load) -# 2348| getStmt(): [BlockStmt] { ... } -# 2349| getStmt(0): [ExprStmt] ExprStmt -# 2349| getExpr(): [AssignExpr] ... = ... +# 2336| getVariable().getInitializer(): [Initializer] initializer for s2 +# 2336| getExpr(): [ConstructorCall] call to String +# 2336| Type = [VoidType] void +# 2336| ValueCategory = prvalue +# 2337| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2337| Type = [VoidType] void +# 2337| ValueCategory = prvalue +# 2337| getQualifier(): [VariableAccess] s2 +# 2337| Type = [Struct] String +# 2337| ValueCategory = lvalue +# 2337| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool +# 2337| Type = [VoidType] void +# 2337| ValueCategory = prvalue +# 2337| getQualifier(): [VariableAccess] B +# 2337| Type = [Class] Bool +# 2337| ValueCategory = lvalue +# 2338| getStmt(1): [ReturnStmt] return ... +# 2340| [TopLevelFunction] void WhileLoopDestructors(bool) +# 2340| : +# 2340| getParameter(0): [Parameter] b +# 2340| Type = [BoolType] bool +# 2340| getEntryPoint(): [BlockStmt] { ... } +# 2341| getStmt(0): [BlockStmt] { ... } +# 2342| getStmt(0): [DeclStmt] declaration +# 2342| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2342| Type = [Struct] String +# 2342| getVariable().getInitializer(): [Initializer] initializer for s +# 2342| getExpr(): [ConstructorCall] call to String +# 2342| Type = [VoidType] void +# 2342| ValueCategory = prvalue +# 2343| getStmt(1): [WhileStmt] while (...) ... +# 2343| getCondition(): [VariableAccess] b +# 2343| Type = [BoolType] bool +# 2343| ValueCategory = prvalue(load) +# 2343| getStmt(): [BlockStmt] { ... } +# 2344| getStmt(0): [ExprStmt] ExprStmt +# 2344| getExpr(): [AssignExpr] ... = ... +# 2344| Type = [BoolType] bool +# 2344| ValueCategory = lvalue +# 2344| getLValue(): [VariableAccess] b +# 2344| Type = [BoolType] bool +# 2344| ValueCategory = lvalue +# 2344| getRValue(): [Literal] 0 +# 2344| Type = [BoolType] bool +# 2344| Value = [Literal] 0 +# 2344| ValueCategory = prvalue +# 2346| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2346| Type = [VoidType] void +# 2346| ValueCategory = prvalue +# 2346| getQualifier(): [VariableAccess] s +# 2346| Type = [Struct] String +# 2346| ValueCategory = lvalue +# 2348| getStmt(1): [BlockStmt] { ... } +# 2349| getStmt(0): [WhileStmt] while (...) ... +# 2349| getCondition(): [ConditionDeclExpr] (condition decl) +# 2349| Type = [BoolType] bool +# 2349| ValueCategory = prvalue +# 2349| getChild(0): [FunctionCall] call to operator bool +# 2349| Type = [BoolType] bool +# 2349| ValueCategory = prvalue +# 2349| getQualifier(): [VariableAccess] B +# 2349| Type = [Class] Bool +# 2349| ValueCategory = prvalue(load) +# 2349| getInitializingExpr(): [ConstructorCall] call to Bool +# 2349| Type = [VoidType] void +# 2349| ValueCategory = prvalue +# 2349| getArgument(0): [VariableAccess] b # 2349| Type = [BoolType] bool -# 2349| ValueCategory = lvalue -# 2349| getLValue(): [VariableAccess] b -# 2349| Type = [BoolType] bool -# 2349| ValueCategory = lvalue -# 2349| getRValue(): [Literal] 0 -# 2349| Type = [BoolType] bool -# 2349| Value = [Literal] 0 -# 2349| ValueCategory = prvalue -# 2350| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool -# 2350| Type = [VoidType] void -# 2350| ValueCategory = prvalue -# 2350| getQualifier(): [VariableAccess] B -# 2350| Type = [Class] Bool +# 2349| ValueCategory = prvalue(load) +# 2349| getStmt(): [BlockStmt] { ... } +# 2350| getStmt(0): [ExprStmt] ExprStmt +# 2350| getExpr(): [AssignExpr] ... = ... +# 2350| Type = [BoolType] bool # 2350| ValueCategory = lvalue -# 2350| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool -# 2350| Type = [VoidType] void -# 2350| ValueCategory = prvalue -# 2350| getQualifier(): [VariableAccess] B -# 2350| Type = [Class] Bool -# 2350| ValueCategory = lvalue -# 2352| getStmt(2): [ReturnStmt] return ... -# 2354| [TopLevelFunction] void VoidFunc() -# 2354| : -# 2354| getEntryPoint(): [BlockStmt] { ... } -# 2354| getStmt(0): [ReturnStmt] return ... -# 2356| [TopLevelFunction] void IfReturnDestructors(bool) -# 2356| : -# 2356| getParameter(0): [Parameter] b -# 2356| Type = [BoolType] bool -# 2356| getEntryPoint(): [BlockStmt] { ... } -# 2357| getStmt(0): [DeclStmt] declaration -# 2357| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2357| Type = [Struct] String -# 2357| getVariable().getInitializer(): [Initializer] initializer for s -# 2357| getExpr(): [ConstructorCall] call to String -# 2357| Type = [VoidType] void -# 2357| ValueCategory = prvalue -# 2358| getStmt(1): [IfStmt] if (...) ... -# 2358| getCondition(): [VariableAccess] b -# 2358| Type = [BoolType] bool -# 2358| ValueCategory = prvalue(load) -# 2358| getThen(): [BlockStmt] { ... } -# 2359| getStmt(0): [ReturnStmt] return ... -# 2365| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2365| Type = [VoidType] void -# 2365| ValueCategory = prvalue -# 2365| getQualifier(): [VariableAccess] s -# 2365| Type = [Struct] String -# 2365| ValueCategory = lvalue -# 2361| getStmt(2): [IfStmt] if (...) ... -# 2361| getCondition(): [VariableAccess] b -# 2361| Type = [BoolType] bool -# 2361| ValueCategory = prvalue(load) -# 2361| getThen(): [BlockStmt] { ... } -# 2362| getStmt(0): [ReturnStmt] return ... -# 2362| getExpr(): [FunctionCall] call to VoidFunc -# 2362| Type = [VoidType] void -# 2362| ValueCategory = prvalue -# 2365| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2365| Type = [VoidType] void -# 2365| ValueCategory = prvalue -# 2365| getQualifier(): [VariableAccess] s -# 2365| Type = [Struct] String -# 2365| ValueCategory = lvalue -# 2364| getStmt(3): [ExprStmt] ExprStmt -# 2364| getExpr(): [VariableAccess] s -# 2364| Type = [Struct] String -# 2364| ValueCategory = lvalue -# 2365| getStmt(4): [ReturnStmt] return ... -# 2365| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2365| Type = [VoidType] void -# 2365| ValueCategory = prvalue -# 2365| getQualifier(): [VariableAccess] s -# 2365| Type = [Struct] String -# 2365| ValueCategory = lvalue -# 2367| [TopLevelFunction] int IfReturnDestructors3(bool) -# 2367| : -# 2367| getParameter(0): [Parameter] b -# 2367| Type = [BoolType] bool -# 2367| getEntryPoint(): [BlockStmt] { ... } -# 2368| getStmt(0): [DeclStmt] declaration -# 2368| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2368| Type = [Struct] String -# 2368| getVariable().getInitializer(): [Initializer] initializer for s -# 2368| getExpr(): [ConstructorCall] call to String -# 2368| Type = [VoidType] void -# 2368| ValueCategory = prvalue -# 2369| getStmt(1): [IfStmt] if (...) ... -# 2369| getCondition(): [VariableAccess] b -# 2369| Type = [BoolType] bool -# 2369| ValueCategory = prvalue(load) -# 2369| getThen(): [BlockStmt] { ... } -# 2370| getStmt(0): [ReturnStmt] return ... -# 2370| getExpr(): [Literal] 1 -# 2370| Type = [IntType] int -# 2370| Value = [Literal] 1 -# 2370| ValueCategory = prvalue -# 2373| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2373| Type = [VoidType] void -# 2373| ValueCategory = prvalue -# 2373| getQualifier(): [VariableAccess] s -# 2373| Type = [Struct] String -# 2373| ValueCategory = lvalue -# 2372| getStmt(2): [ReturnStmt] return ... -# 2372| getExpr(): [Literal] 0 -# 2372| Type = [IntType] int -# 2372| Value = [Literal] 0 -# 2372| ValueCategory = prvalue -# 2373| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2373| Type = [VoidType] void +# 2350| getLValue(): [VariableAccess] b +# 2350| Type = [BoolType] bool +# 2350| ValueCategory = lvalue +# 2350| getRValue(): [Literal] 0 +# 2350| Type = [BoolType] bool +# 2350| Value = [Literal] 0 +# 2350| ValueCategory = prvalue +# 2351| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool +# 2351| Type = [VoidType] void +# 2351| ValueCategory = prvalue +# 2351| getQualifier(): [VariableAccess] B +# 2351| Type = [Class] Bool +# 2351| ValueCategory = lvalue +# 2351| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool +# 2351| Type = [VoidType] void +# 2351| ValueCategory = prvalue +# 2351| getQualifier(): [VariableAccess] B +# 2351| Type = [Class] Bool +# 2351| ValueCategory = lvalue +# 2353| getStmt(2): [ReturnStmt] return ... +# 2355| [TopLevelFunction] void VoidFunc() +# 2355| : +# 2355| getEntryPoint(): [BlockStmt] { ... } +# 2355| getStmt(0): [ReturnStmt] return ... +# 2357| [TopLevelFunction] void IfReturnDestructors(bool) +# 2357| : +# 2357| getParameter(0): [Parameter] b +# 2357| Type = [BoolType] bool +# 2357| getEntryPoint(): [BlockStmt] { ... } +# 2358| getStmt(0): [DeclStmt] declaration +# 2358| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2358| Type = [Struct] String +# 2358| getVariable().getInitializer(): [Initializer] initializer for s +# 2358| getExpr(): [ConstructorCall] call to String +# 2358| Type = [VoidType] void +# 2358| ValueCategory = prvalue +# 2359| getStmt(1): [IfStmt] if (...) ... +# 2359| getCondition(): [VariableAccess] b +# 2359| Type = [BoolType] bool +# 2359| ValueCategory = prvalue(load) +# 2359| getThen(): [BlockStmt] { ... } +# 2360| getStmt(0): [ReturnStmt] return ... +# 2366| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2366| Type = [VoidType] void +# 2366| ValueCategory = prvalue +# 2366| getQualifier(): [VariableAccess] s +# 2366| Type = [Struct] String +# 2366| ValueCategory = lvalue +# 2362| getStmt(2): [IfStmt] if (...) ... +# 2362| getCondition(): [VariableAccess] b +# 2362| Type = [BoolType] bool +# 2362| ValueCategory = prvalue(load) +# 2362| getThen(): [BlockStmt] { ... } +# 2363| getStmt(0): [ReturnStmt] return ... +# 2363| getExpr(): [FunctionCall] call to VoidFunc +# 2363| Type = [VoidType] void +# 2363| ValueCategory = prvalue +# 2366| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2366| Type = [VoidType] void +# 2366| ValueCategory = prvalue +# 2366| getQualifier(): [VariableAccess] s +# 2366| Type = [Struct] String +# 2366| ValueCategory = lvalue +# 2365| getStmt(3): [ExprStmt] ExprStmt +# 2365| getExpr(): [VariableAccess] s +# 2365| Type = [Struct] String +# 2365| ValueCategory = lvalue +# 2366| getStmt(4): [ReturnStmt] return ... +# 2366| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2366| Type = [VoidType] void +# 2366| ValueCategory = prvalue +# 2366| getQualifier(): [VariableAccess] s +# 2366| Type = [Struct] String +# 2366| ValueCategory = lvalue +# 2368| [TopLevelFunction] int IfReturnDestructors3(bool) +# 2368| : +# 2368| getParameter(0): [Parameter] b +# 2368| Type = [BoolType] bool +# 2368| getEntryPoint(): [BlockStmt] { ... } +# 2369| getStmt(0): [DeclStmt] declaration +# 2369| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2369| Type = [Struct] String +# 2369| getVariable().getInitializer(): [Initializer] initializer for s +# 2369| getExpr(): [ConstructorCall] call to String +# 2369| Type = [VoidType] void +# 2369| ValueCategory = prvalue +# 2370| getStmt(1): [IfStmt] if (...) ... +# 2370| getCondition(): [VariableAccess] b +# 2370| Type = [BoolType] bool +# 2370| ValueCategory = prvalue(load) +# 2370| getThen(): [BlockStmt] { ... } +# 2371| getStmt(0): [ReturnStmt] return ... +# 2371| getExpr(): [Literal] 1 +# 2371| Type = [IntType] int +# 2371| Value = [Literal] 1 +# 2371| ValueCategory = prvalue +# 2374| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2374| Type = [VoidType] void +# 2374| ValueCategory = prvalue +# 2374| getQualifier(): [VariableAccess] s +# 2374| Type = [Struct] String +# 2374| ValueCategory = lvalue +# 2373| getStmt(2): [ReturnStmt] return ... +# 2373| getExpr(): [Literal] 0 +# 2373| Type = [IntType] int +# 2373| Value = [Literal] 0 # 2373| ValueCategory = prvalue -# 2373| getQualifier(): [VariableAccess] s -# 2373| Type = [Struct] String -# 2373| ValueCategory = lvalue -# 2375| [TopLevelFunction] void VoidReturnDestructors() -# 2375| : -# 2375| getEntryPoint(): [BlockStmt] { ... } -# 2376| getStmt(0): [DeclStmt] declaration -# 2376| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2376| Type = [Struct] String -# 2376| getVariable().getInitializer(): [Initializer] initializer for s -# 2376| getExpr(): [ConstructorCall] call to String -# 2376| Type = [VoidType] void -# 2376| ValueCategory = prvalue -# 2377| getStmt(1): [ReturnStmt] return ... -# 2377| getExpr(): [FunctionCall] call to VoidFunc -# 2377| Type = [VoidType] void -# 2377| ValueCategory = prvalue -# 2378| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2374| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2374| Type = [VoidType] void +# 2374| ValueCategory = prvalue +# 2374| getQualifier(): [VariableAccess] s +# 2374| Type = [Struct] String +# 2374| ValueCategory = lvalue +# 2376| [TopLevelFunction] void VoidReturnDestructors() +# 2376| : +# 2376| getEntryPoint(): [BlockStmt] { ... } +# 2377| getStmt(0): [DeclStmt] declaration +# 2377| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2377| Type = [Struct] String +# 2377| getVariable().getInitializer(): [Initializer] initializer for s +# 2377| getExpr(): [ConstructorCall] call to String +# 2377| Type = [VoidType] void +# 2377| ValueCategory = prvalue +# 2378| getStmt(1): [ReturnStmt] return ... +# 2378| getExpr(): [FunctionCall] call to VoidFunc # 2378| Type = [VoidType] void # 2378| ValueCategory = prvalue -# 2378| getQualifier(): [VariableAccess] s -# 2378| Type = [Struct] String -# 2378| ValueCategory = lvalue -# 2381| [CopyAssignmentOperator] return_routine_type::HasVoidToIntFunc& return_routine_type::HasVoidToIntFunc::operator=(return_routine_type::HasVoidToIntFunc const&) -# 2381| : +# 2379| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2379| Type = [VoidType] void +# 2379| ValueCategory = prvalue +# 2379| getQualifier(): [VariableAccess] s +# 2379| Type = [Struct] String +# 2379| ValueCategory = lvalue +# 2382| [CopyAssignmentOperator] return_routine_type::HasVoidToIntFunc& return_routine_type::HasVoidToIntFunc::operator=(return_routine_type::HasVoidToIntFunc const&) +# 2382| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [LValueReferenceType] const HasVoidToIntFunc & -# 2381| [MoveAssignmentOperator] return_routine_type::HasVoidToIntFunc& return_routine_type::HasVoidToIntFunc::operator=(return_routine_type::HasVoidToIntFunc&&) -# 2381| : +# 2382| [MoveAssignmentOperator] return_routine_type::HasVoidToIntFunc& return_routine_type::HasVoidToIntFunc::operator=(return_routine_type::HasVoidToIntFunc&&) +# 2382| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [RValueReferenceType] HasVoidToIntFunc && -# 2383| [MemberFunction] void return_routine_type::HasVoidToIntFunc::VoidToInt(int) -# 2383| : -# 2383| getParameter(0): [Parameter] (unnamed parameter 0) -# 2383| Type = [IntType] int -# 2388| [TopLevelFunction] return_routine_type::VoidToIntMemberFunc return_routine_type::GetVoidToIntFunc() -# 2388| : -# 2389| getEntryPoint(): [BlockStmt] { ... } -# 2390| getStmt(0): [ReturnStmt] return ... -# 2390| getExpr(): [FunctionAccess] VoidToInt -# 2390| Type = [RoutineType] ..()(..) -# 2390| ValueCategory = prvalue -# 2395| [TopLevelFunction] int small_operation_should_not_be_constant_folded() -# 2395| : -# 2395| getEntryPoint(): [BlockStmt] { ... } -# 2396| getStmt(0): [ReturnStmt] return ... -# 2396| getExpr(): [BitwiseXorExpr] ... ^ ... -# 2396| Type = [IntType] int -# 2396| Value = [BitwiseXorExpr] 3 -# 2396| ValueCategory = prvalue -# 2396| getLeftOperand(): [Literal] 1 -# 2396| Type = [IntType] int -# 2396| Value = [Literal] 1 -# 2396| ValueCategory = prvalue -# 2396| getRightOperand(): [Literal] 2 -# 2396| Type = [IntType] int -# 2396| Value = [Literal] 2 -# 2396| ValueCategory = prvalue -# 2406| [TopLevelFunction] int large_operation_should_be_constant_folded() -# 2406| : -# 2406| getEntryPoint(): [BlockStmt] { ... } -# 2407| getStmt(0): [ReturnStmt] return ... -# 2407| getExpr(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getExpr().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2410| [TopLevelFunction] void initialization_with_temp_destructor() -# 2410| : -# 2410| getEntryPoint(): [BlockStmt] { ... } -# 2411| getStmt(0): [IfStmt] if (...) ... -# 2411| getCondition(): [ConditionDeclExpr] (condition decl) -# 2411| Type = [BoolType] bool -# 2411| ValueCategory = prvalue -# 2411| getVariableAccess(): [VariableAccess] x -# 2411| Type = [PlainCharType] char -# 2411| ValueCategory = prvalue(load) -# 2411| getInitializingExpr(): [FunctionCall] call to get_x -# 2411| Type = [PlainCharType] char -# 2411| ValueCategory = prvalue -# 2411| getQualifier(): [ConstructorCall] call to ClassWithDestructor -# 2411| Type = [VoidType] void -# 2411| ValueCategory = prvalue -# 2411| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2411| Type = [VoidType] void -# 2411| ValueCategory = prvalue -# 2411| getQualifier(): [ReuseExpr] reuse of temporary object -# 2411| Type = [Class] ClassWithDestructor -# 2411| ValueCategory = xvalue -# 2411| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2411| Type = [Class] ClassWithDestructor -# 2411| ValueCategory = prvalue(load) -# 2411| getVariableAccess().getFullyConverted(): [CStyleCast] (bool)... -# 2411| Conversion = [BoolConversion] conversion to bool -# 2411| Type = [BoolType] bool -# 2411| ValueCategory = prvalue -# 2412| getThen(): [ExprStmt] ExprStmt -# 2412| getExpr(): [PostfixIncrExpr] ... ++ +# 2384| [MemberFunction] void return_routine_type::HasVoidToIntFunc::VoidToInt(int) +# 2384| : +# 2384| getParameter(0): [Parameter] (unnamed parameter 0) +# 2384| Type = [IntType] int +# 2389| [TopLevelFunction] return_routine_type::VoidToIntMemberFunc return_routine_type::GetVoidToIntFunc() +# 2389| : +# 2390| getEntryPoint(): [BlockStmt] { ... } +# 2391| getStmt(0): [ReturnStmt] return ... +# 2391| getExpr(): [FunctionAccess] VoidToInt +# 2391| Type = [RoutineType] ..()(..) +# 2391| ValueCategory = prvalue +# 2396| [TopLevelFunction] int small_operation_should_not_be_constant_folded() +# 2396| : +# 2396| getEntryPoint(): [BlockStmt] { ... } +# 2397| getStmt(0): [ReturnStmt] return ... +# 2397| getExpr(): [BitwiseXorExpr] ... ^ ... +# 2397| Type = [IntType] int +# 2397| Value = [BitwiseXorExpr] 3 +# 2397| ValueCategory = prvalue +# 2397| getLeftOperand(): [Literal] 1 +# 2397| Type = [IntType] int +# 2397| Value = [Literal] 1 +# 2397| ValueCategory = prvalue +# 2397| getRightOperand(): [Literal] 2 +# 2397| Type = [IntType] int +# 2397| Value = [Literal] 2 +# 2397| ValueCategory = prvalue +# 2407| [TopLevelFunction] int large_operation_should_be_constant_folded() +# 2407| : +# 2407| getEntryPoint(): [BlockStmt] { ... } +# 2408| getStmt(0): [ReturnStmt] return ... +# 2408| getExpr(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2411| [TopLevelFunction] void initialization_with_temp_destructor() +# 2411| : +# 2411| getEntryPoint(): [BlockStmt] { ... } +# 2412| getStmt(0): [IfStmt] if (...) ... +# 2412| getCondition(): [ConditionDeclExpr] (condition decl) +# 2412| Type = [BoolType] bool +# 2412| ValueCategory = prvalue +# 2412| getVariableAccess(): [VariableAccess] x # 2412| Type = [PlainCharType] char +# 2412| ValueCategory = prvalue(load) +# 2412| getInitializingExpr(): [FunctionCall] call to get_x +# 2412| Type = [PlainCharType] char +# 2412| ValueCategory = prvalue +# 2412| getQualifier(): [ConstructorCall] call to ClassWithDestructor +# 2412| Type = [VoidType] void +# 2412| ValueCategory = prvalue +# 2412| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2412| Type = [VoidType] void +# 2412| ValueCategory = prvalue +# 2412| getQualifier(): [ReuseExpr] reuse of temporary object +# 2412| Type = [Class] ClassWithDestructor +# 2412| ValueCategory = xvalue +# 2412| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2412| Type = [Class] ClassWithDestructor +# 2412| ValueCategory = prvalue(load) +# 2412| getVariableAccess().getFullyConverted(): [CStyleCast] (bool)... +# 2412| Conversion = [BoolConversion] conversion to bool +# 2412| Type = [BoolType] bool # 2412| ValueCategory = prvalue -# 2412| getOperand(): [VariableAccess] x -# 2412| Type = [PlainCharType] char -# 2412| ValueCategory = lvalue -# 2414| getStmt(1): [IfStmt] if (...) ... -# 2414| getInitialization(): [DeclStmt] declaration -# 2414| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2414| Type = [PlainCharType] char -# 2414| getVariable().getInitializer(): [Initializer] initializer for x -# 2414| getExpr(): [FunctionCall] call to get_x -# 2414| Type = [PlainCharType] char -# 2414| ValueCategory = prvalue -# 2414| getQualifier(): [ConstructorCall] call to ClassWithDestructor -# 2414| Type = [VoidType] void -# 2414| ValueCategory = prvalue -# 2414| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2414| Type = [VoidType] void -# 2414| ValueCategory = prvalue -# 2414| getQualifier(): [ReuseExpr] reuse of temporary object -# 2414| Type = [Class] ClassWithDestructor -# 2414| ValueCategory = xvalue -# 2414| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2414| Type = [Class] ClassWithDestructor -# 2414| ValueCategory = prvalue(load) -# 2414| getCondition(): [VariableAccess] x -# 2414| Type = [PlainCharType] char -# 2414| ValueCategory = prvalue(load) -# 2415| getThen(): [ExprStmt] ExprStmt -# 2415| getExpr(): [PostfixIncrExpr] ... ++ +# 2413| getThen(): [ExprStmt] ExprStmt +# 2413| getExpr(): [PostfixIncrExpr] ... ++ +# 2413| Type = [PlainCharType] char +# 2413| ValueCategory = prvalue +# 2413| getOperand(): [VariableAccess] x +# 2413| Type = [PlainCharType] char +# 2413| ValueCategory = lvalue +# 2415| getStmt(1): [IfStmt] if (...) ... +# 2415| getInitialization(): [DeclStmt] declaration +# 2415| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x # 2415| Type = [PlainCharType] char -# 2415| ValueCategory = prvalue -# 2415| getOperand(): [VariableAccess] x -# 2415| Type = [PlainCharType] char -# 2415| ValueCategory = lvalue -# 2414| getCondition().getFullyConverted(): [CStyleCast] (bool)... -# 2414| Conversion = [BoolConversion] conversion to bool -# 2414| Type = [BoolType] bool -# 2414| ValueCategory = prvalue -# 2417| getStmt(2): [ConstexprIfStmt] if constexpr (...) ... -# 2417| getInitialization(): [DeclStmt] declaration -# 2417| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2417| Type = [PlainCharType] char -# 2417| getVariable().getInitializer(): [Initializer] initializer for x -# 2417| getExpr(): [FunctionCall] call to get_x -# 2417| Type = [PlainCharType] char -# 2417| ValueCategory = prvalue -# 2417| getQualifier(): [ConstructorCall] call to ClassWithDestructor -# 2417| Type = [VoidType] void -# 2417| ValueCategory = prvalue -# 2417| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2417| Type = [VoidType] void -# 2417| ValueCategory = prvalue -# 2417| getQualifier(): [ReuseExpr] reuse of temporary object -# 2417| Type = [Class] ClassWithDestructor -# 2417| ValueCategory = xvalue -# 2417| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2417| Type = [Class] ClassWithDestructor -# 2417| ValueCategory = prvalue(load) -# 2417| getCondition(): [VariableAccess] initialization_with_destructor_bool -# 2417| Type = [BoolType] bool -# 2417| Value = [VariableAccess] 1 -# 2417| ValueCategory = prvalue(load) -# 2418| getThen(): [ExprStmt] ExprStmt -# 2418| getExpr(): [PostfixIncrExpr] ... ++ +# 2415| getVariable().getInitializer(): [Initializer] initializer for x +# 2415| getExpr(): [FunctionCall] call to get_x +# 2415| Type = [PlainCharType] char +# 2415| ValueCategory = prvalue +# 2415| getQualifier(): [ConstructorCall] call to ClassWithDestructor +# 2415| Type = [VoidType] void +# 2415| ValueCategory = prvalue +# 2415| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2415| Type = [VoidType] void +# 2415| ValueCategory = prvalue +# 2415| getQualifier(): [ReuseExpr] reuse of temporary object +# 2415| Type = [Class] ClassWithDestructor +# 2415| ValueCategory = xvalue +# 2415| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2415| Type = [Class] ClassWithDestructor +# 2415| ValueCategory = prvalue(load) +# 2415| getCondition(): [VariableAccess] x +# 2415| Type = [PlainCharType] char +# 2415| ValueCategory = prvalue(load) +# 2416| getThen(): [ExprStmt] ExprStmt +# 2416| getExpr(): [PostfixIncrExpr] ... ++ +# 2416| Type = [PlainCharType] char +# 2416| ValueCategory = prvalue +# 2416| getOperand(): [VariableAccess] x +# 2416| Type = [PlainCharType] char +# 2416| ValueCategory = lvalue +# 2415| getCondition().getFullyConverted(): [CStyleCast] (bool)... +# 2415| Conversion = [BoolConversion] conversion to bool +# 2415| Type = [BoolType] bool +# 2415| ValueCategory = prvalue +# 2418| getStmt(2): [ConstexprIfStmt] if constexpr (...) ... +# 2418| getInitialization(): [DeclStmt] declaration +# 2418| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x # 2418| Type = [PlainCharType] char -# 2418| ValueCategory = prvalue -# 2418| getOperand(): [VariableAccess] x -# 2418| Type = [PlainCharType] char -# 2418| ValueCategory = lvalue -# 2420| getStmt(3): [SwitchStmt] switch (...) ... -# 2420| getExpr(): [ConditionDeclExpr] (condition decl) -# 2420| Type = [IntType] int -# 2420| ValueCategory = prvalue -# 2420| getVariableAccess(): [VariableAccess] x -# 2420| Type = [PlainCharType] char -# 2420| ValueCategory = prvalue(load) -# 2420| getInitializingExpr(): [FunctionCall] call to get_x -# 2420| Type = [PlainCharType] char -# 2420| ValueCategory = prvalue -# 2420| getQualifier(): [ConstructorCall] call to ClassWithDestructor -# 2420| Type = [VoidType] void -# 2420| ValueCategory = prvalue -# 2420| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2420| Type = [VoidType] void -# 2420| ValueCategory = prvalue -# 2420| getQualifier(): [ReuseExpr] reuse of temporary object -# 2420| Type = [Class] ClassWithDestructor -# 2420| ValueCategory = xvalue -# 2420| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2420| Type = [Class] ClassWithDestructor -# 2420| ValueCategory = prvalue(load) -# 2420| getVariableAccess().getFullyConverted(): [CStyleCast] (int)... -# 2420| Conversion = [IntegralConversion] integral conversion -# 2420| Type = [IntType] int -# 2420| ValueCategory = prvalue -# 2420| getStmt(): [BlockStmt] { ... } -# 2421| getStmt(0): [SwitchCase] case ...: -# 2421| getExpr(): [CharLiteral] 97 -# 2421| Type = [PlainCharType] char -# 2421| Value = [CharLiteral] 97 +# 2418| getVariable().getInitializer(): [Initializer] initializer for x +# 2418| getExpr(): [FunctionCall] call to get_x +# 2418| Type = [PlainCharType] char +# 2418| ValueCategory = prvalue +# 2418| getQualifier(): [ConstructorCall] call to ClassWithDestructor +# 2418| Type = [VoidType] void +# 2418| ValueCategory = prvalue +# 2418| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2418| Type = [VoidType] void +# 2418| ValueCategory = prvalue +# 2418| getQualifier(): [ReuseExpr] reuse of temporary object +# 2418| Type = [Class] ClassWithDestructor +# 2418| ValueCategory = xvalue +# 2418| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2418| Type = [Class] ClassWithDestructor +# 2418| ValueCategory = prvalue(load) +# 2418| getCondition(): [VariableAccess] initialization_with_destructor_bool +# 2418| Type = [BoolType] bool +# 2418| Value = [VariableAccess] 1 +# 2418| ValueCategory = prvalue(load) +# 2419| getThen(): [ExprStmt] ExprStmt +# 2419| getExpr(): [PostfixIncrExpr] ... ++ +# 2419| Type = [PlainCharType] char +# 2419| ValueCategory = prvalue +# 2419| getOperand(): [VariableAccess] x +# 2419| Type = [PlainCharType] char +# 2419| ValueCategory = lvalue +# 2421| getStmt(3): [SwitchStmt] switch (...) ... +# 2421| getExpr(): [ConditionDeclExpr] (condition decl) +# 2421| Type = [IntType] int +# 2421| ValueCategory = prvalue +# 2421| getVariableAccess(): [VariableAccess] x +# 2421| Type = [PlainCharType] char +# 2421| ValueCategory = prvalue(load) +# 2421| getInitializingExpr(): [FunctionCall] call to get_x +# 2421| Type = [PlainCharType] char +# 2421| ValueCategory = prvalue +# 2421| getQualifier(): [ConstructorCall] call to ClassWithDestructor +# 2421| Type = [VoidType] void # 2421| ValueCategory = prvalue -# 2421| getExpr().getFullyConverted(): [CStyleCast] (int)... -# 2421| Conversion = [IntegralConversion] integral conversion -# 2421| Type = [IntType] int -# 2421| Value = [CStyleCast] 97 +# 2421| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2421| Type = [VoidType] void # 2421| ValueCategory = prvalue -# 2422| getStmt(1): [ExprStmt] ExprStmt -# 2422| getExpr(): [PostfixIncrExpr] ... ++ +# 2421| getQualifier(): [ReuseExpr] reuse of temporary object +# 2421| Type = [Class] ClassWithDestructor +# 2421| ValueCategory = xvalue +# 2421| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2421| Type = [Class] ClassWithDestructor +# 2421| ValueCategory = prvalue(load) +# 2421| getVariableAccess().getFullyConverted(): [CStyleCast] (int)... +# 2421| Conversion = [IntegralConversion] integral conversion +# 2421| Type = [IntType] int +# 2421| ValueCategory = prvalue +# 2421| getStmt(): [BlockStmt] { ... } +# 2422| getStmt(0): [SwitchCase] case ...: +# 2422| getExpr(): [CharLiteral] 97 # 2422| Type = [PlainCharType] char +# 2422| Value = [CharLiteral] 97 +# 2422| ValueCategory = prvalue +# 2422| getExpr().getFullyConverted(): [CStyleCast] (int)... +# 2422| Conversion = [IntegralConversion] integral conversion +# 2422| Type = [IntType] int +# 2422| Value = [CStyleCast] 97 # 2422| ValueCategory = prvalue -# 2422| getOperand(): [VariableAccess] x -# 2422| Type = [PlainCharType] char -# 2422| ValueCategory = lvalue -# 2425| getStmt(4): [SwitchStmt] switch (...) ... -# 2425| getInitialization(): [DeclStmt] declaration -# 2425| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2425| Type = [PlainCharType] char -# 2425| getVariable().getInitializer(): [Initializer] initializer for x -# 2425| getExpr(): [FunctionCall] call to get_x -# 2425| Type = [PlainCharType] char -# 2425| ValueCategory = prvalue -# 2425| getQualifier(): [ConstructorCall] call to ClassWithDestructor -# 2425| Type = [VoidType] void -# 2425| ValueCategory = prvalue -# 2425| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2425| Type = [VoidType] void -# 2425| ValueCategory = prvalue -# 2425| getQualifier(): [ReuseExpr] reuse of temporary object -# 2425| Type = [Class] ClassWithDestructor -# 2425| ValueCategory = xvalue -# 2425| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2425| Type = [Class] ClassWithDestructor -# 2425| ValueCategory = prvalue(load) -# 2425| getExpr(): [VariableAccess] x -# 2425| Type = [PlainCharType] char -# 2425| ValueCategory = prvalue(load) -# 2425| getStmt(): [BlockStmt] { ... } -# 2426| getStmt(0): [SwitchCase] case ...: -# 2426| getExpr(): [CharLiteral] 97 -# 2426| Type = [PlainCharType] char -# 2426| Value = [CharLiteral] 97 -# 2426| ValueCategory = prvalue -# 2426| getExpr().getFullyConverted(): [CStyleCast] (int)... -# 2426| Conversion = [IntegralConversion] integral conversion -# 2426| Type = [IntType] int -# 2426| Value = [CStyleCast] 97 -# 2426| ValueCategory = prvalue -# 2427| getStmt(1): [ExprStmt] ExprStmt -# 2427| getExpr(): [PostfixIncrExpr] ... ++ +# 2423| getStmt(1): [ExprStmt] ExprStmt +# 2423| getExpr(): [PostfixIncrExpr] ... ++ +# 2423| Type = [PlainCharType] char +# 2423| ValueCategory = prvalue +# 2423| getOperand(): [VariableAccess] x +# 2423| Type = [PlainCharType] char +# 2423| ValueCategory = lvalue +# 2426| getStmt(4): [SwitchStmt] switch (...) ... +# 2426| getInitialization(): [DeclStmt] declaration +# 2426| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2426| Type = [PlainCharType] char +# 2426| getVariable().getInitializer(): [Initializer] initializer for x +# 2426| getExpr(): [FunctionCall] call to get_x +# 2426| Type = [PlainCharType] char +# 2426| ValueCategory = prvalue +# 2426| getQualifier(): [ConstructorCall] call to ClassWithDestructor +# 2426| Type = [VoidType] void +# 2426| ValueCategory = prvalue +# 2426| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2426| Type = [VoidType] void +# 2426| ValueCategory = prvalue +# 2426| getQualifier(): [ReuseExpr] reuse of temporary object +# 2426| Type = [Class] ClassWithDestructor +# 2426| ValueCategory = xvalue +# 2426| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2426| Type = [Class] ClassWithDestructor +# 2426| ValueCategory = prvalue(load) +# 2426| getExpr(): [VariableAccess] x +# 2426| Type = [PlainCharType] char +# 2426| ValueCategory = prvalue(load) +# 2426| getStmt(): [BlockStmt] { ... } +# 2427| getStmt(0): [SwitchCase] case ...: +# 2427| getExpr(): [CharLiteral] 97 # 2427| Type = [PlainCharType] char +# 2427| Value = [CharLiteral] 97 # 2427| ValueCategory = prvalue -# 2427| getOperand(): [VariableAccess] x -# 2427| Type = [PlainCharType] char -# 2427| ValueCategory = lvalue -# 2425| getExpr().getFullyConverted(): [CStyleCast] (int)... -# 2425| Conversion = [IntegralConversion] integral conversion -# 2425| Type = [IntType] int -# 2425| ValueCategory = prvalue -# 2430| getStmt(5): [RangeBasedForStmt] for(...:...) ... -# 2430| getInitialization(): [DeclStmt] declaration -# 2430| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2430| Type = [PlainCharType] char -# 2430| getVariable().getInitializer(): [Initializer] initializer for x -# 2430| getExpr(): [FunctionCall] call to get_x -# 2430| Type = [PlainCharType] char -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [ConstructorCall] call to ClassWithDestructor -# 2430| Type = [VoidType] void -# 2430| ValueCategory = prvalue -# 2430| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2430| Type = [VoidType] void -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [ReuseExpr] reuse of temporary object -# 2430| Type = [Class] ClassWithDestructor -# 2430| ValueCategory = xvalue -# 2430| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2430| Type = [Class] ClassWithDestructor -# 2430| ValueCategory = prvalue(load) -# 2430| getChild(1): [DeclStmt] declaration -# 2430| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) -# 2430| Type = [RValueReferenceType] vector && +# 2427| getExpr().getFullyConverted(): [CStyleCast] (int)... +# 2427| Conversion = [IntegralConversion] integral conversion +# 2427| Type = [IntType] int +# 2427| Value = [CStyleCast] 97 +# 2427| ValueCategory = prvalue +# 2428| getStmt(1): [ExprStmt] ExprStmt +# 2428| getExpr(): [PostfixIncrExpr] ... ++ +# 2428| Type = [PlainCharType] char +# 2428| ValueCategory = prvalue +# 2428| getOperand(): [VariableAccess] x +# 2428| Type = [PlainCharType] char +# 2428| ValueCategory = lvalue +# 2426| getExpr().getFullyConverted(): [CStyleCast] (int)... +# 2426| Conversion = [IntegralConversion] integral conversion +# 2426| Type = [IntType] int +# 2426| ValueCategory = prvalue +# 2431| getStmt(5): [RangeBasedForStmt] for(...:...) ... +# 2431| getInitialization(): [DeclStmt] declaration +# 2431| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2431| Type = [PlainCharType] char +# 2431| getVariable().getInitializer(): [Initializer] initializer for x +# 2431| getExpr(): [FunctionCall] call to get_x +# 2431| Type = [PlainCharType] char +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [ConstructorCall] call to ClassWithDestructor +# 2431| Type = [VoidType] void +# 2431| ValueCategory = prvalue +# 2431| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2431| Type = [VoidType] void +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [ReuseExpr] reuse of temporary object +# 2431| Type = [Class] ClassWithDestructor +# 2431| ValueCategory = xvalue +# 2431| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2431| Type = [Class] ClassWithDestructor +# 2431| ValueCategory = prvalue(load) +# 2431| getChild(1): [DeclStmt] declaration +# 2431| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) +# 2431| Type = [RValueReferenceType] vector && #-----| getVariable().getInitializer(): [Initializer] initializer for (__range) -# 2430| getExpr(): [ConstructorCall] call to vector -# 2430| Type = [VoidType] void -# 2430| ValueCategory = prvalue -# 2430| getArgument(0): [VariableAccess] x -# 2430| Type = [PlainCharType] char -# 2430| ValueCategory = prvalue(load) -# 2430| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2430| Type = [LValueReferenceType] vector & -# 2430| ValueCategory = prvalue -# 2430| getExpr(): [TemporaryObjectExpr] temporary object -# 2430| Type = [ClassTemplateInstantiation,Struct] vector -# 2430| ValueCategory = xvalue -# 2430| getBeginEndDeclaration(): [DeclStmt] declaration -# 2430| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| getExpr(): [ConstructorCall] call to vector +# 2431| Type = [VoidType] void +# 2431| ValueCategory = prvalue +# 2431| getArgument(0): [VariableAccess] x +# 2431| Type = [PlainCharType] char +# 2431| ValueCategory = prvalue(load) +# 2431| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2431| Type = [LValueReferenceType] vector & +# 2431| ValueCategory = prvalue +# 2431| getExpr(): [TemporaryObjectExpr] temporary object +# 2431| Type = [ClassTemplateInstantiation,Struct] vector +# 2431| ValueCategory = xvalue +# 2431| getBeginEndDeclaration(): [DeclStmt] declaration +# 2431| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__begin) -# 2430| getExpr(): [FunctionCall] call to begin -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [VariableAccess] (__range) -# 2430| Type = [RValueReferenceType] vector && -# 2430| ValueCategory = prvalue(load) +# 2431| getExpr(): [FunctionCall] call to begin +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [VariableAccess] (__range) +# 2431| Type = [RValueReferenceType] vector && +# 2431| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -22107,15 +22131,15 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2430| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__end) -# 2430| getExpr(): [FunctionCall] call to end -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [VariableAccess] (__range) -# 2430| Type = [RValueReferenceType] vector && -# 2430| ValueCategory = prvalue(load) +# 2431| getExpr(): [FunctionCall] call to end +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [VariableAccess] (__range) +# 2431| Type = [RValueReferenceType] vector && +# 2431| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -22123,18 +22147,18 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2430| getCondition(): [FunctionCall] call to operator!= -# 2430| Type = [BoolType] bool -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [VariableAccess] (__begin) -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2430| ValueCategory = lvalue -# 2430| getArgument(0): [ConstructorCall] call to iterator -# 2430| Type = [VoidType] void -# 2430| ValueCategory = prvalue -# 2430| getArgument(0): [VariableAccess] (__end) -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2430| ValueCategory = lvalue +# 2431| getCondition(): [FunctionCall] call to operator!= +# 2431| Type = [BoolType] bool +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [VariableAccess] (__begin) +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| ValueCategory = lvalue +# 2431| getArgument(0): [ConstructorCall] call to iterator +# 2431| Type = [VoidType] void +# 2431| ValueCategory = prvalue +# 2431| getArgument(0): [VariableAccess] (__end) +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| ValueCategory = lvalue #-----| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) #-----| Type = [LValueReferenceType] const iterator & #-----| ValueCategory = prvalue @@ -22149,191 +22173,567 @@ ir.cpp: #-----| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object #-----| Type = [ClassTemplateInstantiation,Struct] iterator #-----| ValueCategory = lvalue -# 2430| getUpdate(): [FunctionCall] call to operator++ -# 2430| Type = [LValueReferenceType] iterator & -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [VariableAccess] (__begin) -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2430| ValueCategory = lvalue -# 2430| getChild(5): [DeclStmt] declaration -# 2430| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y -# 2430| Type = [PlainCharType] char -# 2430| getVariable().getInitializer(): [Initializer] initializer for y -# 2430| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* -# 2430| Type = [LValueReferenceType] char & -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [VariableAccess] (__begin) -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2430| ValueCategory = lvalue +# 2431| getUpdate(): [FunctionCall] call to operator++ +# 2431| Type = [LValueReferenceType] iterator & +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [VariableAccess] (__begin) +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| ValueCategory = lvalue +# 2431| getChild(5): [DeclStmt] declaration +# 2431| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2431| Type = [PlainCharType] char +# 2431| getVariable().getInitializer(): [Initializer] initializer for y +# 2431| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* +# 2431| Type = [LValueReferenceType] char & +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [VariableAccess] (__begin) +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| ValueCategory = lvalue #-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const iterator #-----| ValueCategory = lvalue -# 2430| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2430| Type = [PlainCharType] char -# 2430| ValueCategory = prvalue(load) -# 2431| getStmt(): [ExprStmt] ExprStmt -# 2431| getExpr(): [AssignAddExpr] ... += ... -# 2431| Type = [PlainCharType] char -# 2431| ValueCategory = lvalue -# 2431| getLValue(): [VariableAccess] y -# 2431| Type = [PlainCharType] char -# 2431| ValueCategory = lvalue -# 2431| getRValue(): [VariableAccess] x -# 2431| Type = [PlainCharType] char -# 2431| ValueCategory = prvalue(load) -# 2431| getRValue().getFullyConverted(): [CStyleCast] (int)... -# 2431| Conversion = [IntegralConversion] integral conversion -# 2431| Type = [IntType] int -# 2431| ValueCategory = prvalue -# 2430| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2430| Type = [ClassTemplateInstantiation,Struct] iterator -# 2430| ValueCategory = lvalue -# 2432| getStmt(6): [ReturnStmt] return ... -# 2434| [TopLevelFunction] void param_with_destructor_by_value(ClassWithDestructor) -# 2434| : -# 2434| getParameter(0): [Parameter] c -# 2434| Type = [Class] ClassWithDestructor -# 2434| getEntryPoint(): [BlockStmt] { ... } -# 2436| getStmt(0): [ReturnStmt] return ... -# 2438| [TopLevelFunction] void param_with_destructor_by_pointer(ClassWithDestructor*) -# 2438| : -# 2438| getParameter(0): [Parameter] c -# 2438| Type = [PointerType] ClassWithDestructor * -# 2438| getEntryPoint(): [BlockStmt] { ... } -# 2440| getStmt(0): [ReturnStmt] return ... -# 2442| [TopLevelFunction] void param_with_destructor_by_ref(ClassWithDestructor&) -# 2442| : -# 2442| getParameter(0): [Parameter] c -# 2442| Type = [LValueReferenceType] ClassWithDestructor & -# 2442| getEntryPoint(): [BlockStmt] { ... } -# 2444| getStmt(0): [ReturnStmt] return ... -# 2446| [TopLevelFunction] void param_with_destructor_by_rref(ClassWithDestructor&&) -# 2446| : -# 2446| getParameter(0): [Parameter] c -# 2446| Type = [RValueReferenceType] ClassWithDestructor && -# 2446| getEntryPoint(): [BlockStmt] { ... } -# 2448| getStmt(0): [ReturnStmt] return ... -# 2450| [TopLevelFunction] void rethrow_with_destruction(int) -# 2450| : -# 2450| getParameter(0): [Parameter] x -# 2450| Type = [IntType] int -# 2450| getEntryPoint(): [BlockStmt] { ... } -# 2451| getStmt(0): [DeclStmt] declaration -# 2451| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c -# 2451| Type = [Class] ClassWithDestructor -# 2451| getVariable().getInitializer(): [Initializer] initializer for c -# 2451| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2451| Type = [VoidType] void -# 2451| ValueCategory = prvalue -# 2452| getStmt(1): [ExprStmt] ExprStmt -# 2452| getExpr(): [ReThrowExpr] re-throw exception -# 2452| Type = [VoidType] void -# 2452| ValueCategory = prvalue -# 2453| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2453| Type = [VoidType] void -# 2453| ValueCategory = prvalue -# 2453| getQualifier(): [VariableAccess] c -# 2453| Type = [Class] ClassWithDestructor -# 2453| ValueCategory = lvalue -# 2455| [CopyAssignmentOperator] ByValueConstructor& ByValueConstructor::operator=(ByValueConstructor const&) -# 2455| : +# 2431| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2431| Type = [PlainCharType] char +# 2431| ValueCategory = prvalue(load) +# 2432| getStmt(): [ExprStmt] ExprStmt +# 2432| getExpr(): [AssignAddExpr] ... += ... +# 2432| Type = [PlainCharType] char +# 2432| ValueCategory = lvalue +# 2432| getLValue(): [VariableAccess] y +# 2432| Type = [PlainCharType] char +# 2432| ValueCategory = lvalue +# 2432| getRValue(): [VariableAccess] x +# 2432| Type = [PlainCharType] char +# 2432| ValueCategory = prvalue(load) +# 2432| getRValue().getFullyConverted(): [CStyleCast] (int)... +# 2432| Conversion = [IntegralConversion] integral conversion +# 2432| Type = [IntType] int +# 2432| ValueCategory = prvalue +# 2431| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2431| Type = [VoidType] void +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [ReuseExpr] reuse of temporary object +# 2431| Type = [ClassTemplateInstantiation,Struct] vector +# 2431| ValueCategory = xvalue +# 2431| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2431| Type = [ClassTemplateInstantiation,Struct] iterator +# 2431| ValueCategory = lvalue +# 2433| getStmt(6): [ReturnStmt] return ... +# 2435| [TopLevelFunction] void param_with_destructor_by_value(ClassWithDestructor) +# 2435| : +# 2435| getParameter(0): [Parameter] c +# 2435| Type = [Class] ClassWithDestructor +# 2435| getEntryPoint(): [BlockStmt] { ... } +# 2437| getStmt(0): [ReturnStmt] return ... +# 2439| [TopLevelFunction] void param_with_destructor_by_pointer(ClassWithDestructor*) +# 2439| : +# 2439| getParameter(0): [Parameter] c +# 2439| Type = [PointerType] ClassWithDestructor * +# 2439| getEntryPoint(): [BlockStmt] { ... } +# 2441| getStmt(0): [ReturnStmt] return ... +# 2443| [TopLevelFunction] void param_with_destructor_by_ref(ClassWithDestructor&) +# 2443| : +# 2443| getParameter(0): [Parameter] c +# 2443| Type = [LValueReferenceType] ClassWithDestructor & +# 2443| getEntryPoint(): [BlockStmt] { ... } +# 2445| getStmt(0): [ReturnStmt] return ... +# 2447| [TopLevelFunction] void param_with_destructor_by_rref(ClassWithDestructor&&) +# 2447| : +# 2447| getParameter(0): [Parameter] c +# 2447| Type = [RValueReferenceType] ClassWithDestructor && +# 2447| getEntryPoint(): [BlockStmt] { ... } +# 2449| getStmt(0): [ReturnStmt] return ... +# 2451| [TopLevelFunction] void rethrow_with_destruction(int) +# 2451| : +# 2451| getParameter(0): [Parameter] x +# 2451| Type = [IntType] int +# 2451| getEntryPoint(): [BlockStmt] { ... } +# 2452| getStmt(0): [DeclStmt] declaration +# 2452| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c +# 2452| Type = [Class] ClassWithDestructor +# 2452| getVariable().getInitializer(): [Initializer] initializer for c +# 2452| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2452| Type = [VoidType] void +# 2452| ValueCategory = prvalue +# 2453| getStmt(1): [ExprStmt] ExprStmt +# 2453| getExpr(): [ReThrowExpr] re-throw exception +# 2453| Type = [VoidType] void +# 2453| ValueCategory = prvalue +# 2454| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2454| Type = [VoidType] void +# 2454| ValueCategory = prvalue +# 2454| getQualifier(): [VariableAccess] c +# 2454| Type = [Class] ClassWithDestructor +# 2454| ValueCategory = lvalue +# 2456| [CopyAssignmentOperator] ByValueConstructor& ByValueConstructor::operator=(ByValueConstructor const&) +# 2456| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [LValueReferenceType] const ByValueConstructor & -# 2455| [MoveAssignmentOperator] ByValueConstructor& ByValueConstructor::operator=(ByValueConstructor&&) -# 2455| : +# 2456| [MoveAssignmentOperator] ByValueConstructor& ByValueConstructor::operator=(ByValueConstructor&&) +# 2456| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [RValueReferenceType] ByValueConstructor && -# 2455| [CopyConstructor] void ByValueConstructor::ByValueConstructor(ByValueConstructor const&) -# 2455| : +# 2456| [CopyConstructor] void ByValueConstructor::ByValueConstructor(ByValueConstructor const&) +# 2456| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [LValueReferenceType] const ByValueConstructor & -# 2455| [MoveConstructor] void ByValueConstructor::ByValueConstructor(ByValueConstructor&&) -# 2455| : +# 2456| [MoveConstructor] void ByValueConstructor::ByValueConstructor(ByValueConstructor&&) +# 2456| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [RValueReferenceType] ByValueConstructor && -# 2456| [Constructor] void ByValueConstructor::ByValueConstructor(ClassWithDestructor) -# 2456| : -# 2456| getParameter(0): [Parameter] (unnamed parameter 0) -# 2456| Type = [Class] ClassWithDestructor -# 2459| [TopLevelFunction] void new_with_destructor(ClassWithDestructor) -# 2459| : -# 2459| getParameter(0): [Parameter] a -# 2459| Type = [Class] ClassWithDestructor -# 2460| getEntryPoint(): [BlockStmt] { ... } -# 2461| getStmt(0): [DeclStmt] declaration -# 2461| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b -# 2461| Type = [PointerType] ByValueConstructor * -# 2461| getVariable().getInitializer(): [Initializer] initializer for b -# 2461| getExpr(): [NewExpr] new -# 2461| Type = [PointerType] ByValueConstructor * -# 2461| ValueCategory = prvalue -# 2461| getInitializer(): [ConstructorCall] call to ByValueConstructor -# 2461| Type = [VoidType] void -# 2461| ValueCategory = prvalue -# 2461| getArgument(0): [VariableAccess] a -# 2461| Type = [Class] ClassWithDestructor -# 2461| ValueCategory = prvalue(load) -# 2461| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2461| Type = [Class] ClassWithDestructor -# 2461| ValueCategory = lvalue -# 2461| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2461| Type = [VoidType] void -# 2461| ValueCategory = prvalue -# 2461| getQualifier(): [ReuseExpr] reuse of temporary object -# 2461| Type = [Class] ClassWithDestructor -# 2461| ValueCategory = xvalue -# 2462| getStmt(1): [ReturnStmt] return ... -# 2465| [CopyAssignmentOperator] rvalue_conversion_with_destructor::A& rvalue_conversion_with_destructor::A::operator=(rvalue_conversion_with_destructor::A const&) -# 2465| : +# 2457| [Constructor] void ByValueConstructor::ByValueConstructor(ClassWithDestructor) +# 2457| : +# 2457| getParameter(0): [Parameter] (unnamed parameter 0) +# 2457| Type = [Class] ClassWithDestructor +# 2460| [TopLevelFunction] void new_with_destructor(ClassWithDestructor) +# 2460| : +# 2460| getParameter(0): [Parameter] a +# 2460| Type = [Class] ClassWithDestructor +# 2461| getEntryPoint(): [BlockStmt] { ... } +# 2462| getStmt(0): [DeclStmt] declaration +# 2462| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b +# 2462| Type = [PointerType] ByValueConstructor * +# 2462| getVariable().getInitializer(): [Initializer] initializer for b +# 2462| getExpr(): [NewExpr] new +# 2462| Type = [PointerType] ByValueConstructor * +# 2462| ValueCategory = prvalue +# 2462| getInitializer(): [ConstructorCall] call to ByValueConstructor +# 2462| Type = [VoidType] void +# 2462| ValueCategory = prvalue +# 2462| getArgument(0): [VariableAccess] a +# 2462| Type = [Class] ClassWithDestructor +# 2462| ValueCategory = prvalue(load) +# 2462| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2462| Type = [Class] ClassWithDestructor +# 2462| ValueCategory = lvalue +# 2462| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2462| Type = [VoidType] void +# 2462| ValueCategory = prvalue +# 2462| getQualifier(): [ReuseExpr] reuse of temporary object +# 2462| Type = [Class] ClassWithDestructor +# 2462| ValueCategory = xvalue +# 2463| getStmt(1): [ReturnStmt] return ... +# 2466| [CopyAssignmentOperator] rvalue_conversion_with_destructor::A& rvalue_conversion_with_destructor::A::operator=(rvalue_conversion_with_destructor::A const&) +# 2466| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [LValueReferenceType] const A & -# 2465| [MoveAssignmentOperator] rvalue_conversion_with_destructor::A& rvalue_conversion_with_destructor::A::operator=(rvalue_conversion_with_destructor::A&&) -# 2465| : +# 2466| [MoveAssignmentOperator] rvalue_conversion_with_destructor::A& rvalue_conversion_with_destructor::A::operator=(rvalue_conversion_with_destructor::A&&) +# 2466| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [RValueReferenceType] A && -# 2469| [CopyAssignmentOperator] rvalue_conversion_with_destructor::B& rvalue_conversion_with_destructor::B::operator=(rvalue_conversion_with_destructor::B const&) -# 2469| : +# 2470| [CopyAssignmentOperator] rvalue_conversion_with_destructor::B& rvalue_conversion_with_destructor::B::operator=(rvalue_conversion_with_destructor::B const&) +# 2470| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [LValueReferenceType] const B & -# 2469| [Constructor] void rvalue_conversion_with_destructor::B::B() -# 2469| : -# 2471| [Destructor] void rvalue_conversion_with_destructor::B::~B() -# 2471| : -# 2473| [ConstMemberFunction] rvalue_conversion_with_destructor::A* rvalue_conversion_with_destructor::B::operator->() const -# 2473| : -# 2476| [TopLevelFunction] rvalue_conversion_with_destructor::B rvalue_conversion_with_destructor::get() -# 2476| : -# 2478| [TopLevelFunction] void rvalue_conversion_with_destructor::test() -# 2478| : -# 2479| getEntryPoint(): [BlockStmt] { ... } -# 2480| getStmt(0): [DeclStmt] declaration -# 2480| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a -# 2480| Type = [IntType] unsigned int -# 2480| getVariable().getInitializer(): [Initializer] initializer for a -# 2480| getExpr(): [PointerFieldAccess] a -# 2480| Type = [IntType] unsigned int -# 2480| ValueCategory = prvalue(load) -# 2480| getQualifier(): [FunctionCall] call to operator-> -# 2480| Type = [PointerType] A * -# 2480| ValueCategory = prvalue -# 2480| getQualifier(): [FunctionCall] call to get -# 2480| Type = [Struct] B -# 2480| ValueCategory = prvalue -# 2480| getQualifier().getFullyConverted(): [CStyleCast] (const B)... -# 2480| Conversion = [PrvalueAdjustmentConversion] prvalue adjustment conversion -# 2480| Type = [SpecifiedType] const B -# 2480| ValueCategory = prvalue -# 2480| getExpr(): [TemporaryObjectExpr] temporary object -# 2480| Type = [Struct] B -# 2480| ValueCategory = prvalue(load) -# 2480| getImplicitDestructorCall(0): [DestructorCall] call to ~B -# 2480| Type = [VoidType] void -# 2480| ValueCategory = prvalue -# 2480| getQualifier(): [ReuseExpr] reuse of temporary object -# 2480| Type = [Struct] B -# 2480| ValueCategory = xvalue -# 2481| getStmt(1): [ReturnStmt] return ... +# 2470| [Constructor] void rvalue_conversion_with_destructor::B::B() +# 2470| : +# 2472| [Destructor] void rvalue_conversion_with_destructor::B::~B() +# 2472| : +# 2474| [ConstMemberFunction] rvalue_conversion_with_destructor::A* rvalue_conversion_with_destructor::B::operator->() const +# 2474| : +# 2477| [TopLevelFunction] rvalue_conversion_with_destructor::B rvalue_conversion_with_destructor::get() +# 2477| : +# 2479| [TopLevelFunction] void rvalue_conversion_with_destructor::test() +# 2479| : +# 2480| getEntryPoint(): [BlockStmt] { ... } +# 2481| getStmt(0): [DeclStmt] declaration +# 2481| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a +# 2481| Type = [IntType] unsigned int +# 2481| getVariable().getInitializer(): [Initializer] initializer for a +# 2481| getExpr(): [PointerFieldAccess] a +# 2481| Type = [IntType] unsigned int +# 2481| ValueCategory = prvalue(load) +# 2481| getQualifier(): [FunctionCall] call to operator-> +# 2481| Type = [PointerType] A * +# 2481| ValueCategory = prvalue +# 2481| getQualifier(): [FunctionCall] call to get +# 2481| Type = [Struct] B +# 2481| ValueCategory = prvalue +# 2481| getQualifier().getFullyConverted(): [CStyleCast] (const B)... +# 2481| Conversion = [PrvalueAdjustmentConversion] prvalue adjustment conversion +# 2481| Type = [SpecifiedType] const B +# 2481| ValueCategory = prvalue +# 2481| getExpr(): [TemporaryObjectExpr] temporary object +# 2481| Type = [Struct] B +# 2481| ValueCategory = prvalue(load) +# 2481| getImplicitDestructorCall(0): [DestructorCall] call to ~B +# 2481| Type = [VoidType] void +# 2481| ValueCategory = prvalue +# 2481| getQualifier(): [ReuseExpr] reuse of temporary object +# 2481| Type = [Struct] B +# 2481| ValueCategory = xvalue +# 2482| getStmt(1): [ReturnStmt] return ... +# 2485| [TopLevelFunction] void destructor_without_block(bool) +# 2485| : +# 2485| getParameter(0): [Parameter] b +# 2485| Type = [BoolType] bool +# 2486| getEntryPoint(): [BlockStmt] { ... } +# 2487| getStmt(0): [IfStmt] if (...) ... +# 2487| getCondition(): [VariableAccess] b +# 2487| Type = [BoolType] bool +# 2487| ValueCategory = prvalue(load) +# 2488| getThen(): [DeclStmt] declaration +# 2488| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c +# 2488| Type = [Class] ClassWithDestructor +# 2488| getVariable().getInitializer(): [Initializer] initializer for c +# 2488| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2488| Type = [VoidType] void +# 2488| ValueCategory = prvalue +#-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +#-----| Type = [VoidType] void +#-----| ValueCategory = prvalue +#-----| getQualifier(): [VariableAccess] c +#-----| Type = [Class] ClassWithDestructor +#-----| ValueCategory = lvalue +# 2490| getStmt(1): [IfStmt] if (...) ... +# 2490| getCondition(): [VariableAccess] b +# 2490| Type = [BoolType] bool +# 2490| ValueCategory = prvalue(load) +# 2491| getThen(): [DeclStmt] declaration +# 2491| getDeclarationEntry(0): [VariableDeclarationEntry] definition of d +# 2491| Type = [Class] ClassWithDestructor +# 2491| getVariable().getInitializer(): [Initializer] initializer for d +# 2491| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2491| Type = [VoidType] void +# 2491| ValueCategory = prvalue +#-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +#-----| Type = [VoidType] void +#-----| ValueCategory = prvalue +#-----| getQualifier(): [VariableAccess] d +#-----| Type = [Class] ClassWithDestructor +#-----| ValueCategory = lvalue +# 2493| getElse(): [DeclStmt] declaration +# 2493| getDeclarationEntry(0): [VariableDeclarationEntry] definition of e +# 2493| Type = [Class] ClassWithDestructor +# 2493| getVariable().getInitializer(): [Initializer] initializer for e +# 2493| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2493| Type = [VoidType] void +# 2493| ValueCategory = prvalue +#-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +#-----| Type = [VoidType] void +#-----| ValueCategory = prvalue +#-----| getQualifier(): [VariableAccess] e +#-----| Type = [Class] ClassWithDestructor +#-----| ValueCategory = lvalue +# 2495| getStmt(2): [WhileStmt] while (...) ... +# 2495| getCondition(): [VariableAccess] b +# 2495| Type = [BoolType] bool +# 2495| ValueCategory = prvalue(load) +# 2496| getStmt(): [DeclStmt] declaration +# 2496| getDeclarationEntry(0): [VariableDeclarationEntry] definition of f +# 2496| Type = [Class] ClassWithDestructor +# 2496| getVariable().getInitializer(): [Initializer] initializer for f +# 2496| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2496| Type = [VoidType] void +# 2496| ValueCategory = prvalue +#-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +#-----| Type = [VoidType] void +#-----| ValueCategory = prvalue +#-----| getQualifier(): [VariableAccess] f +#-----| Type = [Class] ClassWithDestructor +#-----| ValueCategory = lvalue +# 2498| getStmt(3): [ForStmt] for(...;...;...) ... +# 2498| getInitialization(): [DeclStmt] declaration +# 2498| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i +# 2498| Type = [IntType] int +# 2498| getVariable().getInitializer(): [Initializer] initializer for i +# 2498| getExpr(): [Literal] 0 +# 2498| Type = [IntType] int +# 2498| Value = [Literal] 0 +# 2498| ValueCategory = prvalue +# 2498| getCondition(): [LTExpr] ... < ... +# 2498| Type = [BoolType] bool +# 2498| ValueCategory = prvalue +# 2498| getLesserOperand(): [VariableAccess] i +# 2498| Type = [IntType] int +# 2498| ValueCategory = prvalue(load) +# 2498| getGreaterOperand(): [Literal] 42 +# 2498| Type = [IntType] int +# 2498| Value = [Literal] 42 +# 2498| ValueCategory = prvalue +# 2498| getUpdate(): [PrefixIncrExpr] ++ ... +# 2498| Type = [IntType] int +# 2498| ValueCategory = lvalue +# 2498| getOperand(): [VariableAccess] i +# 2498| Type = [IntType] int +# 2498| ValueCategory = lvalue +# 2499| getStmt(): [DeclStmt] declaration +# 2499| getDeclarationEntry(0): [VariableDeclarationEntry] definition of g +# 2499| Type = [Class] ClassWithDestructor +# 2499| getVariable().getInitializer(): [Initializer] initializer for g +# 2499| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2499| Type = [VoidType] void +# 2499| ValueCategory = prvalue +#-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +#-----| Type = [VoidType] void +#-----| ValueCategory = prvalue +#-----| getQualifier(): [VariableAccess] g +#-----| Type = [Class] ClassWithDestructor +#-----| ValueCategory = lvalue +# 2500| getStmt(4): [ReturnStmt] return ... +# 2502| [TopLevelFunction] void destruction_in_switch_1(int) +# 2502| : +# 2502| getParameter(0): [Parameter] c +# 2502| Type = [IntType] int +# 2502| getEntryPoint(): [BlockStmt] { ... } +# 2503| getStmt(0): [SwitchStmt] switch (...) ... +# 2503| getExpr(): [VariableAccess] c +# 2503| Type = [IntType] int +# 2503| ValueCategory = prvalue(load) +# 2503| getStmt(): [BlockStmt] { ... } +# 2504| getStmt(0): [SwitchCase] case ...: +# 2504| getExpr(): [Literal] 0 +# 2504| Type = [IntType] int +# 2504| Value = [Literal] 0 +# 2504| ValueCategory = prvalue +# 2504| getStmt(1): [BlockStmt] { ... } +# 2505| getStmt(0): [DeclStmt] declaration +# 2505| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2505| Type = [Class] ClassWithDestructor +# 2505| getVariable().getInitializer(): [Initializer] initializer for x +# 2505| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2505| Type = [VoidType] void +# 2505| ValueCategory = prvalue +# 2506| getStmt(1): [BreakStmt] break; +# 2507| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2507| Type = [VoidType] void +# 2507| ValueCategory = prvalue +# 2507| getQualifier(): [VariableAccess] x +# 2507| Type = [Class] ClassWithDestructor +# 2507| ValueCategory = lvalue +# 2507| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2507| Type = [VoidType] void +# 2507| ValueCategory = prvalue +# 2507| getQualifier(): [VariableAccess] x +# 2507| Type = [Class] ClassWithDestructor +# 2507| ValueCategory = lvalue +# 2508| getStmt(1): [LabelStmt] label ...: +# 2509| getStmt(2): [ReturnStmt] return ... +# 2511| [TopLevelFunction] void destruction_in_switch_2(int) +# 2511| : +# 2511| getParameter(0): [Parameter] c +# 2511| Type = [IntType] int +# 2511| getEntryPoint(): [BlockStmt] { ... } +# 2512| getStmt(0): [SwitchStmt] switch (...) ... +# 2512| getInitialization(): [DeclStmt] declaration +# 2512| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2512| Type = [Class] ClassWithDestructor +# 2512| getVariable().getInitializer(): [Initializer] initializer for y +# 2512| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2512| Type = [VoidType] void +# 2512| ValueCategory = prvalue +# 2512| getExpr(): [VariableAccess] c +# 2512| Type = [IntType] int +# 2512| ValueCategory = prvalue(load) +# 2512| getStmt(): [BlockStmt] { ... } +# 2513| getStmt(0): [SwitchCase] case ...: +# 2513| getExpr(): [Literal] 0 +# 2513| Type = [IntType] int +# 2513| Value = [Literal] 0 +# 2513| ValueCategory = prvalue +# 2513| getStmt(1): [BlockStmt] { ... } +# 2514| getStmt(0): [BreakStmt] break; +# 2519| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2519| Type = [VoidType] void +# 2519| ValueCategory = prvalue +# 2519| getQualifier(): [VariableAccess] y +# 2519| Type = [Class] ClassWithDestructor +# 2519| ValueCategory = lvalue +# 2516| getStmt(2): [SwitchCase] default: +# 2516| getStmt(3): [BlockStmt] { ... } +# 2517| getStmt(0): [BreakStmt] break; +# 2519| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2519| Type = [VoidType] void +# 2519| ValueCategory = prvalue +# 2519| getQualifier(): [VariableAccess] y +# 2519| Type = [Class] ClassWithDestructor +# 2519| ValueCategory = lvalue +# 2519| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2519| Type = [VoidType] void +# 2519| ValueCategory = prvalue +# 2519| getQualifier(): [VariableAccess] y +# 2519| Type = [Class] ClassWithDestructor +# 2519| ValueCategory = lvalue +# 2519| getStmt(1): [LabelStmt] label ...: +# 2520| getStmt(2): [ReturnStmt] return ... +# 2522| [TopLevelFunction] void destruction_in_switch_3(int) +# 2522| : +# 2522| getParameter(0): [Parameter] c +# 2522| Type = [IntType] int +# 2522| getEntryPoint(): [BlockStmt] { ... } +# 2523| getStmt(0): [SwitchStmt] switch (...) ... +# 2523| getInitialization(): [DeclStmt] declaration +# 2523| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2523| Type = [Class] ClassWithDestructor +# 2523| getVariable().getInitializer(): [Initializer] initializer for y +# 2523| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2523| Type = [VoidType] void +# 2523| ValueCategory = prvalue +# 2523| getExpr(): [VariableAccess] c +# 2523| Type = [IntType] int +# 2523| ValueCategory = prvalue(load) +# 2523| getStmt(): [BlockStmt] { ... } +# 2524| getStmt(0): [SwitchCase] case ...: +# 2524| getExpr(): [Literal] 0 +# 2524| Type = [IntType] int +# 2524| Value = [Literal] 0 +# 2524| ValueCategory = prvalue +# 2524| getStmt(1): [BlockStmt] { ... } +# 2525| getStmt(0): [DeclStmt] declaration +# 2525| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2525| Type = [Class] ClassWithDestructor +# 2525| getVariable().getInitializer(): [Initializer] initializer for x +# 2525| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2525| Type = [VoidType] void +# 2525| ValueCategory = prvalue +# 2526| getStmt(1): [BreakStmt] break; +# 2527| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2527| Type = [VoidType] void +# 2527| ValueCategory = prvalue +# 2527| getQualifier(): [VariableAccess] x +# 2527| Type = [Class] ClassWithDestructor +# 2527| ValueCategory = lvalue +# 2531| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor +# 2531| Type = [VoidType] void +# 2531| ValueCategory = prvalue +# 2531| getQualifier(): [VariableAccess] y +# 2531| Type = [Class] ClassWithDestructor +# 2531| ValueCategory = lvalue +# 2527| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2527| Type = [VoidType] void +# 2527| ValueCategory = prvalue +# 2527| getQualifier(): [VariableAccess] x +# 2527| Type = [Class] ClassWithDestructor +# 2527| ValueCategory = lvalue +# 2528| getStmt(2): [SwitchCase] default: +# 2528| getStmt(3): [BlockStmt] { ... } +# 2529| getStmt(0): [BreakStmt] break; +# 2531| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2531| Type = [VoidType] void +# 2531| ValueCategory = prvalue +# 2531| getQualifier(): [VariableAccess] y +# 2531| Type = [Class] ClassWithDestructor +# 2531| ValueCategory = lvalue +# 2531| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2531| Type = [VoidType] void +# 2531| ValueCategory = prvalue +# 2531| getQualifier(): [VariableAccess] y +# 2531| Type = [Class] ClassWithDestructor +# 2531| ValueCategory = lvalue +# 2531| getStmt(1): [LabelStmt] label ...: +# 2532| getStmt(2): [ReturnStmt] return ... +# 2534| [TopLevelFunction] void destructor_possibly_not_handled() +# 2534| : +# 2534| getEntryPoint(): [BlockStmt] { ... } +# 2535| getStmt(0): [DeclStmt] declaration +# 2535| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2535| Type = [Class] ClassWithDestructor +# 2535| getVariable().getInitializer(): [Initializer] initializer for x +# 2535| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2535| Type = [VoidType] void +# 2535| ValueCategory = prvalue +# 2536| getStmt(1): [TryStmt] try { ... } +# 2536| getStmt(): [BlockStmt] { ... } +# 2537| getStmt(0): [ExprStmt] ExprStmt +# 2537| getExpr(): [ThrowExpr] throw ... +# 2537| Type = [IntType] int +# 2537| ValueCategory = prvalue +# 2537| getExpr(): [Literal] 42 +# 2537| Type = [IntType] int +# 2537| Value = [Literal] 42 +# 2537| ValueCategory = prvalue +# 2539| getChild(1): [Handler] +# 2539| getBlock(): [CatchBlock] { ... } +# 2541| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2541| Type = [VoidType] void +# 2541| ValueCategory = prvalue +# 2541| getQualifier(): [VariableAccess] x +# 2541| Type = [Class] ClassWithDestructor +# 2541| ValueCategory = lvalue +# 2541| getStmt(2): [ReturnStmt] return ... +# 2541| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2541| Type = [VoidType] void +# 2541| ValueCategory = prvalue +# 2541| getQualifier(): [VariableAccess] x +# 2541| Type = [Class] ClassWithDestructor +# 2541| ValueCategory = lvalue +# 2543| [TopLevelFunction] ClassWithDestructor getClassWithDestructor() +# 2543| : +# 2545| [TopLevelFunction] void this_inconsistency(bool) +# 2545| : +# 2545| getParameter(0): [Parameter] b +# 2545| Type = [BoolType] bool +# 2545| getEntryPoint(): [BlockStmt] { ... } +# 2546| getStmt(0): [IfStmt] if (...) ... +# 2546| getCondition(): [ConditionDeclExpr] (condition decl) +# 2546| Type = [BoolType] bool +# 2546| ValueCategory = prvalue +# 2546| getChild(0): [FunctionCall] call to operator bool +# 2546| Type = [BoolType] bool +# 2546| ValueCategory = prvalue +# 2546| getQualifier(): [VariableAccess] a +# 2546| Type = [LValueReferenceType] const ClassWithDestructor & +# 2546| ValueCategory = prvalue(load) +# 2546| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2546| Type = [SpecifiedType] const ClassWithDestructor +# 2546| ValueCategory = prvalue(load) +# 2546| getInitializingExpr(): [FunctionCall] call to getClassWithDestructor +# 2546| Type = [Class] ClassWithDestructor +# 2546| ValueCategory = prvalue +# 2546| getInitializingExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2546| Type = [LValueReferenceType] const ClassWithDestructor & +# 2546| ValueCategory = prvalue +# 2546| getExpr(): [CStyleCast] (const ClassWithDestructor)... +# 2546| Conversion = [GlvalueConversion] glvalue conversion +# 2546| Type = [SpecifiedType] const ClassWithDestructor +# 2546| ValueCategory = lvalue +# 2546| getExpr(): [TemporaryObjectExpr] temporary object +# 2546| Type = [Class] ClassWithDestructor +# 2546| ValueCategory = lvalue +# 2547| getThen(): [EmptyStmt] ; +# 2547| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2547| Type = [VoidType] void +# 2547| ValueCategory = prvalue +# 2547| getQualifier(): [ReuseExpr] reuse of temporary object +# 2547| Type = [Class] ClassWithDestructor +# 2547| ValueCategory = xvalue +# 2548| getStmt(1): [ReturnStmt] return ... +# 2550| [TopLevelFunction] void constexpr_inconsistency(bool) +# 2550| : +# 2550| getParameter(0): [Parameter] b +# 2550| Type = [BoolType] bool +# 2550| getEntryPoint(): [BlockStmt] { ... } +# 2551| getStmt(0): [ConstexprIfStmt] if constexpr (...) ... +# 2551| getInitialization(): [DeclStmt] declaration +# 2551| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a +# 2551| Type = [LValueReferenceType] const ClassWithDestructor & +# 2551| getVariable().getInitializer(): [Initializer] initializer for a +# 2551| getExpr(): [FunctionCall] call to getClassWithDestructor +# 2551| Type = [Class] ClassWithDestructor +# 2551| ValueCategory = prvalue +# 2551| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2551| Type = [LValueReferenceType] const ClassWithDestructor & +# 2551| ValueCategory = prvalue +# 2551| getExpr(): [CStyleCast] (const ClassWithDestructor)... +# 2551| Conversion = [GlvalueConversion] glvalue conversion +# 2551| Type = [SpecifiedType] const ClassWithDestructor +# 2551| ValueCategory = lvalue +# 2551| getExpr(): [TemporaryObjectExpr] temporary object +# 2551| Type = [Class] ClassWithDestructor +# 2551| ValueCategory = lvalue +# 2551| getCondition(): [VariableAccess] initialization_with_destructor_bool +# 2551| Type = [BoolType] bool +# 2551| Value = [VariableAccess] 1 +# 2551| ValueCategory = prvalue(load) +# 2552| getThen(): [EmptyStmt] ; +# 2552| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2552| Type = [VoidType] void +# 2552| ValueCategory = prvalue +# 2552| getQualifier(): [ReuseExpr] reuse of temporary object +# 2552| Type = [Class] ClassWithDestructor +# 2552| ValueCategory = xvalue +# 2553| getStmt(1): [ReturnStmt] return ... perf-regression.cpp: # 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&) # 4| : diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 51e12b7a6e5d..eef600513eba 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -15335,2475 +15335,3005 @@ ir.cpp: # 2193| v2193_19(void) = AliasedUse : m2193_3 # 2193| v2193_20(void) = ExitFunction : -# 2196| bool initialization_with_destructor_bool -# 2196| Block 0 -# 2196| v2196_1(void) = EnterFunction : -# 2196| m2196_2(unknown) = AliasedDefinition : -# 2196| r2196_3(glval) = VariableAddress[initialization_with_destructor_bool] : -# 2196| r2196_4(bool) = Constant[1] : -# 2196| m2196_5(bool) = Store[initialization_with_destructor_bool] : &:r2196_3, r2196_4 -# 2196| m2196_6(unknown) = Chi : total:m2196_2, partial:m2196_5 -# 2196| v2196_7(void) = ReturnVoid : -# 2196| v2196_8(void) = AliasedUse : ~m2196_6 -# 2196| v2196_9(void) = ExitFunction : - -# 2198| void initialization_with_destructor(bool, char) -# 2198| Block 0 -# 2198| v2198_1(void) = EnterFunction : -# 2198| m2198_2(unknown) = AliasedDefinition : -# 2198| m2198_3(unknown) = InitializeNonLocal : -# 2198| m2198_4(unknown) = Chi : total:m2198_2, partial:m2198_3 -# 2198| r2198_5(glval) = VariableAddress[b] : -# 2198| m2198_6(bool) = InitializeParameter[b] : &:r2198_5 -# 2198| r2198_7(glval) = VariableAddress[c] : -# 2198| m2198_8(char) = InitializeParameter[c] : &:r2198_7 -# 2199| r2199_1(glval) = VariableAddress[x] : -# 2199| m2199_2(ClassWithDestructor) = Uninitialized[x] : &:r2199_1 -# 2199| r2199_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2199| v2199_4(void) = Call[ClassWithDestructor] : func:r2199_3, this:r2199_1 -# 2199| m2199_5(unknown) = ^CallSideEffect : ~m2198_4 -# 2199| m2199_6(unknown) = Chi : total:m2198_4, partial:m2199_5 -# 2199| m2199_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2199_1 -# 2199| m2199_8(ClassWithDestructor) = Chi : total:m2199_2, partial:m2199_7 -# 2199| r2199_9(glval) = VariableAddress[b] : -# 2199| r2199_10(bool) = Load[b] : &:r2199_9, m2198_6 -# 2199| v2199_11(void) = ConditionalBranch : r2199_10 +# 2197| bool initialization_with_destructor_bool +# 2197| Block 0 +# 2197| v2197_1(void) = EnterFunction : +# 2197| m2197_2(unknown) = AliasedDefinition : +# 2197| r2197_3(glval) = VariableAddress[initialization_with_destructor_bool] : +# 2197| r2197_4(bool) = Constant[1] : +# 2197| m2197_5(bool) = Store[initialization_with_destructor_bool] : &:r2197_3, r2197_4 +# 2197| m2197_6(unknown) = Chi : total:m2197_2, partial:m2197_5 +# 2197| v2197_7(void) = ReturnVoid : +# 2197| v2197_8(void) = AliasedUse : ~m2197_6 +# 2197| v2197_9(void) = ExitFunction : + +# 2199| void initialization_with_destructor(bool, char) +# 2199| Block 0 +# 2199| v2199_1(void) = EnterFunction : +# 2199| m2199_2(unknown) = AliasedDefinition : +# 2199| m2199_3(unknown) = InitializeNonLocal : +# 2199| m2199_4(unknown) = Chi : total:m2199_2, partial:m2199_3 +# 2199| r2199_5(glval) = VariableAddress[b] : +# 2199| m2199_6(bool) = InitializeParameter[b] : &:r2199_5 +# 2199| r2199_7(glval) = VariableAddress[c] : +# 2199| m2199_8(char) = InitializeParameter[c] : &:r2199_7 +# 2200| r2200_1(glval) = VariableAddress[x] : +# 2200| m2200_2(ClassWithDestructor) = Uninitialized[x] : &:r2200_1 +# 2200| r2200_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2200| v2200_4(void) = Call[ClassWithDestructor] : func:r2200_3, this:r2200_1 +# 2200| m2200_5(unknown) = ^CallSideEffect : ~m2199_4 +# 2200| m2200_6(unknown) = Chi : total:m2199_4, partial:m2200_5 +# 2200| m2200_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2200_1 +# 2200| m2200_8(ClassWithDestructor) = Chi : total:m2200_2, partial:m2200_7 +# 2200| r2200_9(glval) = VariableAddress[b] : +# 2200| r2200_10(bool) = Load[b] : &:r2200_9, m2199_6 +# 2200| v2200_11(void) = ConditionalBranch : r2200_10 #-----| False -> Block 3 #-----| True -> Block 2 -# 2198| Block 1 -# 2198| m2198_9(unknown) = Phi : from 13:~m2233_5, from 19:~m2233_13, from 23:~m2233_22 -# 2198| v2198_10(void) = ReturnVoid : -# 2198| v2198_11(void) = AliasedUse : ~m2198_9 -# 2198| v2198_12(void) = ExitFunction : - -# 2200| Block 2 -# 2200| r2200_1(glval) = VariableAddress[x] : -# 2200| r2200_2(glval) = FunctionAddress[set_x] : -# 2200| r2200_3(char) = Constant[97] : -# 2200| v2200_4(void) = Call[set_x] : func:r2200_2, this:r2200_1, 0:r2200_3 -# 2200| m2200_5(unknown) = ^CallSideEffect : ~m2199_6 -# 2200| m2200_6(unknown) = Chi : total:m2199_6, partial:m2200_5 -# 2200| v2200_7(void) = ^IndirectReadSideEffect[-1] : &:r2200_1, m2199_8 -# 2200| m2200_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2200_1 -# 2200| m2200_9(ClassWithDestructor) = Chi : total:m2199_8, partial:m2200_8 -# 2200| r2200_10(glval) = VariableAddress[x] : -# 2200| r2200_11(glval) = FunctionAddress[~ClassWithDestructor] : -# 2200| v2200_12(void) = Call[~ClassWithDestructor] : func:r2200_11, this:r2200_10 -# 2200| m2200_13(unknown) = ^CallSideEffect : ~m2200_6 -# 2200| m2200_14(unknown) = Chi : total:m2200_6, partial:m2200_13 -# 2200| v2200_15(void) = ^IndirectReadSideEffect[-1] : &:r2200_10, m2200_9 -# 2200| m2200_16(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2200_10 -# 2200| m2200_17(ClassWithDestructor) = Chi : total:m2200_9, partial:m2200_16 +# 2199| Block 1 +# 2199| m2199_9(unknown) = Phi : from 14:~m2234_5, from 19:~m2234_13, from 23:~m2234_22 +# 2199| v2199_10(void) = ReturnVoid : +# 2199| v2199_11(void) = AliasedUse : ~m2199_9 +# 2199| v2199_12(void) = ExitFunction : + +# 2201| Block 2 +# 2201| r2201_1(glval) = VariableAddress[x] : +# 2201| r2201_2(glval) = FunctionAddress[set_x] : +# 2201| r2201_3(char) = Constant[97] : +# 2201| v2201_4(void) = Call[set_x] : func:r2201_2, this:r2201_1, 0:r2201_3 +# 2201| m2201_5(unknown) = ^CallSideEffect : ~m2200_6 +# 2201| m2201_6(unknown) = Chi : total:m2200_6, partial:m2201_5 +# 2201| v2201_7(void) = ^IndirectReadSideEffect[-1] : &:r2201_1, m2200_8 +# 2201| m2201_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2201_1 +# 2201| m2201_9(ClassWithDestructor) = Chi : total:m2200_8, partial:m2201_8 +# 2201| r2201_10(glval) = VariableAddress[x] : +# 2201| r2201_11(glval) = FunctionAddress[~ClassWithDestructor] : +# 2201| v2201_12(void) = Call[~ClassWithDestructor] : func:r2201_11, this:r2201_10 +# 2201| m2201_13(unknown) = ^CallSideEffect : ~m2201_6 +# 2201| m2201_14(unknown) = Chi : total:m2201_6, partial:m2201_13 +# 2201| v2201_15(void) = ^IndirectReadSideEffect[-1] : &:r2201_10, m2201_9 +# 2201| m2201_16(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2201_10 +# 2201| m2201_17(ClassWithDestructor) = Chi : total:m2201_9, partial:m2201_16 #-----| Goto -> Block 3 -# 2202| Block 3 -# 2202| m2202_1(unknown) = Phi : from 0:~m2199_6, from 2:~m2200_14 -# 2202| r2202_2(glval) = VariableAddress[x] : -# 2202| m2202_3(ClassWithDestructor) = Uninitialized[x] : &:r2202_2 -# 2202| r2202_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2202| v2202_5(void) = Call[ClassWithDestructor] : func:r2202_4, this:r2202_2 -# 2202| m2202_6(unknown) = ^CallSideEffect : ~m2202_1 -# 2202| m2202_7(unknown) = Chi : total:m2202_1, partial:m2202_6 -# 2202| m2202_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2202_2 -# 2202| m2202_9(ClassWithDestructor) = Chi : total:m2202_3, partial:m2202_8 -# 2202| r2202_10(bool) = Constant[1] : -# 2202| v2202_11(void) = ConditionalBranch : r2202_10 +# 2203| Block 3 +# 2203| m2203_1(unknown) = Phi : from 0:~m2200_6, from 2:~m2201_14 +# 2203| r2203_2(glval) = VariableAddress[x] : +# 2203| m2203_3(ClassWithDestructor) = Uninitialized[x] : &:r2203_2 +# 2203| r2203_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2203| v2203_5(void) = Call[ClassWithDestructor] : func:r2203_4, this:r2203_2 +# 2203| m2203_6(unknown) = ^CallSideEffect : ~m2203_1 +# 2203| m2203_7(unknown) = Chi : total:m2203_1, partial:m2203_6 +# 2203| m2203_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2203_2 +# 2203| m2203_9(ClassWithDestructor) = Chi : total:m2203_3, partial:m2203_8 +# 2203| r2203_10(bool) = Constant[1] : +# 2203| v2203_11(void) = ConditionalBranch : r2203_10 #-----| False -> Block 24 #-----| True -> Block 4 -# 2203| Block 4 -# 2203| r2203_1(glval) = VariableAddress[x] : -# 2203| r2203_2(glval) = FunctionAddress[set_x] : -# 2203| r2203_3(char) = Constant[97] : -# 2203| v2203_4(void) = Call[set_x] : func:r2203_2, this:r2203_1, 0:r2203_3 -# 2203| m2203_5(unknown) = ^CallSideEffect : ~m2202_7 -# 2203| m2203_6(unknown) = Chi : total:m2202_7, partial:m2203_5 -# 2203| v2203_7(void) = ^IndirectReadSideEffect[-1] : &:r2203_1, m2202_9 -# 2203| m2203_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2203_1 -# 2203| m2203_9(ClassWithDestructor) = Chi : total:m2202_9, partial:m2203_8 -# 2205| r2205_1(glval) = VariableAddress[x] : -# 2205| m2205_2(ClassWithDestructor) = Uninitialized[x] : &:r2205_1 -# 2205| r2205_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2205| v2205_4(void) = Call[ClassWithDestructor] : func:r2205_3, this:r2205_1 -# 2205| m2205_5(unknown) = ^CallSideEffect : ~m2203_6 -# 2205| m2205_6(unknown) = Chi : total:m2203_6, partial:m2205_5 -# 2205| m2205_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2205_1 -# 2205| m2205_8(ClassWithDestructor) = Chi : total:m2205_2, partial:m2205_7 -# 2205| r2205_9(glval) = VariableAddress[c] : -# 2205| r2205_10(char) = Load[c] : &:r2205_9, m2198_8 -# 2205| r2205_11(int) = Convert : r2205_10 -# 2205| v2205_12(void) = Switch : r2205_11 +# 2204| Block 4 +# 2204| r2204_1(glval) = VariableAddress[x] : +# 2204| r2204_2(glval) = FunctionAddress[set_x] : +# 2204| r2204_3(char) = Constant[97] : +# 2204| v2204_4(void) = Call[set_x] : func:r2204_2, this:r2204_1, 0:r2204_3 +# 2204| m2204_5(unknown) = ^CallSideEffect : ~m2203_7 +# 2204| m2204_6(unknown) = Chi : total:m2203_7, partial:m2204_5 +# 2204| v2204_7(void) = ^IndirectReadSideEffect[-1] : &:r2204_1, m2203_9 +# 2204| m2204_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2204_1 +# 2204| m2204_9(ClassWithDestructor) = Chi : total:m2203_9, partial:m2204_8 +# 2206| r2206_1(glval) = VariableAddress[x] : +# 2206| m2206_2(ClassWithDestructor) = Uninitialized[x] : &:r2206_1 +# 2206| r2206_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2206| v2206_4(void) = Call[ClassWithDestructor] : func:r2206_3, this:r2206_1 +# 2206| m2206_5(unknown) = ^CallSideEffect : ~m2204_6 +# 2206| m2206_6(unknown) = Chi : total:m2204_6, partial:m2206_5 +# 2206| m2206_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2206_1 +# 2206| m2206_8(ClassWithDestructor) = Chi : total:m2206_2, partial:m2206_7 +# 2206| r2206_9(glval) = VariableAddress[c] : +# 2206| r2206_10(char) = Load[c] : &:r2206_9, m2199_8 +# 2206| r2206_11(int) = Convert : r2206_10 +# 2206| v2206_12(void) = Switch : r2206_11 #-----| Case[97] -> Block 5 #-----| Default -> Block 6 -# 2206| Block 5 -# 2206| v2206_1(void) = NoOp : -# 2207| r2207_1(glval) = VariableAddress[x] : -# 2207| r2207_2(glval) = FunctionAddress[set_x] : -# 2207| r2207_3(char) = Constant[97] : -# 2207| v2207_4(void) = Call[set_x] : func:r2207_2, this:r2207_1, 0:r2207_3 -# 2207| m2207_5(unknown) = ^CallSideEffect : ~m2205_6 -# 2207| m2207_6(unknown) = Chi : total:m2205_6, partial:m2207_5 -# 2207| v2207_7(void) = ^IndirectReadSideEffect[-1] : &:r2207_1, m2205_8 -# 2207| m2207_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2207_1 -# 2207| m2207_9(ClassWithDestructor) = Chi : total:m2205_8, partial:m2207_8 -# 2208| v2208_1(void) = NoOp : +# 2207| Block 5 +# 2207| v2207_1(void) = NoOp : +# 2208| r2208_1(glval) = VariableAddress[x] : +# 2208| r2208_2(glval) = FunctionAddress[set_x] : +# 2208| r2208_3(char) = Constant[97] : +# 2208| v2208_4(void) = Call[set_x] : func:r2208_2, this:r2208_1, 0:r2208_3 +# 2208| m2208_5(unknown) = ^CallSideEffect : ~m2206_6 +# 2208| m2208_6(unknown) = Chi : total:m2206_6, partial:m2208_5 +# 2208| v2208_7(void) = ^IndirectReadSideEffect[-1] : &:r2208_1, m2206_8 +# 2208| m2208_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2208_1 +# 2208| m2208_9(ClassWithDestructor) = Chi : total:m2206_8, partial:m2208_8 +# 2213| r2213_1(glval) = VariableAddress[x] : +# 2213| r2213_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2213| v2213_3(void) = Call[~ClassWithDestructor] : func:r2213_2, this:r2213_1 +# 2213| m2213_4(unknown) = ^CallSideEffect : ~m2208_6 +# 2213| m2213_5(unknown) = Chi : total:m2208_6, partial:m2213_4 +# 2213| v2213_6(void) = ^IndirectReadSideEffect[-1] : &:r2213_1, m2208_9 +# 2213| m2213_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2213_1 +# 2213| m2213_8(ClassWithDestructor) = Chi : total:m2208_9, partial:m2213_7 +# 2209| v2209_1(void) = NoOp : #-----| Goto -> Block 7 -# 2209| Block 6 -# 2209| v2209_1(void) = NoOp : -# 2210| r2210_1(glval) = VariableAddress[x] : -# 2210| r2210_2(glval) = FunctionAddress[set_x] : -# 2210| r2210_3(char) = Constant[98] : -# 2210| v2210_4(void) = Call[set_x] : func:r2210_2, this:r2210_1, 0:r2210_3 -# 2210| m2210_5(unknown) = ^CallSideEffect : ~m2205_6 -# 2210| m2210_6(unknown) = Chi : total:m2205_6, partial:m2210_5 -# 2210| v2210_7(void) = ^IndirectReadSideEffect[-1] : &:r2210_1, m2205_8 -# 2210| m2210_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2210_1 -# 2210| m2210_9(ClassWithDestructor) = Chi : total:m2205_8, partial:m2210_8 -# 2211| v2211_1(void) = NoOp : +# 2210| Block 6 +# 2210| v2210_1(void) = NoOp : +# 2211| r2211_1(glval) = VariableAddress[x] : +# 2211| r2211_2(glval) = FunctionAddress[set_x] : +# 2211| r2211_3(char) = Constant[98] : +# 2211| v2211_4(void) = Call[set_x] : func:r2211_2, this:r2211_1, 0:r2211_3 +# 2211| m2211_5(unknown) = ^CallSideEffect : ~m2206_6 +# 2211| m2211_6(unknown) = Chi : total:m2206_6, partial:m2211_5 +# 2211| v2211_7(void) = ^IndirectReadSideEffect[-1] : &:r2211_1, m2206_8 +# 2211| m2211_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2211_1 +# 2211| m2211_9(ClassWithDestructor) = Chi : total:m2206_8, partial:m2211_8 +# 2213| r2213_9(glval) = VariableAddress[x] : +# 2213| r2213_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2213| v2213_11(void) = Call[~ClassWithDestructor] : func:r2213_10, this:r2213_9 +# 2213| m2213_12(unknown) = ^CallSideEffect : ~m2211_6 +# 2213| m2213_13(unknown) = Chi : total:m2211_6, partial:m2213_12 +# 2213| v2213_14(void) = ^IndirectReadSideEffect[-1] : &:r2213_9, m2211_9 +# 2213| m2213_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2213_9 +# 2213| m2213_16(ClassWithDestructor) = Chi : total:m2211_9, partial:m2213_15 +# 2212| v2212_1(void) = NoOp : #-----| Goto -> Block 7 -# 2212| Block 7 -# 2212| m2212_1(unknown) = Phi : from 5:~m2207_6, from 6:~m2210_6 -# 2212| v2212_2(void) = NoOp : -# 2214| r2214_1(glval) = VariableAddress[x] : -# 2214| m2214_2(ClassWithDestructor) = Uninitialized[x] : &:r2214_1 -# 2214| r2214_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2214| v2214_4(void) = Call[ClassWithDestructor] : func:r2214_3, this:r2214_1 -# 2214| m2214_5(unknown) = ^CallSideEffect : ~m2212_1 -# 2214| m2214_6(unknown) = Chi : total:m2212_1, partial:m2214_5 -# 2214| m2214_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2214_1 -# 2214| m2214_8(ClassWithDestructor) = Chi : total:m2214_2, partial:m2214_7 -# 2215| r2215_1(glval>) = VariableAddress[ys] : -# 2215| m2215_2(vector) = Uninitialized[ys] : &:r2215_1 -# 2215| m2215_3(unknown) = Chi : total:m2214_6, partial:m2215_2 -# 2215| r2215_4(glval) = FunctionAddress[vector] : -# 2215| r2215_5(glval) = VariableAddress[#temp2215:45] : -# 2215| r2215_6(glval) = VariableAddress[x] : -# 2215| r2215_7(ClassWithDestructor) = Load[x] : &:r2215_6, m2214_8 -# 2215| m2215_8(ClassWithDestructor) = Store[#temp2215:45] : &:r2215_5, r2215_7 -# 2215| r2215_9(ClassWithDestructor) = Load[#temp2215:45] : &:r2215_5, m2215_8 -# 2215| v2215_10(void) = Call[vector] : func:r2215_4, this:r2215_1, 0:r2215_9 -# 2215| m2215_11(unknown) = ^CallSideEffect : ~m2215_3 -# 2215| m2215_12(unknown) = Chi : total:m2215_3, partial:m2215_11 -# 2215| m2215_13(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2215_1 -# 2215| m2215_14(unknown) = Chi : total:m2215_12, partial:m2215_13 -# 2215| r2215_15(glval) = CopyValue : r2215_5 -# 2215| r2215_16(glval) = FunctionAddress[~ClassWithDestructor] : -# 2215| v2215_17(void) = Call[~ClassWithDestructor] : func:r2215_16, this:r2215_15 -# 2215| m2215_18(unknown) = ^CallSideEffect : ~m2215_14 -# 2215| m2215_19(unknown) = Chi : total:m2215_14, partial:m2215_18 -# 2215| v2215_20(void) = ^IndirectReadSideEffect[-1] : &:r2215_15, m2215_8 -# 2215| m2215_21(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_15 -# 2215| m2215_22(ClassWithDestructor) = Chi : total:m2215_8, partial:m2215_21 -# 2215| r2215_23(glval &>) = VariableAddress[(__range)] : -# 2215| r2215_24(glval>) = VariableAddress[ys] : -# 2215| r2215_25(vector &) = CopyValue : r2215_24 -# 2215| m2215_26(vector &) = Store[(__range)] : &:r2215_23, r2215_25 -# 2215| r2215_27(glval>) = VariableAddress[(__begin)] : -# 2215| r2215_28(glval &>) = VariableAddress[(__range)] : -# 2215| r2215_29(vector &) = Load[(__range)] : &:r2215_28, m2215_26 -#-----| r0_1(glval>) = CopyValue : r2215_29 +# 2213| Block 7 +# 2213| m2213_17(unknown) = Phi : from 5:~m2213_5, from 6:~m2213_13 +# 2213| v2213_18(void) = NoOp : +# 2215| r2215_1(glval) = VariableAddress[x] : +# 2215| m2215_2(ClassWithDestructor) = Uninitialized[x] : &:r2215_1 +# 2215| r2215_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2215| v2215_4(void) = Call[ClassWithDestructor] : func:r2215_3, this:r2215_1 +# 2215| m2215_5(unknown) = ^CallSideEffect : ~m2213_17 +# 2215| m2215_6(unknown) = Chi : total:m2213_17, partial:m2215_5 +# 2215| m2215_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_1 +# 2215| m2215_8(ClassWithDestructor) = Chi : total:m2215_2, partial:m2215_7 +# 2216| r2216_1(glval>) = VariableAddress[ys] : +# 2216| m2216_2(vector) = Uninitialized[ys] : &:r2216_1 +# 2216| m2216_3(unknown) = Chi : total:m2215_6, partial:m2216_2 +# 2216| r2216_4(glval) = FunctionAddress[vector] : +# 2216| r2216_5(glval) = VariableAddress[#temp2216:45] : +# 2216| r2216_6(glval) = VariableAddress[x] : +# 2216| r2216_7(ClassWithDestructor) = Load[x] : &:r2216_6, m2215_8 +# 2216| m2216_8(ClassWithDestructor) = Store[#temp2216:45] : &:r2216_5, r2216_7 +# 2216| r2216_9(ClassWithDestructor) = Load[#temp2216:45] : &:r2216_5, m2216_8 +# 2216| v2216_10(void) = Call[vector] : func:r2216_4, this:r2216_1, 0:r2216_9 +# 2216| m2216_11(unknown) = ^CallSideEffect : ~m2216_3 +# 2216| m2216_12(unknown) = Chi : total:m2216_3, partial:m2216_11 +# 2216| m2216_13(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2216_1 +# 2216| m2216_14(unknown) = Chi : total:m2216_12, partial:m2216_13 +# 2216| r2216_15(glval) = CopyValue : r2216_5 +# 2216| r2216_16(glval) = FunctionAddress[~ClassWithDestructor] : +# 2216| v2216_17(void) = Call[~ClassWithDestructor] : func:r2216_16, this:r2216_15 +# 2216| m2216_18(unknown) = ^CallSideEffect : ~m2216_14 +# 2216| m2216_19(unknown) = Chi : total:m2216_14, partial:m2216_18 +# 2216| v2216_20(void) = ^IndirectReadSideEffect[-1] : &:r2216_15, m2216_8 +# 2216| m2216_21(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_15 +# 2216| m2216_22(ClassWithDestructor) = Chi : total:m2216_8, partial:m2216_21 +# 2216| r2216_23(glval &>) = VariableAddress[(__range)] : +# 2216| r2216_24(glval>) = VariableAddress[ys] : +# 2216| r2216_25(vector &) = CopyValue : r2216_24 +# 2216| m2216_26(vector &) = Store[(__range)] : &:r2216_23, r2216_25 +# 2216| r2216_27(glval>) = VariableAddress[(__begin)] : +# 2216| r2216_28(glval &>) = VariableAddress[(__range)] : +# 2216| r2216_29(vector &) = Load[(__range)] : &:r2216_28, m2216_26 +#-----| r0_1(glval>) = CopyValue : r2216_29 #-----| r0_2(glval>) = Convert : r0_1 -# 2215| r2215_30(glval) = FunctionAddress[begin] : -# 2215| r2215_31(iterator) = Call[begin] : func:r2215_30, this:r0_2 -#-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m2215_19 -# 2215| m2215_32(iterator) = Store[(__begin)] : &:r2215_27, r2215_31 -# 2215| r2215_33(glval>) = VariableAddress[(__end)] : -# 2215| r2215_34(glval &>) = VariableAddress[(__range)] : -# 2215| r2215_35(vector &) = Load[(__range)] : &:r2215_34, m2215_26 -#-----| r0_4(glval>) = CopyValue : r2215_35 +# 2216| r2216_30(glval) = FunctionAddress[begin] : +# 2216| r2216_31(iterator) = Call[begin] : func:r2216_30, this:r0_2 +#-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m2216_19 +# 2216| m2216_32(iterator) = Store[(__begin)] : &:r2216_27, r2216_31 +# 2216| r2216_33(glval>) = VariableAddress[(__end)] : +# 2216| r2216_34(glval &>) = VariableAddress[(__range)] : +# 2216| r2216_35(vector &) = Load[(__range)] : &:r2216_34, m2216_26 +#-----| r0_4(glval>) = CopyValue : r2216_35 #-----| r0_5(glval>) = Convert : r0_4 -# 2215| r2215_36(glval) = FunctionAddress[end] : -# 2215| r2215_37(iterator) = Call[end] : func:r2215_36, this:r0_5 -#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m2215_19 -# 2215| m2215_38(iterator) = Store[(__end)] : &:r2215_33, r2215_37 -# 2215| m2215_39(unknown) = Chi : total:m2215_19, partial:m2215_38 +# 2216| r2216_36(glval) = FunctionAddress[end] : +# 2216| r2216_37(iterator) = Call[end] : func:r2216_36, this:r0_5 +#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m2216_19 +# 2216| m2216_38(iterator) = Store[(__end)] : &:r2216_33, r2216_37 +# 2216| m2216_39(unknown) = Chi : total:m2216_19, partial:m2216_38 #-----| Goto -> Block 8 -# 2215| Block 8 -# 2215| m2215_40(iterator) = Phi : from 7:m2215_32, from 9:m2215_72 -# 2215| m2215_41(unknown) = Phi : from 7:~m2215_39, from 9:~m2215_63 -# 2215| r2215_42(glval>) = VariableAddress[(__begin)] : -#-----| r0_7(glval>) = Convert : r2215_42 -# 2215| r2215_43(glval) = FunctionAddress[operator!=] : +# 2216| Block 8 +# 2216| m2216_40(iterator) = Phi : from 7:m2216_32, from 9:m2216_64 +# 2216| m2216_41(unknown) = Phi : from 7:~m2216_39, from 9:~m2216_69 +# 2216| r2216_42(glval>) = VariableAddress[(__begin)] : +#-----| r0_7(glval>) = Convert : r2216_42 +# 2216| r2216_43(glval) = FunctionAddress[operator!=] : #-----| r0_8(glval>) = VariableAddress[#temp0:0] : #-----| m0_9(iterator) = Uninitialized[#temp0:0] : &:r0_8 -#-----| m0_10(unknown) = Chi : total:m2215_41, partial:m0_9 -# 2215| r2215_44(glval) = FunctionAddress[iterator] : -# 2215| r2215_45(glval>) = VariableAddress[(__end)] : -#-----| r0_11(glval>) = Convert : r2215_45 +#-----| m0_10(unknown) = Chi : total:m2216_41, partial:m0_9 +# 2216| r2216_44(glval) = FunctionAddress[iterator] : +# 2216| r2216_45(glval>) = VariableAddress[(__end)] : +#-----| r0_11(glval>) = Convert : r2216_45 #-----| r0_12(iterator &) = CopyValue : r0_11 -# 2215| v2215_46(void) = Call[iterator] : func:r2215_44, this:r0_8, 0:r0_12 -# 2215| m2215_47(unknown) = ^CallSideEffect : ~m0_10 -# 2215| m2215_48(unknown) = Chi : total:m0_10, partial:m2215_47 -#-----| v0_13(void) = ^BufferReadSideEffect[0] : &:r0_12, ~m2215_48 -# 2215| m2215_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 -# 2215| m2215_50(unknown) = Chi : total:m2215_48, partial:m2215_49 -#-----| r0_14(iterator) = Load[#temp0:0] : &:r0_8, ~m2215_50 -# 2215| r2215_51(bool) = Call[operator!=] : func:r2215_43, this:r0_7, 0:r0_14 -#-----| v0_15(void) = ^IndirectReadSideEffect[-1] : &:r0_7, m2215_40 -# 2215| v2215_52(void) = ConditionalBranch : r2215_51 +# 2216| v2216_46(void) = Call[iterator] : func:r2216_44, this:r0_8, 0:r0_12 +# 2216| m2216_47(unknown) = ^CallSideEffect : ~m0_10 +# 2216| m2216_48(unknown) = Chi : total:m0_10, partial:m2216_47 +#-----| v0_13(void) = ^BufferReadSideEffect[0] : &:r0_12, ~m2216_48 +# 2216| m2216_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 2216| m2216_50(unknown) = Chi : total:m2216_48, partial:m2216_49 +#-----| r0_14(iterator) = Load[#temp0:0] : &:r0_8, ~m2216_50 +# 2216| r2216_51(bool) = Call[operator!=] : func:r2216_43, this:r0_7, 0:r0_14 +#-----| v0_15(void) = ^IndirectReadSideEffect[-1] : &:r0_7, m2216_40 +# 2216| v2216_52(void) = ConditionalBranch : r2216_51 #-----| False -> Block 10 #-----| True -> Block 9 -# 2215| Block 9 -# 2215| r2215_53(glval) = VariableAddress[y] : -# 2215| r2215_54(glval>) = VariableAddress[(__begin)] : -#-----| r0_16(glval>) = Convert : r2215_54 -# 2215| r2215_55(glval) = FunctionAddress[operator*] : -# 2215| r2215_56(ClassWithDestructor &) = Call[operator*] : func:r2215_55, this:r0_16 -#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_16, m2215_40 -# 2215| r2215_57(ClassWithDestructor) = Load[?] : &:r2215_56, ~m2215_50 -# 2215| m2215_58(ClassWithDestructor) = Store[y] : &:r2215_53, r2215_57 -# 2216| r2216_1(glval) = VariableAddress[y] : -# 2216| r2216_2(glval) = FunctionAddress[set_x] : -# 2216| r2216_3(char) = Constant[97] : -# 2216| v2216_4(void) = Call[set_x] : func:r2216_2, this:r2216_1, 0:r2216_3 -# 2216| m2216_5(unknown) = ^CallSideEffect : ~m2215_50 -# 2216| m2216_6(unknown) = Chi : total:m2215_50, partial:m2216_5 -# 2216| v2216_7(void) = ^IndirectReadSideEffect[-1] : &:r2216_1, m2215_58 -# 2216| m2216_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_1 -# 2216| m2216_9(ClassWithDestructor) = Chi : total:m2215_58, partial:m2216_8 -# 2215| r2215_59(glval) = VariableAddress[y] : -# 2215| r2215_60(glval) = FunctionAddress[~ClassWithDestructor] : -# 2215| v2215_61(void) = Call[~ClassWithDestructor] : func:r2215_60, this:r2215_59 -# 2215| m2215_62(unknown) = ^CallSideEffect : ~m2216_6 -# 2215| m2215_63(unknown) = Chi : total:m2216_6, partial:m2215_62 -# 2215| v2215_64(void) = ^IndirectReadSideEffect[-1] : &:r2215_59, m2216_9 -# 2215| m2215_65(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_59 -# 2215| m2215_66(ClassWithDestructor) = Chi : total:m2216_9, partial:m2215_65 -# 2215| r2215_67(glval>) = VariableAddress[(__begin)] : -# 2215| r2215_68(glval) = FunctionAddress[operator++] : -# 2215| r2215_69(iterator &) = Call[operator++] : func:r2215_68, this:r2215_67 -# 2215| v2215_70(void) = ^IndirectReadSideEffect[-1] : &:r2215_67, m2215_40 -# 2215| m2215_71(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2215_67 -# 2215| m2215_72(iterator) = Chi : total:m2215_40, partial:m2215_71 -# 2215| r2215_73(glval>) = CopyValue : r2215_69 +# 2216| Block 9 +# 2216| r2216_53(glval) = VariableAddress[y] : +# 2216| r2216_54(glval>) = VariableAddress[(__begin)] : +#-----| r0_16(glval>) = Convert : r2216_54 +# 2216| r2216_55(glval) = FunctionAddress[operator*] : +# 2216| r2216_56(ClassWithDestructor &) = Call[operator*] : func:r2216_55, this:r0_16 +#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_16, m2216_40 +# 2216| r2216_57(ClassWithDestructor) = Load[?] : &:r2216_56, ~m2216_50 +# 2216| m2216_58(ClassWithDestructor) = Store[y] : &:r2216_53, r2216_57 +# 2217| r2217_1(glval) = VariableAddress[y] : +# 2217| r2217_2(glval) = FunctionAddress[set_x] : +# 2217| r2217_3(char) = Constant[97] : +# 2217| v2217_4(void) = Call[set_x] : func:r2217_2, this:r2217_1, 0:r2217_3 +# 2217| m2217_5(unknown) = ^CallSideEffect : ~m2216_50 +# 2217| m2217_6(unknown) = Chi : total:m2216_50, partial:m2217_5 +# 2217| v2217_7(void) = ^IndirectReadSideEffect[-1] : &:r2217_1, m2216_58 +# 2217| m2217_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2217_1 +# 2217| m2217_9(ClassWithDestructor) = Chi : total:m2216_58, partial:m2217_8 +# 2216| r2216_59(glval>) = VariableAddress[(__begin)] : +# 2216| r2216_60(glval) = FunctionAddress[operator++] : +# 2216| r2216_61(iterator &) = Call[operator++] : func:r2216_60, this:r2216_59 +# 2216| v2216_62(void) = ^IndirectReadSideEffect[-1] : &:r2216_59, m2216_40 +# 2216| m2216_63(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2216_59 +# 2216| m2216_64(iterator) = Chi : total:m2216_40, partial:m2216_63 +# 2216| r2216_65(glval) = VariableAddress[y] : +# 2216| r2216_66(glval) = FunctionAddress[~ClassWithDestructor] : +# 2216| v2216_67(void) = Call[~ClassWithDestructor] : func:r2216_66, this:r2216_65 +# 2216| m2216_68(unknown) = ^CallSideEffect : ~m2217_6 +# 2216| m2216_69(unknown) = Chi : total:m2217_6, partial:m2216_68 +# 2216| v2216_70(void) = ^IndirectReadSideEffect[-1] : &:r2216_65, m2217_9 +# 2216| m2216_71(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_65 +# 2216| m2216_72(ClassWithDestructor) = Chi : total:m2217_9, partial:m2216_71 +# 2216| r2216_73(glval>) = CopyValue : r2216_61 #-----| Goto (back edge) -> Block 8 -# 2218| Block 10 -# 2218| r2218_1(glval>) = VariableAddress[ys] : -# 2218| m2218_2(vector) = Uninitialized[ys] : &:r2218_1 -# 2218| m2218_3(unknown) = Chi : total:m2215_50, partial:m2218_2 -# 2218| r2218_4(glval) = FunctionAddress[vector] : -# 2218| r2218_5(glval) = VariableAddress[#temp2218:45] : -# 2218| r2218_6(glval) = VariableAddress[x] : -# 2218| r2218_7(ClassWithDestructor) = Load[x] : &:r2218_6, m2214_8 -# 2218| m2218_8(ClassWithDestructor) = Store[#temp2218:45] : &:r2218_5, r2218_7 -# 2218| r2218_9(ClassWithDestructor) = Load[#temp2218:45] : &:r2218_5, m2218_8 -# 2218| v2218_10(void) = Call[vector] : func:r2218_4, this:r2218_1, 0:r2218_9 -# 2218| m2218_11(unknown) = ^CallSideEffect : ~m2218_3 -# 2218| m2218_12(unknown) = Chi : total:m2218_3, partial:m2218_11 -# 2218| m2218_13(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_1 -# 2218| m2218_14(unknown) = Chi : total:m2218_12, partial:m2218_13 -# 2218| r2218_15(glval) = CopyValue : r2218_5 -# 2218| r2218_16(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_17(void) = Call[~ClassWithDestructor] : func:r2218_16, this:r2218_15 -# 2218| m2218_18(unknown) = ^CallSideEffect : ~m2218_14 -# 2218| m2218_19(unknown) = Chi : total:m2218_14, partial:m2218_18 -# 2218| v2218_20(void) = ^IndirectReadSideEffect[-1] : &:r2218_15, m2218_8 -# 2218| m2218_21(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_15 -# 2218| m2218_22(ClassWithDestructor) = Chi : total:m2218_8, partial:m2218_21 -# 2218| r2218_23(glval &>) = VariableAddress[(__range)] : -# 2218| r2218_24(glval>) = VariableAddress[ys] : -# 2218| r2218_25(vector &) = CopyValue : r2218_24 -# 2218| m2218_26(vector &) = Store[(__range)] : &:r2218_23, r2218_25 -# 2218| r2218_27(glval>) = VariableAddress[(__begin)] : -# 2218| r2218_28(glval &>) = VariableAddress[(__range)] : -# 2218| r2218_29(vector &) = Load[(__range)] : &:r2218_28, m2218_26 -#-----| r0_18(glval>) = CopyValue : r2218_29 +# 2216| Block 10 +# 2216| r2216_74(glval>) = VariableAddress[ys] : +# 2216| r2216_75(glval) = FunctionAddress[~vector] : +# 2216| v2216_76(void) = Call[~vector] : func:r2216_75, this:r2216_74 +# 2216| m2216_77(unknown) = ^CallSideEffect : ~m2216_50 +# 2216| m2216_78(unknown) = Chi : total:m2216_50, partial:m2216_77 +# 2216| v2216_79(void) = ^IndirectReadSideEffect[-1] : &:r2216_74, ~m2216_78 +# 2216| m2216_80(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2216_74 +# 2216| m2216_81(unknown) = Chi : total:m2216_78, partial:m2216_80 +# 2219| r2219_1(glval>) = VariableAddress[ys] : +# 2219| m2219_2(vector) = Uninitialized[ys] : &:r2219_1 +# 2219| m2219_3(unknown) = Chi : total:m2216_81, partial:m2219_2 +# 2219| r2219_4(glval) = FunctionAddress[vector] : +# 2219| r2219_5(glval) = VariableAddress[#temp2219:45] : +# 2219| r2219_6(glval) = VariableAddress[x] : +# 2219| r2219_7(ClassWithDestructor) = Load[x] : &:r2219_6, m2215_8 +# 2219| m2219_8(ClassWithDestructor) = Store[#temp2219:45] : &:r2219_5, r2219_7 +# 2219| r2219_9(ClassWithDestructor) = Load[#temp2219:45] : &:r2219_5, m2219_8 +# 2219| v2219_10(void) = Call[vector] : func:r2219_4, this:r2219_1, 0:r2219_9 +# 2219| m2219_11(unknown) = ^CallSideEffect : ~m2219_3 +# 2219| m2219_12(unknown) = Chi : total:m2219_3, partial:m2219_11 +# 2219| m2219_13(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2219_1 +# 2219| m2219_14(unknown) = Chi : total:m2219_12, partial:m2219_13 +# 2219| r2219_15(glval) = CopyValue : r2219_5 +# 2219| r2219_16(glval) = FunctionAddress[~ClassWithDestructor] : +# 2219| v2219_17(void) = Call[~ClassWithDestructor] : func:r2219_16, this:r2219_15 +# 2219| m2219_18(unknown) = ^CallSideEffect : ~m2219_14 +# 2219| m2219_19(unknown) = Chi : total:m2219_14, partial:m2219_18 +# 2219| v2219_20(void) = ^IndirectReadSideEffect[-1] : &:r2219_15, m2219_8 +# 2219| m2219_21(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_15 +# 2219| m2219_22(ClassWithDestructor) = Chi : total:m2219_8, partial:m2219_21 +# 2219| r2219_23(glval &>) = VariableAddress[(__range)] : +# 2219| r2219_24(glval>) = VariableAddress[ys] : +# 2219| r2219_25(vector &) = CopyValue : r2219_24 +# 2219| m2219_26(vector &) = Store[(__range)] : &:r2219_23, r2219_25 +# 2219| r2219_27(glval>) = VariableAddress[(__begin)] : +# 2219| r2219_28(glval &>) = VariableAddress[(__range)] : +# 2219| r2219_29(vector &) = Load[(__range)] : &:r2219_28, m2219_26 +#-----| r0_18(glval>) = CopyValue : r2219_29 #-----| r0_19(glval>) = Convert : r0_18 -# 2218| r2218_30(glval) = FunctionAddress[begin] : -# 2218| r2218_31(iterator) = Call[begin] : func:r2218_30, this:r0_19 -#-----| v0_20(void) = ^IndirectReadSideEffect[-1] : &:r0_19, ~m2218_19 -# 2218| m2218_32(iterator) = Store[(__begin)] : &:r2218_27, r2218_31 -# 2218| r2218_33(glval>) = VariableAddress[(__end)] : -# 2218| r2218_34(glval &>) = VariableAddress[(__range)] : -# 2218| r2218_35(vector &) = Load[(__range)] : &:r2218_34, m2218_26 -#-----| r0_21(glval>) = CopyValue : r2218_35 +# 2219| r2219_30(glval) = FunctionAddress[begin] : +# 2219| r2219_31(iterator) = Call[begin] : func:r2219_30, this:r0_19 +#-----| v0_20(void) = ^IndirectReadSideEffect[-1] : &:r0_19, ~m2219_19 +# 2219| m2219_32(iterator) = Store[(__begin)] : &:r2219_27, r2219_31 +# 2219| r2219_33(glval>) = VariableAddress[(__end)] : +# 2219| r2219_34(glval &>) = VariableAddress[(__range)] : +# 2219| r2219_35(vector &) = Load[(__range)] : &:r2219_34, m2219_26 +#-----| r0_21(glval>) = CopyValue : r2219_35 #-----| r0_22(glval>) = Convert : r0_21 -# 2218| r2218_36(glval) = FunctionAddress[end] : -# 2218| r2218_37(iterator) = Call[end] : func:r2218_36, this:r0_22 -#-----| v0_23(void) = ^IndirectReadSideEffect[-1] : &:r0_22, ~m2218_19 -# 2218| m2218_38(iterator) = Store[(__end)] : &:r2218_33, r2218_37 -# 2218| m2218_39(unknown) = Chi : total:m2218_19, partial:m2218_38 +# 2219| r2219_36(glval) = FunctionAddress[end] : +# 2219| r2219_37(iterator) = Call[end] : func:r2219_36, this:r0_22 +#-----| v0_23(void) = ^IndirectReadSideEffect[-1] : &:r0_22, ~m2219_19 +# 2219| m2219_38(iterator) = Store[(__end)] : &:r2219_33, r2219_37 +# 2219| m2219_39(unknown) = Chi : total:m2219_19, partial:m2219_38 #-----| Goto -> Block 11 -# 2218| Block 11 -# 2218| m2218_40(iterator) = Phi : from 10:m2218_32, from 14:m2218_88 -# 2218| m2218_41(unknown) = Phi : from 10:~m2218_39, from 14:~m2218_79 -# 2218| r2218_42(glval>) = VariableAddress[(__begin)] : -#-----| r0_24(glval>) = Convert : r2218_42 -# 2218| r2218_43(glval) = FunctionAddress[operator!=] : +# 2219| Block 11 +# 2219| m2219_40(iterator) = Phi : from 10:m2219_32, from 12:m2219_58 +# 2219| m2219_41(unknown) = Phi : from 10:~m2219_39, from 12:~m2219_63 +# 2219| r2219_42(glval>) = VariableAddress[(__begin)] : +#-----| r0_24(glval>) = Convert : r2219_42 +# 2219| r2219_43(glval) = FunctionAddress[operator!=] : #-----| r0_25(glval>) = VariableAddress[#temp0:0] : #-----| m0_26(iterator) = Uninitialized[#temp0:0] : &:r0_25 -#-----| m0_27(unknown) = Chi : total:m2218_41, partial:m0_26 -# 2218| r2218_44(glval) = FunctionAddress[iterator] : -# 2218| r2218_45(glval>) = VariableAddress[(__end)] : -#-----| r0_28(glval>) = Convert : r2218_45 +#-----| m0_27(unknown) = Chi : total:m2219_41, partial:m0_26 +# 2219| r2219_44(glval) = FunctionAddress[iterator] : +# 2219| r2219_45(glval>) = VariableAddress[(__end)] : +#-----| r0_28(glval>) = Convert : r2219_45 #-----| r0_29(iterator &) = CopyValue : r0_28 -# 2218| v2218_46(void) = Call[iterator] : func:r2218_44, this:r0_25, 0:r0_29 -# 2218| m2218_47(unknown) = ^CallSideEffect : ~m0_27 -# 2218| m2218_48(unknown) = Chi : total:m0_27, partial:m2218_47 -#-----| v0_30(void) = ^BufferReadSideEffect[0] : &:r0_29, ~m2218_48 -# 2218| m2218_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_25 -# 2218| m2218_50(unknown) = Chi : total:m2218_48, partial:m2218_49 -#-----| r0_31(iterator) = Load[#temp0:0] : &:r0_25, ~m2218_50 -# 2218| r2218_51(bool) = Call[operator!=] : func:r2218_43, this:r0_24, 0:r0_31 -#-----| v0_32(void) = ^IndirectReadSideEffect[-1] : &:r0_24, m2218_40 -# 2218| v2218_52(void) = ConditionalBranch : r2218_51 +# 2219| v2219_46(void) = Call[iterator] : func:r2219_44, this:r0_25, 0:r0_29 +# 2219| m2219_47(unknown) = ^CallSideEffect : ~m0_27 +# 2219| m2219_48(unknown) = Chi : total:m0_27, partial:m2219_47 +#-----| v0_30(void) = ^BufferReadSideEffect[0] : &:r0_29, ~m2219_48 +# 2219| m2219_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_25 +# 2219| m2219_50(unknown) = Chi : total:m2219_48, partial:m2219_49 +#-----| r0_31(iterator) = Load[#temp0:0] : &:r0_25, ~m2219_50 +# 2219| r2219_51(bool) = Call[operator!=] : func:r2219_43, this:r0_24, 0:r0_31 +#-----| v0_32(void) = ^IndirectReadSideEffect[-1] : &:r0_24, m2219_40 +# 2219| v2219_52(void) = ConditionalBranch : r2219_51 #-----| False -> Block 15 -#-----| True -> Block 12 +#-----| True -> Block 13 -# 2218| Block 12 -# 2218| r2218_53(glval) = VariableAddress[y] : -# 2218| r2218_54(glval>) = VariableAddress[(__begin)] : -#-----| r0_33(glval>) = Convert : r2218_54 -# 2218| r2218_55(glval) = FunctionAddress[operator*] : -# 2218| r2218_56(ClassWithDestructor &) = Call[operator*] : func:r2218_55, this:r0_33 -#-----| v0_34(void) = ^IndirectReadSideEffect[-1] : &:r0_33, m2218_40 -# 2218| r2218_57(ClassWithDestructor) = Load[?] : &:r2218_56, ~m2218_50 -# 2218| m2218_58(ClassWithDestructor) = Store[y] : &:r2218_53, r2218_57 -# 2219| r2219_1(glval) = VariableAddress[y] : -# 2219| r2219_2(glval) = FunctionAddress[set_x] : -# 2219| r2219_3(char) = Constant[97] : -# 2219| v2219_4(void) = Call[set_x] : func:r2219_2, this:r2219_1, 0:r2219_3 -# 2219| m2219_5(unknown) = ^CallSideEffect : ~m2218_50 -# 2219| m2219_6(unknown) = Chi : total:m2218_50, partial:m2219_5 -# 2219| v2219_7(void) = ^IndirectReadSideEffect[-1] : &:r2219_1, m2218_58 -# 2219| m2219_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_1 -# 2219| m2219_9(ClassWithDestructor) = Chi : total:m2218_58, partial:m2219_8 +# 2219| Block 12 +# 2219| r2219_53(glval>) = VariableAddress[(__begin)] : +# 2219| r2219_54(glval) = FunctionAddress[operator++] : +# 2219| r2219_55(iterator &) = Call[operator++] : func:r2219_54, this:r2219_53 +# 2219| v2219_56(void) = ^IndirectReadSideEffect[-1] : &:r2219_53, m2219_40 +# 2219| m2219_57(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2219_53 +# 2219| m2219_58(iterator) = Chi : total:m2219_40, partial:m2219_57 +# 2219| r2219_59(glval) = VariableAddress[y] : +# 2219| r2219_60(glval) = FunctionAddress[~ClassWithDestructor] : +# 2219| v2219_61(void) = Call[~ClassWithDestructor] : func:r2219_60, this:r2219_59 +# 2219| m2219_62(unknown) = ^CallSideEffect : ~m2221_5 +# 2219| m2219_63(unknown) = Chi : total:m2221_5, partial:m2219_62 +# 2219| v2219_64(void) = ^IndirectReadSideEffect[-1] : &:r2219_59, m2221_8 +# 2219| m2219_65(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_59 +# 2219| m2219_66(ClassWithDestructor) = Chi : total:m2221_8, partial:m2219_65 +# 2219| r2219_67(glval>) = CopyValue : r2219_55 +#-----| Goto (back edge) -> Block 11 + +# 2219| Block 13 +# 2219| r2219_68(glval) = VariableAddress[y] : +# 2219| r2219_69(glval>) = VariableAddress[(__begin)] : +#-----| r0_33(glval>) = Convert : r2219_69 +# 2219| r2219_70(glval) = FunctionAddress[operator*] : +# 2219| r2219_71(ClassWithDestructor &) = Call[operator*] : func:r2219_70, this:r0_33 +#-----| v0_34(void) = ^IndirectReadSideEffect[-1] : &:r0_33, m2219_40 +# 2219| r2219_72(ClassWithDestructor) = Load[?] : &:r2219_71, ~m2219_50 +# 2219| m2219_73(ClassWithDestructor) = Store[y] : &:r2219_68, r2219_72 # 2220| r2220_1(glval) = VariableAddress[y] : -# 2220| r2220_2(glval) = FunctionAddress[get_x] : -# 2220| r2220_3(char) = Call[get_x] : func:r2220_2, this:r2220_1 -# 2220| m2220_4(unknown) = ^CallSideEffect : ~m2219_6 -# 2220| m2220_5(unknown) = Chi : total:m2219_6, partial:m2220_4 -# 2220| v2220_6(void) = ^IndirectReadSideEffect[-1] : &:r2220_1, m2219_9 -# 2220| m2220_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2220_1 -# 2220| m2220_8(ClassWithDestructor) = Chi : total:m2219_9, partial:m2220_7 -# 2220| r2220_9(int) = Convert : r2220_3 -# 2220| r2220_10(int) = Constant[98] : -# 2220| r2220_11(bool) = CompareEQ : r2220_9, r2220_10 -# 2220| v2220_12(void) = ConditionalBranch : r2220_11 -#-----| False -> Block 14 -#-----| True -> Block 13 +# 2220| r2220_2(glval) = FunctionAddress[set_x] : +# 2220| r2220_3(char) = Constant[97] : +# 2220| v2220_4(void) = Call[set_x] : func:r2220_2, this:r2220_1, 0:r2220_3 +# 2220| m2220_5(unknown) = ^CallSideEffect : ~m2219_50 +# 2220| m2220_6(unknown) = Chi : total:m2219_50, partial:m2220_5 +# 2220| v2220_7(void) = ^IndirectReadSideEffect[-1] : &:r2220_1, m2219_73 +# 2220| m2220_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2220_1 +# 2220| m2220_9(ClassWithDestructor) = Chi : total:m2219_73, partial:m2220_8 +# 2221| r2221_1(glval) = VariableAddress[y] : +# 2221| r2221_2(glval) = FunctionAddress[get_x] : +# 2221| r2221_3(char) = Call[get_x] : func:r2221_2, this:r2221_1 +# 2221| m2221_4(unknown) = ^CallSideEffect : ~m2220_6 +# 2221| m2221_5(unknown) = Chi : total:m2220_6, partial:m2221_4 +# 2221| v2221_6(void) = ^IndirectReadSideEffect[-1] : &:r2221_1, m2220_9 +# 2221| m2221_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2221_1 +# 2221| m2221_8(ClassWithDestructor) = Chi : total:m2220_9, partial:m2221_7 +# 2221| r2221_9(int) = Convert : r2221_3 +# 2221| r2221_10(int) = Constant[98] : +# 2221| r2221_11(bool) = CompareEQ : r2221_9, r2221_10 +# 2221| v2221_12(void) = ConditionalBranch : r2221_11 +#-----| False -> Block 12 +#-----| True -> Block 14 -# 2221| Block 13 -# 2221| v2221_1(void) = NoOp : -# 2218| r2218_59(glval) = VariableAddress[y] : -# 2218| r2218_60(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_61(void) = Call[~ClassWithDestructor] : func:r2218_60, this:r2218_59 -# 2218| m2218_62(unknown) = ^CallSideEffect : ~m2220_5 -# 2218| m2218_63(unknown) = Chi : total:m2220_5, partial:m2218_62 -# 2218| v2218_64(void) = ^IndirectReadSideEffect[-1] : &:r2218_59, m2220_8 -# 2218| m2218_65(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_59 -# 2218| m2218_66(ClassWithDestructor) = Chi : total:m2220_8, partial:m2218_65 -# 2218| r2218_67(glval>) = VariableAddress[ys] : -# 2218| r2218_68(glval) = FunctionAddress[~vector] : -# 2218| v2218_69(void) = Call[~vector] : func:r2218_68, this:r2218_67 -# 2218| m2218_70(unknown) = ^CallSideEffect : ~m2218_63 -# 2218| m2218_71(unknown) = Chi : total:m2218_63, partial:m2218_70 -# 2218| v2218_72(void) = ^IndirectReadSideEffect[-1] : &:r2218_67, ~m2218_71 -# 2218| m2218_73(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_67 -# 2218| m2218_74(unknown) = Chi : total:m2218_71, partial:m2218_73 -# 2233| r2233_1(glval) = VariableAddress[x] : -# 2233| r2233_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2233| v2233_3(void) = Call[~ClassWithDestructor] : func:r2233_2, this:r2233_1 -# 2233| m2233_4(unknown) = ^CallSideEffect : ~m2218_74 -# 2233| m2233_5(unknown) = Chi : total:m2218_74, partial:m2233_4 -# 2233| v2233_6(void) = ^IndirectReadSideEffect[-1] : &:r2233_1, m2214_8 -# 2233| m2233_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_1 -# 2233| m2233_8(ClassWithDestructor) = Chi : total:m2214_8, partial:m2233_7 +# 2222| Block 14 +# 2222| v2222_1(void) = NoOp : +# 2219| r2219_74(glval) = VariableAddress[y] : +# 2219| r2219_75(glval) = FunctionAddress[~ClassWithDestructor] : +# 2219| v2219_76(void) = Call[~ClassWithDestructor] : func:r2219_75, this:r2219_74 +# 2219| m2219_77(unknown) = ^CallSideEffect : ~m2221_5 +# 2219| m2219_78(unknown) = Chi : total:m2221_5, partial:m2219_77 +# 2219| v2219_79(void) = ^IndirectReadSideEffect[-1] : &:r2219_74, m2221_8 +# 2219| m2219_80(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_74 +# 2219| m2219_81(ClassWithDestructor) = Chi : total:m2221_8, partial:m2219_80 +# 2219| r2219_82(glval>) = VariableAddress[ys] : +# 2219| r2219_83(glval) = FunctionAddress[~vector] : +# 2219| v2219_84(void) = Call[~vector] : func:r2219_83, this:r2219_82 +# 2219| m2219_85(unknown) = ^CallSideEffect : ~m2219_78 +# 2219| m2219_86(unknown) = Chi : total:m2219_78, partial:m2219_85 +# 2219| v2219_87(void) = ^IndirectReadSideEffect[-1] : &:r2219_82, ~m2219_86 +# 2219| m2219_88(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2219_82 +# 2219| m2219_89(unknown) = Chi : total:m2219_86, partial:m2219_88 +# 2234| r2234_1(glval) = VariableAddress[x] : +# 2234| r2234_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2234| v2234_3(void) = Call[~ClassWithDestructor] : func:r2234_2, this:r2234_1 +# 2234| m2234_4(unknown) = ^CallSideEffect : ~m2219_89 +# 2234| m2234_5(unknown) = Chi : total:m2219_89, partial:m2234_4 +# 2234| v2234_6(void) = ^IndirectReadSideEffect[-1] : &:r2234_1, m2215_8 +# 2234| m2234_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2234_1 +# 2234| m2234_8(ClassWithDestructor) = Chi : total:m2215_8, partial:m2234_7 #-----| Goto -> Block 1 -# 2218| Block 14 -# 2218| r2218_75(glval) = VariableAddress[y] : -# 2218| r2218_76(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_77(void) = Call[~ClassWithDestructor] : func:r2218_76, this:r2218_75 -# 2218| m2218_78(unknown) = ^CallSideEffect : ~m2220_5 -# 2218| m2218_79(unknown) = Chi : total:m2220_5, partial:m2218_78 -# 2218| v2218_80(void) = ^IndirectReadSideEffect[-1] : &:r2218_75, m2220_8 -# 2218| m2218_81(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_75 -# 2218| m2218_82(ClassWithDestructor) = Chi : total:m2220_8, partial:m2218_81 -# 2218| r2218_83(glval>) = VariableAddress[(__begin)] : -# 2218| r2218_84(glval) = FunctionAddress[operator++] : -# 2218| r2218_85(iterator &) = Call[operator++] : func:r2218_84, this:r2218_83 -# 2218| v2218_86(void) = ^IndirectReadSideEffect[-1] : &:r2218_83, m2218_40 -# 2218| m2218_87(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2218_83 -# 2218| m2218_88(iterator) = Chi : total:m2218_40, partial:m2218_87 -# 2218| r2218_89(glval>) = CopyValue : r2218_85 -#-----| Goto (back edge) -> Block 11 - -# 2224| Block 15 -# 2224| r2224_1(glval>) = VariableAddress[ys] : -# 2224| m2224_2(vector) = Uninitialized[ys] : &:r2224_1 -# 2224| m2224_3(unknown) = Chi : total:m2218_50, partial:m2224_2 -# 2224| r2224_4(glval) = FunctionAddress[vector] : -# 2224| r2224_5(int) = Constant[1] : -# 2224| v2224_6(void) = Call[vector] : func:r2224_4, this:r2224_1, 0:r2224_5 -# 2224| m2224_7(unknown) = ^CallSideEffect : ~m2224_3 -# 2224| m2224_8(unknown) = Chi : total:m2224_3, partial:m2224_7 -# 2224| m2224_9(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2224_1 -# 2224| m2224_10(unknown) = Chi : total:m2224_8, partial:m2224_9 -# 2224| r2224_11(glval &>) = VariableAddress[(__range)] : -# 2224| r2224_12(glval>) = VariableAddress[ys] : -# 2224| r2224_13(vector &) = CopyValue : r2224_12 -# 2224| m2224_14(vector &) = Store[(__range)] : &:r2224_11, r2224_13 -# 2224| r2224_15(glval>) = VariableAddress[(__begin)] : -# 2224| r2224_16(glval &>) = VariableAddress[(__range)] : -# 2224| r2224_17(vector &) = Load[(__range)] : &:r2224_16, m2224_14 -#-----| r0_35(glval>) = CopyValue : r2224_17 +# 2219| Block 15 +# 2219| r2219_90(glval>) = VariableAddress[ys] : +# 2219| r2219_91(glval) = FunctionAddress[~vector] : +# 2219| v2219_92(void) = Call[~vector] : func:r2219_91, this:r2219_90 +# 2219| m2219_93(unknown) = ^CallSideEffect : ~m2219_50 +# 2219| m2219_94(unknown) = Chi : total:m2219_50, partial:m2219_93 +# 2219| v2219_95(void) = ^IndirectReadSideEffect[-1] : &:r2219_90, ~m2219_94 +# 2219| m2219_96(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2219_90 +# 2219| m2219_97(unknown) = Chi : total:m2219_94, partial:m2219_96 +# 2225| r2225_1(glval>) = VariableAddress[ys] : +# 2225| m2225_2(vector) = Uninitialized[ys] : &:r2225_1 +# 2225| m2225_3(unknown) = Chi : total:m2219_97, partial:m2225_2 +# 2225| r2225_4(glval) = FunctionAddress[vector] : +# 2225| r2225_5(int) = Constant[1] : +# 2225| v2225_6(void) = Call[vector] : func:r2225_4, this:r2225_1, 0:r2225_5 +# 2225| m2225_7(unknown) = ^CallSideEffect : ~m2225_3 +# 2225| m2225_8(unknown) = Chi : total:m2225_3, partial:m2225_7 +# 2225| m2225_9(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2225_1 +# 2225| m2225_10(unknown) = Chi : total:m2225_8, partial:m2225_9 +# 2225| r2225_11(glval &>) = VariableAddress[(__range)] : +# 2225| r2225_12(glval>) = VariableAddress[ys] : +# 2225| r2225_13(vector &) = CopyValue : r2225_12 +# 2225| m2225_14(vector &) = Store[(__range)] : &:r2225_11, r2225_13 +# 2225| r2225_15(glval>) = VariableAddress[(__begin)] : +# 2225| r2225_16(glval &>) = VariableAddress[(__range)] : +# 2225| r2225_17(vector &) = Load[(__range)] : &:r2225_16, m2225_14 +#-----| r0_35(glval>) = CopyValue : r2225_17 #-----| r0_36(glval>) = Convert : r0_35 -# 2224| r2224_18(glval) = FunctionAddress[begin] : -# 2224| r2224_19(iterator) = Call[begin] : func:r2224_18, this:r0_36 -#-----| v0_37(void) = ^IndirectReadSideEffect[-1] : &:r0_36, ~m2224_10 -# 2224| m2224_20(iterator) = Store[(__begin)] : &:r2224_15, r2224_19 -# 2224| r2224_21(glval>) = VariableAddress[(__end)] : -# 2224| r2224_22(glval &>) = VariableAddress[(__range)] : -# 2224| r2224_23(vector &) = Load[(__range)] : &:r2224_22, m2224_14 -#-----| r0_38(glval>) = CopyValue : r2224_23 +# 2225| r2225_18(glval) = FunctionAddress[begin] : +# 2225| r2225_19(iterator) = Call[begin] : func:r2225_18, this:r0_36 +#-----| v0_37(void) = ^IndirectReadSideEffect[-1] : &:r0_36, ~m2225_10 +# 2225| m2225_20(iterator) = Store[(__begin)] : &:r2225_15, r2225_19 +# 2225| r2225_21(glval>) = VariableAddress[(__end)] : +# 2225| r2225_22(glval &>) = VariableAddress[(__range)] : +# 2225| r2225_23(vector &) = Load[(__range)] : &:r2225_22, m2225_14 +#-----| r0_38(glval>) = CopyValue : r2225_23 #-----| r0_39(glval>) = Convert : r0_38 -# 2224| r2224_24(glval) = FunctionAddress[end] : -# 2224| r2224_25(iterator) = Call[end] : func:r2224_24, this:r0_39 -#-----| v0_40(void) = ^IndirectReadSideEffect[-1] : &:r0_39, ~m2224_10 -# 2224| m2224_26(iterator) = Store[(__end)] : &:r2224_21, r2224_25 -# 2224| m2224_27(unknown) = Chi : total:m2224_10, partial:m2224_26 +# 2225| r2225_24(glval) = FunctionAddress[end] : +# 2225| r2225_25(iterator) = Call[end] : func:r2225_24, this:r0_39 +#-----| v0_40(void) = ^IndirectReadSideEffect[-1] : &:r0_39, ~m2225_10 +# 2225| m2225_26(iterator) = Store[(__end)] : &:r2225_21, r2225_25 +# 2225| m2225_27(unknown) = Chi : total:m2225_10, partial:m2225_26 #-----| Goto -> Block 16 -# 2224| Block 16 -# 2224| m2224_28(iterator) = Phi : from 15:m2224_20, from 17:m2224_46 -# 2224| m2224_29(unknown) = Phi : from 15:~m2224_27, from 17:~m2224_38 -# 2224| r2224_30(glval>) = VariableAddress[(__begin)] : -#-----| r0_41(glval>) = Convert : r2224_30 -# 2224| r2224_31(glval) = FunctionAddress[operator!=] : +# 2225| Block 16 +# 2225| m2225_28(iterator) = Phi : from 15:m2225_20, from 17:m2225_46 +# 2225| m2225_29(unknown) = Phi : from 15:~m2225_27, from 17:~m2225_38 +# 2225| r2225_30(glval>) = VariableAddress[(__begin)] : +#-----| r0_41(glval>) = Convert : r2225_30 +# 2225| r2225_31(glval) = FunctionAddress[operator!=] : #-----| r0_42(glval>) = VariableAddress[#temp0:0] : #-----| m0_43(iterator) = Uninitialized[#temp0:0] : &:r0_42 -#-----| m0_44(unknown) = Chi : total:m2224_29, partial:m0_43 -# 2224| r2224_32(glval) = FunctionAddress[iterator] : -# 2224| r2224_33(glval>) = VariableAddress[(__end)] : -#-----| r0_45(glval>) = Convert : r2224_33 +#-----| m0_44(unknown) = Chi : total:m2225_29, partial:m0_43 +# 2225| r2225_32(glval) = FunctionAddress[iterator] : +# 2225| r2225_33(glval>) = VariableAddress[(__end)] : +#-----| r0_45(glval>) = Convert : r2225_33 #-----| r0_46(iterator &) = CopyValue : r0_45 -# 2224| v2224_34(void) = Call[iterator] : func:r2224_32, this:r0_42, 0:r0_46 -# 2224| m2224_35(unknown) = ^CallSideEffect : ~m0_44 -# 2224| m2224_36(unknown) = Chi : total:m0_44, partial:m2224_35 -#-----| v0_47(void) = ^BufferReadSideEffect[0] : &:r0_46, ~m2224_36 -# 2224| m2224_37(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_42 -# 2224| m2224_38(unknown) = Chi : total:m2224_36, partial:m2224_37 -#-----| r0_48(iterator) = Load[#temp0:0] : &:r0_42, ~m2224_38 -# 2224| r2224_39(bool) = Call[operator!=] : func:r2224_31, this:r0_41, 0:r0_48 -#-----| v0_49(void) = ^IndirectReadSideEffect[-1] : &:r0_41, m2224_28 -# 2224| v2224_40(void) = ConditionalBranch : r2224_39 +# 2225| v2225_34(void) = Call[iterator] : func:r2225_32, this:r0_42, 0:r0_46 +# 2225| m2225_35(unknown) = ^CallSideEffect : ~m0_44 +# 2225| m2225_36(unknown) = Chi : total:m0_44, partial:m2225_35 +#-----| v0_47(void) = ^BufferReadSideEffect[0] : &:r0_46, ~m2225_36 +# 2225| m2225_37(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_42 +# 2225| m2225_38(unknown) = Chi : total:m2225_36, partial:m2225_37 +#-----| r0_48(iterator) = Load[#temp0:0] : &:r0_42, ~m2225_38 +# 2225| r2225_39(bool) = Call[operator!=] : func:r2225_31, this:r0_41, 0:r0_48 +#-----| v0_49(void) = ^IndirectReadSideEffect[-1] : &:r0_41, m2225_28 +# 2225| v2225_40(void) = ConditionalBranch : r2225_39 #-----| False -> Block 20 #-----| True -> Block 18 -# 2224| Block 17 -# 2224| r2224_41(glval>) = VariableAddress[(__begin)] : -# 2224| r2224_42(glval) = FunctionAddress[operator++] : -# 2224| r2224_43(iterator &) = Call[operator++] : func:r2224_42, this:r2224_41 -# 2224| v2224_44(void) = ^IndirectReadSideEffect[-1] : &:r2224_41, m2224_28 -# 2224| m2224_45(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2224_41 -# 2224| m2224_46(iterator) = Chi : total:m2224_28, partial:m2224_45 -# 2224| r2224_47(glval>) = CopyValue : r2224_43 +# 2225| Block 17 +# 2225| r2225_41(glval>) = VariableAddress[(__begin)] : +# 2225| r2225_42(glval) = FunctionAddress[operator++] : +# 2225| r2225_43(iterator &) = Call[operator++] : func:r2225_42, this:r2225_41 +# 2225| v2225_44(void) = ^IndirectReadSideEffect[-1] : &:r2225_41, m2225_28 +# 2225| m2225_45(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2225_41 +# 2225| m2225_46(iterator) = Chi : total:m2225_28, partial:m2225_45 +# 2225| r2225_47(glval>) = CopyValue : r2225_43 #-----| Goto (back edge) -> Block 16 -# 2224| Block 18 -# 2224| r2224_48(glval) = VariableAddress[y] : -# 2224| r2224_49(glval>) = VariableAddress[(__begin)] : -#-----| r0_50(glval>) = Convert : r2224_49 -# 2224| r2224_50(glval) = FunctionAddress[operator*] : -# 2224| r2224_51(int &) = Call[operator*] : func:r2224_50, this:r0_50 -#-----| v0_51(void) = ^IndirectReadSideEffect[-1] : &:r0_50, m2224_28 -# 2224| r2224_52(int) = Load[?] : &:r2224_51, ~m2224_38 -# 2224| m2224_53(int) = Store[y] : &:r2224_48, r2224_52 -# 2225| r2225_1(glval) = VariableAddress[y] : -# 2225| r2225_2(int) = Load[y] : &:r2225_1, m2224_53 -# 2225| r2225_3(int) = Constant[1] : -# 2225| r2225_4(bool) = CompareEQ : r2225_2, r2225_3 -# 2225| v2225_5(void) = ConditionalBranch : r2225_4 +# 2225| Block 18 +# 2225| r2225_48(glval) = VariableAddress[y] : +# 2225| r2225_49(glval>) = VariableAddress[(__begin)] : +#-----| r0_50(glval>) = Convert : r2225_49 +# 2225| r2225_50(glval) = FunctionAddress[operator*] : +# 2225| r2225_51(int &) = Call[operator*] : func:r2225_50, this:r0_50 +#-----| v0_51(void) = ^IndirectReadSideEffect[-1] : &:r0_50, m2225_28 +# 2225| r2225_52(int) = Load[?] : &:r2225_51, ~m2225_38 +# 2225| m2225_53(int) = Store[y] : &:r2225_48, r2225_52 +# 2226| r2226_1(glval) = VariableAddress[y] : +# 2226| r2226_2(int) = Load[y] : &:r2226_1, m2225_53 +# 2226| r2226_3(int) = Constant[1] : +# 2226| r2226_4(bool) = CompareEQ : r2226_2, r2226_3 +# 2226| v2226_5(void) = ConditionalBranch : r2226_4 #-----| False -> Block 17 #-----| True -> Block 19 -# 2226| Block 19 -# 2226| v2226_1(void) = NoOp : -# 2224| r2224_54(glval>) = VariableAddress[ys] : -# 2224| r2224_55(glval) = FunctionAddress[~vector] : -# 2224| v2224_56(void) = Call[~vector] : func:r2224_55, this:r2224_54 -# 2224| m2224_57(unknown) = ^CallSideEffect : ~m2224_38 -# 2224| m2224_58(unknown) = Chi : total:m2224_38, partial:m2224_57 -# 2224| v2224_59(void) = ^IndirectReadSideEffect[-1] : &:r2224_54, ~m2224_58 -# 2224| m2224_60(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2224_54 -# 2224| m2224_61(unknown) = Chi : total:m2224_58, partial:m2224_60 -# 2233| r2233_9(glval) = VariableAddress[x] : -# 2233| r2233_10(glval) = FunctionAddress[~ClassWithDestructor] : -# 2233| v2233_11(void) = Call[~ClassWithDestructor] : func:r2233_10, this:r2233_9 -# 2233| m2233_12(unknown) = ^CallSideEffect : ~m2224_61 -# 2233| m2233_13(unknown) = Chi : total:m2224_61, partial:m2233_12 -# 2233| v2233_14(void) = ^IndirectReadSideEffect[-1] : &:r2233_9, m2214_8 -# 2233| m2233_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_9 -# 2233| m2233_16(ClassWithDestructor) = Chi : total:m2214_8, partial:m2233_15 +# 2227| Block 19 +# 2227| v2227_1(void) = NoOp : +# 2225| r2225_54(glval>) = VariableAddress[ys] : +# 2225| r2225_55(glval) = FunctionAddress[~vector] : +# 2225| v2225_56(void) = Call[~vector] : func:r2225_55, this:r2225_54 +# 2225| m2225_57(unknown) = ^CallSideEffect : ~m2225_38 +# 2225| m2225_58(unknown) = Chi : total:m2225_38, partial:m2225_57 +# 2225| v2225_59(void) = ^IndirectReadSideEffect[-1] : &:r2225_54, ~m2225_58 +# 2225| m2225_60(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2225_54 +# 2225| m2225_61(unknown) = Chi : total:m2225_58, partial:m2225_60 +# 2234| r2234_9(glval) = VariableAddress[x] : +# 2234| r2234_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2234| v2234_11(void) = Call[~ClassWithDestructor] : func:r2234_10, this:r2234_9 +# 2234| m2234_12(unknown) = ^CallSideEffect : ~m2225_61 +# 2234| m2234_13(unknown) = Chi : total:m2225_61, partial:m2234_12 +# 2234| v2234_14(void) = ^IndirectReadSideEffect[-1] : &:r2234_9, m2215_8 +# 2234| m2234_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2234_9 +# 2234| m2234_16(ClassWithDestructor) = Chi : total:m2215_8, partial:m2234_15 #-----| Goto -> Block 1 -# 2229| Block 20 -# 2229| r2229_1(glval>) = VariableAddress[ys] : -# 2229| m2229_2(vector) = Uninitialized[ys] : &:r2229_1 -# 2229| m2229_3(unknown) = Chi : total:m2224_38, partial:m2229_2 -# 2229| r2229_4(glval) = FunctionAddress[vector] : -# 2229| r2229_5(glval) = VariableAddress[#temp2229:45] : -# 2229| r2229_6(glval) = VariableAddress[x] : -# 2229| r2229_7(ClassWithDestructor) = Load[x] : &:r2229_6, m2214_8 -# 2229| m2229_8(ClassWithDestructor) = Store[#temp2229:45] : &:r2229_5, r2229_7 -# 2229| r2229_9(ClassWithDestructor) = Load[#temp2229:45] : &:r2229_5, m2229_8 -# 2229| v2229_10(void) = Call[vector] : func:r2229_4, this:r2229_1, 0:r2229_9 -# 2229| m2229_11(unknown) = ^CallSideEffect : ~m2229_3 -# 2229| m2229_12(unknown) = Chi : total:m2229_3, partial:m2229_11 -# 2229| m2229_13(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2229_1 -# 2229| m2229_14(unknown) = Chi : total:m2229_12, partial:m2229_13 -# 2229| r2229_15(glval) = CopyValue : r2229_5 -# 2229| r2229_16(glval) = FunctionAddress[~ClassWithDestructor] : -# 2229| v2229_17(void) = Call[~ClassWithDestructor] : func:r2229_16, this:r2229_15 -# 2229| m2229_18(unknown) = ^CallSideEffect : ~m2229_14 -# 2229| m2229_19(unknown) = Chi : total:m2229_14, partial:m2229_18 -# 2229| v2229_20(void) = ^IndirectReadSideEffect[-1] : &:r2229_15, m2229_8 -# 2229| m2229_21(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_15 -# 2229| m2229_22(ClassWithDestructor) = Chi : total:m2229_8, partial:m2229_21 -# 2229| r2229_23(glval &>) = VariableAddress[(__range)] : -# 2229| r2229_24(glval>) = VariableAddress[ys] : -# 2229| r2229_25(vector &) = CopyValue : r2229_24 -# 2229| m2229_26(vector &) = Store[(__range)] : &:r2229_23, r2229_25 -# 2229| r2229_27(glval>) = VariableAddress[(__begin)] : -# 2229| r2229_28(glval &>) = VariableAddress[(__range)] : -# 2229| r2229_29(vector &) = Load[(__range)] : &:r2229_28, m2229_26 -#-----| r0_52(glval>) = CopyValue : r2229_29 +# 2225| Block 20 +# 2225| r2225_62(glval>) = VariableAddress[ys] : +# 2225| r2225_63(glval) = FunctionAddress[~vector] : +# 2225| v2225_64(void) = Call[~vector] : func:r2225_63, this:r2225_62 +# 2225| m2225_65(unknown) = ^CallSideEffect : ~m2225_38 +# 2225| m2225_66(unknown) = Chi : total:m2225_38, partial:m2225_65 +# 2225| v2225_67(void) = ^IndirectReadSideEffect[-1] : &:r2225_62, ~m2225_66 +# 2225| m2225_68(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2225_62 +# 2225| m2225_69(unknown) = Chi : total:m2225_66, partial:m2225_68 +# 2230| r2230_1(glval>) = VariableAddress[ys] : +# 2230| m2230_2(vector) = Uninitialized[ys] : &:r2230_1 +# 2230| m2230_3(unknown) = Chi : total:m2225_69, partial:m2230_2 +# 2230| r2230_4(glval) = FunctionAddress[vector] : +# 2230| r2230_5(glval) = VariableAddress[#temp2230:45] : +# 2230| r2230_6(glval) = VariableAddress[x] : +# 2230| r2230_7(ClassWithDestructor) = Load[x] : &:r2230_6, m2215_8 +# 2230| m2230_8(ClassWithDestructor) = Store[#temp2230:45] : &:r2230_5, r2230_7 +# 2230| r2230_9(ClassWithDestructor) = Load[#temp2230:45] : &:r2230_5, m2230_8 +# 2230| v2230_10(void) = Call[vector] : func:r2230_4, this:r2230_1, 0:r2230_9 +# 2230| m2230_11(unknown) = ^CallSideEffect : ~m2230_3 +# 2230| m2230_12(unknown) = Chi : total:m2230_3, partial:m2230_11 +# 2230| m2230_13(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2230_1 +# 2230| m2230_14(unknown) = Chi : total:m2230_12, partial:m2230_13 +# 2230| r2230_15(glval) = CopyValue : r2230_5 +# 2230| r2230_16(glval) = FunctionAddress[~ClassWithDestructor] : +# 2230| v2230_17(void) = Call[~ClassWithDestructor] : func:r2230_16, this:r2230_15 +# 2230| m2230_18(unknown) = ^CallSideEffect : ~m2230_14 +# 2230| m2230_19(unknown) = Chi : total:m2230_14, partial:m2230_18 +# 2230| v2230_20(void) = ^IndirectReadSideEffect[-1] : &:r2230_15, m2230_8 +# 2230| m2230_21(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2230_15 +# 2230| m2230_22(ClassWithDestructor) = Chi : total:m2230_8, partial:m2230_21 +# 2230| r2230_23(glval &>) = VariableAddress[(__range)] : +# 2230| r2230_24(glval>) = VariableAddress[ys] : +# 2230| r2230_25(vector &) = CopyValue : r2230_24 +# 2230| m2230_26(vector &) = Store[(__range)] : &:r2230_23, r2230_25 +# 2230| r2230_27(glval>) = VariableAddress[(__begin)] : +# 2230| r2230_28(glval &>) = VariableAddress[(__range)] : +# 2230| r2230_29(vector &) = Load[(__range)] : &:r2230_28, m2230_26 +#-----| r0_52(glval>) = CopyValue : r2230_29 #-----| r0_53(glval>) = Convert : r0_52 -# 2229| r2229_30(glval) = FunctionAddress[begin] : -# 2229| r2229_31(iterator) = Call[begin] : func:r2229_30, this:r0_53 -#-----| v0_54(void) = ^IndirectReadSideEffect[-1] : &:r0_53, ~m2229_19 -# 2229| m2229_32(iterator) = Store[(__begin)] : &:r2229_27, r2229_31 -# 2229| r2229_33(glval>) = VariableAddress[(__end)] : -# 2229| r2229_34(glval &>) = VariableAddress[(__range)] : -# 2229| r2229_35(vector &) = Load[(__range)] : &:r2229_34, m2229_26 -#-----| r0_55(glval>) = CopyValue : r2229_35 +# 2230| r2230_30(glval) = FunctionAddress[begin] : +# 2230| r2230_31(iterator) = Call[begin] : func:r2230_30, this:r0_53 +#-----| v0_54(void) = ^IndirectReadSideEffect[-1] : &:r0_53, ~m2230_19 +# 2230| m2230_32(iterator) = Store[(__begin)] : &:r2230_27, r2230_31 +# 2230| r2230_33(glval>) = VariableAddress[(__end)] : +# 2230| r2230_34(glval &>) = VariableAddress[(__range)] : +# 2230| r2230_35(vector &) = Load[(__range)] : &:r2230_34, m2230_26 +#-----| r0_55(glval>) = CopyValue : r2230_35 #-----| r0_56(glval>) = Convert : r0_55 -# 2229| r2229_36(glval) = FunctionAddress[end] : -# 2229| r2229_37(iterator) = Call[end] : func:r2229_36, this:r0_56 -#-----| v0_57(void) = ^IndirectReadSideEffect[-1] : &:r0_56, ~m2229_19 -# 2229| m2229_38(iterator) = Store[(__end)] : &:r2229_33, r2229_37 -# 2229| m2229_39(unknown) = Chi : total:m2229_19, partial:m2229_38 +# 2230| r2230_36(glval) = FunctionAddress[end] : +# 2230| r2230_37(iterator) = Call[end] : func:r2230_36, this:r0_56 +#-----| v0_57(void) = ^IndirectReadSideEffect[-1] : &:r0_56, ~m2230_19 +# 2230| m2230_38(iterator) = Store[(__end)] : &:r2230_33, r2230_37 +# 2230| m2230_39(unknown) = Chi : total:m2230_19, partial:m2230_38 #-----| Goto -> Block 21 -# 2229| Block 21 -# 2229| m2229_40(iterator) = Phi : from 20:m2229_32, from 22:m2229_72 -# 2229| m2229_41(unknown) = Phi : from 20:~m2229_39, from 22:~m2229_63 -# 2229| r2229_42(glval>) = VariableAddress[(__begin)] : -#-----| r0_58(glval>) = Convert : r2229_42 -# 2229| r2229_43(glval) = FunctionAddress[operator!=] : +# 2230| Block 21 +# 2230| m2230_40(iterator) = Phi : from 20:m2230_32, from 22:m2230_64 +# 2230| m2230_41(unknown) = Phi : from 20:~m2230_39, from 22:~m2230_69 +# 2230| r2230_42(glval>) = VariableAddress[(__begin)] : +#-----| r0_58(glval>) = Convert : r2230_42 +# 2230| r2230_43(glval) = FunctionAddress[operator!=] : #-----| r0_59(glval>) = VariableAddress[#temp0:0] : #-----| m0_60(iterator) = Uninitialized[#temp0:0] : &:r0_59 -#-----| m0_61(unknown) = Chi : total:m2229_41, partial:m0_60 -# 2229| r2229_44(glval) = FunctionAddress[iterator] : -# 2229| r2229_45(glval>) = VariableAddress[(__end)] : -#-----| r0_62(glval>) = Convert : r2229_45 +#-----| m0_61(unknown) = Chi : total:m2230_41, partial:m0_60 +# 2230| r2230_44(glval) = FunctionAddress[iterator] : +# 2230| r2230_45(glval>) = VariableAddress[(__end)] : +#-----| r0_62(glval>) = Convert : r2230_45 #-----| r0_63(iterator &) = CopyValue : r0_62 -# 2229| v2229_46(void) = Call[iterator] : func:r2229_44, this:r0_59, 0:r0_63 -# 2229| m2229_47(unknown) = ^CallSideEffect : ~m0_61 -# 2229| m2229_48(unknown) = Chi : total:m0_61, partial:m2229_47 -#-----| v0_64(void) = ^BufferReadSideEffect[0] : &:r0_63, ~m2229_48 -# 2229| m2229_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_59 -# 2229| m2229_50(unknown) = Chi : total:m2229_48, partial:m2229_49 -#-----| r0_65(iterator) = Load[#temp0:0] : &:r0_59, ~m2229_50 -# 2229| r2229_51(bool) = Call[operator!=] : func:r2229_43, this:r0_58, 0:r0_65 -#-----| v0_66(void) = ^IndirectReadSideEffect[-1] : &:r0_58, m2229_40 -# 2229| v2229_52(void) = ConditionalBranch : r2229_51 +# 2230| v2230_46(void) = Call[iterator] : func:r2230_44, this:r0_59, 0:r0_63 +# 2230| m2230_47(unknown) = ^CallSideEffect : ~m0_61 +# 2230| m2230_48(unknown) = Chi : total:m0_61, partial:m2230_47 +#-----| v0_64(void) = ^BufferReadSideEffect[0] : &:r0_63, ~m2230_48 +# 2230| m2230_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_59 +# 2230| m2230_50(unknown) = Chi : total:m2230_48, partial:m2230_49 +#-----| r0_65(iterator) = Load[#temp0:0] : &:r0_59, ~m2230_50 +# 2230| r2230_51(bool) = Call[operator!=] : func:r2230_43, this:r0_58, 0:r0_65 +#-----| v0_66(void) = ^IndirectReadSideEffect[-1] : &:r0_58, m2230_40 +# 2230| v2230_52(void) = ConditionalBranch : r2230_51 #-----| False -> Block 23 #-----| True -> Block 22 -# 2229| Block 22 -# 2229| r2229_53(glval) = VariableAddress[y] : -# 2229| r2229_54(glval>) = VariableAddress[(__begin)] : -#-----| r0_67(glval>) = Convert : r2229_54 -# 2229| r2229_55(glval) = FunctionAddress[operator*] : -# 2229| r2229_56(ClassWithDestructor &) = Call[operator*] : func:r2229_55, this:r0_67 -#-----| v0_68(void) = ^IndirectReadSideEffect[-1] : &:r0_67, m2229_40 -# 2229| r2229_57(ClassWithDestructor) = Load[?] : &:r2229_56, ~m2229_50 -# 2229| m2229_58(ClassWithDestructor) = Store[y] : &:r2229_53, r2229_57 -# 2230| r2230_1(glval) = VariableAddress[z1] : -# 2230| m2230_2(ClassWithDestructor) = Uninitialized[z1] : &:r2230_1 -# 2230| r2230_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2230| v2230_4(void) = Call[ClassWithDestructor] : func:r2230_3, this:r2230_1 -# 2230| m2230_5(unknown) = ^CallSideEffect : ~m2229_50 -# 2230| m2230_6(unknown) = Chi : total:m2229_50, partial:m2230_5 -# 2230| m2230_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2230_1 -# 2230| m2230_8(ClassWithDestructor) = Chi : total:m2230_2, partial:m2230_7 -# 2231| r2231_1(glval) = VariableAddress[z2] : -# 2231| m2231_2(ClassWithDestructor) = Uninitialized[z2] : &:r2231_1 +# 2230| Block 22 +# 2230| r2230_53(glval) = VariableAddress[y] : +# 2230| r2230_54(glval>) = VariableAddress[(__begin)] : +#-----| r0_67(glval>) = Convert : r2230_54 +# 2230| r2230_55(glval) = FunctionAddress[operator*] : +# 2230| r2230_56(ClassWithDestructor &) = Call[operator*] : func:r2230_55, this:r0_67 +#-----| v0_68(void) = ^IndirectReadSideEffect[-1] : &:r0_67, m2230_40 +# 2230| r2230_57(ClassWithDestructor) = Load[?] : &:r2230_56, ~m2230_50 +# 2230| m2230_58(ClassWithDestructor) = Store[y] : &:r2230_53, r2230_57 +# 2231| r2231_1(glval) = VariableAddress[z1] : +# 2231| m2231_2(ClassWithDestructor) = Uninitialized[z1] : &:r2231_1 # 2231| r2231_3(glval) = FunctionAddress[ClassWithDestructor] : # 2231| v2231_4(void) = Call[ClassWithDestructor] : func:r2231_3, this:r2231_1 -# 2231| m2231_5(unknown) = ^CallSideEffect : ~m2230_6 -# 2231| m2231_6(unknown) = Chi : total:m2230_6, partial:m2231_5 +# 2231| m2231_5(unknown) = ^CallSideEffect : ~m2230_50 +# 2231| m2231_6(unknown) = Chi : total:m2230_50, partial:m2231_5 # 2231| m2231_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2231_1 # 2231| m2231_8(ClassWithDestructor) = Chi : total:m2231_2, partial:m2231_7 # 2232| r2232_1(glval) = VariableAddress[z2] : -# 2232| r2232_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2232| v2232_3(void) = Call[~ClassWithDestructor] : func:r2232_2, this:r2232_1 -# 2232| m2232_4(unknown) = ^CallSideEffect : ~m2231_6 -# 2232| m2232_5(unknown) = Chi : total:m2231_6, partial:m2232_4 -# 2232| v2232_6(void) = ^IndirectReadSideEffect[-1] : &:r2232_1, m2231_8 +# 2232| m2232_2(ClassWithDestructor) = Uninitialized[z2] : &:r2232_1 +# 2232| r2232_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2232| v2232_4(void) = Call[ClassWithDestructor] : func:r2232_3, this:r2232_1 +# 2232| m2232_5(unknown) = ^CallSideEffect : ~m2231_6 +# 2232| m2232_6(unknown) = Chi : total:m2231_6, partial:m2232_5 # 2232| m2232_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2232_1 -# 2232| m2232_8(ClassWithDestructor) = Chi : total:m2231_8, partial:m2232_7 -# 2232| r2232_9(glval) = VariableAddress[z1] : -# 2232| r2232_10(glval) = FunctionAddress[~ClassWithDestructor] : -# 2232| v2232_11(void) = Call[~ClassWithDestructor] : func:r2232_10, this:r2232_9 -# 2232| m2232_12(unknown) = ^CallSideEffect : ~m2232_5 -# 2232| m2232_13(unknown) = Chi : total:m2232_5, partial:m2232_12 -# 2232| v2232_14(void) = ^IndirectReadSideEffect[-1] : &:r2232_9, m2230_8 -# 2232| m2232_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2232_9 -# 2232| m2232_16(ClassWithDestructor) = Chi : total:m2230_8, partial:m2232_15 -# 2229| r2229_59(glval) = VariableAddress[y] : -# 2229| r2229_60(glval) = FunctionAddress[~ClassWithDestructor] : -# 2229| v2229_61(void) = Call[~ClassWithDestructor] : func:r2229_60, this:r2229_59 -# 2229| m2229_62(unknown) = ^CallSideEffect : ~m2232_13 -# 2229| m2229_63(unknown) = Chi : total:m2232_13, partial:m2229_62 -# 2229| v2229_64(void) = ^IndirectReadSideEffect[-1] : &:r2229_59, m2229_58 -# 2229| m2229_65(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_59 -# 2229| m2229_66(ClassWithDestructor) = Chi : total:m2229_58, partial:m2229_65 -# 2229| r2229_67(glval>) = VariableAddress[(__begin)] : -# 2229| r2229_68(glval) = FunctionAddress[operator++] : -# 2229| r2229_69(iterator &) = Call[operator++] : func:r2229_68, this:r2229_67 -# 2229| v2229_70(void) = ^IndirectReadSideEffect[-1] : &:r2229_67, m2229_40 -# 2229| m2229_71(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2229_67 -# 2229| m2229_72(iterator) = Chi : total:m2229_40, partial:m2229_71 -# 2229| r2229_73(glval>) = CopyValue : r2229_69 +# 2232| m2232_8(ClassWithDestructor) = Chi : total:m2232_2, partial:m2232_7 +# 2233| r2233_1(glval) = VariableAddress[z2] : +# 2233| r2233_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2233| v2233_3(void) = Call[~ClassWithDestructor] : func:r2233_2, this:r2233_1 +# 2233| m2233_4(unknown) = ^CallSideEffect : ~m2232_6 +# 2233| m2233_5(unknown) = Chi : total:m2232_6, partial:m2233_4 +# 2233| v2233_6(void) = ^IndirectReadSideEffect[-1] : &:r2233_1, m2232_8 +# 2233| m2233_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_1 +# 2233| m2233_8(ClassWithDestructor) = Chi : total:m2232_8, partial:m2233_7 +# 2233| r2233_9(glval) = VariableAddress[z1] : +# 2233| r2233_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2233| v2233_11(void) = Call[~ClassWithDestructor] : func:r2233_10, this:r2233_9 +# 2233| m2233_12(unknown) = ^CallSideEffect : ~m2233_5 +# 2233| m2233_13(unknown) = Chi : total:m2233_5, partial:m2233_12 +# 2233| v2233_14(void) = ^IndirectReadSideEffect[-1] : &:r2233_9, m2231_8 +# 2233| m2233_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_9 +# 2233| m2233_16(ClassWithDestructor) = Chi : total:m2231_8, partial:m2233_15 +# 2230| r2230_59(glval>) = VariableAddress[(__begin)] : +# 2230| r2230_60(glval) = FunctionAddress[operator++] : +# 2230| r2230_61(iterator &) = Call[operator++] : func:r2230_60, this:r2230_59 +# 2230| v2230_62(void) = ^IndirectReadSideEffect[-1] : &:r2230_59, m2230_40 +# 2230| m2230_63(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2230_59 +# 2230| m2230_64(iterator) = Chi : total:m2230_40, partial:m2230_63 +# 2230| r2230_65(glval) = VariableAddress[y] : +# 2230| r2230_66(glval) = FunctionAddress[~ClassWithDestructor] : +# 2230| v2230_67(void) = Call[~ClassWithDestructor] : func:r2230_66, this:r2230_65 +# 2230| m2230_68(unknown) = ^CallSideEffect : ~m2233_13 +# 2230| m2230_69(unknown) = Chi : total:m2233_13, partial:m2230_68 +# 2230| v2230_70(void) = ^IndirectReadSideEffect[-1] : &:r2230_65, m2230_58 +# 2230| m2230_71(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2230_65 +# 2230| m2230_72(ClassWithDestructor) = Chi : total:m2230_58, partial:m2230_71 +# 2230| r2230_73(glval>) = CopyValue : r2230_61 #-----| Goto (back edge) -> Block 21 -# 2233| Block 23 -# 2233| v2233_17(void) = NoOp : -# 2233| r2233_18(glval) = VariableAddress[x] : -# 2233| r2233_19(glval) = FunctionAddress[~ClassWithDestructor] : -# 2233| v2233_20(void) = Call[~ClassWithDestructor] : func:r2233_19, this:r2233_18 -# 2233| m2233_21(unknown) = ^CallSideEffect : ~m2229_50 -# 2233| m2233_22(unknown) = Chi : total:m2229_50, partial:m2233_21 -# 2233| v2233_23(void) = ^IndirectReadSideEffect[-1] : &:r2233_18, m2214_8 -# 2233| m2233_24(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_18 -# 2233| m2233_25(ClassWithDestructor) = Chi : total:m2214_8, partial:m2233_24 +# 2230| Block 23 +# 2230| r2230_74(glval>) = VariableAddress[ys] : +# 2230| r2230_75(glval) = FunctionAddress[~vector] : +# 2230| v2230_76(void) = Call[~vector] : func:r2230_75, this:r2230_74 +# 2230| m2230_77(unknown) = ^CallSideEffect : ~m2230_50 +# 2230| m2230_78(unknown) = Chi : total:m2230_50, partial:m2230_77 +# 2230| v2230_79(void) = ^IndirectReadSideEffect[-1] : &:r2230_74, ~m2230_78 +# 2230| m2230_80(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2230_74 +# 2230| m2230_81(unknown) = Chi : total:m2230_78, partial:m2230_80 +# 2234| v2234_17(void) = NoOp : +# 2234| r2234_18(glval) = VariableAddress[x] : +# 2234| r2234_19(glval) = FunctionAddress[~ClassWithDestructor] : +# 2234| v2234_20(void) = Call[~ClassWithDestructor] : func:r2234_19, this:r2234_18 +# 2234| m2234_21(unknown) = ^CallSideEffect : ~m2230_81 +# 2234| m2234_22(unknown) = Chi : total:m2230_81, partial:m2234_21 +# 2234| v2234_23(void) = ^IndirectReadSideEffect[-1] : &:r2234_18, m2215_8 +# 2234| m2234_24(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2234_18 +# 2234| m2234_25(ClassWithDestructor) = Chi : total:m2215_8, partial:m2234_24 #-----| Goto -> Block 1 -# 2198| Block 24 -# 2198| v2198_13(void) = Unreached : - -# 2235| void static_variable_with_destructor_1() -# 2235| Block 0 -# 2235| v2235_1(void) = EnterFunction : -# 2235| m2235_2(unknown) = AliasedDefinition : -# 2235| m2235_3(unknown) = InitializeNonLocal : -# 2235| m2235_4(unknown) = Chi : total:m2235_2, partial:m2235_3 -# 2236| r2236_1(glval) = VariableAddress[a] : -# 2236| m2236_2(ClassWithDestructor) = Uninitialized[a] : &:r2236_1 -# 2236| r2236_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2236| v2236_4(void) = Call[ClassWithDestructor] : func:r2236_3, this:r2236_1 -# 2236| m2236_5(unknown) = ^CallSideEffect : ~m2235_4 -# 2236| m2236_6(unknown) = Chi : total:m2235_4, partial:m2236_5 -# 2236| m2236_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2236_1 -# 2236| m2236_8(ClassWithDestructor) = Chi : total:m2236_2, partial:m2236_7 -# 2237| r2237_1(glval) = VariableAddress[b#init] : -# 2237| r2237_2(bool) = Load[b#init] : &:r2237_1, ~m2236_6 -# 2237| v2237_3(void) = ConditionalBranch : r2237_2 +# 2199| Block 24 +# 2199| v2199_13(void) = Unreached : + +# 2236| void static_variable_with_destructor_1() +# 2236| Block 0 +# 2236| v2236_1(void) = EnterFunction : +# 2236| m2236_2(unknown) = AliasedDefinition : +# 2236| m2236_3(unknown) = InitializeNonLocal : +# 2236| m2236_4(unknown) = Chi : total:m2236_2, partial:m2236_3 +# 2237| r2237_1(glval) = VariableAddress[a] : +# 2237| m2237_2(ClassWithDestructor) = Uninitialized[a] : &:r2237_1 +# 2237| r2237_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2237| v2237_4(void) = Call[ClassWithDestructor] : func:r2237_3, this:r2237_1 +# 2237| m2237_5(unknown) = ^CallSideEffect : ~m2236_4 +# 2237| m2237_6(unknown) = Chi : total:m2236_4, partial:m2237_5 +# 2237| m2237_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2237_1 +# 2237| m2237_8(ClassWithDestructor) = Chi : total:m2237_2, partial:m2237_7 +# 2238| r2238_1(glval) = VariableAddress[b#init] : +# 2238| r2238_2(bool) = Load[b#init] : &:r2238_1, ~m2237_6 +# 2238| v2238_3(void) = ConditionalBranch : r2238_2 #-----| False -> Block 1 #-----| True -> Block 2 -# 2237| Block 1 -# 2237| r2237_4(glval) = VariableAddress[b] : +# 2238| Block 1 +# 2238| r2238_4(glval) = VariableAddress[b] : #-----| r0_1(glval) = FunctionAddress[ClassWithDestructor] : -#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2237_4 -#-----| m0_3(unknown) = ^CallSideEffect : ~m2236_6 -#-----| m0_4(unknown) = Chi : total:m2236_6, partial:m0_3 -#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2237_4 +#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2238_4 +#-----| m0_3(unknown) = ^CallSideEffect : ~m2237_6 +#-----| m0_4(unknown) = Chi : total:m2237_6, partial:m0_3 +#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2238_4 #-----| m0_6(unknown) = Chi : total:m0_4, partial:m0_5 -# 2237| r2237_5(bool) = Constant[1] : -# 2237| m2237_6(bool) = Store[b#init] : &:r2237_1, r2237_5 -# 2237| m2237_7(unknown) = Chi : total:m0_6, partial:m2237_6 +# 2238| r2238_5(bool) = Constant[1] : +# 2238| m2238_6(bool) = Store[b#init] : &:r2238_1, r2238_5 +# 2238| m2238_7(unknown) = Chi : total:m0_6, partial:m2238_6 #-----| Goto -> Block 2 -# 2238| Block 2 -# 2238| m2238_1(unknown) = Phi : from 0:~m2236_6, from 1:~m2237_7 -# 2238| v2238_2(void) = NoOp : -# 2238| r2238_3(glval) = VariableAddress[a] : -# 2238| r2238_4(glval) = FunctionAddress[~ClassWithDestructor] : -# 2238| v2238_5(void) = Call[~ClassWithDestructor] : func:r2238_4, this:r2238_3 -# 2238| m2238_6(unknown) = ^CallSideEffect : ~m2238_1 -# 2238| m2238_7(unknown) = Chi : total:m2238_1, partial:m2238_6 -# 2238| v2238_8(void) = ^IndirectReadSideEffect[-1] : &:r2238_3, m2236_8 -# 2238| m2238_9(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2238_3 -# 2238| m2238_10(ClassWithDestructor) = Chi : total:m2236_8, partial:m2238_9 -# 2235| v2235_5(void) = ReturnVoid : -# 2235| v2235_6(void) = AliasedUse : ~m2238_7 -# 2235| v2235_7(void) = ExitFunction : - -# 2240| void static_variable_with_destructor_2() -# 2240| Block 0 -# 2240| v2240_1(void) = EnterFunction : -# 2240| m2240_2(unknown) = AliasedDefinition : -# 2240| m2240_3(unknown) = InitializeNonLocal : -# 2240| m2240_4(unknown) = Chi : total:m2240_2, partial:m2240_3 -# 2241| r2241_1(glval) = VariableAddress[a#init] : -# 2241| r2241_2(bool) = Load[a#init] : &:r2241_1, ~m2240_3 -# 2241| v2241_3(void) = ConditionalBranch : r2241_2 +# 2239| Block 2 +# 2239| m2239_1(unknown) = Phi : from 0:~m2237_6, from 1:~m2238_7 +# 2239| v2239_2(void) = NoOp : +# 2239| r2239_3(glval) = VariableAddress[a] : +# 2239| r2239_4(glval) = FunctionAddress[~ClassWithDestructor] : +# 2239| v2239_5(void) = Call[~ClassWithDestructor] : func:r2239_4, this:r2239_3 +# 2239| m2239_6(unknown) = ^CallSideEffect : ~m2239_1 +# 2239| m2239_7(unknown) = Chi : total:m2239_1, partial:m2239_6 +# 2239| v2239_8(void) = ^IndirectReadSideEffect[-1] : &:r2239_3, m2237_8 +# 2239| m2239_9(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2239_3 +# 2239| m2239_10(ClassWithDestructor) = Chi : total:m2237_8, partial:m2239_9 +# 2236| v2236_5(void) = ReturnVoid : +# 2236| v2236_6(void) = AliasedUse : ~m2239_7 +# 2236| v2236_7(void) = ExitFunction : + +# 2241| void static_variable_with_destructor_2() +# 2241| Block 0 +# 2241| v2241_1(void) = EnterFunction : +# 2241| m2241_2(unknown) = AliasedDefinition : +# 2241| m2241_3(unknown) = InitializeNonLocal : +# 2241| m2241_4(unknown) = Chi : total:m2241_2, partial:m2241_3 +# 2242| r2242_1(glval) = VariableAddress[a#init] : +# 2242| r2242_2(bool) = Load[a#init] : &:r2242_1, ~m2241_3 +# 2242| v2242_3(void) = ConditionalBranch : r2242_2 #-----| False -> Block 1 #-----| True -> Block 2 -# 2241| Block 1 -# 2241| r2241_4(glval) = VariableAddress[a] : +# 2242| Block 1 +# 2242| r2242_4(glval) = VariableAddress[a] : #-----| r0_1(glval) = FunctionAddress[ClassWithDestructor] : -#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2241_4 -#-----| m0_3(unknown) = ^CallSideEffect : ~m2240_4 -#-----| m0_4(unknown) = Chi : total:m2240_4, partial:m0_3 -#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2241_4 +#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2242_4 +#-----| m0_3(unknown) = ^CallSideEffect : ~m2241_4 +#-----| m0_4(unknown) = Chi : total:m2241_4, partial:m0_3 +#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2242_4 #-----| m0_6(unknown) = Chi : total:m0_4, partial:m0_5 -# 2241| r2241_5(bool) = Constant[1] : -# 2241| m2241_6(bool) = Store[a#init] : &:r2241_1, r2241_5 -# 2241| m2241_7(unknown) = Chi : total:m0_6, partial:m2241_6 +# 2242| r2242_5(bool) = Constant[1] : +# 2242| m2242_6(bool) = Store[a#init] : &:r2242_1, r2242_5 +# 2242| m2242_7(unknown) = Chi : total:m0_6, partial:m2242_6 #-----| Goto -> Block 2 -# 2242| Block 2 -# 2242| m2242_1(unknown) = Phi : from 0:~m2240_4, from 1:~m2241_7 -# 2242| r2242_2(glval) = VariableAddress[b] : -# 2242| m2242_3(ClassWithDestructor) = Uninitialized[b] : &:r2242_2 -# 2242| r2242_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2242| v2242_5(void) = Call[ClassWithDestructor] : func:r2242_4, this:r2242_2 -# 2242| m2242_6(unknown) = ^CallSideEffect : ~m2242_1 -# 2242| m2242_7(unknown) = Chi : total:m2242_1, partial:m2242_6 -# 2242| m2242_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2242_2 -# 2242| m2242_9(ClassWithDestructor) = Chi : total:m2242_3, partial:m2242_8 -# 2243| v2243_1(void) = NoOp : +# 2243| Block 2 +# 2243| m2243_1(unknown) = Phi : from 0:~m2241_4, from 1:~m2242_7 # 2243| r2243_2(glval) = VariableAddress[b] : -# 2243| r2243_3(glval) = FunctionAddress[~ClassWithDestructor] : -# 2243| v2243_4(void) = Call[~ClassWithDestructor] : func:r2243_3, this:r2243_2 -# 2243| m2243_5(unknown) = ^CallSideEffect : ~m2242_7 -# 2243| m2243_6(unknown) = Chi : total:m2242_7, partial:m2243_5 -# 2243| v2243_7(void) = ^IndirectReadSideEffect[-1] : &:r2243_2, m2242_9 +# 2243| m2243_3(ClassWithDestructor) = Uninitialized[b] : &:r2243_2 +# 2243| r2243_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2243| v2243_5(void) = Call[ClassWithDestructor] : func:r2243_4, this:r2243_2 +# 2243| m2243_6(unknown) = ^CallSideEffect : ~m2243_1 +# 2243| m2243_7(unknown) = Chi : total:m2243_1, partial:m2243_6 # 2243| m2243_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2243_2 -# 2243| m2243_9(ClassWithDestructor) = Chi : total:m2242_9, partial:m2243_8 -# 2240| v2240_5(void) = ReturnVoid : -# 2240| v2240_6(void) = AliasedUse : ~m2243_6 -# 2240| v2240_7(void) = ExitFunction : - -# 2245| void static_variable_with_destructor_3() -# 2245| Block 0 -# 2245| v2245_1(void) = EnterFunction : -# 2245| m2245_2(unknown) = AliasedDefinition : -# 2245| m2245_3(unknown) = InitializeNonLocal : -# 2245| m2245_4(unknown) = Chi : total:m2245_2, partial:m2245_3 -# 2246| r2246_1(glval) = VariableAddress[a] : -# 2246| m2246_2(ClassWithDestructor) = Uninitialized[a] : &:r2246_1 -# 2246| r2246_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2246| v2246_4(void) = Call[ClassWithDestructor] : func:r2246_3, this:r2246_1 -# 2246| m2246_5(unknown) = ^CallSideEffect : ~m2245_4 -# 2246| m2246_6(unknown) = Chi : total:m2245_4, partial:m2246_5 -# 2246| m2246_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2246_1 -# 2246| m2246_8(ClassWithDestructor) = Chi : total:m2246_2, partial:m2246_7 -# 2247| r2247_1(glval) = VariableAddress[b] : -# 2247| m2247_2(ClassWithDestructor) = Uninitialized[b] : &:r2247_1 +# 2243| m2243_9(ClassWithDestructor) = Chi : total:m2243_3, partial:m2243_8 +# 2244| v2244_1(void) = NoOp : +# 2244| r2244_2(glval) = VariableAddress[b] : +# 2244| r2244_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2244| v2244_4(void) = Call[~ClassWithDestructor] : func:r2244_3, this:r2244_2 +# 2244| m2244_5(unknown) = ^CallSideEffect : ~m2243_7 +# 2244| m2244_6(unknown) = Chi : total:m2243_7, partial:m2244_5 +# 2244| v2244_7(void) = ^IndirectReadSideEffect[-1] : &:r2244_2, m2243_9 +# 2244| m2244_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2244_2 +# 2244| m2244_9(ClassWithDestructor) = Chi : total:m2243_9, partial:m2244_8 +# 2241| v2241_5(void) = ReturnVoid : +# 2241| v2241_6(void) = AliasedUse : ~m2244_6 +# 2241| v2241_7(void) = ExitFunction : + +# 2246| void static_variable_with_destructor_3() +# 2246| Block 0 +# 2246| v2246_1(void) = EnterFunction : +# 2246| m2246_2(unknown) = AliasedDefinition : +# 2246| m2246_3(unknown) = InitializeNonLocal : +# 2246| m2246_4(unknown) = Chi : total:m2246_2, partial:m2246_3 +# 2247| r2247_1(glval) = VariableAddress[a] : +# 2247| m2247_2(ClassWithDestructor) = Uninitialized[a] : &:r2247_1 # 2247| r2247_3(glval) = FunctionAddress[ClassWithDestructor] : # 2247| v2247_4(void) = Call[ClassWithDestructor] : func:r2247_3, this:r2247_1 -# 2247| m2247_5(unknown) = ^CallSideEffect : ~m2246_6 -# 2247| m2247_6(unknown) = Chi : total:m2246_6, partial:m2247_5 +# 2247| m2247_5(unknown) = ^CallSideEffect : ~m2246_4 +# 2247| m2247_6(unknown) = Chi : total:m2246_4, partial:m2247_5 # 2247| m2247_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2247_1 # 2247| m2247_8(ClassWithDestructor) = Chi : total:m2247_2, partial:m2247_7 -# 2248| r2248_1(glval) = VariableAddress[c#init] : -# 2248| r2248_2(bool) = Load[c#init] : &:r2248_1, ~m2247_6 -# 2248| v2248_3(void) = ConditionalBranch : r2248_2 +# 2248| r2248_1(glval) = VariableAddress[b] : +# 2248| m2248_2(ClassWithDestructor) = Uninitialized[b] : &:r2248_1 +# 2248| r2248_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2248| v2248_4(void) = Call[ClassWithDestructor] : func:r2248_3, this:r2248_1 +# 2248| m2248_5(unknown) = ^CallSideEffect : ~m2247_6 +# 2248| m2248_6(unknown) = Chi : total:m2247_6, partial:m2248_5 +# 2248| m2248_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2248_1 +# 2248| m2248_8(ClassWithDestructor) = Chi : total:m2248_2, partial:m2248_7 +# 2249| r2249_1(glval) = VariableAddress[c#init] : +# 2249| r2249_2(bool) = Load[c#init] : &:r2249_1, ~m2248_6 +# 2249| v2249_3(void) = ConditionalBranch : r2249_2 #-----| False -> Block 1 #-----| True -> Block 2 -# 2248| Block 1 -# 2248| r2248_4(glval) = VariableAddress[c] : +# 2249| Block 1 +# 2249| r2249_4(glval) = VariableAddress[c] : #-----| r0_1(glval) = FunctionAddress[ClassWithDestructor] : -#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2248_4 -#-----| m0_3(unknown) = ^CallSideEffect : ~m2247_6 -#-----| m0_4(unknown) = Chi : total:m2247_6, partial:m0_3 -#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2248_4 +#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2249_4 +#-----| m0_3(unknown) = ^CallSideEffect : ~m2248_6 +#-----| m0_4(unknown) = Chi : total:m2248_6, partial:m0_3 +#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2249_4 #-----| m0_6(unknown) = Chi : total:m0_4, partial:m0_5 -# 2248| r2248_5(bool) = Constant[1] : -# 2248| m2248_6(bool) = Store[c#init] : &:r2248_1, r2248_5 -# 2248| m2248_7(unknown) = Chi : total:m0_6, partial:m2248_6 +# 2249| r2249_5(bool) = Constant[1] : +# 2249| m2249_6(bool) = Store[c#init] : &:r2249_1, r2249_5 +# 2249| m2249_7(unknown) = Chi : total:m0_6, partial:m2249_6 #-----| Goto -> Block 2 -# 2249| Block 2 -# 2249| m2249_1(unknown) = Phi : from 0:~m2247_6, from 1:~m2248_7 -# 2249| v2249_2(void) = NoOp : -# 2249| r2249_3(glval) = VariableAddress[b] : -# 2249| r2249_4(glval) = FunctionAddress[~ClassWithDestructor] : -# 2249| v2249_5(void) = Call[~ClassWithDestructor] : func:r2249_4, this:r2249_3 -# 2249| m2249_6(unknown) = ^CallSideEffect : ~m2249_1 -# 2249| m2249_7(unknown) = Chi : total:m2249_1, partial:m2249_6 -# 2249| v2249_8(void) = ^IndirectReadSideEffect[-1] : &:r2249_3, m2247_8 -# 2249| m2249_9(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2249_3 -# 2249| m2249_10(ClassWithDestructor) = Chi : total:m2247_8, partial:m2249_9 -# 2249| r2249_11(glval) = VariableAddress[a] : -# 2249| r2249_12(glval) = FunctionAddress[~ClassWithDestructor] : -# 2249| v2249_13(void) = Call[~ClassWithDestructor] : func:r2249_12, this:r2249_11 -# 2249| m2249_14(unknown) = ^CallSideEffect : ~m2249_7 -# 2249| m2249_15(unknown) = Chi : total:m2249_7, partial:m2249_14 -# 2249| v2249_16(void) = ^IndirectReadSideEffect[-1] : &:r2249_11, m2246_8 -# 2249| m2249_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2249_11 -# 2249| m2249_18(ClassWithDestructor) = Chi : total:m2246_8, partial:m2249_17 -# 2245| v2245_5(void) = ReturnVoid : -# 2245| v2245_6(void) = AliasedUse : ~m2249_15 -# 2245| v2245_7(void) = ExitFunction : - -# 2251| ClassWithDestructor global_class_with_destructor -# 2251| Block 0 -# 2251| v2251_1(void) = EnterFunction : -# 2251| m2251_2(unknown) = AliasedDefinition : -# 2251| r2251_3(glval) = VariableAddress[global_class_with_destructor] : -# 2251| r2251_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2251| v2251_5(void) = Call[ClassWithDestructor] : func:r2251_4, this:r2251_3 -# 2251| m2251_6(unknown) = ^CallSideEffect : ~m2251_2 -# 2251| m2251_7(unknown) = Chi : total:m2251_2, partial:m2251_6 -# 2251| m2251_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2251_3 -# 2251| m2251_9(unknown) = Chi : total:m2251_7, partial:m2251_8 -# 2251| v2251_10(void) = ReturnVoid : -# 2251| v2251_11(void) = AliasedUse : ~m2251_9 -# 2251| v2251_12(void) = ExitFunction : - -# 2255| ClassWithDestructor& vacuous_destructor_call::get(ClassWithDestructor&) -# 2255| Block 0 -# 2255| v2255_1(void) = EnterFunction : -# 2255| m2255_2(unknown) = AliasedDefinition : -# 2255| m2255_3(unknown) = InitializeNonLocal : -# 2255| m2255_4(unknown) = Chi : total:m2255_2, partial:m2255_3 -# 2255| r2255_5(glval) = VariableAddress[t] : -# 2255| m2255_6(ClassWithDestructor &) = InitializeParameter[t] : &:r2255_5 -# 2255| r2255_7(ClassWithDestructor &) = Load[t] : &:r2255_5, m2255_6 -# 2255| m2255_8(unknown) = InitializeIndirection[t] : &:r2255_7 -# 2255| r2255_9(glval) = VariableAddress[#return] : -# 2255| r2255_10(glval) = VariableAddress[t] : -# 2255| r2255_11(ClassWithDestructor &) = Load[t] : &:r2255_10, m2255_6 -# 2255| r2255_12(glval) = CopyValue : r2255_11 -# 2255| r2255_13(ClassWithDestructor &) = CopyValue : r2255_12 -# 2255| m2255_14(ClassWithDestructor &) = Store[#return] : &:r2255_9, r2255_13 -# 2255| v2255_15(void) = ReturnIndirection[t] : &:r2255_7, m2255_8 -# 2255| r2255_16(glval) = VariableAddress[#return] : -# 2255| v2255_17(void) = ReturnValue : &:r2255_16, m2255_14 -# 2255| v2255_18(void) = AliasedUse : m2255_3 -# 2255| v2255_19(void) = ExitFunction : - -# 2255| int& vacuous_destructor_call::get(int&) -# 2255| Block 0 -# 2255| v2255_1(void) = EnterFunction : -# 2255| m2255_2(unknown) = AliasedDefinition : -# 2255| m2255_3(unknown) = InitializeNonLocal : -# 2255| m2255_4(unknown) = Chi : total:m2255_2, partial:m2255_3 -# 2255| r2255_5(glval) = VariableAddress[t] : -# 2255| m2255_6(int &) = InitializeParameter[t] : &:r2255_5 -# 2255| r2255_7(int &) = Load[t] : &:r2255_5, m2255_6 -# 2255| m2255_8(unknown) = InitializeIndirection[t] : &:r2255_7 -# 2255| r2255_9(glval) = VariableAddress[#return] : -# 2255| r2255_10(glval) = VariableAddress[t] : -# 2255| r2255_11(int &) = Load[t] : &:r2255_10, m2255_6 -# 2255| r2255_12(glval) = CopyValue : r2255_11 -# 2255| r2255_13(int &) = CopyValue : r2255_12 -# 2255| m2255_14(int &) = Store[#return] : &:r2255_9, r2255_13 -# 2255| v2255_15(void) = ReturnIndirection[t] : &:r2255_7, m2255_8 -# 2255| r2255_16(glval) = VariableAddress[#return] : -# 2255| v2255_17(void) = ReturnValue : &:r2255_16, m2255_14 -# 2255| v2255_18(void) = AliasedUse : m2255_3 -# 2255| v2255_19(void) = ExitFunction : - -# 2258| void vacuous_destructor_call::call_destructor(ClassWithDestructor&) -# 2258| Block 0 -# 2258| v2258_1(void) = EnterFunction : -# 2258| m2258_2(unknown) = AliasedDefinition : -# 2258| m2258_3(unknown) = InitializeNonLocal : -# 2258| m2258_4(unknown) = Chi : total:m2258_2, partial:m2258_3 -# 2258| r2258_5(glval) = VariableAddress[t] : -# 2258| m2258_6(ClassWithDestructor &) = InitializeParameter[t] : &:r2258_5 -# 2258| r2258_7(ClassWithDestructor &) = Load[t] : &:r2258_5, m2258_6 -# 2258| m2258_8(unknown) = InitializeIndirection[t] : &:r2258_7 -# 2259| r2259_1(glval) = FunctionAddress[get] : -# 2259| r2259_2(glval) = VariableAddress[t] : -# 2259| r2259_3(ClassWithDestructor &) = Load[t] : &:r2259_2, m2258_6 -# 2259| r2259_4(glval) = CopyValue : r2259_3 -# 2259| r2259_5(ClassWithDestructor &) = CopyValue : r2259_4 -# 2259| r2259_6(ClassWithDestructor &) = Call[get] : func:r2259_1, 0:r2259_5 -# 2259| m2259_7(unknown) = ^CallSideEffect : ~m2258_4 -# 2259| m2259_8(unknown) = Chi : total:m2258_4, partial:m2259_7 -# 2259| v2259_9(void) = ^BufferReadSideEffect[0] : &:r2259_5, ~m2258_8 -# 2259| m2259_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r2259_5 -# 2259| m2259_11(unknown) = Chi : total:m2258_8, partial:m2259_10 -# 2259| r2259_12(glval) = CopyValue : r2259_6 -# 2259| r2259_13(glval) = FunctionAddress[~ClassWithDestructor] : -# 2259| v2259_14(void) = Call[~ClassWithDestructor] : func:r2259_13 -# 2259| m2259_15(unknown) = ^CallSideEffect : ~m2259_8 -# 2259| m2259_16(unknown) = Chi : total:m2259_8, partial:m2259_15 -# 2259| v2259_17(void) = ^IndirectReadSideEffect[-1] : &:r2259_12, ~m2259_11 -# 2259| m2259_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2259_12 -# 2259| m2259_19(unknown) = Chi : total:m2259_11, partial:m2259_18 -# 2260| v2260_1(void) = NoOp : -# 2258| v2258_9(void) = ReturnIndirection[t] : &:r2258_7, m2259_19 -# 2258| v2258_10(void) = ReturnVoid : -# 2258| v2258_11(void) = AliasedUse : ~m2259_16 -# 2258| v2258_12(void) = ExitFunction : - -# 2258| void vacuous_destructor_call::call_destructor(int&) -# 2258| Block 0 -# 2258| v2258_1(void) = EnterFunction : -# 2258| m2258_2(unknown) = AliasedDefinition : -# 2258| m2258_3(unknown) = InitializeNonLocal : -# 2258| m2258_4(unknown) = Chi : total:m2258_2, partial:m2258_3 -# 2258| r2258_5(glval) = VariableAddress[t] : -# 2258| m2258_6(int &) = InitializeParameter[t] : &:r2258_5 -# 2258| r2258_7(int &) = Load[t] : &:r2258_5, m2258_6 -# 2258| m2258_8(unknown) = InitializeIndirection[t] : &:r2258_7 -# 2259| r2259_1(glval) = FunctionAddress[get] : -# 2259| r2259_2(glval) = VariableAddress[t] : -# 2259| r2259_3(int &) = Load[t] : &:r2259_2, m2258_6 -# 2259| r2259_4(glval) = CopyValue : r2259_3 -# 2259| r2259_5(int &) = CopyValue : r2259_4 -# 2259| r2259_6(int &) = Call[get] : func:r2259_1, 0:r2259_5 -# 2259| m2259_7(unknown) = ^CallSideEffect : ~m2258_4 -# 2259| m2259_8(unknown) = Chi : total:m2258_4, partial:m2259_7 -# 2259| v2259_9(void) = ^BufferReadSideEffect[0] : &:r2259_5, ~m2258_8 -# 2259| m2259_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r2259_5 -# 2259| m2259_11(unknown) = Chi : total:m2258_8, partial:m2259_10 -# 2259| r2259_12(glval) = CopyValue : r2259_6 -# 2260| v2260_1(void) = NoOp : -# 2258| v2258_9(void) = ReturnIndirection[t] : &:r2258_7, m2259_11 -# 2258| v2258_10(void) = ReturnVoid : -# 2258| v2258_11(void) = AliasedUse : ~m2259_8 -# 2258| v2258_12(void) = ExitFunction : - -# 2262| void vacuous_destructor_call::non_vacuous_destructor_call() -# 2262| Block 0 -# 2262| v2262_1(void) = EnterFunction : -# 2262| m2262_2(unknown) = AliasedDefinition : -# 2262| m2262_3(unknown) = InitializeNonLocal : -# 2262| m2262_4(unknown) = Chi : total:m2262_2, partial:m2262_3 -# 2263| r2263_1(glval) = VariableAddress[c] : -# 2263| m2263_2(ClassWithDestructor) = Uninitialized[c] : &:r2263_1 -# 2263| r2263_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2263| v2263_4(void) = Call[ClassWithDestructor] : func:r2263_3, this:r2263_1 -# 2263| m2263_5(unknown) = ^CallSideEffect : ~m2262_4 -# 2263| m2263_6(unknown) = Chi : total:m2262_4, partial:m2263_5 -# 2263| m2263_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2263_1 -# 2263| m2263_8(ClassWithDestructor) = Chi : total:m2263_2, partial:m2263_7 -# 2264| r2264_1(glval) = FunctionAddress[call_destructor] : -# 2264| r2264_2(glval) = VariableAddress[c] : -# 2264| r2264_3(ClassWithDestructor &) = CopyValue : r2264_2 -# 2264| v2264_4(void) = Call[call_destructor] : func:r2264_1, 0:r2264_3 -# 2264| m2264_5(unknown) = ^CallSideEffect : ~m2263_6 -# 2264| m2264_6(unknown) = Chi : total:m2263_6, partial:m2264_5 -# 2264| v2264_7(void) = ^BufferReadSideEffect[0] : &:r2264_3, ~m2263_8 -# 2264| m2264_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r2264_3 -# 2264| m2264_9(ClassWithDestructor) = Chi : total:m2263_8, partial:m2264_8 -# 2265| v2265_1(void) = NoOp : +# 2250| Block 2 +# 2250| m2250_1(unknown) = Phi : from 0:~m2248_6, from 1:~m2249_7 +# 2250| v2250_2(void) = NoOp : +# 2250| r2250_3(glval) = VariableAddress[b] : +# 2250| r2250_4(glval) = FunctionAddress[~ClassWithDestructor] : +# 2250| v2250_5(void) = Call[~ClassWithDestructor] : func:r2250_4, this:r2250_3 +# 2250| m2250_6(unknown) = ^CallSideEffect : ~m2250_1 +# 2250| m2250_7(unknown) = Chi : total:m2250_1, partial:m2250_6 +# 2250| v2250_8(void) = ^IndirectReadSideEffect[-1] : &:r2250_3, m2248_8 +# 2250| m2250_9(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2250_3 +# 2250| m2250_10(ClassWithDestructor) = Chi : total:m2248_8, partial:m2250_9 +# 2250| r2250_11(glval) = VariableAddress[a] : +# 2250| r2250_12(glval) = FunctionAddress[~ClassWithDestructor] : +# 2250| v2250_13(void) = Call[~ClassWithDestructor] : func:r2250_12, this:r2250_11 +# 2250| m2250_14(unknown) = ^CallSideEffect : ~m2250_7 +# 2250| m2250_15(unknown) = Chi : total:m2250_7, partial:m2250_14 +# 2250| v2250_16(void) = ^IndirectReadSideEffect[-1] : &:r2250_11, m2247_8 +# 2250| m2250_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2250_11 +# 2250| m2250_18(ClassWithDestructor) = Chi : total:m2247_8, partial:m2250_17 +# 2246| v2246_5(void) = ReturnVoid : +# 2246| v2246_6(void) = AliasedUse : ~m2250_15 +# 2246| v2246_7(void) = ExitFunction : + +# 2252| ClassWithDestructor global_class_with_destructor +# 2252| Block 0 +# 2252| v2252_1(void) = EnterFunction : +# 2252| m2252_2(unknown) = AliasedDefinition : +# 2252| r2252_3(glval) = VariableAddress[global_class_with_destructor] : +# 2252| r2252_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2252| v2252_5(void) = Call[ClassWithDestructor] : func:r2252_4, this:r2252_3 +# 2252| m2252_6(unknown) = ^CallSideEffect : ~m2252_2 +# 2252| m2252_7(unknown) = Chi : total:m2252_2, partial:m2252_6 +# 2252| m2252_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2252_3 +# 2252| m2252_9(unknown) = Chi : total:m2252_7, partial:m2252_8 +# 2252| v2252_10(void) = ReturnVoid : +# 2252| v2252_11(void) = AliasedUse : ~m2252_9 +# 2252| v2252_12(void) = ExitFunction : + +# 2256| ClassWithDestructor& vacuous_destructor_call::get(ClassWithDestructor&) +# 2256| Block 0 +# 2256| v2256_1(void) = EnterFunction : +# 2256| m2256_2(unknown) = AliasedDefinition : +# 2256| m2256_3(unknown) = InitializeNonLocal : +# 2256| m2256_4(unknown) = Chi : total:m2256_2, partial:m2256_3 +# 2256| r2256_5(glval) = VariableAddress[t] : +# 2256| m2256_6(ClassWithDestructor &) = InitializeParameter[t] : &:r2256_5 +# 2256| r2256_7(ClassWithDestructor &) = Load[t] : &:r2256_5, m2256_6 +# 2256| m2256_8(unknown) = InitializeIndirection[t] : &:r2256_7 +# 2256| r2256_9(glval) = VariableAddress[#return] : +# 2256| r2256_10(glval) = VariableAddress[t] : +# 2256| r2256_11(ClassWithDestructor &) = Load[t] : &:r2256_10, m2256_6 +# 2256| r2256_12(glval) = CopyValue : r2256_11 +# 2256| r2256_13(ClassWithDestructor &) = CopyValue : r2256_12 +# 2256| m2256_14(ClassWithDestructor &) = Store[#return] : &:r2256_9, r2256_13 +# 2256| v2256_15(void) = ReturnIndirection[t] : &:r2256_7, m2256_8 +# 2256| r2256_16(glval) = VariableAddress[#return] : +# 2256| v2256_17(void) = ReturnValue : &:r2256_16, m2256_14 +# 2256| v2256_18(void) = AliasedUse : m2256_3 +# 2256| v2256_19(void) = ExitFunction : + +# 2256| int& vacuous_destructor_call::get(int&) +# 2256| Block 0 +# 2256| v2256_1(void) = EnterFunction : +# 2256| m2256_2(unknown) = AliasedDefinition : +# 2256| m2256_3(unknown) = InitializeNonLocal : +# 2256| m2256_4(unknown) = Chi : total:m2256_2, partial:m2256_3 +# 2256| r2256_5(glval) = VariableAddress[t] : +# 2256| m2256_6(int &) = InitializeParameter[t] : &:r2256_5 +# 2256| r2256_7(int &) = Load[t] : &:r2256_5, m2256_6 +# 2256| m2256_8(unknown) = InitializeIndirection[t] : &:r2256_7 +# 2256| r2256_9(glval) = VariableAddress[#return] : +# 2256| r2256_10(glval) = VariableAddress[t] : +# 2256| r2256_11(int &) = Load[t] : &:r2256_10, m2256_6 +# 2256| r2256_12(glval) = CopyValue : r2256_11 +# 2256| r2256_13(int &) = CopyValue : r2256_12 +# 2256| m2256_14(int &) = Store[#return] : &:r2256_9, r2256_13 +# 2256| v2256_15(void) = ReturnIndirection[t] : &:r2256_7, m2256_8 +# 2256| r2256_16(glval) = VariableAddress[#return] : +# 2256| v2256_17(void) = ReturnValue : &:r2256_16, m2256_14 +# 2256| v2256_18(void) = AliasedUse : m2256_3 +# 2256| v2256_19(void) = ExitFunction : + +# 2259| void vacuous_destructor_call::call_destructor(ClassWithDestructor&) +# 2259| Block 0 +# 2259| v2259_1(void) = EnterFunction : +# 2259| m2259_2(unknown) = AliasedDefinition : +# 2259| m2259_3(unknown) = InitializeNonLocal : +# 2259| m2259_4(unknown) = Chi : total:m2259_2, partial:m2259_3 +# 2259| r2259_5(glval) = VariableAddress[t] : +# 2259| m2259_6(ClassWithDestructor &) = InitializeParameter[t] : &:r2259_5 +# 2259| r2259_7(ClassWithDestructor &) = Load[t] : &:r2259_5, m2259_6 +# 2259| m2259_8(unknown) = InitializeIndirection[t] : &:r2259_7 +# 2260| r2260_1(glval) = FunctionAddress[get] : +# 2260| r2260_2(glval) = VariableAddress[t] : +# 2260| r2260_3(ClassWithDestructor &) = Load[t] : &:r2260_2, m2259_6 +# 2260| r2260_4(glval) = CopyValue : r2260_3 +# 2260| r2260_5(ClassWithDestructor &) = CopyValue : r2260_4 +# 2260| r2260_6(ClassWithDestructor &) = Call[get] : func:r2260_1, 0:r2260_5 +# 2260| m2260_7(unknown) = ^CallSideEffect : ~m2259_4 +# 2260| m2260_8(unknown) = Chi : total:m2259_4, partial:m2260_7 +# 2260| v2260_9(void) = ^BufferReadSideEffect[0] : &:r2260_5, ~m2259_8 +# 2260| m2260_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r2260_5 +# 2260| m2260_11(unknown) = Chi : total:m2259_8, partial:m2260_10 +# 2260| r2260_12(glval) = CopyValue : r2260_6 +# 2260| r2260_13(glval) = FunctionAddress[~ClassWithDestructor] : +# 2260| v2260_14(void) = Call[~ClassWithDestructor] : func:r2260_13 +# 2260| m2260_15(unknown) = ^CallSideEffect : ~m2260_8 +# 2260| m2260_16(unknown) = Chi : total:m2260_8, partial:m2260_15 +# 2260| v2260_17(void) = ^IndirectReadSideEffect[-1] : &:r2260_12, ~m2260_11 +# 2260| m2260_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2260_12 +# 2260| m2260_19(unknown) = Chi : total:m2260_11, partial:m2260_18 +# 2261| v2261_1(void) = NoOp : +# 2259| v2259_9(void) = ReturnIndirection[t] : &:r2259_7, m2260_19 +# 2259| v2259_10(void) = ReturnVoid : +# 2259| v2259_11(void) = AliasedUse : ~m2260_16 +# 2259| v2259_12(void) = ExitFunction : + +# 2259| void vacuous_destructor_call::call_destructor(int&) +# 2259| Block 0 +# 2259| v2259_1(void) = EnterFunction : +# 2259| m2259_2(unknown) = AliasedDefinition : +# 2259| m2259_3(unknown) = InitializeNonLocal : +# 2259| m2259_4(unknown) = Chi : total:m2259_2, partial:m2259_3 +# 2259| r2259_5(glval) = VariableAddress[t] : +# 2259| m2259_6(int &) = InitializeParameter[t] : &:r2259_5 +# 2259| r2259_7(int &) = Load[t] : &:r2259_5, m2259_6 +# 2259| m2259_8(unknown) = InitializeIndirection[t] : &:r2259_7 +# 2260| r2260_1(glval) = FunctionAddress[get] : +# 2260| r2260_2(glval) = VariableAddress[t] : +# 2260| r2260_3(int &) = Load[t] : &:r2260_2, m2259_6 +# 2260| r2260_4(glval) = CopyValue : r2260_3 +# 2260| r2260_5(int &) = CopyValue : r2260_4 +# 2260| r2260_6(int &) = Call[get] : func:r2260_1, 0:r2260_5 +# 2260| m2260_7(unknown) = ^CallSideEffect : ~m2259_4 +# 2260| m2260_8(unknown) = Chi : total:m2259_4, partial:m2260_7 +# 2260| v2260_9(void) = ^BufferReadSideEffect[0] : &:r2260_5, ~m2259_8 +# 2260| m2260_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r2260_5 +# 2260| m2260_11(unknown) = Chi : total:m2259_8, partial:m2260_10 +# 2260| r2260_12(glval) = CopyValue : r2260_6 +# 2261| v2261_1(void) = NoOp : +# 2259| v2259_9(void) = ReturnIndirection[t] : &:r2259_7, m2260_11 +# 2259| v2259_10(void) = ReturnVoid : +# 2259| v2259_11(void) = AliasedUse : ~m2260_8 +# 2259| v2259_12(void) = ExitFunction : + +# 2263| void vacuous_destructor_call::non_vacuous_destructor_call() +# 2263| Block 0 +# 2263| v2263_1(void) = EnterFunction : +# 2263| m2263_2(unknown) = AliasedDefinition : +# 2263| m2263_3(unknown) = InitializeNonLocal : +# 2263| m2263_4(unknown) = Chi : total:m2263_2, partial:m2263_3 +# 2264| r2264_1(glval) = VariableAddress[c] : +# 2264| m2264_2(ClassWithDestructor) = Uninitialized[c] : &:r2264_1 +# 2264| r2264_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2264| v2264_4(void) = Call[ClassWithDestructor] : func:r2264_3, this:r2264_1 +# 2264| m2264_5(unknown) = ^CallSideEffect : ~m2263_4 +# 2264| m2264_6(unknown) = Chi : total:m2263_4, partial:m2264_5 +# 2264| m2264_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2264_1 +# 2264| m2264_8(ClassWithDestructor) = Chi : total:m2264_2, partial:m2264_7 +# 2265| r2265_1(glval) = FunctionAddress[call_destructor] : # 2265| r2265_2(glval) = VariableAddress[c] : -# 2265| r2265_3(glval) = FunctionAddress[~ClassWithDestructor] : -# 2265| v2265_4(void) = Call[~ClassWithDestructor] : func:r2265_3, this:r2265_2 +# 2265| r2265_3(ClassWithDestructor &) = CopyValue : r2265_2 +# 2265| v2265_4(void) = Call[call_destructor] : func:r2265_1, 0:r2265_3 # 2265| m2265_5(unknown) = ^CallSideEffect : ~m2264_6 # 2265| m2265_6(unknown) = Chi : total:m2264_6, partial:m2265_5 -# 2265| v2265_7(void) = ^IndirectReadSideEffect[-1] : &:r2265_2, m2264_9 -# 2265| m2265_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2265_2 -# 2265| m2265_9(ClassWithDestructor) = Chi : total:m2264_9, partial:m2265_8 -# 2262| v2262_5(void) = ReturnVoid : -# 2262| v2262_6(void) = AliasedUse : ~m2265_6 -# 2262| v2262_7(void) = ExitFunction : - -# 2267| void vacuous_destructor_call::vacuous_destructor_call() -# 2267| Block 0 -# 2267| v2267_1(void) = EnterFunction : -# 2267| m2267_2(unknown) = AliasedDefinition : -# 2267| m2267_3(unknown) = InitializeNonLocal : -# 2267| m2267_4(unknown) = Chi : total:m2267_2, partial:m2267_3 -# 2268| r2268_1(glval) = VariableAddress[i] : -# 2268| m2268_2(int) = Uninitialized[i] : &:r2268_1 -# 2269| r2269_1(glval) = FunctionAddress[call_destructor] : -# 2269| r2269_2(glval) = VariableAddress[i] : -# 2269| r2269_3(int &) = CopyValue : r2269_2 -# 2269| v2269_4(void) = Call[call_destructor] : func:r2269_1, 0:r2269_3 -# 2269| m2269_5(unknown) = ^CallSideEffect : ~m2267_4 -# 2269| m2269_6(unknown) = Chi : total:m2267_4, partial:m2269_5 -# 2269| v2269_7(void) = ^BufferReadSideEffect[0] : &:r2269_3, ~m2268_2 -# 2269| m2269_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r2269_3 -# 2269| m2269_9(int) = Chi : total:m2268_2, partial:m2269_8 -# 2270| v2270_1(void) = NoOp : -# 2267| v2267_5(void) = ReturnVoid : -# 2267| v2267_6(void) = AliasedUse : ~m2269_6 -# 2267| v2267_7(void) = ExitFunction : - -# 2273| void TryCatchDestructors(bool) -# 2273| Block 0 -# 2273| v2273_1(void) = EnterFunction : -# 2273| m2273_2(unknown) = AliasedDefinition : -# 2273| m2273_3(unknown) = InitializeNonLocal : -# 2273| m2273_4(unknown) = Chi : total:m2273_2, partial:m2273_3 -# 2273| r2273_5(glval) = VariableAddress[b] : -# 2273| m2273_6(bool) = InitializeParameter[b] : &:r2273_5 -# 2275| r2275_1(glval) = VariableAddress[s] : -# 2275| m2275_2(String) = Uninitialized[s] : &:r2275_1 -# 2275| m2275_3(unknown) = Chi : total:m2273_4, partial:m2275_2 -# 2275| r2275_4(glval) = FunctionAddress[String] : -# 2275| v2275_5(void) = Call[String] : func:r2275_4, this:r2275_1 -# 2275| m2275_6(unknown) = ^CallSideEffect : ~m2275_3 -# 2275| m2275_7(unknown) = Chi : total:m2275_3, partial:m2275_6 -# 2275| m2275_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2275_1 -# 2275| m2275_9(unknown) = Chi : total:m2275_7, partial:m2275_8 -# 2276| r2276_1(glval) = VariableAddress[b] : -# 2276| r2276_2(bool) = Load[b] : &:r2276_1, m2273_6 -# 2276| v2276_3(void) = ConditionalBranch : r2276_2 +# 2265| v2265_7(void) = ^BufferReadSideEffect[0] : &:r2265_3, ~m2264_8 +# 2265| m2265_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r2265_3 +# 2265| m2265_9(ClassWithDestructor) = Chi : total:m2264_8, partial:m2265_8 +# 2266| v2266_1(void) = NoOp : +# 2266| r2266_2(glval) = VariableAddress[c] : +# 2266| r2266_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2266| v2266_4(void) = Call[~ClassWithDestructor] : func:r2266_3, this:r2266_2 +# 2266| m2266_5(unknown) = ^CallSideEffect : ~m2265_6 +# 2266| m2266_6(unknown) = Chi : total:m2265_6, partial:m2266_5 +# 2266| v2266_7(void) = ^IndirectReadSideEffect[-1] : &:r2266_2, m2265_9 +# 2266| m2266_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2266_2 +# 2266| m2266_9(ClassWithDestructor) = Chi : total:m2265_9, partial:m2266_8 +# 2263| v2263_5(void) = ReturnVoid : +# 2263| v2263_6(void) = AliasedUse : ~m2266_6 +# 2263| v2263_7(void) = ExitFunction : + +# 2268| void vacuous_destructor_call::vacuous_destructor_call() +# 2268| Block 0 +# 2268| v2268_1(void) = EnterFunction : +# 2268| m2268_2(unknown) = AliasedDefinition : +# 2268| m2268_3(unknown) = InitializeNonLocal : +# 2268| m2268_4(unknown) = Chi : total:m2268_2, partial:m2268_3 +# 2269| r2269_1(glval) = VariableAddress[i] : +# 2269| m2269_2(int) = Uninitialized[i] : &:r2269_1 +# 2270| r2270_1(glval) = FunctionAddress[call_destructor] : +# 2270| r2270_2(glval) = VariableAddress[i] : +# 2270| r2270_3(int &) = CopyValue : r2270_2 +# 2270| v2270_4(void) = Call[call_destructor] : func:r2270_1, 0:r2270_3 +# 2270| m2270_5(unknown) = ^CallSideEffect : ~m2268_4 +# 2270| m2270_6(unknown) = Chi : total:m2268_4, partial:m2270_5 +# 2270| v2270_7(void) = ^BufferReadSideEffect[0] : &:r2270_3, ~m2269_2 +# 2270| m2270_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r2270_3 +# 2270| m2270_9(int) = Chi : total:m2269_2, partial:m2270_8 +# 2271| v2271_1(void) = NoOp : +# 2268| v2268_5(void) = ReturnVoid : +# 2268| v2268_6(void) = AliasedUse : ~m2270_6 +# 2268| v2268_7(void) = ExitFunction : + +# 2274| void TryCatchDestructors(bool) +# 2274| Block 0 +# 2274| v2274_1(void) = EnterFunction : +# 2274| m2274_2(unknown) = AliasedDefinition : +# 2274| m2274_3(unknown) = InitializeNonLocal : +# 2274| m2274_4(unknown) = Chi : total:m2274_2, partial:m2274_3 +# 2274| r2274_5(glval) = VariableAddress[b] : +# 2274| m2274_6(bool) = InitializeParameter[b] : &:r2274_5 +# 2276| r2276_1(glval) = VariableAddress[s] : +# 2276| m2276_2(String) = Uninitialized[s] : &:r2276_1 +# 2276| m2276_3(unknown) = Chi : total:m2274_4, partial:m2276_2 +# 2276| r2276_4(glval) = FunctionAddress[String] : +# 2276| v2276_5(void) = Call[String] : func:r2276_4, this:r2276_1 +# 2276| m2276_6(unknown) = ^CallSideEffect : ~m2276_3 +# 2276| m2276_7(unknown) = Chi : total:m2276_3, partial:m2276_6 +# 2276| m2276_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2276_1 +# 2276| m2276_9(unknown) = Chi : total:m2276_7, partial:m2276_8 +# 2277| r2277_1(glval) = VariableAddress[b] : +# 2277| r2277_2(bool) = Load[b] : &:r2277_1, m2274_6 +# 2277| v2277_3(void) = ConditionalBranch : r2277_2 #-----| False -> Block 4 #-----| True -> Block 3 -# 2273| Block 1 -# 2273| m2273_7(unknown) = Phi : from 2:~m2273_10, from 10:~m2289_1 -# 2273| v2273_8(void) = AliasedUse : ~m2273_7 -# 2273| v2273_9(void) = ExitFunction : +# 2274| Block 1 +# 2274| m2274_7(unknown) = Phi : from 2:~m2274_10, from 10:~m2290_1 +# 2274| v2274_8(void) = AliasedUse : ~m2274_7 +# 2274| v2274_9(void) = ExitFunction : -# 2273| Block 2 -# 2273| m2273_10(unknown) = Phi : from 6:~m2282_12, from 9:~m2280_8 -# 2273| v2273_11(void) = Unwind : +# 2274| Block 2 +# 2274| m2274_10(unknown) = Phi : from 6:~m2283_12, from 9:~m2281_8 +# 2274| v2274_11(void) = Unwind : #-----| Goto -> Block 1 -# 2277| Block 3 -# 2277| r2277_1(glval) = VariableAddress[#throw2277:7] : -# 2277| r2277_2(glval) = StringConstant["string literal"] : -# 2277| r2277_3(char *) = Convert : r2277_2 -# 2277| m2277_4(char *) = Store[#throw2277:7] : &:r2277_1, r2277_3 -# 2277| v2277_5(void) = ThrowValue : &:r2277_1, m2277_4 -# 2280| r2280_1(glval) = VariableAddress[s] : -# 2280| r2280_2(glval) = FunctionAddress[~String] : -# 2280| v2280_3(void) = Call[~String] : func:r2280_2, this:r2280_1 -# 2280| m2280_4(unknown) = ^CallSideEffect : ~m2275_9 -# 2280| m2280_5(unknown) = Chi : total:m2275_9, partial:m2280_4 -# 2280| v2280_6(void) = ^IndirectReadSideEffect[-1] : &:r2280_1, ~m2280_5 -# 2280| m2280_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_1 -# 2280| m2280_8(unknown) = Chi : total:m2280_5, partial:m2280_7 +# 2278| Block 3 +# 2278| r2278_1(glval) = VariableAddress[#throw2278:7] : +# 2278| r2278_2(glval) = StringConstant["string literal"] : +# 2278| r2278_3(char *) = Convert : r2278_2 +# 2278| m2278_4(char *) = Store[#throw2278:7] : &:r2278_1, r2278_3 +# 2278| v2278_5(void) = ThrowValue : &:r2278_1, m2278_4 +# 2281| r2281_1(glval) = VariableAddress[s] : +# 2281| r2281_2(glval) = FunctionAddress[~String] : +# 2281| v2281_3(void) = Call[~String] : func:r2281_2, this:r2281_1 +# 2281| m2281_4(unknown) = ^CallSideEffect : ~m2276_9 +# 2281| m2281_5(unknown) = Chi : total:m2276_9, partial:m2281_4 +# 2281| v2281_6(void) = ^IndirectReadSideEffect[-1] : &:r2281_1, ~m2281_5 +# 2281| m2281_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2281_1 +# 2281| m2281_8(unknown) = Chi : total:m2281_5, partial:m2281_7 #-----| Exception -> Block 5 -# 2279| Block 4 -# 2279| r2279_1(glval) = VariableAddress[s2] : -# 2279| m2279_2(String) = Uninitialized[s2] : &:r2279_1 -# 2279| m2279_3(unknown) = Chi : total:m2275_9, partial:m2279_2 -# 2279| r2279_4(glval) = FunctionAddress[String] : -# 2279| v2279_5(void) = Call[String] : func:r2279_4, this:r2279_1 -# 2279| m2279_6(unknown) = ^CallSideEffect : ~m2279_3 -# 2279| m2279_7(unknown) = Chi : total:m2279_3, partial:m2279_6 -# 2279| m2279_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2279_1 -# 2279| m2279_9(unknown) = Chi : total:m2279_7, partial:m2279_8 -# 2280| r2280_9(glval) = VariableAddress[s2] : -# 2280| r2280_10(glval) = FunctionAddress[~String] : -# 2280| v2280_11(void) = Call[~String] : func:r2280_10, this:r2280_9 -# 2280| m2280_12(unknown) = ^CallSideEffect : ~m2279_9 -# 2280| m2280_13(unknown) = Chi : total:m2279_9, partial:m2280_12 -# 2280| v2280_14(void) = ^IndirectReadSideEffect[-1] : &:r2280_9, ~m2280_13 -# 2280| m2280_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_9 -# 2280| m2280_16(unknown) = Chi : total:m2280_13, partial:m2280_15 -# 2280| r2280_17(glval) = VariableAddress[s] : -# 2280| r2280_18(glval) = FunctionAddress[~String] : -# 2280| v2280_19(void) = Call[~String] : func:r2280_18, this:r2280_17 -# 2280| m2280_20(unknown) = ^CallSideEffect : ~m2280_16 -# 2280| m2280_21(unknown) = Chi : total:m2280_16, partial:m2280_20 -# 2280| v2280_22(void) = ^IndirectReadSideEffect[-1] : &:r2280_17, ~m2280_21 -# 2280| m2280_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_17 -# 2280| m2280_24(unknown) = Chi : total:m2280_21, partial:m2280_23 +# 2280| Block 4 +# 2280| r2280_1(glval) = VariableAddress[s2] : +# 2280| m2280_2(String) = Uninitialized[s2] : &:r2280_1 +# 2280| m2280_3(unknown) = Chi : total:m2276_9, partial:m2280_2 +# 2280| r2280_4(glval) = FunctionAddress[String] : +# 2280| v2280_5(void) = Call[String] : func:r2280_4, this:r2280_1 +# 2280| m2280_6(unknown) = ^CallSideEffect : ~m2280_3 +# 2280| m2280_7(unknown) = Chi : total:m2280_3, partial:m2280_6 +# 2280| m2280_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_1 +# 2280| m2280_9(unknown) = Chi : total:m2280_7, partial:m2280_8 +# 2281| r2281_9(glval) = VariableAddress[s2] : +# 2281| r2281_10(glval) = FunctionAddress[~String] : +# 2281| v2281_11(void) = Call[~String] : func:r2281_10, this:r2281_9 +# 2281| m2281_12(unknown) = ^CallSideEffect : ~m2280_9 +# 2281| m2281_13(unknown) = Chi : total:m2280_9, partial:m2281_12 +# 2281| v2281_14(void) = ^IndirectReadSideEffect[-1] : &:r2281_9, ~m2281_13 +# 2281| m2281_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r2281_9 +# 2281| m2281_16(unknown) = Chi : total:m2281_13, partial:m2281_15 +# 2281| r2281_17(glval) = VariableAddress[s] : +# 2281| r2281_18(glval) = FunctionAddress[~String] : +# 2281| v2281_19(void) = Call[~String] : func:r2281_18, this:r2281_17 +# 2281| m2281_20(unknown) = ^CallSideEffect : ~m2281_16 +# 2281| m2281_21(unknown) = Chi : total:m2281_16, partial:m2281_20 +# 2281| v2281_22(void) = ^IndirectReadSideEffect[-1] : &:r2281_17, ~m2281_21 +# 2281| m2281_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2281_17 +# 2281| m2281_24(unknown) = Chi : total:m2281_21, partial:m2281_23 #-----| Goto -> Block 10 -# 2281| Block 5 -# 2281| v2281_1(void) = CatchByType[const char *] : +# 2282| Block 5 +# 2282| v2282_1(void) = CatchByType[const char *] : #-----| Exception -> Block 7 #-----| Goto -> Block 6 -# 2281| Block 6 -# 2281| r2281_2(glval) = VariableAddress[s] : -# 2281| m2281_3(char *) = InitializeParameter[s] : &:r2281_2 -# 2281| r2281_4(char *) = Load[s] : &:r2281_2, m2281_3 -# 2281| m2281_5(unknown) = InitializeIndirection[s] : &:r2281_4 -# 2281| m2281_6(unknown) = Chi : total:m2280_8, partial:m2281_5 -# 2282| r2282_1(glval) = VariableAddress[#throw2282:5] : -# 2282| m2282_2(String) = Uninitialized[#throw2282:5] : &:r2282_1 -# 2282| m2282_3(unknown) = Chi : total:m2281_6, partial:m2282_2 -# 2282| r2282_4(glval) = FunctionAddress[String] : -# 2282| r2282_5(glval) = VariableAddress[s] : -# 2282| r2282_6(char *) = Load[s] : &:r2282_5, m2281_3 -# 2282| v2282_7(void) = Call[String] : func:r2282_4, this:r2282_1, 0:r2282_6 -# 2282| m2282_8(unknown) = ^CallSideEffect : ~m2282_3 -# 2282| m2282_9(unknown) = Chi : total:m2282_3, partial:m2282_8 -# 2282| v2282_10(void) = ^BufferReadSideEffect[0] : &:r2282_6, ~m2282_9 -# 2282| m2282_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2282_1 -# 2282| m2282_12(unknown) = Chi : total:m2282_9, partial:m2282_11 -# 2282| v2282_13(void) = ThrowValue : &:r2282_1, ~m2282_12 +# 2282| Block 6 +# 2282| r2282_2(glval) = VariableAddress[s] : +# 2282| m2282_3(char *) = InitializeParameter[s] : &:r2282_2 +# 2282| r2282_4(char *) = Load[s] : &:r2282_2, m2282_3 +# 2282| m2282_5(unknown) = InitializeIndirection[s] : &:r2282_4 +# 2282| m2282_6(unknown) = Chi : total:m2281_8, partial:m2282_5 +# 2283| r2283_1(glval) = VariableAddress[#throw2283:5] : +# 2283| m2283_2(String) = Uninitialized[#throw2283:5] : &:r2283_1 +# 2283| m2283_3(unknown) = Chi : total:m2282_6, partial:m2283_2 +# 2283| r2283_4(glval) = FunctionAddress[String] : +# 2283| r2283_5(glval) = VariableAddress[s] : +# 2283| r2283_6(char *) = Load[s] : &:r2283_5, m2282_3 +# 2283| v2283_7(void) = Call[String] : func:r2283_4, this:r2283_1, 0:r2283_6 +# 2283| m2283_8(unknown) = ^CallSideEffect : ~m2283_3 +# 2283| m2283_9(unknown) = Chi : total:m2283_3, partial:m2283_8 +# 2283| v2283_10(void) = ^BufferReadSideEffect[0] : &:r2283_6, ~m2283_9 +# 2283| m2283_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2283_1 +# 2283| m2283_12(unknown) = Chi : total:m2283_9, partial:m2283_11 +# 2283| v2283_13(void) = ThrowValue : &:r2283_1, ~m2283_12 #-----| Exception -> Block 2 -# 2284| Block 7 -# 2284| v2284_1(void) = CatchByType[const String &] : +# 2285| Block 7 +# 2285| v2285_1(void) = CatchByType[const String &] : #-----| Exception -> Block 9 #-----| Goto -> Block 8 -# 2284| Block 8 -# 2284| r2284_2(glval) = VariableAddress[e] : -# 2284| m2284_3(String &) = InitializeParameter[e] : &:r2284_2 -# 2284| r2284_4(String &) = Load[e] : &:r2284_2, m2284_3 -# 2284| m2284_5(unknown) = InitializeIndirection[e] : &:r2284_4 -# 2284| v2284_6(void) = NoOp : +# 2285| Block 8 +# 2285| r2285_2(glval) = VariableAddress[e] : +# 2285| m2285_3(String &) = InitializeParameter[e] : &:r2285_2 +# 2285| r2285_4(String &) = Load[e] : &:r2285_2, m2285_3 +# 2285| m2285_5(unknown) = InitializeIndirection[e] : &:r2285_4 +# 2285| v2285_6(void) = NoOp : #-----| Goto -> Block 10 -# 2286| Block 9 -# 2286| v2286_1(void) = CatchAny : -# 2287| v2287_1(void) = ReThrow : +# 2287| Block 9 +# 2287| v2287_1(void) = CatchAny : +# 2288| v2288_1(void) = ReThrow : #-----| Exception -> Block 2 -# 2289| Block 10 -# 2289| m2289_1(unknown) = Phi : from 4:~m2280_24, from 8:~m2280_8 -# 2289| v2289_2(void) = NoOp : -# 2273| v2273_12(void) = ReturnVoid : +# 2290| Block 10 +# 2290| m2290_1(unknown) = Phi : from 4:~m2281_24, from 8:~m2281_8 +# 2290| v2290_2(void) = NoOp : +# 2274| v2274_12(void) = ReturnVoid : #-----| Goto -> Block 1 -# 2291| void IfDestructors(bool) -# 2291| Block 0 -# 2291| v2291_1(void) = EnterFunction : -# 2291| m2291_2(unknown) = AliasedDefinition : -# 2291| m2291_3(unknown) = InitializeNonLocal : -# 2291| m2291_4(unknown) = Chi : total:m2291_2, partial:m2291_3 -# 2291| r2291_5(glval) = VariableAddress[b] : -# 2291| m2291_6(bool) = InitializeParameter[b] : &:r2291_5 -# 2292| r2292_1(glval) = VariableAddress[s1] : -# 2292| m2292_2(String) = Uninitialized[s1] : &:r2292_1 -# 2292| m2292_3(unknown) = Chi : total:m2291_4, partial:m2292_2 -# 2292| r2292_4(glval) = FunctionAddress[String] : -# 2292| v2292_5(void) = Call[String] : func:r2292_4, this:r2292_1 -# 2292| m2292_6(unknown) = ^CallSideEffect : ~m2292_3 -# 2292| m2292_7(unknown) = Chi : total:m2292_3, partial:m2292_6 -# 2292| m2292_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2292_1 -# 2292| m2292_9(unknown) = Chi : total:m2292_7, partial:m2292_8 -# 2293| r2293_1(glval) = VariableAddress[b] : -# 2293| r2293_2(bool) = Load[b] : &:r2293_1, m2291_6 -# 2293| v2293_3(void) = ConditionalBranch : r2293_2 +# 2292| void IfDestructors(bool) +# 2292| Block 0 +# 2292| v2292_1(void) = EnterFunction : +# 2292| m2292_2(unknown) = AliasedDefinition : +# 2292| m2292_3(unknown) = InitializeNonLocal : +# 2292| m2292_4(unknown) = Chi : total:m2292_2, partial:m2292_3 +# 2292| r2292_5(glval) = VariableAddress[b] : +# 2292| m2292_6(bool) = InitializeParameter[b] : &:r2292_5 +# 2293| r2293_1(glval) = VariableAddress[s1] : +# 2293| m2293_2(String) = Uninitialized[s1] : &:r2293_1 +# 2293| m2293_3(unknown) = Chi : total:m2292_4, partial:m2293_2 +# 2293| r2293_4(glval) = FunctionAddress[String] : +# 2293| v2293_5(void) = Call[String] : func:r2293_4, this:r2293_1 +# 2293| m2293_6(unknown) = ^CallSideEffect : ~m2293_3 +# 2293| m2293_7(unknown) = Chi : total:m2293_3, partial:m2293_6 +# 2293| m2293_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2293_1 +# 2293| m2293_9(unknown) = Chi : total:m2293_7, partial:m2293_8 +# 2294| r2294_1(glval) = VariableAddress[b] : +# 2294| r2294_2(bool) = Load[b] : &:r2294_1, m2292_6 +# 2294| v2294_3(void) = ConditionalBranch : r2294_2 #-----| False -> Block 2 #-----| True -> Block 1 -# 2294| Block 1 -# 2294| r2294_1(glval) = VariableAddress[s2] : -# 2294| m2294_2(String) = Uninitialized[s2] : &:r2294_1 -# 2294| m2294_3(unknown) = Chi : total:m2292_9, partial:m2294_2 -# 2294| r2294_4(glval) = FunctionAddress[String] : -# 2294| v2294_5(void) = Call[String] : func:r2294_4, this:r2294_1 -# 2294| m2294_6(unknown) = ^CallSideEffect : ~m2294_3 -# 2294| m2294_7(unknown) = Chi : total:m2294_3, partial:m2294_6 -# 2294| m2294_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2294_1 -# 2294| m2294_9(unknown) = Chi : total:m2294_7, partial:m2294_8 +# 2295| Block 1 # 2295| r2295_1(glval) = VariableAddress[s2] : -# 2295| r2295_2(glval) = FunctionAddress[~String] : -# 2295| v2295_3(void) = Call[~String] : func:r2295_2, this:r2295_1 -# 2295| m2295_4(unknown) = ^CallSideEffect : ~m2294_9 -# 2295| m2295_5(unknown) = Chi : total:m2294_9, partial:m2295_4 -# 2295| v2295_6(void) = ^IndirectReadSideEffect[-1] : &:r2295_1, ~m2295_5 -# 2295| m2295_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2295_1 -# 2295| m2295_8(unknown) = Chi : total:m2295_5, partial:m2295_7 +# 2295| m2295_2(String) = Uninitialized[s2] : &:r2295_1 +# 2295| m2295_3(unknown) = Chi : total:m2293_9, partial:m2295_2 +# 2295| r2295_4(glval) = FunctionAddress[String] : +# 2295| v2295_5(void) = Call[String] : func:r2295_4, this:r2295_1 +# 2295| m2295_6(unknown) = ^CallSideEffect : ~m2295_3 +# 2295| m2295_7(unknown) = Chi : total:m2295_3, partial:m2295_6 +# 2295| m2295_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2295_1 +# 2295| m2295_9(unknown) = Chi : total:m2295_7, partial:m2295_8 +# 2296| r2296_1(glval) = VariableAddress[s2] : +# 2296| r2296_2(glval) = FunctionAddress[~String] : +# 2296| v2296_3(void) = Call[~String] : func:r2296_2, this:r2296_1 +# 2296| m2296_4(unknown) = ^CallSideEffect : ~m2295_9 +# 2296| m2296_5(unknown) = Chi : total:m2295_9, partial:m2296_4 +# 2296| v2296_6(void) = ^IndirectReadSideEffect[-1] : &:r2296_1, ~m2296_5 +# 2296| m2296_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2296_1 +# 2296| m2296_8(unknown) = Chi : total:m2296_5, partial:m2296_7 #-----| Goto -> Block 3 -# 2296| Block 2 -# 2296| r2296_1(glval) = VariableAddress[s3] : -# 2296| m2296_2(String) = Uninitialized[s3] : &:r2296_1 -# 2296| m2296_3(unknown) = Chi : total:m2292_9, partial:m2296_2 -# 2296| r2296_4(glval) = FunctionAddress[String] : -# 2296| v2296_5(void) = Call[String] : func:r2296_4, this:r2296_1 -# 2296| m2296_6(unknown) = ^CallSideEffect : ~m2296_3 -# 2296| m2296_7(unknown) = Chi : total:m2296_3, partial:m2296_6 -# 2296| m2296_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2296_1 -# 2296| m2296_9(unknown) = Chi : total:m2296_7, partial:m2296_8 +# 2297| Block 2 # 2297| r2297_1(glval) = VariableAddress[s3] : -# 2297| r2297_2(glval) = FunctionAddress[~String] : -# 2297| v2297_3(void) = Call[~String] : func:r2297_2, this:r2297_1 -# 2297| m2297_4(unknown) = ^CallSideEffect : ~m2296_9 -# 2297| m2297_5(unknown) = Chi : total:m2296_9, partial:m2297_4 -# 2297| v2297_6(void) = ^IndirectReadSideEffect[-1] : &:r2297_1, ~m2297_5 -# 2297| m2297_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2297_1 -# 2297| m2297_8(unknown) = Chi : total:m2297_5, partial:m2297_7 +# 2297| m2297_2(String) = Uninitialized[s3] : &:r2297_1 +# 2297| m2297_3(unknown) = Chi : total:m2293_9, partial:m2297_2 +# 2297| r2297_4(glval) = FunctionAddress[String] : +# 2297| v2297_5(void) = Call[String] : func:r2297_4, this:r2297_1 +# 2297| m2297_6(unknown) = ^CallSideEffect : ~m2297_3 +# 2297| m2297_7(unknown) = Chi : total:m2297_3, partial:m2297_6 +# 2297| m2297_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2297_1 +# 2297| m2297_9(unknown) = Chi : total:m2297_7, partial:m2297_8 +# 2298| r2298_1(glval) = VariableAddress[s3] : +# 2298| r2298_2(glval) = FunctionAddress[~String] : +# 2298| v2298_3(void) = Call[~String] : func:r2298_2, this:r2298_1 +# 2298| m2298_4(unknown) = ^CallSideEffect : ~m2297_9 +# 2298| m2298_5(unknown) = Chi : total:m2297_9, partial:m2298_4 +# 2298| v2298_6(void) = ^IndirectReadSideEffect[-1] : &:r2298_1, ~m2298_5 +# 2298| m2298_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2298_1 +# 2298| m2298_8(unknown) = Chi : total:m2298_5, partial:m2298_7 #-----| Goto -> Block 3 -# 2298| Block 3 -# 2298| m2298_1(unknown) = Phi : from 1:~m2295_8, from 2:~m2297_8 -# 2298| r2298_2(glval) = VariableAddress[s4] : -# 2298| m2298_3(String) = Uninitialized[s4] : &:r2298_2 -# 2298| m2298_4(unknown) = Chi : total:m2298_1, partial:m2298_3 -# 2298| r2298_5(glval) = FunctionAddress[String] : -# 2298| v2298_6(void) = Call[String] : func:r2298_5, this:r2298_2 -# 2298| m2298_7(unknown) = ^CallSideEffect : ~m2298_4 -# 2298| m2298_8(unknown) = Chi : total:m2298_4, partial:m2298_7 -# 2298| m2298_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2298_2 -# 2298| m2298_10(unknown) = Chi : total:m2298_8, partial:m2298_9 -# 2299| v2299_1(void) = NoOp : +# 2299| Block 3 +# 2299| m2299_1(unknown) = Phi : from 1:~m2296_8, from 2:~m2298_8 # 2299| r2299_2(glval) = VariableAddress[s4] : -# 2299| r2299_3(glval) = FunctionAddress[~String] : -# 2299| v2299_4(void) = Call[~String] : func:r2299_3, this:r2299_2 -# 2299| m2299_5(unknown) = ^CallSideEffect : ~m2298_10 -# 2299| m2299_6(unknown) = Chi : total:m2298_10, partial:m2299_5 -# 2299| v2299_7(void) = ^IndirectReadSideEffect[-1] : &:r2299_2, ~m2299_6 -# 2299| m2299_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2299_2 -# 2299| m2299_9(unknown) = Chi : total:m2299_6, partial:m2299_8 -# 2299| r2299_10(glval) = VariableAddress[s1] : -# 2299| r2299_11(glval) = FunctionAddress[~String] : -# 2299| v2299_12(void) = Call[~String] : func:r2299_11, this:r2299_10 -# 2299| m2299_13(unknown) = ^CallSideEffect : ~m2299_9 -# 2299| m2299_14(unknown) = Chi : total:m2299_9, partial:m2299_13 -# 2299| v2299_15(void) = ^IndirectReadSideEffect[-1] : &:r2299_10, ~m2299_14 -# 2299| m2299_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r2299_10 -# 2299| m2299_17(unknown) = Chi : total:m2299_14, partial:m2299_16 -# 2291| v2291_7(void) = ReturnVoid : -# 2291| v2291_8(void) = AliasedUse : ~m2299_14 -# 2291| v2291_9(void) = ExitFunction : - -# 2301| void ForDestructors() -# 2301| Block 0 -# 2301| v2301_1(void) = EnterFunction : -# 2301| m2301_2(unknown) = AliasedDefinition : -# 2301| m2301_3(unknown) = InitializeNonLocal : -# 2301| m2301_4(unknown) = Chi : total:m2301_2, partial:m2301_3 -# 2302| r2302_1(glval) = VariableAddress[c] : -# 2302| r2302_2(char) = Constant[97] : -# 2302| m2302_3(char) = Store[c] : &:r2302_1, r2302_2 -# 2303| r2303_1(glval) = VariableAddress[s] : -# 2303| m2303_2(String) = Uninitialized[s] : &:r2303_1 -# 2303| m2303_3(unknown) = Chi : total:m2301_4, partial:m2303_2 -# 2303| r2303_4(glval) = FunctionAddress[String] : -# 2303| r2303_5(glval) = StringConstant["hello"] : -# 2303| r2303_6(char *) = Convert : r2303_5 -# 2303| v2303_7(void) = Call[String] : func:r2303_4, this:r2303_1, 0:r2303_6 -# 2303| m2303_8(unknown) = ^CallSideEffect : ~m2303_3 -# 2303| m2303_9(unknown) = Chi : total:m2303_3, partial:m2303_8 -# 2303| v2303_10(void) = ^BufferReadSideEffect[0] : &:r2303_6, ~m2301_3 -# 2303| m2303_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2303_1 -# 2303| m2303_12(unknown) = Chi : total:m2303_9, partial:m2303_11 +# 2299| m2299_3(String) = Uninitialized[s4] : &:r2299_2 +# 2299| m2299_4(unknown) = Chi : total:m2299_1, partial:m2299_3 +# 2299| r2299_5(glval) = FunctionAddress[String] : +# 2299| v2299_6(void) = Call[String] : func:r2299_5, this:r2299_2 +# 2299| m2299_7(unknown) = ^CallSideEffect : ~m2299_4 +# 2299| m2299_8(unknown) = Chi : total:m2299_4, partial:m2299_7 +# 2299| m2299_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2299_2 +# 2299| m2299_10(unknown) = Chi : total:m2299_8, partial:m2299_9 +# 2300| v2300_1(void) = NoOp : +# 2300| r2300_2(glval) = VariableAddress[s4] : +# 2300| r2300_3(glval) = FunctionAddress[~String] : +# 2300| v2300_4(void) = Call[~String] : func:r2300_3, this:r2300_2 +# 2300| m2300_5(unknown) = ^CallSideEffect : ~m2299_10 +# 2300| m2300_6(unknown) = Chi : total:m2299_10, partial:m2300_5 +# 2300| v2300_7(void) = ^IndirectReadSideEffect[-1] : &:r2300_2, ~m2300_6 +# 2300| m2300_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2300_2 +# 2300| m2300_9(unknown) = Chi : total:m2300_6, partial:m2300_8 +# 2300| r2300_10(glval) = VariableAddress[s1] : +# 2300| r2300_11(glval) = FunctionAddress[~String] : +# 2300| v2300_12(void) = Call[~String] : func:r2300_11, this:r2300_10 +# 2300| m2300_13(unknown) = ^CallSideEffect : ~m2300_9 +# 2300| m2300_14(unknown) = Chi : total:m2300_9, partial:m2300_13 +# 2300| v2300_15(void) = ^IndirectReadSideEffect[-1] : &:r2300_10, ~m2300_14 +# 2300| m2300_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r2300_10 +# 2300| m2300_17(unknown) = Chi : total:m2300_14, partial:m2300_16 +# 2292| v2292_7(void) = ReturnVoid : +# 2292| v2292_8(void) = AliasedUse : ~m2300_14 +# 2292| v2292_9(void) = ExitFunction : + +# 2302| void ForDestructors() +# 2302| Block 0 +# 2302| v2302_1(void) = EnterFunction : +# 2302| m2302_2(unknown) = AliasedDefinition : +# 2302| m2302_3(unknown) = InitializeNonLocal : +# 2302| m2302_4(unknown) = Chi : total:m2302_2, partial:m2302_3 +# 2303| r2303_1(glval) = VariableAddress[c] : +# 2303| r2303_2(char) = Constant[97] : +# 2303| m2303_3(char) = Store[c] : &:r2303_1, r2303_2 +# 2304| r2304_1(glval) = VariableAddress[s] : +# 2304| m2304_2(String) = Uninitialized[s] : &:r2304_1 +# 2304| m2304_3(unknown) = Chi : total:m2302_4, partial:m2304_2 +# 2304| r2304_4(glval) = FunctionAddress[String] : +# 2304| r2304_5(glval) = StringConstant["hello"] : +# 2304| r2304_6(char *) = Convert : r2304_5 +# 2304| v2304_7(void) = Call[String] : func:r2304_4, this:r2304_1, 0:r2304_6 +# 2304| m2304_8(unknown) = ^CallSideEffect : ~m2304_3 +# 2304| m2304_9(unknown) = Chi : total:m2304_3, partial:m2304_8 +# 2304| v2304_10(void) = ^BufferReadSideEffect[0] : &:r2304_6, ~m2302_3 +# 2304| m2304_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_1 +# 2304| m2304_12(unknown) = Chi : total:m2304_9, partial:m2304_11 #-----| Goto -> Block 1 -# 2303| Block 1 -# 2303| m2303_13(unknown) = Phi : from 0:~m2303_12, from 2:~m2303_28 -# 2303| m2303_14(char) = Phi : from 0:m2302_3, from 2:m2303_30 -# 2303| r2303_15(glval) = VariableAddress[c] : -# 2303| r2303_16(char) = Load[c] : &:r2303_15, m2303_14 -# 2303| r2303_17(int) = Convert : r2303_16 -# 2303| r2303_18(int) = Constant[0] : -# 2303| r2303_19(bool) = CompareNE : r2303_17, r2303_18 -# 2303| v2303_20(void) = ConditionalBranch : r2303_19 +# 2304| Block 1 +# 2304| m2304_13(unknown) = Phi : from 0:~m2304_12, from 2:~m2304_28 +# 2304| m2304_14(char) = Phi : from 0:m2303_3, from 2:m2304_30 +# 2304| r2304_15(glval) = VariableAddress[c] : +# 2304| r2304_16(char) = Load[c] : &:r2304_15, m2304_14 +# 2304| r2304_17(int) = Convert : r2304_16 +# 2304| r2304_18(int) = Constant[0] : +# 2304| r2304_19(bool) = CompareNE : r2304_17, r2304_18 +# 2304| v2304_20(void) = ConditionalBranch : r2304_19 #-----| False -> Block 3 #-----| True -> Block 2 -# 2304| Block 2 -# 2304| r2304_1(glval) = VariableAddress[s2] : -# 2304| m2304_2(String) = Uninitialized[s2] : &:r2304_1 -# 2304| m2304_3(unknown) = Chi : total:m2303_13, partial:m2304_2 -# 2304| r2304_4(glval) = FunctionAddress[String] : -# 2304| v2304_5(void) = Call[String] : func:r2304_4, this:r2304_1 -# 2304| m2304_6(unknown) = ^CallSideEffect : ~m2304_3 -# 2304| m2304_7(unknown) = Chi : total:m2304_3, partial:m2304_6 -# 2304| m2304_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_1 -# 2304| m2304_9(unknown) = Chi : total:m2304_7, partial:m2304_8 +# 2305| Block 2 # 2305| r2305_1(glval) = VariableAddress[s2] : -# 2305| r2305_2(glval) = FunctionAddress[~String] : -# 2305| v2305_3(void) = Call[~String] : func:r2305_2, this:r2305_1 -# 2305| m2305_4(unknown) = ^CallSideEffect : ~m2304_9 -# 2305| m2305_5(unknown) = Chi : total:m2304_9, partial:m2305_4 -# 2305| v2305_6(void) = ^IndirectReadSideEffect[-1] : &:r2305_1, ~m2305_5 -# 2305| m2305_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2305_1 -# 2305| m2305_8(unknown) = Chi : total:m2305_5, partial:m2305_7 -# 2303| r2303_21(glval) = VariableAddress[s] : -# 2303| r2303_22(glval) = FunctionAddress[pop_back] : -# 2303| r2303_23(char) = Call[pop_back] : func:r2303_22, this:r2303_21 -# 2303| m2303_24(unknown) = ^CallSideEffect : ~m2305_8 -# 2303| m2303_25(unknown) = Chi : total:m2305_8, partial:m2303_24 -# 2303| v2303_26(void) = ^IndirectReadSideEffect[-1] : &:r2303_21, ~m2303_25 -# 2303| m2303_27(String) = ^IndirectMayWriteSideEffect[-1] : &:r2303_21 -# 2303| m2303_28(unknown) = Chi : total:m2303_25, partial:m2303_27 -# 2303| r2303_29(glval) = VariableAddress[c] : -# 2303| m2303_30(char) = Store[c] : &:r2303_29, r2303_23 +# 2305| m2305_2(String) = Uninitialized[s2] : &:r2305_1 +# 2305| m2305_3(unknown) = Chi : total:m2304_13, partial:m2305_2 +# 2305| r2305_4(glval) = FunctionAddress[String] : +# 2305| v2305_5(void) = Call[String] : func:r2305_4, this:r2305_1 +# 2305| m2305_6(unknown) = ^CallSideEffect : ~m2305_3 +# 2305| m2305_7(unknown) = Chi : total:m2305_3, partial:m2305_6 +# 2305| m2305_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2305_1 +# 2305| m2305_9(unknown) = Chi : total:m2305_7, partial:m2305_8 +# 2306| r2306_1(glval) = VariableAddress[s2] : +# 2306| r2306_2(glval) = FunctionAddress[~String] : +# 2306| v2306_3(void) = Call[~String] : func:r2306_2, this:r2306_1 +# 2306| m2306_4(unknown) = ^CallSideEffect : ~m2305_9 +# 2306| m2306_5(unknown) = Chi : total:m2305_9, partial:m2306_4 +# 2306| v2306_6(void) = ^IndirectReadSideEffect[-1] : &:r2306_1, ~m2306_5 +# 2306| m2306_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2306_1 +# 2306| m2306_8(unknown) = Chi : total:m2306_5, partial:m2306_7 +# 2304| r2304_21(glval) = VariableAddress[s] : +# 2304| r2304_22(glval) = FunctionAddress[pop_back] : +# 2304| r2304_23(char) = Call[pop_back] : func:r2304_22, this:r2304_21 +# 2304| m2304_24(unknown) = ^CallSideEffect : ~m2306_8 +# 2304| m2304_25(unknown) = Chi : total:m2306_8, partial:m2304_24 +# 2304| v2304_26(void) = ^IndirectReadSideEffect[-1] : &:r2304_21, ~m2304_25 +# 2304| m2304_27(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_21 +# 2304| m2304_28(unknown) = Chi : total:m2304_25, partial:m2304_27 +# 2304| r2304_29(glval) = VariableAddress[c] : +# 2304| m2304_30(char) = Store[c] : &:r2304_29, r2304_23 #-----| Goto (back edge) -> Block 1 -# 2303| Block 3 -# 2303| r2303_31(glval) = VariableAddress[s] : -# 2303| r2303_32(glval) = FunctionAddress[~String] : -# 2303| v2303_33(void) = Call[~String] : func:r2303_32, this:r2303_31 -# 2303| m2303_34(unknown) = ^CallSideEffect : ~m2303_13 -# 2303| m2303_35(unknown) = Chi : total:m2303_13, partial:m2303_34 -# 2303| v2303_36(void) = ^IndirectReadSideEffect[-1] : &:r2303_31, ~m2303_35 -# 2303| m2303_37(String) = ^IndirectMayWriteSideEffect[-1] : &:r2303_31 -# 2303| m2303_38(unknown) = Chi : total:m2303_35, partial:m2303_37 -# 2307| r2307_1(glval &&>) = VariableAddress[(__range)] : -# 2307| r2307_2(glval>) = VariableAddress[#temp2307:20] : -# 2307| m2307_3(vector) = Uninitialized[#temp2307:20] : &:r2307_2 -# 2307| m2307_4(unknown) = Chi : total:m2303_38, partial:m2307_3 -# 2307| r2307_5(glval) = FunctionAddress[vector] : -# 2307| r2307_6(glval) = VariableAddress[#temp2307:40] : -# 2307| m2307_7(String) = Uninitialized[#temp2307:40] : &:r2307_6 -# 2307| m2307_8(unknown) = Chi : total:m2307_4, partial:m2307_7 -# 2307| r2307_9(glval) = FunctionAddress[String] : -# 2307| r2307_10(glval) = StringConstant["hello"] : -# 2307| r2307_11(char *) = Convert : r2307_10 -# 2307| v2307_12(void) = Call[String] : func:r2307_9, this:r2307_6, 0:r2307_11 -# 2307| m2307_13(unknown) = ^CallSideEffect : ~m2307_8 -# 2307| m2307_14(unknown) = Chi : total:m2307_8, partial:m2307_13 -# 2307| v2307_15(void) = ^BufferReadSideEffect[0] : &:r2307_11, ~m2301_3 -# 2307| m2307_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_6 -# 2307| m2307_17(unknown) = Chi : total:m2307_14, partial:m2307_16 -# 2307| r2307_18(String) = Load[#temp2307:40] : &:r2307_6, ~m2307_17 -# 2307| v2307_19(void) = Call[vector] : func:r2307_5, this:r2307_2, 0:r2307_18 -# 2307| m2307_20(unknown) = ^CallSideEffect : ~m2307_17 -# 2307| m2307_21(unknown) = Chi : total:m2307_17, partial:m2307_20 -# 2307| m2307_22(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2307_2 -# 2307| m2307_23(unknown) = Chi : total:m2307_21, partial:m2307_22 -# 2307| r2307_24(glval) = CopyValue : r2307_6 -# 2307| r2307_25(glval) = FunctionAddress[~String] : -# 2307| v2307_26(void) = Call[~String] : func:r2307_25, this:r2307_24 -# 2307| m2307_27(unknown) = ^CallSideEffect : ~m2307_23 -# 2307| m2307_28(unknown) = Chi : total:m2307_23, partial:m2307_27 -# 2307| v2307_29(void) = ^IndirectReadSideEffect[-1] : &:r2307_24, ~m2307_28 -# 2307| m2307_30(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_24 -# 2307| m2307_31(unknown) = Chi : total:m2307_28, partial:m2307_30 -# 2307| r2307_32(vector &) = CopyValue : r2307_2 -# 2307| m2307_33(vector &&) = Store[(__range)] : &:r2307_1, r2307_32 -# 2307| r2307_34(glval>) = VariableAddress[(__begin)] : -# 2307| r2307_35(glval &&>) = VariableAddress[(__range)] : -# 2307| r2307_36(vector &&) = Load[(__range)] : &:r2307_35, m2307_33 -#-----| r0_1(glval>) = CopyValue : r2307_36 +# 2304| Block 3 +# 2304| r2304_31(glval) = VariableAddress[s] : +# 2304| r2304_32(glval) = FunctionAddress[~String] : +# 2304| v2304_33(void) = Call[~String] : func:r2304_32, this:r2304_31 +# 2304| m2304_34(unknown) = ^CallSideEffect : ~m2304_13 +# 2304| m2304_35(unknown) = Chi : total:m2304_13, partial:m2304_34 +# 2304| v2304_36(void) = ^IndirectReadSideEffect[-1] : &:r2304_31, ~m2304_35 +# 2304| m2304_37(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_31 +# 2304| m2304_38(unknown) = Chi : total:m2304_35, partial:m2304_37 +# 2308| r2308_1(glval &&>) = VariableAddress[(__range)] : +# 2308| r2308_2(glval>) = VariableAddress[#temp2308:20] : +# 2308| m2308_3(vector) = Uninitialized[#temp2308:20] : &:r2308_2 +# 2308| m2308_4(unknown) = Chi : total:m2304_38, partial:m2308_3 +# 2308| r2308_5(glval) = FunctionAddress[vector] : +# 2308| r2308_6(glval) = VariableAddress[#temp2308:40] : +# 2308| m2308_7(String) = Uninitialized[#temp2308:40] : &:r2308_6 +# 2308| m2308_8(unknown) = Chi : total:m2308_4, partial:m2308_7 +# 2308| r2308_9(glval) = FunctionAddress[String] : +# 2308| r2308_10(glval) = StringConstant["hello"] : +# 2308| r2308_11(char *) = Convert : r2308_10 +# 2308| v2308_12(void) = Call[String] : func:r2308_9, this:r2308_6, 0:r2308_11 +# 2308| m2308_13(unknown) = ^CallSideEffect : ~m2308_8 +# 2308| m2308_14(unknown) = Chi : total:m2308_8, partial:m2308_13 +# 2308| v2308_15(void) = ^BufferReadSideEffect[0] : &:r2308_11, ~m2302_3 +# 2308| m2308_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_6 +# 2308| m2308_17(unknown) = Chi : total:m2308_14, partial:m2308_16 +# 2308| r2308_18(String) = Load[#temp2308:40] : &:r2308_6, ~m2308_17 +# 2308| v2308_19(void) = Call[vector] : func:r2308_5, this:r2308_2, 0:r2308_18 +# 2308| m2308_20(unknown) = ^CallSideEffect : ~m2308_17 +# 2308| m2308_21(unknown) = Chi : total:m2308_17, partial:m2308_20 +# 2308| m2308_22(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2308_2 +# 2308| m2308_23(unknown) = Chi : total:m2308_21, partial:m2308_22 +# 2308| r2308_24(glval) = CopyValue : r2308_6 +# 2308| r2308_25(glval) = FunctionAddress[~String] : +# 2308| v2308_26(void) = Call[~String] : func:r2308_25, this:r2308_24 +# 2308| m2308_27(unknown) = ^CallSideEffect : ~m2308_23 +# 2308| m2308_28(unknown) = Chi : total:m2308_23, partial:m2308_27 +# 2308| v2308_29(void) = ^IndirectReadSideEffect[-1] : &:r2308_24, ~m2308_28 +# 2308| m2308_30(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_24 +# 2308| m2308_31(unknown) = Chi : total:m2308_28, partial:m2308_30 +# 2308| r2308_32(vector &) = CopyValue : r2308_2 +# 2308| m2308_33(vector &&) = Store[(__range)] : &:r2308_1, r2308_32 +# 2308| r2308_34(glval>) = VariableAddress[(__begin)] : +# 2308| r2308_35(glval &&>) = VariableAddress[(__range)] : +# 2308| r2308_36(vector &&) = Load[(__range)] : &:r2308_35, m2308_33 +#-----| r0_1(glval>) = CopyValue : r2308_36 #-----| r0_2(glval>) = Convert : r0_1 -# 2307| r2307_37(glval) = FunctionAddress[begin] : -# 2307| r2307_38(iterator) = Call[begin] : func:r2307_37, this:r0_2 -#-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m2307_28 -# 2307| m2307_39(iterator) = Store[(__begin)] : &:r2307_34, r2307_38 -# 2307| r2307_40(glval>) = VariableAddress[(__end)] : -# 2307| r2307_41(glval &&>) = VariableAddress[(__range)] : -# 2307| r2307_42(vector &&) = Load[(__range)] : &:r2307_41, m2307_33 -#-----| r0_4(glval>) = CopyValue : r2307_42 +# 2308| r2308_37(glval) = FunctionAddress[begin] : +# 2308| r2308_38(iterator) = Call[begin] : func:r2308_37, this:r0_2 +#-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m2308_28 +# 2308| m2308_39(iterator) = Store[(__begin)] : &:r2308_34, r2308_38 +# 2308| r2308_40(glval>) = VariableAddress[(__end)] : +# 2308| r2308_41(glval &&>) = VariableAddress[(__range)] : +# 2308| r2308_42(vector &&) = Load[(__range)] : &:r2308_41, m2308_33 +#-----| r0_4(glval>) = CopyValue : r2308_42 #-----| r0_5(glval>) = Convert : r0_4 -# 2307| r2307_43(glval) = FunctionAddress[end] : -# 2307| r2307_44(iterator) = Call[end] : func:r2307_43, this:r0_5 -#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m2307_28 -# 2307| m2307_45(iterator) = Store[(__end)] : &:r2307_40, r2307_44 -# 2307| m2307_46(unknown) = Chi : total:m2307_31, partial:m2307_45 +# 2308| r2308_43(glval) = FunctionAddress[end] : +# 2308| r2308_44(iterator) = Call[end] : func:r2308_43, this:r0_5 +#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m2308_28 +# 2308| m2308_45(iterator) = Store[(__end)] : &:r2308_40, r2308_44 +# 2308| m2308_46(unknown) = Chi : total:m2308_31, partial:m2308_45 #-----| Goto -> Block 4 -# 2307| Block 4 -# 2307| m2307_47(iterator) = Phi : from 3:m2307_39, from 5:m2307_89 -# 2307| m2307_48(unknown) = Phi : from 3:~m2307_46, from 5:~m2307_83 -# 2307| r2307_49(glval>) = VariableAddress[(__begin)] : -#-----| r0_7(glval>) = Convert : r2307_49 -# 2307| r2307_50(glval) = FunctionAddress[operator!=] : +# 2308| Block 4 +# 2308| m2308_47(iterator) = Phi : from 3:m2308_39, from 5:m2308_81 +# 2308| m2308_48(unknown) = Phi : from 3:~m2308_46, from 5:~m2308_89 +# 2308| r2308_49(glval>) = VariableAddress[(__begin)] : +#-----| r0_7(glval>) = Convert : r2308_49 +# 2308| r2308_50(glval) = FunctionAddress[operator!=] : #-----| r0_8(glval>) = VariableAddress[#temp0:0] : #-----| m0_9(iterator) = Uninitialized[#temp0:0] : &:r0_8 -#-----| m0_10(unknown) = Chi : total:m2307_48, partial:m0_9 -# 2307| r2307_51(glval) = FunctionAddress[iterator] : -# 2307| r2307_52(glval>) = VariableAddress[(__end)] : -#-----| r0_11(glval>) = Convert : r2307_52 +#-----| m0_10(unknown) = Chi : total:m2308_48, partial:m0_9 +# 2308| r2308_51(glval) = FunctionAddress[iterator] : +# 2308| r2308_52(glval>) = VariableAddress[(__end)] : +#-----| r0_11(glval>) = Convert : r2308_52 #-----| r0_12(iterator &) = CopyValue : r0_11 -# 2307| v2307_53(void) = Call[iterator] : func:r2307_51, this:r0_8, 0:r0_12 -# 2307| m2307_54(unknown) = ^CallSideEffect : ~m0_10 -# 2307| m2307_55(unknown) = Chi : total:m0_10, partial:m2307_54 -#-----| v0_13(void) = ^BufferReadSideEffect[0] : &:r0_12, ~m2307_55 -# 2307| m2307_56(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 -# 2307| m2307_57(unknown) = Chi : total:m2307_55, partial:m2307_56 -#-----| r0_14(iterator) = Load[#temp0:0] : &:r0_8, ~m2307_57 -# 2307| r2307_58(bool) = Call[operator!=] : func:r2307_50, this:r0_7, 0:r0_14 -#-----| v0_15(void) = ^IndirectReadSideEffect[-1] : &:r0_7, m2307_47 -# 2307| v2307_59(void) = ConditionalBranch : r2307_58 +# 2308| v2308_53(void) = Call[iterator] : func:r2308_51, this:r0_8, 0:r0_12 +# 2308| m2308_54(unknown) = ^CallSideEffect : ~m0_10 +# 2308| m2308_55(unknown) = Chi : total:m0_10, partial:m2308_54 +#-----| v0_13(void) = ^BufferReadSideEffect[0] : &:r0_12, ~m2308_55 +# 2308| m2308_56(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 2308| m2308_57(unknown) = Chi : total:m2308_55, partial:m2308_56 +#-----| r0_14(iterator) = Load[#temp0:0] : &:r0_8, ~m2308_57 +# 2308| r2308_58(bool) = Call[operator!=] : func:r2308_50, this:r0_7, 0:r0_14 +#-----| v0_15(void) = ^IndirectReadSideEffect[-1] : &:r0_7, m2308_47 +# 2308| v2308_59(void) = ConditionalBranch : r2308_58 #-----| False -> Block 6 #-----| True -> Block 5 -# 2307| Block 5 -# 2307| r2307_60(glval) = VariableAddress[s] : -# 2307| m2307_61(String) = Uninitialized[s] : &:r2307_60 -# 2307| m2307_62(unknown) = Chi : total:m2307_57, partial:m2307_61 -# 2307| r2307_63(glval) = FunctionAddress[String] : -# 2307| r2307_64(glval>) = VariableAddress[(__begin)] : -#-----| r0_16(glval>) = Convert : r2307_64 -# 2307| r2307_65(glval) = FunctionAddress[operator*] : -# 2307| r2307_66(String &) = Call[operator*] : func:r2307_65, this:r0_16 -#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_16, m2307_47 -# 2307| r2307_67(glval) = CopyValue : r2307_66 -# 2307| r2307_68(glval) = Convert : r2307_67 -# 2307| r2307_69(String &) = CopyValue : r2307_68 -# 2307| v2307_70(void) = Call[String] : func:r2307_63, this:r2307_60, 0:r2307_69 -# 2307| m2307_71(unknown) = ^CallSideEffect : ~m2307_62 -# 2307| m2307_72(unknown) = Chi : total:m2307_62, partial:m2307_71 -# 2307| v2307_73(void) = ^BufferReadSideEffect[0] : &:r2307_69, ~m2307_72 -# 2307| m2307_74(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_60 -# 2307| m2307_75(unknown) = Chi : total:m2307_72, partial:m2307_74 -# 2308| r2308_1(glval) = VariableAddress[s2] : -# 2308| m2308_2(String) = Uninitialized[s2] : &:r2308_1 -# 2308| m2308_3(unknown) = Chi : total:m2307_75, partial:m2308_2 -# 2308| r2308_4(glval) = FunctionAddress[String] : -# 2308| v2308_5(void) = Call[String] : func:r2308_4, this:r2308_1 -# 2308| m2308_6(unknown) = ^CallSideEffect : ~m2308_3 -# 2308| m2308_7(unknown) = Chi : total:m2308_3, partial:m2308_6 -# 2308| m2308_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_1 -# 2308| m2308_9(unknown) = Chi : total:m2308_7, partial:m2308_8 +# 2308| Block 5 +# 2308| r2308_60(glval) = VariableAddress[s] : +# 2308| m2308_61(String) = Uninitialized[s] : &:r2308_60 +# 2308| m2308_62(unknown) = Chi : total:m2308_57, partial:m2308_61 +# 2308| r2308_63(glval) = FunctionAddress[String] : +# 2308| r2308_64(glval>) = VariableAddress[(__begin)] : +#-----| r0_16(glval>) = Convert : r2308_64 +# 2308| r2308_65(glval) = FunctionAddress[operator*] : +# 2308| r2308_66(String &) = Call[operator*] : func:r2308_65, this:r0_16 +#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_16, m2308_47 +# 2308| r2308_67(glval) = CopyValue : r2308_66 +# 2308| r2308_68(glval) = Convert : r2308_67 +# 2308| r2308_69(String &) = CopyValue : r2308_68 +# 2308| v2308_70(void) = Call[String] : func:r2308_63, this:r2308_60, 0:r2308_69 +# 2308| m2308_71(unknown) = ^CallSideEffect : ~m2308_62 +# 2308| m2308_72(unknown) = Chi : total:m2308_62, partial:m2308_71 +# 2308| v2308_73(void) = ^BufferReadSideEffect[0] : &:r2308_69, ~m2308_72 +# 2308| m2308_74(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_60 +# 2308| m2308_75(unknown) = Chi : total:m2308_72, partial:m2308_74 # 2309| r2309_1(glval) = VariableAddress[s2] : -# 2309| r2309_2(glval) = FunctionAddress[~String] : -# 2309| v2309_3(void) = Call[~String] : func:r2309_2, this:r2309_1 -# 2309| m2309_4(unknown) = ^CallSideEffect : ~m2308_9 -# 2309| m2309_5(unknown) = Chi : total:m2308_9, partial:m2309_4 -# 2309| v2309_6(void) = ^IndirectReadSideEffect[-1] : &:r2309_1, ~m2309_5 -# 2309| m2309_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2309_1 -# 2309| m2309_8(unknown) = Chi : total:m2309_5, partial:m2309_7 -# 2307| r2307_76(glval) = VariableAddress[s] : -# 2307| r2307_77(glval) = FunctionAddress[~String] : -# 2307| v2307_78(void) = Call[~String] : func:r2307_77, this:r2307_76 -# 2307| m2307_79(unknown) = ^CallSideEffect : ~m2309_8 -# 2307| m2307_80(unknown) = Chi : total:m2309_8, partial:m2307_79 -# 2307| v2307_81(void) = ^IndirectReadSideEffect[-1] : &:r2307_76, ~m2307_80 -# 2307| m2307_82(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_76 -# 2307| m2307_83(unknown) = Chi : total:m2307_80, partial:m2307_82 -# 2307| r2307_84(glval>) = VariableAddress[(__begin)] : -# 2307| r2307_85(glval) = FunctionAddress[operator++] : -# 2307| r2307_86(iterator &) = Call[operator++] : func:r2307_85, this:r2307_84 -# 2307| v2307_87(void) = ^IndirectReadSideEffect[-1] : &:r2307_84, m2307_47 -# 2307| m2307_88(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2307_84 -# 2307| m2307_89(iterator) = Chi : total:m2307_47, partial:m2307_88 -# 2307| r2307_90(glval>) = CopyValue : r2307_86 +# 2309| m2309_2(String) = Uninitialized[s2] : &:r2309_1 +# 2309| m2309_3(unknown) = Chi : total:m2308_75, partial:m2309_2 +# 2309| r2309_4(glval) = FunctionAddress[String] : +# 2309| v2309_5(void) = Call[String] : func:r2309_4, this:r2309_1 +# 2309| m2309_6(unknown) = ^CallSideEffect : ~m2309_3 +# 2309| m2309_7(unknown) = Chi : total:m2309_3, partial:m2309_6 +# 2309| m2309_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2309_1 +# 2309| m2309_9(unknown) = Chi : total:m2309_7, partial:m2309_8 +# 2310| r2310_1(glval) = VariableAddress[s2] : +# 2310| r2310_2(glval) = FunctionAddress[~String] : +# 2310| v2310_3(void) = Call[~String] : func:r2310_2, this:r2310_1 +# 2310| m2310_4(unknown) = ^CallSideEffect : ~m2309_9 +# 2310| m2310_5(unknown) = Chi : total:m2309_9, partial:m2310_4 +# 2310| v2310_6(void) = ^IndirectReadSideEffect[-1] : &:r2310_1, ~m2310_5 +# 2310| m2310_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2310_1 +# 2310| m2310_8(unknown) = Chi : total:m2310_5, partial:m2310_7 +# 2308| r2308_76(glval>) = VariableAddress[(__begin)] : +# 2308| r2308_77(glval) = FunctionAddress[operator++] : +# 2308| r2308_78(iterator &) = Call[operator++] : func:r2308_77, this:r2308_76 +# 2308| v2308_79(void) = ^IndirectReadSideEffect[-1] : &:r2308_76, m2308_47 +# 2308| m2308_80(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2308_76 +# 2308| m2308_81(iterator) = Chi : total:m2308_47, partial:m2308_80 +# 2308| r2308_82(glval) = VariableAddress[s] : +# 2308| r2308_83(glval) = FunctionAddress[~String] : +# 2308| v2308_84(void) = Call[~String] : func:r2308_83, this:r2308_82 +# 2308| m2308_85(unknown) = ^CallSideEffect : ~m2310_8 +# 2308| m2308_86(unknown) = Chi : total:m2310_8, partial:m2308_85 +# 2308| v2308_87(void) = ^IndirectReadSideEffect[-1] : &:r2308_82, ~m2308_86 +# 2308| m2308_88(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_82 +# 2308| m2308_89(unknown) = Chi : total:m2308_86, partial:m2308_88 +# 2308| r2308_90(glval>) = CopyValue : r2308_78 #-----| Goto (back edge) -> Block 4 -# 2311| Block 6 -# 2311| r2311_1(glval) = VariableAddress[s] : -# 2311| m2311_2(String) = Uninitialized[s] : &:r2311_1 -# 2311| m2311_3(unknown) = Chi : total:m2307_57, partial:m2311_2 -# 2311| r2311_4(glval) = FunctionAddress[String] : -# 2311| r2311_5(glval) = StringConstant["hello"] : -# 2311| r2311_6(char *) = Convert : r2311_5 -# 2311| v2311_7(void) = Call[String] : func:r2311_4, this:r2311_1, 0:r2311_6 -# 2311| m2311_8(unknown) = ^CallSideEffect : ~m2311_3 -# 2311| m2311_9(unknown) = Chi : total:m2311_3, partial:m2311_8 -# 2311| v2311_10(void) = ^BufferReadSideEffect[0] : &:r2311_6, ~m2301_3 -# 2311| m2311_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_1 -# 2311| m2311_12(unknown) = Chi : total:m2311_9, partial:m2311_11 -# 2311| r2311_13(glval) = VariableAddress[s2] : -# 2311| m2311_14(String) = Uninitialized[s2] : &:r2311_13 -# 2311| m2311_15(unknown) = Chi : total:m2311_12, partial:m2311_14 -# 2311| r2311_16(glval) = FunctionAddress[String] : -# 2311| r2311_17(glval) = StringConstant["world"] : -# 2311| r2311_18(char *) = Convert : r2311_17 -# 2311| v2311_19(void) = Call[String] : func:r2311_16, this:r2311_13, 0:r2311_18 -# 2311| m2311_20(unknown) = ^CallSideEffect : ~m2311_15 -# 2311| m2311_21(unknown) = Chi : total:m2311_15, partial:m2311_20 -# 2311| v2311_22(void) = ^BufferReadSideEffect[0] : &:r2311_18, ~m2301_3 -# 2311| m2311_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_13 -# 2311| m2311_24(unknown) = Chi : total:m2311_21, partial:m2311_23 +# 2308| Block 6 +# 2308| r2308_91(glval>) = CopyValue : r2308_2 +# 2308| r2308_92(glval) = FunctionAddress[~vector] : +# 2308| v2308_93(void) = Call[~vector] : func:r2308_92, this:r2308_91 +# 2308| m2308_94(unknown) = ^CallSideEffect : ~m2308_57 +# 2308| m2308_95(unknown) = Chi : total:m2308_57, partial:m2308_94 +# 2308| v2308_96(void) = ^IndirectReadSideEffect[-1] : &:r2308_91, ~m2308_95 +# 2308| m2308_97(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2308_91 +# 2308| m2308_98(unknown) = Chi : total:m2308_95, partial:m2308_97 +# 2312| r2312_1(glval) = VariableAddress[s] : +# 2312| m2312_2(String) = Uninitialized[s] : &:r2312_1 +# 2312| m2312_3(unknown) = Chi : total:m2308_98, partial:m2312_2 +# 2312| r2312_4(glval) = FunctionAddress[String] : +# 2312| r2312_5(glval) = StringConstant["hello"] : +# 2312| r2312_6(char *) = Convert : r2312_5 +# 2312| v2312_7(void) = Call[String] : func:r2312_4, this:r2312_1, 0:r2312_6 +# 2312| m2312_8(unknown) = ^CallSideEffect : ~m2312_3 +# 2312| m2312_9(unknown) = Chi : total:m2312_3, partial:m2312_8 +# 2312| v2312_10(void) = ^BufferReadSideEffect[0] : &:r2312_6, ~m2302_3 +# 2312| m2312_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_1 +# 2312| m2312_12(unknown) = Chi : total:m2312_9, partial:m2312_11 +# 2312| r2312_13(glval) = VariableAddress[s2] : +# 2312| m2312_14(String) = Uninitialized[s2] : &:r2312_13 +# 2312| m2312_15(unknown) = Chi : total:m2312_12, partial:m2312_14 +# 2312| r2312_16(glval) = FunctionAddress[String] : +# 2312| r2312_17(glval) = StringConstant["world"] : +# 2312| r2312_18(char *) = Convert : r2312_17 +# 2312| v2312_19(void) = Call[String] : func:r2312_16, this:r2312_13, 0:r2312_18 +# 2312| m2312_20(unknown) = ^CallSideEffect : ~m2312_15 +# 2312| m2312_21(unknown) = Chi : total:m2312_15, partial:m2312_20 +# 2312| v2312_22(void) = ^BufferReadSideEffect[0] : &:r2312_18, ~m2302_3 +# 2312| m2312_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_13 +# 2312| m2312_24(unknown) = Chi : total:m2312_21, partial:m2312_23 #-----| Goto -> Block 7 -# 2311| Block 7 -# 2311| m2311_25(unknown) = Phi : from 6:~m2311_24, from 8:~m2311_40 -# 2311| m2311_26(char) = Phi : from 6:m2303_14, from 8:m2311_42 -# 2311| r2311_27(glval) = VariableAddress[c] : -# 2311| r2311_28(char) = Load[c] : &:r2311_27, m2311_26 -# 2311| r2311_29(int) = Convert : r2311_28 -# 2311| r2311_30(int) = Constant[0] : -# 2311| r2311_31(bool) = CompareNE : r2311_29, r2311_30 -# 2311| v2311_32(void) = ConditionalBranch : r2311_31 +# 2312| Block 7 +# 2312| m2312_25(unknown) = Phi : from 6:~m2312_24, from 8:~m2312_40 +# 2312| m2312_26(char) = Phi : from 6:m2304_14, from 8:m2312_42 +# 2312| r2312_27(glval) = VariableAddress[c] : +# 2312| r2312_28(char) = Load[c] : &:r2312_27, m2312_26 +# 2312| r2312_29(int) = Convert : r2312_28 +# 2312| r2312_30(int) = Constant[0] : +# 2312| r2312_31(bool) = CompareNE : r2312_29, r2312_30 +# 2312| v2312_32(void) = ConditionalBranch : r2312_31 #-----| False -> Block 9 #-----| True -> Block 8 -# 2312| Block 8 -# 2312| r2312_1(char) = Constant[0] : -# 2312| r2312_2(glval) = VariableAddress[c] : -# 2312| m2312_3(char) = Store[c] : &:r2312_2, r2312_1 -# 2311| r2311_33(glval) = VariableAddress[s] : -# 2311| r2311_34(glval) = FunctionAddress[pop_back] : -# 2311| r2311_35(char) = Call[pop_back] : func:r2311_34, this:r2311_33 -# 2311| m2311_36(unknown) = ^CallSideEffect : ~m2311_25 -# 2311| m2311_37(unknown) = Chi : total:m2311_25, partial:m2311_36 -# 2311| v2311_38(void) = ^IndirectReadSideEffect[-1] : &:r2311_33, ~m2311_37 -# 2311| m2311_39(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_33 -# 2311| m2311_40(unknown) = Chi : total:m2311_37, partial:m2311_39 -# 2311| r2311_41(glval) = VariableAddress[c] : -# 2311| m2311_42(char) = Store[c] : &:r2311_41, r2311_35 +# 2313| Block 8 +# 2313| r2313_1(char) = Constant[0] : +# 2313| r2313_2(glval) = VariableAddress[c] : +# 2313| m2313_3(char) = Store[c] : &:r2313_2, r2313_1 +# 2312| r2312_33(glval) = VariableAddress[s] : +# 2312| r2312_34(glval) = FunctionAddress[pop_back] : +# 2312| r2312_35(char) = Call[pop_back] : func:r2312_34, this:r2312_33 +# 2312| m2312_36(unknown) = ^CallSideEffect : ~m2312_25 +# 2312| m2312_37(unknown) = Chi : total:m2312_25, partial:m2312_36 +# 2312| v2312_38(void) = ^IndirectReadSideEffect[-1] : &:r2312_33, ~m2312_37 +# 2312| m2312_39(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_33 +# 2312| m2312_40(unknown) = Chi : total:m2312_37, partial:m2312_39 +# 2312| r2312_41(glval) = VariableAddress[c] : +# 2312| m2312_42(char) = Store[c] : &:r2312_41, r2312_35 #-----| Goto (back edge) -> Block 7 -# 2311| Block 9 -# 2311| r2311_43(glval) = VariableAddress[s2] : -# 2311| r2311_44(glval) = FunctionAddress[~String] : -# 2311| v2311_45(void) = Call[~String] : func:r2311_44, this:r2311_43 -# 2311| m2311_46(unknown) = ^CallSideEffect : ~m2311_25 -# 2311| m2311_47(unknown) = Chi : total:m2311_25, partial:m2311_46 -# 2311| v2311_48(void) = ^IndirectReadSideEffect[-1] : &:r2311_43, ~m2311_47 -# 2311| m2311_49(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_43 -# 2311| m2311_50(unknown) = Chi : total:m2311_47, partial:m2311_49 -# 2311| r2311_51(glval) = VariableAddress[s] : -# 2311| r2311_52(glval) = FunctionAddress[~String] : -# 2311| v2311_53(void) = Call[~String] : func:r2311_52, this:r2311_51 -# 2311| m2311_54(unknown) = ^CallSideEffect : ~m2311_50 -# 2311| m2311_55(unknown) = Chi : total:m2311_50, partial:m2311_54 -# 2311| v2311_56(void) = ^IndirectReadSideEffect[-1] : &:r2311_51, ~m2311_55 -# 2311| m2311_57(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_51 -# 2311| m2311_58(unknown) = Chi : total:m2311_55, partial:m2311_57 -# 2314| v2314_1(void) = NoOp : -# 2301| v2301_5(void) = ReturnVoid : -# 2301| v2301_6(void) = AliasedUse : ~m2311_55 -# 2301| v2301_7(void) = ExitFunction : - -# 2316| void IfDestructors2(bool) -# 2316| Block 0 -# 2316| v2316_1(void) = EnterFunction : -# 2316| m2316_2(unknown) = AliasedDefinition : -# 2316| m2316_3(unknown) = InitializeNonLocal : -# 2316| m2316_4(unknown) = Chi : total:m2316_2, partial:m2316_3 -# 2316| r2316_5(glval) = VariableAddress[b] : -# 2316| m2316_6(bool) = InitializeParameter[b] : &:r2316_5 -# 2317| r2317_1(glval) = VariableAddress[s] : -# 2317| m2317_2(String) = Uninitialized[s] : &:r2317_1 -# 2317| m2317_3(unknown) = Chi : total:m2316_4, partial:m2317_2 -# 2317| r2317_4(glval) = FunctionAddress[String] : -# 2317| r2317_5(glval) = StringConstant["hello"] : -# 2317| r2317_6(char *) = Convert : r2317_5 -# 2317| v2317_7(void) = Call[String] : func:r2317_4, this:r2317_1, 0:r2317_6 -# 2317| m2317_8(unknown) = ^CallSideEffect : ~m2317_3 -# 2317| m2317_9(unknown) = Chi : total:m2317_3, partial:m2317_8 -# 2317| v2317_10(void) = ^BufferReadSideEffect[0] : &:r2317_6, ~m2316_3 -# 2317| m2317_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2317_1 -# 2317| m2317_12(unknown) = Chi : total:m2317_9, partial:m2317_11 -# 2317| r2317_13(glval) = VariableAddress[b] : -# 2317| r2317_14(bool) = Load[b] : &:r2317_13, m2316_6 -# 2317| v2317_15(void) = ConditionalBranch : r2317_14 +# 2312| Block 9 +# 2312| r2312_43(glval) = VariableAddress[s2] : +# 2312| r2312_44(glval) = FunctionAddress[~String] : +# 2312| v2312_45(void) = Call[~String] : func:r2312_44, this:r2312_43 +# 2312| m2312_46(unknown) = ^CallSideEffect : ~m2312_25 +# 2312| m2312_47(unknown) = Chi : total:m2312_25, partial:m2312_46 +# 2312| v2312_48(void) = ^IndirectReadSideEffect[-1] : &:r2312_43, ~m2312_47 +# 2312| m2312_49(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_43 +# 2312| m2312_50(unknown) = Chi : total:m2312_47, partial:m2312_49 +# 2312| r2312_51(glval) = VariableAddress[s] : +# 2312| r2312_52(glval) = FunctionAddress[~String] : +# 2312| v2312_53(void) = Call[~String] : func:r2312_52, this:r2312_51 +# 2312| m2312_54(unknown) = ^CallSideEffect : ~m2312_50 +# 2312| m2312_55(unknown) = Chi : total:m2312_50, partial:m2312_54 +# 2312| v2312_56(void) = ^IndirectReadSideEffect[-1] : &:r2312_51, ~m2312_55 +# 2312| m2312_57(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_51 +# 2312| m2312_58(unknown) = Chi : total:m2312_55, partial:m2312_57 +# 2315| v2315_1(void) = NoOp : +# 2302| v2302_5(void) = ReturnVoid : +# 2302| v2302_6(void) = AliasedUse : ~m2312_55 +# 2302| v2302_7(void) = ExitFunction : + +# 2317| void IfDestructors2(bool) +# 2317| Block 0 +# 2317| v2317_1(void) = EnterFunction : +# 2317| m2317_2(unknown) = AliasedDefinition : +# 2317| m2317_3(unknown) = InitializeNonLocal : +# 2317| m2317_4(unknown) = Chi : total:m2317_2, partial:m2317_3 +# 2317| r2317_5(glval) = VariableAddress[b] : +# 2317| m2317_6(bool) = InitializeParameter[b] : &:r2317_5 +# 2318| r2318_1(glval) = VariableAddress[s] : +# 2318| m2318_2(String) = Uninitialized[s] : &:r2318_1 +# 2318| m2318_3(unknown) = Chi : total:m2317_4, partial:m2318_2 +# 2318| r2318_4(glval) = FunctionAddress[String] : +# 2318| r2318_5(glval) = StringConstant["hello"] : +# 2318| r2318_6(char *) = Convert : r2318_5 +# 2318| v2318_7(void) = Call[String] : func:r2318_4, this:r2318_1, 0:r2318_6 +# 2318| m2318_8(unknown) = ^CallSideEffect : ~m2318_3 +# 2318| m2318_9(unknown) = Chi : total:m2318_3, partial:m2318_8 +# 2318| v2318_10(void) = ^BufferReadSideEffect[0] : &:r2318_6, ~m2317_3 +# 2318| m2318_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2318_1 +# 2318| m2318_12(unknown) = Chi : total:m2318_9, partial:m2318_11 +# 2318| r2318_13(glval) = VariableAddress[b] : +# 2318| r2318_14(bool) = Load[b] : &:r2318_13, m2317_6 +# 2318| v2318_15(void) = ConditionalBranch : r2318_14 #-----| False -> Block 2 #-----| True -> Block 1 -# 2318| Block 1 -# 2318| r2318_1(glval) = VariableAddress[x] : -# 2318| r2318_2(int) = Constant[0] : -# 2318| m2318_3(int) = Store[x] : &:r2318_1, r2318_2 +# 2319| Block 1 +# 2319| r2319_1(glval) = VariableAddress[x] : +# 2319| r2319_2(int) = Constant[0] : +# 2319| m2319_3(int) = Store[x] : &:r2319_1, r2319_2 #-----| Goto -> Block 3 -# 2320| Block 2 -# 2320| r2320_1(glval) = VariableAddress[y] : -# 2320| r2320_2(int) = Constant[0] : -# 2320| m2320_3(int) = Store[y] : &:r2320_1, r2320_2 +# 2321| Block 2 +# 2321| r2321_1(glval) = VariableAddress[y] : +# 2321| r2321_2(int) = Constant[0] : +# 2321| m2321_3(int) = Store[y] : &:r2321_1, r2321_2 #-----| Goto -> Block 3 -# 2321| Block 3 -# 2321| r2321_1(glval) = VariableAddress[s] : -# 2321| r2321_2(glval) = FunctionAddress[~String] : -# 2321| v2321_3(void) = Call[~String] : func:r2321_2, this:r2321_1 -# 2321| m2321_4(unknown) = ^CallSideEffect : ~m2317_12 -# 2321| m2321_5(unknown) = Chi : total:m2317_12, partial:m2321_4 -# 2321| v2321_6(void) = ^IndirectReadSideEffect[-1] : &:r2321_1, ~m2321_5 -# 2321| m2321_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2321_1 -# 2321| m2321_8(unknown) = Chi : total:m2321_5, partial:m2321_7 -# 2322| v2322_1(void) = NoOp : -# 2316| v2316_7(void) = ReturnVoid : -# 2316| v2316_8(void) = AliasedUse : ~m2321_5 -# 2316| v2316_9(void) = ExitFunction : - -# 2331| void IfDestructors3(bool) -# 2331| Block 0 -# 2331| v2331_1(void) = EnterFunction : -# 2331| m2331_2(unknown) = AliasedDefinition : -# 2331| m2331_3(unknown) = InitializeNonLocal : -# 2331| m2331_4(unknown) = Chi : total:m2331_2, partial:m2331_3 -# 2331| r2331_5(glval) = VariableAddress[b] : -# 2331| m2331_6(bool) = InitializeParameter[b] : &:r2331_5 -# 2332| r2332_1(glval) = VariableAddress[B] : -# 2332| m2332_2(Bool) = Uninitialized[B] : &:r2332_1 -# 2332| m2332_3(unknown) = Chi : total:m2331_4, partial:m2332_2 -# 2332| r2332_4(glval) = FunctionAddress[Bool] : +# 2322| Block 3 +# 2322| r2322_1(glval) = VariableAddress[s] : +# 2322| r2322_2(glval) = FunctionAddress[~String] : +# 2322| v2322_3(void) = Call[~String] : func:r2322_2, this:r2322_1 +# 2322| m2322_4(unknown) = ^CallSideEffect : ~m2318_12 +# 2322| m2322_5(unknown) = Chi : total:m2318_12, partial:m2322_4 +# 2322| v2322_6(void) = ^IndirectReadSideEffect[-1] : &:r2322_1, ~m2322_5 +# 2322| m2322_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2322_1 +# 2322| m2322_8(unknown) = Chi : total:m2322_5, partial:m2322_7 +# 2323| v2323_1(void) = NoOp : +# 2317| v2317_7(void) = ReturnVoid : +# 2317| v2317_8(void) = AliasedUse : ~m2322_5 +# 2317| v2317_9(void) = ExitFunction : + +# 2332| void IfDestructors3(bool) +# 2332| Block 0 +# 2332| v2332_1(void) = EnterFunction : +# 2332| m2332_2(unknown) = AliasedDefinition : +# 2332| m2332_3(unknown) = InitializeNonLocal : +# 2332| m2332_4(unknown) = Chi : total:m2332_2, partial:m2332_3 # 2332| r2332_5(glval) = VariableAddress[b] : -# 2332| r2332_6(bool) = Load[b] : &:r2332_5, m2331_6 -# 2332| v2332_7(void) = Call[Bool] : func:r2332_4, this:r2332_1, 0:r2332_6 -# 2332| m2332_8(unknown) = ^CallSideEffect : ~m2332_3 -# 2332| m2332_9(unknown) = Chi : total:m2332_3, partial:m2332_8 -# 2332| m2332_10(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2332_1 -# 2332| m2332_11(unknown) = Chi : total:m2332_9, partial:m2332_10 -# 2332| r2332_12(glval) = VariableAddress[B] : -# 2332| r2332_13(glval) = FunctionAddress[operator bool] : -# 2332| r2332_14(bool) = Call[operator bool] : func:r2332_13, this:r2332_12 -# 2332| m2332_15(unknown) = ^CallSideEffect : ~m2332_11 -# 2332| m2332_16(unknown) = Chi : total:m2332_11, partial:m2332_15 -# 2332| v2332_17(void) = ^IndirectReadSideEffect[-1] : &:r2332_12, ~m2332_16 -# 2332| m2332_18(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2332_12 -# 2332| m2332_19(unknown) = Chi : total:m2332_16, partial:m2332_18 -# 2332| r2332_20(bool) = CopyValue : r2332_14 -# 2332| v2332_21(void) = ConditionalBranch : r2332_20 +# 2332| m2332_6(bool) = InitializeParameter[b] : &:r2332_5 +# 2333| r2333_1(glval) = VariableAddress[B] : +# 2333| m2333_2(Bool) = Uninitialized[B] : &:r2333_1 +# 2333| m2333_3(unknown) = Chi : total:m2332_4, partial:m2333_2 +# 2333| r2333_4(glval) = FunctionAddress[Bool] : +# 2333| r2333_5(glval) = VariableAddress[b] : +# 2333| r2333_6(bool) = Load[b] : &:r2333_5, m2332_6 +# 2333| v2333_7(void) = Call[Bool] : func:r2333_4, this:r2333_1, 0:r2333_6 +# 2333| m2333_8(unknown) = ^CallSideEffect : ~m2333_3 +# 2333| m2333_9(unknown) = Chi : total:m2333_3, partial:m2333_8 +# 2333| m2333_10(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2333_1 +# 2333| m2333_11(unknown) = Chi : total:m2333_9, partial:m2333_10 +# 2333| r2333_12(glval) = VariableAddress[B] : +# 2333| r2333_13(glval) = FunctionAddress[operator bool] : +# 2333| r2333_14(bool) = Call[operator bool] : func:r2333_13, this:r2333_12 +# 2333| m2333_15(unknown) = ^CallSideEffect : ~m2333_11 +# 2333| m2333_16(unknown) = Chi : total:m2333_11, partial:m2333_15 +# 2333| v2333_17(void) = ^IndirectReadSideEffect[-1] : &:r2333_12, ~m2333_16 +# 2333| m2333_18(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2333_12 +# 2333| m2333_19(unknown) = Chi : total:m2333_16, partial:m2333_18 +# 2333| r2333_20(bool) = CopyValue : r2333_14 +# 2333| v2333_21(void) = ConditionalBranch : r2333_20 #-----| False -> Block 2 #-----| True -> Block 1 -# 2333| Block 1 -# 2333| r2333_1(glval) = VariableAddress[s1] : -# 2333| m2333_2(String) = Uninitialized[s1] : &:r2333_1 -# 2333| m2333_3(unknown) = Chi : total:m2332_19, partial:m2333_2 -# 2333| r2333_4(glval) = FunctionAddress[String] : -# 2333| v2333_5(void) = Call[String] : func:r2333_4, this:r2333_1 -# 2333| m2333_6(unknown) = ^CallSideEffect : ~m2333_3 -# 2333| m2333_7(unknown) = Chi : total:m2333_3, partial:m2333_6 -# 2333| m2333_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2333_1 -# 2333| m2333_9(unknown) = Chi : total:m2333_7, partial:m2333_8 +# 2334| Block 1 # 2334| r2334_1(glval) = VariableAddress[s1] : -# 2334| r2334_2(glval) = FunctionAddress[~String] : -# 2334| v2334_3(void) = Call[~String] : func:r2334_2, this:r2334_1 -# 2334| m2334_4(unknown) = ^CallSideEffect : ~m2333_9 -# 2334| m2334_5(unknown) = Chi : total:m2333_9, partial:m2334_4 -# 2334| v2334_6(void) = ^IndirectReadSideEffect[-1] : &:r2334_1, ~m2334_5 -# 2334| m2334_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2334_1 -# 2334| m2334_8(unknown) = Chi : total:m2334_5, partial:m2334_7 +# 2334| m2334_2(String) = Uninitialized[s1] : &:r2334_1 +# 2334| m2334_3(unknown) = Chi : total:m2333_19, partial:m2334_2 +# 2334| r2334_4(glval) = FunctionAddress[String] : +# 2334| v2334_5(void) = Call[String] : func:r2334_4, this:r2334_1 +# 2334| m2334_6(unknown) = ^CallSideEffect : ~m2334_3 +# 2334| m2334_7(unknown) = Chi : total:m2334_3, partial:m2334_6 +# 2334| m2334_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2334_1 +# 2334| m2334_9(unknown) = Chi : total:m2334_7, partial:m2334_8 +# 2335| r2335_1(glval) = VariableAddress[s1] : +# 2335| r2335_2(glval) = FunctionAddress[~String] : +# 2335| v2335_3(void) = Call[~String] : func:r2335_2, this:r2335_1 +# 2335| m2335_4(unknown) = ^CallSideEffect : ~m2334_9 +# 2335| m2335_5(unknown) = Chi : total:m2334_9, partial:m2335_4 +# 2335| v2335_6(void) = ^IndirectReadSideEffect[-1] : &:r2335_1, ~m2335_5 +# 2335| m2335_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2335_1 +# 2335| m2335_8(unknown) = Chi : total:m2335_5, partial:m2335_7 #-----| Goto -> Block 3 -# 2335| Block 2 -# 2335| r2335_1(glval) = VariableAddress[s2] : -# 2335| m2335_2(String) = Uninitialized[s2] : &:r2335_1 -# 2335| m2335_3(unknown) = Chi : total:m2332_19, partial:m2335_2 -# 2335| r2335_4(glval) = FunctionAddress[String] : -# 2335| v2335_5(void) = Call[String] : func:r2335_4, this:r2335_1 -# 2335| m2335_6(unknown) = ^CallSideEffect : ~m2335_3 -# 2335| m2335_7(unknown) = Chi : total:m2335_3, partial:m2335_6 -# 2335| m2335_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2335_1 -# 2335| m2335_9(unknown) = Chi : total:m2335_7, partial:m2335_8 +# 2336| Block 2 # 2336| r2336_1(glval) = VariableAddress[s2] : -# 2336| r2336_2(glval) = FunctionAddress[~String] : -# 2336| v2336_3(void) = Call[~String] : func:r2336_2, this:r2336_1 -# 2336| m2336_4(unknown) = ^CallSideEffect : ~m2335_9 -# 2336| m2336_5(unknown) = Chi : total:m2335_9, partial:m2336_4 -# 2336| v2336_6(void) = ^IndirectReadSideEffect[-1] : &:r2336_1, ~m2336_5 -# 2336| m2336_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2336_1 -# 2336| m2336_8(unknown) = Chi : total:m2336_5, partial:m2336_7 +# 2336| m2336_2(String) = Uninitialized[s2] : &:r2336_1 +# 2336| m2336_3(unknown) = Chi : total:m2333_19, partial:m2336_2 +# 2336| r2336_4(glval) = FunctionAddress[String] : +# 2336| v2336_5(void) = Call[String] : func:r2336_4, this:r2336_1 +# 2336| m2336_6(unknown) = ^CallSideEffect : ~m2336_3 +# 2336| m2336_7(unknown) = Chi : total:m2336_3, partial:m2336_6 +# 2336| m2336_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2336_1 +# 2336| m2336_9(unknown) = Chi : total:m2336_7, partial:m2336_8 +# 2337| r2337_1(glval) = VariableAddress[s2] : +# 2337| r2337_2(glval) = FunctionAddress[~String] : +# 2337| v2337_3(void) = Call[~String] : func:r2337_2, this:r2337_1 +# 2337| m2337_4(unknown) = ^CallSideEffect : ~m2336_9 +# 2337| m2337_5(unknown) = Chi : total:m2336_9, partial:m2337_4 +# 2337| v2337_6(void) = ^IndirectReadSideEffect[-1] : &:r2337_1, ~m2337_5 +# 2337| m2337_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2337_1 +# 2337| m2337_8(unknown) = Chi : total:m2337_5, partial:m2337_7 #-----| Goto -> Block 3 -# 2336| Block 3 -# 2336| m2336_9(unknown) = Phi : from 1:~m2334_8, from 2:~m2336_8 -# 2336| r2336_10(glval) = VariableAddress[B] : -# 2336| r2336_11(glval) = FunctionAddress[~Bool] : -# 2336| v2336_12(void) = Call[~Bool] : func:r2336_11, this:r2336_10 -# 2336| m2336_13(unknown) = ^CallSideEffect : ~m2336_9 -# 2336| m2336_14(unknown) = Chi : total:m2336_9, partial:m2336_13 -# 2336| v2336_15(void) = ^IndirectReadSideEffect[-1] : &:r2336_10, ~m2336_14 -# 2336| m2336_16(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2336_10 -# 2336| m2336_17(unknown) = Chi : total:m2336_14, partial:m2336_16 -# 2337| v2337_1(void) = NoOp : -# 2331| v2331_7(void) = ReturnVoid : -# 2331| v2331_8(void) = AliasedUse : ~m2336_14 -# 2331| v2331_9(void) = ExitFunction : - -# 2339| void WhileLoopDestructors(bool) -# 2339| Block 0 -# 2339| v2339_1(void) = EnterFunction : -# 2339| m2339_2(unknown) = AliasedDefinition : -# 2339| m2339_3(unknown) = InitializeNonLocal : -# 2339| m2339_4(unknown) = Chi : total:m2339_2, partial:m2339_3 -# 2339| r2339_5(glval) = VariableAddress[b] : -# 2339| m2339_6(bool) = InitializeParameter[b] : &:r2339_5 -# 2341| r2341_1(glval) = VariableAddress[s] : -# 2341| m2341_2(String) = Uninitialized[s] : &:r2341_1 -# 2341| m2341_3(unknown) = Chi : total:m2339_4, partial:m2341_2 -# 2341| r2341_4(glval) = FunctionAddress[String] : -# 2341| v2341_5(void) = Call[String] : func:r2341_4, this:r2341_1 -# 2341| m2341_6(unknown) = ^CallSideEffect : ~m2341_3 -# 2341| m2341_7(unknown) = Chi : total:m2341_3, partial:m2341_6 -# 2341| m2341_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2341_1 -# 2341| m2341_9(unknown) = Chi : total:m2341_7, partial:m2341_8 +# 2337| Block 3 +# 2337| m2337_9(unknown) = Phi : from 1:~m2335_8, from 2:~m2337_8 +# 2337| r2337_10(glval) = VariableAddress[B] : +# 2337| r2337_11(glval) = FunctionAddress[~Bool] : +# 2337| v2337_12(void) = Call[~Bool] : func:r2337_11, this:r2337_10 +# 2337| m2337_13(unknown) = ^CallSideEffect : ~m2337_9 +# 2337| m2337_14(unknown) = Chi : total:m2337_9, partial:m2337_13 +# 2337| v2337_15(void) = ^IndirectReadSideEffect[-1] : &:r2337_10, ~m2337_14 +# 2337| m2337_16(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2337_10 +# 2337| m2337_17(unknown) = Chi : total:m2337_14, partial:m2337_16 +# 2338| v2338_1(void) = NoOp : +# 2332| v2332_7(void) = ReturnVoid : +# 2332| v2332_8(void) = AliasedUse : ~m2337_14 +# 2332| v2332_9(void) = ExitFunction : + +# 2340| void WhileLoopDestructors(bool) +# 2340| Block 0 +# 2340| v2340_1(void) = EnterFunction : +# 2340| m2340_2(unknown) = AliasedDefinition : +# 2340| m2340_3(unknown) = InitializeNonLocal : +# 2340| m2340_4(unknown) = Chi : total:m2340_2, partial:m2340_3 +# 2340| r2340_5(glval) = VariableAddress[b] : +# 2340| m2340_6(bool) = InitializeParameter[b] : &:r2340_5 +# 2342| r2342_1(glval) = VariableAddress[s] : +# 2342| m2342_2(String) = Uninitialized[s] : &:r2342_1 +# 2342| m2342_3(unknown) = Chi : total:m2340_4, partial:m2342_2 +# 2342| r2342_4(glval) = FunctionAddress[String] : +# 2342| v2342_5(void) = Call[String] : func:r2342_4, this:r2342_1 +# 2342| m2342_6(unknown) = ^CallSideEffect : ~m2342_3 +# 2342| m2342_7(unknown) = Chi : total:m2342_3, partial:m2342_6 +# 2342| m2342_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2342_1 +# 2342| m2342_9(unknown) = Chi : total:m2342_7, partial:m2342_8 #-----| Goto -> Block 1 -# 2342| Block 1 -# 2342| m2342_1(bool) = Phi : from 0:m2339_6, from 2:m2343_3 -# 2342| r2342_2(glval) = VariableAddress[b] : -# 2342| r2342_3(bool) = Load[b] : &:r2342_2, m2342_1 -# 2342| v2342_4(void) = ConditionalBranch : r2342_3 +# 2343| Block 1 +# 2343| m2343_1(bool) = Phi : from 0:m2340_6, from 2:m2344_3 +# 2343| r2343_2(glval) = VariableAddress[b] : +# 2343| r2343_3(bool) = Load[b] : &:r2343_2, m2343_1 +# 2343| v2343_4(void) = ConditionalBranch : r2343_3 #-----| False -> Block 3 #-----| True -> Block 2 -# 2343| Block 2 -# 2343| r2343_1(bool) = Constant[0] : -# 2343| r2343_2(glval) = VariableAddress[b] : -# 2343| m2343_3(bool) = Store[b] : &:r2343_2, r2343_1 +# 2344| Block 2 +# 2344| r2344_1(bool) = Constant[0] : +# 2344| r2344_2(glval) = VariableAddress[b] : +# 2344| m2344_3(bool) = Store[b] : &:r2344_2, r2344_1 #-----| Goto (back edge) -> Block 1 -# 2345| Block 3 -# 2345| r2345_1(glval) = VariableAddress[s] : -# 2345| r2345_2(glval) = FunctionAddress[~String] : -# 2345| v2345_3(void) = Call[~String] : func:r2345_2, this:r2345_1 -# 2345| m2345_4(unknown) = ^CallSideEffect : ~m2341_9 -# 2345| m2345_5(unknown) = Chi : total:m2341_9, partial:m2345_4 -# 2345| v2345_6(void) = ^IndirectReadSideEffect[-1] : &:r2345_1, ~m2345_5 -# 2345| m2345_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2345_1 -# 2345| m2345_8(unknown) = Chi : total:m2345_5, partial:m2345_7 +# 2346| Block 3 +# 2346| r2346_1(glval) = VariableAddress[s] : +# 2346| r2346_2(glval) = FunctionAddress[~String] : +# 2346| v2346_3(void) = Call[~String] : func:r2346_2, this:r2346_1 +# 2346| m2346_4(unknown) = ^CallSideEffect : ~m2342_9 +# 2346| m2346_5(unknown) = Chi : total:m2342_9, partial:m2346_4 +# 2346| v2346_6(void) = ^IndirectReadSideEffect[-1] : &:r2346_1, ~m2346_5 +# 2346| m2346_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2346_1 +# 2346| m2346_8(unknown) = Chi : total:m2346_5, partial:m2346_7 #-----| Goto -> Block 4 -# 2348| Block 4 -# 2348| m2348_1(unknown) = Phi : from 3:~m2345_8, from 5:~m2350_8 -# 2348| m2348_2(bool) = Phi : from 3:m2342_1, from 5:m2349_3 -# 2348| r2348_3(glval) = VariableAddress[B] : -# 2348| m2348_4(Bool) = Uninitialized[B] : &:r2348_3 -# 2348| m2348_5(unknown) = Chi : total:m2348_1, partial:m2348_4 -# 2348| r2348_6(glval) = FunctionAddress[Bool] : -# 2348| r2348_7(glval) = VariableAddress[b] : -# 2348| r2348_8(bool) = Load[b] : &:r2348_7, m2348_2 -# 2348| v2348_9(void) = Call[Bool] : func:r2348_6, this:r2348_3, 0:r2348_8 -# 2348| m2348_10(unknown) = ^CallSideEffect : ~m2348_5 -# 2348| m2348_11(unknown) = Chi : total:m2348_5, partial:m2348_10 -# 2348| m2348_12(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2348_3 -# 2348| m2348_13(unknown) = Chi : total:m2348_11, partial:m2348_12 -# 2348| r2348_14(glval) = VariableAddress[B] : -# 2348| r2348_15(glval) = FunctionAddress[operator bool] : -# 2348| r2348_16(bool) = Call[operator bool] : func:r2348_15, this:r2348_14 -# 2348| m2348_17(unknown) = ^CallSideEffect : ~m2348_13 -# 2348| m2348_18(unknown) = Chi : total:m2348_13, partial:m2348_17 -# 2348| v2348_19(void) = ^IndirectReadSideEffect[-1] : &:r2348_14, ~m2348_18 -# 2348| m2348_20(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2348_14 -# 2348| m2348_21(unknown) = Chi : total:m2348_18, partial:m2348_20 -# 2348| r2348_22(bool) = CopyValue : r2348_16 -# 2348| v2348_23(void) = ConditionalBranch : r2348_22 +# 2349| Block 4 +# 2349| m2349_1(unknown) = Phi : from 3:~m2346_8, from 5:~m2351_8 +# 2349| m2349_2(bool) = Phi : from 3:m2343_1, from 5:m2350_3 +# 2349| r2349_3(glval) = VariableAddress[B] : +# 2349| m2349_4(Bool) = Uninitialized[B] : &:r2349_3 +# 2349| m2349_5(unknown) = Chi : total:m2349_1, partial:m2349_4 +# 2349| r2349_6(glval) = FunctionAddress[Bool] : +# 2349| r2349_7(glval) = VariableAddress[b] : +# 2349| r2349_8(bool) = Load[b] : &:r2349_7, m2349_2 +# 2349| v2349_9(void) = Call[Bool] : func:r2349_6, this:r2349_3, 0:r2349_8 +# 2349| m2349_10(unknown) = ^CallSideEffect : ~m2349_5 +# 2349| m2349_11(unknown) = Chi : total:m2349_5, partial:m2349_10 +# 2349| m2349_12(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2349_3 +# 2349| m2349_13(unknown) = Chi : total:m2349_11, partial:m2349_12 +# 2349| r2349_14(glval) = VariableAddress[B] : +# 2349| r2349_15(glval) = FunctionAddress[operator bool] : +# 2349| r2349_16(bool) = Call[operator bool] : func:r2349_15, this:r2349_14 +# 2349| m2349_17(unknown) = ^CallSideEffect : ~m2349_13 +# 2349| m2349_18(unknown) = Chi : total:m2349_13, partial:m2349_17 +# 2349| v2349_19(void) = ^IndirectReadSideEffect[-1] : &:r2349_14, ~m2349_18 +# 2349| m2349_20(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2349_14 +# 2349| m2349_21(unknown) = Chi : total:m2349_18, partial:m2349_20 +# 2349| r2349_22(bool) = CopyValue : r2349_16 +# 2349| v2349_23(void) = ConditionalBranch : r2349_22 #-----| False -> Block 6 #-----| True -> Block 5 -# 2349| Block 5 -# 2349| r2349_1(bool) = Constant[0] : -# 2349| r2349_2(glval) = VariableAddress[b] : -# 2349| m2349_3(bool) = Store[b] : &:r2349_2, r2349_1 -# 2350| r2350_1(glval) = VariableAddress[B] : -# 2350| r2350_2(glval) = FunctionAddress[~Bool] : -# 2350| v2350_3(void) = Call[~Bool] : func:r2350_2, this:r2350_1 -# 2350| m2350_4(unknown) = ^CallSideEffect : ~m2348_21 -# 2350| m2350_5(unknown) = Chi : total:m2348_21, partial:m2350_4 -# 2350| v2350_6(void) = ^IndirectReadSideEffect[-1] : &:r2350_1, ~m2350_5 -# 2350| m2350_7(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2350_1 -# 2350| m2350_8(unknown) = Chi : total:m2350_5, partial:m2350_7 +# 2350| Block 5 +# 2350| r2350_1(bool) = Constant[0] : +# 2350| r2350_2(glval) = VariableAddress[b] : +# 2350| m2350_3(bool) = Store[b] : &:r2350_2, r2350_1 +# 2351| r2351_1(glval) = VariableAddress[B] : +# 2351| r2351_2(glval) = FunctionAddress[~Bool] : +# 2351| v2351_3(void) = Call[~Bool] : func:r2351_2, this:r2351_1 +# 2351| m2351_4(unknown) = ^CallSideEffect : ~m2349_21 +# 2351| m2351_5(unknown) = Chi : total:m2349_21, partial:m2351_4 +# 2351| v2351_6(void) = ^IndirectReadSideEffect[-1] : &:r2351_1, ~m2351_5 +# 2351| m2351_7(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2351_1 +# 2351| m2351_8(unknown) = Chi : total:m2351_5, partial:m2351_7 #-----| Goto (back edge) -> Block 4 -# 2350| Block 6 -# 2350| r2350_9(glval) = VariableAddress[B] : -# 2350| r2350_10(glval) = FunctionAddress[~Bool] : -# 2350| v2350_11(void) = Call[~Bool] : func:r2350_10, this:r2350_9 -# 2350| m2350_12(unknown) = ^CallSideEffect : ~m2348_21 -# 2350| m2350_13(unknown) = Chi : total:m2348_21, partial:m2350_12 -# 2350| v2350_14(void) = ^IndirectReadSideEffect[-1] : &:r2350_9, ~m2350_13 -# 2350| m2350_15(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2350_9 -# 2350| m2350_16(unknown) = Chi : total:m2350_13, partial:m2350_15 -# 2352| v2352_1(void) = NoOp : -# 2339| v2339_7(void) = ReturnVoid : -# 2339| v2339_8(void) = AliasedUse : ~m2350_13 -# 2339| v2339_9(void) = ExitFunction : - -# 2354| void VoidFunc() -# 2354| Block 0 -# 2354| v2354_1(void) = EnterFunction : -# 2354| m2354_2(unknown) = AliasedDefinition : -# 2354| m2354_3(unknown) = InitializeNonLocal : -# 2354| m2354_4(unknown) = Chi : total:m2354_2, partial:m2354_3 -# 2354| v2354_5(void) = NoOp : -# 2354| v2354_6(void) = ReturnVoid : -# 2354| v2354_7(void) = AliasedUse : m2354_3 -# 2354| v2354_8(void) = ExitFunction : - -# 2356| void IfReturnDestructors(bool) -# 2356| Block 0 -# 2356| v2356_1(void) = EnterFunction : -# 2356| m2356_2(unknown) = AliasedDefinition : -# 2356| m2356_3(unknown) = InitializeNonLocal : -# 2356| m2356_4(unknown) = Chi : total:m2356_2, partial:m2356_3 -# 2356| r2356_5(glval) = VariableAddress[b] : -# 2356| m2356_6(bool) = InitializeParameter[b] : &:r2356_5 -# 2357| r2357_1(glval) = VariableAddress[s] : -# 2357| m2357_2(String) = Uninitialized[s] : &:r2357_1 -# 2357| m2357_3(unknown) = Chi : total:m2356_4, partial:m2357_2 -# 2357| r2357_4(glval) = FunctionAddress[String] : -# 2357| v2357_5(void) = Call[String] : func:r2357_4, this:r2357_1 -# 2357| m2357_6(unknown) = ^CallSideEffect : ~m2357_3 -# 2357| m2357_7(unknown) = Chi : total:m2357_3, partial:m2357_6 -# 2357| m2357_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2357_1 -# 2357| m2357_9(unknown) = Chi : total:m2357_7, partial:m2357_8 -# 2358| r2358_1(glval) = VariableAddress[b] : -# 2358| r2358_2(bool) = Load[b] : &:r2358_1, m2356_6 -# 2358| v2358_3(void) = ConditionalBranch : r2358_2 +# 2351| Block 6 +# 2351| r2351_9(glval) = VariableAddress[B] : +# 2351| r2351_10(glval) = FunctionAddress[~Bool] : +# 2351| v2351_11(void) = Call[~Bool] : func:r2351_10, this:r2351_9 +# 2351| m2351_12(unknown) = ^CallSideEffect : ~m2349_21 +# 2351| m2351_13(unknown) = Chi : total:m2349_21, partial:m2351_12 +# 2351| v2351_14(void) = ^IndirectReadSideEffect[-1] : &:r2351_9, ~m2351_13 +# 2351| m2351_15(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2351_9 +# 2351| m2351_16(unknown) = Chi : total:m2351_13, partial:m2351_15 +# 2353| v2353_1(void) = NoOp : +# 2340| v2340_7(void) = ReturnVoid : +# 2340| v2340_8(void) = AliasedUse : ~m2351_13 +# 2340| v2340_9(void) = ExitFunction : + +# 2355| void VoidFunc() +# 2355| Block 0 +# 2355| v2355_1(void) = EnterFunction : +# 2355| m2355_2(unknown) = AliasedDefinition : +# 2355| m2355_3(unknown) = InitializeNonLocal : +# 2355| m2355_4(unknown) = Chi : total:m2355_2, partial:m2355_3 +# 2355| v2355_5(void) = NoOp : +# 2355| v2355_6(void) = ReturnVoid : +# 2355| v2355_7(void) = AliasedUse : m2355_3 +# 2355| v2355_8(void) = ExitFunction : + +# 2357| void IfReturnDestructors(bool) +# 2357| Block 0 +# 2357| v2357_1(void) = EnterFunction : +# 2357| m2357_2(unknown) = AliasedDefinition : +# 2357| m2357_3(unknown) = InitializeNonLocal : +# 2357| m2357_4(unknown) = Chi : total:m2357_2, partial:m2357_3 +# 2357| r2357_5(glval) = VariableAddress[b] : +# 2357| m2357_6(bool) = InitializeParameter[b] : &:r2357_5 +# 2358| r2358_1(glval) = VariableAddress[s] : +# 2358| m2358_2(String) = Uninitialized[s] : &:r2358_1 +# 2358| m2358_3(unknown) = Chi : total:m2357_4, partial:m2358_2 +# 2358| r2358_4(glval) = FunctionAddress[String] : +# 2358| v2358_5(void) = Call[String] : func:r2358_4, this:r2358_1 +# 2358| m2358_6(unknown) = ^CallSideEffect : ~m2358_3 +# 2358| m2358_7(unknown) = Chi : total:m2358_3, partial:m2358_6 +# 2358| m2358_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2358_1 +# 2358| m2358_9(unknown) = Chi : total:m2358_7, partial:m2358_8 +# 2359| r2359_1(glval) = VariableAddress[b] : +# 2359| r2359_2(bool) = Load[b] : &:r2359_1, m2357_6 +# 2359| v2359_3(void) = ConditionalBranch : r2359_2 #-----| False -> Block 3 #-----| True -> Block 2 -# 2356| Block 1 -# 2356| m2356_7(unknown) = Phi : from 2:~m2365_8, from 4:~m2365_16, from 5:~m2365_25 -# 2356| v2356_8(void) = ReturnVoid : -# 2356| v2356_9(void) = AliasedUse : ~m2356_7 -# 2356| v2356_10(void) = ExitFunction : - -# 2359| Block 2 -# 2359| v2359_1(void) = NoOp : -# 2365| r2365_1(glval) = VariableAddress[s] : -# 2365| r2365_2(glval) = FunctionAddress[~String] : -# 2365| v2365_3(void) = Call[~String] : func:r2365_2, this:r2365_1 -# 2365| m2365_4(unknown) = ^CallSideEffect : ~m2357_9 -# 2365| m2365_5(unknown) = Chi : total:m2357_9, partial:m2365_4 -# 2365| v2365_6(void) = ^IndirectReadSideEffect[-1] : &:r2365_1, ~m2365_5 -# 2365| m2365_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2365_1 -# 2365| m2365_8(unknown) = Chi : total:m2365_5, partial:m2365_7 +# 2357| Block 1 +# 2357| m2357_7(unknown) = Phi : from 2:~m2366_8, from 4:~m2366_16, from 5:~m2366_25 +# 2357| v2357_8(void) = ReturnVoid : +# 2357| v2357_9(void) = AliasedUse : ~m2357_7 +# 2357| v2357_10(void) = ExitFunction : + +# 2360| Block 2 +# 2360| v2360_1(void) = NoOp : +# 2366| r2366_1(glval) = VariableAddress[s] : +# 2366| r2366_2(glval) = FunctionAddress[~String] : +# 2366| v2366_3(void) = Call[~String] : func:r2366_2, this:r2366_1 +# 2366| m2366_4(unknown) = ^CallSideEffect : ~m2358_9 +# 2366| m2366_5(unknown) = Chi : total:m2358_9, partial:m2366_4 +# 2366| v2366_6(void) = ^IndirectReadSideEffect[-1] : &:r2366_1, ~m2366_5 +# 2366| m2366_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2366_1 +# 2366| m2366_8(unknown) = Chi : total:m2366_5, partial:m2366_7 #-----| Goto -> Block 1 -# 2361| Block 3 -# 2361| r2361_1(glval) = VariableAddress[b] : -# 2361| r2361_2(bool) = Load[b] : &:r2361_1, m2356_6 -# 2361| v2361_3(void) = ConditionalBranch : r2361_2 +# 2362| Block 3 +# 2362| r2362_1(glval) = VariableAddress[b] : +# 2362| r2362_2(bool) = Load[b] : &:r2362_1, m2357_6 +# 2362| v2362_3(void) = ConditionalBranch : r2362_2 #-----| False -> Block 5 #-----| True -> Block 4 -# 2362| Block 4 -# 2362| r2362_1(glval) = FunctionAddress[VoidFunc] : -# 2362| v2362_2(void) = Call[VoidFunc] : func:r2362_1 -# 2362| m2362_3(unknown) = ^CallSideEffect : ~m2357_9 -# 2362| m2362_4(unknown) = Chi : total:m2357_9, partial:m2362_3 -# 2362| v2362_5(void) = NoOp : -# 2365| r2365_9(glval) = VariableAddress[s] : -# 2365| r2365_10(glval) = FunctionAddress[~String] : -# 2365| v2365_11(void) = Call[~String] : func:r2365_10, this:r2365_9 -# 2365| m2365_12(unknown) = ^CallSideEffect : ~m2362_4 -# 2365| m2365_13(unknown) = Chi : total:m2362_4, partial:m2365_12 -# 2365| v2365_14(void) = ^IndirectReadSideEffect[-1] : &:r2365_9, ~m2365_13 -# 2365| m2365_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r2365_9 -# 2365| m2365_16(unknown) = Chi : total:m2365_13, partial:m2365_15 +# 2363| Block 4 +# 2363| r2363_1(glval) = FunctionAddress[VoidFunc] : +# 2363| v2363_2(void) = Call[VoidFunc] : func:r2363_1 +# 2363| m2363_3(unknown) = ^CallSideEffect : ~m2358_9 +# 2363| m2363_4(unknown) = Chi : total:m2358_9, partial:m2363_3 +# 2363| v2363_5(void) = NoOp : +# 2366| r2366_9(glval) = VariableAddress[s] : +# 2366| r2366_10(glval) = FunctionAddress[~String] : +# 2366| v2366_11(void) = Call[~String] : func:r2366_10, this:r2366_9 +# 2366| m2366_12(unknown) = ^CallSideEffect : ~m2363_4 +# 2366| m2366_13(unknown) = Chi : total:m2363_4, partial:m2366_12 +# 2366| v2366_14(void) = ^IndirectReadSideEffect[-1] : &:r2366_9, ~m2366_13 +# 2366| m2366_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r2366_9 +# 2366| m2366_16(unknown) = Chi : total:m2366_13, partial:m2366_15 #-----| Goto -> Block 1 -# 2364| Block 5 -# 2364| r2364_1(glval) = VariableAddress[s] : -# 2365| v2365_17(void) = NoOp : -# 2365| r2365_18(glval) = VariableAddress[s] : -# 2365| r2365_19(glval) = FunctionAddress[~String] : -# 2365| v2365_20(void) = Call[~String] : func:r2365_19, this:r2365_18 -# 2365| m2365_21(unknown) = ^CallSideEffect : ~m2357_9 -# 2365| m2365_22(unknown) = Chi : total:m2357_9, partial:m2365_21 -# 2365| v2365_23(void) = ^IndirectReadSideEffect[-1] : &:r2365_18, ~m2365_22 -# 2365| m2365_24(String) = ^IndirectMayWriteSideEffect[-1] : &:r2365_18 -# 2365| m2365_25(unknown) = Chi : total:m2365_22, partial:m2365_24 +# 2365| Block 5 +# 2365| r2365_1(glval) = VariableAddress[s] : +# 2366| v2366_17(void) = NoOp : +# 2366| r2366_18(glval) = VariableAddress[s] : +# 2366| r2366_19(glval) = FunctionAddress[~String] : +# 2366| v2366_20(void) = Call[~String] : func:r2366_19, this:r2366_18 +# 2366| m2366_21(unknown) = ^CallSideEffect : ~m2358_9 +# 2366| m2366_22(unknown) = Chi : total:m2358_9, partial:m2366_21 +# 2366| v2366_23(void) = ^IndirectReadSideEffect[-1] : &:r2366_18, ~m2366_22 +# 2366| m2366_24(String) = ^IndirectMayWriteSideEffect[-1] : &:r2366_18 +# 2366| m2366_25(unknown) = Chi : total:m2366_22, partial:m2366_24 #-----| Goto -> Block 1 -# 2367| int IfReturnDestructors3(bool) -# 2367| Block 0 -# 2367| v2367_1(void) = EnterFunction : -# 2367| m2367_2(unknown) = AliasedDefinition : -# 2367| m2367_3(unknown) = InitializeNonLocal : -# 2367| m2367_4(unknown) = Chi : total:m2367_2, partial:m2367_3 -# 2367| r2367_5(glval) = VariableAddress[b] : -# 2367| m2367_6(bool) = InitializeParameter[b] : &:r2367_5 -# 2368| r2368_1(glval) = VariableAddress[s] : -# 2368| m2368_2(String) = Uninitialized[s] : &:r2368_1 -# 2368| m2368_3(unknown) = Chi : total:m2367_4, partial:m2368_2 -# 2368| r2368_4(glval) = FunctionAddress[String] : -# 2368| v2368_5(void) = Call[String] : func:r2368_4, this:r2368_1 -# 2368| m2368_6(unknown) = ^CallSideEffect : ~m2368_3 -# 2368| m2368_7(unknown) = Chi : total:m2368_3, partial:m2368_6 -# 2368| m2368_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2368_1 -# 2368| m2368_9(unknown) = Chi : total:m2368_7, partial:m2368_8 -# 2369| r2369_1(glval) = VariableAddress[b] : -# 2369| r2369_2(bool) = Load[b] : &:r2369_1, m2367_6 -# 2369| v2369_3(void) = ConditionalBranch : r2369_2 +# 2368| int IfReturnDestructors3(bool) +# 2368| Block 0 +# 2368| v2368_1(void) = EnterFunction : +# 2368| m2368_2(unknown) = AliasedDefinition : +# 2368| m2368_3(unknown) = InitializeNonLocal : +# 2368| m2368_4(unknown) = Chi : total:m2368_2, partial:m2368_3 +# 2368| r2368_5(glval) = VariableAddress[b] : +# 2368| m2368_6(bool) = InitializeParameter[b] : &:r2368_5 +# 2369| r2369_1(glval) = VariableAddress[s] : +# 2369| m2369_2(String) = Uninitialized[s] : &:r2369_1 +# 2369| m2369_3(unknown) = Chi : total:m2368_4, partial:m2369_2 +# 2369| r2369_4(glval) = FunctionAddress[String] : +# 2369| v2369_5(void) = Call[String] : func:r2369_4, this:r2369_1 +# 2369| m2369_6(unknown) = ^CallSideEffect : ~m2369_3 +# 2369| m2369_7(unknown) = Chi : total:m2369_3, partial:m2369_6 +# 2369| m2369_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2369_1 +# 2369| m2369_9(unknown) = Chi : total:m2369_7, partial:m2369_8 +# 2370| r2370_1(glval) = VariableAddress[b] : +# 2370| r2370_2(bool) = Load[b] : &:r2370_1, m2368_6 +# 2370| v2370_3(void) = ConditionalBranch : r2370_2 #-----| False -> Block 3 #-----| True -> Block 2 -# 2367| Block 1 -# 2367| m2367_7(unknown) = Phi : from 2:~m2373_8, from 3:~m2373_16 -# 2367| m2367_8(int) = Phi : from 2:m2370_3, from 3:m2372_3 -# 2367| r2367_9(glval) = VariableAddress[#return] : -# 2367| v2367_10(void) = ReturnValue : &:r2367_9, m2367_8 -# 2367| v2367_11(void) = AliasedUse : ~m2367_7 -# 2367| v2367_12(void) = ExitFunction : - -# 2370| Block 2 -# 2370| r2370_1(glval) = VariableAddress[#return] : -# 2370| r2370_2(int) = Constant[1] : -# 2370| m2370_3(int) = Store[#return] : &:r2370_1, r2370_2 -# 2373| r2373_1(glval) = VariableAddress[s] : -# 2373| r2373_2(glval) = FunctionAddress[~String] : -# 2373| v2373_3(void) = Call[~String] : func:r2373_2, this:r2373_1 -# 2373| m2373_4(unknown) = ^CallSideEffect : ~m2368_9 -# 2373| m2373_5(unknown) = Chi : total:m2368_9, partial:m2373_4 -# 2373| v2373_6(void) = ^IndirectReadSideEffect[-1] : &:r2373_1, ~m2373_5 -# 2373| m2373_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2373_1 -# 2373| m2373_8(unknown) = Chi : total:m2373_5, partial:m2373_7 +# 2368| Block 1 +# 2368| m2368_7(unknown) = Phi : from 2:~m2374_8, from 3:~m2374_16 +# 2368| m2368_8(int) = Phi : from 2:m2371_3, from 3:m2373_3 +# 2368| r2368_9(glval) = VariableAddress[#return] : +# 2368| v2368_10(void) = ReturnValue : &:r2368_9, m2368_8 +# 2368| v2368_11(void) = AliasedUse : ~m2368_7 +# 2368| v2368_12(void) = ExitFunction : + +# 2371| Block 2 +# 2371| r2371_1(glval) = VariableAddress[#return] : +# 2371| r2371_2(int) = Constant[1] : +# 2371| m2371_3(int) = Store[#return] : &:r2371_1, r2371_2 +# 2374| r2374_1(glval) = VariableAddress[s] : +# 2374| r2374_2(glval) = FunctionAddress[~String] : +# 2374| v2374_3(void) = Call[~String] : func:r2374_2, this:r2374_1 +# 2374| m2374_4(unknown) = ^CallSideEffect : ~m2369_9 +# 2374| m2374_5(unknown) = Chi : total:m2369_9, partial:m2374_4 +# 2374| v2374_6(void) = ^IndirectReadSideEffect[-1] : &:r2374_1, ~m2374_5 +# 2374| m2374_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2374_1 +# 2374| m2374_8(unknown) = Chi : total:m2374_5, partial:m2374_7 #-----| Goto -> Block 1 -# 2372| Block 3 -# 2372| r2372_1(glval) = VariableAddress[#return] : -# 2372| r2372_2(int) = Constant[0] : -# 2372| m2372_3(int) = Store[#return] : &:r2372_1, r2372_2 -# 2373| r2373_9(glval) = VariableAddress[s] : -# 2373| r2373_10(glval) = FunctionAddress[~String] : -# 2373| v2373_11(void) = Call[~String] : func:r2373_10, this:r2373_9 -# 2373| m2373_12(unknown) = ^CallSideEffect : ~m2368_9 -# 2373| m2373_13(unknown) = Chi : total:m2368_9, partial:m2373_12 -# 2373| v2373_14(void) = ^IndirectReadSideEffect[-1] : &:r2373_9, ~m2373_13 -# 2373| m2373_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r2373_9 -# 2373| m2373_16(unknown) = Chi : total:m2373_13, partial:m2373_15 +# 2373| Block 3 +# 2373| r2373_1(glval) = VariableAddress[#return] : +# 2373| r2373_2(int) = Constant[0] : +# 2373| m2373_3(int) = Store[#return] : &:r2373_1, r2373_2 +# 2374| r2374_9(glval) = VariableAddress[s] : +# 2374| r2374_10(glval) = FunctionAddress[~String] : +# 2374| v2374_11(void) = Call[~String] : func:r2374_10, this:r2374_9 +# 2374| m2374_12(unknown) = ^CallSideEffect : ~m2369_9 +# 2374| m2374_13(unknown) = Chi : total:m2369_9, partial:m2374_12 +# 2374| v2374_14(void) = ^IndirectReadSideEffect[-1] : &:r2374_9, ~m2374_13 +# 2374| m2374_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r2374_9 +# 2374| m2374_16(unknown) = Chi : total:m2374_13, partial:m2374_15 #-----| Goto -> Block 1 -# 2375| void VoidReturnDestructors() -# 2375| Block 0 -# 2375| v2375_1(void) = EnterFunction : -# 2375| m2375_2(unknown) = AliasedDefinition : -# 2375| m2375_3(unknown) = InitializeNonLocal : -# 2375| m2375_4(unknown) = Chi : total:m2375_2, partial:m2375_3 -# 2376| r2376_1(glval) = VariableAddress[s] : -# 2376| m2376_2(String) = Uninitialized[s] : &:r2376_1 -# 2376| m2376_3(unknown) = Chi : total:m2375_4, partial:m2376_2 -# 2376| r2376_4(glval) = FunctionAddress[String] : -# 2376| v2376_5(void) = Call[String] : func:r2376_4, this:r2376_1 -# 2376| m2376_6(unknown) = ^CallSideEffect : ~m2376_3 -# 2376| m2376_7(unknown) = Chi : total:m2376_3, partial:m2376_6 -# 2376| m2376_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2376_1 -# 2376| m2376_9(unknown) = Chi : total:m2376_7, partial:m2376_8 -# 2377| r2377_1(glval) = FunctionAddress[VoidFunc] : -# 2377| v2377_2(void) = Call[VoidFunc] : func:r2377_1 -# 2377| m2377_3(unknown) = ^CallSideEffect : ~m2376_9 -# 2377| m2377_4(unknown) = Chi : total:m2376_9, partial:m2377_3 -# 2377| v2377_5(void) = NoOp : -# 2378| r2378_1(glval) = VariableAddress[s] : -# 2378| r2378_2(glval) = FunctionAddress[~String] : -# 2378| v2378_3(void) = Call[~String] : func:r2378_2, this:r2378_1 -# 2378| m2378_4(unknown) = ^CallSideEffect : ~m2377_4 -# 2378| m2378_5(unknown) = Chi : total:m2377_4, partial:m2378_4 -# 2378| v2378_6(void) = ^IndirectReadSideEffect[-1] : &:r2378_1, ~m2378_5 -# 2378| m2378_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2378_1 -# 2378| m2378_8(unknown) = Chi : total:m2378_5, partial:m2378_7 -# 2375| v2375_5(void) = ReturnVoid : -# 2375| v2375_6(void) = AliasedUse : ~m2378_5 -# 2375| v2375_7(void) = ExitFunction : - -# 2388| return_routine_type::VoidToIntMemberFunc return_routine_type::GetVoidToIntFunc() -# 2388| Block 0 -# 2388| v2388_1(void) = EnterFunction : -# 2388| m2388_2(unknown) = AliasedDefinition : -# 2388| m2388_3(unknown) = InitializeNonLocal : -# 2388| m2388_4(unknown) = Chi : total:m2388_2, partial:m2388_3 -# 2390| r2390_1(glval<..:: *>) = VariableAddress[#return] : -# 2390| r2390_2(..()(..)) = FunctionAddress[VoidToInt] : -# 2390| m2390_3(..:: *) = Store[#return] : &:r2390_1, r2390_2 -# 2388| r2388_5(glval<..:: *>) = VariableAddress[#return] : -# 2388| v2388_6(void) = ReturnValue : &:r2388_5, m2390_3 -# 2388| v2388_7(void) = AliasedUse : m2388_3 -# 2388| v2388_8(void) = ExitFunction : - -# 2395| int small_operation_should_not_be_constant_folded() -# 2395| Block 0 -# 2395| v2395_1(void) = EnterFunction : -# 2395| m2395_2(unknown) = AliasedDefinition : -# 2395| m2395_3(unknown) = InitializeNonLocal : -# 2395| m2395_4(unknown) = Chi : total:m2395_2, partial:m2395_3 -# 2396| r2396_1(glval) = VariableAddress[#return] : -# 2396| r2396_2(int) = Constant[1] : -# 2396| r2396_3(int) = Constant[2] : -# 2396| r2396_4(int) = BitXor : r2396_2, r2396_3 -# 2396| m2396_5(int) = Store[#return] : &:r2396_1, r2396_4 -# 2395| r2395_5(glval) = VariableAddress[#return] : -# 2395| v2395_6(void) = ReturnValue : &:r2395_5, m2396_5 -# 2395| v2395_7(void) = AliasedUse : m2395_3 -# 2395| v2395_8(void) = ExitFunction : - -# 2406| int large_operation_should_be_constant_folded() -# 2406| Block 0 -# 2406| v2406_1(void) = EnterFunction : -# 2406| m2406_2(unknown) = AliasedDefinition : -# 2406| m2406_3(unknown) = InitializeNonLocal : -# 2406| m2406_4(unknown) = Chi : total:m2406_2, partial:m2406_3 -# 2407| r2407_1(glval) = VariableAddress[#return] : -# 2407| r2407_2(int) = Constant[0] : -# 2407| m2407_3(int) = Store[#return] : &:r2407_1, r2407_2 -# 2406| r2406_5(glval) = VariableAddress[#return] : -# 2406| v2406_6(void) = ReturnValue : &:r2406_5, m2407_3 -# 2406| v2406_7(void) = AliasedUse : m2406_3 -# 2406| v2406_8(void) = ExitFunction : - -# 2410| void initialization_with_temp_destructor() -# 2410| Block 0 -# 2410| v2410_1(void) = EnterFunction : -# 2410| m2410_2(unknown) = AliasedDefinition : -# 2410| m2410_3(unknown) = InitializeNonLocal : -# 2410| m2410_4(unknown) = Chi : total:m2410_2, partial:m2410_3 -# 2411| r2411_1(glval) = VariableAddress[x] : -# 2411| r2411_2(glval) = VariableAddress[#temp2411:18] : -# 2411| m2411_3(ClassWithDestructor) = Uninitialized[#temp2411:18] : &:r2411_2 -# 2411| r2411_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2411| v2411_5(void) = Call[ClassWithDestructor] : func:r2411_4, this:r2411_2 -# 2411| m2411_6(unknown) = ^CallSideEffect : ~m2410_4 -# 2411| m2411_7(unknown) = Chi : total:m2410_4, partial:m2411_6 -# 2411| m2411_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2411_2 -# 2411| m2411_9(ClassWithDestructor) = Chi : total:m2411_3, partial:m2411_8 -# 2411| r2411_10(glval) = FunctionAddress[get_x] : -# 2411| r2411_11(char) = Call[get_x] : func:r2411_10, this:r2411_2 -# 2411| m2411_12(unknown) = ^CallSideEffect : ~m2411_7 -# 2411| m2411_13(unknown) = Chi : total:m2411_7, partial:m2411_12 -# 2411| v2411_14(void) = ^IndirectReadSideEffect[-1] : &:r2411_2, m2411_9 -# 2411| m2411_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2411_2 -# 2411| m2411_16(ClassWithDestructor) = Chi : total:m2411_9, partial:m2411_15 -# 2411| r2411_17(glval) = CopyValue : r2411_2 -# 2411| r2411_18(glval) = FunctionAddress[~ClassWithDestructor] : -# 2411| v2411_19(void) = Call[~ClassWithDestructor] : func:r2411_18, this:r2411_17 -# 2411| m2411_20(unknown) = ^CallSideEffect : ~m2411_13 -# 2411| m2411_21(unknown) = Chi : total:m2411_13, partial:m2411_20 -# 2411| v2411_22(void) = ^IndirectReadSideEffect[-1] : &:r2411_17, m2411_16 -# 2411| m2411_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2411_17 -# 2411| m2411_24(ClassWithDestructor) = Chi : total:m2411_16, partial:m2411_23 -# 2411| m2411_25(char) = Store[x] : &:r2411_1, r2411_11 -# 2411| r2411_26(glval) = VariableAddress[x] : -# 2411| r2411_27(char) = Load[x] : &:r2411_26, m2411_25 -# 2411| r2411_28(char) = Constant[0] : -# 2411| r2411_29(bool) = CompareNE : r2411_27, r2411_28 -# 2411| r2411_30(bool) = CopyValue : r2411_29 -# 2411| v2411_31(void) = ConditionalBranch : r2411_30 +# 2376| void VoidReturnDestructors() +# 2376| Block 0 +# 2376| v2376_1(void) = EnterFunction : +# 2376| m2376_2(unknown) = AliasedDefinition : +# 2376| m2376_3(unknown) = InitializeNonLocal : +# 2376| m2376_4(unknown) = Chi : total:m2376_2, partial:m2376_3 +# 2377| r2377_1(glval) = VariableAddress[s] : +# 2377| m2377_2(String) = Uninitialized[s] : &:r2377_1 +# 2377| m2377_3(unknown) = Chi : total:m2376_4, partial:m2377_2 +# 2377| r2377_4(glval) = FunctionAddress[String] : +# 2377| v2377_5(void) = Call[String] : func:r2377_4, this:r2377_1 +# 2377| m2377_6(unknown) = ^CallSideEffect : ~m2377_3 +# 2377| m2377_7(unknown) = Chi : total:m2377_3, partial:m2377_6 +# 2377| m2377_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2377_1 +# 2377| m2377_9(unknown) = Chi : total:m2377_7, partial:m2377_8 +# 2378| r2378_1(glval) = FunctionAddress[VoidFunc] : +# 2378| v2378_2(void) = Call[VoidFunc] : func:r2378_1 +# 2378| m2378_3(unknown) = ^CallSideEffect : ~m2377_9 +# 2378| m2378_4(unknown) = Chi : total:m2377_9, partial:m2378_3 +# 2378| v2378_5(void) = NoOp : +# 2379| r2379_1(glval) = VariableAddress[s] : +# 2379| r2379_2(glval) = FunctionAddress[~String] : +# 2379| v2379_3(void) = Call[~String] : func:r2379_2, this:r2379_1 +# 2379| m2379_4(unknown) = ^CallSideEffect : ~m2378_4 +# 2379| m2379_5(unknown) = Chi : total:m2378_4, partial:m2379_4 +# 2379| v2379_6(void) = ^IndirectReadSideEffect[-1] : &:r2379_1, ~m2379_5 +# 2379| m2379_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2379_1 +# 2379| m2379_8(unknown) = Chi : total:m2379_5, partial:m2379_7 +# 2376| v2376_5(void) = ReturnVoid : +# 2376| v2376_6(void) = AliasedUse : ~m2379_5 +# 2376| v2376_7(void) = ExitFunction : + +# 2389| return_routine_type::VoidToIntMemberFunc return_routine_type::GetVoidToIntFunc() +# 2389| Block 0 +# 2389| v2389_1(void) = EnterFunction : +# 2389| m2389_2(unknown) = AliasedDefinition : +# 2389| m2389_3(unknown) = InitializeNonLocal : +# 2389| m2389_4(unknown) = Chi : total:m2389_2, partial:m2389_3 +# 2391| r2391_1(glval<..:: *>) = VariableAddress[#return] : +# 2391| r2391_2(..()(..)) = FunctionAddress[VoidToInt] : +# 2391| m2391_3(..:: *) = Store[#return] : &:r2391_1, r2391_2 +# 2389| r2389_5(glval<..:: *>) = VariableAddress[#return] : +# 2389| v2389_6(void) = ReturnValue : &:r2389_5, m2391_3 +# 2389| v2389_7(void) = AliasedUse : m2389_3 +# 2389| v2389_8(void) = ExitFunction : + +# 2396| int small_operation_should_not_be_constant_folded() +# 2396| Block 0 +# 2396| v2396_1(void) = EnterFunction : +# 2396| m2396_2(unknown) = AliasedDefinition : +# 2396| m2396_3(unknown) = InitializeNonLocal : +# 2396| m2396_4(unknown) = Chi : total:m2396_2, partial:m2396_3 +# 2397| r2397_1(glval) = VariableAddress[#return] : +# 2397| r2397_2(int) = Constant[1] : +# 2397| r2397_3(int) = Constant[2] : +# 2397| r2397_4(int) = BitXor : r2397_2, r2397_3 +# 2397| m2397_5(int) = Store[#return] : &:r2397_1, r2397_4 +# 2396| r2396_5(glval) = VariableAddress[#return] : +# 2396| v2396_6(void) = ReturnValue : &:r2396_5, m2397_5 +# 2396| v2396_7(void) = AliasedUse : m2396_3 +# 2396| v2396_8(void) = ExitFunction : + +# 2407| int large_operation_should_be_constant_folded() +# 2407| Block 0 +# 2407| v2407_1(void) = EnterFunction : +# 2407| m2407_2(unknown) = AliasedDefinition : +# 2407| m2407_3(unknown) = InitializeNonLocal : +# 2407| m2407_4(unknown) = Chi : total:m2407_2, partial:m2407_3 +# 2408| r2408_1(glval) = VariableAddress[#return] : +# 2408| r2408_2(int) = Constant[0] : +# 2408| m2408_3(int) = Store[#return] : &:r2408_1, r2408_2 +# 2407| r2407_5(glval) = VariableAddress[#return] : +# 2407| v2407_6(void) = ReturnValue : &:r2407_5, m2408_3 +# 2407| v2407_7(void) = AliasedUse : m2407_3 +# 2407| v2407_8(void) = ExitFunction : + +# 2411| void initialization_with_temp_destructor() +# 2411| Block 0 +# 2411| v2411_1(void) = EnterFunction : +# 2411| m2411_2(unknown) = AliasedDefinition : +# 2411| m2411_3(unknown) = InitializeNonLocal : +# 2411| m2411_4(unknown) = Chi : total:m2411_2, partial:m2411_3 +# 2412| r2412_1(glval) = VariableAddress[x] : +# 2412| r2412_2(glval) = VariableAddress[#temp2412:18] : +# 2412| m2412_3(ClassWithDestructor) = Uninitialized[#temp2412:18] : &:r2412_2 +# 2412| r2412_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2412| v2412_5(void) = Call[ClassWithDestructor] : func:r2412_4, this:r2412_2 +# 2412| m2412_6(unknown) = ^CallSideEffect : ~m2411_4 +# 2412| m2412_7(unknown) = Chi : total:m2411_4, partial:m2412_6 +# 2412| m2412_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2412_2 +# 2412| m2412_9(ClassWithDestructor) = Chi : total:m2412_3, partial:m2412_8 +# 2412| r2412_10(glval) = FunctionAddress[get_x] : +# 2412| r2412_11(char) = Call[get_x] : func:r2412_10, this:r2412_2 +# 2412| m2412_12(unknown) = ^CallSideEffect : ~m2412_7 +# 2412| m2412_13(unknown) = Chi : total:m2412_7, partial:m2412_12 +# 2412| v2412_14(void) = ^IndirectReadSideEffect[-1] : &:r2412_2, m2412_9 +# 2412| m2412_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2412_2 +# 2412| m2412_16(ClassWithDestructor) = Chi : total:m2412_9, partial:m2412_15 +# 2412| r2412_17(glval) = CopyValue : r2412_2 +# 2412| r2412_18(glval) = FunctionAddress[~ClassWithDestructor] : +# 2412| v2412_19(void) = Call[~ClassWithDestructor] : func:r2412_18, this:r2412_17 +# 2412| m2412_20(unknown) = ^CallSideEffect : ~m2412_13 +# 2412| m2412_21(unknown) = Chi : total:m2412_13, partial:m2412_20 +# 2412| v2412_22(void) = ^IndirectReadSideEffect[-1] : &:r2412_17, m2412_16 +# 2412| m2412_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2412_17 +# 2412| m2412_24(ClassWithDestructor) = Chi : total:m2412_16, partial:m2412_23 +# 2412| m2412_25(char) = Store[x] : &:r2412_1, r2412_11 +# 2412| r2412_26(glval) = VariableAddress[x] : +# 2412| r2412_27(char) = Load[x] : &:r2412_26, m2412_25 +# 2412| r2412_28(char) = Constant[0] : +# 2412| r2412_29(bool) = CompareNE : r2412_27, r2412_28 +# 2412| r2412_30(bool) = CopyValue : r2412_29 +# 2412| v2412_31(void) = ConditionalBranch : r2412_30 #-----| False -> Block 2 #-----| True -> Block 1 -# 2412| Block 1 -# 2412| r2412_1(glval) = VariableAddress[x] : -# 2412| r2412_2(char) = Load[x] : &:r2412_1, m2411_25 -# 2412| r2412_3(char) = Constant[1] : -# 2412| r2412_4(char) = Add : r2412_2, r2412_3 -# 2412| m2412_5(char) = Store[x] : &:r2412_1, r2412_4 +# 2413| Block 1 +# 2413| r2413_1(glval) = VariableAddress[x] : +# 2413| r2413_2(char) = Load[x] : &:r2413_1, m2412_25 +# 2413| r2413_3(char) = Constant[1] : +# 2413| r2413_4(char) = Add : r2413_2, r2413_3 +# 2413| m2413_5(char) = Store[x] : &:r2413_1, r2413_4 #-----| Goto -> Block 2 -# 2414| Block 2 -# 2414| r2414_1(glval) = VariableAddress[x] : -# 2414| r2414_2(glval) = VariableAddress[#temp2414:18] : -# 2414| m2414_3(ClassWithDestructor) = Uninitialized[#temp2414:18] : &:r2414_2 -# 2414| r2414_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2414| v2414_5(void) = Call[ClassWithDestructor] : func:r2414_4, this:r2414_2 -# 2414| m2414_6(unknown) = ^CallSideEffect : ~m2411_21 -# 2414| m2414_7(unknown) = Chi : total:m2411_21, partial:m2414_6 -# 2414| m2414_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2414_2 -# 2414| m2414_9(ClassWithDestructor) = Chi : total:m2414_3, partial:m2414_8 -# 2414| r2414_10(glval) = FunctionAddress[get_x] : -# 2414| r2414_11(char) = Call[get_x] : func:r2414_10, this:r2414_2 -# 2414| m2414_12(unknown) = ^CallSideEffect : ~m2414_7 -# 2414| m2414_13(unknown) = Chi : total:m2414_7, partial:m2414_12 -# 2414| v2414_14(void) = ^IndirectReadSideEffect[-1] : &:r2414_2, m2414_9 -# 2414| m2414_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2414_2 -# 2414| m2414_16(ClassWithDestructor) = Chi : total:m2414_9, partial:m2414_15 -# 2414| r2414_17(glval) = CopyValue : r2414_2 -# 2414| r2414_18(glval) = FunctionAddress[~ClassWithDestructor] : -# 2414| v2414_19(void) = Call[~ClassWithDestructor] : func:r2414_18, this:r2414_17 -# 2414| m2414_20(unknown) = ^CallSideEffect : ~m2414_13 -# 2414| m2414_21(unknown) = Chi : total:m2414_13, partial:m2414_20 -# 2414| v2414_22(void) = ^IndirectReadSideEffect[-1] : &:r2414_17, m2414_16 -# 2414| m2414_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2414_17 -# 2414| m2414_24(ClassWithDestructor) = Chi : total:m2414_16, partial:m2414_23 -# 2414| m2414_25(char) = Store[x] : &:r2414_1, r2414_11 -# 2414| r2414_26(glval) = VariableAddress[x] : -# 2414| r2414_27(char) = Load[x] : &:r2414_26, m2414_25 -# 2414| r2414_28(char) = Constant[0] : -# 2414| r2414_29(bool) = CompareNE : r2414_27, r2414_28 -# 2414| v2414_30(void) = ConditionalBranch : r2414_29 +# 2415| Block 2 +# 2415| r2415_1(glval) = VariableAddress[x] : +# 2415| r2415_2(glval) = VariableAddress[#temp2415:18] : +# 2415| m2415_3(ClassWithDestructor) = Uninitialized[#temp2415:18] : &:r2415_2 +# 2415| r2415_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2415| v2415_5(void) = Call[ClassWithDestructor] : func:r2415_4, this:r2415_2 +# 2415| m2415_6(unknown) = ^CallSideEffect : ~m2412_21 +# 2415| m2415_7(unknown) = Chi : total:m2412_21, partial:m2415_6 +# 2415| m2415_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2415_2 +# 2415| m2415_9(ClassWithDestructor) = Chi : total:m2415_3, partial:m2415_8 +# 2415| r2415_10(glval) = FunctionAddress[get_x] : +# 2415| r2415_11(char) = Call[get_x] : func:r2415_10, this:r2415_2 +# 2415| m2415_12(unknown) = ^CallSideEffect : ~m2415_7 +# 2415| m2415_13(unknown) = Chi : total:m2415_7, partial:m2415_12 +# 2415| v2415_14(void) = ^IndirectReadSideEffect[-1] : &:r2415_2, m2415_9 +# 2415| m2415_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2415_2 +# 2415| m2415_16(ClassWithDestructor) = Chi : total:m2415_9, partial:m2415_15 +# 2415| r2415_17(glval) = CopyValue : r2415_2 +# 2415| r2415_18(glval) = FunctionAddress[~ClassWithDestructor] : +# 2415| v2415_19(void) = Call[~ClassWithDestructor] : func:r2415_18, this:r2415_17 +# 2415| m2415_20(unknown) = ^CallSideEffect : ~m2415_13 +# 2415| m2415_21(unknown) = Chi : total:m2415_13, partial:m2415_20 +# 2415| v2415_22(void) = ^IndirectReadSideEffect[-1] : &:r2415_17, m2415_16 +# 2415| m2415_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2415_17 +# 2415| m2415_24(ClassWithDestructor) = Chi : total:m2415_16, partial:m2415_23 +# 2415| m2415_25(char) = Store[x] : &:r2415_1, r2415_11 +# 2415| r2415_26(glval) = VariableAddress[x] : +# 2415| r2415_27(char) = Load[x] : &:r2415_26, m2415_25 +# 2415| r2415_28(char) = Constant[0] : +# 2415| r2415_29(bool) = CompareNE : r2415_27, r2415_28 +# 2415| v2415_30(void) = ConditionalBranch : r2415_29 #-----| False -> Block 4 #-----| True -> Block 3 -# 2415| Block 3 -# 2415| r2415_1(glval) = VariableAddress[x] : -# 2415| r2415_2(char) = Load[x] : &:r2415_1, m2414_25 -# 2415| r2415_3(char) = Constant[1] : -# 2415| r2415_4(char) = Add : r2415_2, r2415_3 -# 2415| m2415_5(char) = Store[x] : &:r2415_1, r2415_4 +# 2416| Block 3 +# 2416| r2416_1(glval) = VariableAddress[x] : +# 2416| r2416_2(char) = Load[x] : &:r2416_1, m2415_25 +# 2416| r2416_3(char) = Constant[1] : +# 2416| r2416_4(char) = Add : r2416_2, r2416_3 +# 2416| m2416_5(char) = Store[x] : &:r2416_1, r2416_4 #-----| Goto -> Block 4 -# 2417| Block 4 -# 2417| r2417_1(glval) = VariableAddress[x] : -# 2417| r2417_2(glval) = VariableAddress[#temp2417:28] : -# 2417| m2417_3(ClassWithDestructor) = Uninitialized[#temp2417:28] : &:r2417_2 -# 2417| r2417_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2417| v2417_5(void) = Call[ClassWithDestructor] : func:r2417_4, this:r2417_2 -# 2417| m2417_6(unknown) = ^CallSideEffect : ~m2414_21 -# 2417| m2417_7(unknown) = Chi : total:m2414_21, partial:m2417_6 -# 2417| m2417_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2417_2 -# 2417| m2417_9(ClassWithDestructor) = Chi : total:m2417_3, partial:m2417_8 -# 2417| r2417_10(glval) = FunctionAddress[get_x] : -# 2417| r2417_11(char) = Call[get_x] : func:r2417_10, this:r2417_2 -# 2417| m2417_12(unknown) = ^CallSideEffect : ~m2417_7 -# 2417| m2417_13(unknown) = Chi : total:m2417_7, partial:m2417_12 -# 2417| v2417_14(void) = ^IndirectReadSideEffect[-1] : &:r2417_2, m2417_9 -# 2417| m2417_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2417_2 -# 2417| m2417_16(ClassWithDestructor) = Chi : total:m2417_9, partial:m2417_15 -# 2417| r2417_17(glval) = CopyValue : r2417_2 -# 2417| r2417_18(glval) = FunctionAddress[~ClassWithDestructor] : -# 2417| v2417_19(void) = Call[~ClassWithDestructor] : func:r2417_18, this:r2417_17 -# 2417| m2417_20(unknown) = ^CallSideEffect : ~m2417_13 -# 2417| m2417_21(unknown) = Chi : total:m2417_13, partial:m2417_20 -# 2417| v2417_22(void) = ^IndirectReadSideEffect[-1] : &:r2417_17, m2417_16 -# 2417| m2417_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2417_17 -# 2417| m2417_24(ClassWithDestructor) = Chi : total:m2417_16, partial:m2417_23 -# 2417| m2417_25(char) = Store[x] : &:r2417_1, r2417_11 -# 2417| r2417_26(bool) = Constant[1] : -# 2417| v2417_27(void) = ConditionalBranch : r2417_26 +# 2418| Block 4 +# 2418| r2418_1(glval) = VariableAddress[x] : +# 2418| r2418_2(glval) = VariableAddress[#temp2418:28] : +# 2418| m2418_3(ClassWithDestructor) = Uninitialized[#temp2418:28] : &:r2418_2 +# 2418| r2418_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2418| v2418_5(void) = Call[ClassWithDestructor] : func:r2418_4, this:r2418_2 +# 2418| m2418_6(unknown) = ^CallSideEffect : ~m2415_21 +# 2418| m2418_7(unknown) = Chi : total:m2415_21, partial:m2418_6 +# 2418| m2418_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2418_2 +# 2418| m2418_9(ClassWithDestructor) = Chi : total:m2418_3, partial:m2418_8 +# 2418| r2418_10(glval) = FunctionAddress[get_x] : +# 2418| r2418_11(char) = Call[get_x] : func:r2418_10, this:r2418_2 +# 2418| m2418_12(unknown) = ^CallSideEffect : ~m2418_7 +# 2418| m2418_13(unknown) = Chi : total:m2418_7, partial:m2418_12 +# 2418| v2418_14(void) = ^IndirectReadSideEffect[-1] : &:r2418_2, m2418_9 +# 2418| m2418_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2418_2 +# 2418| m2418_16(ClassWithDestructor) = Chi : total:m2418_9, partial:m2418_15 +# 2418| r2418_17(glval) = CopyValue : r2418_2 +# 2418| r2418_18(glval) = FunctionAddress[~ClassWithDestructor] : +# 2418| v2418_19(void) = Call[~ClassWithDestructor] : func:r2418_18, this:r2418_17 +# 2418| m2418_20(unknown) = ^CallSideEffect : ~m2418_13 +# 2418| m2418_21(unknown) = Chi : total:m2418_13, partial:m2418_20 +# 2418| v2418_22(void) = ^IndirectReadSideEffect[-1] : &:r2418_17, m2418_16 +# 2418| m2418_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2418_17 +# 2418| m2418_24(ClassWithDestructor) = Chi : total:m2418_16, partial:m2418_23 +# 2418| m2418_25(char) = Store[x] : &:r2418_1, r2418_11 +# 2418| r2418_26(bool) = Constant[1] : +# 2418| v2418_27(void) = ConditionalBranch : r2418_26 #-----| False -> Block 13 #-----| True -> Block 5 -# 2418| Block 5 -# 2418| r2418_1(glval) = VariableAddress[x] : -# 2418| r2418_2(char) = Load[x] : &:r2418_1, m2417_25 -# 2418| r2418_3(char) = Constant[1] : -# 2418| r2418_4(char) = Add : r2418_2, r2418_3 -# 2418| m2418_5(char) = Store[x] : &:r2418_1, r2418_4 -# 2420| r2420_1(glval) = VariableAddress[x] : -# 2420| r2420_2(glval) = VariableAddress[#temp2420:21] : -# 2420| m2420_3(ClassWithDestructor) = Uninitialized[#temp2420:21] : &:r2420_2 -# 2420| r2420_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2420| v2420_5(void) = Call[ClassWithDestructor] : func:r2420_4, this:r2420_2 -# 2420| m2420_6(unknown) = ^CallSideEffect : ~m2417_21 -# 2420| m2420_7(unknown) = Chi : total:m2417_21, partial:m2420_6 -# 2420| m2420_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2420_2 -# 2420| m2420_9(ClassWithDestructor) = Chi : total:m2420_3, partial:m2420_8 -# 2420| r2420_10(glval) = FunctionAddress[get_x] : -# 2420| r2420_11(char) = Call[get_x] : func:r2420_10, this:r2420_2 -# 2420| m2420_12(unknown) = ^CallSideEffect : ~m2420_7 -# 2420| m2420_13(unknown) = Chi : total:m2420_7, partial:m2420_12 -# 2420| v2420_14(void) = ^IndirectReadSideEffect[-1] : &:r2420_2, m2420_9 -# 2420| m2420_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2420_2 -# 2420| m2420_16(ClassWithDestructor) = Chi : total:m2420_9, partial:m2420_15 -# 2420| r2420_17(glval) = CopyValue : r2420_2 -# 2420| r2420_18(glval) = FunctionAddress[~ClassWithDestructor] : -# 2420| v2420_19(void) = Call[~ClassWithDestructor] : func:r2420_18, this:r2420_17 -# 2420| m2420_20(unknown) = ^CallSideEffect : ~m2420_13 -# 2420| m2420_21(unknown) = Chi : total:m2420_13, partial:m2420_20 -# 2420| v2420_22(void) = ^IndirectReadSideEffect[-1] : &:r2420_17, m2420_16 -# 2420| m2420_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2420_17 -# 2420| m2420_24(ClassWithDestructor) = Chi : total:m2420_16, partial:m2420_23 -# 2420| m2420_25(char) = Store[x] : &:r2420_1, r2420_11 -# 2420| r2420_26(glval) = VariableAddress[x] : -# 2420| r2420_27(char) = Load[x] : &:r2420_26, m2420_25 -# 2420| r2420_28(int) = Convert : r2420_27 -# 2420| r2420_29(int) = CopyValue : r2420_28 -# 2420| v2420_30(void) = Switch : r2420_29 +# 2419| Block 5 +# 2419| r2419_1(glval) = VariableAddress[x] : +# 2419| r2419_2(char) = Load[x] : &:r2419_1, m2418_25 +# 2419| r2419_3(char) = Constant[1] : +# 2419| r2419_4(char) = Add : r2419_2, r2419_3 +# 2419| m2419_5(char) = Store[x] : &:r2419_1, r2419_4 +# 2421| r2421_1(glval) = VariableAddress[x] : +# 2421| r2421_2(glval) = VariableAddress[#temp2421:21] : +# 2421| m2421_3(ClassWithDestructor) = Uninitialized[#temp2421:21] : &:r2421_2 +# 2421| r2421_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2421| v2421_5(void) = Call[ClassWithDestructor] : func:r2421_4, this:r2421_2 +# 2421| m2421_6(unknown) = ^CallSideEffect : ~m2418_21 +# 2421| m2421_7(unknown) = Chi : total:m2418_21, partial:m2421_6 +# 2421| m2421_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2421_2 +# 2421| m2421_9(ClassWithDestructor) = Chi : total:m2421_3, partial:m2421_8 +# 2421| r2421_10(glval) = FunctionAddress[get_x] : +# 2421| r2421_11(char) = Call[get_x] : func:r2421_10, this:r2421_2 +# 2421| m2421_12(unknown) = ^CallSideEffect : ~m2421_7 +# 2421| m2421_13(unknown) = Chi : total:m2421_7, partial:m2421_12 +# 2421| v2421_14(void) = ^IndirectReadSideEffect[-1] : &:r2421_2, m2421_9 +# 2421| m2421_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2421_2 +# 2421| m2421_16(ClassWithDestructor) = Chi : total:m2421_9, partial:m2421_15 +# 2421| r2421_17(glval) = CopyValue : r2421_2 +# 2421| r2421_18(glval) = FunctionAddress[~ClassWithDestructor] : +# 2421| v2421_19(void) = Call[~ClassWithDestructor] : func:r2421_18, this:r2421_17 +# 2421| m2421_20(unknown) = ^CallSideEffect : ~m2421_13 +# 2421| m2421_21(unknown) = Chi : total:m2421_13, partial:m2421_20 +# 2421| v2421_22(void) = ^IndirectReadSideEffect[-1] : &:r2421_17, m2421_16 +# 2421| m2421_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2421_17 +# 2421| m2421_24(ClassWithDestructor) = Chi : total:m2421_16, partial:m2421_23 +# 2421| m2421_25(char) = Store[x] : &:r2421_1, r2421_11 +# 2421| r2421_26(glval) = VariableAddress[x] : +# 2421| r2421_27(char) = Load[x] : &:r2421_26, m2421_25 +# 2421| r2421_28(int) = Convert : r2421_27 +# 2421| r2421_29(int) = CopyValue : r2421_28 +# 2421| v2421_30(void) = Switch : r2421_29 #-----| Case[97] -> Block 6 #-----| Default -> Block 7 -# 2421| Block 6 -# 2421| v2421_1(void) = NoOp : -# 2422| r2422_1(glval) = VariableAddress[x] : -# 2422| r2422_2(char) = Load[x] : &:r2422_1, m2420_25 -# 2422| r2422_3(char) = Constant[1] : -# 2422| r2422_4(char) = Add : r2422_2, r2422_3 -# 2422| m2422_5(char) = Store[x] : &:r2422_1, r2422_4 +# 2422| Block 6 +# 2422| v2422_1(void) = NoOp : +# 2423| r2423_1(glval) = VariableAddress[x] : +# 2423| r2423_2(char) = Load[x] : &:r2423_1, m2421_25 +# 2423| r2423_3(char) = Constant[1] : +# 2423| r2423_4(char) = Add : r2423_2, r2423_3 +# 2423| m2423_5(char) = Store[x] : &:r2423_1, r2423_4 #-----| Goto -> Block 7 -# 2425| Block 7 -# 2425| r2425_1(glval) = VariableAddress[x] : -# 2425| r2425_2(glval) = VariableAddress[#temp2425:21] : -# 2425| m2425_3(ClassWithDestructor) = Uninitialized[#temp2425:21] : &:r2425_2 -# 2425| r2425_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2425| v2425_5(void) = Call[ClassWithDestructor] : func:r2425_4, this:r2425_2 -# 2425| m2425_6(unknown) = ^CallSideEffect : ~m2420_21 -# 2425| m2425_7(unknown) = Chi : total:m2420_21, partial:m2425_6 -# 2425| m2425_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2425_2 -# 2425| m2425_9(ClassWithDestructor) = Chi : total:m2425_3, partial:m2425_8 -# 2425| r2425_10(glval) = FunctionAddress[get_x] : -# 2425| r2425_11(char) = Call[get_x] : func:r2425_10, this:r2425_2 -# 2425| m2425_12(unknown) = ^CallSideEffect : ~m2425_7 -# 2425| m2425_13(unknown) = Chi : total:m2425_7, partial:m2425_12 -# 2425| v2425_14(void) = ^IndirectReadSideEffect[-1] : &:r2425_2, m2425_9 -# 2425| m2425_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2425_2 -# 2425| m2425_16(ClassWithDestructor) = Chi : total:m2425_9, partial:m2425_15 -# 2425| r2425_17(glval) = CopyValue : r2425_2 -# 2425| r2425_18(glval) = FunctionAddress[~ClassWithDestructor] : -# 2425| v2425_19(void) = Call[~ClassWithDestructor] : func:r2425_18, this:r2425_17 -# 2425| m2425_20(unknown) = ^CallSideEffect : ~m2425_13 -# 2425| m2425_21(unknown) = Chi : total:m2425_13, partial:m2425_20 -# 2425| v2425_22(void) = ^IndirectReadSideEffect[-1] : &:r2425_17, m2425_16 -# 2425| m2425_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2425_17 -# 2425| m2425_24(ClassWithDestructor) = Chi : total:m2425_16, partial:m2425_23 -# 2425| m2425_25(char) = Store[x] : &:r2425_1, r2425_11 -# 2425| r2425_26(glval) = VariableAddress[x] : -# 2425| r2425_27(char) = Load[x] : &:r2425_26, m2425_25 -# 2425| r2425_28(int) = Convert : r2425_27 -# 2425| v2425_29(void) = Switch : r2425_28 +# 2426| Block 7 +# 2426| r2426_1(glval) = VariableAddress[x] : +# 2426| r2426_2(glval) = VariableAddress[#temp2426:21] : +# 2426| m2426_3(ClassWithDestructor) = Uninitialized[#temp2426:21] : &:r2426_2 +# 2426| r2426_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2426| v2426_5(void) = Call[ClassWithDestructor] : func:r2426_4, this:r2426_2 +# 2426| m2426_6(unknown) = ^CallSideEffect : ~m2421_21 +# 2426| m2426_7(unknown) = Chi : total:m2421_21, partial:m2426_6 +# 2426| m2426_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2426_2 +# 2426| m2426_9(ClassWithDestructor) = Chi : total:m2426_3, partial:m2426_8 +# 2426| r2426_10(glval) = FunctionAddress[get_x] : +# 2426| r2426_11(char) = Call[get_x] : func:r2426_10, this:r2426_2 +# 2426| m2426_12(unknown) = ^CallSideEffect : ~m2426_7 +# 2426| m2426_13(unknown) = Chi : total:m2426_7, partial:m2426_12 +# 2426| v2426_14(void) = ^IndirectReadSideEffect[-1] : &:r2426_2, m2426_9 +# 2426| m2426_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2426_2 +# 2426| m2426_16(ClassWithDestructor) = Chi : total:m2426_9, partial:m2426_15 +# 2426| r2426_17(glval) = CopyValue : r2426_2 +# 2426| r2426_18(glval) = FunctionAddress[~ClassWithDestructor] : +# 2426| v2426_19(void) = Call[~ClassWithDestructor] : func:r2426_18, this:r2426_17 +# 2426| m2426_20(unknown) = ^CallSideEffect : ~m2426_13 +# 2426| m2426_21(unknown) = Chi : total:m2426_13, partial:m2426_20 +# 2426| v2426_22(void) = ^IndirectReadSideEffect[-1] : &:r2426_17, m2426_16 +# 2426| m2426_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2426_17 +# 2426| m2426_24(ClassWithDestructor) = Chi : total:m2426_16, partial:m2426_23 +# 2426| m2426_25(char) = Store[x] : &:r2426_1, r2426_11 +# 2426| r2426_26(glval) = VariableAddress[x] : +# 2426| r2426_27(char) = Load[x] : &:r2426_26, m2426_25 +# 2426| r2426_28(int) = Convert : r2426_27 +# 2426| v2426_29(void) = Switch : r2426_28 #-----| Case[97] -> Block 8 #-----| Default -> Block 9 -# 2426| Block 8 -# 2426| v2426_1(void) = NoOp : -# 2427| r2427_1(glval) = VariableAddress[x] : -# 2427| r2427_2(char) = Load[x] : &:r2427_1, m2425_25 -# 2427| r2427_3(char) = Constant[1] : -# 2427| r2427_4(char) = Add : r2427_2, r2427_3 -# 2427| m2427_5(char) = Store[x] : &:r2427_1, r2427_4 +# 2427| Block 8 +# 2427| v2427_1(void) = NoOp : +# 2428| r2428_1(glval) = VariableAddress[x] : +# 2428| r2428_2(char) = Load[x] : &:r2428_1, m2426_25 +# 2428| r2428_3(char) = Constant[1] : +# 2428| r2428_4(char) = Add : r2428_2, r2428_3 +# 2428| m2428_5(char) = Store[x] : &:r2428_1, r2428_4 #-----| Goto -> Block 9 -# 2430| Block 9 -# 2430| r2430_1(glval) = VariableAddress[x] : -# 2430| r2430_2(glval) = VariableAddress[#temp2430:18] : -# 2430| m2430_3(ClassWithDestructor) = Uninitialized[#temp2430:18] : &:r2430_2 -# 2430| r2430_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2430| v2430_5(void) = Call[ClassWithDestructor] : func:r2430_4, this:r2430_2 -# 2430| m2430_6(unknown) = ^CallSideEffect : ~m2425_21 -# 2430| m2430_7(unknown) = Chi : total:m2425_21, partial:m2430_6 -# 2430| m2430_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2430_2 -# 2430| m2430_9(ClassWithDestructor) = Chi : total:m2430_3, partial:m2430_8 -# 2430| r2430_10(glval) = FunctionAddress[get_x] : -# 2430| r2430_11(char) = Call[get_x] : func:r2430_10, this:r2430_2 -# 2430| m2430_12(unknown) = ^CallSideEffect : ~m2430_7 -# 2430| m2430_13(unknown) = Chi : total:m2430_7, partial:m2430_12 -# 2430| v2430_14(void) = ^IndirectReadSideEffect[-1] : &:r2430_2, m2430_9 -# 2430| m2430_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2430_2 -# 2430| m2430_16(ClassWithDestructor) = Chi : total:m2430_9, partial:m2430_15 -# 2430| r2430_17(glval) = CopyValue : r2430_2 -# 2430| r2430_18(glval) = FunctionAddress[~ClassWithDestructor] : -# 2430| v2430_19(void) = Call[~ClassWithDestructor] : func:r2430_18, this:r2430_17 -# 2430| m2430_20(unknown) = ^CallSideEffect : ~m2430_13 -# 2430| m2430_21(unknown) = Chi : total:m2430_13, partial:m2430_20 -# 2430| v2430_22(void) = ^IndirectReadSideEffect[-1] : &:r2430_17, m2430_16 -# 2430| m2430_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2430_17 -# 2430| m2430_24(ClassWithDestructor) = Chi : total:m2430_16, partial:m2430_23 -# 2430| m2430_25(char) = Store[x] : &:r2430_1, r2430_11 -# 2430| r2430_26(glval &&>) = VariableAddress[(__range)] : -# 2430| r2430_27(glval>) = VariableAddress[#temp2430:58] : -# 2430| m2430_28(vector) = Uninitialized[#temp2430:58] : &:r2430_27 -# 2430| m2430_29(unknown) = Chi : total:m2430_21, partial:m2430_28 -# 2430| r2430_30(glval) = FunctionAddress[vector] : -# 2430| r2430_31(glval) = VariableAddress[x] : -# 2430| r2430_32(char) = Load[x] : &:r2430_31, m2430_25 -# 2430| v2430_33(void) = Call[vector] : func:r2430_30, this:r2430_27, 0:r2430_32 -# 2430| m2430_34(unknown) = ^CallSideEffect : ~m2430_29 -# 2430| m2430_35(unknown) = Chi : total:m2430_29, partial:m2430_34 -# 2430| m2430_36(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2430_27 -# 2430| m2430_37(unknown) = Chi : total:m2430_35, partial:m2430_36 -# 2430| r2430_38(vector &) = CopyValue : r2430_27 -# 2430| m2430_39(vector &&) = Store[(__range)] : &:r2430_26, r2430_38 -# 2430| r2430_40(glval>) = VariableAddress[(__begin)] : -# 2430| r2430_41(glval &&>) = VariableAddress[(__range)] : -# 2430| r2430_42(vector &&) = Load[(__range)] : &:r2430_41, m2430_39 -#-----| r0_1(glval>) = CopyValue : r2430_42 +# 2431| Block 9 +# 2431| r2431_1(glval) = VariableAddress[x] : +# 2431| r2431_2(glval) = VariableAddress[#temp2431:18] : +# 2431| m2431_3(ClassWithDestructor) = Uninitialized[#temp2431:18] : &:r2431_2 +# 2431| r2431_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2431| v2431_5(void) = Call[ClassWithDestructor] : func:r2431_4, this:r2431_2 +# 2431| m2431_6(unknown) = ^CallSideEffect : ~m2426_21 +# 2431| m2431_7(unknown) = Chi : total:m2426_21, partial:m2431_6 +# 2431| m2431_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2431_2 +# 2431| m2431_9(ClassWithDestructor) = Chi : total:m2431_3, partial:m2431_8 +# 2431| r2431_10(glval) = FunctionAddress[get_x] : +# 2431| r2431_11(char) = Call[get_x] : func:r2431_10, this:r2431_2 +# 2431| m2431_12(unknown) = ^CallSideEffect : ~m2431_7 +# 2431| m2431_13(unknown) = Chi : total:m2431_7, partial:m2431_12 +# 2431| v2431_14(void) = ^IndirectReadSideEffect[-1] : &:r2431_2, m2431_9 +# 2431| m2431_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2431_2 +# 2431| m2431_16(ClassWithDestructor) = Chi : total:m2431_9, partial:m2431_15 +# 2431| r2431_17(glval) = CopyValue : r2431_2 +# 2431| r2431_18(glval) = FunctionAddress[~ClassWithDestructor] : +# 2431| v2431_19(void) = Call[~ClassWithDestructor] : func:r2431_18, this:r2431_17 +# 2431| m2431_20(unknown) = ^CallSideEffect : ~m2431_13 +# 2431| m2431_21(unknown) = Chi : total:m2431_13, partial:m2431_20 +# 2431| v2431_22(void) = ^IndirectReadSideEffect[-1] : &:r2431_17, m2431_16 +# 2431| m2431_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2431_17 +# 2431| m2431_24(ClassWithDestructor) = Chi : total:m2431_16, partial:m2431_23 +# 2431| m2431_25(char) = Store[x] : &:r2431_1, r2431_11 +# 2431| r2431_26(glval &&>) = VariableAddress[(__range)] : +# 2431| r2431_27(glval>) = VariableAddress[#temp2431:58] : +# 2431| m2431_28(vector) = Uninitialized[#temp2431:58] : &:r2431_27 +# 2431| m2431_29(unknown) = Chi : total:m2431_21, partial:m2431_28 +# 2431| r2431_30(glval) = FunctionAddress[vector] : +# 2431| r2431_31(glval) = VariableAddress[x] : +# 2431| r2431_32(char) = Load[x] : &:r2431_31, m2431_25 +# 2431| v2431_33(void) = Call[vector] : func:r2431_30, this:r2431_27, 0:r2431_32 +# 2431| m2431_34(unknown) = ^CallSideEffect : ~m2431_29 +# 2431| m2431_35(unknown) = Chi : total:m2431_29, partial:m2431_34 +# 2431| m2431_36(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2431_27 +# 2431| m2431_37(unknown) = Chi : total:m2431_35, partial:m2431_36 +# 2431| r2431_38(vector &) = CopyValue : r2431_27 +# 2431| m2431_39(vector &&) = Store[(__range)] : &:r2431_26, r2431_38 +# 2431| r2431_40(glval>) = VariableAddress[(__begin)] : +# 2431| r2431_41(glval &&>) = VariableAddress[(__range)] : +# 2431| r2431_42(vector &&) = Load[(__range)] : &:r2431_41, m2431_39 +#-----| r0_1(glval>) = CopyValue : r2431_42 #-----| r0_2(glval>) = Convert : r0_1 -# 2430| r2430_43(glval) = FunctionAddress[begin] : -# 2430| r2430_44(iterator) = Call[begin] : func:r2430_43, this:r0_2 -#-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m2430_37 -# 2430| m2430_45(iterator) = Store[(__begin)] : &:r2430_40, r2430_44 -# 2430| r2430_46(glval>) = VariableAddress[(__end)] : -# 2430| r2430_47(glval &&>) = VariableAddress[(__range)] : -# 2430| r2430_48(vector &&) = Load[(__range)] : &:r2430_47, m2430_39 -#-----| r0_4(glval>) = CopyValue : r2430_48 +# 2431| r2431_43(glval) = FunctionAddress[begin] : +# 2431| r2431_44(iterator) = Call[begin] : func:r2431_43, this:r0_2 +#-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m2431_37 +# 2431| m2431_45(iterator) = Store[(__begin)] : &:r2431_40, r2431_44 +# 2431| r2431_46(glval>) = VariableAddress[(__end)] : +# 2431| r2431_47(glval &&>) = VariableAddress[(__range)] : +# 2431| r2431_48(vector &&) = Load[(__range)] : &:r2431_47, m2431_39 +#-----| r0_4(glval>) = CopyValue : r2431_48 #-----| r0_5(glval>) = Convert : r0_4 -# 2430| r2430_49(glval) = FunctionAddress[end] : -# 2430| r2430_50(iterator) = Call[end] : func:r2430_49, this:r0_5 -#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m2430_37 -# 2430| m2430_51(iterator) = Store[(__end)] : &:r2430_46, r2430_50 -# 2430| m2430_52(unknown) = Chi : total:m2430_37, partial:m2430_51 +# 2431| r2431_49(glval) = FunctionAddress[end] : +# 2431| r2431_50(iterator) = Call[end] : func:r2431_49, this:r0_5 +#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m2431_37 +# 2431| m2431_51(iterator) = Store[(__end)] : &:r2431_46, r2431_50 +# 2431| m2431_52(unknown) = Chi : total:m2431_37, partial:m2431_51 #-----| Goto -> Block 10 -# 2430| Block 10 -# 2430| m2430_53(iterator) = Phi : from 9:m2430_45, from 11:m2430_77 -# 2430| m2430_54(unknown) = Phi : from 9:~m2430_52, from 11:~m2430_63 -# 2430| r2430_55(glval>) = VariableAddress[(__begin)] : -#-----| r0_7(glval>) = Convert : r2430_55 -# 2430| r2430_56(glval) = FunctionAddress[operator!=] : +# 2431| Block 10 +# 2431| m2431_53(iterator) = Phi : from 9:m2431_45, from 11:m2431_77 +# 2431| m2431_54(unknown) = Phi : from 9:~m2431_52, from 11:~m2431_63 +# 2431| r2431_55(glval>) = VariableAddress[(__begin)] : +#-----| r0_7(glval>) = Convert : r2431_55 +# 2431| r2431_56(glval) = FunctionAddress[operator!=] : #-----| r0_8(glval>) = VariableAddress[#temp0:0] : #-----| m0_9(iterator) = Uninitialized[#temp0:0] : &:r0_8 -#-----| m0_10(unknown) = Chi : total:m2430_54, partial:m0_9 -# 2430| r2430_57(glval) = FunctionAddress[iterator] : -# 2430| r2430_58(glval>) = VariableAddress[(__end)] : -#-----| r0_11(glval>) = Convert : r2430_58 +#-----| m0_10(unknown) = Chi : total:m2431_54, partial:m0_9 +# 2431| r2431_57(glval) = FunctionAddress[iterator] : +# 2431| r2431_58(glval>) = VariableAddress[(__end)] : +#-----| r0_11(glval>) = Convert : r2431_58 #-----| r0_12(iterator &) = CopyValue : r0_11 -# 2430| v2430_59(void) = Call[iterator] : func:r2430_57, this:r0_8, 0:r0_12 -# 2430| m2430_60(unknown) = ^CallSideEffect : ~m0_10 -# 2430| m2430_61(unknown) = Chi : total:m0_10, partial:m2430_60 -#-----| v0_13(void) = ^BufferReadSideEffect[0] : &:r0_12, ~m2430_61 -# 2430| m2430_62(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 -# 2430| m2430_63(unknown) = Chi : total:m2430_61, partial:m2430_62 -#-----| r0_14(iterator) = Load[#temp0:0] : &:r0_8, ~m2430_63 -# 2430| r2430_64(bool) = Call[operator!=] : func:r2430_56, this:r0_7, 0:r0_14 -#-----| v0_15(void) = ^IndirectReadSideEffect[-1] : &:r0_7, m2430_53 -# 2430| v2430_65(void) = ConditionalBranch : r2430_64 +# 2431| v2431_59(void) = Call[iterator] : func:r2431_57, this:r0_8, 0:r0_12 +# 2431| m2431_60(unknown) = ^CallSideEffect : ~m0_10 +# 2431| m2431_61(unknown) = Chi : total:m0_10, partial:m2431_60 +#-----| v0_13(void) = ^BufferReadSideEffect[0] : &:r0_12, ~m2431_61 +# 2431| m2431_62(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 2431| m2431_63(unknown) = Chi : total:m2431_61, partial:m2431_62 +#-----| r0_14(iterator) = Load[#temp0:0] : &:r0_8, ~m2431_63 +# 2431| r2431_64(bool) = Call[operator!=] : func:r2431_56, this:r0_7, 0:r0_14 +#-----| v0_15(void) = ^IndirectReadSideEffect[-1] : &:r0_7, m2431_53 +# 2431| v2431_65(void) = ConditionalBranch : r2431_64 #-----| False -> Block 12 #-----| True -> Block 11 -# 2430| Block 11 -# 2430| r2430_66(glval) = VariableAddress[y] : -# 2430| r2430_67(glval>) = VariableAddress[(__begin)] : -#-----| r0_16(glval>) = Convert : r2430_67 -# 2430| r2430_68(glval) = FunctionAddress[operator*] : -# 2430| r2430_69(char &) = Call[operator*] : func:r2430_68, this:r0_16 -#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_16, m2430_53 -# 2430| r2430_70(char) = Load[?] : &:r2430_69, ~m2430_63 -# 2430| m2430_71(char) = Store[y] : &:r2430_66, r2430_70 -# 2431| r2431_1(glval) = VariableAddress[x] : -# 2431| r2431_2(char) = Load[x] : &:r2431_1, m2430_25 -# 2431| r2431_3(int) = Convert : r2431_2 -# 2431| r2431_4(glval) = VariableAddress[y] : -# 2431| r2431_5(char) = Load[y] : &:r2431_4, m2430_71 -# 2431| r2431_6(int) = Convert : r2431_5 -# 2431| r2431_7(int) = Add : r2431_6, r2431_3 -# 2431| r2431_8(char) = Convert : r2431_7 -# 2431| m2431_9(char) = Store[y] : &:r2431_4, r2431_8 -# 2430| r2430_72(glval>) = VariableAddress[(__begin)] : -# 2430| r2430_73(glval) = FunctionAddress[operator++] : -# 2430| r2430_74(iterator &) = Call[operator++] : func:r2430_73, this:r2430_72 -# 2430| v2430_75(void) = ^IndirectReadSideEffect[-1] : &:r2430_72, m2430_53 -# 2430| m2430_76(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2430_72 -# 2430| m2430_77(iterator) = Chi : total:m2430_53, partial:m2430_76 -# 2430| r2430_78(glval>) = CopyValue : r2430_74 +# 2431| Block 11 +# 2431| r2431_66(glval) = VariableAddress[y] : +# 2431| r2431_67(glval>) = VariableAddress[(__begin)] : +#-----| r0_16(glval>) = Convert : r2431_67 +# 2431| r2431_68(glval) = FunctionAddress[operator*] : +# 2431| r2431_69(char &) = Call[operator*] : func:r2431_68, this:r0_16 +#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_16, m2431_53 +# 2431| r2431_70(char) = Load[?] : &:r2431_69, ~m2431_63 +# 2431| m2431_71(char) = Store[y] : &:r2431_66, r2431_70 +# 2432| r2432_1(glval) = VariableAddress[x] : +# 2432| r2432_2(char) = Load[x] : &:r2432_1, m2431_25 +# 2432| r2432_3(int) = Convert : r2432_2 +# 2432| r2432_4(glval) = VariableAddress[y] : +# 2432| r2432_5(char) = Load[y] : &:r2432_4, m2431_71 +# 2432| r2432_6(int) = Convert : r2432_5 +# 2432| r2432_7(int) = Add : r2432_6, r2432_3 +# 2432| r2432_8(char) = Convert : r2432_7 +# 2432| m2432_9(char) = Store[y] : &:r2432_4, r2432_8 +# 2431| r2431_72(glval>) = VariableAddress[(__begin)] : +# 2431| r2431_73(glval) = FunctionAddress[operator++] : +# 2431| r2431_74(iterator &) = Call[operator++] : func:r2431_73, this:r2431_72 +# 2431| v2431_75(void) = ^IndirectReadSideEffect[-1] : &:r2431_72, m2431_53 +# 2431| m2431_76(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2431_72 +# 2431| m2431_77(iterator) = Chi : total:m2431_53, partial:m2431_76 +# 2431| r2431_78(glval>) = CopyValue : r2431_74 #-----| Goto (back edge) -> Block 10 -# 2432| Block 12 -# 2432| v2432_1(void) = NoOp : -# 2410| v2410_5(void) = ReturnVoid : -# 2410| v2410_6(void) = AliasedUse : ~m2430_61 -# 2410| v2410_7(void) = ExitFunction : - -# 2410| Block 13 -# 2410| v2410_8(void) = Unreached : - -# 2434| void param_with_destructor_by_value(ClassWithDestructor) -# 2434| Block 0 -# 2434| v2434_1(void) = EnterFunction : -# 2434| m2434_2(unknown) = AliasedDefinition : -# 2434| m2434_3(unknown) = InitializeNonLocal : -# 2434| m2434_4(unknown) = Chi : total:m2434_2, partial:m2434_3 -# 2434| r2434_5(glval) = VariableAddress[c] : -# 2434| m2434_6(ClassWithDestructor) = InitializeParameter[c] : &:r2434_5 -# 2436| v2436_1(void) = NoOp : -# 2434| v2434_7(void) = ReturnVoid : -# 2434| v2434_8(void) = AliasedUse : m2434_3 -# 2434| v2434_9(void) = ExitFunction : - -# 2438| void param_with_destructor_by_pointer(ClassWithDestructor*) -# 2438| Block 0 -# 2438| v2438_1(void) = EnterFunction : -# 2438| m2438_2(unknown) = AliasedDefinition : -# 2438| m2438_3(unknown) = InitializeNonLocal : -# 2438| m2438_4(unknown) = Chi : total:m2438_2, partial:m2438_3 -# 2438| r2438_5(glval) = VariableAddress[c] : -# 2438| m2438_6(ClassWithDestructor *) = InitializeParameter[c] : &:r2438_5 -# 2438| r2438_7(ClassWithDestructor *) = Load[c] : &:r2438_5, m2438_6 -# 2438| m2438_8(unknown) = InitializeIndirection[c] : &:r2438_7 -# 2440| v2440_1(void) = NoOp : -# 2438| v2438_9(void) = ReturnIndirection[c] : &:r2438_7, m2438_8 -# 2438| v2438_10(void) = ReturnVoid : -# 2438| v2438_11(void) = AliasedUse : m2438_3 -# 2438| v2438_12(void) = ExitFunction : - -# 2442| void param_with_destructor_by_ref(ClassWithDestructor&) -# 2442| Block 0 -# 2442| v2442_1(void) = EnterFunction : -# 2442| m2442_2(unknown) = AliasedDefinition : -# 2442| m2442_3(unknown) = InitializeNonLocal : -# 2442| m2442_4(unknown) = Chi : total:m2442_2, partial:m2442_3 -# 2442| r2442_5(glval) = VariableAddress[c] : -# 2442| m2442_6(ClassWithDestructor &) = InitializeParameter[c] : &:r2442_5 -# 2442| r2442_7(ClassWithDestructor &) = Load[c] : &:r2442_5, m2442_6 -# 2442| m2442_8(unknown) = InitializeIndirection[c] : &:r2442_7 -# 2444| v2444_1(void) = NoOp : -# 2442| v2442_9(void) = ReturnIndirection[c] : &:r2442_7, m2442_8 -# 2442| v2442_10(void) = ReturnVoid : -# 2442| v2442_11(void) = AliasedUse : m2442_3 -# 2442| v2442_12(void) = ExitFunction : - -# 2446| void param_with_destructor_by_rref(ClassWithDestructor&&) -# 2446| Block 0 -# 2446| v2446_1(void) = EnterFunction : -# 2446| m2446_2(unknown) = AliasedDefinition : -# 2446| m2446_3(unknown) = InitializeNonLocal : -# 2446| m2446_4(unknown) = Chi : total:m2446_2, partial:m2446_3 -# 2446| r2446_5(glval) = VariableAddress[c] : -# 2446| m2446_6(ClassWithDestructor &&) = InitializeParameter[c] : &:r2446_5 -# 2446| r2446_7(ClassWithDestructor &&) = Load[c] : &:r2446_5, m2446_6 -# 2446| m2446_8(unknown) = InitializeIndirection[c] : &:r2446_7 -# 2448| v2448_1(void) = NoOp : -# 2446| v2446_9(void) = ReturnIndirection[c] : &:r2446_7, m2446_8 -# 2446| v2446_10(void) = ReturnVoid : -# 2446| v2446_11(void) = AliasedUse : m2446_3 -# 2446| v2446_12(void) = ExitFunction : - -# 2450| void rethrow_with_destruction(int) -# 2450| Block 0 -# 2450| v2450_1(void) = EnterFunction : -# 2450| m2450_2(unknown) = AliasedDefinition : -# 2450| m2450_3(unknown) = InitializeNonLocal : -# 2450| m2450_4(unknown) = Chi : total:m2450_2, partial:m2450_3 -# 2450| r2450_5(glval) = VariableAddress[x] : -# 2450| m2450_6(int) = InitializeParameter[x] : &:r2450_5 -# 2451| r2451_1(glval) = VariableAddress[c] : -# 2451| m2451_2(ClassWithDestructor) = Uninitialized[c] : &:r2451_1 -# 2451| r2451_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2451| v2451_4(void) = Call[ClassWithDestructor] : func:r2451_3, this:r2451_1 -# 2451| m2451_5(unknown) = ^CallSideEffect : ~m2450_4 -# 2451| m2451_6(unknown) = Chi : total:m2450_4, partial:m2451_5 -# 2451| m2451_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2451_1 -# 2451| m2451_8(ClassWithDestructor) = Chi : total:m2451_2, partial:m2451_7 -# 2452| v2452_1(void) = ReThrow : -# 2453| r2453_1(glval) = VariableAddress[c] : -# 2453| r2453_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2453| v2453_3(void) = Call[~ClassWithDestructor] : func:r2453_2, this:r2453_1 -# 2453| m2453_4(unknown) = ^CallSideEffect : ~m2451_6 -# 2453| m2453_5(unknown) = Chi : total:m2451_6, partial:m2453_4 -# 2453| v2453_6(void) = ^IndirectReadSideEffect[-1] : &:r2453_1, m2451_8 -# 2453| m2453_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2453_1 -# 2453| m2453_8(ClassWithDestructor) = Chi : total:m2451_8, partial:m2453_7 +# 2431| Block 12 +# 2431| r2431_79(glval>) = CopyValue : r2431_27 +# 2431| r2431_80(glval) = FunctionAddress[~vector] : +# 2431| v2431_81(void) = Call[~vector] : func:r2431_80, this:r2431_79 +# 2431| m2431_82(unknown) = ^CallSideEffect : ~m2431_63 +# 2431| m2431_83(unknown) = Chi : total:m2431_63, partial:m2431_82 +# 2431| v2431_84(void) = ^IndirectReadSideEffect[-1] : &:r2431_79, ~m2431_83 +# 2431| m2431_85(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2431_79 +# 2431| m2431_86(unknown) = Chi : total:m2431_83, partial:m2431_85 +# 2433| v2433_1(void) = NoOp : +# 2411| v2411_5(void) = ReturnVoid : +# 2411| v2411_6(void) = AliasedUse : ~m2431_83 +# 2411| v2411_7(void) = ExitFunction : + +# 2411| Block 13 +# 2411| v2411_8(void) = Unreached : + +# 2435| void param_with_destructor_by_value(ClassWithDestructor) +# 2435| Block 0 +# 2435| v2435_1(void) = EnterFunction : +# 2435| m2435_2(unknown) = AliasedDefinition : +# 2435| m2435_3(unknown) = InitializeNonLocal : +# 2435| m2435_4(unknown) = Chi : total:m2435_2, partial:m2435_3 +# 2435| r2435_5(glval) = VariableAddress[c] : +# 2435| m2435_6(ClassWithDestructor) = InitializeParameter[c] : &:r2435_5 +# 2437| v2437_1(void) = NoOp : +# 2435| v2435_7(void) = ReturnVoid : +# 2435| v2435_8(void) = AliasedUse : m2435_3 +# 2435| v2435_9(void) = ExitFunction : + +# 2439| void param_with_destructor_by_pointer(ClassWithDestructor*) +# 2439| Block 0 +# 2439| v2439_1(void) = EnterFunction : +# 2439| m2439_2(unknown) = AliasedDefinition : +# 2439| m2439_3(unknown) = InitializeNonLocal : +# 2439| m2439_4(unknown) = Chi : total:m2439_2, partial:m2439_3 +# 2439| r2439_5(glval) = VariableAddress[c] : +# 2439| m2439_6(ClassWithDestructor *) = InitializeParameter[c] : &:r2439_5 +# 2439| r2439_7(ClassWithDestructor *) = Load[c] : &:r2439_5, m2439_6 +# 2439| m2439_8(unknown) = InitializeIndirection[c] : &:r2439_7 +# 2441| v2441_1(void) = NoOp : +# 2439| v2439_9(void) = ReturnIndirection[c] : &:r2439_7, m2439_8 +# 2439| v2439_10(void) = ReturnVoid : +# 2439| v2439_11(void) = AliasedUse : m2439_3 +# 2439| v2439_12(void) = ExitFunction : + +# 2443| void param_with_destructor_by_ref(ClassWithDestructor&) +# 2443| Block 0 +# 2443| v2443_1(void) = EnterFunction : +# 2443| m2443_2(unknown) = AliasedDefinition : +# 2443| m2443_3(unknown) = InitializeNonLocal : +# 2443| m2443_4(unknown) = Chi : total:m2443_2, partial:m2443_3 +# 2443| r2443_5(glval) = VariableAddress[c] : +# 2443| m2443_6(ClassWithDestructor &) = InitializeParameter[c] : &:r2443_5 +# 2443| r2443_7(ClassWithDestructor &) = Load[c] : &:r2443_5, m2443_6 +# 2443| m2443_8(unknown) = InitializeIndirection[c] : &:r2443_7 +# 2445| v2445_1(void) = NoOp : +# 2443| v2443_9(void) = ReturnIndirection[c] : &:r2443_7, m2443_8 +# 2443| v2443_10(void) = ReturnVoid : +# 2443| v2443_11(void) = AliasedUse : m2443_3 +# 2443| v2443_12(void) = ExitFunction : + +# 2447| void param_with_destructor_by_rref(ClassWithDestructor&&) +# 2447| Block 0 +# 2447| v2447_1(void) = EnterFunction : +# 2447| m2447_2(unknown) = AliasedDefinition : +# 2447| m2447_3(unknown) = InitializeNonLocal : +# 2447| m2447_4(unknown) = Chi : total:m2447_2, partial:m2447_3 +# 2447| r2447_5(glval) = VariableAddress[c] : +# 2447| m2447_6(ClassWithDestructor &&) = InitializeParameter[c] : &:r2447_5 +# 2447| r2447_7(ClassWithDestructor &&) = Load[c] : &:r2447_5, m2447_6 +# 2447| m2447_8(unknown) = InitializeIndirection[c] : &:r2447_7 +# 2449| v2449_1(void) = NoOp : +# 2447| v2447_9(void) = ReturnIndirection[c] : &:r2447_7, m2447_8 +# 2447| v2447_10(void) = ReturnVoid : +# 2447| v2447_11(void) = AliasedUse : m2447_3 +# 2447| v2447_12(void) = ExitFunction : + +# 2451| void rethrow_with_destruction(int) +# 2451| Block 0 +# 2451| v2451_1(void) = EnterFunction : +# 2451| m2451_2(unknown) = AliasedDefinition : +# 2451| m2451_3(unknown) = InitializeNonLocal : +# 2451| m2451_4(unknown) = Chi : total:m2451_2, partial:m2451_3 +# 2451| r2451_5(glval) = VariableAddress[x] : +# 2451| m2451_6(int) = InitializeParameter[x] : &:r2451_5 +# 2452| r2452_1(glval) = VariableAddress[c] : +# 2452| m2452_2(ClassWithDestructor) = Uninitialized[c] : &:r2452_1 +# 2452| r2452_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2452| v2452_4(void) = Call[ClassWithDestructor] : func:r2452_3, this:r2452_1 +# 2452| m2452_5(unknown) = ^CallSideEffect : ~m2451_4 +# 2452| m2452_6(unknown) = Chi : total:m2451_4, partial:m2452_5 +# 2452| m2452_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2452_1 +# 2452| m2452_8(ClassWithDestructor) = Chi : total:m2452_2, partial:m2452_7 +# 2453| v2453_1(void) = ReThrow : +# 2454| r2454_1(glval) = VariableAddress[c] : +# 2454| r2454_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2454| v2454_3(void) = Call[~ClassWithDestructor] : func:r2454_2, this:r2454_1 +# 2454| m2454_4(unknown) = ^CallSideEffect : ~m2452_6 +# 2454| m2454_5(unknown) = Chi : total:m2452_6, partial:m2454_4 +# 2454| v2454_6(void) = ^IndirectReadSideEffect[-1] : &:r2454_1, m2452_8 +# 2454| m2454_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2454_1 +# 2454| m2454_8(ClassWithDestructor) = Chi : total:m2452_8, partial:m2454_7 #-----| Exception -> Block 1 -# 2450| Block 1 -# 2450| v2450_7(void) = Unwind : -# 2450| v2450_8(void) = AliasedUse : ~m2453_5 -# 2450| v2450_9(void) = ExitFunction : - -# 2459| void new_with_destructor(ClassWithDestructor) -# 2459| Block 0 -# 2459| v2459_1(void) = EnterFunction : -# 2459| m2459_2(unknown) = AliasedDefinition : -# 2459| m2459_3(unknown) = InitializeNonLocal : -# 2459| m2459_4(unknown) = Chi : total:m2459_2, partial:m2459_3 -# 2459| r2459_5(glval) = VariableAddress[a] : -# 2459| m2459_6(ClassWithDestructor) = InitializeParameter[a] : &:r2459_5 -# 2461| r2461_1(glval) = VariableAddress[b] : -# 2461| r2461_2(glval) = FunctionAddress[operator new] : -# 2461| r2461_3(unsigned long) = Constant[1] : -# 2461| r2461_4(void *) = Call[operator new] : func:r2461_2, 0:r2461_3 -# 2461| m2461_5(unknown) = ^CallSideEffect : ~m2459_4 -# 2461| m2461_6(unknown) = Chi : total:m2459_4, partial:m2461_5 -# 2461| m2461_7(unknown) = ^InitializeDynamicAllocation : &:r2461_4 -# 2461| m2461_8(unknown) = Chi : total:m2461_6, partial:m2461_7 -# 2461| r2461_9(ByValueConstructor *) = Convert : r2461_4 -# 2461| r2461_10(glval) = FunctionAddress[ByValueConstructor] : -# 2461| r2461_11(glval) = VariableAddress[#temp2461:52] : -# 2461| r2461_12(glval) = VariableAddress[a] : -# 2461| r2461_13(ClassWithDestructor) = Load[a] : &:r2461_12, m2459_6 -# 2461| m2461_14(ClassWithDestructor) = Store[#temp2461:52] : &:r2461_11, r2461_13 -# 2461| r2461_15(ClassWithDestructor) = Load[#temp2461:52] : &:r2461_11, m2461_14 -# 2461| v2461_16(void) = Call[ByValueConstructor] : func:r2461_10, this:r2461_9, 0:r2461_15 -# 2461| m2461_17(unknown) = ^CallSideEffect : ~m2461_8 -# 2461| m2461_18(unknown) = Chi : total:m2461_8, partial:m2461_17 -# 2461| m2461_19(ByValueConstructor) = ^IndirectMayWriteSideEffect[-1] : &:r2461_9 -# 2461| m2461_20(unknown) = Chi : total:m2461_18, partial:m2461_19 -# 2461| r2461_21(glval) = CopyValue : r2461_11 -# 2461| r2461_22(glval) = FunctionAddress[~ClassWithDestructor] : -# 2461| v2461_23(void) = Call[~ClassWithDestructor] : func:r2461_22, this:r2461_21 -# 2461| m2461_24(unknown) = ^CallSideEffect : ~m2461_20 -# 2461| m2461_25(unknown) = Chi : total:m2461_20, partial:m2461_24 -# 2461| v2461_26(void) = ^IndirectReadSideEffect[-1] : &:r2461_21, m2461_14 -# 2461| m2461_27(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2461_21 -# 2461| m2461_28(ClassWithDestructor) = Chi : total:m2461_14, partial:m2461_27 -# 2461| m2461_29(ByValueConstructor *) = Store[b] : &:r2461_1, r2461_9 -# 2462| v2462_1(void) = NoOp : -# 2459| v2459_7(void) = ReturnVoid : -# 2459| v2459_8(void) = AliasedUse : ~m2461_25 -# 2459| v2459_9(void) = ExitFunction : - -# 2478| void rvalue_conversion_with_destructor::test() -# 2478| Block 0 -# 2478| v2478_1(void) = EnterFunction : -# 2478| m2478_2(unknown) = AliasedDefinition : -# 2478| m2478_3(unknown) = InitializeNonLocal : -# 2478| m2478_4(unknown) = Chi : total:m2478_2, partial:m2478_3 -# 2480| r2480_1(glval) = VariableAddress[a] : -# 2480| r2480_2(glval) = VariableAddress[#temp2480:18] : -# 2480| r2480_3(glval) = FunctionAddress[get] : -# 2480| r2480_4(B) = Call[get] : func:r2480_3 -# 2480| m2480_5(unknown) = ^CallSideEffect : ~m2478_4 -# 2480| m2480_6(unknown) = Chi : total:m2478_4, partial:m2480_5 -# 2480| m2480_7(B) = Store[#temp2480:18] : &:r2480_2, r2480_4 -# 2480| m2480_8(unknown) = Chi : total:m2480_6, partial:m2480_7 -# 2480| r2480_9(glval) = Convert : r2480_2 -# 2480| r2480_10(glval) = FunctionAddress[operator->] : -# 2480| r2480_11(A *) = Call[operator->] : func:r2480_10, this:r2480_9 -# 2480| m2480_12(unknown) = ^CallSideEffect : ~m2480_8 -# 2480| m2480_13(unknown) = Chi : total:m2480_8, partial:m2480_12 -# 2480| v2480_14(void) = ^IndirectReadSideEffect[-1] : &:r2480_9, ~m2480_13 -# 2480| r2480_15(glval) = FieldAddress[a] : r2480_11 -# 2480| r2480_16(glval) = CopyValue : r2480_2 -# 2480| r2480_17(glval) = FunctionAddress[~B] : -# 2480| v2480_18(void) = Call[~B] : func:r2480_17, this:r2480_16 -# 2480| m2480_19(unknown) = ^CallSideEffect : ~m2480_13 -# 2480| m2480_20(unknown) = Chi : total:m2480_13, partial:m2480_19 -# 2480| v2480_21(void) = ^IndirectReadSideEffect[-1] : &:r2480_16, ~m2480_20 -# 2480| m2480_22(B) = ^IndirectMayWriteSideEffect[-1] : &:r2480_16 -# 2480| m2480_23(unknown) = Chi : total:m2480_20, partial:m2480_22 -# 2480| r2480_24(unsigned int) = Load[?] : &:r2480_15, ~m2480_23 -# 2480| m2480_25(unsigned int) = Store[a] : &:r2480_1, r2480_24 -# 2481| v2481_1(void) = NoOp : -# 2478| v2478_5(void) = ReturnVoid : -# 2478| v2478_6(void) = AliasedUse : ~m2480_20 -# 2478| v2478_7(void) = ExitFunction : +# 2451| Block 1 +# 2451| v2451_7(void) = Unwind : +# 2451| v2451_8(void) = AliasedUse : ~m2454_5 +# 2451| v2451_9(void) = ExitFunction : + +# 2460| void new_with_destructor(ClassWithDestructor) +# 2460| Block 0 +# 2460| v2460_1(void) = EnterFunction : +# 2460| m2460_2(unknown) = AliasedDefinition : +# 2460| m2460_3(unknown) = InitializeNonLocal : +# 2460| m2460_4(unknown) = Chi : total:m2460_2, partial:m2460_3 +# 2460| r2460_5(glval) = VariableAddress[a] : +# 2460| m2460_6(ClassWithDestructor) = InitializeParameter[a] : &:r2460_5 +# 2462| r2462_1(glval) = VariableAddress[b] : +# 2462| r2462_2(glval) = FunctionAddress[operator new] : +# 2462| r2462_3(unsigned long) = Constant[1] : +# 2462| r2462_4(void *) = Call[operator new] : func:r2462_2, 0:r2462_3 +# 2462| m2462_5(unknown) = ^CallSideEffect : ~m2460_4 +# 2462| m2462_6(unknown) = Chi : total:m2460_4, partial:m2462_5 +# 2462| m2462_7(unknown) = ^InitializeDynamicAllocation : &:r2462_4 +# 2462| m2462_8(unknown) = Chi : total:m2462_6, partial:m2462_7 +# 2462| r2462_9(ByValueConstructor *) = Convert : r2462_4 +# 2462| r2462_10(glval) = FunctionAddress[ByValueConstructor] : +# 2462| r2462_11(glval) = VariableAddress[#temp2462:52] : +# 2462| r2462_12(glval) = VariableAddress[a] : +# 2462| r2462_13(ClassWithDestructor) = Load[a] : &:r2462_12, m2460_6 +# 2462| m2462_14(ClassWithDestructor) = Store[#temp2462:52] : &:r2462_11, r2462_13 +# 2462| r2462_15(ClassWithDestructor) = Load[#temp2462:52] : &:r2462_11, m2462_14 +# 2462| v2462_16(void) = Call[ByValueConstructor] : func:r2462_10, this:r2462_9, 0:r2462_15 +# 2462| m2462_17(unknown) = ^CallSideEffect : ~m2462_8 +# 2462| m2462_18(unknown) = Chi : total:m2462_8, partial:m2462_17 +# 2462| m2462_19(ByValueConstructor) = ^IndirectMayWriteSideEffect[-1] : &:r2462_9 +# 2462| m2462_20(unknown) = Chi : total:m2462_18, partial:m2462_19 +# 2462| r2462_21(glval) = CopyValue : r2462_11 +# 2462| r2462_22(glval) = FunctionAddress[~ClassWithDestructor] : +# 2462| v2462_23(void) = Call[~ClassWithDestructor] : func:r2462_22, this:r2462_21 +# 2462| m2462_24(unknown) = ^CallSideEffect : ~m2462_20 +# 2462| m2462_25(unknown) = Chi : total:m2462_20, partial:m2462_24 +# 2462| v2462_26(void) = ^IndirectReadSideEffect[-1] : &:r2462_21, m2462_14 +# 2462| m2462_27(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2462_21 +# 2462| m2462_28(ClassWithDestructor) = Chi : total:m2462_14, partial:m2462_27 +# 2462| m2462_29(ByValueConstructor *) = Store[b] : &:r2462_1, r2462_9 +# 2463| v2463_1(void) = NoOp : +# 2460| v2460_7(void) = ReturnVoid : +# 2460| v2460_8(void) = AliasedUse : ~m2462_25 +# 2460| v2460_9(void) = ExitFunction : + +# 2479| void rvalue_conversion_with_destructor::test() +# 2479| Block 0 +# 2479| v2479_1(void) = EnterFunction : +# 2479| m2479_2(unknown) = AliasedDefinition : +# 2479| m2479_3(unknown) = InitializeNonLocal : +# 2479| m2479_4(unknown) = Chi : total:m2479_2, partial:m2479_3 +# 2481| r2481_1(glval) = VariableAddress[a] : +# 2481| r2481_2(glval) = VariableAddress[#temp2481:18] : +# 2481| r2481_3(glval) = FunctionAddress[get] : +# 2481| r2481_4(B) = Call[get] : func:r2481_3 +# 2481| m2481_5(unknown) = ^CallSideEffect : ~m2479_4 +# 2481| m2481_6(unknown) = Chi : total:m2479_4, partial:m2481_5 +# 2481| m2481_7(B) = Store[#temp2481:18] : &:r2481_2, r2481_4 +# 2481| m2481_8(unknown) = Chi : total:m2481_6, partial:m2481_7 +# 2481| r2481_9(glval) = Convert : r2481_2 +# 2481| r2481_10(glval) = FunctionAddress[operator->] : +# 2481| r2481_11(A *) = Call[operator->] : func:r2481_10, this:r2481_9 +# 2481| m2481_12(unknown) = ^CallSideEffect : ~m2481_8 +# 2481| m2481_13(unknown) = Chi : total:m2481_8, partial:m2481_12 +# 2481| v2481_14(void) = ^IndirectReadSideEffect[-1] : &:r2481_9, ~m2481_13 +# 2481| r2481_15(glval) = FieldAddress[a] : r2481_11 +# 2481| r2481_16(glval) = CopyValue : r2481_2 +# 2481| r2481_17(glval) = FunctionAddress[~B] : +# 2481| v2481_18(void) = Call[~B] : func:r2481_17, this:r2481_16 +# 2481| m2481_19(unknown) = ^CallSideEffect : ~m2481_13 +# 2481| m2481_20(unknown) = Chi : total:m2481_13, partial:m2481_19 +# 2481| v2481_21(void) = ^IndirectReadSideEffect[-1] : &:r2481_16, ~m2481_20 +# 2481| m2481_22(B) = ^IndirectMayWriteSideEffect[-1] : &:r2481_16 +# 2481| m2481_23(unknown) = Chi : total:m2481_20, partial:m2481_22 +# 2481| r2481_24(unsigned int) = Load[?] : &:r2481_15, ~m2481_23 +# 2481| m2481_25(unsigned int) = Store[a] : &:r2481_1, r2481_24 +# 2482| v2482_1(void) = NoOp : +# 2479| v2479_5(void) = ReturnVoid : +# 2479| v2479_6(void) = AliasedUse : ~m2481_20 +# 2479| v2479_7(void) = ExitFunction : + +# 2485| void destructor_without_block(bool) +# 2485| Block 0 +# 2485| v2485_1(void) = EnterFunction : +# 2485| m2485_2(unknown) = AliasedDefinition : +# 2485| m2485_3(unknown) = InitializeNonLocal : +# 2485| m2485_4(unknown) = Chi : total:m2485_2, partial:m2485_3 +# 2485| r2485_5(glval) = VariableAddress[b] : +# 2485| m2485_6(bool) = InitializeParameter[b] : &:r2485_5 +# 2487| r2487_1(glval) = VariableAddress[b] : +# 2487| r2487_2(bool) = Load[b] : &:r2487_1, m2485_6 +# 2487| v2487_3(void) = ConditionalBranch : r2487_2 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 2488| Block 1 +# 2488| r2488_1(glval) = VariableAddress[c] : +# 2488| m2488_2(ClassWithDestructor) = Uninitialized[c] : &:r2488_1 +# 2488| r2488_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2488| v2488_4(void) = Call[ClassWithDestructor] : func:r2488_3, this:r2488_1 +# 2488| m2488_5(unknown) = ^CallSideEffect : ~m2485_4 +# 2488| m2488_6(unknown) = Chi : total:m2485_4, partial:m2488_5 +# 2488| m2488_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2488_1 +# 2488| m2488_8(ClassWithDestructor) = Chi : total:m2488_2, partial:m2488_7 +#-----| r0_1(glval) = VariableAddress[c] : +#-----| r0_2(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_3(void) = Call[~ClassWithDestructor] : func:r0_2, this:r0_1 +#-----| m0_4(unknown) = ^CallSideEffect : ~m2488_6 +#-----| m0_5(unknown) = Chi : total:m2488_6, partial:m0_4 +#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_1, m2488_8 +#-----| m0_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_1 +#-----| m0_8(ClassWithDestructor) = Chi : total:m2488_8, partial:m0_7 +#-----| Goto -> Block 2 + +# 2490| Block 2 +# 2490| m2490_1(unknown) = Phi : from 0:~m2485_4, from 1:~m0_5 +# 2490| r2490_2(glval) = VariableAddress[b] : +# 2490| r2490_3(bool) = Load[b] : &:r2490_2, m2485_6 +# 2490| v2490_4(void) = ConditionalBranch : r2490_3 +#-----| False -> Block 4 +#-----| True -> Block 3 + +# 2491| Block 3 +# 2491| r2491_1(glval) = VariableAddress[d] : +# 2491| m2491_2(ClassWithDestructor) = Uninitialized[d] : &:r2491_1 +# 2491| r2491_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2491| v2491_4(void) = Call[ClassWithDestructor] : func:r2491_3, this:r2491_1 +# 2491| m2491_5(unknown) = ^CallSideEffect : ~m2490_1 +# 2491| m2491_6(unknown) = Chi : total:m2490_1, partial:m2491_5 +# 2491| m2491_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2491_1 +# 2491| m2491_8(ClassWithDestructor) = Chi : total:m2491_2, partial:m2491_7 +#-----| r0_9(glval) = VariableAddress[d] : +#-----| r0_10(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_11(void) = Call[~ClassWithDestructor] : func:r0_10, this:r0_9 +#-----| m0_12(unknown) = ^CallSideEffect : ~m2491_6 +#-----| m0_13(unknown) = Chi : total:m2491_6, partial:m0_12 +#-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_9, m2491_8 +#-----| m0_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 +#-----| m0_16(ClassWithDestructor) = Chi : total:m2491_8, partial:m0_15 +#-----| Goto -> Block 5 + +# 2493| Block 4 +# 2493| r2493_1(glval) = VariableAddress[e] : +# 2493| m2493_2(ClassWithDestructor) = Uninitialized[e] : &:r2493_1 +# 2493| r2493_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2493| v2493_4(void) = Call[ClassWithDestructor] : func:r2493_3, this:r2493_1 +# 2493| m2493_5(unknown) = ^CallSideEffect : ~m2490_1 +# 2493| m2493_6(unknown) = Chi : total:m2490_1, partial:m2493_5 +# 2493| m2493_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2493_1 +# 2493| m2493_8(ClassWithDestructor) = Chi : total:m2493_2, partial:m2493_7 +#-----| r0_17(glval) = VariableAddress[e] : +#-----| r0_18(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_19(void) = Call[~ClassWithDestructor] : func:r0_18, this:r0_17 +#-----| m0_20(unknown) = ^CallSideEffect : ~m2493_6 +#-----| m0_21(unknown) = Chi : total:m2493_6, partial:m0_20 +#-----| v0_22(void) = ^IndirectReadSideEffect[-1] : &:r0_17, m2493_8 +#-----| m0_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_17 +#-----| m0_24(ClassWithDestructor) = Chi : total:m2493_8, partial:m0_23 +#-----| Goto -> Block 5 + +# 2495| Block 5 +# 2495| m2495_1(unknown) = Phi : from 3:~m0_13, from 4:~m0_21, from 6:~m0_29 +# 2495| r2495_2(glval) = VariableAddress[b] : +# 2495| r2495_3(bool) = Load[b] : &:r2495_2, m2485_6 +# 2495| v2495_4(void) = ConditionalBranch : r2495_3 +#-----| False -> Block 7 +#-----| True -> Block 6 + +# 2496| Block 6 +# 2496| r2496_1(glval) = VariableAddress[f] : +# 2496| m2496_2(ClassWithDestructor) = Uninitialized[f] : &:r2496_1 +# 2496| r2496_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2496| v2496_4(void) = Call[ClassWithDestructor] : func:r2496_3, this:r2496_1 +# 2496| m2496_5(unknown) = ^CallSideEffect : ~m2495_1 +# 2496| m2496_6(unknown) = Chi : total:m2495_1, partial:m2496_5 +# 2496| m2496_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2496_1 +# 2496| m2496_8(ClassWithDestructor) = Chi : total:m2496_2, partial:m2496_7 +#-----| r0_25(glval) = VariableAddress[f] : +#-----| r0_26(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_27(void) = Call[~ClassWithDestructor] : func:r0_26, this:r0_25 +#-----| m0_28(unknown) = ^CallSideEffect : ~m2496_6 +#-----| m0_29(unknown) = Chi : total:m2496_6, partial:m0_28 +#-----| v0_30(void) = ^IndirectReadSideEffect[-1] : &:r0_25, m2496_8 +#-----| m0_31(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_25 +#-----| m0_32(ClassWithDestructor) = Chi : total:m2496_8, partial:m0_31 +#-----| Goto (back edge) -> Block 5 + +# 2498| Block 7 +# 2498| r2498_1(glval) = VariableAddress[i] : +# 2498| r2498_2(int) = Constant[0] : +# 2498| m2498_3(int) = Store[i] : &:r2498_1, r2498_2 +#-----| Goto -> Block 8 + +# 2498| Block 8 +# 2498| m2498_4(unknown) = Phi : from 7:~m2495_1, from 9:~m0_37 +# 2498| m2498_5(int) = Phi : from 7:m2498_3, from 9:m2498_15 +# 2498| r2498_6(glval) = VariableAddress[i] : +# 2498| r2498_7(int) = Load[i] : &:r2498_6, m2498_5 +# 2498| r2498_8(int) = Constant[42] : +# 2498| r2498_9(bool) = CompareLT : r2498_7, r2498_8 +# 2498| v2498_10(void) = ConditionalBranch : r2498_9 +#-----| False -> Block 10 +#-----| True -> Block 9 + +# 2499| Block 9 +# 2499| r2499_1(glval) = VariableAddress[g] : +# 2499| m2499_2(ClassWithDestructor) = Uninitialized[g] : &:r2499_1 +# 2499| r2499_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2499| v2499_4(void) = Call[ClassWithDestructor] : func:r2499_3, this:r2499_1 +# 2499| m2499_5(unknown) = ^CallSideEffect : ~m2498_4 +# 2499| m2499_6(unknown) = Chi : total:m2498_4, partial:m2499_5 +# 2499| m2499_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2499_1 +# 2499| m2499_8(ClassWithDestructor) = Chi : total:m2499_2, partial:m2499_7 +#-----| r0_33(glval) = VariableAddress[g] : +#-----| r0_34(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_35(void) = Call[~ClassWithDestructor] : func:r0_34, this:r0_33 +#-----| m0_36(unknown) = ^CallSideEffect : ~m2499_6 +#-----| m0_37(unknown) = Chi : total:m2499_6, partial:m0_36 +#-----| v0_38(void) = ^IndirectReadSideEffect[-1] : &:r0_33, m2499_8 +#-----| m0_39(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_33 +#-----| m0_40(ClassWithDestructor) = Chi : total:m2499_8, partial:m0_39 +# 2498| r2498_11(glval) = VariableAddress[i] : +# 2498| r2498_12(int) = Load[i] : &:r2498_11, m2498_5 +# 2498| r2498_13(int) = Constant[1] : +# 2498| r2498_14(int) = Add : r2498_12, r2498_13 +# 2498| m2498_15(int) = Store[i] : &:r2498_11, r2498_14 +#-----| Goto (back edge) -> Block 8 + +# 2500| Block 10 +# 2500| v2500_1(void) = NoOp : +# 2485| v2485_7(void) = ReturnVoid : +# 2485| v2485_8(void) = AliasedUse : ~m2498_4 +# 2485| v2485_9(void) = ExitFunction : + +# 2502| void destruction_in_switch_1(int) +# 2502| Block 0 +# 2502| v2502_1(void) = EnterFunction : +# 2502| m2502_2(unknown) = AliasedDefinition : +# 2502| m2502_3(unknown) = InitializeNonLocal : +# 2502| m2502_4(unknown) = Chi : total:m2502_2, partial:m2502_3 +# 2502| r2502_5(glval) = VariableAddress[c] : +# 2502| m2502_6(int) = InitializeParameter[c] : &:r2502_5 +# 2503| r2503_1(glval) = VariableAddress[c] : +# 2503| r2503_2(int) = Load[c] : &:r2503_1, m2502_6 +# 2503| v2503_3(void) = Switch : r2503_2 +#-----| Case[0] -> Block 1 +#-----| Default -> Block 2 + +# 2504| Block 1 +# 2504| v2504_1(void) = NoOp : +# 2505| r2505_1(glval) = VariableAddress[x] : +# 2505| m2505_2(ClassWithDestructor) = Uninitialized[x] : &:r2505_1 +# 2505| r2505_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2505| v2505_4(void) = Call[ClassWithDestructor] : func:r2505_3, this:r2505_1 +# 2505| m2505_5(unknown) = ^CallSideEffect : ~m2502_4 +# 2505| m2505_6(unknown) = Chi : total:m2502_4, partial:m2505_5 +# 2505| m2505_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2505_1 +# 2505| m2505_8(ClassWithDestructor) = Chi : total:m2505_2, partial:m2505_7 +# 2507| r2507_1(glval) = VariableAddress[x] : +# 2507| r2507_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2507| v2507_3(void) = Call[~ClassWithDestructor] : func:r2507_2, this:r2507_1 +# 2507| m2507_4(unknown) = ^CallSideEffect : ~m2505_6 +# 2507| m2507_5(unknown) = Chi : total:m2505_6, partial:m2507_4 +# 2507| v2507_6(void) = ^IndirectReadSideEffect[-1] : &:r2507_1, m2505_8 +# 2507| m2507_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2507_1 +# 2507| m2507_8(ClassWithDestructor) = Chi : total:m2505_8, partial:m2507_7 +# 2506| v2506_1(void) = NoOp : +#-----| Goto -> Block 2 + +# 2508| Block 2 +# 2508| m2508_1(unknown) = Phi : from 0:~m2502_4, from 1:~m2507_5 +# 2508| v2508_2(void) = NoOp : +# 2509| v2509_1(void) = NoOp : +# 2502| v2502_7(void) = ReturnVoid : +# 2502| v2502_8(void) = AliasedUse : ~m2508_1 +# 2502| v2502_9(void) = ExitFunction : + +# 2511| void destruction_in_switch_2(int) +# 2511| Block 0 +# 2511| v2511_1(void) = EnterFunction : +# 2511| m2511_2(unknown) = AliasedDefinition : +# 2511| m2511_3(unknown) = InitializeNonLocal : +# 2511| m2511_4(unknown) = Chi : total:m2511_2, partial:m2511_3 +# 2511| r2511_5(glval) = VariableAddress[c] : +# 2511| m2511_6(int) = InitializeParameter[c] : &:r2511_5 +# 2512| r2512_1(glval) = VariableAddress[y] : +# 2512| m2512_2(ClassWithDestructor) = Uninitialized[y] : &:r2512_1 +# 2512| r2512_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2512| v2512_4(void) = Call[ClassWithDestructor] : func:r2512_3, this:r2512_1 +# 2512| m2512_5(unknown) = ^CallSideEffect : ~m2511_4 +# 2512| m2512_6(unknown) = Chi : total:m2511_4, partial:m2512_5 +# 2512| m2512_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2512_1 +# 2512| m2512_8(ClassWithDestructor) = Chi : total:m2512_2, partial:m2512_7 +# 2512| r2512_9(glval) = VariableAddress[c] : +# 2512| r2512_10(int) = Load[c] : &:r2512_9, m2511_6 +# 2512| v2512_11(void) = Switch : r2512_10 +#-----| Case[0] -> Block 1 +#-----| Default -> Block 2 + +# 2513| Block 1 +# 2513| v2513_1(void) = NoOp : +# 2519| r2519_1(glval) = VariableAddress[y] : +# 2519| r2519_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2519| v2519_3(void) = Call[~ClassWithDestructor] : func:r2519_2, this:r2519_1 +# 2519| m2519_4(unknown) = ^CallSideEffect : ~m2512_6 +# 2519| m2519_5(unknown) = Chi : total:m2512_6, partial:m2519_4 +# 2519| v2519_6(void) = ^IndirectReadSideEffect[-1] : &:r2519_1, m2512_8 +# 2519| m2519_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2519_1 +# 2519| m2519_8(ClassWithDestructor) = Chi : total:m2512_8, partial:m2519_7 +# 2514| v2514_1(void) = NoOp : +#-----| Goto -> Block 3 + +# 2516| Block 2 +# 2516| v2516_1(void) = NoOp : +# 2519| r2519_9(glval) = VariableAddress[y] : +# 2519| r2519_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2519| v2519_11(void) = Call[~ClassWithDestructor] : func:r2519_10, this:r2519_9 +# 2519| m2519_12(unknown) = ^CallSideEffect : ~m2512_6 +# 2519| m2519_13(unknown) = Chi : total:m2512_6, partial:m2519_12 +# 2519| v2519_14(void) = ^IndirectReadSideEffect[-1] : &:r2519_9, m2512_8 +# 2519| m2519_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2519_9 +# 2519| m2519_16(ClassWithDestructor) = Chi : total:m2512_8, partial:m2519_15 +# 2517| v2517_1(void) = NoOp : +#-----| Goto -> Block 3 + +# 2519| Block 3 +# 2519| m2519_17(unknown) = Phi : from 1:~m2519_5, from 2:~m2519_13 +# 2519| v2519_18(void) = NoOp : +# 2520| v2520_1(void) = NoOp : +# 2511| v2511_7(void) = ReturnVoid : +# 2511| v2511_8(void) = AliasedUse : ~m2519_17 +# 2511| v2511_9(void) = ExitFunction : + +# 2522| void destruction_in_switch_3(int) +# 2522| Block 0 +# 2522| v2522_1(void) = EnterFunction : +# 2522| m2522_2(unknown) = AliasedDefinition : +# 2522| m2522_3(unknown) = InitializeNonLocal : +# 2522| m2522_4(unknown) = Chi : total:m2522_2, partial:m2522_3 +# 2522| r2522_5(glval) = VariableAddress[c] : +# 2522| m2522_6(int) = InitializeParameter[c] : &:r2522_5 +# 2523| r2523_1(glval) = VariableAddress[y] : +# 2523| m2523_2(ClassWithDestructor) = Uninitialized[y] : &:r2523_1 +# 2523| r2523_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2523| v2523_4(void) = Call[ClassWithDestructor] : func:r2523_3, this:r2523_1 +# 2523| m2523_5(unknown) = ^CallSideEffect : ~m2522_4 +# 2523| m2523_6(unknown) = Chi : total:m2522_4, partial:m2523_5 +# 2523| m2523_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2523_1 +# 2523| m2523_8(ClassWithDestructor) = Chi : total:m2523_2, partial:m2523_7 +# 2523| r2523_9(glval) = VariableAddress[c] : +# 2523| r2523_10(int) = Load[c] : &:r2523_9, m2522_6 +# 2523| v2523_11(void) = Switch : r2523_10 +#-----| Case[0] -> Block 1 +#-----| Default -> Block 2 + +# 2524| Block 1 +# 2524| v2524_1(void) = NoOp : +# 2525| r2525_1(glval) = VariableAddress[x] : +# 2525| m2525_2(ClassWithDestructor) = Uninitialized[x] : &:r2525_1 +# 2525| r2525_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2525| v2525_4(void) = Call[ClassWithDestructor] : func:r2525_3, this:r2525_1 +# 2525| m2525_5(unknown) = ^CallSideEffect : ~m2523_6 +# 2525| m2525_6(unknown) = Chi : total:m2523_6, partial:m2525_5 +# 2525| m2525_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2525_1 +# 2525| m2525_8(ClassWithDestructor) = Chi : total:m2525_2, partial:m2525_7 +# 2527| r2527_1(glval) = VariableAddress[x] : +# 2527| r2527_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2527| v2527_3(void) = Call[~ClassWithDestructor] : func:r2527_2, this:r2527_1 +# 2527| m2527_4(unknown) = ^CallSideEffect : ~m2525_6 +# 2527| m2527_5(unknown) = Chi : total:m2525_6, partial:m2527_4 +# 2527| v2527_6(void) = ^IndirectReadSideEffect[-1] : &:r2527_1, m2525_8 +# 2527| m2527_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2527_1 +# 2527| m2527_8(ClassWithDestructor) = Chi : total:m2525_8, partial:m2527_7 +# 2531| r2531_1(glval) = VariableAddress[y] : +# 2531| r2531_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2531| v2531_3(void) = Call[~ClassWithDestructor] : func:r2531_2, this:r2531_1 +# 2531| m2531_4(unknown) = ^CallSideEffect : ~m2527_5 +# 2531| m2531_5(unknown) = Chi : total:m2527_5, partial:m2531_4 +# 2531| v2531_6(void) = ^IndirectReadSideEffect[-1] : &:r2531_1, m2523_8 +# 2531| m2531_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2531_1 +# 2531| m2531_8(ClassWithDestructor) = Chi : total:m2523_8, partial:m2531_7 +# 2526| v2526_1(void) = NoOp : +#-----| Goto -> Block 3 + +# 2528| Block 2 +# 2528| v2528_1(void) = NoOp : +# 2531| r2531_9(glval) = VariableAddress[y] : +# 2531| r2531_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2531| v2531_11(void) = Call[~ClassWithDestructor] : func:r2531_10, this:r2531_9 +# 2531| m2531_12(unknown) = ^CallSideEffect : ~m2523_6 +# 2531| m2531_13(unknown) = Chi : total:m2523_6, partial:m2531_12 +# 2531| v2531_14(void) = ^IndirectReadSideEffect[-1] : &:r2531_9, m2523_8 +# 2531| m2531_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2531_9 +# 2531| m2531_16(ClassWithDestructor) = Chi : total:m2523_8, partial:m2531_15 +# 2529| v2529_1(void) = NoOp : +#-----| Goto -> Block 3 + +# 2531| Block 3 +# 2531| m2531_17(unknown) = Phi : from 1:~m2531_5, from 2:~m2531_13 +# 2531| v2531_18(void) = NoOp : +# 2532| v2532_1(void) = NoOp : +# 2522| v2522_7(void) = ReturnVoid : +# 2522| v2522_8(void) = AliasedUse : ~m2531_17 +# 2522| v2522_9(void) = ExitFunction : + +# 2534| void destructor_possibly_not_handled() +# 2534| Block 0 +# 2534| v2534_1(void) = EnterFunction : +# 2534| m2534_2(unknown) = AliasedDefinition : +# 2534| m2534_3(unknown) = InitializeNonLocal : +# 2534| m2534_4(unknown) = Chi : total:m2534_2, partial:m2534_3 +# 2535| r2535_1(glval) = VariableAddress[x] : +# 2535| m2535_2(ClassWithDestructor) = Uninitialized[x] : &:r2535_1 +# 2535| r2535_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2535| v2535_4(void) = Call[ClassWithDestructor] : func:r2535_3, this:r2535_1 +# 2535| m2535_5(unknown) = ^CallSideEffect : ~m2534_4 +# 2535| m2535_6(unknown) = Chi : total:m2534_4, partial:m2535_5 +# 2535| m2535_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2535_1 +# 2535| m2535_8(ClassWithDestructor) = Chi : total:m2535_2, partial:m2535_7 +# 2537| r2537_1(glval) = VariableAddress[#throw2537:5] : +# 2537| r2537_2(int) = Constant[42] : +# 2537| m2537_3(int) = Store[#throw2537:5] : &:r2537_1, r2537_2 +# 2537| v2537_4(void) = ThrowValue : &:r2537_1, m2537_3 +#-----| Exception -> Block 3 + +# 2534| Block 1 +# 2534| m2534_5(unknown) = Phi : from 2:~m2535_6, from 4:~m2541_14 +# 2534| v2534_6(void) = AliasedUse : ~m2534_5 +# 2534| v2534_7(void) = ExitFunction : + +# 2534| Block 2 +# 2534| v2534_8(void) = Unwind : +#-----| Goto -> Block 1 + +# 2539| Block 3 +# 2539| v2539_1(void) = CatchByType[char] : +#-----| Exception -> Block 2 +#-----| Goto -> Block 4 + +# 2539| Block 4 +# 2539| r2539_2(glval) = VariableAddress[(unnamed parameter 0)] : +# 2539| m2539_3(char) = InitializeParameter[(unnamed parameter 0)] : &:r2539_2 +# 2539| v2539_4(void) = NoOp : +# 2541| r2541_1(glval) = VariableAddress[x] : +# 2541| r2541_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2541| v2541_3(void) = Call[~ClassWithDestructor] : func:r2541_2, this:r2541_1 +# 2541| m2541_4(unknown) = ^CallSideEffect : ~m2535_6 +# 2541| m2541_5(unknown) = Chi : total:m2535_6, partial:m2541_4 +# 2541| v2541_6(void) = ^IndirectReadSideEffect[-1] : &:r2541_1, m2535_8 +# 2541| m2541_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2541_1 +# 2541| m2541_8(ClassWithDestructor) = Chi : total:m2535_8, partial:m2541_7 +# 2541| v2541_9(void) = NoOp : +# 2541| r2541_10(glval) = VariableAddress[x] : +# 2541| r2541_11(glval) = FunctionAddress[~ClassWithDestructor] : +# 2541| v2541_12(void) = Call[~ClassWithDestructor] : func:r2541_11, this:r2541_10 +# 2541| m2541_13(unknown) = ^CallSideEffect : ~m2541_5 +# 2541| m2541_14(unknown) = Chi : total:m2541_5, partial:m2541_13 +# 2541| v2541_15(void) = ^IndirectReadSideEffect[-1] : &:r2541_10, m2541_8 +# 2541| m2541_16(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2541_10 +# 2541| m2541_17(ClassWithDestructor) = Chi : total:m2541_8, partial:m2541_16 +# 2534| v2534_9(void) = ReturnVoid : +#-----| Goto -> Block 1 + +# 2545| void this_inconsistency(bool) +# 2545| Block 0 +# 2545| v2545_1(void) = EnterFunction : +# 2545| m2545_2(unknown) = AliasedDefinition : +# 2545| m2545_3(unknown) = InitializeNonLocal : +# 2545| m2545_4(unknown) = Chi : total:m2545_2, partial:m2545_3 +# 2545| r2545_5(glval) = VariableAddress[b] : +# 2545| m2545_6(bool) = InitializeParameter[b] : &:r2545_5 +# 2546| r2546_1(glval) = VariableAddress[a] : +# 2546| r2546_2(glval) = VariableAddress[#temp2546:38] : +# 2546| r2546_3(glval) = FunctionAddress[getClassWithDestructor] : +# 2546| r2546_4(ClassWithDestructor) = Call[getClassWithDestructor] : func:r2546_3 +# 2546| m2546_5(unknown) = ^CallSideEffect : ~m2545_4 +# 2546| m2546_6(unknown) = Chi : total:m2545_4, partial:m2546_5 +# 2546| m2546_7(ClassWithDestructor) = Store[#temp2546:38] : &:r2546_2, r2546_4 +# 2546| m2546_8(unknown) = Chi : total:m2546_6, partial:m2546_7 +# 2546| r2546_9(glval) = Convert : r2546_2 +# 2546| r2546_10(ClassWithDestructor &) = CopyValue : r2546_9 +# 2546| m2546_11(ClassWithDestructor &) = Store[a] : &:r2546_1, r2546_10 +# 2546| r2546_12(glval) = VariableAddress[a] : +# 2546| r2546_13(ClassWithDestructor &) = Load[a] : &:r2546_12, m2546_11 +# 2546| r2546_14(ClassWithDestructor) = CopyValue : r2546_13 +# 2546| r2546_15(glval) = FunctionAddress[operator bool] : +# 2546| r2546_16(bool) = Call[operator bool] : func:r2546_15, this:r2546_14 +# 2546| m2546_17(unknown) = ^CallSideEffect : ~m2546_8 +# 2546| m2546_18(unknown) = Chi : total:m2546_8, partial:m2546_17 +# 2546| v2546_19(void) = ^IndirectReadSideEffect[-1] : &:r2546_14, ~m2546_18 +# 2546| r2546_20(bool) = CopyValue : r2546_16 +# 2546| v2546_21(void) = ConditionalBranch : r2546_20 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 2547| Block 1 +# 2547| v2547_1(void) = NoOp : +# 2547| r2547_2(glval) = CopyValue : r2546_2 +# 2547| r2547_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2547| v2547_4(void) = Call[~ClassWithDestructor] : func:r2547_3, this:r2547_2 +# 2547| m2547_5(unknown) = ^CallSideEffect : ~m2546_18 +# 2547| m2547_6(unknown) = Chi : total:m2546_18, partial:m2547_5 +# 2547| v2547_7(void) = ^IndirectReadSideEffect[-1] : &:r2547_2, ~m2547_6 +# 2547| m2547_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2547_2 +# 2547| m2547_9(unknown) = Chi : total:m2547_6, partial:m2547_8 +#-----| Goto -> Block 2 + +# 2548| Block 2 +# 2548| m2548_1(unknown) = Phi : from 0:~m2546_18, from 1:~m2547_9 +# 2548| v2548_2(void) = NoOp : +# 2545| v2545_7(void) = ReturnVoid : +# 2545| v2545_8(void) = AliasedUse : ~m2548_1 +# 2545| v2545_9(void) = ExitFunction : + +# 2550| void constexpr_inconsistency(bool) +# 2550| Block 0 +# 2550| v2550_1(void) = EnterFunction : +# 2550| m2550_2(unknown) = AliasedDefinition : +# 2550| m2550_3(unknown) = InitializeNonLocal : +# 2550| m2550_4(unknown) = Chi : total:m2550_2, partial:m2550_3 +# 2550| r2550_5(glval) = VariableAddress[b] : +# 2550| m2550_6(bool) = InitializeParameter[b] : &:r2550_5 +# 2551| r2551_1(glval) = VariableAddress[a] : +# 2551| r2551_2(glval) = VariableAddress[#temp2551:48] : +# 2551| r2551_3(glval) = FunctionAddress[getClassWithDestructor] : +# 2551| r2551_4(ClassWithDestructor) = Call[getClassWithDestructor] : func:r2551_3 +# 2551| m2551_5(unknown) = ^CallSideEffect : ~m2550_4 +# 2551| m2551_6(unknown) = Chi : total:m2550_4, partial:m2551_5 +# 2551| m2551_7(ClassWithDestructor) = Store[#temp2551:48] : &:r2551_2, r2551_4 +# 2551| r2551_8(glval) = Convert : r2551_2 +# 2551| r2551_9(ClassWithDestructor &) = CopyValue : r2551_8 +# 2551| m2551_10(ClassWithDestructor &) = Store[a] : &:r2551_1, r2551_9 +# 2551| r2551_11(bool) = Constant[1] : +# 2551| v2551_12(void) = ConditionalBranch : r2551_11 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 2552| Block 1 +# 2552| v2552_1(void) = NoOp : +# 2553| v2553_1(void) = NoOp : +# 2550| v2550_7(void) = ReturnVoid : +# 2550| v2550_8(void) = AliasedUse : ~m2551_6 +# 2550| v2550_9(void) = ExitFunction : + +# 2550| Block 2 +# 2550| v2550_10(void) = Unreached : perf-regression.cpp: # 6| void Big::Big() diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected index 8f472b49f273..5a0234a4cc42 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected @@ -27,6 +27,7 @@ invalidOverlap nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer +| ir.cpp:2546:34:2546:34 | Call: call to operator bool | Call instruction 'Call: call to operator bool' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:2545:6:2545:23 | void this_inconsistency(bool) | void this_inconsistency(bool) | nonUniqueIRVariable | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected index 8f472b49f273..5a0234a4cc42 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected @@ -27,6 +27,7 @@ invalidOverlap nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer +| ir.cpp:2546:34:2546:34 | Call: call to operator bool | Call instruction 'Call: call to operator bool' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:2545:6:2545:23 | void this_inconsistency(bool) | void this_inconsistency(bool) | nonUniqueIRVariable | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index 17bfd2f90893..3c6b1cdbbf01 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -2191,6 +2191,7 @@ class ClassWithDestructor { void set_x(char y) { *x = y; } char get_x() { return *x; } + operator bool() const; }; constexpr bool initialization_with_destructor_bool = true; @@ -2432,7 +2433,7 @@ void initialization_with_temp_destructor() { } void param_with_destructor_by_value(ClassWithDestructor c) { - // The call to ~ClassWithDestructor::ClassWithDestructor() seems to be missing here. + // The call to ~ClassWithDestructor::ClassWithDestructor() happens on the side of the caller } void param_with_destructor_by_pointer(ClassWithDestructor* c) { @@ -2481,4 +2482,74 @@ namespace rvalue_conversion_with_destructor { } } +void destructor_without_block(bool b) +{ + if (b) + ClassWithDestructor c; + + if (b) + ClassWithDestructor d; + else + ClassWithDestructor e; + + while (b) + ClassWithDestructor f; + + for(int i = 0; i < 42; ++i) + ClassWithDestructor g; +} + +void destruction_in_switch_1(int c) { + switch (c) { + case 0: { + ClassWithDestructor x; + break; + } + } +} + +void destruction_in_switch_2(int c) { + switch (ClassWithDestructor y; c) { + case 0: { + break; + } + default: { + break; + } + } +} + +void destruction_in_switch_3(int c) { + switch (ClassWithDestructor y; c) { + case 0: { + ClassWithDestructor x; + break; + } + default: { + break; + } + } +} + +void destructor_possibly_not_handled() { + ClassWithDestructor x; + try { + throw 42; + } + catch(char) { + } +} + +ClassWithDestructor getClassWithDestructor(); + +void this_inconsistency(bool b) { + if (const ClassWithDestructor& a = getClassWithDestructor()) + ; +} + +void constexpr_inconsistency(bool b) { + if constexpr (const ClassWithDestructor& a = getClassWithDestructor(); initialization_with_destructor_bool) + ; +} + // semmle-extractor-options: -std=c++20 --clang diff --git a/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected b/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected index 11dd363ebc52..926444e16747 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected @@ -21,6 +21,7 @@ lostReachability backEdgeCountMismatch useNotDominatedByDefinition | ir.cpp:1535:8:1535:8 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | ir.cpp:1535:8:1535:8 | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() | +| ir.cpp:2551:48:2551:71 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | ir.cpp:2550:6:2550:28 | void constexpr_inconsistency(bool) | void constexpr_inconsistency(bool) | | try_except.c:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:6:6:6:6 | void f() | void f() | | try_except.c:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:6:6:6:6 | void f() | void f() | | try_except.c:39:15:39:15 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:32:6:32:6 | void h(int) | void h(int) | @@ -36,6 +37,7 @@ invalidOverlap nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer +| ir.cpp:2546:34:2546:34 | Call: call to operator bool | Call instruction 'Call: call to operator bool' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:2545:6:2545:23 | void this_inconsistency(bool) | void this_inconsistency(bool) | nonUniqueIRVariable | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 7c0a525d0ca0..434da18f6beb 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -14108,2141 +14108,2596 @@ ir.cpp: # 2193| v2193_18(void) = AliasedUse : ~m? # 2193| v2193_19(void) = ExitFunction : -# 2196| bool initialization_with_destructor_bool -# 2196| Block 0 -# 2196| v2196_1(void) = EnterFunction : -# 2196| mu2196_2(unknown) = AliasedDefinition : -# 2196| r2196_3(glval) = VariableAddress[initialization_with_destructor_bool] : -# 2196| r2196_4(bool) = Constant[1] : -# 2196| mu2196_5(bool) = Store[initialization_with_destructor_bool] : &:r2196_3, r2196_4 -# 2196| v2196_6(void) = ReturnVoid : -# 2196| v2196_7(void) = AliasedUse : ~m? -# 2196| v2196_8(void) = ExitFunction : - -# 2198| void initialization_with_destructor(bool, char) -# 2198| Block 0 -# 2198| v2198_1(void) = EnterFunction : -# 2198| mu2198_2(unknown) = AliasedDefinition : -# 2198| mu2198_3(unknown) = InitializeNonLocal : -# 2198| r2198_4(glval) = VariableAddress[b] : -# 2198| mu2198_5(bool) = InitializeParameter[b] : &:r2198_4 -# 2198| r2198_6(glval) = VariableAddress[c] : -# 2198| mu2198_7(char) = InitializeParameter[c] : &:r2198_6 -# 2199| r2199_1(glval) = VariableAddress[x] : -# 2199| mu2199_2(ClassWithDestructor) = Uninitialized[x] : &:r2199_1 -# 2199| r2199_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2199| v2199_4(void) = Call[ClassWithDestructor] : func:r2199_3, this:r2199_1 -# 2199| mu2199_5(unknown) = ^CallSideEffect : ~m? -# 2199| mu2199_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2199_1 -# 2199| r2199_7(glval) = VariableAddress[b] : -# 2199| r2199_8(bool) = Load[b] : &:r2199_7, ~m? -# 2199| v2199_9(void) = ConditionalBranch : r2199_8 +# 2197| bool initialization_with_destructor_bool +# 2197| Block 0 +# 2197| v2197_1(void) = EnterFunction : +# 2197| mu2197_2(unknown) = AliasedDefinition : +# 2197| r2197_3(glval) = VariableAddress[initialization_with_destructor_bool] : +# 2197| r2197_4(bool) = Constant[1] : +# 2197| mu2197_5(bool) = Store[initialization_with_destructor_bool] : &:r2197_3, r2197_4 +# 2197| v2197_6(void) = ReturnVoid : +# 2197| v2197_7(void) = AliasedUse : ~m? +# 2197| v2197_8(void) = ExitFunction : + +# 2199| void initialization_with_destructor(bool, char) +# 2199| Block 0 +# 2199| v2199_1(void) = EnterFunction : +# 2199| mu2199_2(unknown) = AliasedDefinition : +# 2199| mu2199_3(unknown) = InitializeNonLocal : +# 2199| r2199_4(glval) = VariableAddress[b] : +# 2199| mu2199_5(bool) = InitializeParameter[b] : &:r2199_4 +# 2199| r2199_6(glval) = VariableAddress[c] : +# 2199| mu2199_7(char) = InitializeParameter[c] : &:r2199_6 +# 2200| r2200_1(glval) = VariableAddress[x] : +# 2200| mu2200_2(ClassWithDestructor) = Uninitialized[x] : &:r2200_1 +# 2200| r2200_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2200| v2200_4(void) = Call[ClassWithDestructor] : func:r2200_3, this:r2200_1 +# 2200| mu2200_5(unknown) = ^CallSideEffect : ~m? +# 2200| mu2200_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2200_1 +# 2200| r2200_7(glval) = VariableAddress[b] : +# 2200| r2200_8(bool) = Load[b] : &:r2200_7, ~m? +# 2200| v2200_9(void) = ConditionalBranch : r2200_8 #-----| False -> Block 3 #-----| True -> Block 2 -# 2198| Block 1 -# 2198| v2198_8(void) = ReturnVoid : -# 2198| v2198_9(void) = AliasedUse : ~m? -# 2198| v2198_10(void) = ExitFunction : - -# 2200| Block 2 -# 2200| r2200_1(glval) = VariableAddress[x] : -# 2200| r2200_2(glval) = FunctionAddress[set_x] : -# 2200| r2200_3(char) = Constant[97] : -# 2200| v2200_4(void) = Call[set_x] : func:r2200_2, this:r2200_1, 0:r2200_3 -# 2200| mu2200_5(unknown) = ^CallSideEffect : ~m? -# 2200| v2200_6(void) = ^IndirectReadSideEffect[-1] : &:r2200_1, ~m? -# 2200| mu2200_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2200_1 -# 2200| r2200_8(glval) = VariableAddress[x] : -# 2200| r2200_9(glval) = FunctionAddress[~ClassWithDestructor] : -# 2200| v2200_10(void) = Call[~ClassWithDestructor] : func:r2200_9, this:r2200_8 -# 2200| mu2200_11(unknown) = ^CallSideEffect : ~m? -# 2200| v2200_12(void) = ^IndirectReadSideEffect[-1] : &:r2200_8, ~m? -# 2200| mu2200_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2200_8 +# 2199| Block 1 +# 2199| v2199_8(void) = ReturnVoid : +# 2199| v2199_9(void) = AliasedUse : ~m? +# 2199| v2199_10(void) = ExitFunction : + +# 2201| Block 2 +# 2201| r2201_1(glval) = VariableAddress[x] : +# 2201| r2201_2(glval) = FunctionAddress[set_x] : +# 2201| r2201_3(char) = Constant[97] : +# 2201| v2201_4(void) = Call[set_x] : func:r2201_2, this:r2201_1, 0:r2201_3 +# 2201| mu2201_5(unknown) = ^CallSideEffect : ~m? +# 2201| v2201_6(void) = ^IndirectReadSideEffect[-1] : &:r2201_1, ~m? +# 2201| mu2201_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2201_1 +# 2201| r2201_8(glval) = VariableAddress[x] : +# 2201| r2201_9(glval) = FunctionAddress[~ClassWithDestructor] : +# 2201| v2201_10(void) = Call[~ClassWithDestructor] : func:r2201_9, this:r2201_8 +# 2201| mu2201_11(unknown) = ^CallSideEffect : ~m? +# 2201| v2201_12(void) = ^IndirectReadSideEffect[-1] : &:r2201_8, ~m? +# 2201| mu2201_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2201_8 #-----| Goto -> Block 3 -# 2202| Block 3 -# 2202| r2202_1(glval) = VariableAddress[x] : -# 2202| mu2202_2(ClassWithDestructor) = Uninitialized[x] : &:r2202_1 -# 2202| r2202_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2202| v2202_4(void) = Call[ClassWithDestructor] : func:r2202_3, this:r2202_1 -# 2202| mu2202_5(unknown) = ^CallSideEffect : ~m? -# 2202| mu2202_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2202_1 -# 2202| r2202_7(bool) = Constant[1] : -# 2202| v2202_8(void) = ConditionalBranch : r2202_7 +# 2203| Block 3 +# 2203| r2203_1(glval) = VariableAddress[x] : +# 2203| mu2203_2(ClassWithDestructor) = Uninitialized[x] : &:r2203_1 +# 2203| r2203_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2203| v2203_4(void) = Call[ClassWithDestructor] : func:r2203_3, this:r2203_1 +# 2203| mu2203_5(unknown) = ^CallSideEffect : ~m? +# 2203| mu2203_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2203_1 +# 2203| r2203_7(bool) = Constant[1] : +# 2203| v2203_8(void) = ConditionalBranch : r2203_7 #-----| False -> Block 6 #-----| True -> Block 4 -# 2203| Block 4 -# 2203| r2203_1(glval) = VariableAddress[x] : -# 2203| r2203_2(glval) = FunctionAddress[set_x] : -# 2203| r2203_3(char) = Constant[97] : -# 2203| v2203_4(void) = Call[set_x] : func:r2203_2, this:r2203_1, 0:r2203_3 -# 2203| mu2203_5(unknown) = ^CallSideEffect : ~m? -# 2203| v2203_6(void) = ^IndirectReadSideEffect[-1] : &:r2203_1, ~m? -# 2203| mu2203_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2203_1 +# 2204| Block 4 +# 2204| r2204_1(glval) = VariableAddress[x] : +# 2204| r2204_2(glval) = FunctionAddress[set_x] : +# 2204| r2204_3(char) = Constant[97] : +# 2204| v2204_4(void) = Call[set_x] : func:r2204_2, this:r2204_1, 0:r2204_3 +# 2204| mu2204_5(unknown) = ^CallSideEffect : ~m? +# 2204| v2204_6(void) = ^IndirectReadSideEffect[-1] : &:r2204_1, ~m? +# 2204| mu2204_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2204_1 #-----| Goto -> Block 6 -# 2203| Block 5 -# 2203| r2203_8(glval) = VariableAddress[x] : -# 2203| r2203_9(glval) = FunctionAddress[~ClassWithDestructor] : -# 2203| v2203_10(void) = Call[~ClassWithDestructor] : func:r2203_9, this:r2203_8 -# 2203| mu2203_11(unknown) = ^CallSideEffect : ~m? -# 2203| v2203_12(void) = ^IndirectReadSideEffect[-1] : &:r2203_8, ~m? -# 2203| mu2203_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2203_8 +# 2204| Block 5 +# 2204| r2204_8(glval) = VariableAddress[x] : +# 2204| r2204_9(glval) = FunctionAddress[~ClassWithDestructor] : +# 2204| v2204_10(void) = Call[~ClassWithDestructor] : func:r2204_9, this:r2204_8 +# 2204| mu2204_11(unknown) = ^CallSideEffect : ~m? +# 2204| v2204_12(void) = ^IndirectReadSideEffect[-1] : &:r2204_8, ~m? +# 2204| mu2204_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2204_8 #-----| Goto -> Block 6 -# 2205| Block 6 -# 2205| r2205_1(glval) = VariableAddress[x] : -# 2205| mu2205_2(ClassWithDestructor) = Uninitialized[x] : &:r2205_1 -# 2205| r2205_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2205| v2205_4(void) = Call[ClassWithDestructor] : func:r2205_3, this:r2205_1 -# 2205| mu2205_5(unknown) = ^CallSideEffect : ~m? -# 2205| mu2205_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2205_1 -# 2205| r2205_7(glval) = VariableAddress[c] : -# 2205| r2205_8(char) = Load[c] : &:r2205_7, ~m? -# 2205| r2205_9(int) = Convert : r2205_8 -# 2205| v2205_10(void) = Switch : r2205_9 +# 2206| Block 6 +# 2206| r2206_1(glval) = VariableAddress[x] : +# 2206| mu2206_2(ClassWithDestructor) = Uninitialized[x] : &:r2206_1 +# 2206| r2206_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2206| v2206_4(void) = Call[ClassWithDestructor] : func:r2206_3, this:r2206_1 +# 2206| mu2206_5(unknown) = ^CallSideEffect : ~m? +# 2206| mu2206_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2206_1 +# 2206| r2206_7(glval) = VariableAddress[c] : +# 2206| r2206_8(char) = Load[c] : &:r2206_7, ~m? +# 2206| r2206_9(int) = Convert : r2206_8 +# 2206| v2206_10(void) = Switch : r2206_9 #-----| Case[97] -> Block 7 #-----| Default -> Block 8 -# 2206| Block 7 -# 2206| v2206_1(void) = NoOp : -# 2207| r2207_1(glval) = VariableAddress[x] : -# 2207| r2207_2(glval) = FunctionAddress[set_x] : -# 2207| r2207_3(char) = Constant[97] : -# 2207| v2207_4(void) = Call[set_x] : func:r2207_2, this:r2207_1, 0:r2207_3 -# 2207| mu2207_5(unknown) = ^CallSideEffect : ~m? -# 2207| v2207_6(void) = ^IndirectReadSideEffect[-1] : &:r2207_1, ~m? -# 2207| mu2207_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2207_1 -# 2208| v2208_1(void) = NoOp : +# 2207| Block 7 +# 2207| v2207_1(void) = NoOp : +# 2208| r2208_1(glval) = VariableAddress[x] : +# 2208| r2208_2(glval) = FunctionAddress[set_x] : +# 2208| r2208_3(char) = Constant[97] : +# 2208| v2208_4(void) = Call[set_x] : func:r2208_2, this:r2208_1, 0:r2208_3 +# 2208| mu2208_5(unknown) = ^CallSideEffect : ~m? +# 2208| v2208_6(void) = ^IndirectReadSideEffect[-1] : &:r2208_1, ~m? +# 2208| mu2208_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2208_1 +# 2213| r2213_1(glval) = VariableAddress[x] : +# 2213| r2213_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2213| v2213_3(void) = Call[~ClassWithDestructor] : func:r2213_2, this:r2213_1 +# 2213| mu2213_4(unknown) = ^CallSideEffect : ~m? +# 2213| v2213_5(void) = ^IndirectReadSideEffect[-1] : &:r2213_1, ~m? +# 2213| mu2213_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2213_1 +# 2209| v2209_1(void) = NoOp : #-----| Goto -> Block 10 -# 2209| Block 8 -# 2209| v2209_1(void) = NoOp : -# 2210| r2210_1(glval) = VariableAddress[x] : -# 2210| r2210_2(glval) = FunctionAddress[set_x] : -# 2210| r2210_3(char) = Constant[98] : -# 2210| v2210_4(void) = Call[set_x] : func:r2210_2, this:r2210_1, 0:r2210_3 -# 2210| mu2210_5(unknown) = ^CallSideEffect : ~m? -# 2210| v2210_6(void) = ^IndirectReadSideEffect[-1] : &:r2210_1, ~m? -# 2210| mu2210_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2210_1 -# 2211| v2211_1(void) = NoOp : +# 2210| Block 8 +# 2210| v2210_1(void) = NoOp : +# 2211| r2211_1(glval) = VariableAddress[x] : +# 2211| r2211_2(glval) = FunctionAddress[set_x] : +# 2211| r2211_3(char) = Constant[98] : +# 2211| v2211_4(void) = Call[set_x] : func:r2211_2, this:r2211_1, 0:r2211_3 +# 2211| mu2211_5(unknown) = ^CallSideEffect : ~m? +# 2211| v2211_6(void) = ^IndirectReadSideEffect[-1] : &:r2211_1, ~m? +# 2211| mu2211_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2211_1 +# 2213| r2213_7(glval) = VariableAddress[x] : +# 2213| r2213_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2213| v2213_9(void) = Call[~ClassWithDestructor] : func:r2213_8, this:r2213_7 +# 2213| mu2213_10(unknown) = ^CallSideEffect : ~m? +# 2213| v2213_11(void) = ^IndirectReadSideEffect[-1] : &:r2213_7, ~m? +# 2213| mu2213_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2213_7 +# 2212| v2212_1(void) = NoOp : #-----| Goto -> Block 10 -# 2212| Block 9 -# 2212| r2212_1(glval) = VariableAddress[x] : -# 2212| r2212_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2212| v2212_3(void) = Call[~ClassWithDestructor] : func:r2212_2, this:r2212_1 -# 2212| mu2212_4(unknown) = ^CallSideEffect : ~m? -# 2212| v2212_5(void) = ^IndirectReadSideEffect[-1] : &:r2212_1, ~m? -# 2212| mu2212_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2212_1 +# 2213| Block 9 +# 2213| r2213_13(glval) = VariableAddress[x] : +# 2213| r2213_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2213| v2213_15(void) = Call[~ClassWithDestructor] : func:r2213_14, this:r2213_13 +# 2213| mu2213_16(unknown) = ^CallSideEffect : ~m? +# 2213| v2213_17(void) = ^IndirectReadSideEffect[-1] : &:r2213_13, ~m? +# 2213| mu2213_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2213_13 #-----| Goto -> Block 10 -# 2212| Block 10 -# 2212| v2212_7(void) = NoOp : -# 2214| r2214_1(glval) = VariableAddress[x] : -# 2214| mu2214_2(ClassWithDestructor) = Uninitialized[x] : &:r2214_1 -# 2214| r2214_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2214| v2214_4(void) = Call[ClassWithDestructor] : func:r2214_3, this:r2214_1 -# 2214| mu2214_5(unknown) = ^CallSideEffect : ~m? -# 2214| mu2214_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2214_1 -# 2215| r2215_1(glval>) = VariableAddress[ys] : -# 2215| mu2215_2(vector) = Uninitialized[ys] : &:r2215_1 -# 2215| r2215_3(glval) = FunctionAddress[vector] : -# 2215| r2215_4(glval) = VariableAddress[#temp2215:45] : -# 2215| r2215_5(glval) = VariableAddress[x] : -# 2215| r2215_6(ClassWithDestructor) = Load[x] : &:r2215_5, ~m? -# 2215| mu2215_7(ClassWithDestructor) = Store[#temp2215:45] : &:r2215_4, r2215_6 -# 2215| r2215_8(ClassWithDestructor) = Load[#temp2215:45] : &:r2215_4, ~m? -# 2215| v2215_9(void) = Call[vector] : func:r2215_3, this:r2215_1, 0:r2215_8 -# 2215| mu2215_10(unknown) = ^CallSideEffect : ~m? -# 2215| mu2215_11(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2215_1 -# 2215| r2215_12(glval) = CopyValue : r2215_4 -# 2215| r2215_13(glval) = FunctionAddress[~ClassWithDestructor] : -# 2215| v2215_14(void) = Call[~ClassWithDestructor] : func:r2215_13, this:r2215_12 -# 2215| mu2215_15(unknown) = ^CallSideEffect : ~m? -# 2215| v2215_16(void) = ^IndirectReadSideEffect[-1] : &:r2215_12, ~m? -# 2215| mu2215_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_12 -# 2215| r2215_18(glval &>) = VariableAddress[(__range)] : -# 2215| r2215_19(glval>) = VariableAddress[ys] : -# 2215| r2215_20(vector &) = CopyValue : r2215_19 -# 2215| mu2215_21(vector &) = Store[(__range)] : &:r2215_18, r2215_20 -# 2215| r2215_22(glval>) = VariableAddress[(__begin)] : -# 2215| r2215_23(glval &>) = VariableAddress[(__range)] : -# 2215| r2215_24(vector &) = Load[(__range)] : &:r2215_23, ~m? -#-----| r0_1(glval>) = CopyValue : r2215_24 +# 2213| Block 10 +# 2213| v2213_19(void) = NoOp : +# 2215| r2215_1(glval) = VariableAddress[x] : +# 2215| mu2215_2(ClassWithDestructor) = Uninitialized[x] : &:r2215_1 +# 2215| r2215_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2215| v2215_4(void) = Call[ClassWithDestructor] : func:r2215_3, this:r2215_1 +# 2215| mu2215_5(unknown) = ^CallSideEffect : ~m? +# 2215| mu2215_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_1 +# 2216| r2216_1(glval>) = VariableAddress[ys] : +# 2216| mu2216_2(vector) = Uninitialized[ys] : &:r2216_1 +# 2216| r2216_3(glval) = FunctionAddress[vector] : +# 2216| r2216_4(glval) = VariableAddress[#temp2216:45] : +# 2216| r2216_5(glval) = VariableAddress[x] : +# 2216| r2216_6(ClassWithDestructor) = Load[x] : &:r2216_5, ~m? +# 2216| mu2216_7(ClassWithDestructor) = Store[#temp2216:45] : &:r2216_4, r2216_6 +# 2216| r2216_8(ClassWithDestructor) = Load[#temp2216:45] : &:r2216_4, ~m? +# 2216| v2216_9(void) = Call[vector] : func:r2216_3, this:r2216_1, 0:r2216_8 +# 2216| mu2216_10(unknown) = ^CallSideEffect : ~m? +# 2216| mu2216_11(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2216_1 +# 2216| r2216_12(glval) = CopyValue : r2216_4 +# 2216| r2216_13(glval) = FunctionAddress[~ClassWithDestructor] : +# 2216| v2216_14(void) = Call[~ClassWithDestructor] : func:r2216_13, this:r2216_12 +# 2216| mu2216_15(unknown) = ^CallSideEffect : ~m? +# 2216| v2216_16(void) = ^IndirectReadSideEffect[-1] : &:r2216_12, ~m? +# 2216| mu2216_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_12 +# 2216| r2216_18(glval &>) = VariableAddress[(__range)] : +# 2216| r2216_19(glval>) = VariableAddress[ys] : +# 2216| r2216_20(vector &) = CopyValue : r2216_19 +# 2216| mu2216_21(vector &) = Store[(__range)] : &:r2216_18, r2216_20 +# 2216| r2216_22(glval>) = VariableAddress[(__begin)] : +# 2216| r2216_23(glval &>) = VariableAddress[(__range)] : +# 2216| r2216_24(vector &) = Load[(__range)] : &:r2216_23, ~m? +#-----| r0_1(glval>) = CopyValue : r2216_24 #-----| r0_2(glval>) = Convert : r0_1 -# 2215| r2215_25(glval) = FunctionAddress[begin] : -# 2215| r2215_26(iterator) = Call[begin] : func:r2215_25, this:r0_2 +# 2216| r2216_25(glval) = FunctionAddress[begin] : +# 2216| r2216_26(iterator) = Call[begin] : func:r2216_25, this:r0_2 #-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m? -# 2215| mu2215_27(iterator) = Store[(__begin)] : &:r2215_22, r2215_26 -# 2215| r2215_28(glval>) = VariableAddress[(__end)] : -# 2215| r2215_29(glval &>) = VariableAddress[(__range)] : -# 2215| r2215_30(vector &) = Load[(__range)] : &:r2215_29, ~m? -#-----| r0_4(glval>) = CopyValue : r2215_30 +# 2216| mu2216_27(iterator) = Store[(__begin)] : &:r2216_22, r2216_26 +# 2216| r2216_28(glval>) = VariableAddress[(__end)] : +# 2216| r2216_29(glval &>) = VariableAddress[(__range)] : +# 2216| r2216_30(vector &) = Load[(__range)] : &:r2216_29, ~m? +#-----| r0_4(glval>) = CopyValue : r2216_30 #-----| r0_5(glval>) = Convert : r0_4 -# 2215| r2215_31(glval) = FunctionAddress[end] : -# 2215| r2215_32(iterator) = Call[end] : func:r2215_31, this:r0_5 +# 2216| r2216_31(glval) = FunctionAddress[end] : +# 2216| r2216_32(iterator) = Call[end] : func:r2216_31, this:r0_5 #-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m? -# 2215| mu2215_33(iterator) = Store[(__end)] : &:r2215_28, r2215_32 +# 2216| mu2216_33(iterator) = Store[(__end)] : &:r2216_28, r2216_32 #-----| Goto -> Block 11 -# 2215| Block 11 -# 2215| r2215_34(glval>) = VariableAddress[(__begin)] : -#-----| r0_7(glval>) = Convert : r2215_34 -# 2215| r2215_35(glval) = FunctionAddress[operator!=] : +# 2216| Block 11 +# 2216| r2216_34(glval>) = VariableAddress[(__begin)] : +#-----| r0_7(glval>) = Convert : r2216_34 +# 2216| r2216_35(glval) = FunctionAddress[operator!=] : #-----| r0_8(glval>) = VariableAddress[#temp0:0] : #-----| mu0_9(iterator) = Uninitialized[#temp0:0] : &:r0_8 -# 2215| r2215_36(glval) = FunctionAddress[iterator] : -# 2215| r2215_37(glval>) = VariableAddress[(__end)] : -#-----| r0_10(glval>) = Convert : r2215_37 +# 2216| r2216_36(glval) = FunctionAddress[iterator] : +# 2216| r2216_37(glval>) = VariableAddress[(__end)] : +#-----| r0_10(glval>) = Convert : r2216_37 #-----| r0_11(iterator &) = CopyValue : r0_10 -# 2215| v2215_38(void) = Call[iterator] : func:r2215_36, this:r0_8, 0:r0_11 -# 2215| mu2215_39(unknown) = ^CallSideEffect : ~m? +# 2216| v2216_38(void) = Call[iterator] : func:r2216_36, this:r0_8, 0:r0_11 +# 2216| mu2216_39(unknown) = ^CallSideEffect : ~m? #-----| v0_12(void) = ^BufferReadSideEffect[0] : &:r0_11, ~m? -# 2215| mu2215_40(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 2216| mu2216_40(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 #-----| r0_13(iterator) = Load[#temp0:0] : &:r0_8, ~m? -# 2215| r2215_41(bool) = Call[operator!=] : func:r2215_35, this:r0_7, 0:r0_13 +# 2216| r2216_41(bool) = Call[operator!=] : func:r2216_35, this:r0_7, 0:r0_13 #-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~m? -# 2215| v2215_42(void) = ConditionalBranch : r2215_41 -#-----| False -> Block 14 +# 2216| v2216_42(void) = ConditionalBranch : r2216_41 +#-----| False -> Block 13 #-----| True -> Block 12 -# 2215| Block 12 -# 2215| r2215_43(glval) = VariableAddress[y] : -# 2215| r2215_44(glval>) = VariableAddress[(__begin)] : -#-----| r0_15(glval>) = Convert : r2215_44 -# 2215| r2215_45(glval) = FunctionAddress[operator*] : -# 2215| r2215_46(ClassWithDestructor &) = Call[operator*] : func:r2215_45, this:r0_15 +# 2216| Block 12 +# 2216| r2216_43(glval) = VariableAddress[y] : +# 2216| r2216_44(glval>) = VariableAddress[(__begin)] : +#-----| r0_15(glval>) = Convert : r2216_44 +# 2216| r2216_45(glval) = FunctionAddress[operator*] : +# 2216| r2216_46(ClassWithDestructor &) = Call[operator*] : func:r2216_45, this:r0_15 #-----| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_15, ~m? -# 2215| r2215_47(ClassWithDestructor) = Load[?] : &:r2215_46, ~m? -# 2215| mu2215_48(ClassWithDestructor) = Store[y] : &:r2215_43, r2215_47 -# 2216| r2216_1(glval) = VariableAddress[y] : -# 2216| r2216_2(glval) = FunctionAddress[set_x] : -# 2216| r2216_3(char) = Constant[97] : -# 2216| v2216_4(void) = Call[set_x] : func:r2216_2, this:r2216_1, 0:r2216_3 -# 2216| mu2216_5(unknown) = ^CallSideEffect : ~m? -# 2216| v2216_6(void) = ^IndirectReadSideEffect[-1] : &:r2216_1, ~m? -# 2216| mu2216_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_1 -# 2215| r2215_49(glval) = VariableAddress[y] : -# 2215| r2215_50(glval) = FunctionAddress[~ClassWithDestructor] : -# 2215| v2215_51(void) = Call[~ClassWithDestructor] : func:r2215_50, this:r2215_49 -# 2215| mu2215_52(unknown) = ^CallSideEffect : ~m? -# 2215| v2215_53(void) = ^IndirectReadSideEffect[-1] : &:r2215_49, ~m? -# 2215| mu2215_54(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_49 -# 2215| r2215_55(glval>) = VariableAddress[(__begin)] : -# 2215| r2215_56(glval) = FunctionAddress[operator++] : -# 2215| r2215_57(iterator &) = Call[operator++] : func:r2215_56, this:r2215_55 -# 2215| v2215_58(void) = ^IndirectReadSideEffect[-1] : &:r2215_55, ~m? -# 2215| mu2215_59(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2215_55 -# 2215| r2215_60(glval>) = CopyValue : r2215_57 +# 2216| r2216_47(ClassWithDestructor) = Load[?] : &:r2216_46, ~m? +# 2216| mu2216_48(ClassWithDestructor) = Store[y] : &:r2216_43, r2216_47 +# 2217| r2217_1(glval) = VariableAddress[y] : +# 2217| r2217_2(glval) = FunctionAddress[set_x] : +# 2217| r2217_3(char) = Constant[97] : +# 2217| v2217_4(void) = Call[set_x] : func:r2217_2, this:r2217_1, 0:r2217_3 +# 2217| mu2217_5(unknown) = ^CallSideEffect : ~m? +# 2217| v2217_6(void) = ^IndirectReadSideEffect[-1] : &:r2217_1, ~m? +# 2217| mu2217_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2217_1 +# 2216| r2216_49(glval>) = VariableAddress[(__begin)] : +# 2216| r2216_50(glval) = FunctionAddress[operator++] : +# 2216| r2216_51(iterator &) = Call[operator++] : func:r2216_50, this:r2216_49 +# 2216| v2216_52(void) = ^IndirectReadSideEffect[-1] : &:r2216_49, ~m? +# 2216| mu2216_53(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2216_49 +# 2216| r2216_54(glval) = VariableAddress[y] : +# 2216| r2216_55(glval) = FunctionAddress[~ClassWithDestructor] : +# 2216| v2216_56(void) = Call[~ClassWithDestructor] : func:r2216_55, this:r2216_54 +# 2216| mu2216_57(unknown) = ^CallSideEffect : ~m? +# 2216| v2216_58(void) = ^IndirectReadSideEffect[-1] : &:r2216_54, ~m? +# 2216| mu2216_59(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_54 +# 2216| r2216_60(glval>) = CopyValue : r2216_51 #-----| Goto (back edge) -> Block 11 -# 2215| Block 13 -# 2215| r2215_61(glval>) = VariableAddress[ys] : -# 2215| r2215_62(glval) = FunctionAddress[~vector] : -# 2215| v2215_63(void) = Call[~vector] : func:r2215_62, this:r2215_61 -# 2215| mu2215_64(unknown) = ^CallSideEffect : ~m? -# 2215| v2215_65(void) = ^IndirectReadSideEffect[-1] : &:r2215_61, ~m? -# 2215| mu2215_66(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2215_61 -#-----| Goto -> Block 14 - -# 2218| Block 14 -# 2218| r2218_1(glval>) = VariableAddress[ys] : -# 2218| mu2218_2(vector) = Uninitialized[ys] : &:r2218_1 -# 2218| r2218_3(glval) = FunctionAddress[vector] : -# 2218| r2218_4(glval) = VariableAddress[#temp2218:45] : -# 2218| r2218_5(glval) = VariableAddress[x] : -# 2218| r2218_6(ClassWithDestructor) = Load[x] : &:r2218_5, ~m? -# 2218| mu2218_7(ClassWithDestructor) = Store[#temp2218:45] : &:r2218_4, r2218_6 -# 2218| r2218_8(ClassWithDestructor) = Load[#temp2218:45] : &:r2218_4, ~m? -# 2218| v2218_9(void) = Call[vector] : func:r2218_3, this:r2218_1, 0:r2218_8 -# 2218| mu2218_10(unknown) = ^CallSideEffect : ~m? -# 2218| mu2218_11(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_1 -# 2218| r2218_12(glval) = CopyValue : r2218_4 -# 2218| r2218_13(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_14(void) = Call[~ClassWithDestructor] : func:r2218_13, this:r2218_12 -# 2218| mu2218_15(unknown) = ^CallSideEffect : ~m? -# 2218| v2218_16(void) = ^IndirectReadSideEffect[-1] : &:r2218_12, ~m? -# 2218| mu2218_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_12 -# 2218| r2218_18(glval &>) = VariableAddress[(__range)] : -# 2218| r2218_19(glval>) = VariableAddress[ys] : -# 2218| r2218_20(vector &) = CopyValue : r2218_19 -# 2218| mu2218_21(vector &) = Store[(__range)] : &:r2218_18, r2218_20 -# 2218| r2218_22(glval>) = VariableAddress[(__begin)] : -# 2218| r2218_23(glval &>) = VariableAddress[(__range)] : -# 2218| r2218_24(vector &) = Load[(__range)] : &:r2218_23, ~m? -#-----| r0_17(glval>) = CopyValue : r2218_24 +# 2216| Block 13 +# 2216| r2216_61(glval>) = VariableAddress[ys] : +# 2216| r2216_62(glval) = FunctionAddress[~vector] : +# 2216| v2216_63(void) = Call[~vector] : func:r2216_62, this:r2216_61 +# 2216| mu2216_64(unknown) = ^CallSideEffect : ~m? +# 2216| v2216_65(void) = ^IndirectReadSideEffect[-1] : &:r2216_61, ~m? +# 2216| mu2216_66(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2216_61 +# 2219| r2219_1(glval>) = VariableAddress[ys] : +# 2219| mu2219_2(vector) = Uninitialized[ys] : &:r2219_1 +# 2219| r2219_3(glval) = FunctionAddress[vector] : +# 2219| r2219_4(glval) = VariableAddress[#temp2219:45] : +# 2219| r2219_5(glval) = VariableAddress[x] : +# 2219| r2219_6(ClassWithDestructor) = Load[x] : &:r2219_5, ~m? +# 2219| mu2219_7(ClassWithDestructor) = Store[#temp2219:45] : &:r2219_4, r2219_6 +# 2219| r2219_8(ClassWithDestructor) = Load[#temp2219:45] : &:r2219_4, ~m? +# 2219| v2219_9(void) = Call[vector] : func:r2219_3, this:r2219_1, 0:r2219_8 +# 2219| mu2219_10(unknown) = ^CallSideEffect : ~m? +# 2219| mu2219_11(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2219_1 +# 2219| r2219_12(glval) = CopyValue : r2219_4 +# 2219| r2219_13(glval) = FunctionAddress[~ClassWithDestructor] : +# 2219| v2219_14(void) = Call[~ClassWithDestructor] : func:r2219_13, this:r2219_12 +# 2219| mu2219_15(unknown) = ^CallSideEffect : ~m? +# 2219| v2219_16(void) = ^IndirectReadSideEffect[-1] : &:r2219_12, ~m? +# 2219| mu2219_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_12 +# 2219| r2219_18(glval &>) = VariableAddress[(__range)] : +# 2219| r2219_19(glval>) = VariableAddress[ys] : +# 2219| r2219_20(vector &) = CopyValue : r2219_19 +# 2219| mu2219_21(vector &) = Store[(__range)] : &:r2219_18, r2219_20 +# 2219| r2219_22(glval>) = VariableAddress[(__begin)] : +# 2219| r2219_23(glval &>) = VariableAddress[(__range)] : +# 2219| r2219_24(vector &) = Load[(__range)] : &:r2219_23, ~m? +#-----| r0_17(glval>) = CopyValue : r2219_24 #-----| r0_18(glval>) = Convert : r0_17 -# 2218| r2218_25(glval) = FunctionAddress[begin] : -# 2218| r2218_26(iterator) = Call[begin] : func:r2218_25, this:r0_18 +# 2219| r2219_25(glval) = FunctionAddress[begin] : +# 2219| r2219_26(iterator) = Call[begin] : func:r2219_25, this:r0_18 #-----| v0_19(void) = ^IndirectReadSideEffect[-1] : &:r0_18, ~m? -# 2218| mu2218_27(iterator) = Store[(__begin)] : &:r2218_22, r2218_26 -# 2218| r2218_28(glval>) = VariableAddress[(__end)] : -# 2218| r2218_29(glval &>) = VariableAddress[(__range)] : -# 2218| r2218_30(vector &) = Load[(__range)] : &:r2218_29, ~m? -#-----| r0_20(glval>) = CopyValue : r2218_30 +# 2219| mu2219_27(iterator) = Store[(__begin)] : &:r2219_22, r2219_26 +# 2219| r2219_28(glval>) = VariableAddress[(__end)] : +# 2219| r2219_29(glval &>) = VariableAddress[(__range)] : +# 2219| r2219_30(vector &) = Load[(__range)] : &:r2219_29, ~m? +#-----| r0_20(glval>) = CopyValue : r2219_30 #-----| r0_21(glval>) = Convert : r0_20 -# 2218| r2218_31(glval) = FunctionAddress[end] : -# 2218| r2218_32(iterator) = Call[end] : func:r2218_31, this:r0_21 +# 2219| r2219_31(glval) = FunctionAddress[end] : +# 2219| r2219_32(iterator) = Call[end] : func:r2219_31, this:r0_21 #-----| v0_22(void) = ^IndirectReadSideEffect[-1] : &:r0_21, ~m? -# 2218| mu2218_33(iterator) = Store[(__end)] : &:r2218_28, r2218_32 -#-----| Goto -> Block 15 +# 2219| mu2219_33(iterator) = Store[(__end)] : &:r2219_28, r2219_32 +#-----| Goto -> Block 14 -# 2218| Block 15 -# 2218| r2218_34(glval>) = VariableAddress[(__begin)] : -#-----| r0_23(glval>) = Convert : r2218_34 -# 2218| r2218_35(glval) = FunctionAddress[operator!=] : +# 2219| Block 14 +# 2219| r2219_34(glval>) = VariableAddress[(__begin)] : +#-----| r0_23(glval>) = Convert : r2219_34 +# 2219| r2219_35(glval) = FunctionAddress[operator!=] : #-----| r0_24(glval>) = VariableAddress[#temp0:0] : #-----| mu0_25(iterator) = Uninitialized[#temp0:0] : &:r0_24 -# 2218| r2218_36(glval) = FunctionAddress[iterator] : -# 2218| r2218_37(glval>) = VariableAddress[(__end)] : -#-----| r0_26(glval>) = Convert : r2218_37 +# 2219| r2219_36(glval) = FunctionAddress[iterator] : +# 2219| r2219_37(glval>) = VariableAddress[(__end)] : +#-----| r0_26(glval>) = Convert : r2219_37 #-----| r0_27(iterator &) = CopyValue : r0_26 -# 2218| v2218_38(void) = Call[iterator] : func:r2218_36, this:r0_24, 0:r0_27 -# 2218| mu2218_39(unknown) = ^CallSideEffect : ~m? +# 2219| v2219_38(void) = Call[iterator] : func:r2219_36, this:r0_24, 0:r0_27 +# 2219| mu2219_39(unknown) = ^CallSideEffect : ~m? #-----| v0_28(void) = ^BufferReadSideEffect[0] : &:r0_27, ~m? -# 2218| mu2218_40(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_24 +# 2219| mu2219_40(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_24 #-----| r0_29(iterator) = Load[#temp0:0] : &:r0_24, ~m? -# 2218| r2218_41(bool) = Call[operator!=] : func:r2218_35, this:r0_23, 0:r0_29 +# 2219| r2219_41(bool) = Call[operator!=] : func:r2219_35, this:r0_23, 0:r0_29 #-----| v0_30(void) = ^IndirectReadSideEffect[-1] : &:r0_23, ~m? -# 2218| v2218_42(void) = ConditionalBranch : r2218_41 -#-----| False -> Block 20 +# 2219| v2219_42(void) = ConditionalBranch : r2219_41 +#-----| False -> Block 18 #-----| True -> Block 16 -# 2218| Block 16 -# 2218| r2218_43(glval) = VariableAddress[y] : -# 2218| r2218_44(glval>) = VariableAddress[(__begin)] : -#-----| r0_31(glval>) = Convert : r2218_44 -# 2218| r2218_45(glval) = FunctionAddress[operator*] : -# 2218| r2218_46(ClassWithDestructor &) = Call[operator*] : func:r2218_45, this:r0_31 +# 2219| Block 15 +# 2219| r2219_43(glval>) = VariableAddress[(__begin)] : +# 2219| r2219_44(glval) = FunctionAddress[operator++] : +# 2219| r2219_45(iterator &) = Call[operator++] : func:r2219_44, this:r2219_43 +# 2219| v2219_46(void) = ^IndirectReadSideEffect[-1] : &:r2219_43, ~m? +# 2219| mu2219_47(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2219_43 +# 2219| r2219_48(glval) = VariableAddress[y] : +# 2219| r2219_49(glval) = FunctionAddress[~ClassWithDestructor] : +# 2219| v2219_50(void) = Call[~ClassWithDestructor] : func:r2219_49, this:r2219_48 +# 2219| mu2219_51(unknown) = ^CallSideEffect : ~m? +# 2219| v2219_52(void) = ^IndirectReadSideEffect[-1] : &:r2219_48, ~m? +# 2219| mu2219_53(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_48 +# 2219| r2219_54(glval>) = CopyValue : r2219_45 +#-----| Goto (back edge) -> Block 14 + +# 2219| Block 16 +# 2219| r2219_55(glval) = VariableAddress[y] : +# 2219| r2219_56(glval>) = VariableAddress[(__begin)] : +#-----| r0_31(glval>) = Convert : r2219_56 +# 2219| r2219_57(glval) = FunctionAddress[operator*] : +# 2219| r2219_58(ClassWithDestructor &) = Call[operator*] : func:r2219_57, this:r0_31 #-----| v0_32(void) = ^IndirectReadSideEffect[-1] : &:r0_31, ~m? -# 2218| r2218_47(ClassWithDestructor) = Load[?] : &:r2218_46, ~m? -# 2218| mu2218_48(ClassWithDestructor) = Store[y] : &:r2218_43, r2218_47 -# 2219| r2219_1(glval) = VariableAddress[y] : -# 2219| r2219_2(glval) = FunctionAddress[set_x] : -# 2219| r2219_3(char) = Constant[97] : -# 2219| v2219_4(void) = Call[set_x] : func:r2219_2, this:r2219_1, 0:r2219_3 -# 2219| mu2219_5(unknown) = ^CallSideEffect : ~m? -# 2219| v2219_6(void) = ^IndirectReadSideEffect[-1] : &:r2219_1, ~m? -# 2219| mu2219_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_1 +# 2219| r2219_59(ClassWithDestructor) = Load[?] : &:r2219_58, ~m? +# 2219| mu2219_60(ClassWithDestructor) = Store[y] : &:r2219_55, r2219_59 # 2220| r2220_1(glval) = VariableAddress[y] : -# 2220| r2220_2(glval) = FunctionAddress[get_x] : -# 2220| r2220_3(char) = Call[get_x] : func:r2220_2, this:r2220_1 -# 2220| mu2220_4(unknown) = ^CallSideEffect : ~m? -# 2220| v2220_5(void) = ^IndirectReadSideEffect[-1] : &:r2220_1, ~m? -# 2220| mu2220_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2220_1 -# 2220| r2220_7(int) = Convert : r2220_3 -# 2220| r2220_8(int) = Constant[98] : -# 2220| r2220_9(bool) = CompareEQ : r2220_7, r2220_8 -# 2220| v2220_10(void) = ConditionalBranch : r2220_9 -#-----| False -> Block 18 +# 2220| r2220_2(glval) = FunctionAddress[set_x] : +# 2220| r2220_3(char) = Constant[97] : +# 2220| v2220_4(void) = Call[set_x] : func:r2220_2, this:r2220_1, 0:r2220_3 +# 2220| mu2220_5(unknown) = ^CallSideEffect : ~m? +# 2220| v2220_6(void) = ^IndirectReadSideEffect[-1] : &:r2220_1, ~m? +# 2220| mu2220_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2220_1 +# 2221| r2221_1(glval) = VariableAddress[y] : +# 2221| r2221_2(glval) = FunctionAddress[get_x] : +# 2221| r2221_3(char) = Call[get_x] : func:r2221_2, this:r2221_1 +# 2221| mu2221_4(unknown) = ^CallSideEffect : ~m? +# 2221| v2221_5(void) = ^IndirectReadSideEffect[-1] : &:r2221_1, ~m? +# 2221| mu2221_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2221_1 +# 2221| r2221_7(int) = Convert : r2221_3 +# 2221| r2221_8(int) = Constant[98] : +# 2221| r2221_9(bool) = CompareEQ : r2221_7, r2221_8 +# 2221| v2221_10(void) = ConditionalBranch : r2221_9 +#-----| False -> Block 15 #-----| True -> Block 17 -# 2221| Block 17 -# 2221| v2221_1(void) = NoOp : -# 2218| r2218_49(glval) = VariableAddress[y] : -# 2218| r2218_50(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_51(void) = Call[~ClassWithDestructor] : func:r2218_50, this:r2218_49 -# 2218| mu2218_52(unknown) = ^CallSideEffect : ~m? -# 2218| v2218_53(void) = ^IndirectReadSideEffect[-1] : &:r2218_49, ~m? -# 2218| mu2218_54(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_49 -# 2218| r2218_55(glval>) = VariableAddress[ys] : -# 2218| r2218_56(glval) = FunctionAddress[~vector] : -# 2218| v2218_57(void) = Call[~vector] : func:r2218_56, this:r2218_55 -# 2218| mu2218_58(unknown) = ^CallSideEffect : ~m? -# 2218| v2218_59(void) = ^IndirectReadSideEffect[-1] : &:r2218_55, ~m? -# 2218| mu2218_60(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_55 -# 2233| r2233_1(glval) = VariableAddress[x] : -# 2233| r2233_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2233| v2233_3(void) = Call[~ClassWithDestructor] : func:r2233_2, this:r2233_1 -# 2233| mu2233_4(unknown) = ^CallSideEffect : ~m? -# 2233| v2233_5(void) = ^IndirectReadSideEffect[-1] : &:r2233_1, ~m? -# 2233| mu2233_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_1 +# 2222| Block 17 +# 2222| v2222_1(void) = NoOp : +# 2219| r2219_61(glval) = VariableAddress[y] : +# 2219| r2219_62(glval) = FunctionAddress[~ClassWithDestructor] : +# 2219| v2219_63(void) = Call[~ClassWithDestructor] : func:r2219_62, this:r2219_61 +# 2219| mu2219_64(unknown) = ^CallSideEffect : ~m? +# 2219| v2219_65(void) = ^IndirectReadSideEffect[-1] : &:r2219_61, ~m? +# 2219| mu2219_66(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_61 +# 2219| r2219_67(glval>) = VariableAddress[ys] : +# 2219| r2219_68(glval) = FunctionAddress[~vector] : +# 2219| v2219_69(void) = Call[~vector] : func:r2219_68, this:r2219_67 +# 2219| mu2219_70(unknown) = ^CallSideEffect : ~m? +# 2219| v2219_71(void) = ^IndirectReadSideEffect[-1] : &:r2219_67, ~m? +# 2219| mu2219_72(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2219_67 +# 2234| r2234_1(glval) = VariableAddress[x] : +# 2234| r2234_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2234| v2234_3(void) = Call[~ClassWithDestructor] : func:r2234_2, this:r2234_1 +# 2234| mu2234_4(unknown) = ^CallSideEffect : ~m? +# 2234| v2234_5(void) = ^IndirectReadSideEffect[-1] : &:r2234_1, ~m? +# 2234| mu2234_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2234_1 #-----| Goto -> Block 1 -# 2218| Block 18 -# 2218| r2218_61(glval) = VariableAddress[y] : -# 2218| r2218_62(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_63(void) = Call[~ClassWithDestructor] : func:r2218_62, this:r2218_61 -# 2218| mu2218_64(unknown) = ^CallSideEffect : ~m? -# 2218| v2218_65(void) = ^IndirectReadSideEffect[-1] : &:r2218_61, ~m? -# 2218| mu2218_66(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_61 -# 2218| r2218_67(glval>) = VariableAddress[(__begin)] : -# 2218| r2218_68(glval) = FunctionAddress[operator++] : -# 2218| r2218_69(iterator &) = Call[operator++] : func:r2218_68, this:r2218_67 -# 2218| v2218_70(void) = ^IndirectReadSideEffect[-1] : &:r2218_67, ~m? -# 2218| mu2218_71(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2218_67 -# 2218| r2218_72(glval>) = CopyValue : r2218_69 -#-----| Goto (back edge) -> Block 15 - -# 2218| Block 19 -# 2218| r2218_73(glval>) = VariableAddress[ys] : -# 2218| r2218_74(glval) = FunctionAddress[~vector] : -# 2218| v2218_75(void) = Call[~vector] : func:r2218_74, this:r2218_73 -# 2218| mu2218_76(unknown) = ^CallSideEffect : ~m? -# 2218| v2218_77(void) = ^IndirectReadSideEffect[-1] : &:r2218_73, ~m? -# 2218| mu2218_78(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_73 -#-----| Goto -> Block 20 - -# 2224| Block 20 -# 2224| r2224_1(glval>) = VariableAddress[ys] : -# 2224| mu2224_2(vector) = Uninitialized[ys] : &:r2224_1 -# 2224| r2224_3(glval) = FunctionAddress[vector] : -# 2224| r2224_4(int) = Constant[1] : -# 2224| v2224_5(void) = Call[vector] : func:r2224_3, this:r2224_1, 0:r2224_4 -# 2224| mu2224_6(unknown) = ^CallSideEffect : ~m? -# 2224| mu2224_7(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2224_1 -# 2224| r2224_8(glval &>) = VariableAddress[(__range)] : -# 2224| r2224_9(glval>) = VariableAddress[ys] : -# 2224| r2224_10(vector &) = CopyValue : r2224_9 -# 2224| mu2224_11(vector &) = Store[(__range)] : &:r2224_8, r2224_10 -# 2224| r2224_12(glval>) = VariableAddress[(__begin)] : -# 2224| r2224_13(glval &>) = VariableAddress[(__range)] : -# 2224| r2224_14(vector &) = Load[(__range)] : &:r2224_13, ~m? -#-----| r0_33(glval>) = CopyValue : r2224_14 +# 2219| Block 18 +# 2219| r2219_73(glval>) = VariableAddress[ys] : +# 2219| r2219_74(glval) = FunctionAddress[~vector] : +# 2219| v2219_75(void) = Call[~vector] : func:r2219_74, this:r2219_73 +# 2219| mu2219_76(unknown) = ^CallSideEffect : ~m? +# 2219| v2219_77(void) = ^IndirectReadSideEffect[-1] : &:r2219_73, ~m? +# 2219| mu2219_78(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2219_73 +# 2225| r2225_1(glval>) = VariableAddress[ys] : +# 2225| mu2225_2(vector) = Uninitialized[ys] : &:r2225_1 +# 2225| r2225_3(glval) = FunctionAddress[vector] : +# 2225| r2225_4(int) = Constant[1] : +# 2225| v2225_5(void) = Call[vector] : func:r2225_3, this:r2225_1, 0:r2225_4 +# 2225| mu2225_6(unknown) = ^CallSideEffect : ~m? +# 2225| mu2225_7(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2225_1 +# 2225| r2225_8(glval &>) = VariableAddress[(__range)] : +# 2225| r2225_9(glval>) = VariableAddress[ys] : +# 2225| r2225_10(vector &) = CopyValue : r2225_9 +# 2225| mu2225_11(vector &) = Store[(__range)] : &:r2225_8, r2225_10 +# 2225| r2225_12(glval>) = VariableAddress[(__begin)] : +# 2225| r2225_13(glval &>) = VariableAddress[(__range)] : +# 2225| r2225_14(vector &) = Load[(__range)] : &:r2225_13, ~m? +#-----| r0_33(glval>) = CopyValue : r2225_14 #-----| r0_34(glval>) = Convert : r0_33 -# 2224| r2224_15(glval) = FunctionAddress[begin] : -# 2224| r2224_16(iterator) = Call[begin] : func:r2224_15, this:r0_34 +# 2225| r2225_15(glval) = FunctionAddress[begin] : +# 2225| r2225_16(iterator) = Call[begin] : func:r2225_15, this:r0_34 #-----| v0_35(void) = ^IndirectReadSideEffect[-1] : &:r0_34, ~m? -# 2224| mu2224_17(iterator) = Store[(__begin)] : &:r2224_12, r2224_16 -# 2224| r2224_18(glval>) = VariableAddress[(__end)] : -# 2224| r2224_19(glval &>) = VariableAddress[(__range)] : -# 2224| r2224_20(vector &) = Load[(__range)] : &:r2224_19, ~m? -#-----| r0_36(glval>) = CopyValue : r2224_20 +# 2225| mu2225_17(iterator) = Store[(__begin)] : &:r2225_12, r2225_16 +# 2225| r2225_18(glval>) = VariableAddress[(__end)] : +# 2225| r2225_19(glval &>) = VariableAddress[(__range)] : +# 2225| r2225_20(vector &) = Load[(__range)] : &:r2225_19, ~m? +#-----| r0_36(glval>) = CopyValue : r2225_20 #-----| r0_37(glval>) = Convert : r0_36 -# 2224| r2224_21(glval) = FunctionAddress[end] : -# 2224| r2224_22(iterator) = Call[end] : func:r2224_21, this:r0_37 +# 2225| r2225_21(glval) = FunctionAddress[end] : +# 2225| r2225_22(iterator) = Call[end] : func:r2225_21, this:r0_37 #-----| v0_38(void) = ^IndirectReadSideEffect[-1] : &:r0_37, ~m? -# 2224| mu2224_23(iterator) = Store[(__end)] : &:r2224_18, r2224_22 -#-----| Goto -> Block 21 +# 2225| mu2225_23(iterator) = Store[(__end)] : &:r2225_18, r2225_22 +#-----| Goto -> Block 19 -# 2224| Block 21 -# 2224| r2224_24(glval>) = VariableAddress[(__begin)] : -#-----| r0_39(glval>) = Convert : r2224_24 -# 2224| r2224_25(glval) = FunctionAddress[operator!=] : +# 2225| Block 19 +# 2225| r2225_24(glval>) = VariableAddress[(__begin)] : +#-----| r0_39(glval>) = Convert : r2225_24 +# 2225| r2225_25(glval) = FunctionAddress[operator!=] : #-----| r0_40(glval>) = VariableAddress[#temp0:0] : #-----| mu0_41(iterator) = Uninitialized[#temp0:0] : &:r0_40 -# 2224| r2224_26(glval) = FunctionAddress[iterator] : -# 2224| r2224_27(glval>) = VariableAddress[(__end)] : -#-----| r0_42(glval>) = Convert : r2224_27 +# 2225| r2225_26(glval) = FunctionAddress[iterator] : +# 2225| r2225_27(glval>) = VariableAddress[(__end)] : +#-----| r0_42(glval>) = Convert : r2225_27 #-----| r0_43(iterator &) = CopyValue : r0_42 -# 2224| v2224_28(void) = Call[iterator] : func:r2224_26, this:r0_40, 0:r0_43 -# 2224| mu2224_29(unknown) = ^CallSideEffect : ~m? +# 2225| v2225_28(void) = Call[iterator] : func:r2225_26, this:r0_40, 0:r0_43 +# 2225| mu2225_29(unknown) = ^CallSideEffect : ~m? #-----| v0_44(void) = ^BufferReadSideEffect[0] : &:r0_43, ~m? -# 2224| mu2224_30(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_40 +# 2225| mu2225_30(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_40 #-----| r0_45(iterator) = Load[#temp0:0] : &:r0_40, ~m? -# 2224| r2224_31(bool) = Call[operator!=] : func:r2224_25, this:r0_39, 0:r0_45 +# 2225| r2225_31(bool) = Call[operator!=] : func:r2225_25, this:r0_39, 0:r0_45 #-----| v0_46(void) = ^IndirectReadSideEffect[-1] : &:r0_39, ~m? -# 2224| v2224_32(void) = ConditionalBranch : r2224_31 -#-----| False -> Block 26 -#-----| True -> Block 23 - -# 2224| Block 22 -# 2224| r2224_33(glval>) = VariableAddress[(__begin)] : -# 2224| r2224_34(glval) = FunctionAddress[operator++] : -# 2224| r2224_35(iterator &) = Call[operator++] : func:r2224_34, this:r2224_33 -# 2224| v2224_36(void) = ^IndirectReadSideEffect[-1] : &:r2224_33, ~m? -# 2224| mu2224_37(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2224_33 -# 2224| r2224_38(glval>) = CopyValue : r2224_35 -#-----| Goto (back edge) -> Block 21 - -# 2224| Block 23 -# 2224| r2224_39(glval) = VariableAddress[y] : -# 2224| r2224_40(glval>) = VariableAddress[(__begin)] : -#-----| r0_47(glval>) = Convert : r2224_40 -# 2224| r2224_41(glval) = FunctionAddress[operator*] : -# 2224| r2224_42(int &) = Call[operator*] : func:r2224_41, this:r0_47 +# 2225| v2225_32(void) = ConditionalBranch : r2225_31 +#-----| False -> Block 23 +#-----| True -> Block 21 + +# 2225| Block 20 +# 2225| r2225_33(glval>) = VariableAddress[(__begin)] : +# 2225| r2225_34(glval) = FunctionAddress[operator++] : +# 2225| r2225_35(iterator &) = Call[operator++] : func:r2225_34, this:r2225_33 +# 2225| v2225_36(void) = ^IndirectReadSideEffect[-1] : &:r2225_33, ~m? +# 2225| mu2225_37(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2225_33 +# 2225| r2225_38(glval>) = CopyValue : r2225_35 +#-----| Goto (back edge) -> Block 19 + +# 2225| Block 21 +# 2225| r2225_39(glval) = VariableAddress[y] : +# 2225| r2225_40(glval>) = VariableAddress[(__begin)] : +#-----| r0_47(glval>) = Convert : r2225_40 +# 2225| r2225_41(glval) = FunctionAddress[operator*] : +# 2225| r2225_42(int &) = Call[operator*] : func:r2225_41, this:r0_47 #-----| v0_48(void) = ^IndirectReadSideEffect[-1] : &:r0_47, ~m? -# 2224| r2224_43(int) = Load[?] : &:r2224_42, ~m? -# 2224| mu2224_44(int) = Store[y] : &:r2224_39, r2224_43 -# 2225| r2225_1(glval) = VariableAddress[y] : -# 2225| r2225_2(int) = Load[y] : &:r2225_1, ~m? -# 2225| r2225_3(int) = Constant[1] : -# 2225| r2225_4(bool) = CompareEQ : r2225_2, r2225_3 -# 2225| v2225_5(void) = ConditionalBranch : r2225_4 -#-----| False -> Block 22 -#-----| True -> Block 24 - -# 2226| Block 24 -# 2226| v2226_1(void) = NoOp : -# 2224| r2224_45(glval>) = VariableAddress[ys] : -# 2224| r2224_46(glval) = FunctionAddress[~vector] : -# 2224| v2224_47(void) = Call[~vector] : func:r2224_46, this:r2224_45 -# 2224| mu2224_48(unknown) = ^CallSideEffect : ~m? -# 2224| v2224_49(void) = ^IndirectReadSideEffect[-1] : &:r2224_45, ~m? -# 2224| mu2224_50(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2224_45 -# 2233| r2233_7(glval) = VariableAddress[x] : -# 2233| r2233_8(glval) = FunctionAddress[~ClassWithDestructor] : -# 2233| v2233_9(void) = Call[~ClassWithDestructor] : func:r2233_8, this:r2233_7 -# 2233| mu2233_10(unknown) = ^CallSideEffect : ~m? -# 2233| v2233_11(void) = ^IndirectReadSideEffect[-1] : &:r2233_7, ~m? -# 2233| mu2233_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_7 +# 2225| r2225_43(int) = Load[?] : &:r2225_42, ~m? +# 2225| mu2225_44(int) = Store[y] : &:r2225_39, r2225_43 +# 2226| r2226_1(glval) = VariableAddress[y] : +# 2226| r2226_2(int) = Load[y] : &:r2226_1, ~m? +# 2226| r2226_3(int) = Constant[1] : +# 2226| r2226_4(bool) = CompareEQ : r2226_2, r2226_3 +# 2226| v2226_5(void) = ConditionalBranch : r2226_4 +#-----| False -> Block 20 +#-----| True -> Block 22 + +# 2227| Block 22 +# 2227| v2227_1(void) = NoOp : +# 2225| r2225_45(glval>) = VariableAddress[ys] : +# 2225| r2225_46(glval) = FunctionAddress[~vector] : +# 2225| v2225_47(void) = Call[~vector] : func:r2225_46, this:r2225_45 +# 2225| mu2225_48(unknown) = ^CallSideEffect : ~m? +# 2225| v2225_49(void) = ^IndirectReadSideEffect[-1] : &:r2225_45, ~m? +# 2225| mu2225_50(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2225_45 +# 2234| r2234_7(glval) = VariableAddress[x] : +# 2234| r2234_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2234| v2234_9(void) = Call[~ClassWithDestructor] : func:r2234_8, this:r2234_7 +# 2234| mu2234_10(unknown) = ^CallSideEffect : ~m? +# 2234| v2234_11(void) = ^IndirectReadSideEffect[-1] : &:r2234_7, ~m? +# 2234| mu2234_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2234_7 #-----| Goto -> Block 1 -# 2224| Block 25 -# 2224| r2224_51(glval>) = VariableAddress[ys] : -# 2224| r2224_52(glval) = FunctionAddress[~vector] : -# 2224| v2224_53(void) = Call[~vector] : func:r2224_52, this:r2224_51 -# 2224| mu2224_54(unknown) = ^CallSideEffect : ~m? -# 2224| v2224_55(void) = ^IndirectReadSideEffect[-1] : &:r2224_51, ~m? -# 2224| mu2224_56(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2224_51 -#-----| Goto -> Block 26 - -# 2229| Block 26 -# 2229| r2229_1(glval>) = VariableAddress[ys] : -# 2229| mu2229_2(vector) = Uninitialized[ys] : &:r2229_1 -# 2229| r2229_3(glval) = FunctionAddress[vector] : -# 2229| r2229_4(glval) = VariableAddress[#temp2229:45] : -# 2229| r2229_5(glval) = VariableAddress[x] : -# 2229| r2229_6(ClassWithDestructor) = Load[x] : &:r2229_5, ~m? -# 2229| mu2229_7(ClassWithDestructor) = Store[#temp2229:45] : &:r2229_4, r2229_6 -# 2229| r2229_8(ClassWithDestructor) = Load[#temp2229:45] : &:r2229_4, ~m? -# 2229| v2229_9(void) = Call[vector] : func:r2229_3, this:r2229_1, 0:r2229_8 -# 2229| mu2229_10(unknown) = ^CallSideEffect : ~m? -# 2229| mu2229_11(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2229_1 -# 2229| r2229_12(glval) = CopyValue : r2229_4 -# 2229| r2229_13(glval) = FunctionAddress[~ClassWithDestructor] : -# 2229| v2229_14(void) = Call[~ClassWithDestructor] : func:r2229_13, this:r2229_12 -# 2229| mu2229_15(unknown) = ^CallSideEffect : ~m? -# 2229| v2229_16(void) = ^IndirectReadSideEffect[-1] : &:r2229_12, ~m? -# 2229| mu2229_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_12 -# 2229| r2229_18(glval &>) = VariableAddress[(__range)] : -# 2229| r2229_19(glval>) = VariableAddress[ys] : -# 2229| r2229_20(vector &) = CopyValue : r2229_19 -# 2229| mu2229_21(vector &) = Store[(__range)] : &:r2229_18, r2229_20 -# 2229| r2229_22(glval>) = VariableAddress[(__begin)] : -# 2229| r2229_23(glval &>) = VariableAddress[(__range)] : -# 2229| r2229_24(vector &) = Load[(__range)] : &:r2229_23, ~m? -#-----| r0_49(glval>) = CopyValue : r2229_24 +# 2225| Block 23 +# 2225| r2225_51(glval>) = VariableAddress[ys] : +# 2225| r2225_52(glval) = FunctionAddress[~vector] : +# 2225| v2225_53(void) = Call[~vector] : func:r2225_52, this:r2225_51 +# 2225| mu2225_54(unknown) = ^CallSideEffect : ~m? +# 2225| v2225_55(void) = ^IndirectReadSideEffect[-1] : &:r2225_51, ~m? +# 2225| mu2225_56(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2225_51 +# 2230| r2230_1(glval>) = VariableAddress[ys] : +# 2230| mu2230_2(vector) = Uninitialized[ys] : &:r2230_1 +# 2230| r2230_3(glval) = FunctionAddress[vector] : +# 2230| r2230_4(glval) = VariableAddress[#temp2230:45] : +# 2230| r2230_5(glval) = VariableAddress[x] : +# 2230| r2230_6(ClassWithDestructor) = Load[x] : &:r2230_5, ~m? +# 2230| mu2230_7(ClassWithDestructor) = Store[#temp2230:45] : &:r2230_4, r2230_6 +# 2230| r2230_8(ClassWithDestructor) = Load[#temp2230:45] : &:r2230_4, ~m? +# 2230| v2230_9(void) = Call[vector] : func:r2230_3, this:r2230_1, 0:r2230_8 +# 2230| mu2230_10(unknown) = ^CallSideEffect : ~m? +# 2230| mu2230_11(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2230_1 +# 2230| r2230_12(glval) = CopyValue : r2230_4 +# 2230| r2230_13(glval) = FunctionAddress[~ClassWithDestructor] : +# 2230| v2230_14(void) = Call[~ClassWithDestructor] : func:r2230_13, this:r2230_12 +# 2230| mu2230_15(unknown) = ^CallSideEffect : ~m? +# 2230| v2230_16(void) = ^IndirectReadSideEffect[-1] : &:r2230_12, ~m? +# 2230| mu2230_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2230_12 +# 2230| r2230_18(glval &>) = VariableAddress[(__range)] : +# 2230| r2230_19(glval>) = VariableAddress[ys] : +# 2230| r2230_20(vector &) = CopyValue : r2230_19 +# 2230| mu2230_21(vector &) = Store[(__range)] : &:r2230_18, r2230_20 +# 2230| r2230_22(glval>) = VariableAddress[(__begin)] : +# 2230| r2230_23(glval &>) = VariableAddress[(__range)] : +# 2230| r2230_24(vector &) = Load[(__range)] : &:r2230_23, ~m? +#-----| r0_49(glval>) = CopyValue : r2230_24 #-----| r0_50(glval>) = Convert : r0_49 -# 2229| r2229_25(glval) = FunctionAddress[begin] : -# 2229| r2229_26(iterator) = Call[begin] : func:r2229_25, this:r0_50 +# 2230| r2230_25(glval) = FunctionAddress[begin] : +# 2230| r2230_26(iterator) = Call[begin] : func:r2230_25, this:r0_50 #-----| v0_51(void) = ^IndirectReadSideEffect[-1] : &:r0_50, ~m? -# 2229| mu2229_27(iterator) = Store[(__begin)] : &:r2229_22, r2229_26 -# 2229| r2229_28(glval>) = VariableAddress[(__end)] : -# 2229| r2229_29(glval &>) = VariableAddress[(__range)] : -# 2229| r2229_30(vector &) = Load[(__range)] : &:r2229_29, ~m? -#-----| r0_52(glval>) = CopyValue : r2229_30 +# 2230| mu2230_27(iterator) = Store[(__begin)] : &:r2230_22, r2230_26 +# 2230| r2230_28(glval>) = VariableAddress[(__end)] : +# 2230| r2230_29(glval &>) = VariableAddress[(__range)] : +# 2230| r2230_30(vector &) = Load[(__range)] : &:r2230_29, ~m? +#-----| r0_52(glval>) = CopyValue : r2230_30 #-----| r0_53(glval>) = Convert : r0_52 -# 2229| r2229_31(glval) = FunctionAddress[end] : -# 2229| r2229_32(iterator) = Call[end] : func:r2229_31, this:r0_53 +# 2230| r2230_31(glval) = FunctionAddress[end] : +# 2230| r2230_32(iterator) = Call[end] : func:r2230_31, this:r0_53 #-----| v0_54(void) = ^IndirectReadSideEffect[-1] : &:r0_53, ~m? -# 2229| mu2229_33(iterator) = Store[(__end)] : &:r2229_28, r2229_32 -#-----| Goto -> Block 27 +# 2230| mu2230_33(iterator) = Store[(__end)] : &:r2230_28, r2230_32 +#-----| Goto -> Block 24 -# 2229| Block 27 -# 2229| r2229_34(glval>) = VariableAddress[(__begin)] : -#-----| r0_55(glval>) = Convert : r2229_34 -# 2229| r2229_35(glval) = FunctionAddress[operator!=] : +# 2230| Block 24 +# 2230| r2230_34(glval>) = VariableAddress[(__begin)] : +#-----| r0_55(glval>) = Convert : r2230_34 +# 2230| r2230_35(glval) = FunctionAddress[operator!=] : #-----| r0_56(glval>) = VariableAddress[#temp0:0] : #-----| mu0_57(iterator) = Uninitialized[#temp0:0] : &:r0_56 -# 2229| r2229_36(glval) = FunctionAddress[iterator] : -# 2229| r2229_37(glval>) = VariableAddress[(__end)] : -#-----| r0_58(glval>) = Convert : r2229_37 +# 2230| r2230_36(glval) = FunctionAddress[iterator] : +# 2230| r2230_37(glval>) = VariableAddress[(__end)] : +#-----| r0_58(glval>) = Convert : r2230_37 #-----| r0_59(iterator &) = CopyValue : r0_58 -# 2229| v2229_38(void) = Call[iterator] : func:r2229_36, this:r0_56, 0:r0_59 -# 2229| mu2229_39(unknown) = ^CallSideEffect : ~m? +# 2230| v2230_38(void) = Call[iterator] : func:r2230_36, this:r0_56, 0:r0_59 +# 2230| mu2230_39(unknown) = ^CallSideEffect : ~m? #-----| v0_60(void) = ^BufferReadSideEffect[0] : &:r0_59, ~m? -# 2229| mu2229_40(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_56 +# 2230| mu2230_40(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_56 #-----| r0_61(iterator) = Load[#temp0:0] : &:r0_56, ~m? -# 2229| r2229_41(bool) = Call[operator!=] : func:r2229_35, this:r0_55, 0:r0_61 +# 2230| r2230_41(bool) = Call[operator!=] : func:r2230_35, this:r0_55, 0:r0_61 #-----| v0_62(void) = ^IndirectReadSideEffect[-1] : &:r0_55, ~m? -# 2229| v2229_42(void) = ConditionalBranch : r2229_41 -#-----| False -> Block 30 -#-----| True -> Block 28 - -# 2229| Block 28 -# 2229| r2229_43(glval) = VariableAddress[y] : -# 2229| r2229_44(glval>) = VariableAddress[(__begin)] : -#-----| r0_63(glval>) = Convert : r2229_44 -# 2229| r2229_45(glval) = FunctionAddress[operator*] : -# 2229| r2229_46(ClassWithDestructor &) = Call[operator*] : func:r2229_45, this:r0_63 +# 2230| v2230_42(void) = ConditionalBranch : r2230_41 +#-----| False -> Block 26 +#-----| True -> Block 25 + +# 2230| Block 25 +# 2230| r2230_43(glval) = VariableAddress[y] : +# 2230| r2230_44(glval>) = VariableAddress[(__begin)] : +#-----| r0_63(glval>) = Convert : r2230_44 +# 2230| r2230_45(glval) = FunctionAddress[operator*] : +# 2230| r2230_46(ClassWithDestructor &) = Call[operator*] : func:r2230_45, this:r0_63 #-----| v0_64(void) = ^IndirectReadSideEffect[-1] : &:r0_63, ~m? -# 2229| r2229_47(ClassWithDestructor) = Load[?] : &:r2229_46, ~m? -# 2229| mu2229_48(ClassWithDestructor) = Store[y] : &:r2229_43, r2229_47 -# 2230| r2230_1(glval) = VariableAddress[z1] : -# 2230| mu2230_2(ClassWithDestructor) = Uninitialized[z1] : &:r2230_1 -# 2230| r2230_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2230| v2230_4(void) = Call[ClassWithDestructor] : func:r2230_3, this:r2230_1 -# 2230| mu2230_5(unknown) = ^CallSideEffect : ~m? -# 2230| mu2230_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2230_1 -# 2231| r2231_1(glval) = VariableAddress[z2] : -# 2231| mu2231_2(ClassWithDestructor) = Uninitialized[z2] : &:r2231_1 +# 2230| r2230_47(ClassWithDestructor) = Load[?] : &:r2230_46, ~m? +# 2230| mu2230_48(ClassWithDestructor) = Store[y] : &:r2230_43, r2230_47 +# 2231| r2231_1(glval) = VariableAddress[z1] : +# 2231| mu2231_2(ClassWithDestructor) = Uninitialized[z1] : &:r2231_1 # 2231| r2231_3(glval) = FunctionAddress[ClassWithDestructor] : # 2231| v2231_4(void) = Call[ClassWithDestructor] : func:r2231_3, this:r2231_1 # 2231| mu2231_5(unknown) = ^CallSideEffect : ~m? # 2231| mu2231_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2231_1 # 2232| r2232_1(glval) = VariableAddress[z2] : -# 2232| r2232_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2232| v2232_3(void) = Call[~ClassWithDestructor] : func:r2232_2, this:r2232_1 -# 2232| mu2232_4(unknown) = ^CallSideEffect : ~m? -# 2232| v2232_5(void) = ^IndirectReadSideEffect[-1] : &:r2232_1, ~m? +# 2232| mu2232_2(ClassWithDestructor) = Uninitialized[z2] : &:r2232_1 +# 2232| r2232_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2232| v2232_4(void) = Call[ClassWithDestructor] : func:r2232_3, this:r2232_1 +# 2232| mu2232_5(unknown) = ^CallSideEffect : ~m? # 2232| mu2232_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2232_1 -# 2232| r2232_7(glval) = VariableAddress[z1] : -# 2232| r2232_8(glval) = FunctionAddress[~ClassWithDestructor] : -# 2232| v2232_9(void) = Call[~ClassWithDestructor] : func:r2232_8, this:r2232_7 -# 2232| mu2232_10(unknown) = ^CallSideEffect : ~m? -# 2232| v2232_11(void) = ^IndirectReadSideEffect[-1] : &:r2232_7, ~m? -# 2232| mu2232_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2232_7 -# 2229| r2229_49(glval) = VariableAddress[y] : -# 2229| r2229_50(glval) = FunctionAddress[~ClassWithDestructor] : -# 2229| v2229_51(void) = Call[~ClassWithDestructor] : func:r2229_50, this:r2229_49 -# 2229| mu2229_52(unknown) = ^CallSideEffect : ~m? -# 2229| v2229_53(void) = ^IndirectReadSideEffect[-1] : &:r2229_49, ~m? -# 2229| mu2229_54(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_49 -# 2229| r2229_55(glval>) = VariableAddress[(__begin)] : -# 2229| r2229_56(glval) = FunctionAddress[operator++] : -# 2229| r2229_57(iterator &) = Call[operator++] : func:r2229_56, this:r2229_55 -# 2229| v2229_58(void) = ^IndirectReadSideEffect[-1] : &:r2229_55, ~m? -# 2229| mu2229_59(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2229_55 -# 2229| r2229_60(glval>) = CopyValue : r2229_57 -#-----| Goto (back edge) -> Block 27 - -# 2229| Block 29 -# 2229| r2229_61(glval>) = VariableAddress[ys] : -# 2229| r2229_62(glval) = FunctionAddress[~vector] : -# 2229| v2229_63(void) = Call[~vector] : func:r2229_62, this:r2229_61 -# 2229| mu2229_64(unknown) = ^CallSideEffect : ~m? -# 2229| v2229_65(void) = ^IndirectReadSideEffect[-1] : &:r2229_61, ~m? -# 2229| mu2229_66(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2229_61 -#-----| Goto -> Block 30 - -# 2233| Block 30 -# 2233| v2233_13(void) = NoOp : -# 2233| r2233_14(glval) = VariableAddress[x] : -# 2233| r2233_15(glval) = FunctionAddress[~ClassWithDestructor] : -# 2233| v2233_16(void) = Call[~ClassWithDestructor] : func:r2233_15, this:r2233_14 -# 2233| mu2233_17(unknown) = ^CallSideEffect : ~m? -# 2233| v2233_18(void) = ^IndirectReadSideEffect[-1] : &:r2233_14, ~m? -# 2233| mu2233_19(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_14 +# 2233| r2233_1(glval) = VariableAddress[z2] : +# 2233| r2233_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2233| v2233_3(void) = Call[~ClassWithDestructor] : func:r2233_2, this:r2233_1 +# 2233| mu2233_4(unknown) = ^CallSideEffect : ~m? +# 2233| v2233_5(void) = ^IndirectReadSideEffect[-1] : &:r2233_1, ~m? +# 2233| mu2233_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_1 +# 2233| r2233_7(glval) = VariableAddress[z1] : +# 2233| r2233_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2233| v2233_9(void) = Call[~ClassWithDestructor] : func:r2233_8, this:r2233_7 +# 2233| mu2233_10(unknown) = ^CallSideEffect : ~m? +# 2233| v2233_11(void) = ^IndirectReadSideEffect[-1] : &:r2233_7, ~m? +# 2233| mu2233_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_7 +# 2230| r2230_49(glval>) = VariableAddress[(__begin)] : +# 2230| r2230_50(glval) = FunctionAddress[operator++] : +# 2230| r2230_51(iterator &) = Call[operator++] : func:r2230_50, this:r2230_49 +# 2230| v2230_52(void) = ^IndirectReadSideEffect[-1] : &:r2230_49, ~m? +# 2230| mu2230_53(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2230_49 +# 2230| r2230_54(glval) = VariableAddress[y] : +# 2230| r2230_55(glval) = FunctionAddress[~ClassWithDestructor] : +# 2230| v2230_56(void) = Call[~ClassWithDestructor] : func:r2230_55, this:r2230_54 +# 2230| mu2230_57(unknown) = ^CallSideEffect : ~m? +# 2230| v2230_58(void) = ^IndirectReadSideEffect[-1] : &:r2230_54, ~m? +# 2230| mu2230_59(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2230_54 +# 2230| r2230_60(glval>) = CopyValue : r2230_51 +#-----| Goto (back edge) -> Block 24 + +# 2230| Block 26 +# 2230| r2230_61(glval>) = VariableAddress[ys] : +# 2230| r2230_62(glval) = FunctionAddress[~vector] : +# 2230| v2230_63(void) = Call[~vector] : func:r2230_62, this:r2230_61 +# 2230| mu2230_64(unknown) = ^CallSideEffect : ~m? +# 2230| v2230_65(void) = ^IndirectReadSideEffect[-1] : &:r2230_61, ~m? +# 2230| mu2230_66(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2230_61 +# 2234| v2234_13(void) = NoOp : +# 2234| r2234_14(glval) = VariableAddress[x] : +# 2234| r2234_15(glval) = FunctionAddress[~ClassWithDestructor] : +# 2234| v2234_16(void) = Call[~ClassWithDestructor] : func:r2234_15, this:r2234_14 +# 2234| mu2234_17(unknown) = ^CallSideEffect : ~m? +# 2234| v2234_18(void) = ^IndirectReadSideEffect[-1] : &:r2234_14, ~m? +# 2234| mu2234_19(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2234_14 #-----| Goto -> Block 1 -# 2235| void static_variable_with_destructor_1() -# 2235| Block 0 -# 2235| v2235_1(void) = EnterFunction : -# 2235| mu2235_2(unknown) = AliasedDefinition : -# 2235| mu2235_3(unknown) = InitializeNonLocal : -# 2236| r2236_1(glval) = VariableAddress[a] : -# 2236| mu2236_2(ClassWithDestructor) = Uninitialized[a] : &:r2236_1 -# 2236| r2236_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2236| v2236_4(void) = Call[ClassWithDestructor] : func:r2236_3, this:r2236_1 -# 2236| mu2236_5(unknown) = ^CallSideEffect : ~m? -# 2236| mu2236_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2236_1 -# 2237| r2237_1(glval) = VariableAddress[b#init] : -# 2237| r2237_2(bool) = Load[b#init] : &:r2237_1, ~m? -# 2237| v2237_3(void) = ConditionalBranch : r2237_2 +# 2236| void static_variable_with_destructor_1() +# 2236| Block 0 +# 2236| v2236_1(void) = EnterFunction : +# 2236| mu2236_2(unknown) = AliasedDefinition : +# 2236| mu2236_3(unknown) = InitializeNonLocal : +# 2237| r2237_1(glval) = VariableAddress[a] : +# 2237| mu2237_2(ClassWithDestructor) = Uninitialized[a] : &:r2237_1 +# 2237| r2237_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2237| v2237_4(void) = Call[ClassWithDestructor] : func:r2237_3, this:r2237_1 +# 2237| mu2237_5(unknown) = ^CallSideEffect : ~m? +# 2237| mu2237_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2237_1 +# 2238| r2238_1(glval) = VariableAddress[b#init] : +# 2238| r2238_2(bool) = Load[b#init] : &:r2238_1, ~m? +# 2238| v2238_3(void) = ConditionalBranch : r2238_2 #-----| False -> Block 1 #-----| True -> Block 2 -# 2237| Block 1 -# 2237| r2237_4(glval) = VariableAddress[b] : +# 2238| Block 1 +# 2238| r2238_4(glval) = VariableAddress[b] : #-----| r0_1(glval) = FunctionAddress[ClassWithDestructor] : -#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2237_4 +#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2238_4 #-----| mu0_3(unknown) = ^CallSideEffect : ~m? -#-----| mu0_4(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2237_4 -# 2237| r2237_5(bool) = Constant[1] : -# 2237| mu2237_6(bool) = Store[b#init] : &:r2237_1, r2237_5 +#-----| mu0_4(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2238_4 +# 2238| r2238_5(bool) = Constant[1] : +# 2238| mu2238_6(bool) = Store[b#init] : &:r2238_1, r2238_5 #-----| Goto -> Block 2 -# 2238| Block 2 -# 2238| v2238_1(void) = NoOp : -# 2238| r2238_2(glval) = VariableAddress[a] : -# 2238| r2238_3(glval) = FunctionAddress[~ClassWithDestructor] : -# 2238| v2238_4(void) = Call[~ClassWithDestructor] : func:r2238_3, this:r2238_2 -# 2238| mu2238_5(unknown) = ^CallSideEffect : ~m? -# 2238| v2238_6(void) = ^IndirectReadSideEffect[-1] : &:r2238_2, ~m? -# 2238| mu2238_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2238_2 -# 2235| v2235_4(void) = ReturnVoid : -# 2235| v2235_5(void) = AliasedUse : ~m? -# 2235| v2235_6(void) = ExitFunction : - -# 2240| void static_variable_with_destructor_2() -# 2240| Block 0 -# 2240| v2240_1(void) = EnterFunction : -# 2240| mu2240_2(unknown) = AliasedDefinition : -# 2240| mu2240_3(unknown) = InitializeNonLocal : -# 2241| r2241_1(glval) = VariableAddress[a#init] : -# 2241| r2241_2(bool) = Load[a#init] : &:r2241_1, ~m? -# 2241| v2241_3(void) = ConditionalBranch : r2241_2 +# 2239| Block 2 +# 2239| v2239_1(void) = NoOp : +# 2239| r2239_2(glval) = VariableAddress[a] : +# 2239| r2239_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2239| v2239_4(void) = Call[~ClassWithDestructor] : func:r2239_3, this:r2239_2 +# 2239| mu2239_5(unknown) = ^CallSideEffect : ~m? +# 2239| v2239_6(void) = ^IndirectReadSideEffect[-1] : &:r2239_2, ~m? +# 2239| mu2239_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2239_2 +# 2236| v2236_4(void) = ReturnVoid : +# 2236| v2236_5(void) = AliasedUse : ~m? +# 2236| v2236_6(void) = ExitFunction : + +# 2241| void static_variable_with_destructor_2() +# 2241| Block 0 +# 2241| v2241_1(void) = EnterFunction : +# 2241| mu2241_2(unknown) = AliasedDefinition : +# 2241| mu2241_3(unknown) = InitializeNonLocal : +# 2242| r2242_1(glval) = VariableAddress[a#init] : +# 2242| r2242_2(bool) = Load[a#init] : &:r2242_1, ~m? +# 2242| v2242_3(void) = ConditionalBranch : r2242_2 #-----| False -> Block 1 #-----| True -> Block 2 -# 2241| Block 1 -# 2241| r2241_4(glval) = VariableAddress[a] : +# 2242| Block 1 +# 2242| r2242_4(glval) = VariableAddress[a] : #-----| r0_1(glval) = FunctionAddress[ClassWithDestructor] : -#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2241_4 +#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2242_4 #-----| mu0_3(unknown) = ^CallSideEffect : ~m? -#-----| mu0_4(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2241_4 -# 2241| r2241_5(bool) = Constant[1] : -# 2241| mu2241_6(bool) = Store[a#init] : &:r2241_1, r2241_5 +#-----| mu0_4(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2242_4 +# 2242| r2242_5(bool) = Constant[1] : +# 2242| mu2242_6(bool) = Store[a#init] : &:r2242_1, r2242_5 #-----| Goto -> Block 2 -# 2242| Block 2 -# 2242| r2242_1(glval) = VariableAddress[b] : -# 2242| mu2242_2(ClassWithDestructor) = Uninitialized[b] : &:r2242_1 -# 2242| r2242_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2242| v2242_4(void) = Call[ClassWithDestructor] : func:r2242_3, this:r2242_1 -# 2242| mu2242_5(unknown) = ^CallSideEffect : ~m? -# 2242| mu2242_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2242_1 -# 2243| v2243_1(void) = NoOp : -# 2243| r2243_2(glval) = VariableAddress[b] : -# 2243| r2243_3(glval) = FunctionAddress[~ClassWithDestructor] : -# 2243| v2243_4(void) = Call[~ClassWithDestructor] : func:r2243_3, this:r2243_2 +# 2243| Block 2 +# 2243| r2243_1(glval) = VariableAddress[b] : +# 2243| mu2243_2(ClassWithDestructor) = Uninitialized[b] : &:r2243_1 +# 2243| r2243_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2243| v2243_4(void) = Call[ClassWithDestructor] : func:r2243_3, this:r2243_1 # 2243| mu2243_5(unknown) = ^CallSideEffect : ~m? -# 2243| v2243_6(void) = ^IndirectReadSideEffect[-1] : &:r2243_2, ~m? -# 2243| mu2243_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2243_2 -# 2240| v2240_4(void) = ReturnVoid : -# 2240| v2240_5(void) = AliasedUse : ~m? -# 2240| v2240_6(void) = ExitFunction : - -# 2245| void static_variable_with_destructor_3() -# 2245| Block 0 -# 2245| v2245_1(void) = EnterFunction : -# 2245| mu2245_2(unknown) = AliasedDefinition : -# 2245| mu2245_3(unknown) = InitializeNonLocal : -# 2246| r2246_1(glval) = VariableAddress[a] : -# 2246| mu2246_2(ClassWithDestructor) = Uninitialized[a] : &:r2246_1 -# 2246| r2246_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2246| v2246_4(void) = Call[ClassWithDestructor] : func:r2246_3, this:r2246_1 -# 2246| mu2246_5(unknown) = ^CallSideEffect : ~m? -# 2246| mu2246_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2246_1 -# 2247| r2247_1(glval) = VariableAddress[b] : -# 2247| mu2247_2(ClassWithDestructor) = Uninitialized[b] : &:r2247_1 +# 2243| mu2243_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2243_1 +# 2244| v2244_1(void) = NoOp : +# 2244| r2244_2(glval) = VariableAddress[b] : +# 2244| r2244_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2244| v2244_4(void) = Call[~ClassWithDestructor] : func:r2244_3, this:r2244_2 +# 2244| mu2244_5(unknown) = ^CallSideEffect : ~m? +# 2244| v2244_6(void) = ^IndirectReadSideEffect[-1] : &:r2244_2, ~m? +# 2244| mu2244_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2244_2 +# 2241| v2241_4(void) = ReturnVoid : +# 2241| v2241_5(void) = AliasedUse : ~m? +# 2241| v2241_6(void) = ExitFunction : + +# 2246| void static_variable_with_destructor_3() +# 2246| Block 0 +# 2246| v2246_1(void) = EnterFunction : +# 2246| mu2246_2(unknown) = AliasedDefinition : +# 2246| mu2246_3(unknown) = InitializeNonLocal : +# 2247| r2247_1(glval) = VariableAddress[a] : +# 2247| mu2247_2(ClassWithDestructor) = Uninitialized[a] : &:r2247_1 # 2247| r2247_3(glval) = FunctionAddress[ClassWithDestructor] : # 2247| v2247_4(void) = Call[ClassWithDestructor] : func:r2247_3, this:r2247_1 # 2247| mu2247_5(unknown) = ^CallSideEffect : ~m? # 2247| mu2247_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2247_1 -# 2248| r2248_1(glval) = VariableAddress[c#init] : -# 2248| r2248_2(bool) = Load[c#init] : &:r2248_1, ~m? -# 2248| v2248_3(void) = ConditionalBranch : r2248_2 +# 2248| r2248_1(glval) = VariableAddress[b] : +# 2248| mu2248_2(ClassWithDestructor) = Uninitialized[b] : &:r2248_1 +# 2248| r2248_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2248| v2248_4(void) = Call[ClassWithDestructor] : func:r2248_3, this:r2248_1 +# 2248| mu2248_5(unknown) = ^CallSideEffect : ~m? +# 2248| mu2248_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2248_1 +# 2249| r2249_1(glval) = VariableAddress[c#init] : +# 2249| r2249_2(bool) = Load[c#init] : &:r2249_1, ~m? +# 2249| v2249_3(void) = ConditionalBranch : r2249_2 #-----| False -> Block 1 #-----| True -> Block 2 -# 2248| Block 1 -# 2248| r2248_4(glval) = VariableAddress[c] : +# 2249| Block 1 +# 2249| r2249_4(glval) = VariableAddress[c] : #-----| r0_1(glval) = FunctionAddress[ClassWithDestructor] : -#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2248_4 +#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2249_4 #-----| mu0_3(unknown) = ^CallSideEffect : ~m? -#-----| mu0_4(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2248_4 -# 2248| r2248_5(bool) = Constant[1] : -# 2248| mu2248_6(bool) = Store[c#init] : &:r2248_1, r2248_5 +#-----| mu0_4(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2249_4 +# 2249| r2249_5(bool) = Constant[1] : +# 2249| mu2249_6(bool) = Store[c#init] : &:r2249_1, r2249_5 #-----| Goto -> Block 2 -# 2249| Block 2 -# 2249| v2249_1(void) = NoOp : -# 2249| r2249_2(glval) = VariableAddress[b] : -# 2249| r2249_3(glval) = FunctionAddress[~ClassWithDestructor] : -# 2249| v2249_4(void) = Call[~ClassWithDestructor] : func:r2249_3, this:r2249_2 -# 2249| mu2249_5(unknown) = ^CallSideEffect : ~m? -# 2249| v2249_6(void) = ^IndirectReadSideEffect[-1] : &:r2249_2, ~m? -# 2249| mu2249_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2249_2 -# 2249| r2249_8(glval) = VariableAddress[a] : -# 2249| r2249_9(glval) = FunctionAddress[~ClassWithDestructor] : -# 2249| v2249_10(void) = Call[~ClassWithDestructor] : func:r2249_9, this:r2249_8 -# 2249| mu2249_11(unknown) = ^CallSideEffect : ~m? -# 2249| v2249_12(void) = ^IndirectReadSideEffect[-1] : &:r2249_8, ~m? -# 2249| mu2249_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2249_8 -# 2245| v2245_4(void) = ReturnVoid : -# 2245| v2245_5(void) = AliasedUse : ~m? -# 2245| v2245_6(void) = ExitFunction : - -# 2251| ClassWithDestructor global_class_with_destructor -# 2251| Block 0 -# 2251| v2251_1(void) = EnterFunction : -# 2251| mu2251_2(unknown) = AliasedDefinition : -# 2251| r2251_3(glval) = VariableAddress[global_class_with_destructor] : -# 2251| r2251_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2251| v2251_5(void) = Call[ClassWithDestructor] : func:r2251_4, this:r2251_3 -# 2251| mu2251_6(unknown) = ^CallSideEffect : ~m? -# 2251| mu2251_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2251_3 -# 2251| v2251_8(void) = ReturnVoid : -# 2251| v2251_9(void) = AliasedUse : ~m? -# 2251| v2251_10(void) = ExitFunction : - -# 2255| ClassWithDestructor& vacuous_destructor_call::get(ClassWithDestructor&) -# 2255| Block 0 -# 2255| v2255_1(void) = EnterFunction : -# 2255| mu2255_2(unknown) = AliasedDefinition : -# 2255| mu2255_3(unknown) = InitializeNonLocal : -# 2255| r2255_4(glval) = VariableAddress[t] : -# 2255| mu2255_5(ClassWithDestructor &) = InitializeParameter[t] : &:r2255_4 -# 2255| r2255_6(ClassWithDestructor &) = Load[t] : &:r2255_4, ~m? -# 2255| mu2255_7(unknown) = InitializeIndirection[t] : &:r2255_6 -# 2255| r2255_8(glval) = VariableAddress[#return] : -# 2255| r2255_9(glval) = VariableAddress[t] : -# 2255| r2255_10(ClassWithDestructor &) = Load[t] : &:r2255_9, ~m? -# 2255| r2255_11(glval) = CopyValue : r2255_10 -# 2255| r2255_12(ClassWithDestructor &) = CopyValue : r2255_11 -# 2255| mu2255_13(ClassWithDestructor &) = Store[#return] : &:r2255_8, r2255_12 -# 2255| v2255_14(void) = ReturnIndirection[t] : &:r2255_6, ~m? -# 2255| r2255_15(glval) = VariableAddress[#return] : -# 2255| v2255_16(void) = ReturnValue : &:r2255_15, ~m? -# 2255| v2255_17(void) = AliasedUse : ~m? -# 2255| v2255_18(void) = ExitFunction : - -# 2255| int& vacuous_destructor_call::get(int&) -# 2255| Block 0 -# 2255| v2255_1(void) = EnterFunction : -# 2255| mu2255_2(unknown) = AliasedDefinition : -# 2255| mu2255_3(unknown) = InitializeNonLocal : -# 2255| r2255_4(glval) = VariableAddress[t] : -# 2255| mu2255_5(int &) = InitializeParameter[t] : &:r2255_4 -# 2255| r2255_6(int &) = Load[t] : &:r2255_4, ~m? -# 2255| mu2255_7(unknown) = InitializeIndirection[t] : &:r2255_6 -# 2255| r2255_8(glval) = VariableAddress[#return] : -# 2255| r2255_9(glval) = VariableAddress[t] : -# 2255| r2255_10(int &) = Load[t] : &:r2255_9, ~m? -# 2255| r2255_11(glval) = CopyValue : r2255_10 -# 2255| r2255_12(int &) = CopyValue : r2255_11 -# 2255| mu2255_13(int &) = Store[#return] : &:r2255_8, r2255_12 -# 2255| v2255_14(void) = ReturnIndirection[t] : &:r2255_6, ~m? -# 2255| r2255_15(glval) = VariableAddress[#return] : -# 2255| v2255_16(void) = ReturnValue : &:r2255_15, ~m? -# 2255| v2255_17(void) = AliasedUse : ~m? -# 2255| v2255_18(void) = ExitFunction : - -# 2258| void vacuous_destructor_call::call_destructor(ClassWithDestructor&) -# 2258| Block 0 -# 2258| v2258_1(void) = EnterFunction : -# 2258| mu2258_2(unknown) = AliasedDefinition : -# 2258| mu2258_3(unknown) = InitializeNonLocal : -# 2258| r2258_4(glval) = VariableAddress[t] : -# 2258| mu2258_5(ClassWithDestructor &) = InitializeParameter[t] : &:r2258_4 -# 2258| r2258_6(ClassWithDestructor &) = Load[t] : &:r2258_4, ~m? -# 2258| mu2258_7(unknown) = InitializeIndirection[t] : &:r2258_6 -# 2259| r2259_1(glval) = FunctionAddress[get] : -# 2259| r2259_2(glval) = VariableAddress[t] : -# 2259| r2259_3(ClassWithDestructor &) = Load[t] : &:r2259_2, ~m? -# 2259| r2259_4(glval) = CopyValue : r2259_3 -# 2259| r2259_5(ClassWithDestructor &) = CopyValue : r2259_4 -# 2259| r2259_6(ClassWithDestructor &) = Call[get] : func:r2259_1, 0:r2259_5 -# 2259| mu2259_7(unknown) = ^CallSideEffect : ~m? -# 2259| v2259_8(void) = ^BufferReadSideEffect[0] : &:r2259_5, ~m? -# 2259| mu2259_9(unknown) = ^BufferMayWriteSideEffect[0] : &:r2259_5 -# 2259| r2259_10(glval) = CopyValue : r2259_6 -# 2259| r2259_11(glval) = FunctionAddress[~ClassWithDestructor] : -# 2259| v2259_12(void) = Call[~ClassWithDestructor] : func:r2259_11 -# 2259| mu2259_13(unknown) = ^CallSideEffect : ~m? -# 2259| v2259_14(void) = ^IndirectReadSideEffect[-1] : &:r2259_10, ~m? -# 2259| mu2259_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2259_10 -# 2260| v2260_1(void) = NoOp : -# 2258| v2258_8(void) = ReturnIndirection[t] : &:r2258_6, ~m? -# 2258| v2258_9(void) = ReturnVoid : -# 2258| v2258_10(void) = AliasedUse : ~m? -# 2258| v2258_11(void) = ExitFunction : - -# 2258| void vacuous_destructor_call::call_destructor(int&) -# 2258| Block 0 -# 2258| v2258_1(void) = EnterFunction : -# 2258| mu2258_2(unknown) = AliasedDefinition : -# 2258| mu2258_3(unknown) = InitializeNonLocal : -# 2258| r2258_4(glval) = VariableAddress[t] : -# 2258| mu2258_5(int &) = InitializeParameter[t] : &:r2258_4 -# 2258| r2258_6(int &) = Load[t] : &:r2258_4, ~m? -# 2258| mu2258_7(unknown) = InitializeIndirection[t] : &:r2258_6 -# 2259| r2259_1(glval) = FunctionAddress[get] : -# 2259| r2259_2(glval) = VariableAddress[t] : -# 2259| r2259_3(int &) = Load[t] : &:r2259_2, ~m? -# 2259| r2259_4(glval) = CopyValue : r2259_3 -# 2259| r2259_5(int &) = CopyValue : r2259_4 -# 2259| r2259_6(int &) = Call[get] : func:r2259_1, 0:r2259_5 -# 2259| mu2259_7(unknown) = ^CallSideEffect : ~m? -# 2259| v2259_8(void) = ^BufferReadSideEffect[0] : &:r2259_5, ~m? -# 2259| mu2259_9(unknown) = ^BufferMayWriteSideEffect[0] : &:r2259_5 -# 2259| r2259_10(glval) = CopyValue : r2259_6 -# 2260| v2260_1(void) = NoOp : -# 2258| v2258_8(void) = ReturnIndirection[t] : &:r2258_6, ~m? -# 2258| v2258_9(void) = ReturnVoid : -# 2258| v2258_10(void) = AliasedUse : ~m? -# 2258| v2258_11(void) = ExitFunction : - -# 2262| void vacuous_destructor_call::non_vacuous_destructor_call() -# 2262| Block 0 -# 2262| v2262_1(void) = EnterFunction : -# 2262| mu2262_2(unknown) = AliasedDefinition : -# 2262| mu2262_3(unknown) = InitializeNonLocal : -# 2263| r2263_1(glval) = VariableAddress[c] : -# 2263| mu2263_2(ClassWithDestructor) = Uninitialized[c] : &:r2263_1 -# 2263| r2263_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2263| v2263_4(void) = Call[ClassWithDestructor] : func:r2263_3, this:r2263_1 -# 2263| mu2263_5(unknown) = ^CallSideEffect : ~m? -# 2263| mu2263_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2263_1 -# 2264| r2264_1(glval) = FunctionAddress[call_destructor] : -# 2264| r2264_2(glval) = VariableAddress[c] : -# 2264| r2264_3(ClassWithDestructor &) = CopyValue : r2264_2 -# 2264| v2264_4(void) = Call[call_destructor] : func:r2264_1, 0:r2264_3 +# 2250| Block 2 +# 2250| v2250_1(void) = NoOp : +# 2250| r2250_2(glval) = VariableAddress[b] : +# 2250| r2250_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2250| v2250_4(void) = Call[~ClassWithDestructor] : func:r2250_3, this:r2250_2 +# 2250| mu2250_5(unknown) = ^CallSideEffect : ~m? +# 2250| v2250_6(void) = ^IndirectReadSideEffect[-1] : &:r2250_2, ~m? +# 2250| mu2250_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2250_2 +# 2250| r2250_8(glval) = VariableAddress[a] : +# 2250| r2250_9(glval) = FunctionAddress[~ClassWithDestructor] : +# 2250| v2250_10(void) = Call[~ClassWithDestructor] : func:r2250_9, this:r2250_8 +# 2250| mu2250_11(unknown) = ^CallSideEffect : ~m? +# 2250| v2250_12(void) = ^IndirectReadSideEffect[-1] : &:r2250_8, ~m? +# 2250| mu2250_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2250_8 +# 2246| v2246_4(void) = ReturnVoid : +# 2246| v2246_5(void) = AliasedUse : ~m? +# 2246| v2246_6(void) = ExitFunction : + +# 2252| ClassWithDestructor global_class_with_destructor +# 2252| Block 0 +# 2252| v2252_1(void) = EnterFunction : +# 2252| mu2252_2(unknown) = AliasedDefinition : +# 2252| r2252_3(glval) = VariableAddress[global_class_with_destructor] : +# 2252| r2252_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2252| v2252_5(void) = Call[ClassWithDestructor] : func:r2252_4, this:r2252_3 +# 2252| mu2252_6(unknown) = ^CallSideEffect : ~m? +# 2252| mu2252_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2252_3 +# 2252| v2252_8(void) = ReturnVoid : +# 2252| v2252_9(void) = AliasedUse : ~m? +# 2252| v2252_10(void) = ExitFunction : + +# 2256| ClassWithDestructor& vacuous_destructor_call::get(ClassWithDestructor&) +# 2256| Block 0 +# 2256| v2256_1(void) = EnterFunction : +# 2256| mu2256_2(unknown) = AliasedDefinition : +# 2256| mu2256_3(unknown) = InitializeNonLocal : +# 2256| r2256_4(glval) = VariableAddress[t] : +# 2256| mu2256_5(ClassWithDestructor &) = InitializeParameter[t] : &:r2256_4 +# 2256| r2256_6(ClassWithDestructor &) = Load[t] : &:r2256_4, ~m? +# 2256| mu2256_7(unknown) = InitializeIndirection[t] : &:r2256_6 +# 2256| r2256_8(glval) = VariableAddress[#return] : +# 2256| r2256_9(glval) = VariableAddress[t] : +# 2256| r2256_10(ClassWithDestructor &) = Load[t] : &:r2256_9, ~m? +# 2256| r2256_11(glval) = CopyValue : r2256_10 +# 2256| r2256_12(ClassWithDestructor &) = CopyValue : r2256_11 +# 2256| mu2256_13(ClassWithDestructor &) = Store[#return] : &:r2256_8, r2256_12 +# 2256| v2256_14(void) = ReturnIndirection[t] : &:r2256_6, ~m? +# 2256| r2256_15(glval) = VariableAddress[#return] : +# 2256| v2256_16(void) = ReturnValue : &:r2256_15, ~m? +# 2256| v2256_17(void) = AliasedUse : ~m? +# 2256| v2256_18(void) = ExitFunction : + +# 2256| int& vacuous_destructor_call::get(int&) +# 2256| Block 0 +# 2256| v2256_1(void) = EnterFunction : +# 2256| mu2256_2(unknown) = AliasedDefinition : +# 2256| mu2256_3(unknown) = InitializeNonLocal : +# 2256| r2256_4(glval) = VariableAddress[t] : +# 2256| mu2256_5(int &) = InitializeParameter[t] : &:r2256_4 +# 2256| r2256_6(int &) = Load[t] : &:r2256_4, ~m? +# 2256| mu2256_7(unknown) = InitializeIndirection[t] : &:r2256_6 +# 2256| r2256_8(glval) = VariableAddress[#return] : +# 2256| r2256_9(glval) = VariableAddress[t] : +# 2256| r2256_10(int &) = Load[t] : &:r2256_9, ~m? +# 2256| r2256_11(glval) = CopyValue : r2256_10 +# 2256| r2256_12(int &) = CopyValue : r2256_11 +# 2256| mu2256_13(int &) = Store[#return] : &:r2256_8, r2256_12 +# 2256| v2256_14(void) = ReturnIndirection[t] : &:r2256_6, ~m? +# 2256| r2256_15(glval) = VariableAddress[#return] : +# 2256| v2256_16(void) = ReturnValue : &:r2256_15, ~m? +# 2256| v2256_17(void) = AliasedUse : ~m? +# 2256| v2256_18(void) = ExitFunction : + +# 2259| void vacuous_destructor_call::call_destructor(ClassWithDestructor&) +# 2259| Block 0 +# 2259| v2259_1(void) = EnterFunction : +# 2259| mu2259_2(unknown) = AliasedDefinition : +# 2259| mu2259_3(unknown) = InitializeNonLocal : +# 2259| r2259_4(glval) = VariableAddress[t] : +# 2259| mu2259_5(ClassWithDestructor &) = InitializeParameter[t] : &:r2259_4 +# 2259| r2259_6(ClassWithDestructor &) = Load[t] : &:r2259_4, ~m? +# 2259| mu2259_7(unknown) = InitializeIndirection[t] : &:r2259_6 +# 2260| r2260_1(glval) = FunctionAddress[get] : +# 2260| r2260_2(glval) = VariableAddress[t] : +# 2260| r2260_3(ClassWithDestructor &) = Load[t] : &:r2260_2, ~m? +# 2260| r2260_4(glval) = CopyValue : r2260_3 +# 2260| r2260_5(ClassWithDestructor &) = CopyValue : r2260_4 +# 2260| r2260_6(ClassWithDestructor &) = Call[get] : func:r2260_1, 0:r2260_5 +# 2260| mu2260_7(unknown) = ^CallSideEffect : ~m? +# 2260| v2260_8(void) = ^BufferReadSideEffect[0] : &:r2260_5, ~m? +# 2260| mu2260_9(unknown) = ^BufferMayWriteSideEffect[0] : &:r2260_5 +# 2260| r2260_10(glval) = CopyValue : r2260_6 +# 2260| r2260_11(glval) = FunctionAddress[~ClassWithDestructor] : +# 2260| v2260_12(void) = Call[~ClassWithDestructor] : func:r2260_11 +# 2260| mu2260_13(unknown) = ^CallSideEffect : ~m? +# 2260| v2260_14(void) = ^IndirectReadSideEffect[-1] : &:r2260_10, ~m? +# 2260| mu2260_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2260_10 +# 2261| v2261_1(void) = NoOp : +# 2259| v2259_8(void) = ReturnIndirection[t] : &:r2259_6, ~m? +# 2259| v2259_9(void) = ReturnVoid : +# 2259| v2259_10(void) = AliasedUse : ~m? +# 2259| v2259_11(void) = ExitFunction : + +# 2259| void vacuous_destructor_call::call_destructor(int&) +# 2259| Block 0 +# 2259| v2259_1(void) = EnterFunction : +# 2259| mu2259_2(unknown) = AliasedDefinition : +# 2259| mu2259_3(unknown) = InitializeNonLocal : +# 2259| r2259_4(glval) = VariableAddress[t] : +# 2259| mu2259_5(int &) = InitializeParameter[t] : &:r2259_4 +# 2259| r2259_6(int &) = Load[t] : &:r2259_4, ~m? +# 2259| mu2259_7(unknown) = InitializeIndirection[t] : &:r2259_6 +# 2260| r2260_1(glval) = FunctionAddress[get] : +# 2260| r2260_2(glval) = VariableAddress[t] : +# 2260| r2260_3(int &) = Load[t] : &:r2260_2, ~m? +# 2260| r2260_4(glval) = CopyValue : r2260_3 +# 2260| r2260_5(int &) = CopyValue : r2260_4 +# 2260| r2260_6(int &) = Call[get] : func:r2260_1, 0:r2260_5 +# 2260| mu2260_7(unknown) = ^CallSideEffect : ~m? +# 2260| v2260_8(void) = ^BufferReadSideEffect[0] : &:r2260_5, ~m? +# 2260| mu2260_9(unknown) = ^BufferMayWriteSideEffect[0] : &:r2260_5 +# 2260| r2260_10(glval) = CopyValue : r2260_6 +# 2261| v2261_1(void) = NoOp : +# 2259| v2259_8(void) = ReturnIndirection[t] : &:r2259_6, ~m? +# 2259| v2259_9(void) = ReturnVoid : +# 2259| v2259_10(void) = AliasedUse : ~m? +# 2259| v2259_11(void) = ExitFunction : + +# 2263| void vacuous_destructor_call::non_vacuous_destructor_call() +# 2263| Block 0 +# 2263| v2263_1(void) = EnterFunction : +# 2263| mu2263_2(unknown) = AliasedDefinition : +# 2263| mu2263_3(unknown) = InitializeNonLocal : +# 2264| r2264_1(glval) = VariableAddress[c] : +# 2264| mu2264_2(ClassWithDestructor) = Uninitialized[c] : &:r2264_1 +# 2264| r2264_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2264| v2264_4(void) = Call[ClassWithDestructor] : func:r2264_3, this:r2264_1 # 2264| mu2264_5(unknown) = ^CallSideEffect : ~m? -# 2264| v2264_6(void) = ^BufferReadSideEffect[0] : &:r2264_3, ~m? -# 2264| mu2264_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r2264_3 -# 2265| v2265_1(void) = NoOp : +# 2264| mu2264_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2264_1 +# 2265| r2265_1(glval) = FunctionAddress[call_destructor] : # 2265| r2265_2(glval) = VariableAddress[c] : -# 2265| r2265_3(glval) = FunctionAddress[~ClassWithDestructor] : -# 2265| v2265_4(void) = Call[~ClassWithDestructor] : func:r2265_3, this:r2265_2 +# 2265| r2265_3(ClassWithDestructor &) = CopyValue : r2265_2 +# 2265| v2265_4(void) = Call[call_destructor] : func:r2265_1, 0:r2265_3 # 2265| mu2265_5(unknown) = ^CallSideEffect : ~m? -# 2265| v2265_6(void) = ^IndirectReadSideEffect[-1] : &:r2265_2, ~m? -# 2265| mu2265_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2265_2 -# 2262| v2262_4(void) = ReturnVoid : -# 2262| v2262_5(void) = AliasedUse : ~m? -# 2262| v2262_6(void) = ExitFunction : - -# 2267| void vacuous_destructor_call::vacuous_destructor_call() -# 2267| Block 0 -# 2267| v2267_1(void) = EnterFunction : -# 2267| mu2267_2(unknown) = AliasedDefinition : -# 2267| mu2267_3(unknown) = InitializeNonLocal : -# 2268| r2268_1(glval) = VariableAddress[i] : -# 2268| mu2268_2(int) = Uninitialized[i] : &:r2268_1 -# 2269| r2269_1(glval) = FunctionAddress[call_destructor] : -# 2269| r2269_2(glval) = VariableAddress[i] : -# 2269| r2269_3(int &) = CopyValue : r2269_2 -# 2269| v2269_4(void) = Call[call_destructor] : func:r2269_1, 0:r2269_3 -# 2269| mu2269_5(unknown) = ^CallSideEffect : ~m? -# 2269| v2269_6(void) = ^BufferReadSideEffect[0] : &:r2269_3, ~m? -# 2269| mu2269_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r2269_3 -# 2270| v2270_1(void) = NoOp : -# 2267| v2267_4(void) = ReturnVoid : -# 2267| v2267_5(void) = AliasedUse : ~m? -# 2267| v2267_6(void) = ExitFunction : - -# 2273| void TryCatchDestructors(bool) -# 2273| Block 0 -# 2273| v2273_1(void) = EnterFunction : -# 2273| mu2273_2(unknown) = AliasedDefinition : -# 2273| mu2273_3(unknown) = InitializeNonLocal : -# 2273| r2273_4(glval) = VariableAddress[b] : -# 2273| mu2273_5(bool) = InitializeParameter[b] : &:r2273_4 -# 2275| r2275_1(glval) = VariableAddress[s] : -# 2275| mu2275_2(String) = Uninitialized[s] : &:r2275_1 -# 2275| r2275_3(glval) = FunctionAddress[String] : -# 2275| v2275_4(void) = Call[String] : func:r2275_3, this:r2275_1 -# 2275| mu2275_5(unknown) = ^CallSideEffect : ~m? -# 2275| mu2275_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2275_1 -# 2276| r2276_1(glval) = VariableAddress[b] : -# 2276| r2276_2(bool) = Load[b] : &:r2276_1, ~m? -# 2276| v2276_3(void) = ConditionalBranch : r2276_2 +# 2265| v2265_6(void) = ^BufferReadSideEffect[0] : &:r2265_3, ~m? +# 2265| mu2265_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r2265_3 +# 2266| v2266_1(void) = NoOp : +# 2266| r2266_2(glval) = VariableAddress[c] : +# 2266| r2266_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2266| v2266_4(void) = Call[~ClassWithDestructor] : func:r2266_3, this:r2266_2 +# 2266| mu2266_5(unknown) = ^CallSideEffect : ~m? +# 2266| v2266_6(void) = ^IndirectReadSideEffect[-1] : &:r2266_2, ~m? +# 2266| mu2266_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2266_2 +# 2263| v2263_4(void) = ReturnVoid : +# 2263| v2263_5(void) = AliasedUse : ~m? +# 2263| v2263_6(void) = ExitFunction : + +# 2268| void vacuous_destructor_call::vacuous_destructor_call() +# 2268| Block 0 +# 2268| v2268_1(void) = EnterFunction : +# 2268| mu2268_2(unknown) = AliasedDefinition : +# 2268| mu2268_3(unknown) = InitializeNonLocal : +# 2269| r2269_1(glval) = VariableAddress[i] : +# 2269| mu2269_2(int) = Uninitialized[i] : &:r2269_1 +# 2270| r2270_1(glval) = FunctionAddress[call_destructor] : +# 2270| r2270_2(glval) = VariableAddress[i] : +# 2270| r2270_3(int &) = CopyValue : r2270_2 +# 2270| v2270_4(void) = Call[call_destructor] : func:r2270_1, 0:r2270_3 +# 2270| mu2270_5(unknown) = ^CallSideEffect : ~m? +# 2270| v2270_6(void) = ^BufferReadSideEffect[0] : &:r2270_3, ~m? +# 2270| mu2270_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r2270_3 +# 2271| v2271_1(void) = NoOp : +# 2268| v2268_4(void) = ReturnVoid : +# 2268| v2268_5(void) = AliasedUse : ~m? +# 2268| v2268_6(void) = ExitFunction : + +# 2274| void TryCatchDestructors(bool) +# 2274| Block 0 +# 2274| v2274_1(void) = EnterFunction : +# 2274| mu2274_2(unknown) = AliasedDefinition : +# 2274| mu2274_3(unknown) = InitializeNonLocal : +# 2274| r2274_4(glval) = VariableAddress[b] : +# 2274| mu2274_5(bool) = InitializeParameter[b] : &:r2274_4 +# 2276| r2276_1(glval) = VariableAddress[s] : +# 2276| mu2276_2(String) = Uninitialized[s] : &:r2276_1 +# 2276| r2276_3(glval) = FunctionAddress[String] : +# 2276| v2276_4(void) = Call[String] : func:r2276_3, this:r2276_1 +# 2276| mu2276_5(unknown) = ^CallSideEffect : ~m? +# 2276| mu2276_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2276_1 +# 2277| r2277_1(glval) = VariableAddress[b] : +# 2277| r2277_2(bool) = Load[b] : &:r2277_1, ~m? +# 2277| v2277_3(void) = ConditionalBranch : r2277_2 #-----| False -> Block 4 #-----| True -> Block 3 -# 2273| Block 1 -# 2273| v2273_6(void) = AliasedUse : ~m? -# 2273| v2273_7(void) = ExitFunction : +# 2274| Block 1 +# 2274| v2274_6(void) = AliasedUse : ~m? +# 2274| v2274_7(void) = ExitFunction : -# 2273| Block 2 -# 2273| v2273_8(void) = Unwind : +# 2274| Block 2 +# 2274| v2274_8(void) = Unwind : #-----| Goto -> Block 1 -# 2277| Block 3 -# 2277| r2277_1(glval) = VariableAddress[#throw2277:7] : -# 2277| r2277_2(glval) = StringConstant["string literal"] : -# 2277| r2277_3(char *) = Convert : r2277_2 -# 2277| mu2277_4(char *) = Store[#throw2277:7] : &:r2277_1, r2277_3 -# 2277| v2277_5(void) = ThrowValue : &:r2277_1, ~m? -# 2280| r2280_1(glval) = VariableAddress[s] : -# 2280| r2280_2(glval) = FunctionAddress[~String] : -# 2280| v2280_3(void) = Call[~String] : func:r2280_2, this:r2280_1 -# 2280| mu2280_4(unknown) = ^CallSideEffect : ~m? -# 2280| v2280_5(void) = ^IndirectReadSideEffect[-1] : &:r2280_1, ~m? -# 2280| mu2280_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_1 +# 2278| Block 3 +# 2278| r2278_1(glval) = VariableAddress[#throw2278:7] : +# 2278| r2278_2(glval) = StringConstant["string literal"] : +# 2278| r2278_3(char *) = Convert : r2278_2 +# 2278| mu2278_4(char *) = Store[#throw2278:7] : &:r2278_1, r2278_3 +# 2278| v2278_5(void) = ThrowValue : &:r2278_1, ~m? +# 2281| r2281_1(glval) = VariableAddress[s] : +# 2281| r2281_2(glval) = FunctionAddress[~String] : +# 2281| v2281_3(void) = Call[~String] : func:r2281_2, this:r2281_1 +# 2281| mu2281_4(unknown) = ^CallSideEffect : ~m? +# 2281| v2281_5(void) = ^IndirectReadSideEffect[-1] : &:r2281_1, ~m? +# 2281| mu2281_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2281_1 #-----| Exception -> Block 5 -# 2279| Block 4 -# 2279| r2279_1(glval) = VariableAddress[s2] : -# 2279| mu2279_2(String) = Uninitialized[s2] : &:r2279_1 -# 2279| r2279_3(glval) = FunctionAddress[String] : -# 2279| v2279_4(void) = Call[String] : func:r2279_3, this:r2279_1 -# 2279| mu2279_5(unknown) = ^CallSideEffect : ~m? -# 2279| mu2279_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2279_1 -# 2280| r2280_7(glval) = VariableAddress[s2] : -# 2280| r2280_8(glval) = FunctionAddress[~String] : -# 2280| v2280_9(void) = Call[~String] : func:r2280_8, this:r2280_7 -# 2280| mu2280_10(unknown) = ^CallSideEffect : ~m? -# 2280| v2280_11(void) = ^IndirectReadSideEffect[-1] : &:r2280_7, ~m? -# 2280| mu2280_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_7 -# 2280| r2280_13(glval) = VariableAddress[s] : -# 2280| r2280_14(glval) = FunctionAddress[~String] : -# 2280| v2280_15(void) = Call[~String] : func:r2280_14, this:r2280_13 -# 2280| mu2280_16(unknown) = ^CallSideEffect : ~m? -# 2280| v2280_17(void) = ^IndirectReadSideEffect[-1] : &:r2280_13, ~m? -# 2280| mu2280_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_13 +# 2280| Block 4 +# 2280| r2280_1(glval) = VariableAddress[s2] : +# 2280| mu2280_2(String) = Uninitialized[s2] : &:r2280_1 +# 2280| r2280_3(glval) = FunctionAddress[String] : +# 2280| v2280_4(void) = Call[String] : func:r2280_3, this:r2280_1 +# 2280| mu2280_5(unknown) = ^CallSideEffect : ~m? +# 2280| mu2280_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_1 +# 2281| r2281_7(glval) = VariableAddress[s2] : +# 2281| r2281_8(glval) = FunctionAddress[~String] : +# 2281| v2281_9(void) = Call[~String] : func:r2281_8, this:r2281_7 +# 2281| mu2281_10(unknown) = ^CallSideEffect : ~m? +# 2281| v2281_11(void) = ^IndirectReadSideEffect[-1] : &:r2281_7, ~m? +# 2281| mu2281_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2281_7 +# 2281| r2281_13(glval) = VariableAddress[s] : +# 2281| r2281_14(glval) = FunctionAddress[~String] : +# 2281| v2281_15(void) = Call[~String] : func:r2281_14, this:r2281_13 +# 2281| mu2281_16(unknown) = ^CallSideEffect : ~m? +# 2281| v2281_17(void) = ^IndirectReadSideEffect[-1] : &:r2281_13, ~m? +# 2281| mu2281_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r2281_13 #-----| Goto -> Block 10 -# 2281| Block 5 -# 2281| v2281_1(void) = CatchByType[const char *] : +# 2282| Block 5 +# 2282| v2282_1(void) = CatchByType[const char *] : #-----| Exception -> Block 7 #-----| Goto -> Block 6 -# 2281| Block 6 -# 2281| r2281_2(glval) = VariableAddress[s] : -# 2281| mu2281_3(char *) = InitializeParameter[s] : &:r2281_2 -# 2281| r2281_4(char *) = Load[s] : &:r2281_2, ~m? -# 2281| mu2281_5(unknown) = InitializeIndirection[s] : &:r2281_4 -# 2282| r2282_1(glval) = VariableAddress[#throw2282:5] : -# 2282| mu2282_2(String) = Uninitialized[#throw2282:5] : &:r2282_1 -# 2282| r2282_3(glval) = FunctionAddress[String] : -# 2282| r2282_4(glval) = VariableAddress[s] : -# 2282| r2282_5(char *) = Load[s] : &:r2282_4, ~m? -# 2282| v2282_6(void) = Call[String] : func:r2282_3, this:r2282_1, 0:r2282_5 -# 2282| mu2282_7(unknown) = ^CallSideEffect : ~m? -# 2282| v2282_8(void) = ^BufferReadSideEffect[0] : &:r2282_5, ~m? -# 2282| mu2282_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2282_1 -# 2282| v2282_10(void) = ThrowValue : &:r2282_1, ~m? +# 2282| Block 6 +# 2282| r2282_2(glval) = VariableAddress[s] : +# 2282| mu2282_3(char *) = InitializeParameter[s] : &:r2282_2 +# 2282| r2282_4(char *) = Load[s] : &:r2282_2, ~m? +# 2282| mu2282_5(unknown) = InitializeIndirection[s] : &:r2282_4 +# 2283| r2283_1(glval) = VariableAddress[#throw2283:5] : +# 2283| mu2283_2(String) = Uninitialized[#throw2283:5] : &:r2283_1 +# 2283| r2283_3(glval) = FunctionAddress[String] : +# 2283| r2283_4(glval) = VariableAddress[s] : +# 2283| r2283_5(char *) = Load[s] : &:r2283_4, ~m? +# 2283| v2283_6(void) = Call[String] : func:r2283_3, this:r2283_1, 0:r2283_5 +# 2283| mu2283_7(unknown) = ^CallSideEffect : ~m? +# 2283| v2283_8(void) = ^BufferReadSideEffect[0] : &:r2283_5, ~m? +# 2283| mu2283_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2283_1 +# 2283| v2283_10(void) = ThrowValue : &:r2283_1, ~m? #-----| Exception -> Block 2 -# 2284| Block 7 -# 2284| v2284_1(void) = CatchByType[const String &] : +# 2285| Block 7 +# 2285| v2285_1(void) = CatchByType[const String &] : #-----| Exception -> Block 9 #-----| Goto -> Block 8 -# 2284| Block 8 -# 2284| r2284_2(glval) = VariableAddress[e] : -# 2284| mu2284_3(String &) = InitializeParameter[e] : &:r2284_2 -# 2284| r2284_4(String &) = Load[e] : &:r2284_2, ~m? -# 2284| mu2284_5(unknown) = InitializeIndirection[e] : &:r2284_4 -# 2284| v2284_6(void) = NoOp : +# 2285| Block 8 +# 2285| r2285_2(glval) = VariableAddress[e] : +# 2285| mu2285_3(String &) = InitializeParameter[e] : &:r2285_2 +# 2285| r2285_4(String &) = Load[e] : &:r2285_2, ~m? +# 2285| mu2285_5(unknown) = InitializeIndirection[e] : &:r2285_4 +# 2285| v2285_6(void) = NoOp : #-----| Goto -> Block 10 -# 2286| Block 9 -# 2286| v2286_1(void) = CatchAny : -# 2287| v2287_1(void) = ReThrow : +# 2287| Block 9 +# 2287| v2287_1(void) = CatchAny : +# 2288| v2288_1(void) = ReThrow : #-----| Exception -> Block 2 -# 2289| Block 10 -# 2289| v2289_1(void) = NoOp : -# 2273| v2273_9(void) = ReturnVoid : +# 2290| Block 10 +# 2290| v2290_1(void) = NoOp : +# 2274| v2274_9(void) = ReturnVoid : #-----| Goto -> Block 1 -# 2291| void IfDestructors(bool) -# 2291| Block 0 -# 2291| v2291_1(void) = EnterFunction : -# 2291| mu2291_2(unknown) = AliasedDefinition : -# 2291| mu2291_3(unknown) = InitializeNonLocal : -# 2291| r2291_4(glval) = VariableAddress[b] : -# 2291| mu2291_5(bool) = InitializeParameter[b] : &:r2291_4 -# 2292| r2292_1(glval) = VariableAddress[s1] : -# 2292| mu2292_2(String) = Uninitialized[s1] : &:r2292_1 -# 2292| r2292_3(glval) = FunctionAddress[String] : -# 2292| v2292_4(void) = Call[String] : func:r2292_3, this:r2292_1 -# 2292| mu2292_5(unknown) = ^CallSideEffect : ~m? -# 2292| mu2292_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2292_1 -# 2293| r2293_1(glval) = VariableAddress[b] : -# 2293| r2293_2(bool) = Load[b] : &:r2293_1, ~m? -# 2293| v2293_3(void) = ConditionalBranch : r2293_2 +# 2292| void IfDestructors(bool) +# 2292| Block 0 +# 2292| v2292_1(void) = EnterFunction : +# 2292| mu2292_2(unknown) = AliasedDefinition : +# 2292| mu2292_3(unknown) = InitializeNonLocal : +# 2292| r2292_4(glval) = VariableAddress[b] : +# 2292| mu2292_5(bool) = InitializeParameter[b] : &:r2292_4 +# 2293| r2293_1(glval) = VariableAddress[s1] : +# 2293| mu2293_2(String) = Uninitialized[s1] : &:r2293_1 +# 2293| r2293_3(glval) = FunctionAddress[String] : +# 2293| v2293_4(void) = Call[String] : func:r2293_3, this:r2293_1 +# 2293| mu2293_5(unknown) = ^CallSideEffect : ~m? +# 2293| mu2293_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2293_1 +# 2294| r2294_1(glval) = VariableAddress[b] : +# 2294| r2294_2(bool) = Load[b] : &:r2294_1, ~m? +# 2294| v2294_3(void) = ConditionalBranch : r2294_2 #-----| False -> Block 2 #-----| True -> Block 1 -# 2294| Block 1 -# 2294| r2294_1(glval) = VariableAddress[s2] : -# 2294| mu2294_2(String) = Uninitialized[s2] : &:r2294_1 -# 2294| r2294_3(glval) = FunctionAddress[String] : -# 2294| v2294_4(void) = Call[String] : func:r2294_3, this:r2294_1 -# 2294| mu2294_5(unknown) = ^CallSideEffect : ~m? -# 2294| mu2294_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2294_1 +# 2295| Block 1 # 2295| r2295_1(glval) = VariableAddress[s2] : -# 2295| r2295_2(glval) = FunctionAddress[~String] : -# 2295| v2295_3(void) = Call[~String] : func:r2295_2, this:r2295_1 -# 2295| mu2295_4(unknown) = ^CallSideEffect : ~m? -# 2295| v2295_5(void) = ^IndirectReadSideEffect[-1] : &:r2295_1, ~m? +# 2295| mu2295_2(String) = Uninitialized[s2] : &:r2295_1 +# 2295| r2295_3(glval) = FunctionAddress[String] : +# 2295| v2295_4(void) = Call[String] : func:r2295_3, this:r2295_1 +# 2295| mu2295_5(unknown) = ^CallSideEffect : ~m? # 2295| mu2295_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2295_1 +# 2296| r2296_1(glval) = VariableAddress[s2] : +# 2296| r2296_2(glval) = FunctionAddress[~String] : +# 2296| v2296_3(void) = Call[~String] : func:r2296_2, this:r2296_1 +# 2296| mu2296_4(unknown) = ^CallSideEffect : ~m? +# 2296| v2296_5(void) = ^IndirectReadSideEffect[-1] : &:r2296_1, ~m? +# 2296| mu2296_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2296_1 #-----| Goto -> Block 3 -# 2296| Block 2 -# 2296| r2296_1(glval) = VariableAddress[s3] : -# 2296| mu2296_2(String) = Uninitialized[s3] : &:r2296_1 -# 2296| r2296_3(glval) = FunctionAddress[String] : -# 2296| v2296_4(void) = Call[String] : func:r2296_3, this:r2296_1 -# 2296| mu2296_5(unknown) = ^CallSideEffect : ~m? -# 2296| mu2296_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2296_1 +# 2297| Block 2 # 2297| r2297_1(glval) = VariableAddress[s3] : -# 2297| r2297_2(glval) = FunctionAddress[~String] : -# 2297| v2297_3(void) = Call[~String] : func:r2297_2, this:r2297_1 -# 2297| mu2297_4(unknown) = ^CallSideEffect : ~m? -# 2297| v2297_5(void) = ^IndirectReadSideEffect[-1] : &:r2297_1, ~m? +# 2297| mu2297_2(String) = Uninitialized[s3] : &:r2297_1 +# 2297| r2297_3(glval) = FunctionAddress[String] : +# 2297| v2297_4(void) = Call[String] : func:r2297_3, this:r2297_1 +# 2297| mu2297_5(unknown) = ^CallSideEffect : ~m? # 2297| mu2297_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2297_1 +# 2298| r2298_1(glval) = VariableAddress[s3] : +# 2298| r2298_2(glval) = FunctionAddress[~String] : +# 2298| v2298_3(void) = Call[~String] : func:r2298_2, this:r2298_1 +# 2298| mu2298_4(unknown) = ^CallSideEffect : ~m? +# 2298| v2298_5(void) = ^IndirectReadSideEffect[-1] : &:r2298_1, ~m? +# 2298| mu2298_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2298_1 #-----| Goto -> Block 3 -# 2298| Block 3 -# 2298| r2298_1(glval) = VariableAddress[s4] : -# 2298| mu2298_2(String) = Uninitialized[s4] : &:r2298_1 -# 2298| r2298_3(glval) = FunctionAddress[String] : -# 2298| v2298_4(void) = Call[String] : func:r2298_3, this:r2298_1 -# 2298| mu2298_5(unknown) = ^CallSideEffect : ~m? -# 2298| mu2298_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2298_1 -# 2299| v2299_1(void) = NoOp : -# 2299| r2299_2(glval) = VariableAddress[s4] : -# 2299| r2299_3(glval) = FunctionAddress[~String] : -# 2299| v2299_4(void) = Call[~String] : func:r2299_3, this:r2299_2 +# 2299| Block 3 +# 2299| r2299_1(glval) = VariableAddress[s4] : +# 2299| mu2299_2(String) = Uninitialized[s4] : &:r2299_1 +# 2299| r2299_3(glval) = FunctionAddress[String] : +# 2299| v2299_4(void) = Call[String] : func:r2299_3, this:r2299_1 # 2299| mu2299_5(unknown) = ^CallSideEffect : ~m? -# 2299| v2299_6(void) = ^IndirectReadSideEffect[-1] : &:r2299_2, ~m? -# 2299| mu2299_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2299_2 -# 2299| r2299_8(glval) = VariableAddress[s1] : -# 2299| r2299_9(glval) = FunctionAddress[~String] : -# 2299| v2299_10(void) = Call[~String] : func:r2299_9, this:r2299_8 -# 2299| mu2299_11(unknown) = ^CallSideEffect : ~m? -# 2299| v2299_12(void) = ^IndirectReadSideEffect[-1] : &:r2299_8, ~m? -# 2299| mu2299_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r2299_8 -# 2291| v2291_6(void) = ReturnVoid : -# 2291| v2291_7(void) = AliasedUse : ~m? -# 2291| v2291_8(void) = ExitFunction : - -# 2301| void ForDestructors() -# 2301| Block 0 -# 2301| v2301_1(void) = EnterFunction : -# 2301| mu2301_2(unknown) = AliasedDefinition : -# 2301| mu2301_3(unknown) = InitializeNonLocal : -# 2302| r2302_1(glval) = VariableAddress[c] : -# 2302| r2302_2(char) = Constant[97] : -# 2302| mu2302_3(char) = Store[c] : &:r2302_1, r2302_2 -# 2303| r2303_1(glval) = VariableAddress[s] : -# 2303| mu2303_2(String) = Uninitialized[s] : &:r2303_1 -# 2303| r2303_3(glval) = FunctionAddress[String] : -# 2303| r2303_4(glval) = StringConstant["hello"] : -# 2303| r2303_5(char *) = Convert : r2303_4 -# 2303| v2303_6(void) = Call[String] : func:r2303_3, this:r2303_1, 0:r2303_5 -# 2303| mu2303_7(unknown) = ^CallSideEffect : ~m? -# 2303| v2303_8(void) = ^BufferReadSideEffect[0] : &:r2303_5, ~m? -# 2303| mu2303_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2303_1 +# 2299| mu2299_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2299_1 +# 2300| v2300_1(void) = NoOp : +# 2300| r2300_2(glval) = VariableAddress[s4] : +# 2300| r2300_3(glval) = FunctionAddress[~String] : +# 2300| v2300_4(void) = Call[~String] : func:r2300_3, this:r2300_2 +# 2300| mu2300_5(unknown) = ^CallSideEffect : ~m? +# 2300| v2300_6(void) = ^IndirectReadSideEffect[-1] : &:r2300_2, ~m? +# 2300| mu2300_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2300_2 +# 2300| r2300_8(glval) = VariableAddress[s1] : +# 2300| r2300_9(glval) = FunctionAddress[~String] : +# 2300| v2300_10(void) = Call[~String] : func:r2300_9, this:r2300_8 +# 2300| mu2300_11(unknown) = ^CallSideEffect : ~m? +# 2300| v2300_12(void) = ^IndirectReadSideEffect[-1] : &:r2300_8, ~m? +# 2300| mu2300_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r2300_8 +# 2292| v2292_6(void) = ReturnVoid : +# 2292| v2292_7(void) = AliasedUse : ~m? +# 2292| v2292_8(void) = ExitFunction : + +# 2302| void ForDestructors() +# 2302| Block 0 +# 2302| v2302_1(void) = EnterFunction : +# 2302| mu2302_2(unknown) = AliasedDefinition : +# 2302| mu2302_3(unknown) = InitializeNonLocal : +# 2303| r2303_1(glval) = VariableAddress[c] : +# 2303| r2303_2(char) = Constant[97] : +# 2303| mu2303_3(char) = Store[c] : &:r2303_1, r2303_2 +# 2304| r2304_1(glval) = VariableAddress[s] : +# 2304| mu2304_2(String) = Uninitialized[s] : &:r2304_1 +# 2304| r2304_3(glval) = FunctionAddress[String] : +# 2304| r2304_4(glval) = StringConstant["hello"] : +# 2304| r2304_5(char *) = Convert : r2304_4 +# 2304| v2304_6(void) = Call[String] : func:r2304_3, this:r2304_1, 0:r2304_5 +# 2304| mu2304_7(unknown) = ^CallSideEffect : ~m? +# 2304| v2304_8(void) = ^BufferReadSideEffect[0] : &:r2304_5, ~m? +# 2304| mu2304_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_1 #-----| Goto -> Block 1 -# 2303| Block 1 -# 2303| r2303_10(glval) = VariableAddress[c] : -# 2303| r2303_11(char) = Load[c] : &:r2303_10, ~m? -# 2303| r2303_12(int) = Convert : r2303_11 -# 2303| r2303_13(int) = Constant[0] : -# 2303| r2303_14(bool) = CompareNE : r2303_12, r2303_13 -# 2303| v2303_15(void) = ConditionalBranch : r2303_14 +# 2304| Block 1 +# 2304| r2304_10(glval) = VariableAddress[c] : +# 2304| r2304_11(char) = Load[c] : &:r2304_10, ~m? +# 2304| r2304_12(int) = Convert : r2304_11 +# 2304| r2304_13(int) = Constant[0] : +# 2304| r2304_14(bool) = CompareNE : r2304_12, r2304_13 +# 2304| v2304_15(void) = ConditionalBranch : r2304_14 #-----| False -> Block 3 #-----| True -> Block 2 -# 2304| Block 2 -# 2304| r2304_1(glval) = VariableAddress[s2] : -# 2304| mu2304_2(String) = Uninitialized[s2] : &:r2304_1 -# 2304| r2304_3(glval) = FunctionAddress[String] : -# 2304| v2304_4(void) = Call[String] : func:r2304_3, this:r2304_1 -# 2304| mu2304_5(unknown) = ^CallSideEffect : ~m? -# 2304| mu2304_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_1 +# 2305| Block 2 # 2305| r2305_1(glval) = VariableAddress[s2] : -# 2305| r2305_2(glval) = FunctionAddress[~String] : -# 2305| v2305_3(void) = Call[~String] : func:r2305_2, this:r2305_1 -# 2305| mu2305_4(unknown) = ^CallSideEffect : ~m? -# 2305| v2305_5(void) = ^IndirectReadSideEffect[-1] : &:r2305_1, ~m? +# 2305| mu2305_2(String) = Uninitialized[s2] : &:r2305_1 +# 2305| r2305_3(glval) = FunctionAddress[String] : +# 2305| v2305_4(void) = Call[String] : func:r2305_3, this:r2305_1 +# 2305| mu2305_5(unknown) = ^CallSideEffect : ~m? # 2305| mu2305_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2305_1 -# 2303| r2303_16(glval) = VariableAddress[s] : -# 2303| r2303_17(glval) = FunctionAddress[pop_back] : -# 2303| r2303_18(char) = Call[pop_back] : func:r2303_17, this:r2303_16 -# 2303| mu2303_19(unknown) = ^CallSideEffect : ~m? -# 2303| v2303_20(void) = ^IndirectReadSideEffect[-1] : &:r2303_16, ~m? -# 2303| mu2303_21(String) = ^IndirectMayWriteSideEffect[-1] : &:r2303_16 -# 2303| r2303_22(glval) = VariableAddress[c] : -# 2303| mu2303_23(char) = Store[c] : &:r2303_22, r2303_18 +# 2306| r2306_1(glval) = VariableAddress[s2] : +# 2306| r2306_2(glval) = FunctionAddress[~String] : +# 2306| v2306_3(void) = Call[~String] : func:r2306_2, this:r2306_1 +# 2306| mu2306_4(unknown) = ^CallSideEffect : ~m? +# 2306| v2306_5(void) = ^IndirectReadSideEffect[-1] : &:r2306_1, ~m? +# 2306| mu2306_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2306_1 +# 2304| r2304_16(glval) = VariableAddress[s] : +# 2304| r2304_17(glval) = FunctionAddress[pop_back] : +# 2304| r2304_18(char) = Call[pop_back] : func:r2304_17, this:r2304_16 +# 2304| mu2304_19(unknown) = ^CallSideEffect : ~m? +# 2304| v2304_20(void) = ^IndirectReadSideEffect[-1] : &:r2304_16, ~m? +# 2304| mu2304_21(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_16 +# 2304| r2304_22(glval) = VariableAddress[c] : +# 2304| mu2304_23(char) = Store[c] : &:r2304_22, r2304_18 #-----| Goto (back edge) -> Block 1 -# 2303| Block 3 -# 2303| r2303_24(glval) = VariableAddress[s] : -# 2303| r2303_25(glval) = FunctionAddress[~String] : -# 2303| v2303_26(void) = Call[~String] : func:r2303_25, this:r2303_24 -# 2303| mu2303_27(unknown) = ^CallSideEffect : ~m? -# 2303| v2303_28(void) = ^IndirectReadSideEffect[-1] : &:r2303_24, ~m? -# 2303| mu2303_29(String) = ^IndirectMayWriteSideEffect[-1] : &:r2303_24 -# 2307| r2307_1(glval &&>) = VariableAddress[(__range)] : -# 2307| r2307_2(glval>) = VariableAddress[#temp2307:20] : -# 2307| mu2307_3(vector) = Uninitialized[#temp2307:20] : &:r2307_2 -# 2307| r2307_4(glval) = FunctionAddress[vector] : -# 2307| r2307_5(glval) = VariableAddress[#temp2307:40] : -# 2307| mu2307_6(String) = Uninitialized[#temp2307:40] : &:r2307_5 -# 2307| r2307_7(glval) = FunctionAddress[String] : -# 2307| r2307_8(glval) = StringConstant["hello"] : -# 2307| r2307_9(char *) = Convert : r2307_8 -# 2307| v2307_10(void) = Call[String] : func:r2307_7, this:r2307_5, 0:r2307_9 -# 2307| mu2307_11(unknown) = ^CallSideEffect : ~m? -# 2307| v2307_12(void) = ^BufferReadSideEffect[0] : &:r2307_9, ~m? -# 2307| mu2307_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_5 -# 2307| r2307_14(String) = Load[#temp2307:40] : &:r2307_5, ~m? -# 2307| v2307_15(void) = Call[vector] : func:r2307_4, this:r2307_2, 0:r2307_14 -# 2307| mu2307_16(unknown) = ^CallSideEffect : ~m? -# 2307| mu2307_17(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2307_2 -# 2307| r2307_18(glval) = CopyValue : r2307_5 -# 2307| r2307_19(glval) = FunctionAddress[~String] : -# 2307| v2307_20(void) = Call[~String] : func:r2307_19, this:r2307_18 -# 2307| mu2307_21(unknown) = ^CallSideEffect : ~m? -# 2307| v2307_22(void) = ^IndirectReadSideEffect[-1] : &:r2307_18, ~m? -# 2307| mu2307_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_18 -# 2307| r2307_24(vector &) = CopyValue : r2307_2 -# 2307| mu2307_25(vector &&) = Store[(__range)] : &:r2307_1, r2307_24 -# 2307| r2307_26(glval>) = VariableAddress[(__begin)] : -# 2307| r2307_27(glval &&>) = VariableAddress[(__range)] : -# 2307| r2307_28(vector &&) = Load[(__range)] : &:r2307_27, ~m? -#-----| r0_1(glval>) = CopyValue : r2307_28 +# 2304| Block 3 +# 2304| r2304_24(glval) = VariableAddress[s] : +# 2304| r2304_25(glval) = FunctionAddress[~String] : +# 2304| v2304_26(void) = Call[~String] : func:r2304_25, this:r2304_24 +# 2304| mu2304_27(unknown) = ^CallSideEffect : ~m? +# 2304| v2304_28(void) = ^IndirectReadSideEffect[-1] : &:r2304_24, ~m? +# 2304| mu2304_29(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_24 +# 2308| r2308_1(glval &&>) = VariableAddress[(__range)] : +# 2308| r2308_2(glval>) = VariableAddress[#temp2308:20] : +# 2308| mu2308_3(vector) = Uninitialized[#temp2308:20] : &:r2308_2 +# 2308| r2308_4(glval) = FunctionAddress[vector] : +# 2308| r2308_5(glval) = VariableAddress[#temp2308:40] : +# 2308| mu2308_6(String) = Uninitialized[#temp2308:40] : &:r2308_5 +# 2308| r2308_7(glval) = FunctionAddress[String] : +# 2308| r2308_8(glval) = StringConstant["hello"] : +# 2308| r2308_9(char *) = Convert : r2308_8 +# 2308| v2308_10(void) = Call[String] : func:r2308_7, this:r2308_5, 0:r2308_9 +# 2308| mu2308_11(unknown) = ^CallSideEffect : ~m? +# 2308| v2308_12(void) = ^BufferReadSideEffect[0] : &:r2308_9, ~m? +# 2308| mu2308_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_5 +# 2308| r2308_14(String) = Load[#temp2308:40] : &:r2308_5, ~m? +# 2308| v2308_15(void) = Call[vector] : func:r2308_4, this:r2308_2, 0:r2308_14 +# 2308| mu2308_16(unknown) = ^CallSideEffect : ~m? +# 2308| mu2308_17(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2308_2 +# 2308| r2308_18(glval) = CopyValue : r2308_5 +# 2308| r2308_19(glval) = FunctionAddress[~String] : +# 2308| v2308_20(void) = Call[~String] : func:r2308_19, this:r2308_18 +# 2308| mu2308_21(unknown) = ^CallSideEffect : ~m? +# 2308| v2308_22(void) = ^IndirectReadSideEffect[-1] : &:r2308_18, ~m? +# 2308| mu2308_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_18 +# 2308| r2308_24(vector &) = CopyValue : r2308_2 +# 2308| mu2308_25(vector &&) = Store[(__range)] : &:r2308_1, r2308_24 +# 2308| r2308_26(glval>) = VariableAddress[(__begin)] : +# 2308| r2308_27(glval &&>) = VariableAddress[(__range)] : +# 2308| r2308_28(vector &&) = Load[(__range)] : &:r2308_27, ~m? +#-----| r0_1(glval>) = CopyValue : r2308_28 #-----| r0_2(glval>) = Convert : r0_1 -# 2307| r2307_29(glval) = FunctionAddress[begin] : -# 2307| r2307_30(iterator) = Call[begin] : func:r2307_29, this:r0_2 +# 2308| r2308_29(glval) = FunctionAddress[begin] : +# 2308| r2308_30(iterator) = Call[begin] : func:r2308_29, this:r0_2 #-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m? -# 2307| mu2307_31(iterator) = Store[(__begin)] : &:r2307_26, r2307_30 -# 2307| r2307_32(glval>) = VariableAddress[(__end)] : -# 2307| r2307_33(glval &&>) = VariableAddress[(__range)] : -# 2307| r2307_34(vector &&) = Load[(__range)] : &:r2307_33, ~m? -#-----| r0_4(glval>) = CopyValue : r2307_34 +# 2308| mu2308_31(iterator) = Store[(__begin)] : &:r2308_26, r2308_30 +# 2308| r2308_32(glval>) = VariableAddress[(__end)] : +# 2308| r2308_33(glval &&>) = VariableAddress[(__range)] : +# 2308| r2308_34(vector &&) = Load[(__range)] : &:r2308_33, ~m? +#-----| r0_4(glval>) = CopyValue : r2308_34 #-----| r0_5(glval>) = Convert : r0_4 -# 2307| r2307_35(glval) = FunctionAddress[end] : -# 2307| r2307_36(iterator) = Call[end] : func:r2307_35, this:r0_5 +# 2308| r2308_35(glval) = FunctionAddress[end] : +# 2308| r2308_36(iterator) = Call[end] : func:r2308_35, this:r0_5 #-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m? -# 2307| mu2307_37(iterator) = Store[(__end)] : &:r2307_32, r2307_36 +# 2308| mu2308_37(iterator) = Store[(__end)] : &:r2308_32, r2308_36 #-----| Goto -> Block 4 -# 2307| Block 4 -# 2307| r2307_38(glval>) = VariableAddress[(__begin)] : -#-----| r0_7(glval>) = Convert : r2307_38 -# 2307| r2307_39(glval) = FunctionAddress[operator!=] : +# 2308| Block 4 +# 2308| r2308_38(glval>) = VariableAddress[(__begin)] : +#-----| r0_7(glval>) = Convert : r2308_38 +# 2308| r2308_39(glval) = FunctionAddress[operator!=] : #-----| r0_8(glval>) = VariableAddress[#temp0:0] : #-----| mu0_9(iterator) = Uninitialized[#temp0:0] : &:r0_8 -# 2307| r2307_40(glval) = FunctionAddress[iterator] : -# 2307| r2307_41(glval>) = VariableAddress[(__end)] : -#-----| r0_10(glval>) = Convert : r2307_41 +# 2308| r2308_40(glval) = FunctionAddress[iterator] : +# 2308| r2308_41(glval>) = VariableAddress[(__end)] : +#-----| r0_10(glval>) = Convert : r2308_41 #-----| r0_11(iterator &) = CopyValue : r0_10 -# 2307| v2307_42(void) = Call[iterator] : func:r2307_40, this:r0_8, 0:r0_11 -# 2307| mu2307_43(unknown) = ^CallSideEffect : ~m? +# 2308| v2308_42(void) = Call[iterator] : func:r2308_40, this:r0_8, 0:r0_11 +# 2308| mu2308_43(unknown) = ^CallSideEffect : ~m? #-----| v0_12(void) = ^BufferReadSideEffect[0] : &:r0_11, ~m? -# 2307| mu2307_44(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 2308| mu2308_44(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 #-----| r0_13(iterator) = Load[#temp0:0] : &:r0_8, ~m? -# 2307| r2307_45(bool) = Call[operator!=] : func:r2307_39, this:r0_7, 0:r0_13 +# 2308| r2308_45(bool) = Call[operator!=] : func:r2308_39, this:r0_7, 0:r0_13 #-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~m? -# 2307| v2307_46(void) = ConditionalBranch : r2307_45 +# 2308| v2308_46(void) = ConditionalBranch : r2308_45 #-----| False -> Block 6 #-----| True -> Block 5 -# 2307| Block 5 -# 2307| r2307_47(glval) = VariableAddress[s] : -# 2307| mu2307_48(String) = Uninitialized[s] : &:r2307_47 -# 2307| r2307_49(glval) = FunctionAddress[String] : -# 2307| r2307_50(glval>) = VariableAddress[(__begin)] : -#-----| r0_15(glval>) = Convert : r2307_50 -# 2307| r2307_51(glval) = FunctionAddress[operator*] : -# 2307| r2307_52(String &) = Call[operator*] : func:r2307_51, this:r0_15 +# 2308| Block 5 +# 2308| r2308_47(glval) = VariableAddress[s] : +# 2308| mu2308_48(String) = Uninitialized[s] : &:r2308_47 +# 2308| r2308_49(glval) = FunctionAddress[String] : +# 2308| r2308_50(glval>) = VariableAddress[(__begin)] : +#-----| r0_15(glval>) = Convert : r2308_50 +# 2308| r2308_51(glval) = FunctionAddress[operator*] : +# 2308| r2308_52(String &) = Call[operator*] : func:r2308_51, this:r0_15 #-----| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_15, ~m? -# 2307| r2307_53(glval) = CopyValue : r2307_52 -# 2307| r2307_54(glval) = Convert : r2307_53 -# 2307| r2307_55(String &) = CopyValue : r2307_54 -# 2307| v2307_56(void) = Call[String] : func:r2307_49, this:r2307_47, 0:r2307_55 -# 2307| mu2307_57(unknown) = ^CallSideEffect : ~m? -# 2307| v2307_58(void) = ^BufferReadSideEffect[0] : &:r2307_55, ~m? -# 2307| mu2307_59(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_47 -# 2308| r2308_1(glval) = VariableAddress[s2] : -# 2308| mu2308_2(String) = Uninitialized[s2] : &:r2308_1 -# 2308| r2308_3(glval) = FunctionAddress[String] : -# 2308| v2308_4(void) = Call[String] : func:r2308_3, this:r2308_1 -# 2308| mu2308_5(unknown) = ^CallSideEffect : ~m? -# 2308| mu2308_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_1 +# 2308| r2308_53(glval) = CopyValue : r2308_52 +# 2308| r2308_54(glval) = Convert : r2308_53 +# 2308| r2308_55(String &) = CopyValue : r2308_54 +# 2308| v2308_56(void) = Call[String] : func:r2308_49, this:r2308_47, 0:r2308_55 +# 2308| mu2308_57(unknown) = ^CallSideEffect : ~m? +# 2308| v2308_58(void) = ^BufferReadSideEffect[0] : &:r2308_55, ~m? +# 2308| mu2308_59(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_47 # 2309| r2309_1(glval) = VariableAddress[s2] : -# 2309| r2309_2(glval) = FunctionAddress[~String] : -# 2309| v2309_3(void) = Call[~String] : func:r2309_2, this:r2309_1 -# 2309| mu2309_4(unknown) = ^CallSideEffect : ~m? -# 2309| v2309_5(void) = ^IndirectReadSideEffect[-1] : &:r2309_1, ~m? +# 2309| mu2309_2(String) = Uninitialized[s2] : &:r2309_1 +# 2309| r2309_3(glval) = FunctionAddress[String] : +# 2309| v2309_4(void) = Call[String] : func:r2309_3, this:r2309_1 +# 2309| mu2309_5(unknown) = ^CallSideEffect : ~m? # 2309| mu2309_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2309_1 -# 2307| r2307_60(glval) = VariableAddress[s] : -# 2307| r2307_61(glval) = FunctionAddress[~String] : -# 2307| v2307_62(void) = Call[~String] : func:r2307_61, this:r2307_60 -# 2307| mu2307_63(unknown) = ^CallSideEffect : ~m? -# 2307| v2307_64(void) = ^IndirectReadSideEffect[-1] : &:r2307_60, ~m? -# 2307| mu2307_65(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_60 -# 2307| r2307_66(glval>) = VariableAddress[(__begin)] : -# 2307| r2307_67(glval) = FunctionAddress[operator++] : -# 2307| r2307_68(iterator &) = Call[operator++] : func:r2307_67, this:r2307_66 -# 2307| v2307_69(void) = ^IndirectReadSideEffect[-1] : &:r2307_66, ~m? -# 2307| mu2307_70(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2307_66 -# 2307| r2307_71(glval>) = CopyValue : r2307_68 +# 2310| r2310_1(glval) = VariableAddress[s2] : +# 2310| r2310_2(glval) = FunctionAddress[~String] : +# 2310| v2310_3(void) = Call[~String] : func:r2310_2, this:r2310_1 +# 2310| mu2310_4(unknown) = ^CallSideEffect : ~m? +# 2310| v2310_5(void) = ^IndirectReadSideEffect[-1] : &:r2310_1, ~m? +# 2310| mu2310_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2310_1 +# 2308| r2308_60(glval>) = VariableAddress[(__begin)] : +# 2308| r2308_61(glval) = FunctionAddress[operator++] : +# 2308| r2308_62(iterator &) = Call[operator++] : func:r2308_61, this:r2308_60 +# 2308| v2308_63(void) = ^IndirectReadSideEffect[-1] : &:r2308_60, ~m? +# 2308| mu2308_64(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2308_60 +# 2308| r2308_65(glval) = VariableAddress[s] : +# 2308| r2308_66(glval) = FunctionAddress[~String] : +# 2308| v2308_67(void) = Call[~String] : func:r2308_66, this:r2308_65 +# 2308| mu2308_68(unknown) = ^CallSideEffect : ~m? +# 2308| v2308_69(void) = ^IndirectReadSideEffect[-1] : &:r2308_65, ~m? +# 2308| mu2308_70(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_65 +# 2308| r2308_71(glval>) = CopyValue : r2308_62 #-----| Goto (back edge) -> Block 4 -# 2311| Block 6 -# 2311| r2311_1(glval) = VariableAddress[s] : -# 2311| mu2311_2(String) = Uninitialized[s] : &:r2311_1 -# 2311| r2311_3(glval) = FunctionAddress[String] : -# 2311| r2311_4(glval) = StringConstant["hello"] : -# 2311| r2311_5(char *) = Convert : r2311_4 -# 2311| v2311_6(void) = Call[String] : func:r2311_3, this:r2311_1, 0:r2311_5 -# 2311| mu2311_7(unknown) = ^CallSideEffect : ~m? -# 2311| v2311_8(void) = ^BufferReadSideEffect[0] : &:r2311_5, ~m? -# 2311| mu2311_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_1 -# 2311| r2311_10(glval) = VariableAddress[s2] : -# 2311| mu2311_11(String) = Uninitialized[s2] : &:r2311_10 -# 2311| r2311_12(glval) = FunctionAddress[String] : -# 2311| r2311_13(glval) = StringConstant["world"] : -# 2311| r2311_14(char *) = Convert : r2311_13 -# 2311| v2311_15(void) = Call[String] : func:r2311_12, this:r2311_10, 0:r2311_14 -# 2311| mu2311_16(unknown) = ^CallSideEffect : ~m? -# 2311| v2311_17(void) = ^BufferReadSideEffect[0] : &:r2311_14, ~m? -# 2311| mu2311_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_10 +# 2308| Block 6 +# 2308| r2308_72(glval>) = CopyValue : r2308_2 +# 2308| r2308_73(glval) = FunctionAddress[~vector] : +# 2308| v2308_74(void) = Call[~vector] : func:r2308_73, this:r2308_72 +# 2308| mu2308_75(unknown) = ^CallSideEffect : ~m? +# 2308| v2308_76(void) = ^IndirectReadSideEffect[-1] : &:r2308_72, ~m? +# 2308| mu2308_77(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2308_72 +# 2312| r2312_1(glval) = VariableAddress[s] : +# 2312| mu2312_2(String) = Uninitialized[s] : &:r2312_1 +# 2312| r2312_3(glval) = FunctionAddress[String] : +# 2312| r2312_4(glval) = StringConstant["hello"] : +# 2312| r2312_5(char *) = Convert : r2312_4 +# 2312| v2312_6(void) = Call[String] : func:r2312_3, this:r2312_1, 0:r2312_5 +# 2312| mu2312_7(unknown) = ^CallSideEffect : ~m? +# 2312| v2312_8(void) = ^BufferReadSideEffect[0] : &:r2312_5, ~m? +# 2312| mu2312_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_1 +# 2312| r2312_10(glval) = VariableAddress[s2] : +# 2312| mu2312_11(String) = Uninitialized[s2] : &:r2312_10 +# 2312| r2312_12(glval) = FunctionAddress[String] : +# 2312| r2312_13(glval) = StringConstant["world"] : +# 2312| r2312_14(char *) = Convert : r2312_13 +# 2312| v2312_15(void) = Call[String] : func:r2312_12, this:r2312_10, 0:r2312_14 +# 2312| mu2312_16(unknown) = ^CallSideEffect : ~m? +# 2312| v2312_17(void) = ^BufferReadSideEffect[0] : &:r2312_14, ~m? +# 2312| mu2312_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_10 #-----| Goto -> Block 7 -# 2311| Block 7 -# 2311| r2311_19(glval) = VariableAddress[c] : -# 2311| r2311_20(char) = Load[c] : &:r2311_19, ~m? -# 2311| r2311_21(int) = Convert : r2311_20 -# 2311| r2311_22(int) = Constant[0] : -# 2311| r2311_23(bool) = CompareNE : r2311_21, r2311_22 -# 2311| v2311_24(void) = ConditionalBranch : r2311_23 +# 2312| Block 7 +# 2312| r2312_19(glval) = VariableAddress[c] : +# 2312| r2312_20(char) = Load[c] : &:r2312_19, ~m? +# 2312| r2312_21(int) = Convert : r2312_20 +# 2312| r2312_22(int) = Constant[0] : +# 2312| r2312_23(bool) = CompareNE : r2312_21, r2312_22 +# 2312| v2312_24(void) = ConditionalBranch : r2312_23 #-----| False -> Block 9 #-----| True -> Block 8 -# 2312| Block 8 -# 2312| r2312_1(char) = Constant[0] : -# 2312| r2312_2(glval) = VariableAddress[c] : -# 2312| mu2312_3(char) = Store[c] : &:r2312_2, r2312_1 -# 2311| r2311_25(glval) = VariableAddress[s] : -# 2311| r2311_26(glval) = FunctionAddress[pop_back] : -# 2311| r2311_27(char) = Call[pop_back] : func:r2311_26, this:r2311_25 -# 2311| mu2311_28(unknown) = ^CallSideEffect : ~m? -# 2311| v2311_29(void) = ^IndirectReadSideEffect[-1] : &:r2311_25, ~m? -# 2311| mu2311_30(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_25 -# 2311| r2311_31(glval) = VariableAddress[c] : -# 2311| mu2311_32(char) = Store[c] : &:r2311_31, r2311_27 +# 2313| Block 8 +# 2313| r2313_1(char) = Constant[0] : +# 2313| r2313_2(glval) = VariableAddress[c] : +# 2313| mu2313_3(char) = Store[c] : &:r2313_2, r2313_1 +# 2312| r2312_25(glval) = VariableAddress[s] : +# 2312| r2312_26(glval) = FunctionAddress[pop_back] : +# 2312| r2312_27(char) = Call[pop_back] : func:r2312_26, this:r2312_25 +# 2312| mu2312_28(unknown) = ^CallSideEffect : ~m? +# 2312| v2312_29(void) = ^IndirectReadSideEffect[-1] : &:r2312_25, ~m? +# 2312| mu2312_30(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_25 +# 2312| r2312_31(glval) = VariableAddress[c] : +# 2312| mu2312_32(char) = Store[c] : &:r2312_31, r2312_27 #-----| Goto (back edge) -> Block 7 -# 2311| Block 9 -# 2311| r2311_33(glval) = VariableAddress[s2] : -# 2311| r2311_34(glval) = FunctionAddress[~String] : -# 2311| v2311_35(void) = Call[~String] : func:r2311_34, this:r2311_33 -# 2311| mu2311_36(unknown) = ^CallSideEffect : ~m? -# 2311| v2311_37(void) = ^IndirectReadSideEffect[-1] : &:r2311_33, ~m? -# 2311| mu2311_38(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_33 -# 2311| r2311_39(glval) = VariableAddress[s] : -# 2311| r2311_40(glval) = FunctionAddress[~String] : -# 2311| v2311_41(void) = Call[~String] : func:r2311_40, this:r2311_39 -# 2311| mu2311_42(unknown) = ^CallSideEffect : ~m? -# 2311| v2311_43(void) = ^IndirectReadSideEffect[-1] : &:r2311_39, ~m? -# 2311| mu2311_44(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_39 -# 2314| v2314_1(void) = NoOp : -# 2301| v2301_4(void) = ReturnVoid : -# 2301| v2301_5(void) = AliasedUse : ~m? -# 2301| v2301_6(void) = ExitFunction : - -# 2316| void IfDestructors2(bool) -# 2316| Block 0 -# 2316| v2316_1(void) = EnterFunction : -# 2316| mu2316_2(unknown) = AliasedDefinition : -# 2316| mu2316_3(unknown) = InitializeNonLocal : -# 2316| r2316_4(glval) = VariableAddress[b] : -# 2316| mu2316_5(bool) = InitializeParameter[b] : &:r2316_4 -# 2317| r2317_1(glval) = VariableAddress[s] : -# 2317| mu2317_2(String) = Uninitialized[s] : &:r2317_1 -# 2317| r2317_3(glval) = FunctionAddress[String] : -# 2317| r2317_4(glval) = StringConstant["hello"] : -# 2317| r2317_5(char *) = Convert : r2317_4 -# 2317| v2317_6(void) = Call[String] : func:r2317_3, this:r2317_1, 0:r2317_5 -# 2317| mu2317_7(unknown) = ^CallSideEffect : ~m? -# 2317| v2317_8(void) = ^BufferReadSideEffect[0] : &:r2317_5, ~m? -# 2317| mu2317_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2317_1 -# 2317| r2317_10(glval) = VariableAddress[b] : -# 2317| r2317_11(bool) = Load[b] : &:r2317_10, ~m? -# 2317| v2317_12(void) = ConditionalBranch : r2317_11 +# 2312| Block 9 +# 2312| r2312_33(glval) = VariableAddress[s2] : +# 2312| r2312_34(glval) = FunctionAddress[~String] : +# 2312| v2312_35(void) = Call[~String] : func:r2312_34, this:r2312_33 +# 2312| mu2312_36(unknown) = ^CallSideEffect : ~m? +# 2312| v2312_37(void) = ^IndirectReadSideEffect[-1] : &:r2312_33, ~m? +# 2312| mu2312_38(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_33 +# 2312| r2312_39(glval) = VariableAddress[s] : +# 2312| r2312_40(glval) = FunctionAddress[~String] : +# 2312| v2312_41(void) = Call[~String] : func:r2312_40, this:r2312_39 +# 2312| mu2312_42(unknown) = ^CallSideEffect : ~m? +# 2312| v2312_43(void) = ^IndirectReadSideEffect[-1] : &:r2312_39, ~m? +# 2312| mu2312_44(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_39 +# 2315| v2315_1(void) = NoOp : +# 2302| v2302_4(void) = ReturnVoid : +# 2302| v2302_5(void) = AliasedUse : ~m? +# 2302| v2302_6(void) = ExitFunction : + +# 2317| void IfDestructors2(bool) +# 2317| Block 0 +# 2317| v2317_1(void) = EnterFunction : +# 2317| mu2317_2(unknown) = AliasedDefinition : +# 2317| mu2317_3(unknown) = InitializeNonLocal : +# 2317| r2317_4(glval) = VariableAddress[b] : +# 2317| mu2317_5(bool) = InitializeParameter[b] : &:r2317_4 +# 2318| r2318_1(glval) = VariableAddress[s] : +# 2318| mu2318_2(String) = Uninitialized[s] : &:r2318_1 +# 2318| r2318_3(glval) = FunctionAddress[String] : +# 2318| r2318_4(glval) = StringConstant["hello"] : +# 2318| r2318_5(char *) = Convert : r2318_4 +# 2318| v2318_6(void) = Call[String] : func:r2318_3, this:r2318_1, 0:r2318_5 +# 2318| mu2318_7(unknown) = ^CallSideEffect : ~m? +# 2318| v2318_8(void) = ^BufferReadSideEffect[0] : &:r2318_5, ~m? +# 2318| mu2318_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2318_1 +# 2318| r2318_10(glval) = VariableAddress[b] : +# 2318| r2318_11(bool) = Load[b] : &:r2318_10, ~m? +# 2318| v2318_12(void) = ConditionalBranch : r2318_11 #-----| False -> Block 2 #-----| True -> Block 1 -# 2318| Block 1 -# 2318| r2318_1(glval) = VariableAddress[x] : -# 2318| r2318_2(int) = Constant[0] : -# 2318| mu2318_3(int) = Store[x] : &:r2318_1, r2318_2 +# 2319| Block 1 +# 2319| r2319_1(glval) = VariableAddress[x] : +# 2319| r2319_2(int) = Constant[0] : +# 2319| mu2319_3(int) = Store[x] : &:r2319_1, r2319_2 #-----| Goto -> Block 3 -# 2320| Block 2 -# 2320| r2320_1(glval) = VariableAddress[y] : -# 2320| r2320_2(int) = Constant[0] : -# 2320| mu2320_3(int) = Store[y] : &:r2320_1, r2320_2 +# 2321| Block 2 +# 2321| r2321_1(glval) = VariableAddress[y] : +# 2321| r2321_2(int) = Constant[0] : +# 2321| mu2321_3(int) = Store[y] : &:r2321_1, r2321_2 #-----| Goto -> Block 3 -# 2321| Block 3 -# 2321| r2321_1(glval) = VariableAddress[s] : -# 2321| r2321_2(glval) = FunctionAddress[~String] : -# 2321| v2321_3(void) = Call[~String] : func:r2321_2, this:r2321_1 -# 2321| mu2321_4(unknown) = ^CallSideEffect : ~m? -# 2321| v2321_5(void) = ^IndirectReadSideEffect[-1] : &:r2321_1, ~m? -# 2321| mu2321_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2321_1 -# 2322| v2322_1(void) = NoOp : -# 2316| v2316_6(void) = ReturnVoid : -# 2316| v2316_7(void) = AliasedUse : ~m? -# 2316| v2316_8(void) = ExitFunction : - -# 2331| void IfDestructors3(bool) -# 2331| Block 0 -# 2331| v2331_1(void) = EnterFunction : -# 2331| mu2331_2(unknown) = AliasedDefinition : -# 2331| mu2331_3(unknown) = InitializeNonLocal : -# 2331| r2331_4(glval) = VariableAddress[b] : -# 2331| mu2331_5(bool) = InitializeParameter[b] : &:r2331_4 -# 2332| r2332_1(glval) = VariableAddress[B] : -# 2332| mu2332_2(Bool) = Uninitialized[B] : &:r2332_1 -# 2332| r2332_3(glval) = FunctionAddress[Bool] : +# 2322| Block 3 +# 2322| r2322_1(glval) = VariableAddress[s] : +# 2322| r2322_2(glval) = FunctionAddress[~String] : +# 2322| v2322_3(void) = Call[~String] : func:r2322_2, this:r2322_1 +# 2322| mu2322_4(unknown) = ^CallSideEffect : ~m? +# 2322| v2322_5(void) = ^IndirectReadSideEffect[-1] : &:r2322_1, ~m? +# 2322| mu2322_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2322_1 +# 2323| v2323_1(void) = NoOp : +# 2317| v2317_6(void) = ReturnVoid : +# 2317| v2317_7(void) = AliasedUse : ~m? +# 2317| v2317_8(void) = ExitFunction : + +# 2332| void IfDestructors3(bool) +# 2332| Block 0 +# 2332| v2332_1(void) = EnterFunction : +# 2332| mu2332_2(unknown) = AliasedDefinition : +# 2332| mu2332_3(unknown) = InitializeNonLocal : # 2332| r2332_4(glval) = VariableAddress[b] : -# 2332| r2332_5(bool) = Load[b] : &:r2332_4, ~m? -# 2332| v2332_6(void) = Call[Bool] : func:r2332_3, this:r2332_1, 0:r2332_5 -# 2332| mu2332_7(unknown) = ^CallSideEffect : ~m? -# 2332| mu2332_8(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2332_1 -# 2332| r2332_9(glval) = VariableAddress[B] : -# 2332| r2332_10(glval) = FunctionAddress[operator bool] : -# 2332| r2332_11(bool) = Call[operator bool] : func:r2332_10, this:r2332_9 -# 2332| mu2332_12(unknown) = ^CallSideEffect : ~m? -# 2332| v2332_13(void) = ^IndirectReadSideEffect[-1] : &:r2332_9, ~m? -# 2332| mu2332_14(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2332_9 -# 2332| r2332_15(bool) = CopyValue : r2332_11 -# 2332| v2332_16(void) = ConditionalBranch : r2332_15 +# 2332| mu2332_5(bool) = InitializeParameter[b] : &:r2332_4 +# 2333| r2333_1(glval) = VariableAddress[B] : +# 2333| mu2333_2(Bool) = Uninitialized[B] : &:r2333_1 +# 2333| r2333_3(glval) = FunctionAddress[Bool] : +# 2333| r2333_4(glval) = VariableAddress[b] : +# 2333| r2333_5(bool) = Load[b] : &:r2333_4, ~m? +# 2333| v2333_6(void) = Call[Bool] : func:r2333_3, this:r2333_1, 0:r2333_5 +# 2333| mu2333_7(unknown) = ^CallSideEffect : ~m? +# 2333| mu2333_8(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2333_1 +# 2333| r2333_9(glval) = VariableAddress[B] : +# 2333| r2333_10(glval) = FunctionAddress[operator bool] : +# 2333| r2333_11(bool) = Call[operator bool] : func:r2333_10, this:r2333_9 +# 2333| mu2333_12(unknown) = ^CallSideEffect : ~m? +# 2333| v2333_13(void) = ^IndirectReadSideEffect[-1] : &:r2333_9, ~m? +# 2333| mu2333_14(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2333_9 +# 2333| r2333_15(bool) = CopyValue : r2333_11 +# 2333| v2333_16(void) = ConditionalBranch : r2333_15 #-----| False -> Block 2 #-----| True -> Block 1 -# 2333| Block 1 -# 2333| r2333_1(glval) = VariableAddress[s1] : -# 2333| mu2333_2(String) = Uninitialized[s1] : &:r2333_1 -# 2333| r2333_3(glval) = FunctionAddress[String] : -# 2333| v2333_4(void) = Call[String] : func:r2333_3, this:r2333_1 -# 2333| mu2333_5(unknown) = ^CallSideEffect : ~m? -# 2333| mu2333_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2333_1 +# 2334| Block 1 # 2334| r2334_1(glval) = VariableAddress[s1] : -# 2334| r2334_2(glval) = FunctionAddress[~String] : -# 2334| v2334_3(void) = Call[~String] : func:r2334_2, this:r2334_1 -# 2334| mu2334_4(unknown) = ^CallSideEffect : ~m? -# 2334| v2334_5(void) = ^IndirectReadSideEffect[-1] : &:r2334_1, ~m? +# 2334| mu2334_2(String) = Uninitialized[s1] : &:r2334_1 +# 2334| r2334_3(glval) = FunctionAddress[String] : +# 2334| v2334_4(void) = Call[String] : func:r2334_3, this:r2334_1 +# 2334| mu2334_5(unknown) = ^CallSideEffect : ~m? # 2334| mu2334_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2334_1 +# 2335| r2335_1(glval) = VariableAddress[s1] : +# 2335| r2335_2(glval) = FunctionAddress[~String] : +# 2335| v2335_3(void) = Call[~String] : func:r2335_2, this:r2335_1 +# 2335| mu2335_4(unknown) = ^CallSideEffect : ~m? +# 2335| v2335_5(void) = ^IndirectReadSideEffect[-1] : &:r2335_1, ~m? +# 2335| mu2335_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2335_1 #-----| Goto -> Block 3 -# 2335| Block 2 -# 2335| r2335_1(glval) = VariableAddress[s2] : -# 2335| mu2335_2(String) = Uninitialized[s2] : &:r2335_1 -# 2335| r2335_3(glval) = FunctionAddress[String] : -# 2335| v2335_4(void) = Call[String] : func:r2335_3, this:r2335_1 -# 2335| mu2335_5(unknown) = ^CallSideEffect : ~m? -# 2335| mu2335_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2335_1 +# 2336| Block 2 # 2336| r2336_1(glval) = VariableAddress[s2] : -# 2336| r2336_2(glval) = FunctionAddress[~String] : -# 2336| v2336_3(void) = Call[~String] : func:r2336_2, this:r2336_1 -# 2336| mu2336_4(unknown) = ^CallSideEffect : ~m? -# 2336| v2336_5(void) = ^IndirectReadSideEffect[-1] : &:r2336_1, ~m? +# 2336| mu2336_2(String) = Uninitialized[s2] : &:r2336_1 +# 2336| r2336_3(glval) = FunctionAddress[String] : +# 2336| v2336_4(void) = Call[String] : func:r2336_3, this:r2336_1 +# 2336| mu2336_5(unknown) = ^CallSideEffect : ~m? # 2336| mu2336_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2336_1 +# 2337| r2337_1(glval) = VariableAddress[s2] : +# 2337| r2337_2(glval) = FunctionAddress[~String] : +# 2337| v2337_3(void) = Call[~String] : func:r2337_2, this:r2337_1 +# 2337| mu2337_4(unknown) = ^CallSideEffect : ~m? +# 2337| v2337_5(void) = ^IndirectReadSideEffect[-1] : &:r2337_1, ~m? +# 2337| mu2337_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2337_1 #-----| Goto -> Block 3 -# 2336| Block 3 -# 2336| r2336_7(glval) = VariableAddress[B] : -# 2336| r2336_8(glval) = FunctionAddress[~Bool] : -# 2336| v2336_9(void) = Call[~Bool] : func:r2336_8, this:r2336_7 -# 2336| mu2336_10(unknown) = ^CallSideEffect : ~m? -# 2336| v2336_11(void) = ^IndirectReadSideEffect[-1] : &:r2336_7, ~m? -# 2336| mu2336_12(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2336_7 -# 2337| v2337_1(void) = NoOp : -# 2331| v2331_6(void) = ReturnVoid : -# 2331| v2331_7(void) = AliasedUse : ~m? -# 2331| v2331_8(void) = ExitFunction : - -# 2339| void WhileLoopDestructors(bool) -# 2339| Block 0 -# 2339| v2339_1(void) = EnterFunction : -# 2339| mu2339_2(unknown) = AliasedDefinition : -# 2339| mu2339_3(unknown) = InitializeNonLocal : -# 2339| r2339_4(glval) = VariableAddress[b] : -# 2339| mu2339_5(bool) = InitializeParameter[b] : &:r2339_4 -# 2341| r2341_1(glval) = VariableAddress[s] : -# 2341| mu2341_2(String) = Uninitialized[s] : &:r2341_1 -# 2341| r2341_3(glval) = FunctionAddress[String] : -# 2341| v2341_4(void) = Call[String] : func:r2341_3, this:r2341_1 -# 2341| mu2341_5(unknown) = ^CallSideEffect : ~m? -# 2341| mu2341_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2341_1 +# 2337| Block 3 +# 2337| r2337_7(glval) = VariableAddress[B] : +# 2337| r2337_8(glval) = FunctionAddress[~Bool] : +# 2337| v2337_9(void) = Call[~Bool] : func:r2337_8, this:r2337_7 +# 2337| mu2337_10(unknown) = ^CallSideEffect : ~m? +# 2337| v2337_11(void) = ^IndirectReadSideEffect[-1] : &:r2337_7, ~m? +# 2337| mu2337_12(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2337_7 +# 2338| v2338_1(void) = NoOp : +# 2332| v2332_6(void) = ReturnVoid : +# 2332| v2332_7(void) = AliasedUse : ~m? +# 2332| v2332_8(void) = ExitFunction : + +# 2340| void WhileLoopDestructors(bool) +# 2340| Block 0 +# 2340| v2340_1(void) = EnterFunction : +# 2340| mu2340_2(unknown) = AliasedDefinition : +# 2340| mu2340_3(unknown) = InitializeNonLocal : +# 2340| r2340_4(glval) = VariableAddress[b] : +# 2340| mu2340_5(bool) = InitializeParameter[b] : &:r2340_4 +# 2342| r2342_1(glval) = VariableAddress[s] : +# 2342| mu2342_2(String) = Uninitialized[s] : &:r2342_1 +# 2342| r2342_3(glval) = FunctionAddress[String] : +# 2342| v2342_4(void) = Call[String] : func:r2342_3, this:r2342_1 +# 2342| mu2342_5(unknown) = ^CallSideEffect : ~m? +# 2342| mu2342_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2342_1 #-----| Goto -> Block 1 -# 2342| Block 1 -# 2342| r2342_1(glval) = VariableAddress[b] : -# 2342| r2342_2(bool) = Load[b] : &:r2342_1, ~m? -# 2342| v2342_3(void) = ConditionalBranch : r2342_2 +# 2343| Block 1 +# 2343| r2343_1(glval) = VariableAddress[b] : +# 2343| r2343_2(bool) = Load[b] : &:r2343_1, ~m? +# 2343| v2343_3(void) = ConditionalBranch : r2343_2 #-----| False -> Block 3 #-----| True -> Block 2 -# 2343| Block 2 -# 2343| r2343_1(bool) = Constant[0] : -# 2343| r2343_2(glval) = VariableAddress[b] : -# 2343| mu2343_3(bool) = Store[b] : &:r2343_2, r2343_1 +# 2344| Block 2 +# 2344| r2344_1(bool) = Constant[0] : +# 2344| r2344_2(glval) = VariableAddress[b] : +# 2344| mu2344_3(bool) = Store[b] : &:r2344_2, r2344_1 #-----| Goto (back edge) -> Block 1 -# 2345| Block 3 -# 2345| r2345_1(glval) = VariableAddress[s] : -# 2345| r2345_2(glval) = FunctionAddress[~String] : -# 2345| v2345_3(void) = Call[~String] : func:r2345_2, this:r2345_1 -# 2345| mu2345_4(unknown) = ^CallSideEffect : ~m? -# 2345| v2345_5(void) = ^IndirectReadSideEffect[-1] : &:r2345_1, ~m? -# 2345| mu2345_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2345_1 +# 2346| Block 3 +# 2346| r2346_1(glval) = VariableAddress[s] : +# 2346| r2346_2(glval) = FunctionAddress[~String] : +# 2346| v2346_3(void) = Call[~String] : func:r2346_2, this:r2346_1 +# 2346| mu2346_4(unknown) = ^CallSideEffect : ~m? +# 2346| v2346_5(void) = ^IndirectReadSideEffect[-1] : &:r2346_1, ~m? +# 2346| mu2346_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2346_1 #-----| Goto -> Block 4 -# 2348| Block 4 -# 2348| r2348_1(glval) = VariableAddress[B] : -# 2348| mu2348_2(Bool) = Uninitialized[B] : &:r2348_1 -# 2348| r2348_3(glval) = FunctionAddress[Bool] : -# 2348| r2348_4(glval) = VariableAddress[b] : -# 2348| r2348_5(bool) = Load[b] : &:r2348_4, ~m? -# 2348| v2348_6(void) = Call[Bool] : func:r2348_3, this:r2348_1, 0:r2348_5 -# 2348| mu2348_7(unknown) = ^CallSideEffect : ~m? -# 2348| mu2348_8(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2348_1 -# 2348| r2348_9(glval) = VariableAddress[B] : -# 2348| r2348_10(glval) = FunctionAddress[operator bool] : -# 2348| r2348_11(bool) = Call[operator bool] : func:r2348_10, this:r2348_9 -# 2348| mu2348_12(unknown) = ^CallSideEffect : ~m? -# 2348| v2348_13(void) = ^IndirectReadSideEffect[-1] : &:r2348_9, ~m? -# 2348| mu2348_14(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2348_9 -# 2348| r2348_15(bool) = CopyValue : r2348_11 -# 2348| v2348_16(void) = ConditionalBranch : r2348_15 +# 2349| Block 4 +# 2349| r2349_1(glval) = VariableAddress[B] : +# 2349| mu2349_2(Bool) = Uninitialized[B] : &:r2349_1 +# 2349| r2349_3(glval) = FunctionAddress[Bool] : +# 2349| r2349_4(glval) = VariableAddress[b] : +# 2349| r2349_5(bool) = Load[b] : &:r2349_4, ~m? +# 2349| v2349_6(void) = Call[Bool] : func:r2349_3, this:r2349_1, 0:r2349_5 +# 2349| mu2349_7(unknown) = ^CallSideEffect : ~m? +# 2349| mu2349_8(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2349_1 +# 2349| r2349_9(glval) = VariableAddress[B] : +# 2349| r2349_10(glval) = FunctionAddress[operator bool] : +# 2349| r2349_11(bool) = Call[operator bool] : func:r2349_10, this:r2349_9 +# 2349| mu2349_12(unknown) = ^CallSideEffect : ~m? +# 2349| v2349_13(void) = ^IndirectReadSideEffect[-1] : &:r2349_9, ~m? +# 2349| mu2349_14(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2349_9 +# 2349| r2349_15(bool) = CopyValue : r2349_11 +# 2349| v2349_16(void) = ConditionalBranch : r2349_15 #-----| False -> Block 6 #-----| True -> Block 5 -# 2349| Block 5 -# 2349| r2349_1(bool) = Constant[0] : -# 2349| r2349_2(glval) = VariableAddress[b] : -# 2349| mu2349_3(bool) = Store[b] : &:r2349_2, r2349_1 -# 2350| r2350_1(glval) = VariableAddress[B] : -# 2350| r2350_2(glval) = FunctionAddress[~Bool] : -# 2350| v2350_3(void) = Call[~Bool] : func:r2350_2, this:r2350_1 -# 2350| mu2350_4(unknown) = ^CallSideEffect : ~m? -# 2350| v2350_5(void) = ^IndirectReadSideEffect[-1] : &:r2350_1, ~m? -# 2350| mu2350_6(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2350_1 +# 2350| Block 5 +# 2350| r2350_1(bool) = Constant[0] : +# 2350| r2350_2(glval) = VariableAddress[b] : +# 2350| mu2350_3(bool) = Store[b] : &:r2350_2, r2350_1 +# 2351| r2351_1(glval) = VariableAddress[B] : +# 2351| r2351_2(glval) = FunctionAddress[~Bool] : +# 2351| v2351_3(void) = Call[~Bool] : func:r2351_2, this:r2351_1 +# 2351| mu2351_4(unknown) = ^CallSideEffect : ~m? +# 2351| v2351_5(void) = ^IndirectReadSideEffect[-1] : &:r2351_1, ~m? +# 2351| mu2351_6(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2351_1 #-----| Goto (back edge) -> Block 4 -# 2350| Block 6 -# 2350| r2350_7(glval) = VariableAddress[B] : -# 2350| r2350_8(glval) = FunctionAddress[~Bool] : -# 2350| v2350_9(void) = Call[~Bool] : func:r2350_8, this:r2350_7 -# 2350| mu2350_10(unknown) = ^CallSideEffect : ~m? -# 2350| v2350_11(void) = ^IndirectReadSideEffect[-1] : &:r2350_7, ~m? -# 2350| mu2350_12(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2350_7 -# 2352| v2352_1(void) = NoOp : -# 2339| v2339_6(void) = ReturnVoid : -# 2339| v2339_7(void) = AliasedUse : ~m? -# 2339| v2339_8(void) = ExitFunction : - -# 2354| void VoidFunc() -# 2354| Block 0 -# 2354| v2354_1(void) = EnterFunction : -# 2354| mu2354_2(unknown) = AliasedDefinition : -# 2354| mu2354_3(unknown) = InitializeNonLocal : -# 2354| v2354_4(void) = NoOp : -# 2354| v2354_5(void) = ReturnVoid : -# 2354| v2354_6(void) = AliasedUse : ~m? -# 2354| v2354_7(void) = ExitFunction : - -# 2356| void IfReturnDestructors(bool) -# 2356| Block 0 -# 2356| v2356_1(void) = EnterFunction : -# 2356| mu2356_2(unknown) = AliasedDefinition : -# 2356| mu2356_3(unknown) = InitializeNonLocal : -# 2356| r2356_4(glval) = VariableAddress[b] : -# 2356| mu2356_5(bool) = InitializeParameter[b] : &:r2356_4 -# 2357| r2357_1(glval) = VariableAddress[s] : -# 2357| mu2357_2(String) = Uninitialized[s] : &:r2357_1 -# 2357| r2357_3(glval) = FunctionAddress[String] : -# 2357| v2357_4(void) = Call[String] : func:r2357_3, this:r2357_1 -# 2357| mu2357_5(unknown) = ^CallSideEffect : ~m? -# 2357| mu2357_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2357_1 -# 2358| r2358_1(glval) = VariableAddress[b] : -# 2358| r2358_2(bool) = Load[b] : &:r2358_1, ~m? -# 2358| v2358_3(void) = ConditionalBranch : r2358_2 +# 2351| Block 6 +# 2351| r2351_7(glval) = VariableAddress[B] : +# 2351| r2351_8(glval) = FunctionAddress[~Bool] : +# 2351| v2351_9(void) = Call[~Bool] : func:r2351_8, this:r2351_7 +# 2351| mu2351_10(unknown) = ^CallSideEffect : ~m? +# 2351| v2351_11(void) = ^IndirectReadSideEffect[-1] : &:r2351_7, ~m? +# 2351| mu2351_12(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2351_7 +# 2353| v2353_1(void) = NoOp : +# 2340| v2340_6(void) = ReturnVoid : +# 2340| v2340_7(void) = AliasedUse : ~m? +# 2340| v2340_8(void) = ExitFunction : + +# 2355| void VoidFunc() +# 2355| Block 0 +# 2355| v2355_1(void) = EnterFunction : +# 2355| mu2355_2(unknown) = AliasedDefinition : +# 2355| mu2355_3(unknown) = InitializeNonLocal : +# 2355| v2355_4(void) = NoOp : +# 2355| v2355_5(void) = ReturnVoid : +# 2355| v2355_6(void) = AliasedUse : ~m? +# 2355| v2355_7(void) = ExitFunction : + +# 2357| void IfReturnDestructors(bool) +# 2357| Block 0 +# 2357| v2357_1(void) = EnterFunction : +# 2357| mu2357_2(unknown) = AliasedDefinition : +# 2357| mu2357_3(unknown) = InitializeNonLocal : +# 2357| r2357_4(glval) = VariableAddress[b] : +# 2357| mu2357_5(bool) = InitializeParameter[b] : &:r2357_4 +# 2358| r2358_1(glval) = VariableAddress[s] : +# 2358| mu2358_2(String) = Uninitialized[s] : &:r2358_1 +# 2358| r2358_3(glval) = FunctionAddress[String] : +# 2358| v2358_4(void) = Call[String] : func:r2358_3, this:r2358_1 +# 2358| mu2358_5(unknown) = ^CallSideEffect : ~m? +# 2358| mu2358_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2358_1 +# 2359| r2359_1(glval) = VariableAddress[b] : +# 2359| r2359_2(bool) = Load[b] : &:r2359_1, ~m? +# 2359| v2359_3(void) = ConditionalBranch : r2359_2 #-----| False -> Block 3 #-----| True -> Block 2 -# 2356| Block 1 -# 2356| v2356_6(void) = ReturnVoid : -# 2356| v2356_7(void) = AliasedUse : ~m? -# 2356| v2356_8(void) = ExitFunction : - -# 2359| Block 2 -# 2359| v2359_1(void) = NoOp : -# 2365| r2365_1(glval) = VariableAddress[s] : -# 2365| r2365_2(glval) = FunctionAddress[~String] : -# 2365| v2365_3(void) = Call[~String] : func:r2365_2, this:r2365_1 -# 2365| mu2365_4(unknown) = ^CallSideEffect : ~m? -# 2365| v2365_5(void) = ^IndirectReadSideEffect[-1] : &:r2365_1, ~m? -# 2365| mu2365_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2365_1 +# 2357| Block 1 +# 2357| v2357_6(void) = ReturnVoid : +# 2357| v2357_7(void) = AliasedUse : ~m? +# 2357| v2357_8(void) = ExitFunction : + +# 2360| Block 2 +# 2360| v2360_1(void) = NoOp : +# 2366| r2366_1(glval) = VariableAddress[s] : +# 2366| r2366_2(glval) = FunctionAddress[~String] : +# 2366| v2366_3(void) = Call[~String] : func:r2366_2, this:r2366_1 +# 2366| mu2366_4(unknown) = ^CallSideEffect : ~m? +# 2366| v2366_5(void) = ^IndirectReadSideEffect[-1] : &:r2366_1, ~m? +# 2366| mu2366_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2366_1 #-----| Goto -> Block 1 -# 2361| Block 3 -# 2361| r2361_1(glval) = VariableAddress[b] : -# 2361| r2361_2(bool) = Load[b] : &:r2361_1, ~m? -# 2361| v2361_3(void) = ConditionalBranch : r2361_2 +# 2362| Block 3 +# 2362| r2362_1(glval) = VariableAddress[b] : +# 2362| r2362_2(bool) = Load[b] : &:r2362_1, ~m? +# 2362| v2362_3(void) = ConditionalBranch : r2362_2 #-----| False -> Block 5 #-----| True -> Block 4 -# 2362| Block 4 -# 2362| r2362_1(glval) = FunctionAddress[VoidFunc] : -# 2362| v2362_2(void) = Call[VoidFunc] : func:r2362_1 -# 2362| mu2362_3(unknown) = ^CallSideEffect : ~m? -# 2362| v2362_4(void) = NoOp : -# 2365| r2365_7(glval) = VariableAddress[s] : -# 2365| r2365_8(glval) = FunctionAddress[~String] : -# 2365| v2365_9(void) = Call[~String] : func:r2365_8, this:r2365_7 -# 2365| mu2365_10(unknown) = ^CallSideEffect : ~m? -# 2365| v2365_11(void) = ^IndirectReadSideEffect[-1] : &:r2365_7, ~m? -# 2365| mu2365_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2365_7 +# 2363| Block 4 +# 2363| r2363_1(glval) = FunctionAddress[VoidFunc] : +# 2363| v2363_2(void) = Call[VoidFunc] : func:r2363_1 +# 2363| mu2363_3(unknown) = ^CallSideEffect : ~m? +# 2363| v2363_4(void) = NoOp : +# 2366| r2366_7(glval) = VariableAddress[s] : +# 2366| r2366_8(glval) = FunctionAddress[~String] : +# 2366| v2366_9(void) = Call[~String] : func:r2366_8, this:r2366_7 +# 2366| mu2366_10(unknown) = ^CallSideEffect : ~m? +# 2366| v2366_11(void) = ^IndirectReadSideEffect[-1] : &:r2366_7, ~m? +# 2366| mu2366_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2366_7 #-----| Goto -> Block 1 -# 2364| Block 5 -# 2364| r2364_1(glval) = VariableAddress[s] : -# 2365| v2365_13(void) = NoOp : -# 2365| r2365_14(glval) = VariableAddress[s] : -# 2365| r2365_15(glval) = FunctionAddress[~String] : -# 2365| v2365_16(void) = Call[~String] : func:r2365_15, this:r2365_14 -# 2365| mu2365_17(unknown) = ^CallSideEffect : ~m? -# 2365| v2365_18(void) = ^IndirectReadSideEffect[-1] : &:r2365_14, ~m? -# 2365| mu2365_19(String) = ^IndirectMayWriteSideEffect[-1] : &:r2365_14 +# 2365| Block 5 +# 2365| r2365_1(glval) = VariableAddress[s] : +# 2366| v2366_13(void) = NoOp : +# 2366| r2366_14(glval) = VariableAddress[s] : +# 2366| r2366_15(glval) = FunctionAddress[~String] : +# 2366| v2366_16(void) = Call[~String] : func:r2366_15, this:r2366_14 +# 2366| mu2366_17(unknown) = ^CallSideEffect : ~m? +# 2366| v2366_18(void) = ^IndirectReadSideEffect[-1] : &:r2366_14, ~m? +# 2366| mu2366_19(String) = ^IndirectMayWriteSideEffect[-1] : &:r2366_14 #-----| Goto -> Block 1 -# 2367| int IfReturnDestructors3(bool) -# 2367| Block 0 -# 2367| v2367_1(void) = EnterFunction : -# 2367| mu2367_2(unknown) = AliasedDefinition : -# 2367| mu2367_3(unknown) = InitializeNonLocal : -# 2367| r2367_4(glval) = VariableAddress[b] : -# 2367| mu2367_5(bool) = InitializeParameter[b] : &:r2367_4 -# 2368| r2368_1(glval) = VariableAddress[s] : -# 2368| mu2368_2(String) = Uninitialized[s] : &:r2368_1 -# 2368| r2368_3(glval) = FunctionAddress[String] : -# 2368| v2368_4(void) = Call[String] : func:r2368_3, this:r2368_1 -# 2368| mu2368_5(unknown) = ^CallSideEffect : ~m? -# 2368| mu2368_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2368_1 -# 2369| r2369_1(glval) = VariableAddress[b] : -# 2369| r2369_2(bool) = Load[b] : &:r2369_1, ~m? -# 2369| v2369_3(void) = ConditionalBranch : r2369_2 +# 2368| int IfReturnDestructors3(bool) +# 2368| Block 0 +# 2368| v2368_1(void) = EnterFunction : +# 2368| mu2368_2(unknown) = AliasedDefinition : +# 2368| mu2368_3(unknown) = InitializeNonLocal : +# 2368| r2368_4(glval) = VariableAddress[b] : +# 2368| mu2368_5(bool) = InitializeParameter[b] : &:r2368_4 +# 2369| r2369_1(glval) = VariableAddress[s] : +# 2369| mu2369_2(String) = Uninitialized[s] : &:r2369_1 +# 2369| r2369_3(glval) = FunctionAddress[String] : +# 2369| v2369_4(void) = Call[String] : func:r2369_3, this:r2369_1 +# 2369| mu2369_5(unknown) = ^CallSideEffect : ~m? +# 2369| mu2369_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2369_1 +# 2370| r2370_1(glval) = VariableAddress[b] : +# 2370| r2370_2(bool) = Load[b] : &:r2370_1, ~m? +# 2370| v2370_3(void) = ConditionalBranch : r2370_2 #-----| False -> Block 3 #-----| True -> Block 2 -# 2367| Block 1 -# 2367| r2367_6(glval) = VariableAddress[#return] : -# 2367| v2367_7(void) = ReturnValue : &:r2367_6, ~m? -# 2367| v2367_8(void) = AliasedUse : ~m? -# 2367| v2367_9(void) = ExitFunction : - -# 2370| Block 2 -# 2370| r2370_1(glval) = VariableAddress[#return] : -# 2370| r2370_2(int) = Constant[1] : -# 2370| mu2370_3(int) = Store[#return] : &:r2370_1, r2370_2 -# 2373| r2373_1(glval) = VariableAddress[s] : -# 2373| r2373_2(glval) = FunctionAddress[~String] : -# 2373| v2373_3(void) = Call[~String] : func:r2373_2, this:r2373_1 -# 2373| mu2373_4(unknown) = ^CallSideEffect : ~m? -# 2373| v2373_5(void) = ^IndirectReadSideEffect[-1] : &:r2373_1, ~m? -# 2373| mu2373_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2373_1 +# 2368| Block 1 +# 2368| r2368_6(glval) = VariableAddress[#return] : +# 2368| v2368_7(void) = ReturnValue : &:r2368_6, ~m? +# 2368| v2368_8(void) = AliasedUse : ~m? +# 2368| v2368_9(void) = ExitFunction : + +# 2371| Block 2 +# 2371| r2371_1(glval) = VariableAddress[#return] : +# 2371| r2371_2(int) = Constant[1] : +# 2371| mu2371_3(int) = Store[#return] : &:r2371_1, r2371_2 +# 2374| r2374_1(glval) = VariableAddress[s] : +# 2374| r2374_2(glval) = FunctionAddress[~String] : +# 2374| v2374_3(void) = Call[~String] : func:r2374_2, this:r2374_1 +# 2374| mu2374_4(unknown) = ^CallSideEffect : ~m? +# 2374| v2374_5(void) = ^IndirectReadSideEffect[-1] : &:r2374_1, ~m? +# 2374| mu2374_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2374_1 #-----| Goto -> Block 1 -# 2372| Block 3 -# 2372| r2372_1(glval) = VariableAddress[#return] : -# 2372| r2372_2(int) = Constant[0] : -# 2372| mu2372_3(int) = Store[#return] : &:r2372_1, r2372_2 -# 2373| r2373_7(glval) = VariableAddress[s] : -# 2373| r2373_8(glval) = FunctionAddress[~String] : -# 2373| v2373_9(void) = Call[~String] : func:r2373_8, this:r2373_7 -# 2373| mu2373_10(unknown) = ^CallSideEffect : ~m? -# 2373| v2373_11(void) = ^IndirectReadSideEffect[-1] : &:r2373_7, ~m? -# 2373| mu2373_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2373_7 +# 2373| Block 3 +# 2373| r2373_1(glval) = VariableAddress[#return] : +# 2373| r2373_2(int) = Constant[0] : +# 2373| mu2373_3(int) = Store[#return] : &:r2373_1, r2373_2 +# 2374| r2374_7(glval) = VariableAddress[s] : +# 2374| r2374_8(glval) = FunctionAddress[~String] : +# 2374| v2374_9(void) = Call[~String] : func:r2374_8, this:r2374_7 +# 2374| mu2374_10(unknown) = ^CallSideEffect : ~m? +# 2374| v2374_11(void) = ^IndirectReadSideEffect[-1] : &:r2374_7, ~m? +# 2374| mu2374_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2374_7 #-----| Goto -> Block 1 -# 2375| void VoidReturnDestructors() -# 2375| Block 0 -# 2375| v2375_1(void) = EnterFunction : -# 2375| mu2375_2(unknown) = AliasedDefinition : -# 2375| mu2375_3(unknown) = InitializeNonLocal : -# 2376| r2376_1(glval) = VariableAddress[s] : -# 2376| mu2376_2(String) = Uninitialized[s] : &:r2376_1 -# 2376| r2376_3(glval) = FunctionAddress[String] : -# 2376| v2376_4(void) = Call[String] : func:r2376_3, this:r2376_1 -# 2376| mu2376_5(unknown) = ^CallSideEffect : ~m? -# 2376| mu2376_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2376_1 -# 2377| r2377_1(glval) = FunctionAddress[VoidFunc] : -# 2377| v2377_2(void) = Call[VoidFunc] : func:r2377_1 -# 2377| mu2377_3(unknown) = ^CallSideEffect : ~m? -# 2377| v2377_4(void) = NoOp : -# 2378| r2378_1(glval) = VariableAddress[s] : -# 2378| r2378_2(glval) = FunctionAddress[~String] : -# 2378| v2378_3(void) = Call[~String] : func:r2378_2, this:r2378_1 -# 2378| mu2378_4(unknown) = ^CallSideEffect : ~m? -# 2378| v2378_5(void) = ^IndirectReadSideEffect[-1] : &:r2378_1, ~m? -# 2378| mu2378_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2378_1 -# 2375| v2375_4(void) = ReturnVoid : -# 2375| v2375_5(void) = AliasedUse : ~m? -# 2375| v2375_6(void) = ExitFunction : - -# 2388| return_routine_type::VoidToIntMemberFunc return_routine_type::GetVoidToIntFunc() -# 2388| Block 0 -# 2388| v2388_1(void) = EnterFunction : -# 2388| mu2388_2(unknown) = AliasedDefinition : -# 2388| mu2388_3(unknown) = InitializeNonLocal : -# 2390| r2390_1(glval<..:: *>) = VariableAddress[#return] : -# 2390| r2390_2(..()(..)) = FunctionAddress[VoidToInt] : -# 2390| mu2390_3(..:: *) = Store[#return] : &:r2390_1, r2390_2 -# 2388| r2388_4(glval<..:: *>) = VariableAddress[#return] : -# 2388| v2388_5(void) = ReturnValue : &:r2388_4, ~m? -# 2388| v2388_6(void) = AliasedUse : ~m? -# 2388| v2388_7(void) = ExitFunction : - -# 2395| int small_operation_should_not_be_constant_folded() -# 2395| Block 0 -# 2395| v2395_1(void) = EnterFunction : -# 2395| mu2395_2(unknown) = AliasedDefinition : -# 2395| mu2395_3(unknown) = InitializeNonLocal : -# 2396| r2396_1(glval) = VariableAddress[#return] : -# 2396| r2396_2(int) = Constant[1] : -# 2396| r2396_3(int) = Constant[2] : -# 2396| r2396_4(int) = BitXor : r2396_2, r2396_3 -# 2396| mu2396_5(int) = Store[#return] : &:r2396_1, r2396_4 -# 2395| r2395_4(glval) = VariableAddress[#return] : -# 2395| v2395_5(void) = ReturnValue : &:r2395_4, ~m? -# 2395| v2395_6(void) = AliasedUse : ~m? -# 2395| v2395_7(void) = ExitFunction : - -# 2406| int large_operation_should_be_constant_folded() -# 2406| Block 0 -# 2406| v2406_1(void) = EnterFunction : -# 2406| mu2406_2(unknown) = AliasedDefinition : -# 2406| mu2406_3(unknown) = InitializeNonLocal : -# 2407| r2407_1(glval) = VariableAddress[#return] : -# 2407| r2407_2(int) = Constant[0] : -# 2407| mu2407_3(int) = Store[#return] : &:r2407_1, r2407_2 -# 2406| r2406_4(glval) = VariableAddress[#return] : -# 2406| v2406_5(void) = ReturnValue : &:r2406_4, ~m? -# 2406| v2406_6(void) = AliasedUse : ~m? -# 2406| v2406_7(void) = ExitFunction : - -# 2410| void initialization_with_temp_destructor() -# 2410| Block 0 -# 2410| v2410_1(void) = EnterFunction : -# 2410| mu2410_2(unknown) = AliasedDefinition : -# 2410| mu2410_3(unknown) = InitializeNonLocal : -# 2411| r2411_1(glval) = VariableAddress[x] : -# 2411| r2411_2(glval) = VariableAddress[#temp2411:18] : -# 2411| mu2411_3(ClassWithDestructor) = Uninitialized[#temp2411:18] : &:r2411_2 -# 2411| r2411_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2411| v2411_5(void) = Call[ClassWithDestructor] : func:r2411_4, this:r2411_2 -# 2411| mu2411_6(unknown) = ^CallSideEffect : ~m? -# 2411| mu2411_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2411_2 -# 2411| r2411_8(glval) = FunctionAddress[get_x] : -# 2411| r2411_9(char) = Call[get_x] : func:r2411_8, this:r2411_2 -# 2411| mu2411_10(unknown) = ^CallSideEffect : ~m? -# 2411| v2411_11(void) = ^IndirectReadSideEffect[-1] : &:r2411_2, ~m? -# 2411| mu2411_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2411_2 -# 2411| r2411_13(glval) = CopyValue : r2411_2 -# 2411| r2411_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2411| v2411_15(void) = Call[~ClassWithDestructor] : func:r2411_14, this:r2411_13 -# 2411| mu2411_16(unknown) = ^CallSideEffect : ~m? -# 2411| v2411_17(void) = ^IndirectReadSideEffect[-1] : &:r2411_13, ~m? -# 2411| mu2411_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2411_13 -# 2411| mu2411_19(char) = Store[x] : &:r2411_1, r2411_9 -# 2411| r2411_20(glval) = VariableAddress[x] : -# 2411| r2411_21(char) = Load[x] : &:r2411_20, ~m? -# 2411| r2411_22(char) = Constant[0] : -# 2411| r2411_23(bool) = CompareNE : r2411_21, r2411_22 -# 2411| r2411_24(bool) = CopyValue : r2411_23 -# 2411| v2411_25(void) = ConditionalBranch : r2411_24 +# 2376| void VoidReturnDestructors() +# 2376| Block 0 +# 2376| v2376_1(void) = EnterFunction : +# 2376| mu2376_2(unknown) = AliasedDefinition : +# 2376| mu2376_3(unknown) = InitializeNonLocal : +# 2377| r2377_1(glval) = VariableAddress[s] : +# 2377| mu2377_2(String) = Uninitialized[s] : &:r2377_1 +# 2377| r2377_3(glval) = FunctionAddress[String] : +# 2377| v2377_4(void) = Call[String] : func:r2377_3, this:r2377_1 +# 2377| mu2377_5(unknown) = ^CallSideEffect : ~m? +# 2377| mu2377_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2377_1 +# 2378| r2378_1(glval) = FunctionAddress[VoidFunc] : +# 2378| v2378_2(void) = Call[VoidFunc] : func:r2378_1 +# 2378| mu2378_3(unknown) = ^CallSideEffect : ~m? +# 2378| v2378_4(void) = NoOp : +# 2379| r2379_1(glval) = VariableAddress[s] : +# 2379| r2379_2(glval) = FunctionAddress[~String] : +# 2379| v2379_3(void) = Call[~String] : func:r2379_2, this:r2379_1 +# 2379| mu2379_4(unknown) = ^CallSideEffect : ~m? +# 2379| v2379_5(void) = ^IndirectReadSideEffect[-1] : &:r2379_1, ~m? +# 2379| mu2379_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2379_1 +# 2376| v2376_4(void) = ReturnVoid : +# 2376| v2376_5(void) = AliasedUse : ~m? +# 2376| v2376_6(void) = ExitFunction : + +# 2389| return_routine_type::VoidToIntMemberFunc return_routine_type::GetVoidToIntFunc() +# 2389| Block 0 +# 2389| v2389_1(void) = EnterFunction : +# 2389| mu2389_2(unknown) = AliasedDefinition : +# 2389| mu2389_3(unknown) = InitializeNonLocal : +# 2391| r2391_1(glval<..:: *>) = VariableAddress[#return] : +# 2391| r2391_2(..()(..)) = FunctionAddress[VoidToInt] : +# 2391| mu2391_3(..:: *) = Store[#return] : &:r2391_1, r2391_2 +# 2389| r2389_4(glval<..:: *>) = VariableAddress[#return] : +# 2389| v2389_5(void) = ReturnValue : &:r2389_4, ~m? +# 2389| v2389_6(void) = AliasedUse : ~m? +# 2389| v2389_7(void) = ExitFunction : + +# 2396| int small_operation_should_not_be_constant_folded() +# 2396| Block 0 +# 2396| v2396_1(void) = EnterFunction : +# 2396| mu2396_2(unknown) = AliasedDefinition : +# 2396| mu2396_3(unknown) = InitializeNonLocal : +# 2397| r2397_1(glval) = VariableAddress[#return] : +# 2397| r2397_2(int) = Constant[1] : +# 2397| r2397_3(int) = Constant[2] : +# 2397| r2397_4(int) = BitXor : r2397_2, r2397_3 +# 2397| mu2397_5(int) = Store[#return] : &:r2397_1, r2397_4 +# 2396| r2396_4(glval) = VariableAddress[#return] : +# 2396| v2396_5(void) = ReturnValue : &:r2396_4, ~m? +# 2396| v2396_6(void) = AliasedUse : ~m? +# 2396| v2396_7(void) = ExitFunction : + +# 2407| int large_operation_should_be_constant_folded() +# 2407| Block 0 +# 2407| v2407_1(void) = EnterFunction : +# 2407| mu2407_2(unknown) = AliasedDefinition : +# 2407| mu2407_3(unknown) = InitializeNonLocal : +# 2408| r2408_1(glval) = VariableAddress[#return] : +# 2408| r2408_2(int) = Constant[0] : +# 2408| mu2408_3(int) = Store[#return] : &:r2408_1, r2408_2 +# 2407| r2407_4(glval) = VariableAddress[#return] : +# 2407| v2407_5(void) = ReturnValue : &:r2407_4, ~m? +# 2407| v2407_6(void) = AliasedUse : ~m? +# 2407| v2407_7(void) = ExitFunction : + +# 2411| void initialization_with_temp_destructor() +# 2411| Block 0 +# 2411| v2411_1(void) = EnterFunction : +# 2411| mu2411_2(unknown) = AliasedDefinition : +# 2411| mu2411_3(unknown) = InitializeNonLocal : +# 2412| r2412_1(glval) = VariableAddress[x] : +# 2412| r2412_2(glval) = VariableAddress[#temp2412:18] : +# 2412| mu2412_3(ClassWithDestructor) = Uninitialized[#temp2412:18] : &:r2412_2 +# 2412| r2412_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2412| v2412_5(void) = Call[ClassWithDestructor] : func:r2412_4, this:r2412_2 +# 2412| mu2412_6(unknown) = ^CallSideEffect : ~m? +# 2412| mu2412_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2412_2 +# 2412| r2412_8(glval) = FunctionAddress[get_x] : +# 2412| r2412_9(char) = Call[get_x] : func:r2412_8, this:r2412_2 +# 2412| mu2412_10(unknown) = ^CallSideEffect : ~m? +# 2412| v2412_11(void) = ^IndirectReadSideEffect[-1] : &:r2412_2, ~m? +# 2412| mu2412_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2412_2 +# 2412| r2412_13(glval) = CopyValue : r2412_2 +# 2412| r2412_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2412| v2412_15(void) = Call[~ClassWithDestructor] : func:r2412_14, this:r2412_13 +# 2412| mu2412_16(unknown) = ^CallSideEffect : ~m? +# 2412| v2412_17(void) = ^IndirectReadSideEffect[-1] : &:r2412_13, ~m? +# 2412| mu2412_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2412_13 +# 2412| mu2412_19(char) = Store[x] : &:r2412_1, r2412_9 +# 2412| r2412_20(glval) = VariableAddress[x] : +# 2412| r2412_21(char) = Load[x] : &:r2412_20, ~m? +# 2412| r2412_22(char) = Constant[0] : +# 2412| r2412_23(bool) = CompareNE : r2412_21, r2412_22 +# 2412| r2412_24(bool) = CopyValue : r2412_23 +# 2412| v2412_25(void) = ConditionalBranch : r2412_24 #-----| False -> Block 2 #-----| True -> Block 1 -# 2412| Block 1 -# 2412| r2412_1(glval) = VariableAddress[x] : -# 2412| r2412_2(char) = Load[x] : &:r2412_1, ~m? -# 2412| r2412_3(char) = Constant[1] : -# 2412| r2412_4(char) = Add : r2412_2, r2412_3 -# 2412| mu2412_5(char) = Store[x] : &:r2412_1, r2412_4 +# 2413| Block 1 +# 2413| r2413_1(glval) = VariableAddress[x] : +# 2413| r2413_2(char) = Load[x] : &:r2413_1, ~m? +# 2413| r2413_3(char) = Constant[1] : +# 2413| r2413_4(char) = Add : r2413_2, r2413_3 +# 2413| mu2413_5(char) = Store[x] : &:r2413_1, r2413_4 #-----| Goto -> Block 2 -# 2414| Block 2 -# 2414| r2414_1(glval) = VariableAddress[x] : -# 2414| r2414_2(glval) = VariableAddress[#temp2414:18] : -# 2414| mu2414_3(ClassWithDestructor) = Uninitialized[#temp2414:18] : &:r2414_2 -# 2414| r2414_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2414| v2414_5(void) = Call[ClassWithDestructor] : func:r2414_4, this:r2414_2 -# 2414| mu2414_6(unknown) = ^CallSideEffect : ~m? -# 2414| mu2414_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2414_2 -# 2414| r2414_8(glval) = FunctionAddress[get_x] : -# 2414| r2414_9(char) = Call[get_x] : func:r2414_8, this:r2414_2 -# 2414| mu2414_10(unknown) = ^CallSideEffect : ~m? -# 2414| v2414_11(void) = ^IndirectReadSideEffect[-1] : &:r2414_2, ~m? -# 2414| mu2414_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2414_2 -# 2414| r2414_13(glval) = CopyValue : r2414_2 -# 2414| r2414_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2414| v2414_15(void) = Call[~ClassWithDestructor] : func:r2414_14, this:r2414_13 -# 2414| mu2414_16(unknown) = ^CallSideEffect : ~m? -# 2414| v2414_17(void) = ^IndirectReadSideEffect[-1] : &:r2414_13, ~m? -# 2414| mu2414_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2414_13 -# 2414| mu2414_19(char) = Store[x] : &:r2414_1, r2414_9 -# 2414| r2414_20(glval) = VariableAddress[x] : -# 2414| r2414_21(char) = Load[x] : &:r2414_20, ~m? -# 2414| r2414_22(char) = Constant[0] : -# 2414| r2414_23(bool) = CompareNE : r2414_21, r2414_22 -# 2414| v2414_24(void) = ConditionalBranch : r2414_23 +# 2415| Block 2 +# 2415| r2415_1(glval) = VariableAddress[x] : +# 2415| r2415_2(glval) = VariableAddress[#temp2415:18] : +# 2415| mu2415_3(ClassWithDestructor) = Uninitialized[#temp2415:18] : &:r2415_2 +# 2415| r2415_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2415| v2415_5(void) = Call[ClassWithDestructor] : func:r2415_4, this:r2415_2 +# 2415| mu2415_6(unknown) = ^CallSideEffect : ~m? +# 2415| mu2415_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2415_2 +# 2415| r2415_8(glval) = FunctionAddress[get_x] : +# 2415| r2415_9(char) = Call[get_x] : func:r2415_8, this:r2415_2 +# 2415| mu2415_10(unknown) = ^CallSideEffect : ~m? +# 2415| v2415_11(void) = ^IndirectReadSideEffect[-1] : &:r2415_2, ~m? +# 2415| mu2415_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2415_2 +# 2415| r2415_13(glval) = CopyValue : r2415_2 +# 2415| r2415_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2415| v2415_15(void) = Call[~ClassWithDestructor] : func:r2415_14, this:r2415_13 +# 2415| mu2415_16(unknown) = ^CallSideEffect : ~m? +# 2415| v2415_17(void) = ^IndirectReadSideEffect[-1] : &:r2415_13, ~m? +# 2415| mu2415_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2415_13 +# 2415| mu2415_19(char) = Store[x] : &:r2415_1, r2415_9 +# 2415| r2415_20(glval) = VariableAddress[x] : +# 2415| r2415_21(char) = Load[x] : &:r2415_20, ~m? +# 2415| r2415_22(char) = Constant[0] : +# 2415| r2415_23(bool) = CompareNE : r2415_21, r2415_22 +# 2415| v2415_24(void) = ConditionalBranch : r2415_23 #-----| False -> Block 4 #-----| True -> Block 3 -# 2415| Block 3 -# 2415| r2415_1(glval) = VariableAddress[x] : -# 2415| r2415_2(char) = Load[x] : &:r2415_1, ~m? -# 2415| r2415_3(char) = Constant[1] : -# 2415| r2415_4(char) = Add : r2415_2, r2415_3 -# 2415| mu2415_5(char) = Store[x] : &:r2415_1, r2415_4 +# 2416| Block 3 +# 2416| r2416_1(glval) = VariableAddress[x] : +# 2416| r2416_2(char) = Load[x] : &:r2416_1, ~m? +# 2416| r2416_3(char) = Constant[1] : +# 2416| r2416_4(char) = Add : r2416_2, r2416_3 +# 2416| mu2416_5(char) = Store[x] : &:r2416_1, r2416_4 #-----| Goto -> Block 4 -# 2417| Block 4 -# 2417| r2417_1(glval) = VariableAddress[x] : -# 2417| r2417_2(glval) = VariableAddress[#temp2417:28] : -# 2417| mu2417_3(ClassWithDestructor) = Uninitialized[#temp2417:28] : &:r2417_2 -# 2417| r2417_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2417| v2417_5(void) = Call[ClassWithDestructor] : func:r2417_4, this:r2417_2 -# 2417| mu2417_6(unknown) = ^CallSideEffect : ~m? -# 2417| mu2417_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2417_2 -# 2417| r2417_8(glval) = FunctionAddress[get_x] : -# 2417| r2417_9(char) = Call[get_x] : func:r2417_8, this:r2417_2 -# 2417| mu2417_10(unknown) = ^CallSideEffect : ~m? -# 2417| v2417_11(void) = ^IndirectReadSideEffect[-1] : &:r2417_2, ~m? -# 2417| mu2417_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2417_2 -# 2417| r2417_13(glval) = CopyValue : r2417_2 -# 2417| r2417_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2417| v2417_15(void) = Call[~ClassWithDestructor] : func:r2417_14, this:r2417_13 -# 2417| mu2417_16(unknown) = ^CallSideEffect : ~m? -# 2417| v2417_17(void) = ^IndirectReadSideEffect[-1] : &:r2417_13, ~m? -# 2417| mu2417_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2417_13 -# 2417| mu2417_19(char) = Store[x] : &:r2417_1, r2417_9 -# 2417| r2417_20(bool) = Constant[1] : -# 2417| v2417_21(void) = ConditionalBranch : r2417_20 +# 2418| Block 4 +# 2418| r2418_1(glval) = VariableAddress[x] : +# 2418| r2418_2(glval) = VariableAddress[#temp2418:28] : +# 2418| mu2418_3(ClassWithDestructor) = Uninitialized[#temp2418:28] : &:r2418_2 +# 2418| r2418_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2418| v2418_5(void) = Call[ClassWithDestructor] : func:r2418_4, this:r2418_2 +# 2418| mu2418_6(unknown) = ^CallSideEffect : ~m? +# 2418| mu2418_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2418_2 +# 2418| r2418_8(glval) = FunctionAddress[get_x] : +# 2418| r2418_9(char) = Call[get_x] : func:r2418_8, this:r2418_2 +# 2418| mu2418_10(unknown) = ^CallSideEffect : ~m? +# 2418| v2418_11(void) = ^IndirectReadSideEffect[-1] : &:r2418_2, ~m? +# 2418| mu2418_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2418_2 +# 2418| r2418_13(glval) = CopyValue : r2418_2 +# 2418| r2418_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2418| v2418_15(void) = Call[~ClassWithDestructor] : func:r2418_14, this:r2418_13 +# 2418| mu2418_16(unknown) = ^CallSideEffect : ~m? +# 2418| v2418_17(void) = ^IndirectReadSideEffect[-1] : &:r2418_13, ~m? +# 2418| mu2418_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2418_13 +# 2418| mu2418_19(char) = Store[x] : &:r2418_1, r2418_9 +# 2418| r2418_20(bool) = Constant[1] : +# 2418| v2418_21(void) = ConditionalBranch : r2418_20 #-----| False -> Block 6 #-----| True -> Block 5 -# 2418| Block 5 -# 2418| r2418_1(glval) = VariableAddress[x] : -# 2418| r2418_2(char) = Load[x] : &:r2418_1, ~m? -# 2418| r2418_3(char) = Constant[1] : -# 2418| r2418_4(char) = Add : r2418_2, r2418_3 -# 2418| mu2418_5(char) = Store[x] : &:r2418_1, r2418_4 +# 2419| Block 5 +# 2419| r2419_1(glval) = VariableAddress[x] : +# 2419| r2419_2(char) = Load[x] : &:r2419_1, ~m? +# 2419| r2419_3(char) = Constant[1] : +# 2419| r2419_4(char) = Add : r2419_2, r2419_3 +# 2419| mu2419_5(char) = Store[x] : &:r2419_1, r2419_4 #-----| Goto -> Block 6 -# 2420| Block 6 -# 2420| r2420_1(glval) = VariableAddress[x] : -# 2420| r2420_2(glval) = VariableAddress[#temp2420:21] : -# 2420| mu2420_3(ClassWithDestructor) = Uninitialized[#temp2420:21] : &:r2420_2 -# 2420| r2420_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2420| v2420_5(void) = Call[ClassWithDestructor] : func:r2420_4, this:r2420_2 -# 2420| mu2420_6(unknown) = ^CallSideEffect : ~m? -# 2420| mu2420_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2420_2 -# 2420| r2420_8(glval) = FunctionAddress[get_x] : -# 2420| r2420_9(char) = Call[get_x] : func:r2420_8, this:r2420_2 -# 2420| mu2420_10(unknown) = ^CallSideEffect : ~m? -# 2420| v2420_11(void) = ^IndirectReadSideEffect[-1] : &:r2420_2, ~m? -# 2420| mu2420_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2420_2 -# 2420| r2420_13(glval) = CopyValue : r2420_2 -# 2420| r2420_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2420| v2420_15(void) = Call[~ClassWithDestructor] : func:r2420_14, this:r2420_13 -# 2420| mu2420_16(unknown) = ^CallSideEffect : ~m? -# 2420| v2420_17(void) = ^IndirectReadSideEffect[-1] : &:r2420_13, ~m? -# 2420| mu2420_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2420_13 -# 2420| mu2420_19(char) = Store[x] : &:r2420_1, r2420_9 -# 2420| r2420_20(glval) = VariableAddress[x] : -# 2420| r2420_21(char) = Load[x] : &:r2420_20, ~m? -# 2420| r2420_22(int) = Convert : r2420_21 -# 2420| r2420_23(int) = CopyValue : r2420_22 -# 2420| v2420_24(void) = Switch : r2420_23 +# 2421| Block 6 +# 2421| r2421_1(glval) = VariableAddress[x] : +# 2421| r2421_2(glval) = VariableAddress[#temp2421:21] : +# 2421| mu2421_3(ClassWithDestructor) = Uninitialized[#temp2421:21] : &:r2421_2 +# 2421| r2421_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2421| v2421_5(void) = Call[ClassWithDestructor] : func:r2421_4, this:r2421_2 +# 2421| mu2421_6(unknown) = ^CallSideEffect : ~m? +# 2421| mu2421_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2421_2 +# 2421| r2421_8(glval) = FunctionAddress[get_x] : +# 2421| r2421_9(char) = Call[get_x] : func:r2421_8, this:r2421_2 +# 2421| mu2421_10(unknown) = ^CallSideEffect : ~m? +# 2421| v2421_11(void) = ^IndirectReadSideEffect[-1] : &:r2421_2, ~m? +# 2421| mu2421_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2421_2 +# 2421| r2421_13(glval) = CopyValue : r2421_2 +# 2421| r2421_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2421| v2421_15(void) = Call[~ClassWithDestructor] : func:r2421_14, this:r2421_13 +# 2421| mu2421_16(unknown) = ^CallSideEffect : ~m? +# 2421| v2421_17(void) = ^IndirectReadSideEffect[-1] : &:r2421_13, ~m? +# 2421| mu2421_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2421_13 +# 2421| mu2421_19(char) = Store[x] : &:r2421_1, r2421_9 +# 2421| r2421_20(glval) = VariableAddress[x] : +# 2421| r2421_21(char) = Load[x] : &:r2421_20, ~m? +# 2421| r2421_22(int) = Convert : r2421_21 +# 2421| r2421_23(int) = CopyValue : r2421_22 +# 2421| v2421_24(void) = Switch : r2421_23 #-----| Case[97] -> Block 7 #-----| Default -> Block 8 -# 2421| Block 7 -# 2421| v2421_1(void) = NoOp : -# 2422| r2422_1(glval) = VariableAddress[x] : -# 2422| r2422_2(char) = Load[x] : &:r2422_1, ~m? -# 2422| r2422_3(char) = Constant[1] : -# 2422| r2422_4(char) = Add : r2422_2, r2422_3 -# 2422| mu2422_5(char) = Store[x] : &:r2422_1, r2422_4 +# 2422| Block 7 +# 2422| v2422_1(void) = NoOp : +# 2423| r2423_1(glval) = VariableAddress[x] : +# 2423| r2423_2(char) = Load[x] : &:r2423_1, ~m? +# 2423| r2423_3(char) = Constant[1] : +# 2423| r2423_4(char) = Add : r2423_2, r2423_3 +# 2423| mu2423_5(char) = Store[x] : &:r2423_1, r2423_4 #-----| Goto -> Block 8 -# 2425| Block 8 -# 2425| r2425_1(glval) = VariableAddress[x] : -# 2425| r2425_2(glval) = VariableAddress[#temp2425:21] : -# 2425| mu2425_3(ClassWithDestructor) = Uninitialized[#temp2425:21] : &:r2425_2 -# 2425| r2425_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2425| v2425_5(void) = Call[ClassWithDestructor] : func:r2425_4, this:r2425_2 -# 2425| mu2425_6(unknown) = ^CallSideEffect : ~m? -# 2425| mu2425_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2425_2 -# 2425| r2425_8(glval) = FunctionAddress[get_x] : -# 2425| r2425_9(char) = Call[get_x] : func:r2425_8, this:r2425_2 -# 2425| mu2425_10(unknown) = ^CallSideEffect : ~m? -# 2425| v2425_11(void) = ^IndirectReadSideEffect[-1] : &:r2425_2, ~m? -# 2425| mu2425_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2425_2 -# 2425| r2425_13(glval) = CopyValue : r2425_2 -# 2425| r2425_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2425| v2425_15(void) = Call[~ClassWithDestructor] : func:r2425_14, this:r2425_13 -# 2425| mu2425_16(unknown) = ^CallSideEffect : ~m? -# 2425| v2425_17(void) = ^IndirectReadSideEffect[-1] : &:r2425_13, ~m? -# 2425| mu2425_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2425_13 -# 2425| mu2425_19(char) = Store[x] : &:r2425_1, r2425_9 -# 2425| r2425_20(glval) = VariableAddress[x] : -# 2425| r2425_21(char) = Load[x] : &:r2425_20, ~m? -# 2425| r2425_22(int) = Convert : r2425_21 -# 2425| v2425_23(void) = Switch : r2425_22 +# 2426| Block 8 +# 2426| r2426_1(glval) = VariableAddress[x] : +# 2426| r2426_2(glval) = VariableAddress[#temp2426:21] : +# 2426| mu2426_3(ClassWithDestructor) = Uninitialized[#temp2426:21] : &:r2426_2 +# 2426| r2426_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2426| v2426_5(void) = Call[ClassWithDestructor] : func:r2426_4, this:r2426_2 +# 2426| mu2426_6(unknown) = ^CallSideEffect : ~m? +# 2426| mu2426_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2426_2 +# 2426| r2426_8(glval) = FunctionAddress[get_x] : +# 2426| r2426_9(char) = Call[get_x] : func:r2426_8, this:r2426_2 +# 2426| mu2426_10(unknown) = ^CallSideEffect : ~m? +# 2426| v2426_11(void) = ^IndirectReadSideEffect[-1] : &:r2426_2, ~m? +# 2426| mu2426_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2426_2 +# 2426| r2426_13(glval) = CopyValue : r2426_2 +# 2426| r2426_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2426| v2426_15(void) = Call[~ClassWithDestructor] : func:r2426_14, this:r2426_13 +# 2426| mu2426_16(unknown) = ^CallSideEffect : ~m? +# 2426| v2426_17(void) = ^IndirectReadSideEffect[-1] : &:r2426_13, ~m? +# 2426| mu2426_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2426_13 +# 2426| mu2426_19(char) = Store[x] : &:r2426_1, r2426_9 +# 2426| r2426_20(glval) = VariableAddress[x] : +# 2426| r2426_21(char) = Load[x] : &:r2426_20, ~m? +# 2426| r2426_22(int) = Convert : r2426_21 +# 2426| v2426_23(void) = Switch : r2426_22 #-----| Case[97] -> Block 9 #-----| Default -> Block 10 -# 2426| Block 9 -# 2426| v2426_1(void) = NoOp : -# 2427| r2427_1(glval) = VariableAddress[x] : -# 2427| r2427_2(char) = Load[x] : &:r2427_1, ~m? -# 2427| r2427_3(char) = Constant[1] : -# 2427| r2427_4(char) = Add : r2427_2, r2427_3 -# 2427| mu2427_5(char) = Store[x] : &:r2427_1, r2427_4 +# 2427| Block 9 +# 2427| v2427_1(void) = NoOp : +# 2428| r2428_1(glval) = VariableAddress[x] : +# 2428| r2428_2(char) = Load[x] : &:r2428_1, ~m? +# 2428| r2428_3(char) = Constant[1] : +# 2428| r2428_4(char) = Add : r2428_2, r2428_3 +# 2428| mu2428_5(char) = Store[x] : &:r2428_1, r2428_4 #-----| Goto -> Block 10 -# 2430| Block 10 -# 2430| r2430_1(glval) = VariableAddress[x] : -# 2430| r2430_2(glval) = VariableAddress[#temp2430:18] : -# 2430| mu2430_3(ClassWithDestructor) = Uninitialized[#temp2430:18] : &:r2430_2 -# 2430| r2430_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2430| v2430_5(void) = Call[ClassWithDestructor] : func:r2430_4, this:r2430_2 -# 2430| mu2430_6(unknown) = ^CallSideEffect : ~m? -# 2430| mu2430_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2430_2 -# 2430| r2430_8(glval) = FunctionAddress[get_x] : -# 2430| r2430_9(char) = Call[get_x] : func:r2430_8, this:r2430_2 -# 2430| mu2430_10(unknown) = ^CallSideEffect : ~m? -# 2430| v2430_11(void) = ^IndirectReadSideEffect[-1] : &:r2430_2, ~m? -# 2430| mu2430_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2430_2 -# 2430| r2430_13(glval) = CopyValue : r2430_2 -# 2430| r2430_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2430| v2430_15(void) = Call[~ClassWithDestructor] : func:r2430_14, this:r2430_13 -# 2430| mu2430_16(unknown) = ^CallSideEffect : ~m? -# 2430| v2430_17(void) = ^IndirectReadSideEffect[-1] : &:r2430_13, ~m? -# 2430| mu2430_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2430_13 -# 2430| mu2430_19(char) = Store[x] : &:r2430_1, r2430_9 -# 2430| r2430_20(glval &&>) = VariableAddress[(__range)] : -# 2430| r2430_21(glval>) = VariableAddress[#temp2430:58] : -# 2430| mu2430_22(vector) = Uninitialized[#temp2430:58] : &:r2430_21 -# 2430| r2430_23(glval) = FunctionAddress[vector] : -# 2430| r2430_24(glval) = VariableAddress[x] : -# 2430| r2430_25(char) = Load[x] : &:r2430_24, ~m? -# 2430| v2430_26(void) = Call[vector] : func:r2430_23, this:r2430_21, 0:r2430_25 -# 2430| mu2430_27(unknown) = ^CallSideEffect : ~m? -# 2430| mu2430_28(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2430_21 -# 2430| r2430_29(vector &) = CopyValue : r2430_21 -# 2430| mu2430_30(vector &&) = Store[(__range)] : &:r2430_20, r2430_29 -# 2430| r2430_31(glval>) = VariableAddress[(__begin)] : -# 2430| r2430_32(glval &&>) = VariableAddress[(__range)] : -# 2430| r2430_33(vector &&) = Load[(__range)] : &:r2430_32, ~m? -#-----| r0_1(glval>) = CopyValue : r2430_33 +# 2431| Block 10 +# 2431| r2431_1(glval) = VariableAddress[x] : +# 2431| r2431_2(glval) = VariableAddress[#temp2431:18] : +# 2431| mu2431_3(ClassWithDestructor) = Uninitialized[#temp2431:18] : &:r2431_2 +# 2431| r2431_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2431| v2431_5(void) = Call[ClassWithDestructor] : func:r2431_4, this:r2431_2 +# 2431| mu2431_6(unknown) = ^CallSideEffect : ~m? +# 2431| mu2431_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2431_2 +# 2431| r2431_8(glval) = FunctionAddress[get_x] : +# 2431| r2431_9(char) = Call[get_x] : func:r2431_8, this:r2431_2 +# 2431| mu2431_10(unknown) = ^CallSideEffect : ~m? +# 2431| v2431_11(void) = ^IndirectReadSideEffect[-1] : &:r2431_2, ~m? +# 2431| mu2431_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2431_2 +# 2431| r2431_13(glval) = CopyValue : r2431_2 +# 2431| r2431_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2431| v2431_15(void) = Call[~ClassWithDestructor] : func:r2431_14, this:r2431_13 +# 2431| mu2431_16(unknown) = ^CallSideEffect : ~m? +# 2431| v2431_17(void) = ^IndirectReadSideEffect[-1] : &:r2431_13, ~m? +# 2431| mu2431_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2431_13 +# 2431| mu2431_19(char) = Store[x] : &:r2431_1, r2431_9 +# 2431| r2431_20(glval &&>) = VariableAddress[(__range)] : +# 2431| r2431_21(glval>) = VariableAddress[#temp2431:58] : +# 2431| mu2431_22(vector) = Uninitialized[#temp2431:58] : &:r2431_21 +# 2431| r2431_23(glval) = FunctionAddress[vector] : +# 2431| r2431_24(glval) = VariableAddress[x] : +# 2431| r2431_25(char) = Load[x] : &:r2431_24, ~m? +# 2431| v2431_26(void) = Call[vector] : func:r2431_23, this:r2431_21, 0:r2431_25 +# 2431| mu2431_27(unknown) = ^CallSideEffect : ~m? +# 2431| mu2431_28(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2431_21 +# 2431| r2431_29(vector &) = CopyValue : r2431_21 +# 2431| mu2431_30(vector &&) = Store[(__range)] : &:r2431_20, r2431_29 +# 2431| r2431_31(glval>) = VariableAddress[(__begin)] : +# 2431| r2431_32(glval &&>) = VariableAddress[(__range)] : +# 2431| r2431_33(vector &&) = Load[(__range)] : &:r2431_32, ~m? +#-----| r0_1(glval>) = CopyValue : r2431_33 #-----| r0_2(glval>) = Convert : r0_1 -# 2430| r2430_34(glval) = FunctionAddress[begin] : -# 2430| r2430_35(iterator) = Call[begin] : func:r2430_34, this:r0_2 +# 2431| r2431_34(glval) = FunctionAddress[begin] : +# 2431| r2431_35(iterator) = Call[begin] : func:r2431_34, this:r0_2 #-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m? -# 2430| mu2430_36(iterator) = Store[(__begin)] : &:r2430_31, r2430_35 -# 2430| r2430_37(glval>) = VariableAddress[(__end)] : -# 2430| r2430_38(glval &&>) = VariableAddress[(__range)] : -# 2430| r2430_39(vector &&) = Load[(__range)] : &:r2430_38, ~m? -#-----| r0_4(glval>) = CopyValue : r2430_39 +# 2431| mu2431_36(iterator) = Store[(__begin)] : &:r2431_31, r2431_35 +# 2431| r2431_37(glval>) = VariableAddress[(__end)] : +# 2431| r2431_38(glval &&>) = VariableAddress[(__range)] : +# 2431| r2431_39(vector &&) = Load[(__range)] : &:r2431_38, ~m? +#-----| r0_4(glval>) = CopyValue : r2431_39 #-----| r0_5(glval>) = Convert : r0_4 -# 2430| r2430_40(glval) = FunctionAddress[end] : -# 2430| r2430_41(iterator) = Call[end] : func:r2430_40, this:r0_5 +# 2431| r2431_40(glval) = FunctionAddress[end] : +# 2431| r2431_41(iterator) = Call[end] : func:r2431_40, this:r0_5 #-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m? -# 2430| mu2430_42(iterator) = Store[(__end)] : &:r2430_37, r2430_41 +# 2431| mu2431_42(iterator) = Store[(__end)] : &:r2431_37, r2431_41 #-----| Goto -> Block 11 -# 2430| Block 11 -# 2430| r2430_43(glval>) = VariableAddress[(__begin)] : -#-----| r0_7(glval>) = Convert : r2430_43 -# 2430| r2430_44(glval) = FunctionAddress[operator!=] : +# 2431| Block 11 +# 2431| r2431_43(glval>) = VariableAddress[(__begin)] : +#-----| r0_7(glval>) = Convert : r2431_43 +# 2431| r2431_44(glval) = FunctionAddress[operator!=] : #-----| r0_8(glval>) = VariableAddress[#temp0:0] : #-----| mu0_9(iterator) = Uninitialized[#temp0:0] : &:r0_8 -# 2430| r2430_45(glval) = FunctionAddress[iterator] : -# 2430| r2430_46(glval>) = VariableAddress[(__end)] : -#-----| r0_10(glval>) = Convert : r2430_46 +# 2431| r2431_45(glval) = FunctionAddress[iterator] : +# 2431| r2431_46(glval>) = VariableAddress[(__end)] : +#-----| r0_10(glval>) = Convert : r2431_46 #-----| r0_11(iterator &) = CopyValue : r0_10 -# 2430| v2430_47(void) = Call[iterator] : func:r2430_45, this:r0_8, 0:r0_11 -# 2430| mu2430_48(unknown) = ^CallSideEffect : ~m? +# 2431| v2431_47(void) = Call[iterator] : func:r2431_45, this:r0_8, 0:r0_11 +# 2431| mu2431_48(unknown) = ^CallSideEffect : ~m? #-----| v0_12(void) = ^BufferReadSideEffect[0] : &:r0_11, ~m? -# 2430| mu2430_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 2431| mu2431_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 #-----| r0_13(iterator) = Load[#temp0:0] : &:r0_8, ~m? -# 2430| r2430_50(bool) = Call[operator!=] : func:r2430_44, this:r0_7, 0:r0_13 +# 2431| r2431_50(bool) = Call[operator!=] : func:r2431_44, this:r0_7, 0:r0_13 #-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~m? -# 2430| v2430_51(void) = ConditionalBranch : r2430_50 +# 2431| v2431_51(void) = ConditionalBranch : r2431_50 #-----| False -> Block 13 #-----| True -> Block 12 -# 2430| Block 12 -# 2430| r2430_52(glval) = VariableAddress[y] : -# 2430| r2430_53(glval>) = VariableAddress[(__begin)] : -#-----| r0_15(glval>) = Convert : r2430_53 -# 2430| r2430_54(glval) = FunctionAddress[operator*] : -# 2430| r2430_55(char &) = Call[operator*] : func:r2430_54, this:r0_15 +# 2431| Block 12 +# 2431| r2431_52(glval) = VariableAddress[y] : +# 2431| r2431_53(glval>) = VariableAddress[(__begin)] : +#-----| r0_15(glval>) = Convert : r2431_53 +# 2431| r2431_54(glval) = FunctionAddress[operator*] : +# 2431| r2431_55(char &) = Call[operator*] : func:r2431_54, this:r0_15 #-----| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_15, ~m? -# 2430| r2430_56(char) = Load[?] : &:r2430_55, ~m? -# 2430| mu2430_57(char) = Store[y] : &:r2430_52, r2430_56 -# 2431| r2431_1(glval) = VariableAddress[x] : -# 2431| r2431_2(char) = Load[x] : &:r2431_1, ~m? -# 2431| r2431_3(int) = Convert : r2431_2 -# 2431| r2431_4(glval) = VariableAddress[y] : -# 2431| r2431_5(char) = Load[y] : &:r2431_4, ~m? -# 2431| r2431_6(int) = Convert : r2431_5 -# 2431| r2431_7(int) = Add : r2431_6, r2431_3 -# 2431| r2431_8(char) = Convert : r2431_7 -# 2431| mu2431_9(char) = Store[y] : &:r2431_4, r2431_8 -# 2430| r2430_58(glval>) = VariableAddress[(__begin)] : -# 2430| r2430_59(glval) = FunctionAddress[operator++] : -# 2430| r2430_60(iterator &) = Call[operator++] : func:r2430_59, this:r2430_58 -# 2430| v2430_61(void) = ^IndirectReadSideEffect[-1] : &:r2430_58, ~m? -# 2430| mu2430_62(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2430_58 -# 2430| r2430_63(glval>) = CopyValue : r2430_60 +# 2431| r2431_56(char) = Load[?] : &:r2431_55, ~m? +# 2431| mu2431_57(char) = Store[y] : &:r2431_52, r2431_56 +# 2432| r2432_1(glval) = VariableAddress[x] : +# 2432| r2432_2(char) = Load[x] : &:r2432_1, ~m? +# 2432| r2432_3(int) = Convert : r2432_2 +# 2432| r2432_4(glval) = VariableAddress[y] : +# 2432| r2432_5(char) = Load[y] : &:r2432_4, ~m? +# 2432| r2432_6(int) = Convert : r2432_5 +# 2432| r2432_7(int) = Add : r2432_6, r2432_3 +# 2432| r2432_8(char) = Convert : r2432_7 +# 2432| mu2432_9(char) = Store[y] : &:r2432_4, r2432_8 +# 2431| r2431_58(glval>) = VariableAddress[(__begin)] : +# 2431| r2431_59(glval) = FunctionAddress[operator++] : +# 2431| r2431_60(iterator &) = Call[operator++] : func:r2431_59, this:r2431_58 +# 2431| v2431_61(void) = ^IndirectReadSideEffect[-1] : &:r2431_58, ~m? +# 2431| mu2431_62(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2431_58 +# 2431| r2431_63(glval>) = CopyValue : r2431_60 #-----| Goto (back edge) -> Block 11 -# 2432| Block 13 -# 2432| v2432_1(void) = NoOp : -# 2410| v2410_4(void) = ReturnVoid : -# 2410| v2410_5(void) = AliasedUse : ~m? -# 2410| v2410_6(void) = ExitFunction : - -# 2434| void param_with_destructor_by_value(ClassWithDestructor) -# 2434| Block 0 -# 2434| v2434_1(void) = EnterFunction : -# 2434| mu2434_2(unknown) = AliasedDefinition : -# 2434| mu2434_3(unknown) = InitializeNonLocal : -# 2434| r2434_4(glval) = VariableAddress[c] : -# 2434| mu2434_5(ClassWithDestructor) = InitializeParameter[c] : &:r2434_4 -# 2436| v2436_1(void) = NoOp : -# 2434| v2434_6(void) = ReturnVoid : -# 2434| v2434_7(void) = AliasedUse : ~m? -# 2434| v2434_8(void) = ExitFunction : - -# 2438| void param_with_destructor_by_pointer(ClassWithDestructor*) -# 2438| Block 0 -# 2438| v2438_1(void) = EnterFunction : -# 2438| mu2438_2(unknown) = AliasedDefinition : -# 2438| mu2438_3(unknown) = InitializeNonLocal : -# 2438| r2438_4(glval) = VariableAddress[c] : -# 2438| mu2438_5(ClassWithDestructor *) = InitializeParameter[c] : &:r2438_4 -# 2438| r2438_6(ClassWithDestructor *) = Load[c] : &:r2438_4, ~m? -# 2438| mu2438_7(unknown) = InitializeIndirection[c] : &:r2438_6 -# 2440| v2440_1(void) = NoOp : -# 2438| v2438_8(void) = ReturnIndirection[c] : &:r2438_6, ~m? -# 2438| v2438_9(void) = ReturnVoid : -# 2438| v2438_10(void) = AliasedUse : ~m? -# 2438| v2438_11(void) = ExitFunction : - -# 2442| void param_with_destructor_by_ref(ClassWithDestructor&) -# 2442| Block 0 -# 2442| v2442_1(void) = EnterFunction : -# 2442| mu2442_2(unknown) = AliasedDefinition : -# 2442| mu2442_3(unknown) = InitializeNonLocal : -# 2442| r2442_4(glval) = VariableAddress[c] : -# 2442| mu2442_5(ClassWithDestructor &) = InitializeParameter[c] : &:r2442_4 -# 2442| r2442_6(ClassWithDestructor &) = Load[c] : &:r2442_4, ~m? -# 2442| mu2442_7(unknown) = InitializeIndirection[c] : &:r2442_6 -# 2444| v2444_1(void) = NoOp : -# 2442| v2442_8(void) = ReturnIndirection[c] : &:r2442_6, ~m? -# 2442| v2442_9(void) = ReturnVoid : -# 2442| v2442_10(void) = AliasedUse : ~m? -# 2442| v2442_11(void) = ExitFunction : - -# 2446| void param_with_destructor_by_rref(ClassWithDestructor&&) -# 2446| Block 0 -# 2446| v2446_1(void) = EnterFunction : -# 2446| mu2446_2(unknown) = AliasedDefinition : -# 2446| mu2446_3(unknown) = InitializeNonLocal : -# 2446| r2446_4(glval) = VariableAddress[c] : -# 2446| mu2446_5(ClassWithDestructor &&) = InitializeParameter[c] : &:r2446_4 -# 2446| r2446_6(ClassWithDestructor &&) = Load[c] : &:r2446_4, ~m? -# 2446| mu2446_7(unknown) = InitializeIndirection[c] : &:r2446_6 -# 2448| v2448_1(void) = NoOp : -# 2446| v2446_8(void) = ReturnIndirection[c] : &:r2446_6, ~m? -# 2446| v2446_9(void) = ReturnVoid : -# 2446| v2446_10(void) = AliasedUse : ~m? -# 2446| v2446_11(void) = ExitFunction : - -# 2450| void rethrow_with_destruction(int) -# 2450| Block 0 -# 2450| v2450_1(void) = EnterFunction : -# 2450| mu2450_2(unknown) = AliasedDefinition : -# 2450| mu2450_3(unknown) = InitializeNonLocal : -# 2450| r2450_4(glval) = VariableAddress[x] : -# 2450| mu2450_5(int) = InitializeParameter[x] : &:r2450_4 -# 2451| r2451_1(glval) = VariableAddress[c] : -# 2451| mu2451_2(ClassWithDestructor) = Uninitialized[c] : &:r2451_1 -# 2451| r2451_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2451| v2451_4(void) = Call[ClassWithDestructor] : func:r2451_3, this:r2451_1 -# 2451| mu2451_5(unknown) = ^CallSideEffect : ~m? -# 2451| mu2451_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2451_1 -# 2452| v2452_1(void) = ReThrow : -# 2453| r2453_1(glval) = VariableAddress[c] : -# 2453| r2453_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2453| v2453_3(void) = Call[~ClassWithDestructor] : func:r2453_2, this:r2453_1 -# 2453| mu2453_4(unknown) = ^CallSideEffect : ~m? -# 2453| v2453_5(void) = ^IndirectReadSideEffect[-1] : &:r2453_1, ~m? -# 2453| mu2453_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2453_1 +# 2431| Block 13 +# 2431| r2431_64(glval>) = CopyValue : r2431_21 +# 2431| r2431_65(glval) = FunctionAddress[~vector] : +# 2431| v2431_66(void) = Call[~vector] : func:r2431_65, this:r2431_64 +# 2431| mu2431_67(unknown) = ^CallSideEffect : ~m? +# 2431| v2431_68(void) = ^IndirectReadSideEffect[-1] : &:r2431_64, ~m? +# 2431| mu2431_69(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2431_64 +# 2433| v2433_1(void) = NoOp : +# 2411| v2411_4(void) = ReturnVoid : +# 2411| v2411_5(void) = AliasedUse : ~m? +# 2411| v2411_6(void) = ExitFunction : + +# 2435| void param_with_destructor_by_value(ClassWithDestructor) +# 2435| Block 0 +# 2435| v2435_1(void) = EnterFunction : +# 2435| mu2435_2(unknown) = AliasedDefinition : +# 2435| mu2435_3(unknown) = InitializeNonLocal : +# 2435| r2435_4(glval) = VariableAddress[c] : +# 2435| mu2435_5(ClassWithDestructor) = InitializeParameter[c] : &:r2435_4 +# 2437| v2437_1(void) = NoOp : +# 2435| v2435_6(void) = ReturnVoid : +# 2435| v2435_7(void) = AliasedUse : ~m? +# 2435| v2435_8(void) = ExitFunction : + +# 2439| void param_with_destructor_by_pointer(ClassWithDestructor*) +# 2439| Block 0 +# 2439| v2439_1(void) = EnterFunction : +# 2439| mu2439_2(unknown) = AliasedDefinition : +# 2439| mu2439_3(unknown) = InitializeNonLocal : +# 2439| r2439_4(glval) = VariableAddress[c] : +# 2439| mu2439_5(ClassWithDestructor *) = InitializeParameter[c] : &:r2439_4 +# 2439| r2439_6(ClassWithDestructor *) = Load[c] : &:r2439_4, ~m? +# 2439| mu2439_7(unknown) = InitializeIndirection[c] : &:r2439_6 +# 2441| v2441_1(void) = NoOp : +# 2439| v2439_8(void) = ReturnIndirection[c] : &:r2439_6, ~m? +# 2439| v2439_9(void) = ReturnVoid : +# 2439| v2439_10(void) = AliasedUse : ~m? +# 2439| v2439_11(void) = ExitFunction : + +# 2443| void param_with_destructor_by_ref(ClassWithDestructor&) +# 2443| Block 0 +# 2443| v2443_1(void) = EnterFunction : +# 2443| mu2443_2(unknown) = AliasedDefinition : +# 2443| mu2443_3(unknown) = InitializeNonLocal : +# 2443| r2443_4(glval) = VariableAddress[c] : +# 2443| mu2443_5(ClassWithDestructor &) = InitializeParameter[c] : &:r2443_4 +# 2443| r2443_6(ClassWithDestructor &) = Load[c] : &:r2443_4, ~m? +# 2443| mu2443_7(unknown) = InitializeIndirection[c] : &:r2443_6 +# 2445| v2445_1(void) = NoOp : +# 2443| v2443_8(void) = ReturnIndirection[c] : &:r2443_6, ~m? +# 2443| v2443_9(void) = ReturnVoid : +# 2443| v2443_10(void) = AliasedUse : ~m? +# 2443| v2443_11(void) = ExitFunction : + +# 2447| void param_with_destructor_by_rref(ClassWithDestructor&&) +# 2447| Block 0 +# 2447| v2447_1(void) = EnterFunction : +# 2447| mu2447_2(unknown) = AliasedDefinition : +# 2447| mu2447_3(unknown) = InitializeNonLocal : +# 2447| r2447_4(glval) = VariableAddress[c] : +# 2447| mu2447_5(ClassWithDestructor &&) = InitializeParameter[c] : &:r2447_4 +# 2447| r2447_6(ClassWithDestructor &&) = Load[c] : &:r2447_4, ~m? +# 2447| mu2447_7(unknown) = InitializeIndirection[c] : &:r2447_6 +# 2449| v2449_1(void) = NoOp : +# 2447| v2447_8(void) = ReturnIndirection[c] : &:r2447_6, ~m? +# 2447| v2447_9(void) = ReturnVoid : +# 2447| v2447_10(void) = AliasedUse : ~m? +# 2447| v2447_11(void) = ExitFunction : + +# 2451| void rethrow_with_destruction(int) +# 2451| Block 0 +# 2451| v2451_1(void) = EnterFunction : +# 2451| mu2451_2(unknown) = AliasedDefinition : +# 2451| mu2451_3(unknown) = InitializeNonLocal : +# 2451| r2451_4(glval) = VariableAddress[x] : +# 2451| mu2451_5(int) = InitializeParameter[x] : &:r2451_4 +# 2452| r2452_1(glval) = VariableAddress[c] : +# 2452| mu2452_2(ClassWithDestructor) = Uninitialized[c] : &:r2452_1 +# 2452| r2452_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2452| v2452_4(void) = Call[ClassWithDestructor] : func:r2452_3, this:r2452_1 +# 2452| mu2452_5(unknown) = ^CallSideEffect : ~m? +# 2452| mu2452_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2452_1 +# 2453| v2453_1(void) = ReThrow : +# 2454| r2454_1(glval) = VariableAddress[c] : +# 2454| r2454_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2454| v2454_3(void) = Call[~ClassWithDestructor] : func:r2454_2, this:r2454_1 +# 2454| mu2454_4(unknown) = ^CallSideEffect : ~m? +# 2454| v2454_5(void) = ^IndirectReadSideEffect[-1] : &:r2454_1, ~m? +# 2454| mu2454_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2454_1 +#-----| Exception -> Block 3 + +# 2451| Block 1 +# 2451| v2451_6(void) = AliasedUse : ~m? +# 2451| v2451_7(void) = ExitFunction : + +# 2451| Block 2 +# 2451| v2451_8(void) = ReturnVoid : +#-----| Goto -> Block 1 + +# 2451| Block 3 +# 2451| v2451_9(void) = Unwind : +#-----| Goto -> Block 1 + +# 2460| void new_with_destructor(ClassWithDestructor) +# 2460| Block 0 +# 2460| v2460_1(void) = EnterFunction : +# 2460| mu2460_2(unknown) = AliasedDefinition : +# 2460| mu2460_3(unknown) = InitializeNonLocal : +# 2460| r2460_4(glval) = VariableAddress[a] : +# 2460| mu2460_5(ClassWithDestructor) = InitializeParameter[a] : &:r2460_4 +# 2462| r2462_1(glval) = VariableAddress[b] : +# 2462| r2462_2(glval) = FunctionAddress[operator new] : +# 2462| r2462_3(unsigned long) = Constant[1] : +# 2462| r2462_4(void *) = Call[operator new] : func:r2462_2, 0:r2462_3 +# 2462| mu2462_5(unknown) = ^CallSideEffect : ~m? +# 2462| mu2462_6(unknown) = ^InitializeDynamicAllocation : &:r2462_4 +# 2462| r2462_7(ByValueConstructor *) = Convert : r2462_4 +# 2462| r2462_8(glval) = FunctionAddress[ByValueConstructor] : +# 2462| r2462_9(glval) = VariableAddress[#temp2462:52] : +# 2462| r2462_10(glval) = VariableAddress[a] : +# 2462| r2462_11(ClassWithDestructor) = Load[a] : &:r2462_10, ~m? +# 2462| mu2462_12(ClassWithDestructor) = Store[#temp2462:52] : &:r2462_9, r2462_11 +# 2462| r2462_13(ClassWithDestructor) = Load[#temp2462:52] : &:r2462_9, ~m? +# 2462| v2462_14(void) = Call[ByValueConstructor] : func:r2462_8, this:r2462_7, 0:r2462_13 +# 2462| mu2462_15(unknown) = ^CallSideEffect : ~m? +# 2462| mu2462_16(ByValueConstructor) = ^IndirectMayWriteSideEffect[-1] : &:r2462_7 +# 2462| r2462_17(glval) = CopyValue : r2462_9 +# 2462| r2462_18(glval) = FunctionAddress[~ClassWithDestructor] : +# 2462| v2462_19(void) = Call[~ClassWithDestructor] : func:r2462_18, this:r2462_17 +# 2462| mu2462_20(unknown) = ^CallSideEffect : ~m? +# 2462| v2462_21(void) = ^IndirectReadSideEffect[-1] : &:r2462_17, ~m? +# 2462| mu2462_22(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2462_17 +# 2462| mu2462_23(ByValueConstructor *) = Store[b] : &:r2462_1, r2462_7 +# 2463| v2463_1(void) = NoOp : +# 2460| v2460_6(void) = ReturnVoid : +# 2460| v2460_7(void) = AliasedUse : ~m? +# 2460| v2460_8(void) = ExitFunction : + +# 2479| void rvalue_conversion_with_destructor::test() +# 2479| Block 0 +# 2479| v2479_1(void) = EnterFunction : +# 2479| mu2479_2(unknown) = AliasedDefinition : +# 2479| mu2479_3(unknown) = InitializeNonLocal : +# 2481| r2481_1(glval) = VariableAddress[a] : +# 2481| r2481_2(glval) = VariableAddress[#temp2481:18] : +# 2481| r2481_3(glval) = FunctionAddress[get] : +# 2481| r2481_4(B) = Call[get] : func:r2481_3 +# 2481| mu2481_5(unknown) = ^CallSideEffect : ~m? +# 2481| mu2481_6(B) = Store[#temp2481:18] : &:r2481_2, r2481_4 +# 2481| r2481_7(glval) = Convert : r2481_2 +# 2481| r2481_8(glval) = FunctionAddress[operator->] : +# 2481| r2481_9(A *) = Call[operator->] : func:r2481_8, this:r2481_7 +# 2481| mu2481_10(unknown) = ^CallSideEffect : ~m? +# 2481| v2481_11(void) = ^IndirectReadSideEffect[-1] : &:r2481_7, ~m? +# 2481| r2481_12(glval) = FieldAddress[a] : r2481_9 +# 2481| r2481_13(glval) = CopyValue : r2481_2 +# 2481| r2481_14(glval) = FunctionAddress[~B] : +# 2481| v2481_15(void) = Call[~B] : func:r2481_14, this:r2481_13 +# 2481| mu2481_16(unknown) = ^CallSideEffect : ~m? +# 2481| v2481_17(void) = ^IndirectReadSideEffect[-1] : &:r2481_13, ~m? +# 2481| mu2481_18(B) = ^IndirectMayWriteSideEffect[-1] : &:r2481_13 +# 2481| r2481_19(unsigned int) = Load[?] : &:r2481_12, ~m? +# 2481| mu2481_20(unsigned int) = Store[a] : &:r2481_1, r2481_19 +# 2482| v2482_1(void) = NoOp : +# 2479| v2479_4(void) = ReturnVoid : +# 2479| v2479_5(void) = AliasedUse : ~m? +# 2479| v2479_6(void) = ExitFunction : + +# 2485| void destructor_without_block(bool) +# 2485| Block 0 +# 2485| v2485_1(void) = EnterFunction : +# 2485| mu2485_2(unknown) = AliasedDefinition : +# 2485| mu2485_3(unknown) = InitializeNonLocal : +# 2485| r2485_4(glval) = VariableAddress[b] : +# 2485| mu2485_5(bool) = InitializeParameter[b] : &:r2485_4 +# 2487| r2487_1(glval) = VariableAddress[b] : +# 2487| r2487_2(bool) = Load[b] : &:r2487_1, ~m? +# 2487| v2487_3(void) = ConditionalBranch : r2487_2 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 2488| Block 1 +# 2488| r2488_1(glval) = VariableAddress[c] : +# 2488| mu2488_2(ClassWithDestructor) = Uninitialized[c] : &:r2488_1 +# 2488| r2488_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2488| v2488_4(void) = Call[ClassWithDestructor] : func:r2488_3, this:r2488_1 +# 2488| mu2488_5(unknown) = ^CallSideEffect : ~m? +# 2488| mu2488_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2488_1 +#-----| r0_1(glval) = VariableAddress[c] : +#-----| r0_2(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_3(void) = Call[~ClassWithDestructor] : func:r0_2, this:r0_1 +#-----| mu0_4(unknown) = ^CallSideEffect : ~m? +#-----| v0_5(void) = ^IndirectReadSideEffect[-1] : &:r0_1, ~m? +#-----| mu0_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_1 +#-----| Goto -> Block 2 + +# 2490| Block 2 +# 2490| r2490_1(glval) = VariableAddress[b] : +# 2490| r2490_2(bool) = Load[b] : &:r2490_1, ~m? +# 2490| v2490_3(void) = ConditionalBranch : r2490_2 +#-----| False -> Block 4 +#-----| True -> Block 3 + +# 2491| Block 3 +# 2491| r2491_1(glval) = VariableAddress[d] : +# 2491| mu2491_2(ClassWithDestructor) = Uninitialized[d] : &:r2491_1 +# 2491| r2491_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2491| v2491_4(void) = Call[ClassWithDestructor] : func:r2491_3, this:r2491_1 +# 2491| mu2491_5(unknown) = ^CallSideEffect : ~m? +# 2491| mu2491_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2491_1 +#-----| r0_7(glval) = VariableAddress[d] : +#-----| r0_8(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_9(void) = Call[~ClassWithDestructor] : func:r0_8, this:r0_7 +#-----| mu0_10(unknown) = ^CallSideEffect : ~m? +#-----| v0_11(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~m? +#-----| mu0_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_7 +#-----| Goto -> Block 5 + +# 2493| Block 4 +# 2493| r2493_1(glval) = VariableAddress[e] : +# 2493| mu2493_2(ClassWithDestructor) = Uninitialized[e] : &:r2493_1 +# 2493| r2493_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2493| v2493_4(void) = Call[ClassWithDestructor] : func:r2493_3, this:r2493_1 +# 2493| mu2493_5(unknown) = ^CallSideEffect : ~m? +# 2493| mu2493_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2493_1 +#-----| r0_13(glval) = VariableAddress[e] : +#-----| r0_14(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_15(void) = Call[~ClassWithDestructor] : func:r0_14, this:r0_13 +#-----| mu0_16(unknown) = ^CallSideEffect : ~m? +#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_13, ~m? +#-----| mu0_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_13 +#-----| Goto -> Block 5 + +# 2495| Block 5 +# 2495| r2495_1(glval) = VariableAddress[b] : +# 2495| r2495_2(bool) = Load[b] : &:r2495_1, ~m? +# 2495| v2495_3(void) = ConditionalBranch : r2495_2 +#-----| False -> Block 7 +#-----| True -> Block 6 + +# 2496| Block 6 +# 2496| r2496_1(glval) = VariableAddress[f] : +# 2496| mu2496_2(ClassWithDestructor) = Uninitialized[f] : &:r2496_1 +# 2496| r2496_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2496| v2496_4(void) = Call[ClassWithDestructor] : func:r2496_3, this:r2496_1 +# 2496| mu2496_5(unknown) = ^CallSideEffect : ~m? +# 2496| mu2496_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2496_1 +#-----| r0_19(glval) = VariableAddress[f] : +#-----| r0_20(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_21(void) = Call[~ClassWithDestructor] : func:r0_20, this:r0_19 +#-----| mu0_22(unknown) = ^CallSideEffect : ~m? +#-----| v0_23(void) = ^IndirectReadSideEffect[-1] : &:r0_19, ~m? +#-----| mu0_24(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_19 +#-----| Goto (back edge) -> Block 5 + +# 2498| Block 7 +# 2498| r2498_1(glval) = VariableAddress[i] : +# 2498| r2498_2(int) = Constant[0] : +# 2498| mu2498_3(int) = Store[i] : &:r2498_1, r2498_2 +#-----| Goto -> Block 8 + +# 2498| Block 8 +# 2498| r2498_4(glval) = VariableAddress[i] : +# 2498| r2498_5(int) = Load[i] : &:r2498_4, ~m? +# 2498| r2498_6(int) = Constant[42] : +# 2498| r2498_7(bool) = CompareLT : r2498_5, r2498_6 +# 2498| v2498_8(void) = ConditionalBranch : r2498_7 +#-----| False -> Block 10 +#-----| True -> Block 9 + +# 2499| Block 9 +# 2499| r2499_1(glval) = VariableAddress[g] : +# 2499| mu2499_2(ClassWithDestructor) = Uninitialized[g] : &:r2499_1 +# 2499| r2499_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2499| v2499_4(void) = Call[ClassWithDestructor] : func:r2499_3, this:r2499_1 +# 2499| mu2499_5(unknown) = ^CallSideEffect : ~m? +# 2499| mu2499_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2499_1 +#-----| r0_25(glval) = VariableAddress[g] : +#-----| r0_26(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_27(void) = Call[~ClassWithDestructor] : func:r0_26, this:r0_25 +#-----| mu0_28(unknown) = ^CallSideEffect : ~m? +#-----| v0_29(void) = ^IndirectReadSideEffect[-1] : &:r0_25, ~m? +#-----| mu0_30(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_25 +# 2498| r2498_9(glval) = VariableAddress[i] : +# 2498| r2498_10(int) = Load[i] : &:r2498_9, ~m? +# 2498| r2498_11(int) = Constant[1] : +# 2498| r2498_12(int) = Add : r2498_10, r2498_11 +# 2498| mu2498_13(int) = Store[i] : &:r2498_9, r2498_12 +#-----| Goto (back edge) -> Block 8 + +# 2500| Block 10 +# 2500| v2500_1(void) = NoOp : +# 2485| v2485_6(void) = ReturnVoid : +# 2485| v2485_7(void) = AliasedUse : ~m? +# 2485| v2485_8(void) = ExitFunction : + +# 2502| void destruction_in_switch_1(int) +# 2502| Block 0 +# 2502| v2502_1(void) = EnterFunction : +# 2502| mu2502_2(unknown) = AliasedDefinition : +# 2502| mu2502_3(unknown) = InitializeNonLocal : +# 2502| r2502_4(glval) = VariableAddress[c] : +# 2502| mu2502_5(int) = InitializeParameter[c] : &:r2502_4 +# 2503| r2503_1(glval) = VariableAddress[c] : +# 2503| r2503_2(int) = Load[c] : &:r2503_1, ~m? +# 2503| v2503_3(void) = Switch : r2503_2 +#-----| Case[0] -> Block 1 +#-----| Default -> Block 3 + +# 2504| Block 1 +# 2504| v2504_1(void) = NoOp : +# 2505| r2505_1(glval) = VariableAddress[x] : +# 2505| mu2505_2(ClassWithDestructor) = Uninitialized[x] : &:r2505_1 +# 2505| r2505_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2505| v2505_4(void) = Call[ClassWithDestructor] : func:r2505_3, this:r2505_1 +# 2505| mu2505_5(unknown) = ^CallSideEffect : ~m? +# 2505| mu2505_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2505_1 +# 2507| r2507_1(glval) = VariableAddress[x] : +# 2507| r2507_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2507| v2507_3(void) = Call[~ClassWithDestructor] : func:r2507_2, this:r2507_1 +# 2507| mu2507_4(unknown) = ^CallSideEffect : ~m? +# 2507| v2507_5(void) = ^IndirectReadSideEffect[-1] : &:r2507_1, ~m? +# 2507| mu2507_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2507_1 +# 2506| v2506_1(void) = NoOp : +#-----| Goto -> Block 3 + +# 2507| Block 2 +# 2507| r2507_7(glval) = VariableAddress[x] : +# 2507| r2507_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2507| v2507_9(void) = Call[~ClassWithDestructor] : func:r2507_8, this:r2507_7 +# 2507| mu2507_10(unknown) = ^CallSideEffect : ~m? +# 2507| v2507_11(void) = ^IndirectReadSideEffect[-1] : &:r2507_7, ~m? +# 2507| mu2507_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2507_7 +#-----| Goto -> Block 3 + +# 2508| Block 3 +# 2508| v2508_1(void) = NoOp : +# 2509| v2509_1(void) = NoOp : +# 2502| v2502_6(void) = ReturnVoid : +# 2502| v2502_7(void) = AliasedUse : ~m? +# 2502| v2502_8(void) = ExitFunction : + +# 2511| void destruction_in_switch_2(int) +# 2511| Block 0 +# 2511| v2511_1(void) = EnterFunction : +# 2511| mu2511_2(unknown) = AliasedDefinition : +# 2511| mu2511_3(unknown) = InitializeNonLocal : +# 2511| r2511_4(glval) = VariableAddress[c] : +# 2511| mu2511_5(int) = InitializeParameter[c] : &:r2511_4 +# 2512| r2512_1(glval) = VariableAddress[y] : +# 2512| mu2512_2(ClassWithDestructor) = Uninitialized[y] : &:r2512_1 +# 2512| r2512_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2512| v2512_4(void) = Call[ClassWithDestructor] : func:r2512_3, this:r2512_1 +# 2512| mu2512_5(unknown) = ^CallSideEffect : ~m? +# 2512| mu2512_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2512_1 +# 2512| r2512_7(glval) = VariableAddress[c] : +# 2512| r2512_8(int) = Load[c] : &:r2512_7, ~m? +# 2512| v2512_9(void) = Switch : r2512_8 +#-----| Case[0] -> Block 1 +#-----| Default -> Block 2 + +# 2513| Block 1 +# 2513| v2513_1(void) = NoOp : +# 2519| r2519_1(glval) = VariableAddress[y] : +# 2519| r2519_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2519| v2519_3(void) = Call[~ClassWithDestructor] : func:r2519_2, this:r2519_1 +# 2519| mu2519_4(unknown) = ^CallSideEffect : ~m? +# 2519| v2519_5(void) = ^IndirectReadSideEffect[-1] : &:r2519_1, ~m? +# 2519| mu2519_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2519_1 +# 2514| v2514_1(void) = NoOp : +#-----| Goto -> Block 4 + +# 2516| Block 2 +# 2516| v2516_1(void) = NoOp : +# 2519| r2519_7(glval) = VariableAddress[y] : +# 2519| r2519_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2519| v2519_9(void) = Call[~ClassWithDestructor] : func:r2519_8, this:r2519_7 +# 2519| mu2519_10(unknown) = ^CallSideEffect : ~m? +# 2519| v2519_11(void) = ^IndirectReadSideEffect[-1] : &:r2519_7, ~m? +# 2519| mu2519_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2519_7 +# 2517| v2517_1(void) = NoOp : +#-----| Goto -> Block 4 + +# 2519| Block 3 +# 2519| r2519_13(glval) = VariableAddress[y] : +# 2519| r2519_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2519| v2519_15(void) = Call[~ClassWithDestructor] : func:r2519_14, this:r2519_13 +# 2519| mu2519_16(unknown) = ^CallSideEffect : ~m? +# 2519| v2519_17(void) = ^IndirectReadSideEffect[-1] : &:r2519_13, ~m? +# 2519| mu2519_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2519_13 +#-----| Goto -> Block 4 + +# 2519| Block 4 +# 2519| v2519_19(void) = NoOp : +# 2520| v2520_1(void) = NoOp : +# 2511| v2511_6(void) = ReturnVoid : +# 2511| v2511_7(void) = AliasedUse : ~m? +# 2511| v2511_8(void) = ExitFunction : + +# 2522| void destruction_in_switch_3(int) +# 2522| Block 0 +# 2522| v2522_1(void) = EnterFunction : +# 2522| mu2522_2(unknown) = AliasedDefinition : +# 2522| mu2522_3(unknown) = InitializeNonLocal : +# 2522| r2522_4(glval) = VariableAddress[c] : +# 2522| mu2522_5(int) = InitializeParameter[c] : &:r2522_4 +# 2523| r2523_1(glval) = VariableAddress[y] : +# 2523| mu2523_2(ClassWithDestructor) = Uninitialized[y] : &:r2523_1 +# 2523| r2523_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2523| v2523_4(void) = Call[ClassWithDestructor] : func:r2523_3, this:r2523_1 +# 2523| mu2523_5(unknown) = ^CallSideEffect : ~m? +# 2523| mu2523_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2523_1 +# 2523| r2523_7(glval) = VariableAddress[c] : +# 2523| r2523_8(int) = Load[c] : &:r2523_7, ~m? +# 2523| v2523_9(void) = Switch : r2523_8 +#-----| Case[0] -> Block 1 +#-----| Default -> Block 3 + +# 2524| Block 1 +# 2524| v2524_1(void) = NoOp : +# 2525| r2525_1(glval) = VariableAddress[x] : +# 2525| mu2525_2(ClassWithDestructor) = Uninitialized[x] : &:r2525_1 +# 2525| r2525_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2525| v2525_4(void) = Call[ClassWithDestructor] : func:r2525_3, this:r2525_1 +# 2525| mu2525_5(unknown) = ^CallSideEffect : ~m? +# 2525| mu2525_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2525_1 +# 2527| r2527_1(glval) = VariableAddress[x] : +# 2527| r2527_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2527| v2527_3(void) = Call[~ClassWithDestructor] : func:r2527_2, this:r2527_1 +# 2527| mu2527_4(unknown) = ^CallSideEffect : ~m? +# 2527| v2527_5(void) = ^IndirectReadSideEffect[-1] : &:r2527_1, ~m? +# 2527| mu2527_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2527_1 +# 2531| r2531_1(glval) = VariableAddress[y] : +# 2531| r2531_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2531| v2531_3(void) = Call[~ClassWithDestructor] : func:r2531_2, this:r2531_1 +# 2531| mu2531_4(unknown) = ^CallSideEffect : ~m? +# 2531| v2531_5(void) = ^IndirectReadSideEffect[-1] : &:r2531_1, ~m? +# 2531| mu2531_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2531_1 +# 2526| v2526_1(void) = NoOp : +#-----| Goto -> Block 5 + +# 2527| Block 2 +# 2527| r2527_7(glval) = VariableAddress[x] : +# 2527| r2527_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2527| v2527_9(void) = Call[~ClassWithDestructor] : func:r2527_8, this:r2527_7 +# 2527| mu2527_10(unknown) = ^CallSideEffect : ~m? +# 2527| v2527_11(void) = ^IndirectReadSideEffect[-1] : &:r2527_7, ~m? +# 2527| mu2527_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2527_7 +#-----| Goto -> Block 3 + +# 2528| Block 3 +# 2528| v2528_1(void) = NoOp : +# 2531| r2531_7(glval) = VariableAddress[y] : +# 2531| r2531_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2531| v2531_9(void) = Call[~ClassWithDestructor] : func:r2531_8, this:r2531_7 +# 2531| mu2531_10(unknown) = ^CallSideEffect : ~m? +# 2531| v2531_11(void) = ^IndirectReadSideEffect[-1] : &:r2531_7, ~m? +# 2531| mu2531_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2531_7 +# 2529| v2529_1(void) = NoOp : +#-----| Goto -> Block 5 + +# 2531| Block 4 +# 2531| r2531_13(glval) = VariableAddress[y] : +# 2531| r2531_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2531| v2531_15(void) = Call[~ClassWithDestructor] : func:r2531_14, this:r2531_13 +# 2531| mu2531_16(unknown) = ^CallSideEffect : ~m? +# 2531| v2531_17(void) = ^IndirectReadSideEffect[-1] : &:r2531_13, ~m? +# 2531| mu2531_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2531_13 +#-----| Goto -> Block 5 + +# 2531| Block 5 +# 2531| v2531_19(void) = NoOp : +# 2532| v2532_1(void) = NoOp : +# 2522| v2522_6(void) = ReturnVoid : +# 2522| v2522_7(void) = AliasedUse : ~m? +# 2522| v2522_8(void) = ExitFunction : + +# 2534| void destructor_possibly_not_handled() +# 2534| Block 0 +# 2534| v2534_1(void) = EnterFunction : +# 2534| mu2534_2(unknown) = AliasedDefinition : +# 2534| mu2534_3(unknown) = InitializeNonLocal : +# 2535| r2535_1(glval) = VariableAddress[x] : +# 2535| mu2535_2(ClassWithDestructor) = Uninitialized[x] : &:r2535_1 +# 2535| r2535_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2535| v2535_4(void) = Call[ClassWithDestructor] : func:r2535_3, this:r2535_1 +# 2535| mu2535_5(unknown) = ^CallSideEffect : ~m? +# 2535| mu2535_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2535_1 +# 2537| r2537_1(glval) = VariableAddress[#throw2537:5] : +# 2537| r2537_2(int) = Constant[42] : +# 2537| mu2537_3(int) = Store[#throw2537:5] : &:r2537_1, r2537_2 +# 2537| v2537_4(void) = ThrowValue : &:r2537_1, ~m? #-----| Exception -> Block 3 -# 2450| Block 1 -# 2450| v2450_6(void) = AliasedUse : ~m? -# 2450| v2450_7(void) = ExitFunction : +# 2534| Block 1 +# 2534| v2534_4(void) = AliasedUse : ~m? +# 2534| v2534_5(void) = ExitFunction : -# 2450| Block 2 -# 2450| v2450_8(void) = ReturnVoid : +# 2534| Block 2 +# 2534| v2534_6(void) = Unwind : #-----| Goto -> Block 1 -# 2450| Block 3 -# 2450| v2450_9(void) = Unwind : +# 2539| Block 3 +# 2539| v2539_1(void) = CatchByType[char] : +#-----| Exception -> Block 2 +#-----| Goto -> Block 4 + +# 2539| Block 4 +# 2539| r2539_2(glval) = VariableAddress[(unnamed parameter 0)] : +# 2539| mu2539_3(char) = InitializeParameter[(unnamed parameter 0)] : &:r2539_2 +# 2539| v2539_4(void) = NoOp : +# 2541| r2541_1(glval) = VariableAddress[x] : +# 2541| r2541_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2541| v2541_3(void) = Call[~ClassWithDestructor] : func:r2541_2, this:r2541_1 +# 2541| mu2541_4(unknown) = ^CallSideEffect : ~m? +# 2541| v2541_5(void) = ^IndirectReadSideEffect[-1] : &:r2541_1, ~m? +# 2541| mu2541_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2541_1 +# 2541| v2541_7(void) = NoOp : +# 2541| r2541_8(glval) = VariableAddress[x] : +# 2541| r2541_9(glval) = FunctionAddress[~ClassWithDestructor] : +# 2541| v2541_10(void) = Call[~ClassWithDestructor] : func:r2541_9, this:r2541_8 +# 2541| mu2541_11(unknown) = ^CallSideEffect : ~m? +# 2541| v2541_12(void) = ^IndirectReadSideEffect[-1] : &:r2541_8, ~m? +# 2541| mu2541_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2541_8 +# 2534| v2534_7(void) = ReturnVoid : #-----| Goto -> Block 1 -# 2459| void new_with_destructor(ClassWithDestructor) -# 2459| Block 0 -# 2459| v2459_1(void) = EnterFunction : -# 2459| mu2459_2(unknown) = AliasedDefinition : -# 2459| mu2459_3(unknown) = InitializeNonLocal : -# 2459| r2459_4(glval) = VariableAddress[a] : -# 2459| mu2459_5(ClassWithDestructor) = InitializeParameter[a] : &:r2459_4 -# 2461| r2461_1(glval) = VariableAddress[b] : -# 2461| r2461_2(glval) = FunctionAddress[operator new] : -# 2461| r2461_3(unsigned long) = Constant[1] : -# 2461| r2461_4(void *) = Call[operator new] : func:r2461_2, 0:r2461_3 -# 2461| mu2461_5(unknown) = ^CallSideEffect : ~m? -# 2461| mu2461_6(unknown) = ^InitializeDynamicAllocation : &:r2461_4 -# 2461| r2461_7(ByValueConstructor *) = Convert : r2461_4 -# 2461| r2461_8(glval) = FunctionAddress[ByValueConstructor] : -# 2461| r2461_9(glval) = VariableAddress[#temp2461:52] : -# 2461| r2461_10(glval) = VariableAddress[a] : -# 2461| r2461_11(ClassWithDestructor) = Load[a] : &:r2461_10, ~m? -# 2461| mu2461_12(ClassWithDestructor) = Store[#temp2461:52] : &:r2461_9, r2461_11 -# 2461| r2461_13(ClassWithDestructor) = Load[#temp2461:52] : &:r2461_9, ~m? -# 2461| v2461_14(void) = Call[ByValueConstructor] : func:r2461_8, this:r2461_7, 0:r2461_13 -# 2461| mu2461_15(unknown) = ^CallSideEffect : ~m? -# 2461| mu2461_16(ByValueConstructor) = ^IndirectMayWriteSideEffect[-1] : &:r2461_7 -# 2461| r2461_17(glval) = CopyValue : r2461_9 -# 2461| r2461_18(glval) = FunctionAddress[~ClassWithDestructor] : -# 2461| v2461_19(void) = Call[~ClassWithDestructor] : func:r2461_18, this:r2461_17 -# 2461| mu2461_20(unknown) = ^CallSideEffect : ~m? -# 2461| v2461_21(void) = ^IndirectReadSideEffect[-1] : &:r2461_17, ~m? -# 2461| mu2461_22(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2461_17 -# 2461| mu2461_23(ByValueConstructor *) = Store[b] : &:r2461_1, r2461_7 -# 2462| v2462_1(void) = NoOp : -# 2459| v2459_6(void) = ReturnVoid : -# 2459| v2459_7(void) = AliasedUse : ~m? -# 2459| v2459_8(void) = ExitFunction : - -# 2478| void rvalue_conversion_with_destructor::test() -# 2478| Block 0 -# 2478| v2478_1(void) = EnterFunction : -# 2478| mu2478_2(unknown) = AliasedDefinition : -# 2478| mu2478_3(unknown) = InitializeNonLocal : -# 2480| r2480_1(glval) = VariableAddress[a] : -# 2480| r2480_2(glval) = VariableAddress[#temp2480:18] : -# 2480| r2480_3(glval) = FunctionAddress[get] : -# 2480| r2480_4(B) = Call[get] : func:r2480_3 -# 2480| mu2480_5(unknown) = ^CallSideEffect : ~m? -# 2480| mu2480_6(B) = Store[#temp2480:18] : &:r2480_2, r2480_4 -# 2480| r2480_7(glval) = Convert : r2480_2 -# 2480| r2480_8(glval) = FunctionAddress[operator->] : -# 2480| r2480_9(A *) = Call[operator->] : func:r2480_8, this:r2480_7 -# 2480| mu2480_10(unknown) = ^CallSideEffect : ~m? -# 2480| v2480_11(void) = ^IndirectReadSideEffect[-1] : &:r2480_7, ~m? -# 2480| r2480_12(glval) = FieldAddress[a] : r2480_9 -# 2480| r2480_13(glval) = CopyValue : r2480_2 -# 2480| r2480_14(glval) = FunctionAddress[~B] : -# 2480| v2480_15(void) = Call[~B] : func:r2480_14, this:r2480_13 -# 2480| mu2480_16(unknown) = ^CallSideEffect : ~m? -# 2480| v2480_17(void) = ^IndirectReadSideEffect[-1] : &:r2480_13, ~m? -# 2480| mu2480_18(B) = ^IndirectMayWriteSideEffect[-1] : &:r2480_13 -# 2480| r2480_19(unsigned int) = Load[?] : &:r2480_12, ~m? -# 2480| mu2480_20(unsigned int) = Store[a] : &:r2480_1, r2480_19 -# 2481| v2481_1(void) = NoOp : -# 2478| v2478_4(void) = ReturnVoid : -# 2478| v2478_5(void) = AliasedUse : ~m? -# 2478| v2478_6(void) = ExitFunction : +# 2545| void this_inconsistency(bool) +# 2545| Block 0 +# 2545| v2545_1(void) = EnterFunction : +# 2545| mu2545_2(unknown) = AliasedDefinition : +# 2545| mu2545_3(unknown) = InitializeNonLocal : +# 2545| r2545_4(glval) = VariableAddress[b] : +# 2545| mu2545_5(bool) = InitializeParameter[b] : &:r2545_4 +# 2546| r2546_1(glval) = VariableAddress[a] : +# 2546| r2546_2(glval) = VariableAddress[#temp2546:38] : +# 2546| r2546_3(glval) = FunctionAddress[getClassWithDestructor] : +# 2546| r2546_4(ClassWithDestructor) = Call[getClassWithDestructor] : func:r2546_3 +# 2546| mu2546_5(unknown) = ^CallSideEffect : ~m? +# 2546| mu2546_6(ClassWithDestructor) = Store[#temp2546:38] : &:r2546_2, r2546_4 +# 2546| r2546_7(glval) = Convert : r2546_2 +# 2546| r2546_8(ClassWithDestructor &) = CopyValue : r2546_7 +# 2546| mu2546_9(ClassWithDestructor &) = Store[a] : &:r2546_1, r2546_8 +# 2546| r2546_10(glval) = VariableAddress[a] : +# 2546| r2546_11(ClassWithDestructor &) = Load[a] : &:r2546_10, ~m? +# 2546| r2546_12(ClassWithDestructor) = CopyValue : r2546_11 +# 2546| r2546_13(glval) = FunctionAddress[operator bool] : +# 2546| r2546_14(bool) = Call[operator bool] : func:r2546_13, this:r2546_12 +# 2546| mu2546_15(unknown) = ^CallSideEffect : ~m? +# 2546| v2546_16(void) = ^IndirectReadSideEffect[-1] : &:r2546_12, ~m? +# 2546| r2546_17(bool) = CopyValue : r2546_14 +# 2546| v2546_18(void) = ConditionalBranch : r2546_17 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 2547| Block 1 +# 2547| v2547_1(void) = NoOp : +# 2547| r2547_2(glval) = CopyValue : r2546_2 +# 2547| r2547_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2547| v2547_4(void) = Call[~ClassWithDestructor] : func:r2547_3, this:r2547_2 +# 2547| mu2547_5(unknown) = ^CallSideEffect : ~m? +# 2547| v2547_6(void) = ^IndirectReadSideEffect[-1] : &:r2547_2, ~m? +# 2547| mu2547_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2547_2 +#-----| Goto -> Block 2 + +# 2548| Block 2 +# 2548| v2548_1(void) = NoOp : +# 2545| v2545_6(void) = ReturnVoid : +# 2545| v2545_7(void) = AliasedUse : ~m? +# 2545| v2545_8(void) = ExitFunction : + +# 2550| void constexpr_inconsistency(bool) +# 2550| Block 0 +# 2550| v2550_1(void) = EnterFunction : +# 2550| mu2550_2(unknown) = AliasedDefinition : +# 2550| mu2550_3(unknown) = InitializeNonLocal : +# 2550| r2550_4(glval) = VariableAddress[b] : +# 2550| mu2550_5(bool) = InitializeParameter[b] : &:r2550_4 +# 2551| r2551_1(glval) = VariableAddress[a] : +# 2551| r2551_2(glval) = VariableAddress[#temp2551:48] : +# 2551| r2551_3(glval) = FunctionAddress[getClassWithDestructor] : +# 2551| r2551_4(ClassWithDestructor) = Call[getClassWithDestructor] : func:r2551_3 +# 2551| mu2551_5(unknown) = ^CallSideEffect : ~m? +# 2551| mu2551_6(ClassWithDestructor) = Store[#temp2551:48] : &:r2551_2, r2551_4 +# 2551| r2551_7(glval) = Convert : r2551_2 +# 2551| r2551_8(ClassWithDestructor &) = CopyValue : r2551_7 +# 2551| mu2551_9(ClassWithDestructor &) = Store[a] : &:r2551_1, r2551_8 +# 2551| r2551_10(bool) = Constant[1] : +# 2551| v2551_11(void) = ConditionalBranch : r2551_10 +#-----| False -> Block 3 +#-----| True -> Block 1 + +# 2552| Block 1 +# 2552| v2552_1(void) = NoOp : +#-----| Goto -> Block 3 + +# 2552| Block 2 +# 2552| r2552_2(glval) = CopyValue : r2551_2 +# 2552| r2552_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2552| v2552_4(void) = Call[~ClassWithDestructor] : func:r2552_3, this:r2552_2 +# 2552| mu2552_5(unknown) = ^CallSideEffect : ~m? +# 2552| v2552_6(void) = ^IndirectReadSideEffect[-1] : &:r2552_2, ~m? +# 2552| mu2552_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2552_2 +#-----| Goto -> Block 3 + +# 2553| Block 3 +# 2553| v2553_1(void) = NoOp : +# 2550| v2550_6(void) = ReturnVoid : +# 2550| v2550_7(void) = AliasedUse : ~m? +# 2550| v2550_8(void) = ExitFunction : perf-regression.cpp: # 6| void Big::Big() diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected index 8f472b49f273..5a0234a4cc42 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected @@ -27,6 +27,7 @@ invalidOverlap nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer +| ir.cpp:2546:34:2546:34 | Call: call to operator bool | Call instruction 'Call: call to operator bool' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:2545:6:2545:23 | void this_inconsistency(bool) | void this_inconsistency(bool) | nonUniqueIRVariable | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected index 8f472b49f273..5a0234a4cc42 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected @@ -27,6 +27,7 @@ invalidOverlap nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer +| ir.cpp:2546:34:2546:34 | Call: call to operator bool | Call instruction 'Call: call to operator bool' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:2545:6:2545:23 | void this_inconsistency(bool) | void this_inconsistency(bool) | nonUniqueIRVariable | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | diff --git a/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected index 2a8d7ad25bd5..c9fd8e3dbbe8 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected @@ -4,12 +4,6 @@ uniqueType uniqueNodeLocation missingLocation uniqueNodeToString -| builtin.c:5:5:5:11 | (no string representation) | Node should have one toString but has 0. | -| misc.c:227:7:227:28 | (no string representation) | Node should have one toString but has 0. | -| static_init_templates.cpp:80:18:80:23 | (no string representation) | Node should have one toString but has 0. | -| static_init_templates.cpp:80:18:80:23 | (no string representation) | Node should have one toString but has 0. | -| static_init_templates.cpp:89:18:89:23 | (no string representation) | Node should have one toString but has 0. | -| static_init_templates.cpp:89:18:89:23 | (no string representation) | Node should have one toString but has 0. | parameterCallable localFlowIsLocal readStepIsLocal diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected deleted file mode 100644 index 69c21b5e0b1d..000000000000 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected +++ /dev/null @@ -1,41 +0,0 @@ -WARNING: Type GVN has been deprecated and may be removed in future (ast_gvn.ql:4,6-9) -| test.cpp:5:3:5:3 | x | 5:c3-c3 6:c3-c3 | -| test.cpp:5:7:5:8 | p0 | 5:c7-c8 6:c7-c8 | -| test.cpp:5:7:5:13 | ... + ... | 5:c7-c13 6:c7-c13 7:c7-c7 | -| test.cpp:5:12:5:13 | p1 | 5:c12-c13 6:c12-c13 | -| test.cpp:16:3:16:3 | x | 16:c3-c3 17:c3-c3 | -| test.cpp:16:7:16:8 | p0 | 16:c7-c8 17:c7-c8 | -| test.cpp:16:7:16:13 | ... + ... | 16:c7-c13 17:c7-c13 | -| test.cpp:16:7:16:24 | ... + ... | 16:c7-c24 17:c7-c24 18:c7-c7 | -| test.cpp:16:12:16:13 | p1 | 16:c12-c13 17:c12-c13 | -| test.cpp:16:17:16:24 | global01 | 16:c17-c24 17:c17-c24 | -| test.cpp:29:7:29:8 | p0 | 29:c7-c8 31:c7-c8 | -| test.cpp:29:7:29:13 | ... + ... | 29:c7-c13 31:c7-c13 | -| test.cpp:29:12:29:13 | p1 | 29:c12-c13 31:c12-c13 | -| test.cpp:31:7:31:24 | ... + ... | 31:c7-c24 32:c7-c7 | -| test.cpp:43:7:43:8 | p0 | 43:c7-c8 45:c7-c8 | -| test.cpp:43:7:43:13 | ... + ... | 43:c7-c13 45:c7-c13 | -| test.cpp:43:12:43:13 | p1 | 43:c12-c13 45:c12-c13 | -| test.cpp:44:9:44:9 | 0 | 44:c9-c9 51:c25-c25 53:c18-c21 56:c39-c42 59:c17-c20 88:c12-c12 | -| test.cpp:45:7:45:24 | ... + ... | 45:c7-c24 46:c7-c7 | -| test.cpp:53:10:53:13 | (int)... | 53:c10-c13 56:c21-c24 | -| test.cpp:53:10:53:13 | * ... | 53:c10-c13 56:c21-c24 | -| test.cpp:53:11:53:13 | str | 53:c11-c13 56:c22-c24 | -| test.cpp:53:18:53:21 | 0 | 53:c18-c21 56:c39-c42 59:c17-c20 | -| test.cpp:56:13:56:16 | (int)... | 56:c13-c16 56:c31-c34 59:c9-c12 | -| test.cpp:56:13:56:16 | * ... | 56:c13-c16 56:c31-c34 59:c9-c12 | -| test.cpp:56:14:56:16 | ptr | 56:c14-c16 56:c32-c34 56:c47-c49 59:c10-c12 | -| test.cpp:62:5:62:10 | result | 62:c5-c10 65:c10-c15 | -| test.cpp:77:20:77:30 | (signed short)... | 77:c20-c30 79:c7-c7 | -| test.cpp:79:11:79:14 | vals | 79:c11-c14 79:c24-c27 | -| test.cpp:105:11:105:12 | (Base *)... | 105:c11-c12 106:c14-c35 107:c11-c12 | -| test.cpp:105:11:105:12 | pd | 105:c11-c12 106:c33-c34 | -| test.cpp:105:15:105:15 | b | 105:c15-c15 107:c15-c15 109:c10-c10 | -| test.cpp:125:11:125:12 | pa | 125:c11-c12 126:c11-c12 128:c3-c4 129:c11-c12 | -| test.cpp:125:15:125:15 | x | 125:c15-c15 126:c15-c15 128:c7-c7 | -| test.cpp:136:11:136:18 | global_a | 136:c11-c18 137:c11-c18 139:c3-c10 | -| test.cpp:136:21:136:21 | x | 136:c21-c21 137:c21-c21 139:c13-c13 | -| test.cpp:144:11:144:12 | pa | 144:c11-c12 145:c11-c12 147:c3-c4 149:c11-c12 | -| test.cpp:145:15:145:15 | y | 145:c15-c15 147:c7-c7 | -| test.cpp:153:11:153:18 | global_a | 153:c11-c18 154:c11-c18 156:c3-c10 | -| test.cpp:153:21:153:21 | x | 153:c21-c21 154:c21-c21 | diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.ql b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.ql deleted file mode 100644 index 84d0a7b3672d..000000000000 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.ql +++ /dev/null @@ -1,11 +0,0 @@ -import cpp -import semmle.code.cpp.valuenumbering.GlobalValueNumberingImpl - -from GVN g -where strictcount(g.getAnExpr()) > 1 -select g, - strictconcat(Location loc | - loc = g.getAnExpr().getLocation() - | - loc.getStartLine() + ":c" + loc.getStartColumn() + "-c" + loc.getEndColumn(), " " - ) diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected deleted file mode 100644 index d94d58ad5eac..000000000000 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected +++ /dev/null @@ -1,3 +0,0 @@ -WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (ast_uniqueness.ql:7,13-30) -WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (ast_uniqueness.ql:8,30-47) -WARNING: Type GVN has been deprecated and may be removed in future (ast_uniqueness.ql:8,18-21) diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.ql b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.ql deleted file mode 100644 index bc6dbf94bf7c..000000000000 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.ql +++ /dev/null @@ -1,8 +0,0 @@ -import cpp -import semmle.code.cpp.valuenumbering.GlobalValueNumberingImpl - -// Every expression should have exactly one GVN. -// So this query should have zero results. -from Expr e -where count(globalValueNumber(e)) != 1 -select e, concat(GVN g | g = globalValueNumber(e) | g.getKind(), ", ") diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected deleted file mode 100644 index 810c83f197f9..000000000000 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected +++ /dev/null @@ -1,130 +0,0 @@ -WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (diff_ir_expr.ql:8,29-51) -| test.cpp:5:3:5:13 | ... = ... | test.cpp:5:3:5:13 | ... = ... | AST only | -| test.cpp:6:3:6:13 | ... = ... | test.cpp:6:3:6:13 | ... = ... | AST only | -| test.cpp:7:3:7:7 | ... = ... | test.cpp:7:3:7:7 | ... = ... | AST only | -| test.cpp:16:3:16:24 | ... = ... | test.cpp:16:3:16:24 | ... = ... | AST only | -| test.cpp:17:3:17:24 | ... = ... | test.cpp:17:3:17:24 | ... = ... | AST only | -| test.cpp:18:3:18:7 | ... = ... | test.cpp:18:3:18:7 | ... = ... | AST only | -| test.cpp:29:3:29:3 | x | test.cpp:31:3:31:3 | x | IR only | -| test.cpp:29:3:29:24 | ... = ... | test.cpp:29:3:29:24 | ... = ... | AST only | -| test.cpp:30:3:30:17 | call to change_global02 | test.cpp:30:3:30:17 | call to change_global02 | AST only | -| test.cpp:31:3:31:3 | x | test.cpp:29:3:29:3 | x | IR only | -| test.cpp:31:3:31:24 | ... = ... | test.cpp:31:3:31:24 | ... = ... | AST only | -| test.cpp:32:3:32:7 | ... = ... | test.cpp:32:3:32:7 | ... = ... | AST only | -| test.cpp:43:3:43:3 | x | test.cpp:45:3:45:3 | x | IR only | -| test.cpp:43:3:43:24 | ... = ... | test.cpp:43:3:43:24 | ... = ... | AST only | -| test.cpp:43:7:43:24 | ... + ... | test.cpp:45:7:45:24 | ... + ... | IR only | -| test.cpp:43:7:43:24 | ... + ... | test.cpp:46:7:46:7 | x | IR only | -| test.cpp:43:17:43:24 | global03 | test.cpp:45:17:45:24 | global03 | IR only | -| test.cpp:44:3:44:5 | * ... | test.cpp:44:4:44:5 | p2 | IR only | -| test.cpp:44:3:44:9 | ... = ... | test.cpp:44:3:44:9 | ... = ... | AST only | -| test.cpp:44:4:44:5 | p2 | test.cpp:44:3:44:5 | * ... | IR only | -| test.cpp:44:9:44:9 | 0 | test.cpp:51:25:51:25 | 0 | AST only | -| test.cpp:44:9:44:9 | 0 | test.cpp:53:18:53:21 | (int)... | AST only | -| test.cpp:44:9:44:9 | 0 | test.cpp:56:39:56:42 | (int)... | AST only | -| test.cpp:44:9:44:9 | 0 | test.cpp:59:17:59:20 | (int)... | AST only | -| test.cpp:44:9:44:9 | 0 | test.cpp:88:12:88:12 | 0 | AST only | -| test.cpp:45:3:45:3 | x | test.cpp:43:3:43:3 | x | IR only | -| test.cpp:45:3:45:24 | ... = ... | test.cpp:45:3:45:24 | ... = ... | AST only | -| test.cpp:45:7:45:24 | ... + ... | test.cpp:43:7:43:24 | ... + ... | IR only | -| test.cpp:45:17:45:24 | global03 | test.cpp:43:17:43:24 | global03 | IR only | -| test.cpp:46:3:46:7 | ... = ... | test.cpp:46:3:46:7 | ... = ... | AST only | -| test.cpp:46:7:46:7 | x | test.cpp:43:7:43:24 | ... + ... | IR only | -| test.cpp:51:25:51:25 | 0 | test.cpp:44:9:44:9 | 0 | AST only | -| test.cpp:51:25:51:25 | 0 | test.cpp:53:18:53:21 | (int)... | AST only | -| test.cpp:51:25:51:25 | 0 | test.cpp:56:39:56:42 | (int)... | AST only | -| test.cpp:51:25:51:25 | 0 | test.cpp:59:17:59:20 | (int)... | AST only | -| test.cpp:51:25:51:25 | 0 | test.cpp:88:12:88:12 | 0 | AST only | -| test.cpp:51:25:51:25 | (unsigned int)... | test.cpp:51:25:51:25 | (unsigned int)... | AST only | -| test.cpp:53:10:53:13 | (int)... | test.cpp:53:10:53:13 | (int)... | AST only | -| test.cpp:53:10:53:13 | (int)... | test.cpp:56:21:56:24 | (int)... | AST only | -| test.cpp:53:18:53:21 | (int)... | test.cpp:44:9:44:9 | 0 | AST only | -| test.cpp:53:18:53:21 | (int)... | test.cpp:51:25:51:25 | 0 | AST only | -| test.cpp:53:18:53:21 | (int)... | test.cpp:53:18:53:21 | (int)... | AST only | -| test.cpp:53:18:53:21 | (int)... | test.cpp:56:39:56:42 | (int)... | AST only | -| test.cpp:53:18:53:21 | (int)... | test.cpp:59:17:59:20 | (int)... | AST only | -| test.cpp:53:18:53:21 | (int)... | test.cpp:88:12:88:12 | 0 | AST only | -| test.cpp:55:5:55:15 | ... = ... | test.cpp:55:5:55:15 | ... = ... | AST only | -| test.cpp:56:12:56:25 | (...) | test.cpp:56:12:56:25 | (...) | AST only | -| test.cpp:56:12:56:43 | ... && ... | test.cpp:56:12:56:43 | ... && ... | AST only | -| test.cpp:56:13:56:16 | (int)... | test.cpp:56:13:56:16 | (int)... | AST only | -| test.cpp:56:13:56:16 | (int)... | test.cpp:56:31:56:34 | (int)... | AST only | -| test.cpp:56:13:56:16 | (int)... | test.cpp:59:9:59:12 | (int)... | AST only | -| test.cpp:56:21:56:24 | (int)... | test.cpp:53:10:53:13 | (int)... | AST only | -| test.cpp:56:21:56:24 | (int)... | test.cpp:56:21:56:24 | (int)... | AST only | -| test.cpp:56:30:56:43 | (...) | test.cpp:56:30:56:43 | (...) | AST only | -| test.cpp:56:31:56:34 | (int)... | test.cpp:56:13:56:16 | (int)... | AST only | -| test.cpp:56:31:56:34 | (int)... | test.cpp:56:31:56:34 | (int)... | AST only | -| test.cpp:56:31:56:34 | (int)... | test.cpp:59:9:59:12 | (int)... | AST only | -| test.cpp:56:39:56:42 | (int)... | test.cpp:44:9:44:9 | 0 | AST only | -| test.cpp:56:39:56:42 | (int)... | test.cpp:51:25:51:25 | 0 | AST only | -| test.cpp:56:39:56:42 | (int)... | test.cpp:53:18:53:21 | (int)... | AST only | -| test.cpp:56:39:56:42 | (int)... | test.cpp:56:39:56:42 | (int)... | AST only | -| test.cpp:56:39:56:42 | (int)... | test.cpp:59:17:59:20 | (int)... | AST only | -| test.cpp:56:39:56:42 | (int)... | test.cpp:88:12:88:12 | 0 | AST only | -| test.cpp:56:47:56:51 | ... ++ | test.cpp:56:47:56:51 | ... ++ | AST only | -| test.cpp:59:9:59:12 | (int)... | test.cpp:56:13:56:16 | (int)... | AST only | -| test.cpp:59:9:59:12 | (int)... | test.cpp:56:31:56:34 | (int)... | AST only | -| test.cpp:59:9:59:12 | (int)... | test.cpp:59:9:59:12 | (int)... | AST only | -| test.cpp:59:17:59:20 | (int)... | test.cpp:44:9:44:9 | 0 | AST only | -| test.cpp:59:17:59:20 | (int)... | test.cpp:51:25:51:25 | 0 | AST only | -| test.cpp:59:17:59:20 | (int)... | test.cpp:53:18:53:21 | (int)... | AST only | -| test.cpp:59:17:59:20 | (int)... | test.cpp:56:39:56:42 | (int)... | AST only | -| test.cpp:59:17:59:20 | (int)... | test.cpp:59:17:59:20 | (int)... | AST only | -| test.cpp:59:17:59:20 | (int)... | test.cpp:88:12:88:12 | 0 | AST only | -| test.cpp:62:5:62:12 | ... ++ | test.cpp:62:5:62:12 | ... ++ | AST only | -| test.cpp:77:20:77:28 | call to getAValue | test.cpp:79:7:79:7 | v | IR only | -| test.cpp:77:20:77:30 | (signed short)... | test.cpp:77:20:77:30 | (signed short)... | AST only | -| test.cpp:77:20:77:30 | (signed short)... | test.cpp:79:7:79:7 | v | AST only | -| test.cpp:79:7:79:7 | (int)... | test.cpp:79:7:79:7 | (int)... | AST only | -| test.cpp:79:7:79:7 | v | test.cpp:77:20:77:28 | call to getAValue | IR only | -| test.cpp:79:7:79:7 | v | test.cpp:77:20:77:30 | (signed short)... | AST only | -| test.cpp:79:11:79:20 | (int)... | test.cpp:79:11:79:20 | (int)... | AST only | -| test.cpp:79:24:79:33 | (int)... | test.cpp:79:24:79:33 | (int)... | AST only | -| test.cpp:80:5:80:19 | ... = ... | test.cpp:80:5:80:19 | ... = ... | AST only | -| test.cpp:80:9:80:19 | (signed short)... | test.cpp:80:9:80:19 | (signed short)... | AST only | -| test.cpp:88:3:88:20 | ... = ... | test.cpp:88:3:88:20 | ... = ... | AST only | -| test.cpp:88:12:88:12 | 0 | test.cpp:44:9:44:9 | 0 | AST only | -| test.cpp:88:12:88:12 | 0 | test.cpp:51:25:51:25 | 0 | AST only | -| test.cpp:88:12:88:12 | 0 | test.cpp:53:18:53:21 | (int)... | AST only | -| test.cpp:88:12:88:12 | 0 | test.cpp:56:39:56:42 | (int)... | AST only | -| test.cpp:88:12:88:12 | 0 | test.cpp:59:17:59:20 | (int)... | AST only | -| test.cpp:88:12:88:12 | (void *)... | test.cpp:88:12:88:12 | (void *)... | AST only | -| test.cpp:92:11:92:16 | ... = ... | test.cpp:92:15:92:16 | 10 | IR only | -| test.cpp:92:11:92:16 | ... = ... | test.cpp:93:10:93:10 | x | IR only | -| test.cpp:92:15:92:16 | 10 | test.cpp:92:11:92:16 | ... = ... | IR only | -| test.cpp:92:15:92:16 | 10 | test.cpp:93:10:93:10 | x | IR only | -| test.cpp:93:10:93:10 | x | test.cpp:92:11:92:16 | ... = ... | IR only | -| test.cpp:93:10:93:10 | x | test.cpp:92:15:92:16 | 10 | IR only | -| test.cpp:105:11:105:12 | (Base *)... | test.cpp:105:11:105:12 | (Base *)... | AST only | -| test.cpp:105:11:105:12 | (Base *)... | test.cpp:106:14:106:35 | static_cast... | AST only | -| test.cpp:105:11:105:12 | (Base *)... | test.cpp:107:11:107:12 | pb | AST only | -| test.cpp:105:11:105:12 | pd | test.cpp:107:11:107:12 | pb | IR only | -| test.cpp:106:14:106:35 | static_cast... | test.cpp:105:11:105:12 | (Base *)... | AST only | -| test.cpp:106:14:106:35 | static_cast... | test.cpp:106:14:106:35 | static_cast... | AST only | -| test.cpp:106:14:106:35 | static_cast... | test.cpp:107:11:107:12 | pb | AST only | -| test.cpp:106:33:106:34 | pd | test.cpp:107:11:107:12 | pb | IR only | -| test.cpp:107:11:107:12 | pb | test.cpp:105:11:105:12 | (Base *)... | AST only | -| test.cpp:107:11:107:12 | pb | test.cpp:105:11:105:12 | pd | IR only | -| test.cpp:107:11:107:12 | pb | test.cpp:106:14:106:35 | static_cast... | AST only | -| test.cpp:107:11:107:12 | pb | test.cpp:106:33:106:34 | pd | IR only | -| test.cpp:113:3:113:5 | a | test.cpp:115:3:115:5 | a | IR only | -| test.cpp:115:3:115:5 | a | test.cpp:113:3:113:5 | a | IR only | -| test.cpp:125:15:125:15 | x | test.cpp:128:7:128:7 | x | AST only | -| test.cpp:126:15:126:15 | x | test.cpp:128:7:128:7 | x | AST only | -| test.cpp:128:3:128:11 | ... = ... | test.cpp:128:3:128:11 | ... = ... | AST only | -| test.cpp:128:7:128:7 | x | test.cpp:125:15:125:15 | x | AST only | -| test.cpp:128:7:128:7 | x | test.cpp:126:15:126:15 | x | AST only | -| test.cpp:128:11:128:11 | n | test.cpp:129:15:129:15 | x | IR only | -| test.cpp:129:15:129:15 | x | test.cpp:128:11:128:11 | n | IR only | -| test.cpp:136:21:136:21 | x | test.cpp:139:13:139:13 | x | AST only | -| test.cpp:137:21:137:21 | x | test.cpp:139:13:139:13 | x | AST only | -| test.cpp:139:3:139:24 | ... = ... | test.cpp:139:3:139:24 | ... = ... | AST only | -| test.cpp:139:13:139:13 | x | test.cpp:136:21:136:21 | x | AST only | -| test.cpp:139:13:139:13 | x | test.cpp:137:21:137:21 | x | AST only | -| test.cpp:144:15:144:15 | x | test.cpp:149:15:149:15 | x | IR only | -| test.cpp:145:15:145:15 | y | test.cpp:147:7:147:7 | y | AST only | -| test.cpp:147:3:147:18 | ... = ... | test.cpp:147:3:147:18 | ... = ... | AST only | -| test.cpp:147:7:147:7 | y | test.cpp:145:15:145:15 | y | AST only | -| test.cpp:149:15:149:15 | x | test.cpp:144:15:144:15 | x | IR only | -| test.cpp:156:3:156:17 | ... = ... | test.cpp:156:3:156:17 | ... = ... | AST only | diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.ql b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.ql deleted file mode 100644 index 7b897f39dbd9..000000000000 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.ql +++ /dev/null @@ -1,15 +0,0 @@ -import cpp -import semmle.code.cpp.valuenumbering.GlobalValueNumberingImpl as AST -import semmle.code.cpp.ir.internal.ASTValueNumbering as IR -import semmle.code.cpp.ir.IR - -Expr ir(Expr e) { result = IR::globalValueNumber(e).getAnExpr() } - -Expr ast(Expr e) { result = AST::globalValueNumber(e).getAnExpr() } - -from Expr e, Expr evn, string note -where - evn = ast(e) and not evn = ir(e) and note = "AST only" - or - evn = ir(e) and not evn = ast(e) and note = "IR only" -select e, evn, note diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected index 46e30cedf3e3..87b5ee6c4abd 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected @@ -26,6 +26,8 @@ | test.cpp:128:15:128:16 | v4 | | test.cpp:185:10:185:12 | cpy | | test.cpp:199:10:199:12 | cpy | +| test.cpp:208:7:208:7 | a | +| test.cpp:214:7:214:7 | a | | test_free.cpp:11:10:11:10 | a | | test_free.cpp:14:10:14:10 | a | | test_free.cpp:16:10:16:10 | a | diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected index 7625783731a3..9df8e932bfc2 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected @@ -1,4 +1,6 @@ edges +| test.cpp:208:7:208:7 | pointer to free output argument | test.cpp:209:2:209:2 | a | provenance | | +| test.cpp:214:7:214:7 | pointer to free output argument | test.cpp:215:2:215:2 | a | provenance | | | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:12:5:12:5 | a | provenance | | | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:13:5:13:6 | * ... | provenance | | | test_free.cpp:42:27:42:27 | pointer to free output argument | test_free.cpp:45:5:45:5 | a | provenance | | @@ -31,6 +33,10 @@ edges | test_free.cpp:322:12:322:12 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | provenance | | | test_free.cpp:331:12:331:12 | pointer to operator delete output argument | test_free.cpp:332:5:332:6 | * ... | provenance | | nodes +| test.cpp:208:7:208:7 | pointer to free output argument | semmle.label | pointer to free output argument | +| test.cpp:209:2:209:2 | a | semmle.label | a | +| test.cpp:214:7:214:7 | pointer to free output argument | semmle.label | pointer to free output argument | +| test.cpp:215:2:215:2 | a | semmle.label | a | | test_free.cpp:11:10:11:10 | pointer to free output argument | semmle.label | pointer to free output argument | | test_free.cpp:12:5:12:5 | a | semmle.label | a | | test_free.cpp:13:5:13:6 | * ... | semmle.label | * ... | @@ -82,6 +88,8 @@ nodes | test_free.cpp:332:5:332:6 | * ... | semmle.label | * ... | subpaths #select +| test.cpp:209:2:209:2 | a | test.cpp:208:7:208:7 | pointer to free output argument | test.cpp:209:2:209:2 | a | Memory may have been previously freed by $@. | test.cpp:208:2:208:5 | call to free | call to free | +| test.cpp:215:2:215:2 | a | test.cpp:214:7:214:7 | pointer to free output argument | test.cpp:215:2:215:2 | a | Memory may have been previously freed by $@. | test.cpp:214:2:214:5 | call to free | call to free | | test_free.cpp:12:5:12:5 | a | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:12:5:12:5 | a | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free | | test_free.cpp:13:5:13:6 | * ... | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:13:5:13:6 | * ... | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free | | test_free.cpp:45:5:45:5 | a | test_free.cpp:42:27:42:27 | pointer to free output argument | test_free.cpp:45:5:45:5 | a | Memory may have been previously freed by $@. | test_free.cpp:42:22:42:25 | call to free | call to free | diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp b/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp index 4f05f9d49545..c8d21115f3fe 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp @@ -114,7 +114,7 @@ int main() mc2->method2(); delete mc2; } - + { void *v1 = malloc(100); int *i2 = (int *)malloc(100); @@ -198,3 +198,19 @@ void test_strndupa_dealloc() { char *cpy = strndupa(msg, 4); free(cpy); // BAD [NOT DETECTED] } + +// --- + +void test_reassignment() { + char *a = (char *)malloc(128); + char *b = (char *)malloc(128); + + free(a); + a[0] = 0; // BAD + + a = b; + a[0] = 0; // GOOD + + free(a); + a[0] = 0; // BAD +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.cpp b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.cpp index 90c21ca90f3b..ac3f1ab3ed5c 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.cpp @@ -3,7 +3,7 @@ void C6317_positive(int i) { - if (i & !FLAGS) // BUG + if (i & !FLAGS) // BUG { } } @@ -71,3 +71,22 @@ void macroUsage(unsigned int arg1, unsigned int arg2) } } + +void bool_examples(bool a, bool b) +{ + if (a & !b) // dubious (confusing intent, but shouldn't produce a wrong result) + { + } + + if (a & ~b) + { + } + + if (a && ~b) + { + } + + if (a && !b) + { + } +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.expected b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.expected index a5bbea858da3..9c6d4154bf5e 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.expected @@ -14,3 +14,4 @@ | IncorrectNotOperatorUsage.cpp:48:9:48:18 | ... \| ... | Usage of a logical not (!) expression as a bitwise operator. | | IncorrectNotOperatorUsage.cpp:49:9:49:20 | ... \| ... | Usage of a logical not (!) expression as a bitwise operator. | | IncorrectNotOperatorUsage.cpp:70:10:70:34 | ... \| ... | Usage of a logical not (!) expression as a bitwise operator. | +| IncorrectNotOperatorUsage.cpp:77:9:77:14 | ... & ... | Usage of a logical not (!) expression as a bitwise operator. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected index 1a1bf6081e21..f8b96c81b1eb 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected @@ -1,11 +1,16 @@ edges | test.c:8:27:8:30 | **argv | test.c:9:23:9:29 | *access to array | provenance | | | test.c:8:27:8:30 | **argv | test.c:31:22:31:28 | *access to array | provenance | | -| test.c:8:27:8:30 | **argv | test.c:57:10:57:16 | *access to array | provenance | | +| test.c:8:27:8:30 | **argv | test.c:69:14:69:20 | *access to array | provenance | | | test.c:9:23:9:29 | *access to array | test.c:17:11:17:18 | *fileName | provenance | TaintFunction | | test.c:31:22:31:28 | *access to array | test.c:32:11:32:18 | *fileName | provenance | | | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | *fileName | provenance | | | test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | *fileName | provenance | | +| test.c:48:21:48:26 | *call to getenv | test.c:48:21:48:26 | *call to getenv | provenance | | +| test.c:48:21:48:26 | *call to getenv | test.c:49:11:49:17 | *tainted | provenance | | +| test.c:54:21:54:26 | *call to getenv | test.c:55:11:55:16 | *buffer | provenance | TaintFunction | +| test.c:74:13:74:18 | read output argument | test.c:76:11:76:16 | *buffer | provenance | | +| test.c:75:13:75:18 | read output argument | test.c:76:11:76:16 | *buffer | provenance | | nodes | test.c:8:27:8:30 | **argv | semmle.label | **argv | | test.c:9:23:9:29 | *access to array | semmle.label | *access to array | @@ -16,11 +21,23 @@ nodes | test.c:38:11:38:18 | *fileName | semmle.label | *fileName | | test.c:43:17:43:24 | scanf output argument | semmle.label | scanf output argument | | test.c:44:11:44:18 | *fileName | semmle.label | *fileName | -| test.c:57:10:57:16 | *access to array | semmle.label | *access to array | +| test.c:48:21:48:26 | *call to getenv | semmle.label | *call to getenv | +| test.c:48:21:48:26 | *call to getenv | semmle.label | *call to getenv | +| test.c:49:11:49:17 | *tainted | semmle.label | *tainted | +| test.c:54:21:54:26 | *call to getenv | semmle.label | *call to getenv | +| test.c:55:11:55:16 | *buffer | semmle.label | *buffer | +| test.c:69:14:69:20 | *access to array | semmle.label | *access to array | +| test.c:74:13:74:18 | read output argument | semmle.label | read output argument | +| test.c:75:13:75:18 | read output argument | semmle.label | read output argument | +| test.c:76:11:76:16 | *buffer | semmle.label | *buffer | subpaths #select | test.c:17:11:17:18 | fileName | test.c:8:27:8:30 | **argv | test.c:17:11:17:18 | *fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | **argv | user input (a command-line argument) | | test.c:32:11:32:18 | fileName | test.c:8:27:8:30 | **argv | test.c:32:11:32:18 | *fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | **argv | user input (a command-line argument) | | test.c:38:11:38:18 | fileName | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | *fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:37:17:37:24 | scanf output argument | user input (value read by scanf) | | test.c:44:11:44:18 | fileName | test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | *fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:43:17:43:24 | scanf output argument | user input (value read by scanf) | -| test.c:57:10:57:16 | access to array | test.c:8:27:8:30 | **argv | test.c:57:10:57:16 | *access to array | This argument to a file access function is derived from $@ and then passed to read(fileName), which calls fopen(filename). | test.c:8:27:8:30 | **argv | user input (a command-line argument) | +| test.c:49:11:49:17 | tainted | test.c:48:21:48:26 | *call to getenv | test.c:49:11:49:17 | *tainted | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:48:21:48:26 | *call to getenv | user input (an environment variable) | +| test.c:55:11:55:16 | buffer | test.c:54:21:54:26 | *call to getenv | test.c:55:11:55:16 | *buffer | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:54:21:54:26 | *call to getenv | user input (an environment variable) | +| test.c:69:14:69:20 | access to array | test.c:8:27:8:30 | **argv | test.c:69:14:69:20 | *access to array | This argument to a file access function is derived from $@ and then passed to readFile(fileName), which calls fopen(filename). | test.c:8:27:8:30 | **argv | user input (a command-line argument) | +| test.c:76:11:76:16 | buffer | test.c:74:13:74:18 | read output argument | test.c:76:11:76:16 | *buffer | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:74:13:74:18 | read output argument | user input (buffer read by read) | +| test.c:76:11:76:16 | buffer | test.c:75:13:75:18 | read output argument | test.c:76:11:76:16 | *buffer | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:75:13:75:18 | read output argument | user input (buffer read by read) | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/stdlib.h b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/stdlib.h index 5b6483480f73..53344da57d6d 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/stdlib.h +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/stdlib.h @@ -6,6 +6,7 @@ typedef struct {} FILE; #define FILENAME_MAX 1000 typedef unsigned long size_t; +typedef signed long ssize_t; FILE *fopen(const char *filename, const char *mode); int sprintf(char *s, const char *format, ...); @@ -15,3 +16,4 @@ int scanf(const char *format, ...); void *malloc(size_t size); double strtod(const char *ptr, char **endptr); char *getenv(const char *name); +ssize_t read(int fd, void *buffer, size_t count); diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/test.c b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/test.c index 824db8f16ada..4c4782758324 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/test.c +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/test.c @@ -7,7 +7,7 @@ int main(int argc, char** argv) { char *userAndFile = argv[2]; - + { char fileBuffer[FILENAME_MAX] = "/home/"; char *fileName = fileBuffer; @@ -44,6 +44,18 @@ int main(int argc, char** argv) { fopen(fileName, "wb+"); // BAD } + { + char *tainted = getenv("A_STRING"); + fopen(tainted, "wb+"); // BAD + } + + { + char buffer[1024]; + strncpy(buffer, getenv("A_STRING"), 1024); + fopen(buffer, "wb+"); // BAD + fopen(buffer, "wb+"); // (we don't want a duplicate result here) + } + { char *aNumber = getenv("A_NUMBER"); double number = strtod(aNumber, 0); @@ -53,11 +65,18 @@ int main(int argc, char** argv) { } { - void read(const char *fileName); - read(argv[1]); // BAD + void readFile(const char *fileName); + readFile(argv[1]); // BAD + } + + { + char buffer[1024]; + read(0, buffer, 1024); + read(0, buffer, 1024); + fopen(buffer, "wb+"); // BAD [duplicated with both sources] } } -void read(char *fileName) { +void readFile(char *fileName) { fopen(fileName, "wb+"); } diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected new file mode 100644 index 000000000000..126f1e8f4f76 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected @@ -0,0 +1,5 @@ +| test.cpp:680:30:680:30 | call to operator[] | This object is destroyed at the end of the full-expression. | +| test.cpp:683:31:683:32 | call to at | This object is destroyed at the end of the full-expression. | +| test.cpp:702:27:702:27 | call to operator[] | This object is destroyed at the end of the full-expression. | +| test.cpp:727:23:727:23 | call to operator[] | This object is destroyed at the end of the full-expression. | +| test.cpp:735:23:735:23 | call to operator[] | This object is destroyed at the end of the full-expression. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.qlref new file mode 100644 index 000000000000..fb2d78f87dfe --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-416/IteratorToExpiredContainer.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp similarity index 99% rename from cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/test.cpp rename to cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp index 85d9c4b57ad9..bab492796f3c 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp @@ -686,7 +686,7 @@ void test() { for (auto x : returnRef()[0]) {} // GOOD for (auto x : returnRef().at(0)) {} // GOOD - for(auto it = returnValue().begin(); it != returnValue().end(); ++it) {} // BAD + for(auto it = returnValue().begin(); it != returnValue().end(); ++it) {} // BAD [NOT DETECTED] { auto v = returnValue(); @@ -792,4 +792,13 @@ void test4() { // function we may end up in the destructor call `chunk.~A()`in `A.foo`. This destructor // call can flow to `begin` through the back-edge and cause a strange FP. auto zero = A().size(); +} + +void test5(int i) +{ + while(i < 10) { + const auto& vvs = returnValue(); + for(const auto& vs : vvs) { } + ++i; + } // GOOD } \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseOfStringAfterLifetimeEnds/UseOfStringAfterLifetimeEnds.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseOfStringAfterLifetimeEnds/UseOfStringAfterLifetimeEnds.expected index e6f64d57c994..1949ae5c3980 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseOfStringAfterLifetimeEnds/UseOfStringAfterLifetimeEnds.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseOfStringAfterLifetimeEnds/UseOfStringAfterLifetimeEnds.expected @@ -1,13 +1,13 @@ -| test.cpp:165:34:165:38 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:166:39:166:43 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:167:44:167:48 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:169:29:169:33 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:178:37:178:41 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:181:39:181:43 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:183:37:183:41 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:187:34:187:37 | call to data | The underlying string object is destroyed after the call to 'data' returns. | -| test.cpp:188:39:188:42 | call to data | The underlying string object is destroyed after the call to 'data' returns. | -| test.cpp:189:44:189:47 | call to data | The underlying string object is destroyed after the call to 'data' returns. | -| test.cpp:191:29:191:32 | call to data | The underlying string object is destroyed after the call to 'data' returns. | -| test.cpp:193:47:193:51 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:195:31:195:35 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | +| test.cpp:165:34:165:38 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:166:39:166:43 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:167:44:167:48 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:169:29:169:33 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:178:37:178:41 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:181:39:181:43 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:183:37:183:41 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:187:34:187:37 | call to data | The underlying temporary string object is destroyed after the call to 'data' returns. | +| test.cpp:188:39:188:42 | call to data | The underlying temporary string object is destroyed after the call to 'data' returns. | +| test.cpp:189:44:189:47 | call to data | The underlying temporary string object is destroyed after the call to 'data' returns. | +| test.cpp:191:29:191:32 | call to data | The underlying temporary string object is destroyed after the call to 'data' returns. | +| test.cpp:193:47:193:51 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:195:31:195:35 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/LoopConditionsConst.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/LoopConditionsConst.expected index 01dbbaa2e652..07ca32b1718c 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/LoopConditionsConst.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/LoopConditionsConst.expected @@ -22,3 +22,4 @@ | test.cpp:416:2:418:2 | for(...;...;...) ... | test.cpp:416:18:416:23 | ... < ... | 1 | i | { ... } | i | return ... | | test.cpp:424:2:425:2 | for(...;...;...) ... | test.cpp:424:18:424:23 | ... < ... | 1 | i | { ... } | i | return ... | | test.cpp:433:2:434:2 | for(...;...;...) ... | test.cpp:433:18:433:22 | 0 | 0 | | { ... } | 0 | return ... | +| test.cpp:559:3:564:3 | while (...) ... | test.cpp:559:9:559:15 | call to getBool | | call to getBool | { ... } | call to getBool | ExprStmt | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected index d27b2c996b33..94d01d0e6c13 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected @@ -13,6 +13,7 @@ nodes | test.cpp:458:6:458:6 | definition of x | semmle.label | definition of x | | test.cpp:464:6:464:6 | definition of x | semmle.label | definition of x | | test.cpp:471:6:471:6 | definition of x | semmle.label | definition of x | +| test.cpp:557:15:557:15 | definition of r | semmle.label | definition of r | #select | test.cpp:12:6:12:8 | foo | test.cpp:11:6:11:8 | definition of foo | test.cpp:11:6:11:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:11:6:11:8 | foo | foo | | test.cpp:113:6:113:8 | foo | test.cpp:111:6:111:8 | definition of foo | test.cpp:111:6:111:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:111:6:111:8 | foo | foo | @@ -27,3 +28,4 @@ nodes | test.cpp:460:7:460:7 | x | test.cpp:458:6:458:6 | definition of x | test.cpp:458:6:458:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:458:6:458:6 | x | x | | test.cpp:467:2:467:2 | x | test.cpp:464:6:464:6 | definition of x | test.cpp:464:6:464:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:464:6:464:6 | x | x | | test.cpp:474:7:474:7 | x | test.cpp:471:6:471:6 | definition of x | test.cpp:471:6:471:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:471:6:471:6 | x | x | +| test.cpp:567:7:567:7 | r | test.cpp:557:15:557:15 | definition of r | test.cpp:557:15:557:15 | definition of r | The variable $@ may not be initialized at this access. | test.cpp:557:15:557:15 | r | r | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/test.cpp index e3489cee4cc3..4f56ab1259ab 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/test.cpp @@ -1,6 +1,6 @@ // Semmle test cases for rule CWE-457. -void use(int data); +void use(...); void test1() { int foo = 1; @@ -544,4 +544,25 @@ class StaticMethodClass{ int static_method_false_positive(){ StaticMethodClass *t; int i = t->get(); // GOOD: the `get` method is static and this is equivalent to StaticMethodClass::get() +} + +struct LinkedList +{ + LinkedList* next; +}; + +bool getBool(); + +void test45() { + LinkedList *r, *s, **rP = &r; + + while(getBool()) + { + s = new LinkedList; + *rP = s; + rP = &s->next; + } + + *rP = NULL; + use(r); // GOOD [FALSE POSITIVE] } \ No newline at end of file diff --git a/cpp/ql/test/successor-tests/stackvariables/stackvariables/graphable.expected b/cpp/ql/test/successor-tests/stackvariables/stackvariables/graphable.expected index c4e250d591f8..e90d571bce4a 100644 --- a/cpp/ql/test/successor-tests/stackvariables/stackvariables/graphable.expected +++ b/cpp/ql/test/successor-tests/stackvariables/stackvariables/graphable.expected @@ -41,99 +41,99 @@ | BoxedInt::~BoxedInt | true | 481 | 483 | | | BoxedInt::~BoxedInt | true | 483 | 222 | | | BoxedInt::~BoxedInt | true | 485 | 474 | | -| NonTrivial::NonTrivial | false | 543 | 543 | NonTrivial | -| NonTrivial::operator= | false | 549 | 549 | operator= | -| NonTrivial::~NonTrivial | false | 557 | 557 | ~NonTrivial | -| NonTrivial::~NonTrivial | false | 563 | 563 | return ... | -| NonTrivial::~NonTrivial | false | 565 | 565 | { ... } | -| NonTrivial::~NonTrivial | true | 563 | 557 | | -| NonTrivial::~NonTrivial | true | 565 | 563 | | +| NonTrivial::NonTrivial | false | 544 | 544 | NonTrivial | +| NonTrivial::operator= | false | 550 | 550 | operator= | +| NonTrivial::~NonTrivial | false | 558 | 558 | ~NonTrivial | +| NonTrivial::~NonTrivial | false | 564 | 564 | return ... | +| NonTrivial::~NonTrivial | false | 566 | 566 | { ... } | +| NonTrivial::~NonTrivial | true | 564 | 558 | | +| NonTrivial::~NonTrivial | true | 566 | 564 | | | __va_list_tag::operator= | false | 66 | 66 | operator= | | __va_list_tag::operator= | false | 72 | 72 | operator= | -| early_return | false | 799 | 799 | early_return | -| early_return | false | 807 | 807 | declaration | -| early_return | false | 812 | 812 | if (...) ... | -| early_return | false | 814 | 814 | x | -| early_return | false | 816 | 816 | (bool)... | -| early_return | false | 820 | 820 | declaration | -| early_return | false | 822 | 822 | return ... | -| early_return | false | 824 | 824 | { ... } | -| early_return | false | 826 | 826 | declaration | -| early_return | false | 831 | 831 | return ... | -| early_return | false | 833 | 833 | { ... } | -| early_return | false | 835 | 835 | inner | -| early_return | false | 837 | 837 | call to inner.~NonTrivial | -| early_return | false | 838 | 838 | before | -| early_return | false | 840 | 840 | call to before.~NonTrivial | -| early_return | false | 841 | 841 | inner | -| early_return | false | 842 | 842 | call to inner.~NonTrivial | -| early_return | false | 843 | 843 | before | -| early_return | false | 844 | 844 | call to before.~NonTrivial | -| early_return | false | 845 | 845 | after | -| early_return | false | 846 | 846 | call to after.~NonTrivial | -| early_return | true | 807 | 812 | | -| early_return | true | 812 | 814 | | -| early_return | true | 814 | 824 | T | -| early_return | true | 814 | 826 | F | -| early_return | true | 820 | 822 | | -| early_return | true | 822 | 841 | | -| early_return | true | 824 | 820 | | -| early_return | true | 826 | 831 | | -| early_return | true | 831 | 845 | | -| early_return | true | 833 | 807 | | -| early_return | true | 835 | 837 | | -| early_return | true | 837 | 826 | | -| early_return | true | 838 | 840 | | -| early_return | true | 840 | 799 | | -| early_return | true | 841 | 842 | | -| early_return | true | 842 | 838 | | -| early_return | true | 843 | 844 | | -| early_return | true | 844 | 799 | | -| early_return | true | 845 | 846 | | -| early_return | true | 846 | 843 | | -| early_throw | false | 749 | 749 | early_throw | -| early_throw | false | 757 | 757 | declaration | -| early_throw | false | 762 | 762 | if (...) ... | -| early_throw | false | 764 | 764 | x | -| early_throw | false | 766 | 766 | (bool)... | -| early_throw | false | 770 | 770 | declaration | -| early_throw | false | 772 | 772 | ExprStmt | -| early_throw | false | 774 | 774 | re-throw exception | -| early_throw | false | 776 | 776 | { ... } | -| early_throw | false | 778 | 778 | declaration | -| early_throw | false | 783 | 783 | return ... | -| early_throw | false | 785 | 785 | { ... } | -| early_throw | false | 787 | 787 | inner | -| early_throw | false | 789 | 789 | call to inner.~NonTrivial | -| early_throw | false | 790 | 790 | before | -| early_throw | false | 792 | 792 | call to before.~NonTrivial | -| early_throw | false | 793 | 793 | inner | -| early_throw | false | 794 | 794 | call to inner.~NonTrivial | -| early_throw | false | 795 | 795 | before | -| early_throw | false | 796 | 796 | call to before.~NonTrivial | -| early_throw | false | 797 | 797 | after | -| early_throw | false | 798 | 798 | call to after.~NonTrivial | -| early_throw | true | 757 | 762 | | -| early_throw | true | 762 | 764 | | -| early_throw | true | 764 | 776 | T | -| early_throw | true | 764 | 778 | F | -| early_throw | true | 770 | 772 | | -| early_throw | true | 772 | 774 | | -| early_throw | true | 774 | 793 | | -| early_throw | true | 776 | 770 | | -| early_throw | true | 778 | 783 | | -| early_throw | true | 783 | 797 | | -| early_throw | true | 785 | 757 | | -| early_throw | true | 787 | 789 | | -| early_throw | true | 789 | 778 | | -| early_throw | true | 790 | 792 | | -| early_throw | true | 792 | 749 | | -| early_throw | true | 793 | 794 | | -| early_throw | true | 794 | 790 | | -| early_throw | true | 795 | 796 | | -| early_throw | true | 796 | 749 | | -| early_throw | true | 797 | 798 | | -| early_throw | true | 798 | 795 | | +| early_return | false | 800 | 800 | early_return | +| early_return | false | 808 | 808 | declaration | +| early_return | false | 813 | 813 | if (...) ... | +| early_return | false | 815 | 815 | x | +| early_return | false | 817 | 817 | (bool)... | +| early_return | false | 821 | 821 | declaration | +| early_return | false | 823 | 823 | return ... | +| early_return | false | 825 | 825 | { ... } | +| early_return | false | 827 | 827 | declaration | +| early_return | false | 832 | 832 | return ... | +| early_return | false | 834 | 834 | { ... } | +| early_return | false | 836 | 836 | before | +| early_return | false | 838 | 838 | call to before.~NonTrivial | +| early_return | false | 839 | 839 | inner | +| early_return | false | 841 | 841 | call to inner.~NonTrivial | +| early_return | false | 842 | 842 | inner | +| early_return | false | 843 | 843 | call to inner.~NonTrivial | +| early_return | false | 844 | 844 | before | +| early_return | false | 845 | 845 | call to before.~NonTrivial | +| early_return | false | 846 | 846 | after | +| early_return | false | 847 | 847 | call to after.~NonTrivial | +| early_return | true | 808 | 813 | | +| early_return | true | 813 | 815 | | +| early_return | true | 815 | 825 | T | +| early_return | true | 815 | 827 | F | +| early_return | true | 821 | 823 | | +| early_return | true | 823 | 839 | | +| early_return | true | 825 | 821 | | +| early_return | true | 827 | 832 | | +| early_return | true | 832 | 846 | | +| early_return | true | 834 | 808 | | +| early_return | true | 836 | 838 | | +| early_return | true | 838 | 800 | | +| early_return | true | 839 | 841 | | +| early_return | true | 841 | 836 | | +| early_return | true | 842 | 843 | | +| early_return | true | 843 | 827 | | +| early_return | true | 844 | 845 | | +| early_return | true | 845 | 800 | | +| early_return | true | 846 | 847 | | +| early_return | true | 847 | 844 | | +| early_throw | false | 750 | 750 | early_throw | +| early_throw | false | 758 | 758 | declaration | +| early_throw | false | 763 | 763 | if (...) ... | +| early_throw | false | 765 | 765 | x | +| early_throw | false | 767 | 767 | (bool)... | +| early_throw | false | 771 | 771 | declaration | +| early_throw | false | 773 | 773 | ExprStmt | +| early_throw | false | 775 | 775 | re-throw exception | +| early_throw | false | 777 | 777 | { ... } | +| early_throw | false | 779 | 779 | declaration | +| early_throw | false | 784 | 784 | return ... | +| early_throw | false | 786 | 786 | { ... } | +| early_throw | false | 788 | 788 | before | +| early_throw | false | 790 | 790 | call to before.~NonTrivial | +| early_throw | false | 791 | 791 | inner | +| early_throw | false | 793 | 793 | call to inner.~NonTrivial | +| early_throw | false | 794 | 794 | inner | +| early_throw | false | 795 | 795 | call to inner.~NonTrivial | +| early_throw | false | 796 | 796 | before | +| early_throw | false | 797 | 797 | call to before.~NonTrivial | +| early_throw | false | 798 | 798 | after | +| early_throw | false | 799 | 799 | call to after.~NonTrivial | +| early_throw | true | 758 | 763 | | +| early_throw | true | 763 | 765 | | +| early_throw | true | 765 | 777 | T | +| early_throw | true | 765 | 779 | F | +| early_throw | true | 771 | 773 | | +| early_throw | true | 773 | 775 | | +| early_throw | true | 775 | 791 | | +| early_throw | true | 777 | 771 | | +| early_throw | true | 779 | 784 | | +| early_throw | true | 784 | 798 | | +| early_throw | true | 786 | 758 | | +| early_throw | true | 788 | 790 | | +| early_throw | true | 790 | 750 | | +| early_throw | true | 791 | 793 | | +| early_throw | true | 793 | 788 | | +| early_throw | true | 794 | 795 | | +| early_throw | true | 795 | 779 | | +| early_throw | true | 796 | 797 | | +| early_throw | true | 797 | 750 | | +| early_throw | true | 798 | 799 | | +| early_throw | true | 799 | 796 | | | for_decl_bind | false | 153 | 153 | for_decl_bind | | for_decl_bind | false | 161 | 161 | for(...;...;...) ... | | for_decl_bind | false | 164 | 164 | call to BoxedInt | @@ -194,108 +194,108 @@ | for_decl_bind | true | 225 | 219 | | | for_decl_bind | true | 226 | 227 | | | for_decl_bind | true | 227 | 182 | | -| for_loop_scope | false | 698 | 698 | for_loop_scope | -| for_loop_scope | false | 706 | 706 | declaration | -| for_loop_scope | false | 711 | 711 | for(...;...;...) ... | -| for_loop_scope | false | 716 | 716 | x | -| for_loop_scope | false | 720 | 720 | 10 | -| for_loop_scope | false | 721 | 721 | ... < ... | -| for_loop_scope | false | 726 | 726 | declaration | -| for_loop_scope | false | 728 | 728 | { ... } | -| for_loop_scope | false | 730 | 730 | declaration | -| for_loop_scope | false | 732 | 732 | x | -| for_loop_scope | false | 734 | 734 | ++ ... | -| for_loop_scope | false | 736 | 736 | return ... | -| for_loop_scope | false | 738 | 738 | { ... } | -| for_loop_scope | false | 740 | 740 | for_scope | -| for_loop_scope | false | 742 | 742 | call to for_scope.~NonTrivial | -| for_loop_scope | false | 743 | 743 | inner_scope | -| for_loop_scope | false | 745 | 745 | call to inner_scope.~NonTrivial | -| for_loop_scope | false | 746 | 746 | outer_scope | -| for_loop_scope | false | 748 | 748 | call to outer_scope.~NonTrivial | -| for_loop_scope | true | 706 | 711 | | -| for_loop_scope | true | 711 | 730 | | -| for_loop_scope | true | 716 | 720 | | -| for_loop_scope | true | 720 | 721 | | -| for_loop_scope | true | 721 | 728 | T | -| for_loop_scope | true | 721 | 740 | F | -| for_loop_scope | true | 726 | 743 | | -| for_loop_scope | true | 728 | 726 | | -| for_loop_scope | true | 730 | 716 | | -| for_loop_scope | true | 732 | 734 | | -| for_loop_scope | true | 734 | 716 | | -| for_loop_scope | true | 736 | 746 | | -| for_loop_scope | true | 738 | 706 | | -| for_loop_scope | true | 740 | 742 | | -| for_loop_scope | true | 742 | 736 | | -| for_loop_scope | true | 743 | 745 | | -| for_loop_scope | true | 745 | 732 | | -| for_loop_scope | true | 746 | 748 | | -| for_loop_scope | true | 748 | 698 | | -| gotos | false | 608 | 608 | gotos | -| gotos | false | 616 | 616 | declaration | -| gotos | false | 621 | 621 | if (...) ... | -| gotos | false | 623 | 623 | x | -| gotos | false | 625 | 625 | (bool)... | -| gotos | false | 626 | 626 | goto ... | -| gotos | false | 628 | 628 | x | -| gotos | false | 630 | 630 | ++ ... | -| gotos | false | 632 | 632 | initializer for y | -| gotos | false | 643 | 643 | declaration | -| gotos | false | 645 | 645 | label ...: | -| gotos | false | 647 | 647 | declaration | -| gotos | false | 649 | 649 | if (...) ... | -| gotos | false | 651 | 651 | y | -| gotos | false | 653 | 653 | (bool)... | -| gotos | false | 654 | 654 | goto ... | -| gotos | false | 656 | 656 | declaration | -| gotos | false | 658 | 658 | { ... } | -| gotos | false | 660 | 660 | label ...: | -| gotos | false | 662 | 662 | ExprStmt | -| gotos | false | 664 | 664 | x | -| gotos | false | 666 | 666 | -- ... | -| gotos | false | 668 | 668 | return ... | -| gotos | false | 670 | 670 | { ... } | -| gotos | false | 672 | 672 | nt2 | -| gotos | false | 674 | 674 | call to nt2.~NonTrivial | -| gotos | false | 675 | 675 | nt3 | -| gotos | false | 676 | 676 | call to nt3.~NonTrivial | -| gotos | false | 677 | 677 | nt2 | -| gotos | false | 678 | 678 | call to nt2.~NonTrivial | -| gotos | false | 679 | 679 | nt1 | -| gotos | false | 681 | 681 | call to nt1.~NonTrivial | -| gotos | true | 616 | 621 | | -| gotos | true | 621 | 623 | | -| gotos | true | 623 | 626 | T | -| gotos | true | 623 | 658 | F | -| gotos | true | 626 | 645 | | -| gotos | true | 628 | 630 | | -| gotos | true | 630 | 645 | | -| gotos | true | 632 | 628 | | -| gotos | true | 643 | 632 | | -| gotos | true | 643 | 645 | | -| gotos | true | 645 | 647 | | -| gotos | true | 647 | 649 | | -| gotos | true | 649 | 651 | | -| gotos | true | 651 | 654 | T | -| gotos | true | 651 | 656 | F | -| gotos | true | 654 | 677 | | -| gotos | true | 656 | 675 | | -| gotos | true | 658 | 643 | | -| gotos | true | 660 | 662 | | -| gotos | true | 662 | 664 | | -| gotos | true | 664 | 666 | | -| gotos | true | 666 | 668 | | -| gotos | true | 668 | 679 | | -| gotos | true | 670 | 616 | | -| gotos | true | 672 | 674 | | -| gotos | true | 674 | 660 | | -| gotos | true | 675 | 676 | | -| gotos | true | 676 | 672 | | -| gotos | true | 677 | 678 | | -| gotos | true | 678 | 660 | | -| gotos | true | 679 | 681 | | -| gotos | true | 681 | 608 | | +| for_loop_scope | false | 699 | 699 | for_loop_scope | +| for_loop_scope | false | 707 | 707 | declaration | +| for_loop_scope | false | 712 | 712 | for(...;...;...) ... | +| for_loop_scope | false | 717 | 717 | x | +| for_loop_scope | false | 721 | 721 | 10 | +| for_loop_scope | false | 722 | 722 | ... < ... | +| for_loop_scope | false | 727 | 727 | declaration | +| for_loop_scope | false | 729 | 729 | { ... } | +| for_loop_scope | false | 731 | 731 | declaration | +| for_loop_scope | false | 733 | 733 | x | +| for_loop_scope | false | 735 | 735 | ++ ... | +| for_loop_scope | false | 737 | 737 | return ... | +| for_loop_scope | false | 739 | 739 | { ... } | +| for_loop_scope | false | 741 | 741 | for_scope | +| for_loop_scope | false | 743 | 743 | call to for_scope.~NonTrivial | +| for_loop_scope | false | 744 | 744 | inner_scope | +| for_loop_scope | false | 746 | 746 | call to inner_scope.~NonTrivial | +| for_loop_scope | false | 747 | 747 | outer_scope | +| for_loop_scope | false | 749 | 749 | call to outer_scope.~NonTrivial | +| for_loop_scope | true | 707 | 712 | | +| for_loop_scope | true | 712 | 731 | | +| for_loop_scope | true | 717 | 721 | | +| for_loop_scope | true | 721 | 722 | | +| for_loop_scope | true | 722 | 729 | T | +| for_loop_scope | true | 722 | 741 | F | +| for_loop_scope | true | 727 | 744 | | +| for_loop_scope | true | 729 | 727 | | +| for_loop_scope | true | 731 | 717 | | +| for_loop_scope | true | 733 | 735 | | +| for_loop_scope | true | 735 | 717 | | +| for_loop_scope | true | 737 | 747 | | +| for_loop_scope | true | 739 | 707 | | +| for_loop_scope | true | 741 | 743 | | +| for_loop_scope | true | 743 | 737 | | +| for_loop_scope | true | 744 | 746 | | +| for_loop_scope | true | 746 | 733 | | +| for_loop_scope | true | 747 | 749 | | +| for_loop_scope | true | 749 | 699 | | +| gotos | false | 609 | 609 | gotos | +| gotos | false | 617 | 617 | declaration | +| gotos | false | 622 | 622 | if (...) ... | +| gotos | false | 624 | 624 | x | +| gotos | false | 626 | 626 | (bool)... | +| gotos | false | 627 | 627 | goto ... | +| gotos | false | 629 | 629 | x | +| gotos | false | 631 | 631 | ++ ... | +| gotos | false | 633 | 633 | initializer for y | +| gotos | false | 644 | 644 | declaration | +| gotos | false | 646 | 646 | label ...: | +| gotos | false | 648 | 648 | declaration | +| gotos | false | 650 | 650 | if (...) ... | +| gotos | false | 652 | 652 | y | +| gotos | false | 654 | 654 | (bool)... | +| gotos | false | 655 | 655 | goto ... | +| gotos | false | 657 | 657 | declaration | +| gotos | false | 659 | 659 | { ... } | +| gotos | false | 661 | 661 | label ...: | +| gotos | false | 663 | 663 | ExprStmt | +| gotos | false | 665 | 665 | x | +| gotos | false | 667 | 667 | -- ... | +| gotos | false | 669 | 669 | return ... | +| gotos | false | 671 | 671 | { ... } | +| gotos | false | 673 | 673 | nt2 | +| gotos | false | 675 | 675 | call to nt2.~NonTrivial | +| gotos | false | 676 | 676 | nt2 | +| gotos | false | 677 | 677 | call to nt2.~NonTrivial | +| gotos | false | 678 | 678 | nt3 | +| gotos | false | 679 | 679 | call to nt3.~NonTrivial | +| gotos | false | 680 | 680 | nt1 | +| gotos | false | 682 | 682 | call to nt1.~NonTrivial | +| gotos | true | 617 | 622 | | +| gotos | true | 622 | 624 | | +| gotos | true | 624 | 627 | T | +| gotos | true | 624 | 659 | F | +| gotos | true | 627 | 646 | | +| gotos | true | 629 | 631 | | +| gotos | true | 631 | 646 | | +| gotos | true | 633 | 629 | | +| gotos | true | 644 | 633 | | +| gotos | true | 644 | 646 | | +| gotos | true | 646 | 648 | | +| gotos | true | 648 | 650 | | +| gotos | true | 650 | 652 | | +| gotos | true | 652 | 655 | T | +| gotos | true | 652 | 657 | F | +| gotos | true | 655 | 673 | | +| gotos | true | 657 | 678 | | +| gotos | true | 659 | 644 | | +| gotos | true | 661 | 663 | | +| gotos | true | 663 | 665 | | +| gotos | true | 665 | 667 | | +| gotos | true | 667 | 669 | | +| gotos | true | 669 | 680 | | +| gotos | true | 671 | 617 | | +| gotos | true | 673 | 675 | | +| gotos | true | 675 | 661 | | +| gotos | true | 676 | 677 | | +| gotos | true | 677 | 661 | | +| gotos | true | 678 | 679 | | +| gotos | true | 679 | 676 | | +| gotos | true | 680 | 682 | | +| gotos | true | 682 | 609 | | | if_decl_bind | false | 375 | 375 | if_decl_bind | | if_decl_bind | false | 383 | 383 | if (...) ... | | if_decl_bind | false | 386 | 386 | call to operator int | @@ -350,45 +350,45 @@ | if_decl_bind | true | 435 | 383 | | | if_decl_bind | true | 437 | 439 | | | if_decl_bind | true | 439 | 424 | | -| never_destructs | false | 682 | 682 | never_destructs | -| never_destructs | false | 687 | 687 | declaration | -| never_destructs | false | 692 | 692 | label ...: | -| never_destructs | false | 694 | 694 | goto ... | -| never_destructs | false | 696 | 696 | { ... } | -| never_destructs | true | 687 | 692 | | -| never_destructs | true | 692 | 694 | | -| never_destructs | true | 694 | 692 | | -| never_destructs | true | 696 | 687 | | +| never_destructs | false | 683 | 683 | never_destructs | +| never_destructs | false | 688 | 688 | declaration | +| never_destructs | false | 693 | 693 | label ...: | +| never_destructs | false | 695 | 695 | goto ... | +| never_destructs | false | 697 | 697 | { ... } | +| never_destructs | true | 688 | 693 | | +| never_destructs | true | 693 | 695 | | +| never_destructs | true | 695 | 693 | | +| never_destructs | true | 697 | 688 | | | operator delete | false | 476 | 476 | operator delete | | operator new | false | 499 | 499 | operator new | -| simple | false | 871 | 871 | simple | -| simple | false | 876 | 876 | declaration | -| simple | false | 881 | 881 | return ... | -| simple | false | 883 | 883 | { ... } | -| simple | false | 885 | 885 | nt | -| simple | false | 887 | 887 | call to nt.~NonTrivial | -| simple | true | 876 | 881 | | -| simple | true | 881 | 885 | | -| simple | true | 883 | 876 | | -| simple | true | 885 | 887 | | -| simple | true | 887 | 871 | | -| simple2 | false | 847 | 847 | simple2 | -| simple2 | false | 852 | 852 | declaration | -| simple2 | false | 857 | 857 | declaration | -| simple2 | false | 862 | 862 | return ... | -| simple2 | false | 864 | 864 | { ... } | -| simple2 | false | 866 | 866 | one | -| simple2 | false | 868 | 868 | call to one.~NonTrivial | -| simple2 | false | 869 | 869 | two | -| simple2 | false | 870 | 870 | call to two.~NonTrivial | -| simple2 | true | 852 | 857 | | -| simple2 | true | 857 | 862 | | -| simple2 | true | 862 | 869 | | -| simple2 | true | 864 | 852 | | -| simple2 | true | 866 | 868 | | -| simple2 | true | 868 | 847 | | -| simple2 | true | 869 | 870 | | -| simple2 | true | 870 | 866 | | +| simple | false | 872 | 872 | simple | +| simple | false | 877 | 877 | declaration | +| simple | false | 882 | 882 | return ... | +| simple | false | 884 | 884 | { ... } | +| simple | false | 886 | 886 | nt | +| simple | false | 888 | 888 | call to nt.~NonTrivial | +| simple | true | 877 | 882 | | +| simple | true | 882 | 886 | | +| simple | true | 884 | 877 | | +| simple | true | 886 | 888 | | +| simple | true | 888 | 872 | | +| simple2 | false | 848 | 848 | simple2 | +| simple2 | false | 853 | 853 | declaration | +| simple2 | false | 858 | 858 | declaration | +| simple2 | false | 863 | 863 | return ... | +| simple2 | false | 865 | 865 | { ... } | +| simple2 | false | 867 | 867 | one | +| simple2 | false | 869 | 869 | call to one.~NonTrivial | +| simple2 | false | 870 | 870 | two | +| simple2 | false | 871 | 871 | call to two.~NonTrivial | +| simple2 | true | 853 | 858 | | +| simple2 | true | 858 | 863 | | +| simple2 | true | 863 | 870 | | +| simple2 | true | 865 | 853 | | +| simple2 | true | 867 | 869 | | +| simple2 | true | 869 | 848 | | +| simple2 | true | 870 | 871 | | +| simple2 | true | 871 | 867 | | | switch_decl_bind | false | 276 | 276 | switch_decl_bind | | switch_decl_bind | false | 284 | 284 | switch (...) ... | | switch_decl_bind | false | 287 | 287 | call to operator int | @@ -444,21 +444,21 @@ | switch_decl_bind | true | 310 | 313 | | | switch_decl_bind | true | 313 | 315 | | | switch_decl_bind | true | 315 | 317 | | -| switch_decl_bind | true | 317 | 371 | | +| switch_decl_bind | true | 317 | 368 | | | switch_decl_bind | true | 319 | 324 | | | switch_decl_bind | true | 324 | 326 | | | switch_decl_bind | true | 326 | 328 | | | switch_decl_bind | true | 328 | 330 | | | switch_decl_bind | true | 330 | 332 | | | switch_decl_bind | true | 332 | 334 | | -| switch_decl_bind | true | 334 | 373 | | +| switch_decl_bind | true | 334 | 371 | | | switch_decl_bind | true | 336 | 338 | | | switch_decl_bind | true | 338 | 340 | | | switch_decl_bind | true | 340 | 342 | | | switch_decl_bind | true | 342 | 344 | | | switch_decl_bind | true | 344 | 348 | | | switch_decl_bind | true | 348 | 349 | | -| switch_decl_bind | true | 349 | 368 | | +| switch_decl_bind | true | 349 | 373 | | | switch_decl_bind | true | 351 | 300 | | | switch_decl_bind | true | 351 | 319 | | | switch_decl_bind | true | 351 | 336 | | @@ -501,10 +501,11 @@ | while_decl_bind | true | 241 | 251 | | | while_decl_bind | true | 243 | 241 | | | while_decl_bind | true | 251 | 259 | T | -| while_decl_bind | true | 251 | 271 | F | +| while_decl_bind | true | 251 | 274 | F | | while_decl_bind | true | 253 | 255 | | | while_decl_bind | true | 255 | 257 | | -| while_decl_bind | true | 257 | 274 | | +| while_decl_bind | true | 257 | 243 | | +| while_decl_bind | true | 257 | 271 | | | while_decl_bind | true | 259 | 253 | | | while_decl_bind | true | 261 | 263 | | | while_decl_bind | true | 263 | 265 | | @@ -512,6 +513,5 @@ | while_decl_bind | true | 267 | 228 | | | while_decl_bind | true | 269 | 236 | | | while_decl_bind | true | 271 | 273 | | -| while_decl_bind | true | 273 | 261 | | | while_decl_bind | true | 274 | 275 | | -| while_decl_bind | true | 275 | 243 | | +| while_decl_bind | true | 275 | 261 | | diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs index a59991b4b837..9308a137e7e3 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs @@ -16,6 +16,11 @@ internal class Assets { private readonly ILogger logger; + /// + /// Contains the dependencies found in the parsed assets files. + /// + public DependencyContainer Dependencies { get; } = new(); + internal Assets(ILogger logger) { this.logger = logger; @@ -72,7 +77,7 @@ private record class ReferenceInfo(string? Type, Dictionary? Com /// "json.net" /// } /// - private void AddPackageDependencies(JObject json, DependencyContainer dependencies) + private void AddPackageDependencies(JObject json, string jsonPath) { // If there is more than one framework we need to pick just one. // To ensure stability we pick one based on the lexicographic order of @@ -86,7 +91,7 @@ private void AddPackageDependencies(JObject json, DependencyContainer dependenci if (references is null) { - logger.LogDebug("No references found in the targets section in the assets file."); + logger.LogDebug($"No references found in the targets section in '{jsonPath}'"); return; } @@ -107,13 +112,13 @@ private void AddPackageDependencies(JObject json, DependencyContainer dependenci // If this is a framework reference then include everything. if (FrameworkPackageNames.AllFrameworks.Any(framework => name.StartsWith(framework))) { - dependencies.AddFramework(name); + Dependencies.AddFramework(name); } return; } info.Compile - .ForEach(r => dependencies.Add(name, r.Key)); + .ForEach(r => Dependencies.Add(name, r.Key)); }); return; @@ -149,7 +154,7 @@ private void AddPackageDependencies(JObject json, DependencyContainer dependenci /// "microsoft.netcore.app.ref" /// } /// - private void AddFrameworkDependencies(JObject json, DependencyContainer dependencies) + private void AddFrameworkDependencies(JObject json, string jsonPath) { var frameworks = json @@ -158,7 +163,7 @@ private void AddFrameworkDependencies(JObject json, DependencyContainer dependen if (frameworks is null) { - logger.LogDebug("No framework section in assets.json."); + logger.LogDebug($"No framework section in '{jsonPath}'."); return; } @@ -172,13 +177,13 @@ private void AddFrameworkDependencies(JObject json, DependencyContainer dependen if (references is null) { - logger.LogDebug("No framework references in assets.json."); + logger.LogDebug($"No framework references in '{jsonPath}'."); return; } references .Properties() - .ForEach(f => dependencies.AddFramework($"{f.Name}.Ref".ToLowerInvariant())); + .ForEach(f => Dependencies.AddFramework($"{f.Name}.Ref".ToLowerInvariant())); } /// @@ -186,13 +191,13 @@ private void AddFrameworkDependencies(JObject json, DependencyContainer dependen /// (together with used package information) required for compilation. /// /// True if parsing succeeds, otherwise false. - public bool TryParse(string json, DependencyContainer dependencies) + public bool TryParse(string json) { try { var obj = JObject.Parse(json); - AddPackageDependencies(obj, dependencies); - AddFrameworkDependencies(obj, dependencies); + AddPackageDependencies(obj, json); + AddFrameworkDependencies(obj, json); return true; } catch (Exception e) @@ -217,19 +222,24 @@ private static bool TryReadAllText(string path, ILogger logger, [NotNullWhen(ret } } - public static DependencyContainer GetCompilationDependencies(ILogger logger, IEnumerable assets) + /// + /// Add the dependencies from the assets file to the dependencies. + /// + /// Path to an assets file. + public void AddDependencies(string asset) { - var parser = new Assets(logger); - var dependencies = new DependencyContainer(); - assets.ForEach(asset => + if (TryReadAllText(asset, logger, out var json)) { - if (TryReadAllText(asset, logger, out var json)) - { - parser.TryParse(json, dependencies); - } - }); - return dependencies; + TryParse(json); + } } + + /// + /// Add the dependencies from the assets files to the dependencies. + /// + /// Collection of paths to assets files. + public void AddDependenciesRange(IEnumerable assets) => + assets.ForEach(AddDependencies); } internal static class JsonExtensions diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyContainer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyContainer.cs index d3858f17fe18..230731104124 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyContainer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyContainer.cs @@ -12,7 +12,7 @@ internal class DependencyContainer /// /// Paths to dependencies required for compilation. /// - public List Paths { get; } = new(); + public HashSet Paths { get; } = new(); /// /// Packages that are used as a part of the required dependencies. @@ -45,7 +45,7 @@ public void Add(string package, string dependency) var p = package.Replace('/', Path.DirectorySeparatorChar); var d = dependency.Replace('/', Path.DirectorySeparatorChar); - // In most cases paths in asset files point to dll's or the empty _._ file. + // In most cases paths in assets files point to dll's or the empty _._ file. // That is, for _._ we don't need to add anything. if (Path.GetFileName(d) == "_._") { @@ -68,4 +68,18 @@ public void AddFramework(string framework) Packages.Add(GetPackageName(p)); } } -} \ No newline at end of file + + internal static class DependencyContainerExtensions + { + /// + /// Flatten a list of containers into a single container. + /// + public static DependencyContainer Flatten(this IEnumerable containers, DependencyContainer init) => + containers.Aggregate(init, (acc, container) => + { + acc.Paths.UnionWith(container.Paths); + acc.Packages.UnionWith(container.Packages); + return acc; + }); + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index d0e68defac16..f18d30f4f192 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -3,8 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Security.Cryptography; -using System.Text; using System.Threading.Tasks; using Semmle.Util; @@ -191,6 +189,7 @@ void exitCallback(int ret, string msg, bool silent) private HashSet AddFrameworkDlls(HashSet dllLocations) { + logger.LogInfo("Adding .NET Framework DLLs"); var frameworkLocations = new HashSet(); var frameworkReferences = Environment.GetEnvironmentVariable(EnvironmentVariableNames.DotnetFrameworkReferences); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs index c573c5ff4e68..642403271ff3 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs @@ -91,9 +91,9 @@ public bool AddPackage(string folder, string package) return dotnetCliInvoker.RunCommand(args); } - public IList GetListedRuntimes() => GetResultList("--list-runtimes", null, false); + public IList GetListedRuntimes() => GetResultList("--list-runtimes"); - public IList GetListedSdks() => GetResultList("--list-sdks", null, false); + public IList GetListedSdks() => GetResultList("--list-sdks"); private IList GetResultList(string args, string? workingDirectory = null, bool silent = true) { @@ -143,7 +143,7 @@ private static BuildScript DownloadDotNet(IBuildActions actions, ILogger logger, // See https://docs.microsoft.com/en-us/dotnet/core/tools/global-json var versions = new List(); - foreach (var path in files.Where(p => p.EndsWith("global.json", StringComparison.Ordinal))) + foreach (var path in files.Where(p => string.Equals(FileUtils.SafeGetFileName(p, logger), "global.json", StringComparison.OrdinalIgnoreCase))) { try { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs index 1802521e28d3..126780212270 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs @@ -19,6 +19,7 @@ public DotNetCliInvoker(ILogger logger, string exec) { this.logger = logger; this.Exec = exec; + logger.LogInfo($"Using .NET CLI executable: '{Exec}'"); } private ProcessStartInfo MakeDotnetStartInfo(string args, string? workingDirectory) @@ -43,7 +44,7 @@ private ProcessStartInfo MakeDotnetStartInfo(string args, string? workingDirecto private bool RunCommandAux(string args, string? workingDirectory, out IList output, bool silent) { var dirLog = string.IsNullOrWhiteSpace(workingDirectory) ? "" : $" in {workingDirectory}"; - logger.LogInfo($"Running {Exec} {args}{dirLog}"); + logger.LogInfo($"Running '{Exec} {args}'{dirLog}"); var pi = MakeDotnetStartInfo(args, workingDirectory); var threadId = Environment.CurrentManagedThreadId; void onOut(string s) => logger.Log(silent ? Severity.Debug : Severity.Info, s, threadId); @@ -51,7 +52,7 @@ private bool RunCommandAux(string args, string? workingDirectory, out IList line in unsafeFileReader.ReadLines(file)) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileProvider.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileProvider.cs index f5ba20cd8880..7b88a1fc1a28 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileProvider.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileProvider.cs @@ -21,6 +21,7 @@ public class FileProvider private readonly Lazy dlls; private readonly Lazy nugetConfigs; private readonly Lazy globalJsons; + private readonly Lazy packagesConfigs; private readonly Lazy razorViews; private readonly Lazy resources; private readonly Lazy rootNugetConfig; @@ -32,31 +33,38 @@ public FileProvider(DirectoryInfo sourceDir, ILogger logger) all = GetAllFiles(); allNonBinary = new Lazy(() => all.Where(f => !binaryFileExtensions.Contains(f.Extension.ToLowerInvariant())).ToArray()); - smallNonBinary = new Lazy(() => - { - var ret = SelectSmallFiles(allNonBinary.Value).SelectFileNames().ToArray(); - logger.LogInfo($"Found {ret.Length} small non-binary files in {SourceDir}."); - return ret; - }); + smallNonBinary = new Lazy(() => ReturnAndLogFiles("small non-binary", SelectSmallFiles(allNonBinary.Value).SelectFileNames().ToArray())); sources = new Lazy(() => SelectTextFileNamesByExtension("source", ".cs")); projects = new Lazy(() => SelectTextFileNamesByExtension("project", ".csproj")); solutions = new Lazy(() => SelectTextFileNamesByExtension("solution", ".sln")); dlls = new Lazy(() => SelectBinaryFileNamesByExtension("DLL", ".dll")); - nugetConfigs = new Lazy(() => allNonBinary.Value.SelectFileNamesByName("nuget.config").ToArray()); - globalJsons = new Lazy(() => allNonBinary.Value.SelectFileNamesByName("global.json").ToArray()); + nugetConfigs = new Lazy(() => SelectTextFileNamesByName("nuget.config")); + globalJsons = new Lazy(() => SelectTextFileNamesByName("global.json")); + packagesConfigs = new Lazy(() => SelectTextFileNamesByName("packages.config")); razorViews = new Lazy(() => SelectTextFileNamesByExtension("razor view", ".cshtml", ".razor")); resources = new Lazy(() => SelectTextFileNamesByExtension("resource", ".resx")); rootNugetConfig = new Lazy(() => all.SelectRootFiles(SourceDir).SelectFileNamesByName("nuget.config").FirstOrDefault()); } - private string[] SelectTextFileNamesByExtension(string filetype, params string[] extensions) + private string[] ReturnAndLogFiles(string filetype, IEnumerable files) { - var ret = allNonBinary.Value.SelectFileNamesByExtension(extensions).ToArray(); + var ret = files.ToArray(); logger.LogInfo($"Found {ret.Length} {filetype} files in {SourceDir}."); return ret; } + private string[] SelectTextFileNamesByExtension(string filetype, params string[] extensions) + => ReturnAndLogFiles(filetype, allNonBinary.Value.SelectFileNamesByExtension(extensions)); + + private string[] SelectTextFileNamesByName(string name) + { + var ret = allNonBinary.Value.SelectFileNamesByName(name).ToArray(); + var ending = ret.Length == 0 ? "." : $": {string.Join(", ", ret.OrderBy(s => s))}."; + logger.LogInfo($"Found {ret.Length} {name} files in {SourceDir}{ending}"); + return ret; + } + private string[] SelectBinaryFileNamesByExtension(string filetype, params string[] extensions) { var ret = all.SelectFileNamesByExtension(extensions).ToArray(); @@ -117,6 +125,7 @@ private FileInfo[] GetAllFiles() public ICollection NugetConfigs => nugetConfigs.Value; public string? RootNugetConfig => rootNugetConfig.Value; public IEnumerable GlobalJsons => globalJsons.Value; + public ICollection PackagesConfigs => packagesConfigs.Value; public ICollection RazorViews => razorViews.Value; public ICollection Resources => resources.Value; } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs index 01b4eb6b5f4b..8537e4b5e0ee 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs @@ -20,9 +20,9 @@ internal class NugetExeWrapper : IDisposable /// /// The list of package files. /// - private readonly FileInfo[] packageFiles; + private readonly ICollection packageFiles; - public int PackageCount => packageFiles.Length; + public int PackageCount => packageFiles.Count; private readonly string? backupNugetConfig; private readonly string? nugetConfigPath; @@ -37,23 +37,21 @@ internal class NugetExeWrapper : IDisposable /// /// Create the package manager for a specified source tree. /// - public NugetExeWrapper(string sourceDir, TemporaryDirectory packageDirectory, Util.Logging.ILogger logger) + public NugetExeWrapper(FileProvider fileProvider, TemporaryDirectory packageDirectory, Util.Logging.ILogger logger) { this.packageDirectory = packageDirectory; this.logger = logger; - packageFiles = new DirectoryInfo(sourceDir) - .EnumerateFiles("packages.config", SearchOption.AllDirectories) - .ToArray(); + packageFiles = fileProvider.PackagesConfigs; - if (packageFiles.Length > 0) + if (packageFiles.Count > 0) { - logger.LogInfo($"Found {packageFiles.Length} packages.config files, trying to use nuget.exe for package restore"); - nugetExe = ResolveNugetExe(sourceDir); + logger.LogInfo($"Found packages.config files, trying to use nuget.exe for package restore"); + nugetExe = ResolveNugetExe(fileProvider.SourceDir.FullName); if (HasNoPackageSource()) { // We only modify or add a top level nuget.config file - nugetConfigPath = Path.Combine(sourceDir, "nuget.config"); + nugetConfigPath = Path.Combine(fileProvider.SourceDir.FullName, "nuget.config"); try { if (File.Exists(nugetConfigPath)) @@ -86,10 +84,6 @@ public NugetExeWrapper(string sourceDir, TemporaryDirectory packageDirectory, Ut } } } - else - { - logger.LogInfo("Found no packages.config file"); - } } /// @@ -195,7 +189,7 @@ private bool TryRestoreNugetPackage(string package) /// public int InstallPackages() { - return packageFiles.Count(package => TryRestoreNugetPackage(package.FullName)); + return packageFiles.Count(package => TryRestoreNugetPackage(package)); } private bool HasNoPackageSource() diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index 735e4a676c68..5e556682df21 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -93,7 +94,10 @@ public static DirectoryInfo[] GetOrderedPackageVersionSubDirectories(string pack public HashSet Restore() { var assemblyLookupLocations = new HashSet(); - var checkNugetFeedResponsiveness = EnvironmentVariables.GetBoolean(EnvironmentVariableNames.CheckNugetFeedResponsiveness); + var checkNugetFeedResponsiveness = EnvironmentVariables.GetBooleanOptOut(EnvironmentVariableNames.CheckNugetFeedResponsiveness); + logger.LogInfo($"Checking NuGet feed responsiveness: {checkNugetFeedResponsiveness}"); + compilationInfoContainer.CompilationInfos.Add(("NuGet feed responsiveness checked", checkNugetFeedResponsiveness ? "1" : "0")); + try { if (checkNugetFeedResponsiveness && !CheckFeeds()) @@ -105,7 +109,7 @@ public HashSet Restore() : [unresponsiveMissingPackageLocation]; } - using (var nuget = new NugetExeWrapper(fileProvider.SourceDir.FullName, legacyPackageDirectory, logger)) + using (var nuget = new NugetExeWrapper(fileProvider, legacyPackageDirectory, logger)) { var count = nuget.InstallPackages(); @@ -144,11 +148,11 @@ public HashSet Restore() logger.LogError($"Failed to restore Nuget packages with nuget.exe: {exc.Message}"); } - var restoredProjects = RestoreSolutions(out var assets1); + var restoredProjects = RestoreSolutions(out var container); var projects = fileProvider.Projects.Except(restoredProjects); - RestoreProjects(projects, out var assets2); + RestoreProjects(projects, out var containers); - var dependencies = Assets.GetCompilationDependencies(logger, assets1.Union(assets2)); + var dependencies = containers.Flatten(container); var paths = dependencies .Paths @@ -178,7 +182,7 @@ private List GetReachableFallbackNugetFeeds() logger.LogInfo($"No fallback Nuget feeds specified. Using default feed: {PublicNugetOrgFeed}"); } - logger.LogInfo($"Checking fallback Nuget feed reachability on feeds: {string.Join(", ", fallbackFeeds.OrderBy(f => f))}"); + logger.LogInfo($"Checking fallback Nuget feed reachability on feeds: {string.Join(", ", fallbackFeeds.OrderBy(f => f))}"); var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback: true); var reachableFallbackFeeds = fallbackFeeds.Where(feed => IsFeedReachable(feed, initialTimeout, tryCount, allowExceptions: false)).ToList(); if (reachableFallbackFeeds.Count == 0) @@ -198,14 +202,14 @@ private List GetReachableFallbackNugetFeeds() /// As opposed to RestoreProjects this is not run in parallel using PLINQ /// as `dotnet restore` on a solution already uses multiple threads for restoring /// the projects (this can be disabled with the `--disable-parallel` flag). - /// Populates assets with the relative paths to the assets files generated by the restore. + /// Populates dependencies with the relevant dependencies from the assets files generated by the restore. /// Returns a list of projects that are up to date with respect to restore. /// - private IEnumerable RestoreSolutions(out IEnumerable assets) + private IEnumerable RestoreSolutions(out DependencyContainer dependencies) { var successCount = 0; var nugetSourceFailures = 0; - var assetFiles = new List(); + var assets = new Assets(logger); var projects = fileProvider.Solutions.SelectMany(solution => { logger.LogInfo($"Restoring solution {solution}..."); @@ -218,10 +222,10 @@ private IEnumerable RestoreSolutions(out IEnumerable assets) { nugetSourceFailures++; } - assetFiles.AddRange(res.AssetsFilePaths); + assets.AddDependenciesRange(res.AssetsFilePaths); return res.RestoredProjects; }).ToList(); - assets = assetFiles; + dependencies = assets.Dependencies; compilationInfoContainer.CompilationInfos.Add(("Successfully restored solution files", successCount.ToString())); compilationInfoContainer.CompilationInfos.Add(("Failed solution restore with package source error", nugetSourceFailures.ToString())); compilationInfoContainer.CompilationInfos.Add(("Restored projects through solution files", projects.Count.ToString())); @@ -231,33 +235,39 @@ private IEnumerable RestoreSolutions(out IEnumerable assets) /// /// Executes `dotnet restore` on all projects in projects. /// This is done in parallel for performance reasons. - /// Populates assets with the relative paths to the assets files generated by the restore. + /// Populates dependencies with the relative paths to the assets files generated by the restore. /// /// A list of paths to project files. - private void RestoreProjects(IEnumerable projects, out IEnumerable assets) + private void RestoreProjects(IEnumerable projects, out ConcurrentBag dependencies) { var successCount = 0; var nugetSourceFailures = 0; - var assetFiles = new List(); + ConcurrentBag collectedDependencies = []; var sync = new object(); - Parallel.ForEach(projects, new ParallelOptions { MaxDegreeOfParallelism = DependencyManager.Threads }, project => + var projectGroups = projects.GroupBy(Path.GetDirectoryName); + Parallel.ForEach(projectGroups, new ParallelOptions { MaxDegreeOfParallelism = DependencyManager.Threads }, projectGroup => { - logger.LogInfo($"Restoring project {project}..."); - var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true)); - lock (sync) + var assets = new Assets(logger); + foreach (var project in projectGroup) { - if (res.Success) - { - successCount++; - } - if (res.HasNugetPackageSourceError) + logger.LogInfo($"Restoring project {project}..."); + var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true)); + assets.AddDependenciesRange(res.AssetsFilePaths); + lock (sync) { - nugetSourceFailures++; + if (res.Success) + { + successCount++; + } + if (res.HasNugetPackageSourceError) + { + nugetSourceFailures++; + } } - assetFiles.AddRange(res.AssetsFilePaths); } + collectedDependencies.Add(assets.Dependencies); }); - assets = assetFiles; + dependencies = collectedDependencies; compilationInfoContainer.CompilationInfos.Add(("Successfully restored project files", successCount.ToString())); compilationInfoContainer.CompilationInfos.Add(("Failed project restore with package source error", nugetSourceFailures.ToString())); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/DotnetSourceGeneratorBase.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/DotnetSourceGeneratorBase.cs index 4d353ffbeea4..461590348df7 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/DotnetSourceGeneratorBase.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/DotnetSourceGeneratorBase.cs @@ -55,7 +55,7 @@ protected override IEnumerable Run() // group additional files by closes project file: var projects = fileProvider.Projects - .Select(p => (File: p, Directory: SafeGetDirectoryName(p))) + .Select(p => (File: p, Directory: FileUtils.SafeGetDirectoryName(p, logger))) .Where(p => p.Directory.Length > 0); var groupedFiles = new Dictionary>(); @@ -93,30 +93,6 @@ protected override IEnumerable Run() } } - private string SafeGetDirectoryName(string fileName) - { - try - { - var dir = Path.GetDirectoryName(fileName); - if (dir is null) - { - return ""; - } - - if (!dir.EndsWith(Path.DirectorySeparatorChar)) - { - dir += Path.DirectorySeparatorChar; - } - - return dir; - } - catch (Exception ex) - { - logger.LogDebug($"Failed to get directory name for {fileName}: {ex.Message}"); - return ""; - } - } - protected abstract ICollection AdditionalFiles { get; } protected abstract string FileType { get; } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/RazorGenerator.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/RazorGenerator.cs index b2670e023e56..3f9a17dc6b30 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/RazorGenerator.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/RazorGenerator.cs @@ -20,17 +20,9 @@ public RazorGenerator( protected override bool IsEnabled() { - var webViewExtractionOption = Environment.GetEnvironmentVariable(EnvironmentVariableNames.WebViewGeneration); - if (webViewExtractionOption == null || - bool.TryParse(webViewExtractionOption, out var shouldExtractWebViews) && - shouldExtractWebViews) - { - compilationInfoContainer.CompilationInfos.Add(("WebView extraction enabled", "1")); - return true; - } - - compilationInfoContainer.CompilationInfos.Add(("WebView extraction enabled", "0")); - return false; + var webViewExtractionOption = EnvironmentVariables.GetBooleanOptOut(EnvironmentVariableNames.WebViewGeneration); + compilationInfoContainer.CompilationInfos.Add(("WebView extraction enabled", webViewExtractionOption ? "1" : "0")); + return webViewExtractionOption; } protected override ICollection AdditionalFiles => fileProvider.RazorViews; diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs index fac8523989ec..e578dd4aa31c 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs @@ -40,7 +40,6 @@ private static void AnalyseStandalone( output.Name, syntaxTrees, references, new CSharpCompilationOptions(OutputKind.ConsoleApplication, allowUnsafe: true) ), (compilation, options) => analyser.Initialize(output.FullName, extractionInput.CompilationInfos, compilation, options), - _ => { }, () => { foreach (var type in analyser.MissingNamespaces) @@ -121,17 +120,20 @@ public void Started(int item, int total, string source) public void MissingType(string type) { - logger.Log(Severity.Debug, "Missing type {0}", type); + logger.LogDebug($"Missing type {type}"); } public void MissingNamespace(string @namespace) { - logger.Log(Severity.Info, "Missing namespace {0}", @namespace); + logger.LogInfo($"Missing namespace {@namespace}"); } public void MissingSummary(int missingTypes, int missingNamespaces) { - logger.Log(Severity.Info, "Failed to resolve {0} types in {1} namespaces", missingTypes, missingNamespaces); + if (missingTypes > 0 || missingNamespaces > 0) + { + logger.LogInfo($"Failed to resolve {missingTypes} types in {missingNamespaces} namespaces"); + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs index cda4610a217f..2f21716284f0 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs @@ -245,6 +245,8 @@ private void DoAnalyseCompilation() } } + public void LogPerformance(Entities.PerformanceMetrics p) => compilationEntity.PopulatePerformance(p); + #nullable restore warnings /// diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs index 22a55849a026..03369e7b6013 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs @@ -309,7 +309,6 @@ public static ExitCode Analyse(Stopwatch stopwatch, Analyser analyser, CommonOpt Func, IEnumerable> getSyntaxTreeTasks, Func, IEnumerable, CSharpCompilation> getCompilation, Action initializeAnalyser, - Action logPerformance, Action postProcess) { using var references = new BlockingCollection(); @@ -368,7 +367,7 @@ public static ExitCode Analyse(Stopwatch stopwatch, Analyser analyser, CommonOpt PeakWorkingSet = currentProcess.PeakWorkingSet64 }; - logPerformance(performance); + analyser.LogPerformance(performance); analyser.Logger.Log(Severity.Info, " Extraction took {0}", sw.Elapsed); postProcess(); @@ -422,7 +421,6 @@ private static ExitCode AnalyseTracing( ); }, (compilation, options) => analyser.EndInitialize(compilerArguments, options, compilation), - performance => analyser.LogPerformance(performance), () => { }); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs index 22db6710f36f..3b73c35f55a4 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs @@ -175,9 +175,6 @@ private IEnumerable FilteredDiagnostics Where(e => e.Severity >= DiagnosticSeverity.Error && !errorsToIgnore.Contains(e.Id)); } } - - public void LogPerformance(Entities.PerformanceMetrics p) => compilationEntity.PopulatePerformance(p); - #nullable restore warnings } } diff --git a/csharp/extractor/Semmle.Extraction.Tests/Assets.cs b/csharp/extractor/Semmle.Extraction.Tests/Assets.cs index 3406788bd1c7..ea04597f96bd 100644 --- a/csharp/extractor/Semmle.Extraction.Tests/Assets.cs +++ b/csharp/extractor/Semmle.Extraction.Tests/Assets.cs @@ -14,29 +14,28 @@ public void TestAssets1() // Setup var assets = new Assets(new LoggerStub()); var json = assetsJson1; - var dependencies = new DependencyContainer(); // Execute - var success = assets.TryParse(json, dependencies); + var success = assets.TryParse(json); // Verify Assert.True(success); - Assert.Equal(6, dependencies.Paths.Count()); - Assert.Equal(5, dependencies.Packages.Count()); + Assert.Equal(6, assets.Dependencies.Paths.Count); + Assert.Equal(5, assets.Dependencies.Packages.Count); - var normalizedPaths = dependencies.Paths.Select(FixExpectedPathOnWindows); + var normalizedPaths = assets.Dependencies.Paths.Select(FixExpectedPathOnWindows); // Used references Assert.Contains("castle.core/4.4.1/lib/netstandard1.5/Castle.Core.dll", normalizedPaths); Assert.Contains("castle.core/4.4.1/lib/netstandard1.5/Castle.Core2.dll", normalizedPaths); Assert.Contains("json.net/1.0.33/lib/netstandard2.0/Json.Net.dll", normalizedPaths); Assert.Contains("microsoft.aspnetcore.cryptography.internal/6.0.8/lib/net6.0/Microsoft.AspNetCore.Cryptography.Internal.dll", normalizedPaths); // Used packages - Assert.Contains("castle.core", dependencies.Packages); - Assert.Contains("json.net", dependencies.Packages); - Assert.Contains("microsoft.aspnetcore.cryptography.internal", dependencies.Packages); + Assert.Contains("castle.core", assets.Dependencies.Packages); + Assert.Contains("json.net", assets.Dependencies.Packages); + Assert.Contains("microsoft.aspnetcore.cryptography.internal", assets.Dependencies.Packages); // Used frameworks - Assert.Contains("microsoft.netcore.app.ref", dependencies.Packages); - Assert.Contains("microsoft.aspnetcore.app.ref", dependencies.Packages); + Assert.Contains("microsoft.netcore.app.ref", assets.Dependencies.Packages); + Assert.Contains("microsoft.aspnetcore.app.ref", assets.Dependencies.Packages); } [Fact] @@ -45,14 +44,13 @@ public void TestAssetsFailure() // Setup var assets = new Assets(new LoggerStub()); var json = "garbage data"; - var dependencies = new DependencyContainer(); // Execute - var success = assets.TryParse(json, dependencies); + var success = assets.TryParse(json); // Verify Assert.False(success); - Assert.Empty(dependencies.Paths); + Assert.Empty(assets.Dependencies.Paths); } [Fact] @@ -61,28 +59,27 @@ public void TestAssetsNet70() // Setup var assets = new Assets(new LoggerStub()); var json = assetsNet70; - var dependencies = new DependencyContainer(); // Execute - var success = assets.TryParse(json, dependencies); + var success = assets.TryParse(json); // Verify Assert.True(success); - Assert.Equal(4, dependencies.Paths.Count); - Assert.Equal(4, dependencies.Packages.Count); + Assert.Equal(4, assets.Dependencies.Paths.Count); + Assert.Equal(4, assets.Dependencies.Packages.Count); - var normalizedPaths = dependencies.Paths.Select(FixExpectedPathOnWindows); + var normalizedPaths = assets.Dependencies.Paths.Select(FixExpectedPathOnWindows); // Used paths Assert.Contains("microsoft.netcore.app.ref", normalizedPaths); Assert.Contains("microsoft.aspnetcore.app.ref", normalizedPaths); Assert.Contains("newtonsoft.json/12.0.1/lib/netstandard2.0/Newtonsoft.Json.dll", normalizedPaths); Assert.Contains("newtonsoft.json.bson/1.0.2/lib/netstandard2.0/Newtonsoft.Json.Bson.dll", normalizedPaths); // Used packages - Assert.Contains("microsoft.netcore.app.ref", dependencies.Packages); - Assert.Contains("microsoft.aspnetcore.app.ref", dependencies.Packages); - Assert.Contains("newtonsoft.json", dependencies.Packages); - Assert.Contains("newtonsoft.json.bson", dependencies.Packages); + Assert.Contains("microsoft.netcore.app.ref", assets.Dependencies.Packages); + Assert.Contains("microsoft.aspnetcore.app.ref", assets.Dependencies.Packages); + Assert.Contains("newtonsoft.json", assets.Dependencies.Packages); + Assert.Contains("newtonsoft.json.bson", assets.Dependencies.Packages); } @@ -92,25 +89,24 @@ public void TestAssetsNet48() // Setup var assets = new Assets(new LoggerStub()); var json = assetsNet48; - var dependencies = new DependencyContainer(); // Execute - var success = assets.TryParse(json, dependencies); + var success = assets.TryParse(json); // Verify Assert.True(success); - Assert.Equal(3, dependencies.Paths.Count); - Assert.Equal(3, dependencies.Packages.Count); + Assert.Equal(3, assets.Dependencies.Paths.Count); + Assert.Equal(3, assets.Dependencies.Packages.Count); - var normalizedPaths = dependencies.Paths.Select(FixExpectedPathOnWindows); + var normalizedPaths = assets.Dependencies.Paths.Select(FixExpectedPathOnWindows); // Used references Assert.Contains("microsoft.netframework.referenceassemblies.net48/1.0.2", normalizedPaths); Assert.Contains("newtonsoft.json/12.0.1/lib/net45/Newtonsoft.Json.dll", normalizedPaths); Assert.Contains("newtonsoft.json.bson/1.0.2/lib/net45/Newtonsoft.Json.Bson.dll", normalizedPaths); // Used packages - Assert.Contains("microsoft.netframework.referenceassemblies.net48", dependencies.Packages); - Assert.Contains("newtonsoft.json", dependencies.Packages); - Assert.Contains("newtonsoft.json.bson", dependencies.Packages); + Assert.Contains("microsoft.netframework.referenceassemblies.net48", assets.Dependencies.Packages); + Assert.Contains("newtonsoft.json", assets.Dependencies.Packages); + Assert.Contains("newtonsoft.json.bson", assets.Dependencies.Packages); } [Fact] @@ -119,26 +115,25 @@ public void TestAssetsNetstandard21() // Setup var assets = new Assets(new LoggerStub()); var json = assetsNetstandard21; - var dependencies = new DependencyContainer(); // Execute - var success = assets.TryParse(json, dependencies); + var success = assets.TryParse(json); // Verify Assert.True(success); - Assert.Equal(3, dependencies.Paths.Count); - Assert.Equal(3, dependencies.Packages.Count); + Assert.Equal(3, assets.Dependencies.Paths.Count); + Assert.Equal(3, assets.Dependencies.Packages.Count); - var normalizedPaths = dependencies.Paths.Select(FixExpectedPathOnWindows); + var normalizedPaths = assets.Dependencies.Paths.Select(FixExpectedPathOnWindows); // Used references Assert.Contains("netstandard.library.ref", normalizedPaths); Assert.Contains("newtonsoft.json/12.0.1/lib/netstandard2.0/Newtonsoft.Json.dll", normalizedPaths); Assert.Contains("newtonsoft.json.bson/1.0.2/lib/netstandard2.0/Newtonsoft.Json.Bson.dll", normalizedPaths); // Used packages - Assert.Contains("netstandard.library.ref", dependencies.Packages); - Assert.Contains("newtonsoft.json", dependencies.Packages); - Assert.Contains("newtonsoft.json.bson", dependencies.Packages); + Assert.Contains("netstandard.library.ref", assets.Dependencies.Packages); + Assert.Contains("newtonsoft.json", assets.Dependencies.Packages); + Assert.Contains("newtonsoft.json.bson", assets.Dependencies.Packages); } [Fact] @@ -147,17 +142,16 @@ public void TestAssetsNetStandard16() // Setup var assets = new Assets(new LoggerStub()); var json = assetsNetstandard16; - var dependencies = new DependencyContainer(); // Execute - var success = assets.TryParse(json, dependencies); + var success = assets.TryParse(json); // Verify Assert.True(success); - Assert.Equal(5, dependencies.Paths.Count); - Assert.Equal(5, dependencies.Packages.Count); + Assert.Equal(5, assets.Dependencies.Paths.Count); + Assert.Equal(5, assets.Dependencies.Packages.Count); - var normalizedPaths = dependencies.Paths.Select(FixExpectedPathOnWindows); + var normalizedPaths = assets.Dependencies.Paths.Select(FixExpectedPathOnWindows); // Used references Assert.Contains("netstandard.library/1.6.1", normalizedPaths); @@ -166,11 +160,11 @@ public void TestAssetsNetStandard16() Assert.Contains("newtonsoft.json/12.0.1/lib/netstandard1.3/Newtonsoft.Json.dll", normalizedPaths); Assert.Contains("newtonsoft.json.bson/1.0.2/lib/netstandard1.3/Newtonsoft.Json.Bson.dll", normalizedPaths); // Used packages - Assert.Contains("netstandard.library", dependencies.Packages); - Assert.Contains("microsoft.csharp", dependencies.Packages); - Assert.Contains("microsoft.win32.primitives", dependencies.Packages); - Assert.Contains("newtonsoft.json", dependencies.Packages); - Assert.Contains("newtonsoft.json.bson", dependencies.Packages); + Assert.Contains("netstandard.library", assets.Dependencies.Packages); + Assert.Contains("microsoft.csharp", assets.Dependencies.Packages); + Assert.Contains("microsoft.win32.primitives", assets.Dependencies.Packages); + Assert.Contains("newtonsoft.json", assets.Dependencies.Packages); + Assert.Contains("newtonsoft.json.bson", assets.Dependencies.Packages); } [Fact] @@ -179,26 +173,25 @@ public void TestAssetsNetcoreapp20() // Setup var assets = new Assets(new LoggerStub()); var json = assetsNetcoreapp20; - var dependencies = new DependencyContainer(); // Execute - var success = assets.TryParse(json, dependencies); + var success = assets.TryParse(json); // Verify Assert.True(success); - Assert.Equal(144, dependencies.Paths.Count); - Assert.Equal(3, dependencies.Packages.Count); + Assert.Equal(144, assets.Dependencies.Paths.Count); + Assert.Equal(3, assets.Dependencies.Packages.Count); - var normalizedPaths = dependencies.Paths.Select(FixExpectedPathOnWindows); + var normalizedPaths = assets.Dependencies.Paths.Select(FixExpectedPathOnWindows); // Used references (only some of them) Assert.Contains("microsoft.netcore.app/2.0.0/ref/netcoreapp2.0/Microsoft.CSharp.dll", normalizedPaths); Assert.Contains("newtonsoft.json/12.0.1/lib/netstandard2.0/Newtonsoft.Json.dll", normalizedPaths); Assert.Contains("newtonsoft.json.bson/1.0.2/lib/netstandard2.0/Newtonsoft.Json.Bson.dll", normalizedPaths); // Used packages - Assert.Contains("microsoft.netcore.app", dependencies.Packages); - Assert.Contains("newtonsoft.json", dependencies.Packages); - Assert.Contains("newtonsoft.json.bson", dependencies.Packages); + Assert.Contains("microsoft.netcore.app", assets.Dependencies.Packages); + Assert.Contains("newtonsoft.json", assets.Dependencies.Packages); + Assert.Contains("newtonsoft.json.bson", assets.Dependencies.Packages); } [Fact] @@ -207,15 +200,14 @@ public void TestAssetsNetcoreapp31() // Setup var assets = new Assets(new LoggerStub()); var json = assetsNetcoreapp31; - var dependencies = new DependencyContainer(); // Execute - var success = assets.TryParse(json, dependencies); + var success = assets.TryParse(json); // Verify Assert.True(success); - var normalizedPaths = dependencies.Paths.Select(FixExpectedPathOnWindows); + var normalizedPaths = assets.Dependencies.Paths.Select(FixExpectedPathOnWindows); // Used paths Assert.Contains("microsoft.netcore.app.ref", normalizedPaths); @@ -223,10 +215,10 @@ public void TestAssetsNetcoreapp31() Assert.Contains("newtonsoft.json/12.0.1/lib/netstandard2.0/Newtonsoft.Json.dll", normalizedPaths); Assert.Contains("newtonsoft.json.bson/1.0.2/lib/netstandard2.0/Newtonsoft.Json.Bson.dll", normalizedPaths); // Used packages - Assert.Contains("microsoft.netcore.app.ref", dependencies.Packages); - Assert.Contains("microsoft.aspnetcore.app.ref", dependencies.Packages); - Assert.Contains("newtonsoft.json", dependencies.Packages); - Assert.Contains("newtonsoft.json.bson", dependencies.Packages); + Assert.Contains("microsoft.netcore.app.ref", assets.Dependencies.Packages); + Assert.Contains("microsoft.aspnetcore.app.ref", assets.Dependencies.Packages); + Assert.Contains("newtonsoft.json", assets.Dependencies.Packages); + Assert.Contains("newtonsoft.json.bson", assets.Dependencies.Packages); } /// diff --git a/csharp/extractor/Semmle.Util/EnvironmentVariables.cs b/csharp/extractor/Semmle.Util/EnvironmentVariables.cs index c8c272e94ad9..076507d07e0a 100644 --- a/csharp/extractor/Semmle.Util/EnvironmentVariables.cs +++ b/csharp/extractor/Semmle.Util/EnvironmentVariables.cs @@ -29,6 +29,19 @@ public static int GetDefaultNumberOfThreads() return threads; } + public static bool GetBooleanOptOut(string name) + { + var env = Environment.GetEnvironmentVariable(name); + if (env == null || + bool.TryParse(env, out var value) && + value) + { + return true; + } + + return false; + } + public static bool GetBoolean(string name) { var env = Environment.GetEnvironmentVariable(name); diff --git a/csharp/extractor/Semmle.Util/FileUtils.cs b/csharp/extractor/Semmle.Util/FileUtils.cs index 4a22877e3c10..4d9052bcc4ea 100644 --- a/csharp/extractor/Semmle.Util/FileUtils.cs +++ b/csharp/extractor/Semmle.Util/FileUtils.cs @@ -185,5 +185,42 @@ public static FileInfo CreateTemporaryFile(string extension, out bool shouldClea return new FileInfo(outputPath); } + + public static string SafeGetDirectoryName(string path, ILogger logger) + { + try + { + var dir = Path.GetDirectoryName(path); + if (dir is null) + { + return ""; + } + + if (!dir.EndsWith(Path.DirectorySeparatorChar)) + { + dir += Path.DirectorySeparatorChar; + } + + return dir; + } + catch (Exception ex) + { + logger.LogDebug($"Failed to get directory name for {path}: {ex.Message}"); + return ""; + } + } + + public static string? SafeGetFileName(string path, ILogger logger) + { + try + { + return Path.GetFileName(path); + } + catch (Exception ex) + { + logger.LogDebug($"Failed to get file name for {path}: {ex.Message}"); + return null; + } + } } } diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index b19677a4af47..a1fa74650477 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.15 + +No user-facing changes. + ## 1.7.14 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.15.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.15.md new file mode 100644 index 000000000000..42dec3d1f07f --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.15.md @@ -0,0 +1,3 @@ +## 1.7.15 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index e2ee0b0d7d4b..07b34a2aaf70 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.14 +lastReleaseVersion: 1.7.15 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 1ba514323d65..4129c2ad6fd7 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.7.15-dev +version: 1.7.16-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index b19677a4af47..a1fa74650477 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.15 + +No user-facing changes. + ## 1.7.14 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.15.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.15.md new file mode 100644 index 000000000000..42dec3d1f07f --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.15.md @@ -0,0 +1,3 @@ +## 1.7.15 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index e2ee0b0d7d4b..07b34a2aaf70 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.14 +lastReleaseVersion: 1.7.15 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index d4840e16bda0..033c39775dda 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.7.15-dev +version: 1.7.16-dev groups: - csharp - solorigate diff --git a/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.expected b/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.expected index 2f5b2c9ea4eb..1fbab458c34a 100644 --- a/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.expected +++ b/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.expected @@ -1,5 +1,7 @@ +| All Nuget feeds reachable | 1.0 | | Failed project restore with package source error | 0.0 | | Failed solution restore with package source error | 0.0 | +| NuGet feed responsiveness checked | 1.0 | | Project files on filesystem | 1.0 | | Resource extraction enabled | 1.0 | | Restored .NET framework variants | 1.0 | diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.expected b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.expected new file mode 100644 index 000000000000..2d54c0155a43 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.expected @@ -0,0 +1,166 @@ +| [...]/avalara.avatax/23.11.0/lib/netstandard2.0/Avalara.AvaTax.RestClient.dll | +| [...]/microsoft.bcl.asyncinterfaces/8.0.0/lib/netstandard2.1/Microsoft.Bcl.AsyncInterfaces.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.CSharp.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.VisualBasic.Core.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.VisualBasic.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.Win32.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.Win32.Registry.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.AppContext.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Buffers.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.Concurrent.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.Immutable.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.NonGeneric.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.Specialized.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.Annotations.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.DataAnnotations.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.EventBasedAsync.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.TypeConverter.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Configuration.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Console.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Core.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Data.Common.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Data.DataSetExtensions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Data.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Contracts.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Debug.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.DiagnosticSource.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.FileVersionInfo.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Process.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.StackTrace.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.TextWriterTraceListener.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Tools.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.TraceSource.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Tracing.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Drawing.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Drawing.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Dynamic.Runtime.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Formats.Asn1.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Formats.Tar.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Globalization.Calendars.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Globalization.Extensions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Globalization.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Compression.Brotli.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Compression.FileSystem.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Compression.ZipFile.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Compression.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.AccessControl.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.DriveInfo.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.Watcher.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.IsolatedStorage.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.MemoryMappedFiles.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Pipes.AccessControl.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Pipes.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.UnmanagedMemoryStream.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Linq.Expressions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Linq.Parallel.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Linq.Queryable.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Linq.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Memory.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Http.Json.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Http.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.HttpListener.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Mail.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.NameResolution.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.NetworkInformation.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Ping.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Quic.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Requests.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Security.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.ServicePoint.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Sockets.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebClient.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebHeaderCollection.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebProxy.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebSockets.Client.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebSockets.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Numerics.Vectors.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Numerics.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ObjectModel.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.DispatchProxy.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Emit.ILGeneration.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Emit.Lightweight.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Emit.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Extensions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Metadata.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.TypeExtensions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Resources.Reader.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Resources.ResourceManager.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Resources.Writer.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.CompilerServices.Unsafe.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.CompilerServices.VisualC.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Extensions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Handles.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.InteropServices.JavaScript.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.InteropServices.RuntimeInformation.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.InteropServices.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Intrinsics.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Loader.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Numerics.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.Formatters.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.Json.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.Xml.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.AccessControl.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Claims.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Algorithms.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Cng.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Csp.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Encoding.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.OpenSsl.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.X509Certificates.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Principal.Windows.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Principal.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.SecureString.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ServiceModel.Web.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ServiceProcess.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Encoding.CodePages.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Encoding.Extensions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Encoding.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Encodings.Web.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Json.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.RegularExpressions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Channels.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Overlapped.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Tasks.Dataflow.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Tasks.Extensions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Tasks.Parallel.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Tasks.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Thread.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.ThreadPool.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Timer.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Transactions.Local.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Transactions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ValueTuple.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Web.HttpUtility.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Web.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Windows.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.Linq.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.ReaderWriter.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.Serialization.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XDocument.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XPath.XDocument.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XPath.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XmlDocument.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XmlSerializer.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/WindowsBase.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/mscorlib.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/netstandard.dll | +| [...]/newtonsoft.json/12.0.1/lib/netstandard2.0/Newtonsoft.Json.dll | diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.ql b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.ql new file mode 100644 index 000000000000..b78ceee2d8f8 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.ql @@ -0,0 +1,17 @@ +import csharp + +private string getPath(Assembly a) { + not a.getCompilation().getOutputAssembly() = a and + exists(string s | s = a.getFile().getAbsolutePath() | + result = + "[...]" + + s.substring(s.indexOf("test-db/working/") + "test-db/working/".length() + 16 + + "/packages".length(), s.length()) + or + result = s and + not exists(s.indexOf("test-db/working/")) + ) +} + +from Assembly a +select getPath(a) diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Program.cs b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Program.cs new file mode 100644 index 000000000000..39a9e95bb6e3 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Program.cs @@ -0,0 +1,6 @@ +class Program +{ + static void Main(string[] args) + { + } +} \ No newline at end of file diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/global.json b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/global.json new file mode 100644 index 000000000000..d54915e8d4d0 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "8.0.101" + } +} diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone1.csproj b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone1.csproj new file mode 100644 index 000000000000..67d37d1a7608 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone1.csproj @@ -0,0 +1,16 @@ + + + + Exe + net8.0 + + + + + + + + + + + diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone2.csproj b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone2.csproj new file mode 100644 index 000000000000..05fb5c1aa487 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone2.csproj @@ -0,0 +1,16 @@ + + + + Exe + net8.0 + + + + + + + + + + + diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/test.py b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/test.py new file mode 100644 index 000000000000..a17966e148a9 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/test.py @@ -0,0 +1,3 @@ +from create_database_utils import * + +run_codeql_database_create([], lang="csharp", extra_args=["--build-mode=none"]) diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/CompilationInfo.expected b/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/CompilationInfo.expected index 9171a445bcd7..81a44b5f8fd2 100644 --- a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/CompilationInfo.expected +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/CompilationInfo.expected @@ -1,6 +1,8 @@ +| All Nuget feeds reachable | 1.0 | | Failed project restore with package source error | 1.0 | | Failed solution restore with package source error | 0.0 | | Fallback nuget restore | 1.0 | +| NuGet feed responsiveness checked | 1.0 | | Project files on filesystem | 1.0 | | Resolved assembly conflicts | 7.0 | | Resource extraction enabled | 0.0 | diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected b/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected index bd676f6f1d7a..026a3d386e3c 100644 --- a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected @@ -1,6 +1,7 @@ | All Nuget feeds reachable | 0.0 | | Fallback nuget restore | 1.0 | | Inherited Nuget feed count | 1.0 | +| NuGet feed responsiveness checked | 1.0 | | Project files on filesystem | 1.0 | | Resolved assembly conflicts | 7.0 | | Resource extraction enabled | 0.0 | diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/test.py b/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/test.py index 0b290510983e..7345609d4d61 100644 --- a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/test.py +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/test.py @@ -2,7 +2,7 @@ from diagnostics_test_utils import * import os -os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK"] = "true" # Enable NuGet feed check +# os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK"] = "true" # Nuget feed check is enabled by default os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_TIMEOUT"] = "1" # 1ms, the GET request should fail with such short timeout os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_LIMIT"] = "1" # Limit the count of checks to 1 os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_EXCLUDED"] = "https://abc.de:8000/packages/" # Exclude this feed from check diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 95817811fdef..c136a0828890 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.10.0 + +### Breaking Changes + +* Deleted the deprecated `getAssemblyName` predicate from the `Operator` class. Use `getFunctionName` instead. +* Deleted the deprecated `LShiftOperator`, `RShiftOperator`, `AssignLShiftExpr`, `AssignRShiftExpr`, `LShiftExpr`, and `RShiftExpr` aliases. +* Deleted the deprecated `getCallableDescription` predicate from the `ExternalApiDataNode` class. Use `hasQualifiedName` instead. + +### Minor Analysis Improvements + +* Generated .NET Runtime models for properties with both getters and setters have been removed as this is now handled by the data flow library. + ## 0.9.1 ### Minor Analysis Improvements diff --git a/csharp/ql/lib/change-notes/2024-04-05-dotnet-runtime-property-models.md b/csharp/ql/lib/change-notes/2024-04-05-dotnet-runtime-property-models.md deleted file mode 100644 index f4ae2b3bb5e8..000000000000 --- a/csharp/ql/lib/change-notes/2024-04-05-dotnet-runtime-property-models.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Generated .NET Runtime models for properties with both getters and setters have been removed as this is now handled by the data flow library. diff --git a/csharp/ql/lib/change-notes/released/0.10.0.md b/csharp/ql/lib/change-notes/released/0.10.0.md new file mode 100644 index 000000000000..fc6c28cf41bd --- /dev/null +++ b/csharp/ql/lib/change-notes/released/0.10.0.md @@ -0,0 +1,11 @@ +## 0.10.0 + +### Breaking Changes + +* Deleted the deprecated `getAssemblyName` predicate from the `Operator` class. Use `getFunctionName` instead. +* Deleted the deprecated `LShiftOperator`, `RShiftOperator`, `AssignLShiftExpr`, `AssignRShiftExpr`, `LShiftExpr`, and `RShiftExpr` aliases. +* Deleted the deprecated `getCallableDescription` predicate from the `ExternalApiDataNode` class. Use `hasQualifiedName` instead. + +### Minor Analysis Improvements + +* Generated .NET Runtime models for properties with both getters and setters have been removed as this is now handled by the data flow library. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 6789dcd18b70..b21db6232459 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.9.1 +lastReleaseVersion: 0.10.0 diff --git a/csharp/ql/lib/ext/default.model.yml b/csharp/ql/lib/ext/empty.model.yml similarity index 73% rename from csharp/ql/lib/ext/default.model.yml rename to csharp/ql/lib/ext/empty.model.yml index a041c1f649b1..6b38b783cbe2 100644 --- a/csharp/ql/lib/ext/default.model.yml +++ b/csharp/ql/lib/ext/empty.model.yml @@ -1,4 +1,6 @@ extensions: + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about undefined extensionals. - addsTo: pack: codeql/csharp-all extensible: sourceModel diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 385fba580d08..13ddf66ad755 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.9.2-dev +version: 0.10.1-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/lib/semmle/code/csharp/Callable.qll b/csharp/ql/lib/semmle/code/csharp/Callable.qll index 9cd365c2ecd6..59cffa8d39e5 100644 --- a/csharp/ql/lib/semmle/code/csharp/Callable.qll +++ b/csharp/ql/lib/semmle/code/csharp/Callable.qll @@ -527,13 +527,6 @@ class Destructor extends Callable, Member, Attributable, @destructor { * (`BinaryOperator`), or a conversion operator (`ConversionOperator`). */ class Operator extends Callable, Member, Attributable, Overridable, @operator { - /** - * DEPRECATED: use `getFunctionName()` instead. - * - * Gets the assembly name of this operator. - */ - deprecated string getAssemblyName() { result = this.getFunctionName() } - override string getName() { operators(this, _, result, _, _, _) } override string getUndecoratedName() { operators(this, _, result, _, _, _) } @@ -989,9 +982,6 @@ class LeftShiftOperator extends BinaryOperator { override string getAPrimaryQlClass() { result = "LeftShiftOperator" } } -/** DEPRECATED: Alias for LeftShiftOperator. */ -deprecated class LShiftOperator = LeftShiftOperator; - /** * A user-defined right shift operator (`>>`), for example * @@ -1007,9 +997,6 @@ class RightShiftOperator extends BinaryOperator { override string getAPrimaryQlClass() { result = "RightShiftOperator" } } -/** DEPRECATED: Alias for RightShiftOperator. */ -deprecated class RShiftOperator = RightShiftOperator; - /** * A user-defined unsigned right shift operator (`>>>`), for example * diff --git a/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll b/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll index 636f8061b2a2..778ee8d610c9 100644 --- a/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll +++ b/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll @@ -51,8 +51,6 @@ class TopLevelExprParent extends Element, @top_level_expr_parent { final Expr getAChildExpr() { result = this.getChildExpr(_) } } -private predicate hasNoSourceLocation(Element e) { not e.getALocation() instanceof SourceLocation } - /** INTERNAL: Do not use. */ Expr getExpressionBody(Callable c) { result = c.getAChildExpr() and @@ -67,17 +65,46 @@ private ControlFlowElement getBody(Callable c) { result = getStatementBody(c) } +pragma[nomagic] +private SourceLocation getASourceLocation(Element e) { + result = e.getALocation().(SourceLocation) and + not exists(e.getALocation().(SourceLocation).getMappedLocation()) + or + result = e.getALocation().(SourceLocation).getMappedLocation() +} + +pragma[nomagic] +private predicate hasNoSourceLocation(Element e) { not exists(getASourceLocation(e)) } + +pragma[nomagic] +private Location getFirstSourceLocation(Element e) { + result = + min(Location l, string filepath, int startline, int startcolumn, int endline, int endcolumn | + l = getASourceLocation(e) and + l.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + | + l order by filepath, startline, startcolumn, endline, endcolumn + ) +} + cached private module Cached { cached Location bestLocation(Element e) { - result = e.getALocation().(SourceLocation) and - not exists(e.getALocation().(SourceLocation).getMappedLocation()) - or - result = e.getALocation().(SourceLocation).getMappedLocation() + ( + if e.(Modifiable).isPartial() or e instanceof Namespace + then result = getASourceLocation(e) + else result = getFirstSourceLocation(e) + ) or hasNoSourceLocation(e) and - result = min(Location l | l = e.getALocation() | l order by l.getFile().toString()) + result = + min(Location l, string filepath | + l = e.getALocation() and + l.hasLocationInfo(filepath, _, _, _, _) + | + l order by filepath + ) or not exists(e.getALocation()) and result instanceof EmptyLocation diff --git a/csharp/ql/lib/semmle/code/csharp/Location.qll b/csharp/ql/lib/semmle/code/csharp/Location.qll index 8b4fabb44e79..319b3890e4e1 100644 --- a/csharp/ql/lib/semmle/code/csharp/Location.qll +++ b/csharp/ql/lib/semmle/code/csharp/Location.qll @@ -63,7 +63,7 @@ class EmptyLocation extends Location { */ class SourceLocation extends Location, @location_default { /** Gets the location that takes into account `#line` directives, if any. */ - Location getMappedLocation() { + SourceLocation getMappedLocation() { locations_mapped(this, result) and not exists(LineDirective l | l.getALocation() = this) } diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll index 14da6da266f7..a5576f023d7b 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll @@ -192,9 +192,6 @@ class AssignLeftShiftExpr extends AssignBitwiseOperation, @assign_lshift_expr { override string getAPrimaryQlClass() { result = "AssignLeftShiftExpr" } } -/** DEPRECATED: Alias for AssignLeftShipExpr. */ -deprecated class AssignLShiftExpr = AssignLeftShiftExpr; - /** * A right-shift assignment operation, for example `x >>= y`. */ @@ -204,9 +201,6 @@ class AssignRightShiftExpr extends AssignBitwiseOperation, @assign_rshift_expr { override string getAPrimaryQlClass() { result = "AssignRightShiftExpr" } } -/** DEPRECATED: Alias for AssignRightShiftExpr. */ -deprecated class AssignRShiftExpr = AssignRightShiftExpr; - /** * An unsigned right-shift assignment operation, for example `x >>>= y`. */ diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll index d32485a51f8e..d818a1d08f87 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll @@ -47,9 +47,6 @@ class LeftShiftExpr extends BinaryBitwiseOperation, @lshift_expr { override string getAPrimaryQlClass() { result = "LeftShiftExpr" } } -/** DEPRECATED: Alias for LeftShiftExpr. */ -deprecated class LShiftExpr = LeftShiftExpr; - /** * A right-shift operation, for example `x >> y`. */ @@ -59,9 +56,6 @@ class RightShiftExpr extends BinaryBitwiseOperation, @rshift_expr { override string getAPrimaryQlClass() { result = "RightShiftExpr" } } -/** DEPRECATED: Alias for RightShiftExpr. */ -deprecated class RShiftExpr = RightShiftExpr; - /** * An unsigned right-shift operation, for example `x >>> y`. */ diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll index 1256ae5a7ee4..e33c4e37d282 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.codedom.Compiler private import semmle.code.csharp.security.Sanitizers @@ -16,7 +17,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for user input treated as code vulnerabilities. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for user input treated as code vulnerabilities. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll index a8938ecc6c90..cd7119a36af5 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll @@ -6,6 +6,7 @@ import csharp private import semmle.code.csharp.controlflow.Guards private import semmle.code.csharp.controlflow.BasicBlocks +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.Net @@ -14,12 +15,12 @@ private import semmle.code.csharp.security.SensitiveActions /** * A data flow source for user-controlled bypass of sensitive method. */ -abstract class Source extends DataFlow::Node { } +abstract class Source extends ApiSourceNode { } /** * A data flow sink for user-controlled bypass of sensitive method. */ -abstract class Sink extends DataFlow::ExprNode { +abstract class Sink extends ApiSinkExprNode { /** Gets the 'MethodCall' which is considered sensitive. */ abstract MethodCall getSensitiveMethodCall(); } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll index 03db7fadf811..1e5f5ae82567 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.security.dataflow.flowsinks.ExternalLocationSink private import semmle.code.csharp.security.PrivateData @@ -15,7 +16,7 @@ abstract class Source extends DataFlow::ExprNode { } /** * A data flow sink for private information flowing unencrypted to an external location. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for private information flowing unencrypted to an external location. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll index a0d0ada957a5..41888fc25571 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll @@ -71,17 +71,6 @@ class ExternalApiDataNode extends DataFlow::Node { predicate hasQualifiedName(string qualifier, string name) { this.getCallable().hasFullyQualifiedName(qualifier, name) } - - /** - * DEPRECATED: Use hasQualifiedName/2 instead. - * - * Gets the description of the callable being called. - */ - deprecated string getCallableDescription() { - exists(string qualifier, string name | - this.hasQualifiedName(qualifier, name) and result = getQualifiedName(qualifier, name) - ) - } } /** diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/HardcodedCredentialsQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/HardcodedCredentialsQuery.qll index dd6669579e1e..63a0bb50732e 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/HardcodedCredentialsQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/HardcodedCredentialsQuery.qll @@ -9,6 +9,7 @@ private import semmle.code.csharp.frameworks.Moq private import semmle.code.csharp.frameworks.system.web.Security private import semmle.code.csharp.frameworks.system.security.cryptography.X509Certificates private import semmle.code.csharp.frameworks.Test +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks /** * A data flow source for hard coded credentials. @@ -18,7 +19,7 @@ abstract class Source extends DataFlow::ExprNode { } /** * A data flow sink for hard coded credentials. */ -abstract class Sink extends DataFlow::ExprNode { +abstract class Sink extends ApiSinkExprNode { /** * Gets a description of this sink, including a placeholder for the sink and a placeholder for * the supplementary element. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll index 58a34f7604bd..78800f392097 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll @@ -4,6 +4,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.DirectoryServices private import semmle.code.csharp.frameworks.system.directoryservices.Protocols @@ -18,7 +19,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for unvalidated user input that is used to construct LDAP queries. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for unvalidated user input that is used to construct LDAP queries. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll index ed6e69f0709c..f0153fea2d4f 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.text.RegularExpressions @@ -18,7 +19,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for untrusted user input used in log entries. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for untrusted user input used in log entries. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/MissingXMLValidationQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/MissingXMLValidationQuery.qll index 914239bf7d5b..b2934d31edac 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/MissingXMLValidationQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/MissingXMLValidationQuery.qll @@ -4,6 +4,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.Xml private import semmle.code.csharp.security.Sanitizers @@ -18,7 +19,7 @@ abstract class Source extends DataFlow::Node { } * A data flow sink for untrusted user input processed as XML without validation against a known * schema. */ -abstract class Sink extends DataFlow::ExprNode { +abstract class Sink extends ApiSinkExprNode { /** Gets a string describing the reason why this is a sink. */ abstract string getReason(); } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll index 84d12fca0ccd..bf4fbd993233 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll @@ -5,6 +5,7 @@ import csharp private import semmle.code.csharp.dataflow.DataFlow2 +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.text.RegularExpressions private import semmle.code.csharp.security.Sanitizers @@ -17,7 +18,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for untrusted user input used in dangerous regular expression operations. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for untrusted user input used in dangerous regular expression operations. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/RegexInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/RegexInjectionQuery.qll index 501ede13f299..1a053c29f24d 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/RegexInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/RegexInjectionQuery.qll @@ -4,6 +4,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.text.RegularExpressions private import semmle.code.csharp.security.Sanitizers @@ -16,7 +17,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for untrusted user input used to construct regular expressions. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for untrusted user input used to construct regular expressions. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ResourceInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ResourceInjectionQuery.qll index a66283de02a7..fb016dcddae6 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ResourceInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ResourceInjectionQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.Data private import semmle.code.csharp.security.Sanitizers @@ -15,7 +16,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for untrusted user input used in resource descriptors. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for untrusted user input used in resource descriptors. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll index b7b198bbca0e..6473aa58e1cc 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.Sql private import semmle.code.csharp.security.Sanitizers @@ -16,7 +17,7 @@ abstract class Source extends DataFlow::Node { } /** * A sink for SQL injection vulnerabilities. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for SQL injection vulnerabilities. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/TaintedPathQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/TaintedPathQuery.qll index bbd32b583533..ca2b13439cee 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/TaintedPathQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/TaintedPathQuery.qll @@ -5,6 +5,7 @@ import csharp private import semmle.code.csharp.controlflow.Guards +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.IO private import semmle.code.csharp.frameworks.system.Web @@ -18,7 +19,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for uncontrolled data in path expression vulnerabilities. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for uncontrolled data in path expression vulnerabilities. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll index 6de1305a11d1..a5341aca42f8 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll @@ -6,6 +6,7 @@ import csharp private import semmle.code.csharp.serialization.Deserializers private import semmle.code.csharp.dataflow.TaintTracking2 +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources /** @@ -16,7 +17,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for unsafe deserialization vulnerabilities. */ -abstract class Sink extends DataFlow::Node { } +abstract class Sink extends ApiSinkNode { } /** * A data flow sink for unsafe deserialization vulnerabilities to an instance method. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll index 9a5ec46cb37a..b21d5846bf56 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.controlflow.Guards private import semmle.code.csharp.frameworks.Format @@ -20,7 +21,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for unvalidated URL redirect vulnerabilities. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for unvalidated URL redirect vulnerabilities. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XMLEntityInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XMLEntityInjectionQuery.qll index 7e7fd61fb1c9..0bb842adf79d 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XMLEntityInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XMLEntityInjectionQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.text.RegularExpressions @@ -19,7 +20,7 @@ private class ThreatModelSource extends Source instanceof ThreatModelFlowSource /** * A data flow sink for untrusted user input used in XML processing. */ -abstract class Sink extends DataFlow::ExprNode { +abstract class Sink extends ApiSinkExprNode { /** * Gets the reason for the insecurity of this sink. */ diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XPathInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XPathInjectionQuery.qll index 1edddf45f56f..c471a4324251 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XPathInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XPathInjectionQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.xml.XPath private import semmle.code.csharp.frameworks.system.Xml @@ -16,7 +17,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for untrusted user input used in XPath expression. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for untrusted user input used in XPath expression. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ZipSlipQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ZipSlipQuery.qll index a83bb8b4f5a4..93e7b601585d 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ZipSlipQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ZipSlipQuery.qll @@ -4,6 +4,7 @@ import csharp private import semmle.code.csharp.controlflow.Guards +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks /** * A data flow source for unsafe zip extraction. @@ -13,7 +14,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for unsafe zip extraction. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for unsafe zip extraction. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/AllSinks.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/AllSinks.qll deleted file mode 100644 index bf601bdf9b66..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/AllSinks.qll +++ /dev/null @@ -1,84 +0,0 @@ -/** Provides classes representing various flow sinks for data flow / taint tracking. */ - -private import semmle.code.csharp.dataflow.internal.ExternalFlow - -/** - * A data flow sink node. - */ -abstract class SinkNode extends DataFlow::Node { } - -/** - * Module that adds all sinks to `SinkNode`, excluding sinks for cryptography based - * queries, and queries where sinks are not succifiently explicit. - */ -private module AllSinks { - private import ParallelSink as ParallelSink - private import Remote as Remote - private import semmle.code.csharp.security.dataflow.CodeInjectionQuery as CodeInjectionQuery - private import semmle.code.csharp.security.dataflow.ConditionalBypassQuery as ConditionalBypassQuery - private import semmle.code.csharp.security.dataflow.ExposureOfPrivateInformationQuery as ExposureOfPrivateInformationQuery - private import semmle.code.csharp.security.dataflow.HardcodedCredentialsQuery as HardcodedCredentialsQuery - private import semmle.code.csharp.security.dataflow.LDAPInjectionQuery as LdapInjectionQuery - private import semmle.code.csharp.security.dataflow.LogForgingQuery as LogForgingQuery - private import semmle.code.csharp.security.dataflow.MissingXMLValidationQuery as MissingXmlValidationQuery - private import semmle.code.csharp.security.dataflow.ReDoSQuery as ReDosQuery - private import semmle.code.csharp.security.dataflow.RegexInjectionQuery as RegexInjectionQuery - private import semmle.code.csharp.security.dataflow.ResourceInjectionQuery as ResourceInjectionQuery - private import semmle.code.csharp.security.dataflow.SqlInjectionQuery as SqlInjectionQuery - private import semmle.code.csharp.security.dataflow.TaintedPathQuery as TaintedPathQuery - private import semmle.code.csharp.security.dataflow.UnsafeDeserializationQuery as UnsafeDeserializationQuery - private import semmle.code.csharp.security.dataflow.UrlRedirectQuery as UrlRedirectQuery - private import semmle.code.csharp.security.dataflow.XMLEntityInjectionQuery as XmlEntityInjectionQuery - private import semmle.code.csharp.security.dataflow.XPathInjectionQuery as XpathInjectionQuery - private import semmle.code.csharp.security.dataflow.XSSSinks as XssSinks - private import semmle.code.csharp.security.dataflow.ZipSlipQuery as ZipSlipQuery - - private class ParallelSink extends SinkNode instanceof ParallelSink::ParallelSink { } - - private class RemoteSinkFlowSinks extends SinkNode instanceof Remote::RemoteFlowSink { } - - private class CodeInjectionSink extends SinkNode instanceof CodeInjectionQuery::Sink { } - - private class ConditionalBypassSink extends SinkNode instanceof ConditionalBypassQuery::Sink { } - - private class ExposureOfPrivateInformationSink extends SinkNode instanceof ExposureOfPrivateInformationQuery::Sink - { } - - private class HardcodedCredentialsSink extends SinkNode instanceof HardcodedCredentialsQuery::Sink - { } - - private class LdapInjectionSink extends SinkNode instanceof LdapInjectionQuery::Sink { } - - private class LogForgingSink extends SinkNode instanceof LogForgingQuery::Sink { } - - private class MissingXmlValidationSink extends SinkNode instanceof MissingXmlValidationQuery::Sink - { } - - private class ReDosSink extends SinkNode instanceof ReDosQuery::Sink { } - - private class RegexInjectionSink extends SinkNode instanceof RegexInjectionQuery::Sink { } - - private class ResourceInjectionSink extends SinkNode instanceof ResourceInjectionQuery::Sink { } - - private class SqlInjectionSink extends SinkNode instanceof SqlInjectionQuery::Sink { } - - private class TaintedPathSink extends SinkNode instanceof TaintedPathQuery::Sink { } - - private class UnsafeDeserializationSink extends SinkNode instanceof UnsafeDeserializationQuery::Sink - { } - - private class UrlRedirectSink extends SinkNode instanceof UrlRedirectQuery::Sink { } - - private class XmlEntityInjectionSink extends SinkNode instanceof XmlEntityInjectionQuery::Sink { } - - private class XpathInjectionSink extends SinkNode instanceof XpathInjectionQuery::Sink { } - - private class XssSink extends SinkNode instanceof XssSinks::Sink { } - - /** - * Add all models as data sinks. - */ - private class SinkNodeExternal extends SinkNode { - SinkNodeExternal() { sinkNode(this, _) } - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ApiSinks.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ApiSinks.qll new file mode 100644 index 000000000000..15c64b45ca08 --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ApiSinks.qll @@ -0,0 +1,35 @@ +/** Provides classes representing various flow sinks for data flow / taint tracking. */ + +private import semmle.code.csharp.dataflow.internal.ExternalFlow +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks + +/** + * A data flow sink node. + */ +final class SinkNode = ApiSinkNode; + +/** + * Module that adds all API like sinks to `SinkNode`, excluding sinks for cryptography based + * queries, and queries where sinks are not sufficiently defined (eg. using broad method name matching). + */ +private module AllApiSinks { + private import ParallelSink + private import Remote + private import semmle.code.csharp.security.dataflow.CodeInjectionQuery as CodeInjectionQuery + private import semmle.code.csharp.security.dataflow.ConditionalBypassQuery as ConditionalBypassQuery + private import semmle.code.csharp.security.dataflow.ExposureOfPrivateInformationQuery as ExposureOfPrivateInformationQuery + private import semmle.code.csharp.security.dataflow.HardcodedCredentialsQuery as HardcodedCredentialsQuery + private import semmle.code.csharp.security.dataflow.LDAPInjectionQuery as LdapInjectionQuery + private import semmle.code.csharp.security.dataflow.LogForgingQuery as LogForgingQuery + private import semmle.code.csharp.security.dataflow.MissingXMLValidationQuery as MissingXmlValidationQuery + private import semmle.code.csharp.security.dataflow.ReDoSQuery as ReDosQuery + private import semmle.code.csharp.security.dataflow.RegexInjectionQuery as RegexInjectionQuery + private import semmle.code.csharp.security.dataflow.ResourceInjectionQuery as ResourceInjectionQuery + private import semmle.code.csharp.security.dataflow.SqlInjectionQuery as SqlInjectionQuery + private import semmle.code.csharp.security.dataflow.TaintedPathQuery as TaintedPathQuery + private import semmle.code.csharp.security.dataflow.UnsafeDeserializationQuery as UnsafeDeserializationQuery + private import semmle.code.csharp.security.dataflow.UrlRedirectQuery as UrlRedirectQuery + private import semmle.code.csharp.security.dataflow.XMLEntityInjectionQuery as XmlEntityInjectionQuery + private import semmle.code.csharp.security.dataflow.XPathInjectionQuery as XpathInjectionQuery + private import semmle.code.csharp.security.dataflow.ZipSlipQuery as ZipSlipQuery +} diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll index abd1ad92733e..3bcfdde669a4 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll @@ -3,6 +3,7 @@ */ import csharp +private import FlowSinks private import Remote private import semmle.code.csharp.commons.Loggers private import semmle.code.csharp.frameworks.system.Web @@ -16,7 +17,7 @@ private import semmle.code.csharp.dataflow.internal.ExternalFlow * which the application may have no access control. For example, files on a local or remote * filesystem (including log files and cookies). */ -abstract class ExternalLocationSink extends DataFlow::ExprNode { } +abstract class ExternalLocationSink extends ApiSinkExprNode { } private class ExternalModelSink extends ExternalLocationSink { ExternalModelSink() { sinkNode(this, "file-content-store") } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/FlowSinks.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/FlowSinks.qll new file mode 100644 index 000000000000..0c5bf14e65cf --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/FlowSinks.qll @@ -0,0 +1,23 @@ +/** Provides classes representing various flow sinks for data flow / taint tracking. */ + +private import csharp +private import semmle.code.csharp.dataflow.internal.ExternalFlow + +/** + * A data flow sink node for an API, which should be considered + * supported from a modeling perspective. + */ +abstract class ApiSinkNode extends DataFlow::Node { } + +/** + * A data flow sink expression node for an API, which should be considered + * supported from a modeling perspective. + */ +abstract class ApiSinkExprNode extends ApiSinkNode, DataFlow::ExprNode { } + +/** + * Add all sink models as data sinks. + */ +private class ApiSinkNodeExternal extends ApiSinkNode { + ApiSinkNodeExternal() { sinkNode(this, _) } +} diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ParallelSink.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ParallelSink.qll index 5e53c9bd8fd2..1546d72887d5 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ParallelSink.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ParallelSink.qll @@ -3,11 +3,12 @@ */ import csharp +private import FlowSinks /** * A data flow sink node for parallel execution. */ -abstract class ParallelSink extends DataFlow::Node { } +abstract class ParallelSink extends ApiSinkNode { } /** * A data flow sink node for lambda parallel sink. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/Remote.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/Remote.qll index 0770a948b095..b58beb38ca59 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/Remote.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/Remote.qll @@ -5,12 +5,13 @@ import csharp private import Email::Email private import ExternalLocationSink +private import FlowSinks private import Html private import semmle.code.csharp.security.dataflow.XSSSinks as XssSinks private import semmle.code.csharp.frameworks.system.web.UI /** A data flow sink of remote user output. */ -abstract class RemoteFlowSink extends DataFlow::Node { } +abstract class RemoteFlowSink extends ApiSinkNode { } /** * A value written to the `[Inner]Text` property of an object defined in the diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/AllSources.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/AllSources.qll deleted file mode 100644 index 7d05500446a4..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/AllSources.qll +++ /dev/null @@ -1,77 +0,0 @@ -/** Provides classes representing various flow sources for data flow / taint tracking. */ - -private import semmle.code.csharp.dataflow.internal.ExternalFlow - -/** - * A data flow source node. - */ -abstract class SourceNode extends DataFlow::Node { } - -/** - * Module that adds all sources to `SourceNode`, excluding source for cryptography based - * queries, and queries where sources are not succifiently explicit or mainly hardcoded constants. - */ -private module AllSources { - private import FlowSources as FlowSources - private import semmle.code.csharp.security.cryptography.HardcodedSymmetricEncryptionKey - private import semmle.code.csharp.security.dataflow.CleartextStorageQuery as CleartextStorageQuery - private import semmle.code.csharp.security.dataflow.CodeInjectionQuery as CodeInjectionQuery - private import semmle.code.csharp.security.dataflow.ConditionalBypassQuery as ConditionalBypassQuery - private import semmle.code.csharp.security.dataflow.ExposureOfPrivateInformationQuery as ExposureOfPrivateInformationQuery - private import semmle.code.csharp.security.dataflow.HardcodedCredentialsQuery as HardcodedCredentialsQuery - private import semmle.code.csharp.security.dataflow.LDAPInjectionQuery as LdapInjectionQuery - private import semmle.code.csharp.security.dataflow.LogForgingQuery as LogForgingQuery - private import semmle.code.csharp.security.dataflow.MissingXMLValidationQuery as MissingXmlValidationQuery - private import semmle.code.csharp.security.dataflow.ReDoSQuery as ReDosQuery - private import semmle.code.csharp.security.dataflow.RegexInjectionQuery as RegexInjectionQuery - private import semmle.code.csharp.security.dataflow.ResourceInjectionQuery as ResourceInjectionQuery - private import semmle.code.csharp.security.dataflow.SqlInjectionQuery as SqlInjectionQuery - private import semmle.code.csharp.security.dataflow.TaintedPathQuery as TaintedPathQuery - private import semmle.code.csharp.security.dataflow.UnsafeDeserializationQuery as UnsafeDeserializationQuery - private import semmle.code.csharp.security.dataflow.UrlRedirectQuery as UrlRedirectQuery - private import semmle.code.csharp.security.dataflow.XMLEntityInjectionQuery as XmlEntityInjectionQuery - private import semmle.code.csharp.security.dataflow.XPathInjectionQuery as XpathInjectionQuery - private import semmle.code.csharp.security.dataflow.ZipSlipQuery as ZipSlipQuery - - private class FlowSourcesSources extends SourceNode instanceof FlowSources::SourceNode { } - - private class CodeInjectionSource extends SourceNode instanceof CodeInjectionQuery::Source { } - - private class ConditionalBypassSource extends SourceNode instanceof ConditionalBypassQuery::Source - { } - - private class LdapInjectionSource extends SourceNode instanceof LdapInjectionQuery::Source { } - - private class LogForgingSource extends SourceNode instanceof LogForgingQuery::Source { } - - private class MissingXmlValidationSource extends SourceNode instanceof MissingXmlValidationQuery::Source - { } - - private class ReDosSource extends SourceNode instanceof ReDosQuery::Source { } - - private class RegexInjectionSource extends SourceNode instanceof RegexInjectionQuery::Source { } - - private class ResourceInjectionSource extends SourceNode instanceof ResourceInjectionQuery::Source - { } - - private class SqlInjectionSource extends SourceNode instanceof SqlInjectionQuery::Source { } - - private class TaintedPathSource extends SourceNode instanceof TaintedPathQuery::Source { } - - private class UnsafeDeserializationSource extends SourceNode instanceof UnsafeDeserializationQuery::Source - { } - - private class UrlRedirectSource extends SourceNode instanceof UrlRedirectQuery::Source { } - - private class XmlEntityInjectionSource extends SourceNode instanceof XmlEntityInjectionQuery::Source - { } - - private class XpathInjectionSource extends SourceNode instanceof XpathInjectionQuery::Source { } - - /** - * Add all models as data sources. - */ - private class SourceNodeExternal extends SourceNode { - SourceNodeExternal() { sourceNode(this, _) } - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/ApiSources.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/ApiSources.qll new file mode 100644 index 000000000000..2aa451831aaf --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/ApiSources.qll @@ -0,0 +1,14 @@ +/** Provides classes representing various flow sources for data flow / taint tracking. */ + +private import FlowSources as FlowSources + +final class SourceNode = FlowSources::SourceNode; + +/** + * Module that adds all API like sources to `SourceNode`, excluding some sources for cryptography based + * queries, and queries where sources are not sufficiently defined (eg. using broad method name matching). + */ +private module AllApiSources { + private import semmle.code.csharp.security.dataflow.ConditionalBypassQuery as ConditionalBypassQuery + private import semmle.code.csharp.security.dataflow.ZipSlipQuery as ZipSlipQuery +} diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/FlowSources.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/FlowSources.qll index a5ada1cbaf8b..c610b3de4c74 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/FlowSources.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/FlowSources.qll @@ -32,3 +32,18 @@ class ThreatModelFlowSource extends DataFlow::Node { ) } } + +/** + * A data flow source node for an API, which should be considered + * supported from a modeling perspective. + */ +abstract class ApiSourceNode extends DataFlow::Node { } + +private class AddSourceNodes extends ApiSourceNode instanceof SourceNode { } + +/** + * Add all source models as data sources. + */ +private class ApiSourceNodeExternal extends ApiSourceNode { + ApiSourceNodeExternal() { sourceNode(this, _) } +} diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index 7b89cfb9a385..7954eef127f5 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.15 + +No user-facing changes. + ## 0.8.14 No user-facing changes. diff --git a/csharp/ql/src/Telemetry/ExternalApi.qll b/csharp/ql/src/Telemetry/ExternalApi.qll index a710cdf7cfde..270db8b0d19c 100644 --- a/csharp/ql/src/Telemetry/ExternalApi.qll +++ b/csharp/ql/src/Telemetry/ExternalApi.qll @@ -8,8 +8,8 @@ private import semmle.code.csharp.dataflow.internal.DataFlowDispatch as DataFlow private import semmle.code.csharp.dataflow.internal.ExternalFlow private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl private import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate -private import semmle.code.csharp.security.dataflow.flowsources.AllSources -private import semmle.code.csharp.security.dataflow.flowsinks.AllSinks +private import semmle.code.csharp.security.dataflow.flowsources.ApiSources as ApiSources +private import semmle.code.csharp.security.dataflow.flowsinks.ApiSinks as ApiSinks private import TestLibrary /** Holds if the given callable is not worth supporting. */ @@ -85,11 +85,11 @@ class ExternalApi extends Callable { /** Holds if this API is a known source. */ pragma[nomagic] - predicate isSource() { this.getAnOutput() instanceof SourceNode } + predicate isSource() { this.getAnOutput() instanceof ApiSources::SourceNode } /** Holds if this API is a known sink. */ pragma[nomagic] - predicate isSink() { this.getAnInput() instanceof SinkNode } + predicate isSink() { this.getAnInput() instanceof ApiSinks::SinkNode } /** Holds if this API is a known neutral. */ pragma[nomagic] diff --git a/csharp/ql/src/Telemetry/ExtractorInformation.ql b/csharp/ql/src/Telemetry/ExtractorInformation.ql index 64f90e481706..f466e2c8e8ec 100644 --- a/csharp/ql/src/Telemetry/ExtractorInformation.ql +++ b/csharp/ql/src/Telemetry/ExtractorInformation.ql @@ -201,6 +201,14 @@ predicate analyzerAssemblies(string key, float value) { value = 1.0 } +predicate timingValues(string key, float value) { + exists(Compilation c | + key = "Total elapsed seconds" and value = c.getElapsedSeconds() + or + key = "Extractor elapsed seconds" and value = c.getExtractorElapsedSeconds() + ) +} + from string key, float value where ( @@ -230,7 +238,8 @@ where ExprStatsReport::numberOfOk(key, value) or ExprStatsReport::numberOfNotOk(key, value) or ExprStatsReport::percentageOfOk(key, value) or - analyzerAssemblies(key, value) + analyzerAssemblies(key, value) or + timingValues(key, value) ) and /* Infinity */ value != 1.0 / 0.0 and diff --git a/csharp/ql/src/change-notes/released/0.8.15.md b/csharp/ql/src/change-notes/released/0.8.15.md new file mode 100644 index 000000000000..18c028b4ff00 --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.8.15.md @@ -0,0 +1,3 @@ +## 0.8.15 + +No user-facing changes. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index b36a2e248f34..2e3c183bb7a2 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.8.14 +lastReleaseVersion: 0.8.15 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index cf2bfcdcd9b8..3e7180240edb 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.8.15-dev +version: 0.8.16-dev groups: - csharp - queries diff --git a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected index f53a82e3d923..527816c645be 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected @@ -749,191 +749,72 @@ | LoopUnrolling.cs:97:22:97:22 | String x | LoopUnrolling.cs:97:9:100:9 | foreach (... ... in ...) ... | 6 | | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | MultiImplementationA.cs:4:7:4:8 | {...} | 2 | | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | enter C1 | 1 | -| MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | enter C1 | 1 | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 | 2 | -| MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 | 2 | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | 1 | -| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | 1 | | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | 1 | -| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | 1 | | MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:22:6:31 | exit get_P1 (abnormal) | 3 | -| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationB.cs:3:22:3:22 | exit get_P1 (abnormal) | 3 | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | 1 | -| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | 1 | | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | 1 | -| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | 1 | | MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:21:7:23 | exit get_P2 (abnormal) | 4 | -| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationB.cs:4:21:4:23 | exit get_P2 (abnormal) | 4 | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | 1 | -| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | 1 | | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | 1 | -| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | 1 | | MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:41:7:43 | exit set_P2 (abnormal) | 4 | -| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationB.cs:4:39:4:41 | exit set_P2 (abnormal) | 4 | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M | 1 | -| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M | 1 | | MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M | 1 | -| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M | 1 | | MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:16:8:16 | exit M (abnormal) | 3 | -| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationB.cs:5:16:5:16 | exit M (abnormal) | 3 | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | exit get_Item (normal) | 2 | -| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | exit get_Item (normal) | 2 | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item | 1 | -| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item | 1 | | MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | 1 | -| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | 1 | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item | 1 | -| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item | 1 | | MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | 1 | -| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | 1 | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:36:15:38 | exit get_Item (normal) | 4 | -| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationB.cs:13:36:13:38 | exit get_Item (normal) | 4 | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item | 1 | -| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item | 1 | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item | 2 | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item | 2 | | MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:58:15:60 | {...} | 1 | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 | 1 | -| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 | 1 | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 | 2 | -| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 | 2 | | MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:18:9:18:22 | M2(...) | 2 | | MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | exit M2 | 4 | | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | exit C2 (normal) | 14 | -| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | exit C2 (normal) | 14 | | MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | 1 | -| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | 1 | | MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | 1 | -| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | 1 | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 | 1 | -| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 | 1 | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 | 2 | -| MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 | 2 | | MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:27:21:29 | {...} | 3 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | 1 | -| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | 1 | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | 1 | -| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | 1 | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (normal) | 2 | -| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | exit ~C2 (normal) | 2 | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | 1 | -| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | 1 | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | 1 | -| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | 1 | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (normal) | 2 | -| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (normal) | 2 | | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | MultiImplementationA.cs:28:7:28:8 | {...} | 2 | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | enter C3 | 1 | -| MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | enter C3 | 1 | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 | 2 | -| MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 | 2 | | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | 5 | -| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | exit get_P3 | 5 | | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | {...} | 2 | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | enter C4 | 1 | -| MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | enter C4 | 1 | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 | 2 | -| MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 | 2 | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 | 1 | -| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 | 1 | | MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | 1 | -| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | 1 | | MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:9:36:10 | exit M1 (abnormal) | 4 | -| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationB.cs:32:9:32:10 | exit M1 (abnormal) | 4 | | MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | exit M2 | 6 | | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | {...} | 2 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | enter C1 | 1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | enter C1 | 1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 | 2 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 | 2 | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 (normal) | 2 | -| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 (normal) | 2 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | 1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | 1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | 1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | 1 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | 1 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | 1 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | 1 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | 1 | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationA.cs:7:21:7:23 | exit get_P2 (normal) | 4 | -| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:21:4:23 | exit get_P2 (normal) | 4 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | 1 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | 1 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | 1 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | 1 | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | exit set_P2 (normal) | 2 | -| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | exit set_P2 (normal) | 2 | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M | 1 | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M | 1 | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M | 1 | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M | 1 | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | exit M (normal) | 2 | -| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | exit M (normal) | 2 | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item | 1 | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item | 1 | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | 1 | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | 1 | | MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationA.cs:14:31:14:31 | exit get_Item (abnormal) | 3 | -| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:31:12:40 | exit get_Item (abnormal) | 3 | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item | 1 | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item | 1 | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | 1 | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | 1 | | MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationA.cs:15:36:15:38 | exit get_Item (abnormal) | 4 | -| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:36:13:38 | exit get_Item (abnormal) | 4 | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item | 1 | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item | 1 | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item | 2 | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item | 2 | | MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:60:13:62 | {...} | 1 | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 | 1 | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 | 1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 | 2 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 | 2 | | MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:16:9:16:31 | M2(...) | 2 | | MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | exit M2 | 5 | | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | exit C2 (abnormal) | 12 | -| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | exit C2 (abnormal) | 12 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | 1 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | 1 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | 1 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | 1 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 | 1 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 | 1 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 | 2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 | 2 | | MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:27:19:29 | {...} | 3 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | 1 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | 1 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | 1 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | 1 | | MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (abnormal) | 4 | -| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:6:20:7 | exit ~C2 (abnormal) | 4 | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | 1 | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | 1 | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | 1 | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | 1 | | MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (abnormal) | 3 | -| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (abnormal) | 3 | | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | {...} | 2 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | enter C3 | 1 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | enter C3 | 1 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 | 2 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 | 2 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | 5 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | exit get_P3 | 5 | | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | {...} | 2 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | enter C4 | 1 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | enter C4 | 1 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 | 2 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 | 2 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 | 1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 | 1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | 1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | 1 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | exit M1 (normal) | 2 | -| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | exit M1 (normal) | 2 | | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | NullCoalescing.cs:1:7:1:20 | exit NullCoalescing | 5 | | NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:23:3:23 | access to parameter i | 2 | | NullCoalescing.cs:3:23:3:28 | ... ?? ... | NullCoalescing.cs:3:9:3:10 | exit M1 | 3 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected index 831c014ef0ba..9a1a38b7935a 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected @@ -2923,50 +2923,41 @@ dominance | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 | -| MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:28:6:31 | null | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 | | MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationA.cs:6:22:6:31 | exit get_P1 (abnormal) | -| MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationB.cs:3:22:3:22 | exit get_P1 (abnormal) | | MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:22:6:31 | throw ... | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} | | MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:33:7:36 | null | | MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationA.cs:7:21:7:23 | exit get_P2 (abnormal) | -| MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationB.cs:4:21:4:23 | exit get_P2 (abnormal) | | MultiImplementationA.cs:7:33:7:36 | null | MultiImplementationA.cs:7:27:7:37 | throw ...; | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} | | MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:53:7:56 | null | | MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationA.cs:7:41:7:43 | exit set_P2 (abnormal) | -| MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationB.cs:4:39:4:41 | exit set_P2 (abnormal) | | MultiImplementationA.cs:7:53:7:56 | null | MultiImplementationA.cs:7:47:7:57 | throw ...; | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:29:8:32 | null | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:23:5:23 | 2 | | MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationA.cs:8:16:8:16 | exit M (abnormal) | -| MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationB.cs:5:16:5:16 | exit M (abnormal) | | MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:23:8:32 | throw ... | | MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationA.cs:13:20:13:20 | 0 | | MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationA.cs:24:16:24:16 | this access | | MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationA.cs:13:16:13:20 | ... = ... | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | exit get_Item (normal) | -| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | exit get_Item (normal) | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:37:12:40 | null | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:40:15:52 | {...} | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:40:13:54 | {...} | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:49:15:49 | access to parameter s | | MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationA.cs:15:36:15:38 | exit get_Item (normal) | -| MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationB.cs:13:36:13:38 | exit get_Item (normal) | | MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationA.cs:15:42:15:50 | return ...; | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:58:15:60 | {...} | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:60:13:62 | {...} | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:17:5:19:5 | {...} | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 | -| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 | | MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:18:9:18:22 | M2(...) | | MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:21:18:21 | 0 | | MultiImplementationA.cs:18:9:18:22 | exit M2 (normal) | MultiImplementationA.cs:18:9:18:22 | exit M2 | @@ -2977,23 +2968,19 @@ dominance | MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:24:20:29 | ...; | | MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationA.cs:20:28:20:28 | access to parameter i | | MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationA.cs:20:12:20:13 | exit C2 (normal) | -| MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationB.cs:18:12:18:13 | exit C2 (normal) | | MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationA.cs:20:24:20:24 | this access | | MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationA.cs:20:24:20:28 | ... = ... | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:24:21:24 | 0 | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:24:19:24 | 1 | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 | -| MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 | | MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationA.cs:21:27:21:29 | {...} | | MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (normal) | -| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | exit ~C2 (normal) | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:50:23:53 | null | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:56:21:59 | null | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (normal) | -| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (normal) | | MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationA.cs:24:32:24:34 | ... = ... | | MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:24:34:24:34 | 0 | | MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationA.cs:20:22:20:31 | {...} | @@ -3002,23 +2989,18 @@ dominance | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 | -| MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 | | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:34:30:37 | null | | MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | -| MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | MultiImplementationB.cs:27:21:27:23 | exit get_P3 | | MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | -| MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | | MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationA.cs:30:28:30:37 | throw ... | | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | {...} | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 | -| MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:14:36:28 | {...} | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:17:32:17 | 0 | | MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:22:36:25 | null | | MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationA.cs:36:9:36:10 | exit M1 (abnormal) | -| MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationB.cs:32:9:32:10 | exit M1 (abnormal) | | MultiImplementationA.cs:36:22:36:25 | null | MultiImplementationA.cs:36:16:36:26 | throw ...; | | MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:14:37:28 | {...} | | MultiImplementationA.cs:37:9:37:10 | exit M2 (abnormal) | MultiImplementationA.cs:37:9:37:10 | exit M2 | @@ -3026,100 +3008,43 @@ dominance | MultiImplementationA.cs:37:16:37:26 | throw ...; | MultiImplementationA.cs:37:9:37:10 | exit M2 (abnormal) | | MultiImplementationA.cs:37:22:37:25 | null | MultiImplementationA.cs:37:16:37:26 | throw ...; | | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | {...} | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 (normal) | -| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 (normal) | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:28:6:31 | null | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:34:4:34 | 1 | | MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationA.cs:7:21:7:23 | exit get_P2 (normal) | -| MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationB.cs:4:21:4:23 | exit get_P2 (normal) | | MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationB.cs:4:27:4:35 | return ...; | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | exit set_P2 (normal) | -| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | exit set_P2 (normal) | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:29:8:32 | null | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:23:5:23 | 2 | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | exit M (normal) | -| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | exit M (normal) | | MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:11:20:11:20 | 1 | | MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationB.cs:22:16:22:16 | this access | | MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationB.cs:11:16:11:20 | ... = ... | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:37:12:40 | null | | MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationA.cs:14:31:14:31 | exit get_Item (abnormal) | -| MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationB.cs:12:31:12:40 | exit get_Item (abnormal) | | MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:31:12:40 | throw ... | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:40:15:52 | {...} | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:40:13:54 | {...} | | MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:48:13:51 | null | | MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationA.cs:15:36:15:38 | exit get_Item (abnormal) | -| MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationB.cs:13:36:13:38 | exit get_Item (abnormal) | | MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationB.cs:13:42:13:52 | throw ...; | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:58:15:60 | {...} | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:60:13:62 | {...} | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:17:5:19:5 | {...} | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:15:5:17:5 | {...} | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 | | MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:16:9:16:31 | M2(...) | | MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:27:16:30 | null | | MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) | MultiImplementationB.cs:16:9:16:31 | exit M2 | | MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) | | MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:21:16:30 | throw ... | | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:11:16:11:16 | this access | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | | MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:30:18:33 | null | | MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationA.cs:20:12:20:13 | exit C2 (abnormal) | -| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationB.cs:18:12:18:13 | exit C2 (abnormal) | | MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationB.cs:18:24:18:34 | throw ...; | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:24:21:24 | 0 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:24:19:24 | 1 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 | | MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationB.cs:19:27:19:29 | {...} | | MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} | | MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:19:20:22 | null | | MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (abnormal) | -| MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationB.cs:20:6:20:7 | exit ~C2 (abnormal) | | MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationB.cs:20:13:20:23 | throw ...; | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:50:23:53 | null | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:56:21:59 | null | | MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (abnormal) | -| MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (abnormal) | | MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:50:21:59 | throw ... | | MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationB.cs:22:32:22:34 | ... = ... | | MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:22:34:22:34 | 1 | | MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationB.cs:18:22:18:36 | {...} | | MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationB.cs:22:16:22:16 | access to property P | | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | {...} | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:34:30:37 | null | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | MultiImplementationB.cs:27:21:27:23 | exit get_P3 | | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | {...} | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:14:36:28 | {...} | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:17:32:17 | 0 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | exit M1 (normal) | -| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | exit M1 (normal) | | NullCoalescing.cs:1:7:1:20 | call to constructor Object | NullCoalescing.cs:1:7:1:20 | {...} | | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | NullCoalescing.cs:1:7:1:20 | call to constructor Object | | NullCoalescing.cs:1:7:1:20 | exit NullCoalescing (normal) | NullCoalescing.cs:1:7:1:20 | exit NullCoalescing | @@ -7205,7 +7130,6 @@ postDominance | LoopUnrolling.cs:99:13:99:33 | ...; | LoopUnrolling.cs:98:9:100:9 | {...} | | LoopUnrolling.cs:99:31:99:31 | access to local variable x | LoopUnrolling.cs:99:13:99:33 | ...; | | MultiImplementationA.cs:4:7:4:8 | exit C1 | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | -| MultiImplementationA.cs:4:7:4:8 | exit C1 | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | {...} | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | {...} | | MultiImplementationA.cs:4:7:4:8 | {...} | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | @@ -7227,21 +7151,17 @@ postDominance | MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationA.cs:13:20:13:20 | 0 | | MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationA.cs:13:16:13:16 | this access | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | enter get_Item | -| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | enter get_Item | | MultiImplementationA.cs:14:31:14:31 | exit get_Item (abnormal) | MultiImplementationB.cs:12:31:12:40 | throw ... | | MultiImplementationA.cs:14:31:14:31 | exit get_Item (normal) | MultiImplementationA.cs:14:31:14:31 | access to parameter i | | MultiImplementationA.cs:15:36:15:38 | exit get_Item (abnormal) | MultiImplementationB.cs:13:42:13:52 | throw ...; | | MultiImplementationA.cs:15:36:15:38 | exit get_Item (normal) | MultiImplementationA.cs:15:42:15:50 | return ...; | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:36:15:38 | enter get_Item | -| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationB.cs:13:36:13:38 | enter get_Item | | MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationA.cs:15:49:15:49 | access to parameter s | | MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationA.cs:15:40:15:52 | {...} | | MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:58:15:60 | {...} | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:60:13:62 | {...} | | MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | -| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:18:9:18:22 | M2(...) | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:16:9:16:31 | M2(...) | | MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationA.cs:17:5:19:5 | {...} | @@ -7249,7 +7169,6 @@ postDominance | MultiImplementationA.cs:18:9:18:22 | exit M2 (normal) | MultiImplementationA.cs:18:21:18:21 | 0 | | MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:9:18:22 | enter M2 | | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | enter C2 | -| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | enter C2 | | MultiImplementationA.cs:20:12:20:13 | exit C2 (abnormal) | MultiImplementationB.cs:18:24:18:34 | throw ...; | | MultiImplementationA.cs:20:12:20:13 | exit C2 (normal) | MultiImplementationA.cs:20:24:20:28 | ... = ... | | MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:24:32:24:34 | ... = ... | @@ -7258,7 +7177,6 @@ postDominance | MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationA.cs:20:22:20:31 | {...} | | MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationA.cs:20:24:20:24 | this access | | MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | -| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:27:21:29 | {...} | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:27:19:29 | {...} | | MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationA.cs:21:24:21:24 | 0 | @@ -7266,28 +7184,22 @@ postDominance | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (abnormal) | MultiImplementationB.cs:20:13:20:23 | throw ...; | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (normal) | MultiImplementationA.cs:22:11:22:13 | {...} | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | -| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (abnormal) | MultiImplementationB.cs:21:50:21:59 | throw ... | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (normal) | MultiImplementationA.cs:23:50:23:53 | null | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | -| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | | MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationA.cs:24:34:24:34 | 0 | | MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:13:16:13:20 | ... = ... | | MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationA.cs:24:16:24:16 | access to property P | | MultiImplementationA.cs:24:34:24:34 | 0 | MultiImplementationA.cs:24:16:24:16 | this access | | MultiImplementationA.cs:28:7:28:8 | exit C3 | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | -| MultiImplementationA.cs:28:7:28:8 | exit C3 | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | {...} | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | {...} | | MultiImplementationA.cs:28:7:28:8 | {...} | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | -| MultiImplementationA.cs:30:21:30:23 | exit get_P3 | MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | | MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | MultiImplementationA.cs:30:28:30:37 | throw ... | | MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationA.cs:30:34:30:37 | null | | MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | -| MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationB.cs:27:21:27:23 | enter get_P3 | | MultiImplementationA.cs:34:15:34:16 | exit C4 | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | -| MultiImplementationA.cs:34:15:34:16 | exit C4 | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | {...} | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | {...} | | MultiImplementationA.cs:34:15:34:16 | {...} | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | @@ -7300,91 +7212,39 @@ postDominance | MultiImplementationA.cs:37:14:37:28 | {...} | MultiImplementationA.cs:37:9:37:10 | enter M2 | | MultiImplementationA.cs:37:16:37:26 | throw ...; | MultiImplementationA.cs:37:22:37:25 | null | | MultiImplementationA.cs:37:22:37:25 | null | MultiImplementationA.cs:37:14:37:28 | {...} | -| MultiImplementationB.cs:1:7:1:8 | exit C1 | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | -| MultiImplementationB.cs:1:7:1:8 | exit C1 | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | {...} | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | {...} | | MultiImplementationB.cs:1:7:1:8 | {...} | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | -| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 (abnormal) | MultiImplementationA.cs:6:22:6:31 | throw ... | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 (normal) | MultiImplementationB.cs:3:22:3:22 | 0 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 (abnormal) | MultiImplementationA.cs:7:27:7:37 | throw ...; | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 (normal) | MultiImplementationB.cs:4:27:4:35 | return ...; | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | -| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | | MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationB.cs:4:34:4:34 | 1 | | MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationB.cs:4:25:4:37 | {...} | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 (abnormal) | MultiImplementationA.cs:7:47:7:57 | throw ...; | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 (normal) | MultiImplementationB.cs:4:43:4:45 | {...} | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | -| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | -| MultiImplementationB.cs:5:16:5:16 | exit M (abnormal) | MultiImplementationA.cs:8:23:8:32 | throw ... | -| MultiImplementationB.cs:5:16:5:16 | exit M (normal) | MultiImplementationB.cs:5:23:5:23 | 2 | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | enter M | -| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | enter M | | MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | | MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationB.cs:11:20:11:20 | 1 | | MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationB.cs:11:16:11:16 | this access | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item (abnormal) | MultiImplementationB.cs:12:31:12:40 | throw ... | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item (normal) | MultiImplementationA.cs:14:31:14:31 | access to parameter i | | MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationB.cs:12:37:12:40 | null | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item (abnormal) | MultiImplementationB.cs:13:42:13:52 | throw ...; | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item (normal) | MultiImplementationA.cs:15:42:15:50 | return ...; | | MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationB.cs:13:48:13:51 | null | | MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationB.cs:13:40:13:54 | {...} | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:58:15:60 | {...} | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:60:13:62 | {...} | -| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | -| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:18:9:18:22 | M2(...) | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:16:9:16:31 | M2(...) | | MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationB.cs:16:9:16:31 | exit M2 | MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) | | MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) | MultiImplementationB.cs:16:21:16:30 | throw ... | | MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:27:16:30 | null | | MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:9:16:31 | enter M2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 (abnormal) | MultiImplementationB.cs:18:24:18:34 | throw ...; | -| MultiImplementationB.cs:18:12:18:13 | exit C2 (normal) | MultiImplementationA.cs:20:24:20:28 | ... = ... | | MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:22:32:22:34 | ... = ... | | MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationB.cs:18:30:18:33 | null | | MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationB.cs:18:22:18:36 | {...} | -| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | -| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:27:21:29 | {...} | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:27:19:29 | {...} | | MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationB.cs:19:24:19:24 | 1 | | MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 (abnormal) | MultiImplementationB.cs:20:13:20:23 | throw ...; | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 (normal) | MultiImplementationA.cs:22:11:22:13 | {...} | | MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationB.cs:20:19:20:22 | null | | MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationB.cs:20:11:20:25 | {...} | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (abnormal) | MultiImplementationB.cs:21:50:21:59 | throw ... | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (normal) | MultiImplementationA.cs:23:50:23:53 | null | | MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationB.cs:21:56:21:59 | null | | MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationB.cs:22:34:22:34 | 1 | | MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:11:16:11:20 | ... = ... | | MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationB.cs:22:16:22:16 | access to property P | | MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationB.cs:22:16:22:16 | this access | -| MultiImplementationB.cs:25:7:25:8 | exit C3 | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | -| MultiImplementationB.cs:25:7:25:8 | exit C3 | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | {...} | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | {...} | | MultiImplementationB.cs:25:7:25:8 | {...} | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 | MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 | MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | MultiImplementationA.cs:30:28:30:37 | throw ... | -| MultiImplementationB.cs:30:15:30:16 | exit C4 | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | -| MultiImplementationB.cs:30:15:30:16 | exit C4 | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | {...} | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | {...} | | MultiImplementationB.cs:30:15:30:16 | {...} | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationB.cs:32:9:32:10 | exit M1 (abnormal) | MultiImplementationA.cs:36:16:36:26 | throw ...; | -| MultiImplementationB.cs:32:9:32:10 | exit M1 (normal) | MultiImplementationB.cs:32:17:32:17 | 0 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | enter M1 | -| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | enter M1 | | NullCoalescing.cs:1:7:1:20 | call to constructor Object | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | | NullCoalescing.cs:1:7:1:20 | exit NullCoalescing | NullCoalescing.cs:1:7:1:20 | exit NullCoalescing (normal) | | NullCoalescing.cs:1:7:1:20 | exit NullCoalescing (normal) | NullCoalescing.cs:1:7:1:20 | {...} | @@ -11734,81 +11594,54 @@ blockDominance | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | enter C1 | | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | enter C1 | -| MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | -| MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:28:6:31 | null | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 | -| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | -| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | -| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | | MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:28:6:31 | null | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} | -| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | -| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} | | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | -| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | | MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:25:7:39 | {...} | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} | -| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | -| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} | | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | -| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | | MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:45:7:59 | {...} | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | exit M | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:29:8:32 | null | -| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M | -| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | exit M | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:23:5:23 | 2 | | MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M | -| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M | | MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:29:8:32 | null | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | access to parameter i | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | -| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item | -| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:37:12:40 | null | | MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | -| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:40:15:52 | {...} | -| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item | -| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:40:13:54 | {...} | | MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | -| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:40:15:52 | {...} | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:58:15:60 | {...} | -| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item | -| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:60:13:62 | {...} | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | | MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:58:15:60 | {...} | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:17:5:19:5 | {...} | -| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 | -| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | -| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | | MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:17:5:19:5 | {...} | | MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | enter M2 | | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | @@ -11816,213 +11649,61 @@ blockDominance | MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | | MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | | MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | -| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | -| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | | MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | -| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:24:21:24 | 0 | -| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 | -| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:24:19:24 | 1 | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | -| MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | | MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:24:21:24 | 0 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} | -| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | -| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | -| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:11:22:13 | {...} | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:50:23:53 | null | -| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:56:21:59 | null | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:50:23:53 | null | | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | enter C3 | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | enter C3 | -| MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | -| MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | -| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | enter get_P3 | | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | enter C4 | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | enter C4 | -| MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | -| MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:14:36:28 | {...} | -| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 | -| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:17:32:17 | 0 | | MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | -| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | | MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:14:36:28 | {...} | | MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | enter M2 | | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | enter C1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | enter C1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | 0 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:28:6:31 | null | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:25:4:37 | {...} | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:43:4:45 | {...} | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | exit M | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:29:8:32 | null | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | exit M | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:23:5:23 | 2 | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:23:5:23 | 2 | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:37:12:40 | null | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | | MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:37:12:40 | null | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:40:15:52 | {...} | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:40:13:54 | {...} | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | | MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:40:13:54 | {...} | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:58:15:60 | {...} | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:60:13:62 | {...} | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | | MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:60:13:62 | {...} | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:17:5:19:5 | {...} | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:15:5:17:5 | {...} | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | | MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | enter M2 | | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:24:21:24 | 0 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:24:19:24 | 1 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | | MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:24:19:24 | 1 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | | MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:11:20:25 | {...} | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:50:23:53 | null | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:56:21:59 | null | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | | MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:56:21:59 | null | | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | enter C3 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | enter C3 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | enter get_P3 | | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | enter C4 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | enter C4 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:14:36:28 | {...} | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:17:32:17 | 0 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:17:32:17 | 0 | | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | | NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:9:3:10 | enter M1 | @@ -15399,238 +15080,99 @@ postBlockDominance | LoopUnrolling.cs:97:22:97:22 | String x | LoopUnrolling.cs:97:22:97:22 | String x | | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | enter C1 | -| MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | enter C1 | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | enter C1 | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | enter C1 | -| MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | -| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | -| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | | MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:28:6:31 | null | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | -| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | -| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | | MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:25:7:39 | {...} | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | -| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | -| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | | MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:45:7:59 | {...} | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M | -| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M | | MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M | -| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M | | MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:29:8:32 | null | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | access to parameter i | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | enter get_Item | -| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | enter get_Item | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item | -| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item | | MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | -| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item | -| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item | | MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | -| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:36:15:38 | enter get_Item | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:40:15:52 | {...} | -| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationB.cs:13:36:13:38 | enter get_Item | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item | -| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | enter set_Item | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:58:15:60 | {...} | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | enter set_Item | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:60:13:62 | {...} | | MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:58:15:60 | {...} | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 | -| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | enter M1 | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:17:5:19:5 | {...} | -| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | enter M1 | -| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:17:5:19:5 | {...} | | MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | enter M2 | | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | enter C2 | -| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | enter C2 | | MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | -| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | | MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | -| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 | -| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | enter C2 | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:24:21:24 | 0 | -| MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | enter C2 | -| MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:24:19:24 | 1 | | MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:24:21:24 | 0 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | -| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | -| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:11:22:13 | {...} | -| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:50:23:53 | null | -| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | enter C3 | -| MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | enter C3 | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | enter C3 | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | enter C3 | -| MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | -| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | enter get_P3 | | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | enter C4 | -| MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | enter C4 | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | enter C4 | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | enter C4 | -| MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 | -| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 | | MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | -| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | | MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:14:36:28 | {...} | | MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | enter M2 | | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | enter C1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | enter C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | enter C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | enter C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | 0 | -| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | -| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:25:4:37 | {...} | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | -| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:43:4:45 | {...} | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | enter M | -| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | enter M | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:23:5:23 | 2 | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | | MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:37:12:40 | null | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | | MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:40:13:54 | {...} | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | enter set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:58:15:60 | {...} | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | enter set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:60:13:62 | {...} | | MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:60:13:62 | {...} | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | enter M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:17:5:19:5 | {...} | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | enter M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | enter M2 | | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | enter C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:24:21:24 | 0 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | enter C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:24:19:24 | 1 | | MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:24:19:24 | 1 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | | MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:11:20:25 | {...} | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | | MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:56:21:59 | null | | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | enter C3 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | enter C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | enter C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | enter C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | enter get_P3 | | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | enter C4 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | enter C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | enter C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | enter C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | enter M1 | -| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | enter M1 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:17:32:17 | 0 | | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | | NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:9:3:10 | enter M1 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected b/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected index fb983a081ae3..9edc62925d86 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected @@ -3157,223 +3157,116 @@ nodeEnclosing | LoopUnrolling.cs:99:13:99:33 | ...; | LoopUnrolling.cs:94:10:94:12 | M11 | | LoopUnrolling.cs:99:31:99:31 | access to local variable x | LoopUnrolling.cs:94:10:94:12 | M11 | | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:4:7:4:8 | exit C1 | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | exit C1 | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:4:7:4:8 | {...} | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | {...} | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:6:22:6:31 | exit get_P1 (abnormal) | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:22:6:31 | exit get_P1 (abnormal) | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:6:22:6:31 | exit get_P1 (normal) | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:22:6:31 | exit get_P1 (normal) | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:21:7:23 | exit get_P2 (abnormal) | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:21:7:23 | exit get_P2 (abnormal) | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:21:7:23 | exit get_P2 (normal) | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:21:7:23 | exit get_P2 (normal) | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:33:7:36 | null | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:33:7:36 | null | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:41:7:43 | exit set_P2 (abnormal) | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:41:7:43 | exit set_P2 (abnormal) | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:41:7:43 | exit set_P2 (normal) | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:41:7:43 | exit set_P2 (normal) | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:53:7:56 | null | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:53:7:56 | null | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:8:16:8:16 | exit M (abnormal) | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:16:8:16 | exit M (abnormal) | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:8:16:8:16 | exit M (normal) | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:16:8:16 | exit M (normal) | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:14:31:14:31 | exit get_Item (abnormal) | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | exit get_Item (abnormal) | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:14:31:14:31 | exit get_Item (normal) | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | exit get_Item (normal) | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:36:15:38 | exit get_Item (abnormal) | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:36:15:38 | exit get_Item (abnormal) | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:36:15:38 | exit get_Item (normal) | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:36:15:38 | exit get_Item (normal) | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | M2 | | MultiImplementationA.cs:18:9:18:22 | exit M2 | MultiImplementationA.cs:18:9:18:22 | M2 | | MultiImplementationA.cs:18:9:18:22 | exit M2 (normal) | MultiImplementationA.cs:18:9:18:22 | M2 | | MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:9:18:22 | M2 | | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:12:20:13 | exit C2 (abnormal) | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | exit C2 (abnormal) | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:12:20:13 | exit C2 (normal) | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | exit C2 (normal) | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (abnormal) | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:6:22:7 | exit ~C2 (abnormal) | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (normal) | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:6:22:7 | exit ~C2 (normal) | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (abnormal) | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (abnormal) | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (normal) | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (normal) | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:24:34:24:34 | 0 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:24:34:24:34 | 0 | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:28:7:28:8 | exit C3 | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | exit C3 | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:28:7:28:8 | {...} | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | {...} | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationA.cs:30:21:30:23 | exit get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:34:15:34:16 | exit C4 | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | exit C4 | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:34:15:34:16 | {...} | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | {...} | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:9:36:10 | exit M1 (abnormal) | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:9:36:10 | exit M1 (abnormal) | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:9:36:10 | exit M1 (normal) | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:9:36:10 | exit M1 (normal) | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:22:36:25 | null | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:22:36:25 | null | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | M2 | | MultiImplementationA.cs:37:9:37:10 | exit M2 | MultiImplementationA.cs:37:9:37:10 | M2 | | MultiImplementationA.cs:37:9:37:10 | exit M2 (abnormal) | MultiImplementationA.cs:37:9:37:10 | M2 | @@ -3381,212 +3274,50 @@ nodeEnclosing | MultiImplementationA.cs:37:16:37:26 | throw ...; | MultiImplementationA.cs:37:9:37:10 | M2 | | MultiImplementationA.cs:37:22:37:25 | null | MultiImplementationA.cs:37:9:37:10 | M2 | | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 | MultiImplementationB.cs:1:7:1:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationB.cs:1:7:1:8 | {...} | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | {...} | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 (abnormal) | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 (abnormal) | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 (normal) | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 (normal) | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 (abnormal) | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 (abnormal) | MultiImplementationB.cs:4:21:4:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 (normal) | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 (normal) | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationB.cs:4:21:4:23 | get_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 (abnormal) | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 (abnormal) | MultiImplementationB.cs:4:39:4:41 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 (normal) | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 (normal) | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | set_P2 | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M (abnormal) | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M (abnormal) | MultiImplementationB.cs:5:16:5:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M (normal) | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M (normal) | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item (abnormal) | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item (abnormal) | MultiImplementationB.cs:12:31:12:40 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item (normal) | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item (normal) | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:31:12:40 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item (abnormal) | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item (abnormal) | MultiImplementationB.cs:13:36:13:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item (normal) | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item (normal) | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationB.cs:13:36:13:38 | get_Item | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:56:13:58 | set_Item | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | M2 | | MultiImplementationB.cs:16:9:16:31 | exit M2 | MultiImplementationB.cs:16:9:16:31 | M2 | | MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) | MultiImplementationB.cs:16:9:16:31 | M2 | | MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:9:16:31 | M2 | | MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:9:16:31 | M2 | | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 (abnormal) | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 (abnormal) | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 (normal) | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 (normal) | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationB.cs:19:12:19:13 | C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 (abnormal) | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 (abnormal) | MultiImplementationB.cs:20:6:20:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 (normal) | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 (normal) | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationB.cs:20:6:20:7 | ~C2 | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (abnormal) | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (abnormal) | MultiImplementationB.cs:21:28:21:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (normal) | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (normal) | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 | MultiImplementationB.cs:25:7:25:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationB.cs:25:7:25:8 | {...} | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | {...} | MultiImplementationB.cs:25:7:25:8 | C3 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 | MultiImplementationB.cs:30:15:30:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationB.cs:30:15:30:16 | {...} | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | {...} | MultiImplementationB.cs:30:15:30:16 | C4 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 (abnormal) | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 (abnormal) | MultiImplementationB.cs:32:9:32:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 (normal) | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 (normal) | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | M1 | | NullCoalescing.cs:1:7:1:20 | call to constructor Object | NullCoalescing.cs:1:7:1:20 | NullCoalescing | | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | NullCoalescing.cs:1:7:1:20 | NullCoalescing | | NullCoalescing.cs:1:7:1:20 | exit NullCoalescing | NullCoalescing.cs:1:7:1:20 | NullCoalescing | @@ -5843,204 +5574,73 @@ blockEnclosing | LoopUnrolling.cs:94:10:94:12 | exit M11 (normal) | LoopUnrolling.cs:94:10:94:12 | M11 | | LoopUnrolling.cs:97:22:97:22 | String x | LoopUnrolling.cs:94:10:94:12 | M11 | | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | M2 | | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | M2 | | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:21:4:23 | get_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | set_P2 | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | M | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:31:12:40 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:36:13:38 | get_Item | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:56:13:58 | set_Item | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | M2 | | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:12:19:13 | C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:6:20:7 | ~C2 | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | C3 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | C4 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | M1 | | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | NullCoalescing.cs:1:7:1:20 | NullCoalescing | | NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:9:3:10 | M1 | | NullCoalescing.cs:3:23:3:28 | ... ?? ... | NullCoalescing.cs:3:9:3:10 | M1 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected index 502acfb87b7f..fd3b8ff38bb4 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected @@ -3541,6 +3541,9 @@ ConditionalAccess.cs: # 7| exit M3 (normal) #-----| -> exit M3 +# 7| access to property Length +#-----| -> exit M3 (normal) + # 7| access to parameter s1 #-----| non-null -> ... ?? ... #-----| null -> access to parameter s2 @@ -3559,9 +3562,6 @@ ConditionalAccess.cs: #-----| non-null -> [non-null] ... ?? ... #-----| null -> [null] ... ?? ... -# 7| access to property Length -#-----| -> exit M3 (normal) - # 9| enter M4 #-----| -> access to parameter s @@ -3574,13 +3574,13 @@ ConditionalAccess.cs: #-----| non-null -> access to property Length #-----| null -> 0 -# 9| ... ?? ... -#-----| -> exit M4 (normal) - # 9| access to property Length #-----| non-null -> ... ?? ... #-----| null -> 0 +# 9| ... ?? ... +#-----| -> exit M4 (normal) + # 9| 0 #-----| -> ... ?? ... @@ -3602,13 +3602,13 @@ ConditionalAccess.cs: #-----| non-null -> access to property Length #-----| null -> 0 +# 13| access to property Length +#-----| -> 0 + # 13| ... > ... #-----| true -> 0 #-----| false -> 1 -# 13| access to property Length -#-----| -> 0 - # 13| (...) ... #-----| -> ... > ... @@ -3674,15 +3674,15 @@ ConditionalAccess.cs: # 24| String s = ... #-----| -> ...; +# 24| call to method ToString +#-----| -> String s = ... + # 24| (...) ... #-----| non-null -> call to method ToString # 24| access to parameter i #-----| -> (...) ... -# 24| call to method ToString -#-----| -> String s = ... - # 25| ... = ... #-----| -> exit M7 (normal) @@ -3739,12 +3739,12 @@ ConditionalAccess.cs: # 35| this access #-----| -> access to property Prop -# 35| ...; -#-----| -> this access - # 35| call to method Out #-----| -> exit M8 (normal) +# 35| ...; +#-----| -> this access + # 41| enter CommaJoinWith #-----| -> access to parameter s1 @@ -8195,13 +8195,13 @@ Foreach.cs: #-----| non-null -> call to method ToArray #-----| null -> call to method Empty -# 20| ... ?? ... -#-----| -> foreach (... ... in ...) ... - # 20| call to method ToArray #-----| non-null -> ... ?? ... #-----| null -> call to method Empty +# 20| ... ?? ... +#-----| -> foreach (... ... in ...) ... + # 20| call to method Empty #-----| -> ... ?? ... @@ -9592,40 +9592,92 @@ MultiImplementationA.cs: # 4| call to constructor Object #-----| -> {...} +# 4| enter C1 +#-----| -> call to constructor Object +#-----| -> call to constructor Object + +# 4| exit C1 + +# 4| exit C1 (normal) +#-----| -> exit C1 + # 4| {...} #-----| -> exit C1 (normal) -#-----| -> exit C1 (normal) + +# 6| enter get_P1 +#-----| -> null +#-----| -> 0 + +# 6| exit get_P1 + +# 6| exit get_P1 (abnormal) +#-----| -> exit get_P1 + +# 6| exit get_P1 (normal) +#-----| -> exit get_P1 # 6| throw ... #-----| exception(NullReferenceException) -> exit get_P1 (abnormal) -#-----| exception(NullReferenceException) -> exit get_P1 (abnormal) # 6| null #-----| -> throw ... +# 7| enter get_P2 +#-----| -> {...} +#-----| -> {...} + +# 7| exit get_P2 + +# 7| exit get_P2 (abnormal) +#-----| -> exit get_P2 + +# 7| exit get_P2 (normal) +#-----| -> exit get_P2 + # 7| {...} #-----| -> null # 7| throw ...; #-----| exception(NullReferenceException) -> exit get_P2 (abnormal) -#-----| exception(NullReferenceException) -> exit get_P2 (abnormal) # 7| null #-----| -> throw ...; +# 7| enter set_P2 +#-----| -> {...} +#-----| -> {...} + +# 7| exit set_P2 + +# 7| exit set_P2 (abnormal) +#-----| -> exit set_P2 + +# 7| exit set_P2 (normal) +#-----| -> exit set_P2 + # 7| {...} #-----| -> null # 7| throw ...; #-----| exception(NullReferenceException) -> exit set_P2 (abnormal) -#-----| exception(NullReferenceException) -> exit set_P2 (abnormal) # 7| null #-----| -> throw ...; +# 8| enter M +#-----| -> null +#-----| -> 2 + +# 8| exit M + +# 8| exit M (abnormal) +#-----| -> exit M + +# 8| exit M (normal) +#-----| -> exit M + # 8| throw ... #-----| exception(NullReferenceException) -> exit M (abnormal) -#-----| exception(NullReferenceException) -> exit M (abnormal) # 8| null #-----| -> throw ... @@ -9641,34 +9693,66 @@ MultiImplementationA.cs: # 14| access to parameter i #-----| -> exit get_Item (normal) -#-----| -> exit get_Item (normal) + +# 14| enter get_Item +#-----| -> access to parameter i +#-----| -> null + +# 14| exit get_Item + +# 14| exit get_Item (abnormal) +#-----| -> exit get_Item + +# 14| exit get_Item (normal) +#-----| -> exit get_Item + +# 15| enter get_Item +#-----| -> {...} +#-----| -> {...} + +# 15| exit get_Item + +# 15| exit get_Item (abnormal) +#-----| -> exit get_Item + +# 15| exit get_Item (normal) +#-----| -> exit get_Item # 15| {...} #-----| -> access to parameter s # 15| return ...; #-----| return -> exit get_Item (normal) -#-----| return -> exit get_Item (normal) # 15| access to parameter s #-----| -> return ...; +# 15| enter set_Item +#-----| -> {...} +#-----| -> {...} + +# 15| exit set_Item + +# 15| exit set_Item (normal) +#-----| -> exit set_Item + # 15| {...} #-----| -> exit set_Item (normal) -#-----| -> exit set_Item (normal) + +# 16| enter M1 +#-----| -> {...} +#-----| -> {...} # 16| exit M1 -MultiImplementationB.cs: -# 14| exit M1 +# 16| exit M1 (normal) +#-----| -> exit M1 -MultiImplementationA.cs: # 17| {...} #-----| -> M2(...) # 18| M2(...) #-----| -> exit M1 (normal) -#-----| -> exit M1 (normal) # 18| enter M2 #-----| -> 0 @@ -9684,6 +9768,18 @@ MultiImplementationA.cs: # 20| call to constructor Object #-----| -> this access +# 20| enter C2 +#-----| -> call to constructor Object +#-----| -> call to constructor Object + +# 20| exit C2 + +# 20| exit C2 (abnormal) +#-----| -> exit C2 + +# 20| exit C2 (normal) +#-----| -> exit C2 + # 20| {...} #-----| -> ...; @@ -9692,7 +9788,6 @@ MultiImplementationA.cs: # 20| ... = ... #-----| -> exit C2 (normal) -#-----| -> exit C2 (normal) # 20| ...; #-----| -> this access @@ -9700,6 +9795,15 @@ MultiImplementationA.cs: # 20| access to parameter i #-----| -> ... = ... +# 21| enter C2 +#-----| -> 0 +#-----| -> 1 + +# 21| exit C2 + +# 21| exit C2 (normal) +#-----| -> exit C2 + # 21| call to constructor C2 #-----| -> {...} @@ -9708,15 +9812,36 @@ MultiImplementationA.cs: # 21| {...} #-----| -> exit C2 (normal) -#-----| -> exit C2 (normal) + +# 22| enter ~C2 +#-----| -> {...} +#-----| -> {...} + +# 22| exit ~C2 + +# 22| exit ~C2 (abnormal) +#-----| -> exit ~C2 + +# 22| exit ~C2 (normal) +#-----| -> exit ~C2 # 22| {...} #-----| -> exit ~C2 (normal) -#-----| -> exit ~C2 (normal) + +# 23| enter implicit conversion +#-----| -> null +#-----| -> null + +# 23| exit implicit conversion + +# 23| exit implicit conversion (abnormal) +#-----| -> exit implicit conversion + +# 23| exit implicit conversion (normal) +#-----| -> exit implicit conversion # 23| null #-----| -> exit implicit conversion (normal) -#-----| -> exit implicit conversion (normal) # 24| access to property P #-----| -> ... = ... @@ -9733,13 +9858,28 @@ MultiImplementationA.cs: # 28| call to constructor Object #-----| -> {...} +# 28| enter C3 +#-----| -> call to constructor Object +#-----| -> call to constructor Object + +# 28| exit C3 + +# 28| exit C3 (normal) +#-----| -> exit C3 + # 28| {...} #-----| -> exit C3 (normal) -#-----| -> exit C3 (normal) + +# 30| enter get_P3 +#-----| -> null + +# 30| exit get_P3 + +# 30| exit get_P3 (abnormal) +#-----| -> exit get_P3 # 30| throw ... #-----| exception(NullReferenceException) -> exit get_P3 (abnormal) -#-----| exception(NullReferenceException) -> exit get_P3 (abnormal) # 30| null #-----| -> throw ... @@ -9747,16 +9887,35 @@ MultiImplementationA.cs: # 34| call to constructor Object #-----| -> {...} +# 34| enter C4 +#-----| -> call to constructor Object +#-----| -> call to constructor Object + +# 34| exit C4 + +# 34| exit C4 (normal) +#-----| -> exit C4 + # 34| {...} #-----| -> exit C4 (normal) -#-----| -> exit C4 (normal) + +# 36| enter M1 +#-----| -> {...} +#-----| -> 0 + +# 36| exit M1 + +# 36| exit M1 (abnormal) +#-----| -> exit M1 + +# 36| exit M1 (normal) +#-----| -> exit M1 # 36| {...} #-----| -> null # 36| throw ...; #-----| exception(NullReferenceException) -> exit M1 (abnormal) -#-----| exception(NullReferenceException) -> exit M1 (abnormal) # 36| null #-----| -> throw ...; @@ -9782,201 +9941,26 @@ MultiImplementationB.cs: # 1| call to constructor Object #-----| -> {...} -MultiImplementationA.cs: -# 4| enter C1 -#-----| -> call to constructor Object -#-----| -> call to constructor Object +# 1| {...} +#-----| -> exit C1 (normal) -MultiImplementationB.cs: -# 1| enter C1 -#-----| -> call to constructor Object -#-----| -> call to constructor Object +# 3| 0 +#-----| -> exit get_P1 (normal) -MultiImplementationA.cs: -# 4| exit C1 +# 4| {...} +#-----| -> 1 -MultiImplementationB.cs: -# 1| exit C1 - -MultiImplementationA.cs: -# 4| exit C1 (normal) -#-----| -> exit C1 -#-----| -> exit C1 - -MultiImplementationB.cs: -# 1| exit C1 (normal) -#-----| -> exit C1 -#-----| -> exit C1 - -# 1| {...} -#-----| -> exit C1 (normal) -#-----| -> exit C1 (normal) - -# 3| 0 -#-----| -> exit get_P1 (normal) -#-----| -> exit get_P1 (normal) - -MultiImplementationA.cs: -# 6| enter get_P1 -#-----| -> null -#-----| -> 0 - -MultiImplementationB.cs: -# 3| enter get_P1 -#-----| -> null -#-----| -> 0 - -MultiImplementationA.cs: -# 6| exit get_P1 - -MultiImplementationB.cs: -# 3| exit get_P1 - -MultiImplementationA.cs: -# 6| exit get_P1 (abnormal) -#-----| -> exit get_P1 -#-----| -> exit get_P1 - -MultiImplementationB.cs: -# 3| exit get_P1 (abnormal) -#-----| -> exit get_P1 -#-----| -> exit get_P1 - -MultiImplementationA.cs: -# 6| exit get_P1 (normal) -#-----| -> exit get_P1 -#-----| -> exit get_P1 - -MultiImplementationB.cs: -# 3| exit get_P1 (normal) -#-----| -> exit get_P1 -#-----| -> exit get_P1 - -MultiImplementationA.cs: -# 7| enter get_P2 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationB.cs: -# 4| enter get_P2 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationA.cs: -# 7| exit get_P2 - -MultiImplementationB.cs: -# 4| exit get_P2 - -MultiImplementationA.cs: -# 7| exit get_P2 (abnormal) -#-----| -> exit get_P2 -#-----| -> exit get_P2 - -MultiImplementationB.cs: -# 4| exit get_P2 (abnormal) -#-----| -> exit get_P2 -#-----| -> exit get_P2 - -MultiImplementationA.cs: -# 7| exit get_P2 (normal) -#-----| -> exit get_P2 -#-----| -> exit get_P2 - -MultiImplementationB.cs: -# 4| exit get_P2 (normal) -#-----| -> exit get_P2 -#-----| -> exit get_P2 - -# 4| {...} -#-----| -> 1 - -# 4| return ...; -#-----| return -> exit get_P2 (normal) -#-----| return -> exit get_P2 (normal) +# 4| return ...; +#-----| return -> exit get_P2 (normal) # 4| 1 #-----| -> return ...; -MultiImplementationA.cs: -# 7| enter set_P2 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationB.cs: -# 4| enter set_P2 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationA.cs: -# 7| exit set_P2 - -MultiImplementationB.cs: -# 4| exit set_P2 - -MultiImplementationA.cs: -# 7| exit set_P2 (abnormal) -#-----| -> exit set_P2 -#-----| -> exit set_P2 - -MultiImplementationB.cs: -# 4| exit set_P2 (abnormal) -#-----| -> exit set_P2 -#-----| -> exit set_P2 - -MultiImplementationA.cs: -# 7| exit set_P2 (normal) -#-----| -> exit set_P2 -#-----| -> exit set_P2 - -MultiImplementationB.cs: -# 4| exit set_P2 (normal) -#-----| -> exit set_P2 -#-----| -> exit set_P2 - # 4| {...} #-----| -> exit set_P2 (normal) -#-----| -> exit set_P2 (normal) - -MultiImplementationA.cs: -# 8| enter M -#-----| -> null -#-----| -> 2 - -MultiImplementationB.cs: -# 5| enter M -#-----| -> null -#-----| -> 2 - -MultiImplementationA.cs: -# 8| exit M - -MultiImplementationB.cs: -# 5| exit M - -MultiImplementationA.cs: -# 8| exit M (abnormal) -#-----| -> exit M -#-----| -> exit M - -MultiImplementationB.cs: -# 5| exit M (abnormal) -#-----| -> exit M -#-----| -> exit M - -MultiImplementationA.cs: -# 8| exit M (normal) -#-----| -> exit M -#-----| -> exit M - -MultiImplementationB.cs: -# 5| exit M (normal) -#-----| -> exit M -#-----| -> exit M # 5| 2 #-----| -> exit M (normal) -#-----| -> exit M (normal) # 11| this access #-----| -> 1 @@ -9987,151 +9971,29 @@ MultiImplementationB.cs: # 11| 1 #-----| -> ... = ... -MultiImplementationA.cs: -# 14| enter get_Item -#-----| -> access to parameter i -#-----| -> null - -MultiImplementationB.cs: -# 12| enter get_Item -#-----| -> access to parameter i -#-----| -> null - -MultiImplementationA.cs: -# 14| exit get_Item - -MultiImplementationB.cs: -# 12| exit get_Item - -MultiImplementationA.cs: -# 14| exit get_Item (abnormal) -#-----| -> exit get_Item -#-----| -> exit get_Item - -MultiImplementationB.cs: -# 12| exit get_Item (abnormal) -#-----| -> exit get_Item -#-----| -> exit get_Item - -MultiImplementationA.cs: -# 14| exit get_Item (normal) -#-----| -> exit get_Item -#-----| -> exit get_Item - -MultiImplementationB.cs: -# 12| exit get_Item (normal) -#-----| -> exit get_Item -#-----| -> exit get_Item - # 12| throw ... #-----| exception(NullReferenceException) -> exit get_Item (abnormal) -#-----| exception(NullReferenceException) -> exit get_Item (abnormal) # 12| null #-----| -> throw ... -MultiImplementationA.cs: -# 15| enter get_Item -#-----| -> {...} -#-----| -> {...} - -MultiImplementationB.cs: -# 13| enter get_Item -#-----| -> {...} -#-----| -> {...} - -MultiImplementationA.cs: -# 15| exit get_Item - -MultiImplementationB.cs: -# 13| exit get_Item - -MultiImplementationA.cs: -# 15| exit get_Item (abnormal) -#-----| -> exit get_Item -#-----| -> exit get_Item - -MultiImplementationB.cs: -# 13| exit get_Item (abnormal) -#-----| -> exit get_Item -#-----| -> exit get_Item - -MultiImplementationA.cs: -# 15| exit get_Item (normal) -#-----| -> exit get_Item -#-----| -> exit get_Item - -MultiImplementationB.cs: -# 13| exit get_Item (normal) -#-----| -> exit get_Item -#-----| -> exit get_Item - # 13| {...} #-----| -> null # 13| throw ...; #-----| exception(NullReferenceException) -> exit get_Item (abnormal) -#-----| exception(NullReferenceException) -> exit get_Item (abnormal) # 13| null #-----| -> throw ...; -MultiImplementationA.cs: -# 15| enter set_Item -#-----| -> {...} -#-----| -> {...} - -MultiImplementationB.cs: -# 13| enter set_Item -#-----| -> {...} -#-----| -> {...} - -MultiImplementationA.cs: -# 15| exit set_Item - -MultiImplementationB.cs: -# 13| exit set_Item - -MultiImplementationA.cs: -# 15| exit set_Item (normal) -#-----| -> exit set_Item -#-----| -> exit set_Item - -MultiImplementationB.cs: -# 13| exit set_Item (normal) -#-----| -> exit set_Item -#-----| -> exit set_Item - # 13| {...} #-----| -> exit set_Item (normal) -#-----| -> exit set_Item (normal) - -MultiImplementationA.cs: -# 16| enter M1 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationB.cs: -# 14| enter M1 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationA.cs: -# 16| exit M1 (normal) -#-----| -> exit M1 -#-----| -> exit M1 - -MultiImplementationB.cs: -# 14| exit M1 (normal) -#-----| -> exit M1 -#-----| -> exit M1 # 15| {...} #-----| -> M2(...) # 16| M2(...) #-----| -> exit M1 (normal) -#-----| -> exit M1 (normal) # 16| enter M2 #-----| -> null @@ -10150,78 +10012,15 @@ MultiImplementationB.cs: # 18| call to constructor Object #-----| -> this access -MultiImplementationA.cs: -# 20| enter C2 -#-----| -> call to constructor Object -#-----| -> call to constructor Object - -MultiImplementationB.cs: -# 18| enter C2 -#-----| -> call to constructor Object -#-----| -> call to constructor Object - -MultiImplementationA.cs: -# 20| exit C2 - -MultiImplementationB.cs: -# 18| exit C2 - -MultiImplementationA.cs: -# 20| exit C2 (abnormal) -#-----| -> exit C2 -#-----| -> exit C2 - -MultiImplementationB.cs: -# 18| exit C2 (abnormal) -#-----| -> exit C2 -#-----| -> exit C2 - -MultiImplementationA.cs: -# 20| exit C2 (normal) -#-----| -> exit C2 -#-----| -> exit C2 - -MultiImplementationB.cs: -# 18| exit C2 (normal) -#-----| -> exit C2 -#-----| -> exit C2 - # 18| {...} #-----| -> null # 18| throw ...; #-----| exception(NullReferenceException) -> exit C2 (abnormal) -#-----| exception(NullReferenceException) -> exit C2 (abnormal) # 18| null #-----| -> throw ...; -MultiImplementationA.cs: -# 21| enter C2 -#-----| -> 0 -#-----| -> 1 - -MultiImplementationB.cs: -# 19| enter C2 -#-----| -> 0 -#-----| -> 1 - -MultiImplementationA.cs: -# 21| exit C2 - -MultiImplementationB.cs: -# 19| exit C2 - -MultiImplementationA.cs: -# 21| exit C2 (normal) -#-----| -> exit C2 -#-----| -> exit C2 - -MultiImplementationB.cs: -# 19| exit C2 (normal) -#-----| -> exit C2 -#-----| -> exit C2 - # 19| call to constructor C2 #-----| -> {...} @@ -10230,93 +10029,18 @@ MultiImplementationB.cs: # 19| {...} #-----| -> exit C2 (normal) -#-----| -> exit C2 (normal) - -MultiImplementationA.cs: -# 22| enter ~C2 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationB.cs: -# 20| enter ~C2 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationA.cs: -# 22| exit ~C2 - -MultiImplementationB.cs: -# 20| exit ~C2 - -MultiImplementationA.cs: -# 22| exit ~C2 (abnormal) -#-----| -> exit ~C2 -#-----| -> exit ~C2 - -MultiImplementationB.cs: -# 20| exit ~C2 (abnormal) -#-----| -> exit ~C2 -#-----| -> exit ~C2 - -MultiImplementationA.cs: -# 22| exit ~C2 (normal) -#-----| -> exit ~C2 -#-----| -> exit ~C2 - -MultiImplementationB.cs: -# 20| exit ~C2 (normal) -#-----| -> exit ~C2 -#-----| -> exit ~C2 # 20| {...} #-----| -> null # 20| throw ...; #-----| exception(NullReferenceException) -> exit ~C2 (abnormal) -#-----| exception(NullReferenceException) -> exit ~C2 (abnormal) # 20| null #-----| -> throw ...; -MultiImplementationA.cs: -# 23| enter implicit conversion -#-----| -> null -#-----| -> null - -MultiImplementationB.cs: -# 21| enter implicit conversion -#-----| -> null -#-----| -> null - -MultiImplementationA.cs: -# 23| exit implicit conversion - -MultiImplementationB.cs: -# 21| exit implicit conversion - -MultiImplementationA.cs: -# 23| exit implicit conversion (abnormal) -#-----| -> exit implicit conversion -#-----| -> exit implicit conversion - -MultiImplementationB.cs: -# 21| exit implicit conversion (abnormal) -#-----| -> exit implicit conversion -#-----| -> exit implicit conversion - -MultiImplementationA.cs: -# 23| exit implicit conversion (normal) -#-----| -> exit implicit conversion -#-----| -> exit implicit conversion - -MultiImplementationB.cs: -# 21| exit implicit conversion (normal) -#-----| -> exit implicit conversion -#-----| -> exit implicit conversion - # 21| throw ... #-----| exception(NullReferenceException) -> exit implicit conversion (abnormal) -#-----| exception(NullReferenceException) -> exit implicit conversion (abnormal) # 21| null #-----| -> throw ... @@ -10336,132 +10060,17 @@ MultiImplementationB.cs: # 25| call to constructor Object #-----| -> {...} -MultiImplementationA.cs: -# 28| enter C3 -#-----| -> call to constructor Object -#-----| -> call to constructor Object - -MultiImplementationB.cs: -# 25| enter C3 -#-----| -> call to constructor Object -#-----| -> call to constructor Object - -MultiImplementationA.cs: -# 28| exit C3 - -MultiImplementationB.cs: -# 25| exit C3 - -MultiImplementationA.cs: -# 28| exit C3 (normal) -#-----| -> exit C3 -#-----| -> exit C3 - -MultiImplementationB.cs: -# 25| exit C3 (normal) -#-----| -> exit C3 -#-----| -> exit C3 - # 25| {...} #-----| -> exit C3 (normal) -#-----| -> exit C3 (normal) - -MultiImplementationA.cs: -# 30| enter get_P3 -#-----| -> null - -MultiImplementationB.cs: -# 27| enter get_P3 -#-----| -> null - -MultiImplementationA.cs: -# 30| exit get_P3 - -MultiImplementationB.cs: -# 27| exit get_P3 - -MultiImplementationA.cs: -# 30| exit get_P3 (abnormal) -#-----| -> exit get_P3 -#-----| -> exit get_P3 - -MultiImplementationB.cs: -# 27| exit get_P3 (abnormal) -#-----| -> exit get_P3 -#-----| -> exit get_P3 # 30| call to constructor Object #-----| -> {...} -MultiImplementationA.cs: -# 34| enter C4 -#-----| -> call to constructor Object -#-----| -> call to constructor Object - -MultiImplementationB.cs: -# 30| enter C4 -#-----| -> call to constructor Object -#-----| -> call to constructor Object - -MultiImplementationA.cs: -# 34| exit C4 - -MultiImplementationB.cs: -# 30| exit C4 - -MultiImplementationA.cs: -# 34| exit C4 (normal) -#-----| -> exit C4 -#-----| -> exit C4 - -MultiImplementationB.cs: -# 30| exit C4 (normal) -#-----| -> exit C4 -#-----| -> exit C4 - # 30| {...} #-----| -> exit C4 (normal) -#-----| -> exit C4 (normal) - -MultiImplementationA.cs: -# 36| enter M1 -#-----| -> {...} -#-----| -> 0 - -MultiImplementationB.cs: -# 32| enter M1 -#-----| -> {...} -#-----| -> 0 - -MultiImplementationA.cs: -# 36| exit M1 - -MultiImplementationB.cs: -# 32| exit M1 - -MultiImplementationA.cs: -# 36| exit M1 (abnormal) -#-----| -> exit M1 -#-----| -> exit M1 - -MultiImplementationB.cs: -# 32| exit M1 (abnormal) -#-----| -> exit M1 -#-----| -> exit M1 - -MultiImplementationA.cs: -# 36| exit M1 (normal) -#-----| -> exit M1 -#-----| -> exit M1 - -MultiImplementationB.cs: -# 32| exit M1 (normal) -#-----| -> exit M1 -#-----| -> exit M1 # 32| 0 #-----| -> exit M1 (normal) -#-----| -> exit M1 (normal) NullCoalescing.cs: # 1| call to constructor Object @@ -12374,6 +11983,9 @@ Switch.cs: # 131| return ...; #-----| return -> exit M12 (normal) +# 131| call to method ToString +#-----| -> return ...; + # 131| access to parameter o #-----| -> String s @@ -12406,9 +12018,6 @@ Switch.cs: # 131| null #-----| null -> [null] ... => ... -# 131| call to method ToString -#-----| -> return ...; - # 134| enter M13 #-----| -> {...} diff --git a/csharp/ql/test/library-tests/controlflow/graph/Nodes.expected b/csharp/ql/test/library-tests/controlflow/graph/Nodes.expected index 0dc443fa6236..72ad97ec2bb9 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Nodes.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/Nodes.expected @@ -1210,40 +1210,7 @@ entryPoint | MultiImplementationA.cs:36:9:36:10 | M1 | MultiImplementationA.cs:36:14:36:28 | {...} | | MultiImplementationA.cs:36:9:36:10 | M1 | MultiImplementationB.cs:32:17:32:17 | 0 | | MultiImplementationA.cs:37:9:37:10 | M2 | MultiImplementationA.cs:37:14:37:28 | {...} | -| MultiImplementationB.cs:1:7:1:8 | C1 | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | C1 | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationB.cs:3:22:3:22 | get_P1 | MultiImplementationA.cs:6:28:6:31 | null | -| MultiImplementationB.cs:3:22:3:22 | get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 | -| MultiImplementationB.cs:4:21:4:23 | get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} | -| MultiImplementationB.cs:4:21:4:23 | get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} | -| MultiImplementationB.cs:4:39:4:41 | set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} | -| MultiImplementationB.cs:4:39:4:41 | set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} | -| MultiImplementationB.cs:5:16:5:16 | M | MultiImplementationA.cs:8:29:8:32 | null | -| MultiImplementationB.cs:5:16:5:16 | M | MultiImplementationB.cs:5:23:5:23 | 2 | -| MultiImplementationB.cs:12:31:12:40 | get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i | -| MultiImplementationB.cs:12:31:12:40 | get_Item | MultiImplementationB.cs:12:37:12:40 | null | -| MultiImplementationB.cs:13:36:13:38 | get_Item | MultiImplementationA.cs:15:40:15:52 | {...} | -| MultiImplementationB.cs:13:36:13:38 | get_Item | MultiImplementationB.cs:13:40:13:54 | {...} | -| MultiImplementationB.cs:13:56:13:58 | set_Item | MultiImplementationA.cs:15:58:15:60 | {...} | -| MultiImplementationB.cs:13:56:13:58 | set_Item | MultiImplementationB.cs:13:60:13:62 | {...} | -| MultiImplementationB.cs:14:17:14:18 | M1 | MultiImplementationA.cs:17:5:19:5 | {...} | -| MultiImplementationB.cs:14:17:14:18 | M1 | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationB.cs:16:9:16:31 | M2 | MultiImplementationB.cs:16:27:16:30 | null | -| MultiImplementationB.cs:18:12:18:13 | C2 | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | -| MultiImplementationB.cs:18:12:18:13 | C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | -| MultiImplementationB.cs:19:12:19:13 | C2 | MultiImplementationA.cs:21:24:21:24 | 0 | -| MultiImplementationB.cs:19:12:19:13 | C2 | MultiImplementationB.cs:19:24:19:24 | 1 | -| MultiImplementationB.cs:20:6:20:7 | ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} | -| MultiImplementationB.cs:20:6:20:7 | ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} | -| MultiImplementationB.cs:21:28:21:35 | implicit conversion | MultiImplementationA.cs:23:50:23:53 | null | -| MultiImplementationB.cs:21:28:21:35 | implicit conversion | MultiImplementationB.cs:21:56:21:59 | null | -| MultiImplementationB.cs:25:7:25:8 | C3 | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | C3 | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationB.cs:27:21:27:23 | get_P3 | MultiImplementationA.cs:30:34:30:37 | null | -| MultiImplementationB.cs:30:15:30:16 | C4 | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | C4 | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationB.cs:32:9:32:10 | M1 | MultiImplementationA.cs:36:14:36:28 | {...} | -| MultiImplementationB.cs:32:9:32:10 | M1 | MultiImplementationB.cs:32:17:32:17 | 0 | | NullCoalescing.cs:1:7:1:20 | NullCoalescing | NullCoalescing.cs:1:7:1:20 | call to constructor Object | | NullCoalescing.cs:3:9:3:10 | M1 | NullCoalescing.cs:3:23:3:23 | access to parameter i | | NullCoalescing.cs:5:9:5:10 | M2 | NullCoalescing.cs:5:25:5:25 | access to parameter b | diff --git a/csharp/ql/test/library-tests/csharp7/TupleTypes.expected b/csharp/ql/test/library-tests/csharp7/TupleTypes.expected index d958ad60e4d1..9d7f3330151b 100644 --- a/csharp/ql/test/library-tests/csharp7/TupleTypes.expected +++ b/csharp/ql/test/library-tests/csharp7/TupleTypes.expected @@ -7,7 +7,6 @@ | (Int32,String) | (int, string) | ValueTuple | 2 | 0 | CSharp7.cs:95:19:95:19 | Item1 | | (Int32,String) | (int, string) | ValueTuple | 2 | 1 | CSharp7.cs:95:22:95:37 | Item2 | | (String,Int32) | (string, int) | ValueTuple | 2 | 0 | CSharp7.cs:82:17:82:17 | Item1 | -| (String,Int32) | (string, int) | ValueTuple | 2 | 0 | CSharp7.cs:101:19:101:38 | Item1 | | (String,Int32) | (string, int) | ValueTuple | 2 | 1 | CSharp7.cs:82:23:82:23 | Item2 | | (String,String) | (string, string) | ValueTuple | 2 | 0 | CSharp7.cs:87:19:87:27 | Item1 | | (String,String) | (string, string) | ValueTuple | 2 | 1 | CSharp7.cs:87:30:87:33 | Item2 | diff --git a/csharp/ql/test/library-tests/exprorstmtparent/Callable.expected b/csharp/ql/test/library-tests/exprorstmtparent/Callable.expected index 191dd35f9765..2de32e4ee009 100644 --- a/csharp/ql/test/library-tests/exprorstmtparent/Callable.expected +++ b/csharp/ql/test/library-tests/exprorstmtparent/Callable.expected @@ -34,39 +34,4 @@ | A.cs:36:9:36:10 | M1 | B.cs:32:17:32:17 | 0 | | A.cs:37:9:37:10 | M2 | A.cs:37:14:37:28 | {...} | | A.cs:37:9:37:10 | M2 | C.cs:3:17:3:17 | 0 | -| B.cs:1:7:1:8 | C1 | A.cs:4:7:4:8 | {...} | -| B.cs:1:7:1:8 | C1 | B.cs:1:7:1:8 | {...} | -| B.cs:3:22:3:22 | get_P1 | A.cs:6:22:6:31 | throw ... | -| B.cs:3:22:3:22 | get_P1 | B.cs:3:22:3:22 | 0 | -| B.cs:4:21:4:23 | get_P2 | A.cs:7:25:7:39 | {...} | -| B.cs:4:21:4:23 | get_P2 | B.cs:4:25:4:37 | {...} | -| B.cs:4:39:4:41 | set_P2 | A.cs:7:45:7:59 | {...} | -| B.cs:4:39:4:41 | set_P2 | B.cs:4:43:4:45 | {...} | -| B.cs:5:16:5:16 | M | A.cs:8:23:8:32 | throw ... | -| B.cs:5:16:5:16 | M | B.cs:5:23:5:23 | 2 | -| B.cs:12:31:12:40 | get_Item | A.cs:14:31:14:31 | access to parameter i | -| B.cs:12:31:12:40 | get_Item | B.cs:12:31:12:40 | throw ... | -| B.cs:13:36:13:38 | get_Item | A.cs:15:40:15:52 | {...} | -| B.cs:13:36:13:38 | get_Item | B.cs:13:40:13:54 | {...} | -| B.cs:13:56:13:58 | set_Item | A.cs:15:58:15:60 | {...} | -| B.cs:13:56:13:58 | set_Item | B.cs:13:60:13:62 | {...} | -| B.cs:14:17:14:18 | M1 | A.cs:17:5:19:5 | {...} | -| B.cs:14:17:14:18 | M1 | B.cs:15:5:17:5 | {...} | | B.cs:16:9:16:31 | M2 | B.cs:16:21:16:30 | throw ... | -| B.cs:18:12:18:13 | C2 | A.cs:20:22:20:31 | {...} | -| B.cs:18:12:18:13 | C2 | B.cs:18:22:18:36 | {...} | -| B.cs:19:12:19:13 | C2 | A.cs:21:27:21:29 | {...} | -| B.cs:19:12:19:13 | C2 | B.cs:19:27:19:29 | {...} | -| B.cs:20:6:20:7 | ~C2 | A.cs:22:11:22:13 | {...} | -| B.cs:20:6:20:7 | ~C2 | B.cs:20:11:20:25 | {...} | -| B.cs:21:28:21:35 | implicit conversion | A.cs:23:50:23:53 | null | -| B.cs:21:28:21:35 | implicit conversion | B.cs:21:50:21:59 | throw ... | -| B.cs:25:7:25:8 | C3 | A.cs:28:7:28:8 | {...} | -| B.cs:25:7:25:8 | C3 | B.cs:25:7:25:8 | {...} | -| B.cs:27:21:27:23 | get_P3 | A.cs:30:28:30:37 | throw ... | -| B.cs:32:9:32:10 | M1 | A.cs:36:14:36:28 | {...} | -| B.cs:32:9:32:10 | M1 | B.cs:32:17:32:17 | 0 | -| C.cs:1:15:1:16 | C4 | A.cs:34:15:34:16 | {...} | -| C.cs:1:15:1:16 | C4 | C.cs:1:15:1:16 | {...} | -| C.cs:3:9:3:10 | M2 | A.cs:37:14:37:28 | {...} | -| C.cs:3:9:3:10 | M2 | C.cs:3:17:3:17 | 0 | diff --git a/csharp/ql/test/library-tests/exprorstmtparent/Declaration.expected b/csharp/ql/test/library-tests/exprorstmtparent/Declaration.expected index 2bab92ce872b..a1df8e9dd0ff 100644 --- a/csharp/ql/test/library-tests/exprorstmtparent/Declaration.expected +++ b/csharp/ql/test/library-tests/exprorstmtparent/Declaration.expected @@ -38,45 +38,7 @@ | A.cs:34:15:34:16 | C4 | | A.cs:36:9:36:10 | M1 | | A.cs:37:9:37:10 | M2 | -| B.cs:1:7:1:8 | C1 | -| B.cs:3:16:3:17 | P1 | -| B.cs:3:22:3:22 | get_P1 | -| B.cs:4:16:4:17 | P2 | -| B.cs:4:21:4:23 | get_P2 | -| B.cs:4:39:4:41 | set_P2 | -| B.cs:4:39:4:41 | value | -| B.cs:5:16:5:16 | M | -| B.cs:9:7:9:8 | C2 | -| B.cs:11:16:11:16 | F | -| B.cs:12:16:12:19 | Item | -| B.cs:12:25:12:25 | i | -| B.cs:12:25:12:25 | i | -| B.cs:12:31:12:40 | get_Item | -| B.cs:13:19:13:22 | Item | -| B.cs:13:31:13:31 | s | -| B.cs:13:31:13:31 | s | -| B.cs:13:31:13:31 | s | -| B.cs:13:36:13:38 | get_Item | -| B.cs:13:56:13:58 | set_Item | -| B.cs:13:56:13:58 | value | -| B.cs:14:17:14:18 | M1 | -| B.cs:14:24:14:24 | i | | B.cs:16:9:16:31 | M2 | -| B.cs:18:12:18:13 | C2 | -| B.cs:18:19:18:19 | i | -| B.cs:19:12:19:13 | C2 | -| B.cs:20:6:20:7 | ~C2 | -| B.cs:21:28:21:35 | implicit conversion | -| B.cs:21:44:21:44 | i | -| B.cs:22:16:22:16 | P | -| B.cs:22:20:22:22 | get_P | -| B.cs:22:25:22:27 | set_P | -| B.cs:22:25:22:27 | value | -| B.cs:25:7:25:8 | C3 | -| B.cs:27:16:27:17 | P3 | -| B.cs:27:21:27:23 | get_P3 | | B.cs:30:15:30:16 | C4 | -| B.cs:32:9:32:10 | M1 | | C.cs:1:15:1:16 | C4 | -| C.cs:3:9:3:10 | M2 | | file://:0:0:0:0 | | diff --git a/csharp/ql/test/library-tests/exprorstmtparent/Indexer.expected b/csharp/ql/test/library-tests/exprorstmtparent/Indexer.expected index 2421dc75b7a5..260045e6eb9d 100644 --- a/csharp/ql/test/library-tests/exprorstmtparent/Indexer.expected +++ b/csharp/ql/test/library-tests/exprorstmtparent/Indexer.expected @@ -1,4 +1,2 @@ | A.cs:14:16:14:19 | Item | A.cs:14:31:14:31 | access to parameter i | | A.cs:14:16:14:19 | Item | B.cs:12:31:12:40 | throw ... | -| B.cs:12:16:12:19 | Item | A.cs:14:31:14:31 | access to parameter i | -| B.cs:12:16:12:19 | Item | B.cs:12:31:12:40 | throw ... | diff --git a/csharp/ql/test/library-tests/exprorstmtparent/Parameter.expected b/csharp/ql/test/library-tests/exprorstmtparent/Parameter.expected index 405336b42285..952b77bf3af5 100644 --- a/csharp/ql/test/library-tests/exprorstmtparent/Parameter.expected +++ b/csharp/ql/test/library-tests/exprorstmtparent/Parameter.expected @@ -1,4 +1,2 @@ | A.cs:16:24:16:24 | i | A.cs:16:28:16:28 | 0 | | A.cs:16:24:16:24 | i | B.cs:14:28:14:28 | 1 | -| B.cs:14:24:14:24 | i | A.cs:16:28:16:28 | 0 | -| B.cs:14:24:14:24 | i | B.cs:14:28:14:28 | 1 | diff --git a/csharp/ql/test/library-tests/exprorstmtparent/Property.expected b/csharp/ql/test/library-tests/exprorstmtparent/Property.expected index bf3e4797973d..3ffc55cfe3cb 100644 --- a/csharp/ql/test/library-tests/exprorstmtparent/Property.expected +++ b/csharp/ql/test/library-tests/exprorstmtparent/Property.expected @@ -2,7 +2,3 @@ | A.cs:6:16:6:17 | P1 | B.cs:3:22:3:22 | 0 | body | | A.cs:24:16:24:16 | P | A.cs:24:34:24:34 | 0 | initializer | | A.cs:24:16:24:16 | P | B.cs:22:34:22:34 | 1 | initializer | -| B.cs:3:16:3:17 | P1 | A.cs:6:22:6:31 | throw ... | body | -| B.cs:3:16:3:17 | P1 | B.cs:3:22:3:22 | 0 | body | -| B.cs:22:16:22:16 | P | A.cs:24:34:24:34 | 0 | initializer | -| B.cs:22:16:22:16 | P | B.cs:22:34:22:34 | 1 | initializer | diff --git a/csharp/ql/test/library-tests/extractor/tagstack/Bodies.expected b/csharp/ql/test/library-tests/extractor/tagstack/Bodies.expected index 147cd9914254..60c8b99a6d4c 100644 --- a/csharp/ql/test/library-tests/extractor/tagstack/Bodies.expected +++ b/csharp/ql/test/library-tests/extractor/tagstack/Bodies.expected @@ -1,2 +1 @@ | A.cs:5:12:5:13 | M1 | This method has multiple bodies. | -| B.cs:5:12:5:13 | M1 | This method has multiple bodies. | diff --git a/csharp/ql/test/library-tests/extractor/tagstack/Classes.expected b/csharp/ql/test/library-tests/extractor/tagstack/Classes.expected index 33c9f5a6b3d5..3163ed48abe9 100644 --- a/csharp/ql/test/library-tests/extractor/tagstack/Classes.expected +++ b/csharp/ql/test/library-tests/extractor/tagstack/Classes.expected @@ -1,2 +1 @@ | A.cs:3:7:3:7 | C | -| B.cs:3:7:3:7 | C | diff --git a/csharp/ql/test/library-tests/extractor/tagstack/Methods.expected b/csharp/ql/test/library-tests/extractor/tagstack/Methods.expected index 27a65e160d5d..664f3830acb3 100644 --- a/csharp/ql/test/library-tests/extractor/tagstack/Methods.expected +++ b/csharp/ql/test/library-tests/extractor/tagstack/Methods.expected @@ -1,4 +1,3 @@ | A.cs:5:12:5:13 | M1 | | A.cs:6:10:6:11 | M2 | -| B.cs:5:12:5:13 | M1 | | B.cs:6:10:6:11 | M3 | diff --git a/csharp/ql/test/library-tests/standalone/errorrecovery/ErrorTypes.expected b/csharp/ql/test/library-tests/standalone/errorrecovery/ErrorTypes.expected index bd9f2307b756..6de54b87ba87 100644 --- a/csharp/ql/test/library-tests/standalone/errorrecovery/ErrorTypes.expected +++ b/csharp/ql/test/library-tests/standalone/errorrecovery/ErrorTypes.expected @@ -13,10 +13,8 @@ | errors.cs:74:17:74:17 | x | Int32 | | errors.cs:75:17:75:17 | x | Int32 | | errors.cs:82:13:82:13 | F | Int32 | -| errors.cs:89:13:89:13 | F | Int32 | | errors.cs:91:29:91:29 | a | Func | | errors.cs:91:34:91:35 | x1 | Int32 | | errors.cs:91:38:91:39 | x2 | Int32 | -| errors.cs:92:29:92:29 | a | Func | | errors.cs:92:34:92:35 | y1 | Int32 | | errors.cs:92:38:92:39 | y2 | Int32 | diff --git a/csharp/ql/test/library-tests/standalone/errorrecovery/Methods.expected b/csharp/ql/test/library-tests/standalone/errorrecovery/Methods.expected index 54d152d2a8fc..a27ebd477de8 100644 --- a/csharp/ql/test/library-tests/standalone/errorrecovery/Methods.expected +++ b/csharp/ql/test/library-tests/standalone/errorrecovery/Methods.expected @@ -6,6 +6,5 @@ | errors.cs:67:22:67:22 | M | 0 | | errors.cs:72:22:72:22 | M | 0 | | errors.cs:81:18:81:22 | get_P | 0 | -| errors.cs:88:18:88:22 | get_P | 0 | | errors.cs:91:33:91:45 | (...) => ... | 0 | | errors.cs:92:33:92:45 | (...) => ... | 0 | diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.17.1.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.17.1.rst new file mode 100644 index 000000000000..e0e09d2a2270 --- /dev/null +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.17.1.rst @@ -0,0 +1,106 @@ +.. _codeql-cli-2.17.1: + +========================== +CodeQL 2.17.1 (2024-04-24) +========================== + +.. contents:: Contents + :depth: 2 + :local: + :backlinks: none + +This is an overview of changes in the CodeQL CLI and relevant CodeQL query and library packs. For additional updates on changes to the CodeQL code scanning experience, check out the `code scanning section on the GitHub blog `__, `relevant GitHub Changelog updates `__, `changes in the CodeQL extension for Visual Studio Code `__, and the `CodeQL Action changelog `__. + +Security Coverage +----------------- + +CodeQL 2.17.1 runs a total of 412 security queries when configured with the Default suite (covering 160 CWE). The Extended suite enables an additional 130 queries (covering 34 more CWE). 2 security queries have been added with this release. + +CodeQL CLI +---------- + +Deprecations +~~~~~~~~~~~~ + +* The :code:`--mode` option and :code:`-m` alias to :code:`codeql database create`, + :code:`codeql database cleanup`, and :code:`codeql dataset cleanup` has been deprecated. Instead, use the new :code:`--cache-cleanup` option, which has identical behavior. + +Improvements +~~~~~~~~~~~~ + +* Improved the diagnostic message produced when no code is processed when creating a database. If a build mode was specified using + :code:`--build-mode`, the message is now tailored to your build mode. + +Miscellaneous +~~~~~~~~~~~~~ + +* The :code:`scc` tool used by the CodeQL CLI to calculate source code baseline information has been updated to version `3.2.0 `__. + +Query Packs +----------- + +Minor Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Java +"""" + +* The :code:`java/unknown-javadoc-parameter` now accepts :code:`@param` tags that apply to the parameters of a record. + +JavaScript/TypeScript +""""""""""""""""""""" + +* :code:`API::Node#getInstance()` now includes instances of subclasses, include transitive subclasses. + The same changes applies to uses of the :code:`Instance` token in data extensions. + +New Queries +~~~~~~~~~~~ + +Ruby +"""" + +* Added a new query, :code:`rb/insecure-mass-assignment`, for finding instances of mass assignment operations accepting arbitrary parameters from remote user input. +* Added a new query, :code:`rb/csrf-protection-not-enabled`, to detect cases where Cross-Site Request Forgery protection is not enabled in Ruby on Rails controllers. + +Language Libraries +------------------ + +Minor Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +C# +"" + +* Extracting suppress nullable warning expressions did not work when applied directly to a method call (like :code:`System.Console.Readline()!`). This has been fixed. + +Golang +"""""" + +* Data flow through variables declared in statements of the form :code:`x := y.(type)` at the beginning of type switches has been fixed, which may result in more alerts. +* Added strings.ReplaceAll, http.ParseMultipartForm sanitizers and remove path sanitizer. + +Java +"""" + +* About 6,700 summary models and 6,800 neutral summary models for the JDK that were generated using data flow have been added. This may lead to new alerts being reported. + +Python +"""""" + +* Improved the type-tracking capabilities (and therefore also API graphs) to allow tracking items in tuples and dictionaries. + +Shared Libraries +---------------- + +New Features +~~~~~~~~~~~~ + +Dataflow Analysis +""""""""""""""""" + +* The :code:`PathGraph` result of a data flow computation has been augmented with model provenance information for each of the flow steps. Any qltests that include the edges relation in their output (for example, :code:`.qlref`\ s that reference path-problem queries) will need to be have their expected output updated accordingly. + +Type-flow Analysis +"""""""""""""""""" + +* Initial release. Adds a library to implement type-flow analysis. diff --git a/docs/codeql/codeql-overview/codeql-changelog/index.rst b/docs/codeql/codeql-overview/codeql-changelog/index.rst index 222e133ed190..3662d5fccff4 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/index.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/index.rst @@ -11,6 +11,7 @@ A list of queries for each suite and language `is available here = 0 +} + // Given a list of `go.mod` file paths, try to parse them all. The resulting array of `GoModule` objects // will be the same length as the input array and the objects will contain at least the `go.mod` path. // If parsing the corresponding file is successful, then the parsed contents will also be available. @@ -196,7 +203,7 @@ func LoadGoModules(emitDiagnostics bool, goModFilePaths []string) []*GoModule { continue } - modFile, err := modfile.ParseLax(goModFilePath, modFileSrc, nil) + modFile, err := modfile.Parse(goModFilePath, modFileSrc, nil) if err != nil { log.Printf("Unable to parse %s: %s.\n", goModFilePath, err.Error()) @@ -209,8 +216,7 @@ func LoadGoModules(emitDiagnostics bool, goModFilePaths []string) []*GoModule { // there is no `toolchain` directive, check that it is a valid Go toolchain version. Otherwise, // `go` commands which try to download the right version of the Go toolchain will fail. We detect // this situation and emit a diagnostic. - if modFile.Toolchain == nil && modFile.Go != nil && - !toolchainVersionRe.Match([]byte(modFile.Go.Version)) && semver.Compare("v"+modFile.Go.Version, "v1.21.0") >= 0 { + if hasInvalidToolchainVersion(modFile) { diagnostics.EmitInvalidToolchainVersion(goModFilePath, modFile.Go.Version) } } @@ -569,7 +575,7 @@ func getModMode(depMode DependencyInstallerMode, baseDir string) ModMode { // Tries to open `go.mod` and read a go directive, returning the version and whether it was found. // The version string is returned in the "1.2.3" format. func tryReadGoDirective(path string) GoVersionInfo { - versionRe := regexp.MustCompile(`(?m)^go[ \t\r]+([0-9]+\.[0-9]+(\.[0-9]+)?)$`) + versionRe := regexp.MustCompile(`(?m)^go[ \t\r]+([0-9]+\.[0-9]+(\.[0-9]+)?)`) goMod, err := os.ReadFile(path) if err != nil { log.Println("Failed to read go.mod to check for missing Go version") diff --git a/go/extractor/project/project_test.go b/go/extractor/project/project_test.go index f2de420773f9..b7485960b5fd 100644 --- a/go/extractor/project/project_test.go +++ b/go/extractor/project/project_test.go @@ -3,6 +3,8 @@ package project import ( "path/filepath" "testing" + + "golang.org/x/mod/modfile" ) func testStartsWithAnyOf(t *testing.T, path string, prefix string, expectation bool) { @@ -25,3 +27,38 @@ func TestStartsWithAnyOf(t *testing.T) { testStartsWithAnyOf(t, filepath.Join("foo", "bar"), "bar", false) testStartsWithAnyOf(t, filepath.Join("foo", "bar"), filepath.Join("foo", "baz"), false) } + +func testHasInvalidToolchainVersion(t *testing.T, contents string) bool { + modFile, err := modfile.Parse("test.go", []byte(contents), nil) + + if err != nil { + t.Errorf("Unable to parse %s: %s.\n", contents, err.Error()) + } + + return hasInvalidToolchainVersion(modFile) +} + +func TestHasInvalidToolchainVersion(t *testing.T) { + invalid := []string{ + "go 1.21\n", + "go 1.22\n", + } + + for _, v := range invalid { + if !testHasInvalidToolchainVersion(t, v) { + t.Errorf("Expected testHasInvalidToolchainVersion(\"%s\") to be true, but got false", v) + } + } + + valid := []string{ + "go 1.20\n", + "go 1.21.1\n", + "go 1.22\n\ntoolchain go1.22.0\n", + } + + for _, v := range valid { + if testHasInvalidToolchainVersion(t, v) { + t.Errorf("Expected testHasInvalidToolchainVersion(\"%s\") to be false, but got true", v) + } + } +} diff --git a/go/extractor/srcarchive/BUILD.bazel b/go/extractor/srcarchive/BUILD.bazel new file mode 100644 index 000000000000..e72e2e7ca08a --- /dev/null +++ b/go/extractor/srcarchive/BUILD.bazel @@ -0,0 +1,19 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "srcarchive", + srcs = [ + "projectlayout.go", + "srcarchive.go", + ], + importpath = "github.com/github/codeql-go/extractor/srcarchive", + visibility = ["//visibility:public"], +) + +go_test( + name = "srcarchive_test", + srcs = ["projectlayout_test.go"], + embed = [":srcarchive"], +) diff --git a/go/extractor/toolchain/BUILD.bazel b/go/extractor/toolchain/BUILD.bazel new file mode 100644 index 000000000000..fde8d327e9e2 --- /dev/null +++ b/go/extractor/toolchain/BUILD.bazel @@ -0,0 +1,20 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "toolchain", + srcs = ["toolchain.go"], + importpath = "github.com/github/codeql-go/extractor/toolchain", + visibility = ["//visibility:public"], + deps = [ + "//go/extractor/util", + "//go/extractor/vendor/golang.org/x/mod/semver", + ], +) + +go_test( + name = "toolchain_test", + srcs = ["toolchain_test.go"], + embed = [":toolchain"], +) diff --git a/go/extractor/trap/BUILD.bazel b/go/extractor/trap/BUILD.bazel new file mode 100644 index 000000000000..6cc7c4983b2e --- /dev/null +++ b/go/extractor/trap/BUILD.bazel @@ -0,0 +1,25 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "trap", + srcs = [ + "labels.go", + "trapwriter.go", + "util.go", + ], + importpath = "github.com/github/codeql-go/extractor/trap", + visibility = ["//visibility:public"], + deps = [ + "//go/extractor/srcarchive", + "//go/extractor/util", + "//go/extractor/vendor/golang.org/x/tools/go/packages", + ], +) + +go_test( + name = "trap_test", + srcs = ["trapwriter_test.go"], + embed = [":trap"], +) diff --git a/go/extractor/util/BUILD.bazel b/go/extractor/util/BUILD.bazel new file mode 100644 index 000000000000..8b8869cac524 --- /dev/null +++ b/go/extractor/util/BUILD.bazel @@ -0,0 +1,16 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "util", + srcs = ["util.go"], + importpath = "github.com/github/codeql-go/extractor/util", + visibility = ["//visibility:public"], +) + +go_test( + name = "util_test", + srcs = ["util_test.go"], + embed = [":util"], +) diff --git a/go/extractor/vendor/golang.org/x/mod/internal/lazyregexp/BUILD.bazel b/go/extractor/vendor/golang.org/x/mod/internal/lazyregexp/BUILD.bazel new file mode 100644 index 000000000000..deb5dc2b019a --- /dev/null +++ b/go/extractor/vendor/golang.org/x/mod/internal/lazyregexp/BUILD.bazel @@ -0,0 +1,11 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "lazyregexp", + srcs = ["lazyre.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/mod/internal/lazyregexp", + importpath = "golang.org/x/mod/internal/lazyregexp", + visibility = ["//go/extractor/vendor/golang.org/x/mod:__subpackages__"], +) diff --git a/go/extractor/vendor/golang.org/x/mod/modfile/BUILD.bazel b/go/extractor/vendor/golang.org/x/mod/modfile/BUILD.bazel new file mode 100644 index 000000000000..097bacb107ce --- /dev/null +++ b/go/extractor/vendor/golang.org/x/mod/modfile/BUILD.bazel @@ -0,0 +1,21 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "modfile", + srcs = [ + "print.go", + "read.go", + "rule.go", + "work.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/mod/modfile", + importpath = "golang.org/x/mod/modfile", + visibility = ["//visibility:public"], + deps = [ + "//go/extractor/vendor/golang.org/x/mod/internal/lazyregexp", + "//go/extractor/vendor/golang.org/x/mod/module", + "//go/extractor/vendor/golang.org/x/mod/semver", + ], +) diff --git a/go/extractor/vendor/golang.org/x/mod/module/BUILD.bazel b/go/extractor/vendor/golang.org/x/mod/module/BUILD.bazel new file mode 100644 index 000000000000..3bf5ae9997d1 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/mod/module/BUILD.bazel @@ -0,0 +1,18 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "module", + srcs = [ + "module.go", + "pseudo.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/mod/module", + importpath = "golang.org/x/mod/module", + visibility = ["//visibility:public"], + deps = [ + "//go/extractor/vendor/golang.org/x/mod/internal/lazyregexp", + "//go/extractor/vendor/golang.org/x/mod/semver", + ], +) diff --git a/go/extractor/vendor/golang.org/x/mod/semver/BUILD.bazel b/go/extractor/vendor/golang.org/x/mod/semver/BUILD.bazel new file mode 100644 index 000000000000..760be56c9e08 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/mod/semver/BUILD.bazel @@ -0,0 +1,11 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "semver", + srcs = ["semver.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/mod/semver", + importpath = "golang.org/x/mod/semver", + visibility = ["//visibility:public"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/go/gcexportdata/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/go/gcexportdata/BUILD.bazel new file mode 100644 index 000000000000..5d68c2fe989e --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/go/gcexportdata/BUILD.bazel @@ -0,0 +1,15 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "gcexportdata", + srcs = [ + "gcexportdata.go", + "importer.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/go/gcexportdata", + importpath = "golang.org/x/tools/go/gcexportdata", + visibility = ["//visibility:public"], + deps = ["//go/extractor/vendor/golang.org/x/tools/internal/gcimporter"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver/BUILD.bazel new file mode 100644 index 000000000000..2ef27e2c88af --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver/BUILD.bazel @@ -0,0 +1,12 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "packagesdriver", + srcs = ["sizes.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver", + importpath = "golang.org/x/tools/go/internal/packagesdriver", + visibility = ["//go/extractor/vendor/golang.org/x/tools/go:__subpackages__"], + deps = ["//go/extractor/vendor/golang.org/x/tools/internal/gocommand"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/go/packages/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/go/packages/BUILD.bazel new file mode 100644 index 000000000000..03d3e3b01585 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/go/packages/BUILD.bazel @@ -0,0 +1,27 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "packages", + srcs = [ + "doc.go", + "external.go", + "golist.go", + "golist_overlay.go", + "loadmode_string.go", + "packages.go", + "visit.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/go/packages", + importpath = "golang.org/x/tools/go/packages", + visibility = ["//visibility:public"], + deps = [ + "//go/extractor/vendor/golang.org/x/tools/go/gcexportdata", + "//go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver", + "//go/extractor/vendor/golang.org/x/tools/internal/gocommand", + "//go/extractor/vendor/golang.org/x/tools/internal/packagesinternal", + "//go/extractor/vendor/golang.org/x/tools/internal/typesinternal", + "//go/extractor/vendor/golang.org/x/tools/internal/versions", + ], +) diff --git a/go/extractor/vendor/golang.org/x/tools/go/types/objectpath/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/go/types/objectpath/BUILD.bazel new file mode 100644 index 000000000000..374c5c601bc8 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/go/types/objectpath/BUILD.bazel @@ -0,0 +1,12 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "objectpath", + srcs = ["objectpath.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/go/types/objectpath", + importpath = "golang.org/x/tools/go/types/objectpath", + visibility = ["//visibility:public"], + deps = ["//go/extractor/vendor/golang.org/x/tools/internal/typeparams"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/BUILD.bazel new file mode 100644 index 000000000000..200e436fcd4b --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/BUILD.bazel @@ -0,0 +1,19 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "event", + srcs = [ + "doc.go", + "event.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/event", + importpath = "golang.org/x/tools/internal/event", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], + deps = [ + "//go/extractor/vendor/golang.org/x/tools/internal/event/core", + "//go/extractor/vendor/golang.org/x/tools/internal/event/keys", + "//go/extractor/vendor/golang.org/x/tools/internal/event/label", + ], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/core/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/core/BUILD.bazel new file mode 100644 index 000000000000..a16713f536ce --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/core/BUILD.bazel @@ -0,0 +1,19 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "core", + srcs = [ + "event.go", + "export.go", + "fast.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/event/core", + importpath = "golang.org/x/tools/internal/event/core", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], + deps = [ + "//go/extractor/vendor/golang.org/x/tools/internal/event/keys", + "//go/extractor/vendor/golang.org/x/tools/internal/event/label", + ], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/keys/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/keys/BUILD.bazel new file mode 100644 index 000000000000..1feefdf1a834 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/keys/BUILD.bazel @@ -0,0 +1,16 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "keys", + srcs = [ + "keys.go", + "standard.go", + "util.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/event/keys", + importpath = "golang.org/x/tools/internal/event/keys", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], + deps = ["//go/extractor/vendor/golang.org/x/tools/internal/event/label"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/label/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/label/BUILD.bazel new file mode 100644 index 000000000000..a4430ba0a17c --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/label/BUILD.bazel @@ -0,0 +1,11 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "label", + srcs = ["label.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/event/label", + importpath = "golang.org/x/tools/internal/event/label", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/tag/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/tag/BUILD.bazel new file mode 100644 index 000000000000..d2c87f41a8ae --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/tag/BUILD.bazel @@ -0,0 +1,12 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "tag", + srcs = ["tag.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/event/tag", + importpath = "golang.org/x/tools/internal/event/tag", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], + deps = ["//go/extractor/vendor/golang.org/x/tools/internal/event/keys"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/gcimporter/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/gcimporter/BUILD.bazel new file mode 100644 index 000000000000..56da3b0130e2 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/gcimporter/BUILD.bazel @@ -0,0 +1,29 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "gcimporter", + srcs = [ + "bimport.go", + "exportdata.go", + "gcimporter.go", + "iexport.go", + "iimport.go", + "newInterface10.go", + "newInterface11.go", + "support_go117.go", + "support_go118.go", + "unified_no.go", + "ureader_no.go", + "ureader_yes.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/gcimporter", + importpath = "golang.org/x/tools/internal/gcimporter", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], + deps = [ + "//go/extractor/vendor/golang.org/x/tools/go/types/objectpath", + "//go/extractor/vendor/golang.org/x/tools/internal/pkgbits", + "//go/extractor/vendor/golang.org/x/tools/internal/tokeninternal", + ], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/gocommand/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/gocommand/BUILD.bazel new file mode 100644 index 000000000000..7e64f94b95cb --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/gocommand/BUILD.bazel @@ -0,0 +1,22 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "gocommand", + srcs = [ + "invoke.go", + "vendor.go", + "version.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/gocommand", + importpath = "golang.org/x/tools/internal/gocommand", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], + deps = [ + "//go/extractor/vendor/golang.org/x/mod/semver", + "//go/extractor/vendor/golang.org/x/tools/internal/event", + "//go/extractor/vendor/golang.org/x/tools/internal/event/keys", + "//go/extractor/vendor/golang.org/x/tools/internal/event/label", + "//go/extractor/vendor/golang.org/x/tools/internal/event/tag", + ], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/packagesinternal/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/packagesinternal/BUILD.bazel new file mode 100644 index 000000000000..2d2b7dc5b33c --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/packagesinternal/BUILD.bazel @@ -0,0 +1,11 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "packagesinternal", + srcs = ["packages.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/packagesinternal", + importpath = "golang.org/x/tools/internal/packagesinternal", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/pkgbits/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/pkgbits/BUILD.bazel new file mode 100644 index 000000000000..cce327470517 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/pkgbits/BUILD.bazel @@ -0,0 +1,23 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "pkgbits", + srcs = [ + "codes.go", + "decoder.go", + "doc.go", + "encoder.go", + "flags.go", + "frames_go1.go", + "frames_go17.go", + "reloc.go", + "support.go", + "sync.go", + "syncmarker_string.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/pkgbits", + importpath = "golang.org/x/tools/internal/pkgbits", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/tokeninternal/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/tokeninternal/BUILD.bazel new file mode 100644 index 000000000000..c0f6cc8fb13a --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/tokeninternal/BUILD.bazel @@ -0,0 +1,11 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "tokeninternal", + srcs = ["tokeninternal.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/tokeninternal", + importpath = "golang.org/x/tools/internal/tokeninternal", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/typeparams/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/typeparams/BUILD.bazel new file mode 100644 index 000000000000..9c2dc20b6c65 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/typeparams/BUILD.bazel @@ -0,0 +1,17 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "typeparams", + srcs = [ + "common.go", + "coretype.go", + "normalize.go", + "termlist.go", + "typeterm.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/typeparams", + importpath = "golang.org/x/tools/internal/typeparams", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/typesinternal/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/typesinternal/BUILD.bazel new file mode 100644 index 000000000000..653752ab7152 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/typesinternal/BUILD.bazel @@ -0,0 +1,16 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "typesinternal", + srcs = [ + "errorcode.go", + "errorcode_string.go", + "types.go", + "types_118.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/typesinternal", + importpath = "golang.org/x/tools/internal/typesinternal", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/versions/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/versions/BUILD.bazel new file mode 100644 index 000000000000..85d428debf54 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/versions/BUILD.bazel @@ -0,0 +1,17 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "versions", + srcs = [ + "gover.go", + "types.go", + "types_go121.go", + "types_go122.go", + "versions.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/versions", + importpath = "golang.org/x/tools/internal/versions", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], +) diff --git a/go/extractor/vendor/modules.txt b/go/extractor/vendor/modules.txt index 5687615f62c3..37c4a68d828d 100644 --- a/go/extractor/vendor/modules.txt +++ b/go/extractor/vendor/modules.txt @@ -1,3 +1,4 @@ +## workspace # golang.org/x/mod v0.15.0 ## explicit; go 1.18 golang.org/x/mod/internal/lazyregexp diff --git a/go/gen.py b/go/gen.py new file mode 100644 index 000000000000..6f8d47d70962 --- /dev/null +++ b/go/gen.py @@ -0,0 +1,75 @@ +""" +Update generated files related to Go in the repo. Using --force will regenerate all files from scratch. + +In particular the script will: +1. update the `vendor` dir with `go work vendor` (using a go toolchain provided by bazel) +2. update `BUILD.bazel` files using gazelle +3. update `ql/lib/go.dbscheme` using a compiled `go-dbschemegen` +""" + +import sys +import pathlib +import subprocess +import os +import argparse +import shutil +from python.runfiles import runfiles + +def options(): + p = argparse.ArgumentParser(description="Update generated files related to Go in the repo") + p.add_argument("--force", "-f", action="store_true", help="Regenerate all files from scratch rather than updating them") + p.add_argument("executables", nargs=3, help="Internally provided executables") + return p.parse_args() + +opts = options() + +try: + workspace_dir = pathlib.Path(os.environ.pop('BUILD_WORKSPACE_DIRECTORY')) +except KeyError: + print("this should be run with bazel run", file=sys.stderr) + sys.exit(1) + +go_extractor_dir = workspace_dir / "go" / "extractor" + +if not go_extractor_dir.exists(): + # internal repo? + workspace_dir /= "ql" + go_extractor_dir = workspace_dir / "go" / "extractor" + +go_dbscheme = workspace_dir / "go" / "ql" / "lib" / "go.dbscheme" +r = runfiles.Create() +go, gazelle, go_gen_dbscheme = map(r.Rlocation, opts.executables) + + +if opts.force: + print("clearing vendor directory") + shutil.rmtree(go_extractor_dir / "vendor") + +existing_build_files = set(go_extractor_dir.glob("*/**/BUILD.bazel")) + +print("updating vendor directory") +subprocess.check_call([go, "-C", go_extractor_dir, "work", "vendor"]) + +if opts.force: + print("clearing generated BUILD files") + for build_file in existing_build_files: + build_file.unlink() + +print("running gazelle", gazelle, go_extractor_dir) +subprocess.check_call([gazelle, "go/extractor"], cwd=workspace_dir) + +# we want to stamp all newly generated `BUILD.bazel` files with a header +build_files_to_update = set(go_extractor_dir.glob("*/**/BUILD.bazel")) +# if --force, all files are new +if not opts.force: + # otherwise, subtract the files that existed at the start + build_files_to_update -= existing_build_files + # but bring back the `vendor` ones, as the vendor update step always clears them + build_files_to_update.update(go_extractor_dir.glob("vendor/**/BUILD.bazel")) + +print("adding header to newly generated BUILD files") +for build_file in build_files_to_update: + contents = build_file.read_text() + build_file.write_text(f"# generated running `bazel run //go/gazelle`, do not edit\n\n{contents}") + +subprocess.check_call([go_gen_dbscheme, go_dbscheme]) diff --git a/go/ql/consistency-queries/CHANGELOG.md b/go/ql/consistency-queries/CHANGELOG.md index 29ece641a7e3..ad4781e2cbda 100644 --- a/go/ql/consistency-queries/CHANGELOG.md +++ b/go/ql/consistency-queries/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.14 + +No user-facing changes. + ## 0.0.13 No user-facing changes. diff --git a/go/ql/consistency-queries/change-notes/released/0.0.14.md b/go/ql/consistency-queries/change-notes/released/0.0.14.md new file mode 100644 index 000000000000..63b4d50ca454 --- /dev/null +++ b/go/ql/consistency-queries/change-notes/released/0.0.14.md @@ -0,0 +1,3 @@ +## 0.0.14 + +No user-facing changes. diff --git a/go/ql/consistency-queries/codeql-pack.release.yml b/go/ql/consistency-queries/codeql-pack.release.yml index 044e54e4f7e5..ca29e45d0a67 100644 --- a/go/ql/consistency-queries/codeql-pack.release.yml +++ b/go/ql/consistency-queries/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.13 +lastReleaseVersion: 0.0.14 diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index 7744027ba9f5..f56add92e15b 100644 --- a/go/ql/consistency-queries/qlpack.yml +++ b/go/ql/consistency-queries/qlpack.yml @@ -1,5 +1,5 @@ name: codeql-go-consistency-queries -version: 0.0.14-dev +version: 0.0.15-dev groups: - go - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index fdfa26c8d4c0..de0b40c8648d 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,14 @@ +## 0.8.0 + +### Breaking Changes + +* Deleted the deprecated `CsvRemoteSource` alias. Use `MaDRemoteSource` instead. + +### Deprecated APIs + +* To make Go consistent with other language libraries, the `UntrustedFlowSource` name has been deprecated throughout. Use `RemoteFlowSource` instead, which replaces it. +* Where modules have classes named `UntrustedFlowAsSource`, these are also deprecated and the `Source` class in the same module or the `RemoteFlowSource` class should be used instead. + ## 0.7.14 ### Minor Analysis Improvements diff --git a/go/ql/lib/change-notes/2024-04-18-untrustedflowsource-renamed-remoteflowsource.md b/go/ql/lib/change-notes/released/0.8.0.md similarity index 72% rename from go/ql/lib/change-notes/2024-04-18-untrustedflowsource-renamed-remoteflowsource.md rename to go/ql/lib/change-notes/released/0.8.0.md index cb3edc34d848..829bdac7b08c 100644 --- a/go/ql/lib/change-notes/2024-04-18-untrustedflowsource-renamed-remoteflowsource.md +++ b/go/ql/lib/change-notes/released/0.8.0.md @@ -1,5 +1,10 @@ ---- -category: deprecated ---- +## 0.8.0 + +### Breaking Changes + +* Deleted the deprecated `CsvRemoteSource` alias. Use `MaDRemoteSource` instead. + +### Deprecated APIs + * To make Go consistent with other language libraries, the `UntrustedFlowSource` name has been deprecated throughout. Use `RemoteFlowSource` instead, which replaces it. * Where modules have classes named `UntrustedFlowAsSource`, these are also deprecated and the `Source` class in the same module or the `RemoteFlowSource` class should be used instead. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 2189dcea5188..37eab3197dcb 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.14 +lastReleaseVersion: 0.8.0 diff --git a/go/ql/lib/ext/dummy.model.yml b/go/ql/lib/ext/empty.model.yml similarity index 66% rename from go/ql/lib/ext/dummy.model.yml rename to go/ql/lib/ext/empty.model.yml index e04298be8ba4..03279fc65880 100644 --- a/go/ql/lib/ext/dummy.model.yml +++ b/go/ql/lib/ext/empty.model.yml @@ -1,5 +1,6 @@ extensions: - # Make sure that the extensible model predicates are at least defined as empty. + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about undefined extensionals. - addsTo: pack: codeql/go-all extensible: sourceModel diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 9af680ede6f1..53780e3ecee3 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.7.15-dev +version: 0.8.1-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/lib/semmle/go/security/FlowSources.qll b/go/ql/lib/semmle/go/security/FlowSources.qll index 6de620c79e42..cf77dade35ab 100644 --- a/go/ql/lib/semmle/go/security/FlowSources.qll +++ b/go/ql/lib/semmle/go/security/FlowSources.qll @@ -39,6 +39,4 @@ module RemoteFlowSource { class MaDRemoteSource extends Range { MaDRemoteSource() { ExternalFlow::sourceNode(this, "remote") } } - - deprecated class CsvRemoteSource = MaDRemoteSource; } diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index e5c2f9589d77..0364ec221d40 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.7.15 + +### Minor Analysis Improvements + +* The query `go/incomplete-hostname-regexp` now recognizes more sources involving concatenation of string literals and also follows flow through string concatenation. This may lead to more alerts. +* Added some more barriers to flow for `go/incorrect-integer-conversion` to reduce false positives, especially around type switches. + ## 0.7.14 No user-facing changes. diff --git a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql index 48731179127e..03018ee1c32d 100644 --- a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql +++ b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql @@ -81,14 +81,12 @@ predicate regexpGuardsError(RegexpPattern regexp) { module IncompleteHostNameRegexpConfig implements DataFlow::ConfigSig { additional predicate isSourceString(DataFlow::Node source, string hostPart) { - exists(Expr e | - e = source.asExpr() and - isIncompleteHostNameRegexpPattern(e.getStringValue(), hostPart) - | - e instanceof StringLit - or - e instanceof AddExpr and - not isIncompleteHostNameRegexpPattern(e.(AddExpr).getAnOperand().getStringValue(), _) + exists(Expr e | e = source.asExpr() | + isIncompleteHostNameRegexpPattern(e.getStringValue(), hostPart) and + // Exclude constant names to avoid duplicate results, because the string + // literals which they are initialised with are also considered as + // sources. + not e instanceof ConstantName ) } @@ -101,6 +99,10 @@ module IncompleteHostNameRegexpConfig implements DataFlow::ConfigSig { ) and not regexpGuardsError(sink) } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + StringOps::Concatenation::taintStep(node1, node2) + } } module Flow = DataFlow::Global; diff --git a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexpGood2.go b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexpGood2.go index 7c5df3f67426..c6c3fc069815 100644 --- a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexpGood2.go +++ b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexpGood2.go @@ -6,7 +6,7 @@ import ( "regexp" ) -func checkRedirectGood(req *http.Request, via []*http.Request) error { +func checkRedirectGood2(req *http.Request, via []*http.Request) error { // GOOD: the host of `req.URL` must be `example.com`, `www.example.com` or `beta.example.com` re := `^((www|beta)\.)?example\.com/` if matched, _ := regexp.MatchString(re, req.URL.Host); matched { diff --git a/go/ql/src/change-notes/2024-04-17-incorrect-integer-conversion-barriers.md b/go/ql/src/change-notes/2024-04-17-incorrect-integer-conversion-barriers.md deleted file mode 100644 index 7453f2bef5c5..000000000000 --- a/go/ql/src/change-notes/2024-04-17-incorrect-integer-conversion-barriers.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added some more barriers to flow for `go/incorrect-integer-conversion` to reduce false positives, especially around type switches. diff --git a/go/ql/src/change-notes/released/0.7.15.md b/go/ql/src/change-notes/released/0.7.15.md new file mode 100644 index 000000000000..5672b61cc772 --- /dev/null +++ b/go/ql/src/change-notes/released/0.7.15.md @@ -0,0 +1,6 @@ +## 0.7.15 + +### Minor Analysis Improvements + +* The query `go/incomplete-hostname-regexp` now recognizes more sources involving concatenation of string literals and also follows flow through string concatenation. This may lead to more alerts. +* Added some more barriers to flow for `go/incorrect-integer-conversion` to reduce false positives, especially around type switches. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 2189dcea5188..e56b7f6a7b1d 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.14 +lastReleaseVersion: 0.7.15 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 63c52f6fb9fe..121ba9674729 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.7.15-dev +version: 0.7.16-dev groups: - go - queries diff --git a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected index 4486b4e0962f..c9ba782fd56b 100644 --- a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected @@ -1,12 +1,22 @@ edges | IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:12:38:12:39 | re | provenance | | +| main.go:49:21:49:45 | `https://www.example.com` | main.go:62:15:62:25 | sourceConst | provenance | | +| main.go:62:15:62:25 | sourceConst | main.go:65:15:65:23 | localVar3 | provenance | | nodes | IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | semmle.label | "^((www\|beta).)?example.com/" | | IncompleteHostnameRegexp.go:12:38:12:39 | re | semmle.label | re | -| main.go:39:60:39:79 | "^test2.github.com$" | semmle.label | "^test2.github.com$" | -| main.go:44:15:44:39 | `https://www.example.com` | semmle.label | `https://www.example.com` | +| main.go:40:60:40:79 | "^test2.github.com$" | semmle.label | "^test2.github.com$" | +| main.go:45:15:45:39 | `https://www.example.com` | semmle.label | `https://www.example.com` | +| main.go:49:21:49:45 | `https://www.example.com` | semmle.label | `https://www.example.com` | +| main.go:56:15:56:34 | ...+... | semmle.label | ...+... | +| main.go:58:15:58:42 | ...+... | semmle.label | ...+... | +| main.go:62:15:62:25 | sourceConst | semmle.label | sourceConst | +| main.go:65:15:65:23 | localVar3 | semmle.label | localVar3 | subpaths #select | IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:12:38:12:39 | re | This regular expression has an unescaped dot before ')?example.com', so it might match more hosts than expected when $@. | IncompleteHostnameRegexp.go:12:38:12:39 | re | the regular expression is used | -| main.go:39:60:39:79 | "^test2.github.com$" | main.go:39:60:39:79 | "^test2.github.com$" | main.go:39:60:39:79 | "^test2.github.com$" | This regular expression has an unescaped dot before 'github.com', so it might match more hosts than expected when $@. | main.go:39:60:39:79 | "^test2.github.com$" | the regular expression is used | -| main.go:44:15:44:39 | `https://www.example.com` | main.go:44:15:44:39 | `https://www.example.com` | main.go:44:15:44:39 | `https://www.example.com` | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:44:15:44:39 | `https://www.example.com` | the regular expression is used | +| main.go:40:60:40:79 | "^test2.github.com$" | main.go:40:60:40:79 | "^test2.github.com$" | main.go:40:60:40:79 | "^test2.github.com$" | This regular expression has an unescaped dot before 'github.com', so it might match more hosts than expected when $@. | main.go:40:60:40:79 | "^test2.github.com$" | the regular expression is used | +| main.go:45:15:45:39 | `https://www.example.com` | main.go:45:15:45:39 | `https://www.example.com` | main.go:45:15:45:39 | `https://www.example.com` | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:45:15:45:39 | `https://www.example.com` | the regular expression is used | +| main.go:49:21:49:45 | `https://www.example.com` | main.go:49:21:49:45 | `https://www.example.com` | main.go:65:15:65:23 | localVar3 | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:65:15:65:23 | localVar3 | the regular expression is used | +| main.go:56:15:56:34 | ...+... | main.go:56:15:56:34 | ...+... | main.go:56:15:56:34 | ...+... | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:56:15:56:34 | ...+... | the regular expression is used | +| main.go:58:15:58:42 | ...+... | main.go:58:15:58:42 | ...+... | main.go:58:15:58:42 | ...+... | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:58:15:58:42 | ...+... | the regular expression is used | diff --git a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexpGood2.go b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexpGood2.go new file mode 100644 index 000000000000..c6c3fc069815 --- /dev/null +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexpGood2.go @@ -0,0 +1,16 @@ +package main + +import ( + "errors" + "net/http" + "regexp" +) + +func checkRedirectGood2(req *http.Request, via []*http.Request) error { + // GOOD: the host of `req.URL` must be `example.com`, `www.example.com` or `beta.example.com` + re := `^((www|beta)\.)?example\.com/` + if matched, _ := regexp.MatchString(re, req.URL.Host); matched { + return nil + } + return errors.New("Invalid redirect") +} diff --git a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/main.go b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/main.go index fb1e5b77b516..7eda0d7255a2 100644 --- a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/main.go +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/main.go @@ -3,10 +3,11 @@ package main import ( - "github.com/elazarl/goproxy" "net/http" "regexp" "time" + + "github.com/elazarl/goproxy" ) func Match(notARegex string) bool { @@ -44,3 +45,22 @@ func main() { regexp.Match(`https://www.example.com`, []byte("")) // NOT OK regexp.Match(`https://www\.example\.com`, []byte("")) // OK } + +const sourceConst = `https://www.example.com` +const firstHalfConst = `https://www.example.` + +func concatenateStrings() { + firstHalf := `https://www.example.` + regexp.Match(firstHalf+`com`, []byte("")) // MISSING: NOT OK + + regexp.Match(firstHalfConst+`com`, []byte("")) // NOT OK + + regexp.Match(`https://www.example.`+`com`, []byte("")) // NOT OK +} + +func avoidDuplicateResults() { + localVar1 := sourceConst + localVar2 := localVar1 + localVar3 := localVar2 + regexp.Match(localVar3, []byte("")) // NOT OK +} diff --git a/go/rules.bzl b/go/rules.bzl new file mode 100644 index 000000000000..e26dd57bf449 --- /dev/null +++ b/go/rules.bzl @@ -0,0 +1,37 @@ +load("@rules_go//go:def.bzl", "go_binary", "go_cross_binary") + +def codeql_go_binary(*, name, visibility = None, **kwargs): + def internal(prefix = "internal"): + return "%s/%s" % (prefix, name) + + go_binary( + name = internal(), + visibility = ["//visibility:private"], + **kwargs + ) + macos_targets = ("darwin_arm64", "darwin_amd64") + for target in macos_targets: + go_cross_binary( + name = internal(target), + platform = "@rules_go//go/toolchain:%s" % target, + target = internal(), + target_compatible_with = ["@platforms//os:macos"], + visibility = ["//visibility:private"], + ) + native.genrule( + name = internal("universal"), + outs = [internal("universal_")], + srcs = [internal(t) for t in macos_targets], + target_compatible_with = ["@platforms//os:macos"], + executable = True, + visibility = ["//visibility:private"], + cmd = "lipo -create $(SRCS) -output $@", + ) + native.alias( + name = name, + actual = select({ + "@platforms//os:macos": internal("universal"), + "//conditions:default": internal(), + }), + visibility = visibility, + ) diff --git a/java/kotlin-extractor/src/main/java/com/semmle/util/process/Env.java b/java/kotlin-extractor/src/main/java/com/semmle/util/process/Env.java index 0ce3d42c14f0..71a03b0bf45a 100644 --- a/java/kotlin-extractor/src/main/java/com/semmle/util/process/Env.java +++ b/java/kotlin-extractor/src/main/java/com/semmle/util/process/Env.java @@ -276,7 +276,6 @@ public enum Var { */ ODASA_SRC, ODASA_DB, - ODASA_BUILD_ERROR_DIR, TRAP_FOLDER, SOURCE_ARCHIVE, ODASA_OUTPUT, diff --git a/java/ql/automodel/src/CHANGELOG.md b/java/ql/automodel/src/CHANGELOG.md index 7b0018f30363..d8475687370d 100644 --- a/java/ql/automodel/src/CHANGELOG.md +++ b/java/ql/automodel/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.22 + +No user-facing changes. + ## 0.0.21 No user-facing changes. diff --git a/java/ql/automodel/src/change-notes/released/0.0.22.md b/java/ql/automodel/src/change-notes/released/0.0.22.md new file mode 100644 index 000000000000..002267474382 --- /dev/null +++ b/java/ql/automodel/src/change-notes/released/0.0.22.md @@ -0,0 +1,3 @@ +## 0.0.22 + +No user-facing changes. diff --git a/java/ql/automodel/src/codeql-pack.release.yml b/java/ql/automodel/src/codeql-pack.release.yml index 0c15c351db40..11aaa2243f57 100644 --- a/java/ql/automodel/src/codeql-pack.release.yml +++ b/java/ql/automodel/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.21 +lastReleaseVersion: 0.0.22 diff --git a/java/ql/automodel/src/qlpack.yml b/java/ql/automodel/src/qlpack.yml index 300f0cb5d0b5..79c6f172bcc2 100644 --- a/java/ql/automodel/src/qlpack.yml +++ b/java/ql/automodel/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-automodel-queries -version: 0.0.22-dev +version: 0.0.23-dev groups: - java - automodel diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 7c86037ae04c..4265865ea374 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.10.0 + +### Breaking Changes + +* Deleted the deprecated `AssignLShiftExpr`, `AssignRShiftExpr`, `AssignURShiftExpr`, `LShiftExpr`, `RShiftExpr`, and `URShiftExpr` aliases. + ## 0.9.1 ### Minor Analysis Improvements diff --git a/java/ql/lib/change-notes/2024-04-26-env-vars.md b/java/ql/lib/change-notes/2024-04-26-env-vars.md new file mode 100644 index 000000000000..cb2003740ef2 --- /dev/null +++ b/java/ql/lib/change-notes/2024-04-26-env-vars.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* The Java extractor no longer supports the `ODASA_BUILD_ERROR_DIR` legacy environment variable. diff --git a/java/ql/lib/change-notes/released/0.10.0.md b/java/ql/lib/change-notes/released/0.10.0.md new file mode 100644 index 000000000000..e18998c07ec6 --- /dev/null +++ b/java/ql/lib/change-notes/released/0.10.0.md @@ -0,0 +1,5 @@ +## 0.10.0 + +### Breaking Changes + +* Deleted the deprecated `AssignLShiftExpr`, `AssignRShiftExpr`, `AssignURShiftExpr`, `LShiftExpr`, `RShiftExpr`, and `URShiftExpr` aliases. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 6789dcd18b70..b21db6232459 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.9.1 +lastReleaseVersion: 0.10.0 diff --git a/java/ql/lib/ext/dummy.model.yml b/java/ql/lib/ext/empty.model.yml similarity index 69% rename from java/ql/lib/ext/dummy.model.yml rename to java/ql/lib/ext/empty.model.yml index 0269fe72311f..43028e7cc14e 100644 --- a/java/ql/lib/ext/dummy.model.yml +++ b/java/ql/lib/ext/empty.model.yml @@ -1,5 +1,6 @@ extensions: - # Make sure that the extensible model predicates are at least defined as empty. + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about undefined extensionals. - addsTo: pack: codeql/java-all extensible: sourceModel @@ -15,4 +16,4 @@ extensions: - addsTo: pack: codeql/java-all extensible: neutralModel - data: [] \ No newline at end of file + data: [] diff --git a/java/ql/lib/ext/experimental/dummy.model.yml b/java/ql/lib/ext/experimental/empty.model.yml similarity index 69% rename from java/ql/lib/ext/experimental/dummy.model.yml rename to java/ql/lib/ext/experimental/empty.model.yml index b43cb611b663..b1ee4d24cdfa 100644 --- a/java/ql/lib/ext/experimental/dummy.model.yml +++ b/java/ql/lib/ext/experimental/empty.model.yml @@ -1,6 +1,6 @@ -# Define the extensible prediactes related to experimental queries -# to at least be empty. extensions: + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about undefined extensionals. - addsTo: pack: codeql/java-all extensible: experimentalSourceModel diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 2a4bad9bc0f7..d3bcafad03c9 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.9.2-dev +version: 0.10.1-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/lib/semmle/code/java/Expr.qll b/java/ql/lib/semmle/code/java/Expr.qll index e0208b4df9e4..1862319e30bb 100644 --- a/java/ql/lib/semmle/code/java/Expr.qll +++ b/java/ql/lib/semmle/code/java/Expr.qll @@ -511,9 +511,6 @@ class AssignLeftShiftExpr extends AssignOp, @assignlshiftexpr { override string getAPrimaryQlClass() { result = "AssignLeftShiftExpr" } } -/** DEPRECATED: Alias for AssignLeftShiftExpr. */ -deprecated class AssignLShiftExpr = AssignLeftShiftExpr; - /** A compound assignment expression using the `>>=` operator. */ class AssignRightShiftExpr extends AssignOp, @assignrshiftexpr { override string getOp() { result = ">>=" } @@ -521,9 +518,6 @@ class AssignRightShiftExpr extends AssignOp, @assignrshiftexpr { override string getAPrimaryQlClass() { result = "AssignRightShiftExpr" } } -/** DEPRECATED: Alias for AssignRightShiftExpr. */ -deprecated class AssignRShiftExpr = AssignRightShiftExpr; - /** A compound assignment expression using the `>>>=` operator. */ class AssignUnsignedRightShiftExpr extends AssignOp, @assignurshiftexpr { override string getOp() { result = ">>>=" } @@ -531,9 +525,6 @@ class AssignUnsignedRightShiftExpr extends AssignOp, @assignurshiftexpr { override string getAPrimaryQlClass() { result = "AssignUnsignedRightShiftExpr" } } -/** DEPRECATED: Alias for AssignUnsignedRightShiftExpr. */ -deprecated class AssignURShiftExpr = AssignUnsignedRightShiftExpr; - /** A common super-class to represent constant literals. */ class Literal extends Expr, @literal { /** @@ -793,9 +784,6 @@ class LeftShiftExpr extends BinaryExpr, @lshiftexpr { override string getAPrimaryQlClass() { result = "LeftShiftExpr" } } -/** DEPRECATED: Alias for LeftShiftExpr. */ -deprecated class LShiftExpr = LeftShiftExpr; - /** A binary expression using the `>>` operator. */ class RightShiftExpr extends BinaryExpr, @rshiftexpr { override string getOp() { result = " >> " } @@ -803,9 +791,6 @@ class RightShiftExpr extends BinaryExpr, @rshiftexpr { override string getAPrimaryQlClass() { result = "RightShiftExpr" } } -/** DEPRECATED: Alias for RightShiftExpr. */ -deprecated class RShiftExpr = RightShiftExpr; - /** A binary expression using the `>>>` operator. */ class UnsignedRightShiftExpr extends BinaryExpr, @urshiftexpr { override string getOp() { result = " >>> " } @@ -813,9 +798,6 @@ class UnsignedRightShiftExpr extends BinaryExpr, @urshiftexpr { override string getAPrimaryQlClass() { result = "UnsignedRightShiftExpr" } } -/** DEPRECATED: Alias for UnsignedRightShiftExpr. */ -deprecated class URShiftExpr = UnsignedRightShiftExpr; - /** A binary expression using the `&` operator. */ class AndBitwiseExpr extends BinaryExpr, @andbitexpr { override string getOp() { result = " & " } diff --git a/java/ql/lib/semmle/code/java/dataflow/ApiSinks.qll b/java/ql/lib/semmle/code/java/dataflow/ApiSinks.qll new file mode 100644 index 000000000000..c600bb1672d8 --- /dev/null +++ b/java/ql/lib/semmle/code/java/dataflow/ApiSinks.qll @@ -0,0 +1,39 @@ +/** Provides classes representing various flow sinks for data flow / taint tracking. */ + +private import semmle.code.java.dataflow.FlowSinks as FlowSinks + +final class SinkNode = FlowSinks::ApiSinkNode; + +/** + * Module that adds all API like sinks to `SinkNode`, excluding sinks for cryptography based + * queries, and queries where sinks are not succifiently defined (eg. using broad method name matching). + */ +private module AllApiSinks { + private import semmle.code.java.security.AndroidSensitiveCommunicationQuery + private import semmle.code.java.security.ArbitraryApkInstallation + private import semmle.code.java.security.CleartextStorageAndroidDatabaseQuery + private import semmle.code.java.security.CleartextStorageAndroidFilesystemQuery + private import semmle.code.java.security.CleartextStorageCookieQuery + private import semmle.code.java.security.CleartextStorageSharedPrefsQuery + private import semmle.code.java.security.ExternallyControlledFormatStringQuery + private import semmle.code.java.security.InsecureBasicAuth + private import semmle.code.java.security.IntentUriPermissionManipulation + private import semmle.code.java.security.InsecureLdapAuth + private import semmle.code.java.security.InsecureTrustManager + private import semmle.code.java.security.JndiInjection + private import semmle.code.java.security.JWT + private import semmle.code.java.security.OgnlInjection + private import semmle.code.java.security.SensitiveResultReceiverQuery + private import semmle.code.java.security.SensitiveUiQuery + private import semmle.code.java.security.SpelInjection + private import semmle.code.java.security.SpelInjectionQuery + private import semmle.code.java.security.QueryInjection + private import semmle.code.java.security.TempDirLocalInformationDisclosureQuery + private import semmle.code.java.security.UnsafeAndroidAccess + private import semmle.code.java.security.UnsafeContentUriResolution + private import semmle.code.java.security.UnsafeDeserializationQuery + private import semmle.code.java.security.UrlRedirect + private import semmle.code.java.security.WebviewDebuggingEnabledQuery + private import semmle.code.java.security.XPath + private import semmle.code.java.security.XSS +} diff --git a/java/ql/lib/semmle/code/java/dataflow/ApiSources.qll b/java/ql/lib/semmle/code/java/dataflow/ApiSources.qll new file mode 100644 index 000000000000..5f825ad5445f --- /dev/null +++ b/java/ql/lib/semmle/code/java/dataflow/ApiSources.qll @@ -0,0 +1,23 @@ +/** Provides classes representing various flow sources for data flow / taint tracking. */ + +private import semmle.code.java.dataflow.FlowSources as FlowSources + +final class SourceNode = FlowSources::ApiSourceNode; + +/** + * Module that adds all API like sources to `SourceNode`, excluding some sources for cryptography based + * queries, and queries where sources are not succifiently defined (eg. using broad method name matching). + */ +private module AllApiSources { + private import semmle.code.java.security.ArbitraryApkInstallation + private import semmle.code.java.security.CleartextStorageAndroidDatabaseQuery + private import semmle.code.java.security.CleartextStorageAndroidFilesystemQuery + private import semmle.code.java.security.CleartextStorageCookieQuery + private import semmle.code.java.security.CleartextStorageSharedPrefsQuery + private import semmle.code.java.security.ImplicitPendingIntentsQuery + private import semmle.code.java.security.ImproperIntentVerificationQuery + private import semmle.code.java.security.InsecureTrustManager + private import semmle.code.java.security.JWT + private import semmle.code.java.security.StackTraceExposureQuery + private import semmle.code.java.security.ZipSlipQuery +} diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSinks.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSinks.qll new file mode 100644 index 000000000000..72cd96f6745c --- /dev/null +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSinks.qll @@ -0,0 +1,18 @@ +/** Provides classes representing various flow sinks for data flow / taint tracking. */ + +private import java +private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.DataFlow + +/** + * A data flow sink node for an API, which should be considered + * supported for a modeling perspective. + */ +abstract class ApiSinkNode extends DataFlow::Node { } + +/** + * Add all sink models as data sinks. + */ +private class ApiSinkNodeExternal extends ApiSinkNode { + ApiSinkNodeExternal() { sinkNode(this, _) } +} diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll index 425eb3ccaa60..6befe289a17c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll @@ -194,15 +194,17 @@ private class AndroidExternalStorageSource extends RemoteFlowSource { } /** Class for `tainted` user input. */ -abstract class UserInput extends DataFlow::Node { } +abstract class UserInput extends SourceNode { } /** * Input that may be controlled by a remote user. */ -private class RemoteUserInput extends UserInput instanceof RemoteFlowSource { } +private class RemoteUserInput extends UserInput instanceof RemoteFlowSource { + override string getThreatModel() { result = RemoteFlowSource.super.getThreatModel() } +} /** A node with input that may be controlled by a local user. */ -abstract class LocalUserInput extends UserInput, SourceNode { +abstract class LocalUserInput extends UserInput { override string getThreatModel() { result = "local" } } @@ -385,3 +387,18 @@ class AndroidJavascriptInterfaceMethodParameter extends RemoteFlowSource { result = "Parameter of method with JavascriptInterface annotation" } } + +/** + * A data flow source node for an API, which should be considered + * supported for a modeling perspective. + */ +abstract class ApiSourceNode extends DataFlow::Node { } + +private class AddSourceNodes extends ApiSourceNode instanceof SourceNode { } + +/** + * Add all source models as data sources. + */ +private class ApiSourceNodeExternal extends ApiSourceNode { + ApiSourceNodeExternal() { sourceNode(this, _) } +} diff --git a/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll b/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll index 7575ccb62135..a07d7c741faa 100644 --- a/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll +++ b/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll @@ -1162,14 +1162,6 @@ module Impl implements RegexTreeViewSig { root.getLiteral().isIgnoreCase() } - /** - * Gets the flags for `root`, or the empty string if `root` has no flags. - */ - additional deprecated string getFlags(RegExpTerm root) { - root.isRootTerm() and - result = root.getLiteral().getFlags() - } - /** * Holds if `root` has the `s` flag for multi-line matching. */ diff --git a/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll index 53adc7132c5e..a4f9713ac308 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll @@ -4,6 +4,7 @@ import java import semmle.code.java.dataflow.TaintTracking import semmle.code.java.frameworks.android.Intent import semmle.code.java.security.SensitiveActions +private import semmle.code.java.dataflow.FlowSinks /** * Gets regular expression for matching names of Android variables that indicate the value being held contains sensitive information. @@ -151,17 +152,24 @@ deprecated class SensitiveCommunicationConfig extends TaintTracking::Configurati } } +/** + * A sensitive communication sink node. + */ +private class SensitiveCommunicationSink extends ApiSinkNode { + SensitiveCommunicationSink() { + isSensitiveBroadcastSink(this) + or + isStartActivityOrServiceSink(this) + } +} + /** * Taint configuration tracking flow from variables containing sensitive information to broadcast Intents. */ module SensitiveCommunicationConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.asExpr() instanceof SensitiveInfoExpr } - predicate isSink(DataFlow::Node sink) { - isSensitiveBroadcastSink(sink) - or - isStartActivityOrServiceSink(sink) - } + predicate isSink(DataFlow::Node sink) { sink instanceof SensitiveCommunicationSink } /** * Holds if broadcast doesn't specify receiving package name of the 3rd party app diff --git a/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallation.qll b/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallation.qll index 3aa59286fcd0..d7c5fe94f28a 100644 --- a/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallation.qll +++ b/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallation.qll @@ -4,6 +4,7 @@ import java import semmle.code.java.frameworks.android.Intent import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.FlowSources /** A string literal that represents the MIME type for Android APKs. */ @@ -48,7 +49,7 @@ class SetDataMethod extends Method { } /** A dataflow sink for the URI of an intent. */ -class SetDataSink extends DataFlow::ExprNode { +class SetDataSink extends ApiSinkNode, DataFlow::ExprNode { SetDataSink() { exists(MethodCall ma | this.getExpr() = ma.getQualifier() and @@ -69,7 +70,7 @@ class UriConstructorMethod extends Method { * A dataflow source representing the URIs which an APK not controlled by the * application may come from. Including external storage and web URLs. */ -class ExternalApkSource extends DataFlow::Node { +class ExternalApkSource extends ApiSourceNode { ExternalApkSource() { sourceNode(this, "android-external-storage-dir") or this.asExpr().(MethodCall).getMethod() instanceof UriConstructorMethod or diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll index b42389a1df6e..5ee9248d9eb5 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll @@ -6,6 +6,8 @@ import semmle.code.java.frameworks.android.ContentProviders import semmle.code.java.frameworks.android.Intent import semmle.code.java.frameworks.android.SQLite import semmle.code.java.security.CleartextStorageQuery +private import semmle.code.java.dataflow.FlowSinks +private import semmle.code.java.dataflow.FlowSources private class LocalDatabaseCleartextStorageSink extends CleartextStorageSink { LocalDatabaseCleartextStorageSink() { localDatabaseInput(_, this.asExpr()) } @@ -96,15 +98,24 @@ private predicate localDatabaseStore(DataFlow::Node database, MethodCall store) ) } +/** + * A local database open method call source node. + */ +private class LocalDatabaseOpenMethodCallSource extends ApiSourceNode { + LocalDatabaseOpenMethodCallSource() { this.asExpr() instanceof LocalDatabaseOpenMethodCall } +} + +/** + * A local database sink node. + */ +private class LocalDatabaseSink extends ApiSinkNode { + LocalDatabaseSink() { localDatabaseInput(this, _) or localDatabaseStore(this, _) } +} + private module LocalDatabaseFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { - source.asExpr() instanceof LocalDatabaseOpenMethodCall - } + predicate isSource(DataFlow::Node source) { source instanceof LocalDatabaseOpenMethodCallSource } - predicate isSink(DataFlow::Node sink) { - localDatabaseInput(sink, _) or - localDatabaseStore(sink, _) - } + predicate isSink(DataFlow::Node sink) { sink instanceof LocalDatabaseSink } predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { // Adds a step for tracking databases through field flow, that is, a database is opened and diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll index d7097f1ecf23..06fa83813124 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll @@ -5,9 +5,11 @@ import java import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.security.CleartextStorageQuery import semmle.code.xml.AndroidManifest +private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks +private import semmle.code.java.dataflow.FlowSources private class AndroidFilesystemCleartextStorageSink extends CleartextStorageSink { AndroidFilesystemCleartextStorageSink() { @@ -79,13 +81,27 @@ private class CloseFileMethod extends Method { } } -private module FilesystemFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { src.asExpr() instanceof LocalFileOpenCall } +/** + * A local file open call source node. + */ +private class LocalFileOpenCallSource extends ApiSourceNode { + LocalFileOpenCallSource() { this.asExpr() instanceof LocalFileOpenCall } +} - predicate isSink(DataFlow::Node sink) { - filesystemInput(sink, _) or - closesFile(sink, _) +/** + * A local file sink node. + */ +private class LocalFileSink extends ApiSinkNode { + LocalFileSink() { + filesystemInput(this, _) or + closesFile(this, _) } +} + +private module FilesystemFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src instanceof LocalFileOpenCallSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof LocalFileSink } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { // Add nested Writer constructors as extra data flow steps diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll index 2b6534e8cbda..a36a4754584a 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll @@ -4,6 +4,8 @@ import java import semmle.code.java.dataflow.DataFlow deprecated import semmle.code.java.dataflow.DataFlow3 import semmle.code.java.security.CleartextStorageQuery +private import semmle.code.java.dataflow.FlowSinks +private import semmle.code.java.dataflow.FlowSources private class CookieCleartextStorageSink extends CleartextStorageSink { CookieCleartextStorageSink() { this.asExpr() = cookieInput(_) } @@ -37,10 +39,24 @@ private predicate cookieStore(DataFlow::Node cookie, Expr store) { ) } +/** + * A cookie source node. + */ +private class CookieSource extends ApiSourceNode { + CookieSource() { this.asExpr() instanceof Cookie } +} + +/** + * A cookie store sink node. + */ +private class CookieStoreSink extends ApiSinkNode { + CookieStoreSink() { cookieStore(this, _) } +} + private module CookieToStoreFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { src.asExpr() instanceof Cookie } + predicate isSource(DataFlow::Node src) { src instanceof CookieSource } - predicate isSink(DataFlow::Node sink) { cookieStore(sink, _) } + predicate isSink(DataFlow::Node sink) { sink instanceof CookieStoreSink } } private module CookieToStoreFlow = DataFlow::Global; diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll index 39e1ffa3c75d..f72d40106e35 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll @@ -4,6 +4,8 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.frameworks.android.SharedPreferences import semmle.code.java.security.CleartextStorageQuery +private import semmle.code.java.dataflow.FlowSinks +private import semmle.code.java.dataflow.FlowSources private class SharedPrefsCleartextStorageSink extends CleartextStorageSink { SharedPrefsCleartextStorageSink() { @@ -67,16 +69,30 @@ private predicate sharedPreferencesStore(DataFlow::Node editor, MethodCall m) { editor.asExpr() = m.getQualifier().getUnderlyingExpr() } -/** Flow from `SharedPreferences.Editor` to either a setter or a store method. */ -private module SharedPreferencesFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { - src.asExpr() instanceof SharedPreferencesEditorMethodCall +/** + * A shared preferences editor method call source node. + */ +private class SharedPreferencesEditorMethodCallSource extends ApiSourceNode { + SharedPreferencesEditorMethodCallSource() { + this.asExpr() instanceof SharedPreferencesEditorMethodCall } +} - predicate isSink(DataFlow::Node sink) { - sharedPreferencesInput(sink, _) or - sharedPreferencesStore(sink, _) +/** + * A shared preferences sink node. + */ +private class SharedPreferencesSink extends ApiSinkNode { + SharedPreferencesSink() { + sharedPreferencesInput(this, _) or + sharedPreferencesStore(this, _) } } +/** Flow from `SharedPreferences.Editor` to either a setter or a store method. */ +private module SharedPreferencesFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src instanceof SharedPreferencesEditorMethodCallSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof SharedPreferencesSink } +} + private module SharedPreferencesFlow = DataFlow::Global; diff --git a/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll b/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll index a71ebc964f64..606e31a07cb7 100644 --- a/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll @@ -1,18 +1,24 @@ /** Provides a taint-tracking configuration to reason about externally controlled format string vulnerabilities. */ import java +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.FlowSources private import semmle.code.java.StringFormat +/** + * A string format sink node. + */ +private class StringFormatSink extends ApiSinkNode { + StringFormatSink() { this.asExpr() = any(StringFormat formatCall).getFormatArgument() } +} + /** * A taint-tracking configuration for externally controlled format string vulnerabilities. */ module ExternallyControlledFormatStringConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ThreatModelFlowSource } - predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(StringFormat formatCall).getFormatArgument() - } + predicate isSink(DataFlow::Node sink) { sink instanceof StringFormatSink } predicate isBarrier(DataFlow::Node node) { node.getType() instanceof NumericType or node.getType() instanceof BooleanType diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll index 4cac7715b98a..a5d8f256b036 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll @@ -2,8 +2,7 @@ import java private import semmle.code.java.dataflow.ExternalFlow -private import semmle.code.java.dataflow.TaintTracking -private import semmle.code.java.frameworks.android.Intent +private import semmle.code.java.dataflow.FlowSources private import semmle.code.java.frameworks.android.PendingIntent private newtype TPendingIntentState = @@ -27,7 +26,7 @@ class NoState extends PendingIntentState, TNoState { } /** A source for an implicit `PendingIntent` flow. */ -abstract class ImplicitPendingIntentSource extends DataFlow::Node { +abstract class ImplicitPendingIntentSource extends ApiSourceNode { /** * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. * diff --git a/java/ql/lib/semmle/code/java/security/InsecureBasicAuth.qll b/java/ql/lib/semmle/code/java/security/InsecureBasicAuth.qll index df9b6bdf4a11..b21492406adf 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureBasicAuth.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureBasicAuth.qll @@ -4,6 +4,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.TaintTracking import semmle.code.java.security.HttpsUrls +private import semmle.code.java.dataflow.FlowSinks /** * A source that represents HTTP URLs. @@ -20,7 +21,7 @@ private class DefaultInsecureBasicAuthSource extends InsecureBasicAuthSource { * A sink that represents a method that sets Basic Authentication. * Extend this class to add your own Insecure Basic Authentication sinks. */ -abstract class InsecureBasicAuthSink extends DataFlow::Node { } +abstract class InsecureBasicAuthSink extends ApiSinkNode { } /** A default sink representing methods that set an Authorization header. */ private class DefaultInsecureBasicAuthSink extends InsecureBasicAuthSink { diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll index 9a8cd91b1fcf..52d58afc9e76 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll @@ -2,6 +2,7 @@ import java private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.frameworks.Networking private import semmle.code.java.frameworks.Jndi @@ -32,7 +33,7 @@ class InsecureLdapUrl extends Expr { /** * A sink representing the construction of a `DirContextEnvironment`. */ -class InsecureLdapUrlSink extends DataFlow::Node { +class InsecureLdapUrlSink extends ApiSinkNode { InsecureLdapUrlSink() { exists(ConstructorCall cc | cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and diff --git a/java/ql/lib/semmle/code/java/security/InsecureRandomnessQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureRandomnessQuery.qll index f983876d7b38..423046b6746e 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureRandomnessQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureRandomnessQuery.qll @@ -4,6 +4,7 @@ import java private import semmle.code.java.frameworks.OpenSaml private import semmle.code.java.frameworks.Servlets private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.security.Cookies private import semmle.code.java.security.RandomQuery @@ -49,7 +50,7 @@ abstract class InsecureRandomnessSink extends DataFlow::Node { } /** * A node which sets the value of a cookie. */ -private class CookieSink extends InsecureRandomnessSink { +private class CookieSink extends InsecureRandomnessSink, ApiSinkNode { CookieSink() { this.asExpr() instanceof SetCookieValue } } diff --git a/java/ql/lib/semmle/code/java/security/InsecureTrustManager.qll b/java/ql/lib/semmle/code/java/security/InsecureTrustManager.qll index d82f088cf155..41d8f28573ca 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureTrustManager.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureTrustManager.qll @@ -2,11 +2,12 @@ import java private import semmle.code.java.controlflow.Guards +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.security.Encryption private import semmle.code.java.security.SecurityFlag /** The creation of an insecure `TrustManager`. */ -abstract class InsecureTrustManagerSource extends DataFlow::Node { } +abstract class InsecureTrustManagerSource extends ApiSourceNode { } private class DefaultInsecureTrustManagerSource extends InsecureTrustManagerSource { DefaultInsecureTrustManagerSource() { @@ -18,7 +19,7 @@ private class DefaultInsecureTrustManagerSource extends InsecureTrustManagerSour * The use of a `TrustManager` in an SSL context. * Intentionally insecure connections are not considered sinks. */ -abstract class InsecureTrustManagerSink extends DataFlow::Node { +abstract class InsecureTrustManagerSink extends ApiSinkNode { InsecureTrustManagerSink() { not isGuardedByInsecureFlag(this) } } diff --git a/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulation.qll b/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulation.qll index 4309af8b3c80..2f9470f2bb9a 100644 --- a/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulation.qll +++ b/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulation.qll @@ -6,6 +6,7 @@ import java private import semmle.code.java.controlflow.Guards private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.frameworks.android.Android private import semmle.code.java.frameworks.android.Intent @@ -14,7 +15,7 @@ private import semmle.code.java.frameworks.android.Intent * A sink for Intent URI permission manipulation vulnerabilities in Android, * that is, method calls that return an Intent as the result of an Activity. */ -abstract class IntentUriPermissionManipulationSink extends DataFlow::Node { } +abstract class IntentUriPermissionManipulationSink extends ApiSinkNode { } /** * A sanitizer that makes sure that an Intent is safe to be returned to another Activity. diff --git a/java/ql/lib/semmle/code/java/security/JWT.qll b/java/ql/lib/semmle/code/java/security/JWT.qll index 183495d85652..5ba47072dc68 100644 --- a/java/ql/lib/semmle/code/java/security/JWT.qll +++ b/java/ql/lib/semmle/code/java/security/JWT.qll @@ -1,10 +1,11 @@ /** Provides classes for working with JSON Web Token (JWT) libraries. */ import java -private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSinks +private import semmle.code.java.dataflow.FlowSources /** A method access that assigns signing keys to a JWT parser. */ -class JwtParserWithInsecureParseSource extends DataFlow::Node { +class JwtParserWithInsecureParseSource extends ApiSourceNode { JwtParserWithInsecureParseSource() { exists(MethodCall ma, Method m | m.getDeclaringType().getAnAncestor() instanceof TypeJwtParser or @@ -24,7 +25,7 @@ class JwtParserWithInsecureParseSource extends DataFlow::Node { * the qualifier of a call to a `parse(token, handler)` method * where the `handler` is considered insecure. */ -class JwtParserWithInsecureParseSink extends DataFlow::Node { +class JwtParserWithInsecureParseSink extends ApiSinkNode { MethodCall insecureParseMa; JwtParserWithInsecureParseSink() { diff --git a/java/ql/lib/semmle/code/java/security/JndiInjection.qll b/java/ql/lib/semmle/code/java/security/JndiInjection.qll index d7282996057d..3df8d6df378e 100644 --- a/java/ql/lib/semmle/code/java/security/JndiInjection.qll +++ b/java/ql/lib/semmle/code/java/security/JndiInjection.qll @@ -3,11 +3,12 @@ import java private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.frameworks.Jndi private import semmle.code.java.frameworks.SpringLdap /** A data flow sink for unvalidated user input that is used in JNDI lookup. */ -abstract class JndiInjectionSink extends DataFlow::Node { } +abstract class JndiInjectionSink extends ApiSinkNode { } /** A sanitizer for JNDI injection vulnerabilities. */ abstract class JndiInjectionSanitizer extends DataFlow::Node { } diff --git a/java/ql/lib/semmle/code/java/security/OgnlInjection.qll b/java/ql/lib/semmle/code/java/security/OgnlInjection.qll index d5297702bef4..37f31618fc32 100644 --- a/java/ql/lib/semmle/code/java/security/OgnlInjection.qll +++ b/java/ql/lib/semmle/code/java/security/OgnlInjection.qll @@ -2,6 +2,7 @@ import java private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.frameworks.MyBatis @@ -10,7 +11,7 @@ private import semmle.code.java.frameworks.MyBatis * * Extend this class to add your own OGNL injection sinks. */ -abstract class OgnlInjectionSink extends DataFlow::Node { } +abstract class OgnlInjectionSink extends ApiSinkNode { } /** * A unit class for adding additional taint steps. diff --git a/java/ql/lib/semmle/code/java/security/QueryInjection.qll b/java/ql/lib/semmle/code/java/security/QueryInjection.qll index aa92aa16a14c..df316155ba1a 100644 --- a/java/ql/lib/semmle/code/java/security/QueryInjection.qll +++ b/java/ql/lib/semmle/code/java/security/QueryInjection.qll @@ -5,9 +5,10 @@ import semmle.code.java.dataflow.DataFlow import semmle.code.java.frameworks.javaee.Persistence private import semmle.code.java.frameworks.MyBatis private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks /** A sink for database query language injection vulnerabilities. */ -abstract class QueryInjectionSink extends DataFlow::Node { } +abstract class QueryInjectionSink extends ApiSinkNode { } /** * A unit class for adding additional taint steps. diff --git a/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll index 63d6d88d83cb..8269a42c5c25 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll @@ -4,6 +4,7 @@ import java import semmle.code.java.dataflow.TaintTracking import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.SensitiveActions +private import semmle.code.java.dataflow.FlowSinks private class ResultReceiverSendCall extends MethodCall { ResultReceiverSendCall() { @@ -50,15 +51,22 @@ deprecated private class SensitiveResultReceiverConf extends TaintTracking::Conf } } -private module SensitiveResultReceiverConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SensitiveExpr } - - predicate isSink(DataFlow::Node node) { +/** + * A sensitive result receiver sink node. + */ +private class SensitiveResultReceiverSink extends ApiSinkNode { + SensitiveResultReceiverSink() { exists(ResultReceiverSendCall call | untrustedResultReceiverSend(_, call) and - node.asExpr() = call.getSentData() + this.asExpr() = call.getSentData() ) } +} + +private module SensitiveResultReceiverConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SensitiveExpr } + + predicate isSink(DataFlow::Node node) { node instanceof SensitiveResultReceiverSink } predicate allowImplicitRead(DataFlow::Node n, DataFlow::ContentSet c) { isSink(n) and exists(c) } } diff --git a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll index 38a5aeb93cf9..a7e76d0e2e31 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll @@ -2,6 +2,7 @@ import java private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.security.SensitiveActions private import semmle.code.java.frameworks.android.Layout @@ -53,16 +54,23 @@ private class MaskCall extends MethodCall { } } -/** A configuration for tracking sensitive information to text fields. */ -private module TextFieldTrackingConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SensitiveExpr } - - predicate isSink(DataFlow::Node sink) { +/** + * A text field sink node. + */ +private class TextFieldSink extends ApiSinkNode { + TextFieldSink() { exists(SetTextCall call | - sink.asExpr() = call.getStringArgument() and + this.asExpr() = call.getStringArgument() and not setTextCallIsMasked(call) ) } +} + +/** A configuration for tracking sensitive information to text fields. */ +private module TextFieldTrackingConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SensitiveExpr } + + predicate isSink(DataFlow::Node sink) { sink instanceof TextFieldSink } predicate isBarrier(DataFlow::Node node) { node instanceof SimpleTypeSanitizer } diff --git a/java/ql/lib/semmle/code/java/security/SpelInjection.qll b/java/ql/lib/semmle/code/java/security/SpelInjection.qll index 1aed2049afe4..13eb195eae46 100644 --- a/java/ql/lib/semmle/code/java/security/SpelInjection.qll +++ b/java/ql/lib/semmle/code/java/security/SpelInjection.qll @@ -2,10 +2,11 @@ import java private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.frameworks.spring.SpringExpression /** A data flow sink for unvalidated user input that is used to construct SpEL expressions. */ -abstract class SpelExpressionEvaluationSink extends DataFlow::ExprNode { } +abstract class SpelExpressionEvaluationSink extends ApiSinkNode, DataFlow::ExprNode { } /** * A unit class for adding additional taint steps. diff --git a/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll b/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll index dba9492d137b..1a2fe31e8794 100644 --- a/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll +++ b/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll @@ -1,8 +1,7 @@ /** Provides predicates to reason about exposure of stack-traces. */ import java -private import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.TaintTracking +private import semmle.code.java.dataflow.FlowSources private import semmle.code.java.security.InformationLeak /** @@ -19,7 +18,7 @@ private class PrintStackTraceMethod extends Method { } private module ServletWriterSourceToPrintStackTraceMethodFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { src.asExpr() instanceof XssVulnerableWriterSource } + predicate isSource(DataFlow::Node src) { src instanceof XssVulnerableWriterSourceNode } predicate isSink(DataFlow::Node sink) { exists(MethodCall ma | @@ -95,7 +94,10 @@ predicate stringifiedStackFlowsExternally(DataFlow::Node externalExpr, Expr stac ) } -private class GetMessageFlowSource extends DataFlow::Node { +/** + * A get message source node. + */ +private class GetMessageFlowSource extends ApiSourceNode { GetMessageFlowSource() { exists(Method method | this.asExpr().(MethodCall).getMethod() = method | method.hasName("getMessage") and diff --git a/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll b/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll index 843db3b5934b..f1ffcaecc515 100644 --- a/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll @@ -1,6 +1,7 @@ /** Provides classes to reason about local information disclosure in a temporary directory. */ import java +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.os.OSCheck private import semmle.code.java.security.TempDirUtils @@ -29,7 +30,7 @@ private class MethodFileFileCreation extends MethodFileSystemFileCreation { /** * A dataflow node that creates a file or directory in the file system. */ -abstract private class FileCreationSink extends DataFlow::Node { } +abstract private class FileCreationSink extends ApiSinkNode { } /** * The qualifier of a call to one of `File`'s file-creating or directory-creating methods, diff --git a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll index 499475cff3ec..afd3af221bed 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll @@ -4,6 +4,7 @@ import java private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.frameworks.android.WebView private import semmle.code.java.frameworks.kotlin.Kotlin @@ -12,7 +13,7 @@ private import semmle.code.java.frameworks.kotlin.Kotlin * * Extend this class to add your own Unsafe Resource Fetching sinks. */ -abstract class UrlResourceSink extends DataFlow::Node { +abstract class UrlResourceSink extends ApiSinkNode { /** * Gets a description of this vulnerability. */ diff --git a/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolution.qll b/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolution.qll index 5537add5a2ca..b19d06bbf88c 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolution.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolution.qll @@ -1,13 +1,14 @@ /** Provides classes to reason about vulnerabilites related to content URIs. */ import java +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.frameworks.android.Android private import semmle.code.java.security.PathSanitizer private import semmle.code.java.security.Sanitizers /** A URI that gets resolved by a `ContentResolver`. */ -abstract class ContentUriResolutionSink extends DataFlow::Node { } +abstract class ContentUriResolutionSink extends ApiSinkNode { } /** A sanitizer for content URIs. */ abstract class ContentUriResolutionSanitizer extends DataFlow::Node { } diff --git a/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll index 272c483f7a21..734ad4c89fe6 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll @@ -3,6 +3,7 @@ */ import semmle.code.java.dataflow.FlowSources +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.TaintTracking2 private import semmle.code.java.dispatch.VirtualDispatch private import semmle.code.java.frameworks.Kryo @@ -235,7 +236,7 @@ predicate unsafeDeserialization(MethodCall ma, Expr sink) { } /** A sink for unsafe deserialization. */ -class UnsafeDeserializationSink extends DataFlow::ExprNode { +class UnsafeDeserializationSink extends ApiSinkNode, DataFlow::ExprNode { UnsafeDeserializationSink() { unsafeDeserialization(_, this.getExpr()) } /** Gets a call that triggers unsafe deserialization. */ diff --git a/java/ql/lib/semmle/code/java/security/UrlRedirect.qll b/java/ql/lib/semmle/code/java/security/UrlRedirect.qll index e806905c1674..02f66e3f0e95 100644 --- a/java/ql/lib/semmle/code/java/security/UrlRedirect.qll +++ b/java/ql/lib/semmle/code/java/security/UrlRedirect.qll @@ -2,14 +2,15 @@ import java import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.frameworks.Servlets import semmle.code.java.frameworks.ApacheHttp +private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.frameworks.JaxWS private import semmle.code.java.security.RequestForgery /** A URL redirection sink. */ -abstract class UrlRedirectSink extends DataFlow::Node { } +abstract class UrlRedirectSink extends ApiSinkNode { } /** A URL redirection sanitizer. */ abstract class UrlRedirectSanitizer extends DataFlow::Node { } diff --git a/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll index 00b9c715f752..f10b0132b5ac 100644 --- a/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll +++ b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll @@ -4,6 +4,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.controlflow.Guards import semmle.code.java.security.SecurityTests +private import semmle.code.java.dataflow.FlowSinks /** Holds if `ex` looks like a check that this is a debug build. */ private predicate isDebugCheck(Expr ex) { @@ -44,18 +45,25 @@ deprecated class WebviewDebugEnabledConfig extends DataFlow::Configuration { } } +/** + * A webview debug sink node. + */ +private class WebviewDebugSink extends ApiSinkNode { + WebviewDebugSink() { + exists(MethodCall ma | + ma.getMethod().hasQualifiedName("android.webkit", "WebView", "setWebContentsDebuggingEnabled") and + this.asExpr() = ma.getArgument(0) + ) + } +} + /** A configuration to find instances of `setWebContentDebuggingEnabled` called with `true` values. */ module WebviewDebugEnabledConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { node.asExpr().(BooleanLiteral).getBooleanValue() = true } - predicate isSink(DataFlow::Node node) { - exists(MethodCall ma | - ma.getMethod().hasQualifiedName("android.webkit", "WebView", "setWebContentsDebuggingEnabled") and - node.asExpr() = ma.getArgument(0) - ) - } + predicate isSink(DataFlow::Node node) { node instanceof WebviewDebugSink } predicate isBarrier(DataFlow::Node node) { exists(Guard debug | isDebugCheck(debug) and debug.controls(node.asExpr().getBasicBlock(), _)) diff --git a/java/ql/lib/semmle/code/java/security/XPath.qll b/java/ql/lib/semmle/code/java/security/XPath.qll index 573d6530b330..c2992fdc272a 100644 --- a/java/ql/lib/semmle/code/java/security/XPath.qll +++ b/java/ql/lib/semmle/code/java/security/XPath.qll @@ -3,12 +3,13 @@ import java import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks /** * A sink that represents a method that interprets XPath expressions. * Extend this class to add your own XPath Injection sinks. */ -abstract class XPathInjectionSink extends DataFlow::Node { } +abstract class XPathInjectionSink extends ApiSinkNode { } /** A default sink representing methods susceptible to XPath Injection attacks. */ private class DefaultXPathInjectionSink extends XPathInjectionSink { diff --git a/java/ql/lib/semmle/code/java/security/XSS.qll b/java/ql/lib/semmle/code/java/security/XSS.qll index 9edee5823bfc..777e5fae0627 100644 --- a/java/ql/lib/semmle/code/java/security/XSS.qll +++ b/java/ql/lib/semmle/code/java/security/XSS.qll @@ -10,9 +10,11 @@ private import semmle.code.java.frameworks.hudson.Hudson import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSources +private import semmle.code.java.dataflow.FlowSinks /** A sink that represent a method that outputs data without applying contextual output encoding. */ -abstract class XssSink extends DataFlow::Node { } +abstract class XssSink extends ApiSinkNode { } /** A sanitizer that neutralizes dangerous characters that can be used to perform a XSS attack. */ abstract class XssSanitizer extends DataFlow::Node { } @@ -62,7 +64,7 @@ private class DefaultXssSanitizer extends XssSanitizer { /** A configuration that tracks data from a servlet writer to an output method. */ private module XssVulnerableWriterSourceToWritingMethodFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { src.asExpr() instanceof XssVulnerableWriterSource } + predicate isSource(DataFlow::Node src) { src instanceof XssVulnerableWriterSourceNode } predicate isSink(DataFlow::Node sink) { exists(MethodCall ma | @@ -105,6 +107,13 @@ class XssVulnerableWriterSource extends MethodCall { } } +/** + * A xss vulnerable writer source node. + */ +class XssVulnerableWriterSourceNode extends ApiSourceNode { + XssVulnerableWriterSourceNode() { this.asExpr() instanceof XssVulnerableWriterSource } +} + /** * Holds if `s` is an HTTP Content-Type vulnerable to XSS. */ diff --git a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll index 7ba99a31e268..75e2f7000c55 100644 --- a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll @@ -4,6 +4,7 @@ import java import semmle.code.java.dataflow.TaintTracking import semmle.code.java.security.PathSanitizer private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSources private import semmle.code.java.security.PathCreation /** @@ -21,13 +22,20 @@ private class ArchiveEntryNameMethod extends Method { } } +/** + * An entry name method source node. + */ +private class ArchiveEntryNameMethodSource extends ApiSourceNode { + ArchiveEntryNameMethodSource() { + this.asExpr().(MethodCall).getMethod() instanceof ArchiveEntryNameMethod + } +} + /** * A taint-tracking configuration for reasoning about unsafe zip file extraction. */ module ZipSlipConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { - source.asExpr().(MethodCall).getMethod() instanceof ArchiveEntryNameMethod - } + predicate isSource(DataFlow::Node source) { source instanceof ArchiveEntryNameMethodSource } predicate isSink(DataFlow::Node sink) { sink instanceof FileCreationSink } diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 00af3da16607..a242e40221e1 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.15 + +No user-facing changes. + ## 0.8.14 ### Minor Analysis Improvements diff --git a/java/ql/src/Telemetry/ExternalApi.qll b/java/ql/src/Telemetry/ExternalApi.qll index 47527dfbb46a..a548593c36a3 100644 --- a/java/ql/src/Telemetry/ExternalApi.qll +++ b/java/ql/src/Telemetry/ExternalApi.qll @@ -1,6 +1,8 @@ /** Provides classes and predicates related to handling APIs from external libraries. */ private import java +private import semmle.code.java.dataflow.ApiSources as ApiSources +private import semmle.code.java.dataflow.ApiSinks as ApiSinks private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSources @@ -69,13 +71,11 @@ class ExternalApi extends Callable { } pragma[nomagic] - predicate isSource() { - this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _) - } + predicate isSource() { this.getAnOutput() instanceof ApiSources::SourceNode } /** Holds if this API is a known sink. */ pragma[nomagic] - predicate isSink() { sinkNode(this.getAnInput(), _) } + predicate isSink() { this.getAnInput() instanceof ApiSinks::SinkNode } /** Holds if this API is a known neutral. */ pragma[nomagic] diff --git a/java/ql/src/change-notes/released/0.8.15.md b/java/ql/src/change-notes/released/0.8.15.md new file mode 100644 index 000000000000..18c028b4ff00 --- /dev/null +++ b/java/ql/src/change-notes/released/0.8.15.md @@ -0,0 +1,3 @@ +## 0.8.15 + +No user-facing changes. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index b36a2e248f34..2e3c183bb7a2 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.8.14 +lastReleaseVersion: 0.8.15 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index eb3b350c821d..1279345f1964 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.8.15-dev +version: 0.8.16-dev groups: - java - queries diff --git a/java/ql/test/TestUtilities/InlineMadTest.qll b/java/ql/test/TestUtilities/InlineMadTest.qll new file mode 100644 index 000000000000..a336fa6b3a9a --- /dev/null +++ b/java/ql/test/TestUtilities/InlineMadTest.qll @@ -0,0 +1,65 @@ +import java as J + +private signature module InlineMadTestLangSig { + /** + * A base class of callables for modeling. + */ + class Callable; + + /** + * Gets a relevant code comment for `c`, if any. + */ + string getComment(Callable c); +} + +private module InlineMadTestImpl { + private class Callable = Lang::Callable; + + signature module InlineMadTestConfigSig { + /** + * Gets the kind of a captured model. + */ + string getKind(); + + /** + * Gets a captured model for `c`, if any. + */ + string getCapturedModel(Callable c); + } + + module InlineMadTest { + private string expects(Callable c) { + Lang::getComment(c).regexpCapture(" *(SPURIOUS-)?" + Input::getKind() + "=(.*)", 2) = result + } + + query predicate unexpectedModel(string msg) { + exists(Callable c, string flow | + flow = Input::getCapturedModel(c) and + not flow = expects(c) and + msg = "Unexpected " + Input::getKind() + " found: " + flow + ) + } + + query predicate expectedModel(string msg) { + exists(Callable c, string e | + e = expects(c) and + not e = Input::getCapturedModel(c) and + msg = "Expected " + Input::getKind() + " missing: " + e + ) + } + } +} + +private module InlineMadTestLang implements InlineMadTestLangSig { + class Callable = J::Callable; + + string getComment(Callable c) { + exists(J::Javadoc doc | + hasJavadoc(c, doc) and + isNormalComment(doc) and + result = doc.getChild(0).toString() + ) + } +} + +import InlineMadTestImpl diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected index 68dc7169533f..d08da075f3fd 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected @@ -13,4 +13,5 @@ | java.util.Map#put(Object,Object) | 1 | | java.util.Map$Entry#getKey() | 1 | | java.util.Set#iterator() | 1 | +| javax.servlet.http.HttpServletResponse#sendRedirect(String) | 1 | | org.apache.commons.io.FileUtils#deleteDirectory(File) | 1 | diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java index 880d183aecdb..8fd5f679824e 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java @@ -1,10 +1,13 @@ +import java.io.File; +import java.io.FileWriter; +import java.io.InputStream; +import java.io.IOException; +import java.net.URL; import java.time.Duration; import java.util.HashMap; import java.util.Map; -import java.io.InputStream; -import java.net.URL; -import java.io.File; -import java.io.FileWriter; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.ServletException; import org.apache.commons.io.FileUtils; class SupportedExternalApis { @@ -30,4 +33,8 @@ public static void main(String[] args) throws Exception { file.compareTo(file); // supported neutral sink (compareTo) } + + public static void doSendRedirect(HttpServletResponse req) throws ServletException, IOException { + req.sendRedirect("myredirect"); // supported sink (sendRedirect) + } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.expected b/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.expected index df6a7bfc8544..cb6fc390349c 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.expected +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.expected @@ -1,25 +1,2 @@ -| p;Factory;getIntValue;();summary;df-generated | -| p;FinalClass;returnsConstant;();summary;df-generated | -| p;FluentAPI$Inner;notThis;(String);summary;df-generated | -| p;ImmutablePojo;getX;();summary;df-generated | -| p;Joiner;length;();summary;df-generated | -| p;ParamFlow;ignorePrimitiveReturnValue;(String);summary;df-generated | -| p;ParamFlow;mapType;(Class);summary;df-generated | -| p;Pojo;doNotSetValue;(String);summary;df-generated | -| p;Pojo;getBigDecimal;();summary;df-generated | -| p;Pojo;getBigInt;();summary;df-generated | -| p;Pojo;getBoxedArray;();summary;df-generated | -| p;Pojo;getBoxedCollection;();summary;df-generated | -| p;Pojo;getBoxedValue;();summary;df-generated | -| p;Pojo;getFloatArray;();summary;df-generated | -| p;Pojo;getIntValue;();summary;df-generated | -| p;Pojo;getPrimitiveArray;();summary;df-generated | -| p;PrivateFlowViaPublicInterface$SPI;openStreamNone;();summary;df-generated | -| p;PrivateFlowViaPublicInterface;createAnSPIWithoutTrackingFile;(File);summary;df-generated | -| p;Sinks;copyFileToDirectory;(Path,Path,CopyOption[]);summary;df-generated | -| p;Sinks;propagate;(String);summary;df-generated | -| p;Sinks;readUrl;(URL,Charset);summary;df-generated | -| p;Sources;readUrl;(URL);summary;df-generated | -| p;Sources;socketStream;();summary;df-generated | -| p;Sources;sourceToParameter;(InputStream[],List);summary;df-generated | -| p;Sources;wrappedSocketStream;();summary;df-generated | +unexpectedModel +expectedModel diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.ql new file mode 100644 index 000000000000..e68730cc0edd --- /dev/null +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.ql @@ -0,0 +1,11 @@ +import java +import utils.modelgenerator.internal.CaptureSummaryFlowQuery +import TestUtilities.InlineMadTest + +module InlineMadTestConfig implements InlineMadTestConfigSig { + string getCapturedModel(Callable c) { result = captureNoFlow(c) } + + string getKind() { result = "neutral" } +} + +import InlineMadTest diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.qlref b/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.qlref deleted file mode 100644 index 851ddc0d2946..000000000000 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.qlref +++ /dev/null @@ -1 +0,0 @@ -utils/modelgenerator/CaptureNeutralModels.ql \ No newline at end of file diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected b/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected index 799a1a37dd45..cb6fc390349c 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected @@ -1,5 +1,2 @@ -| p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];path-injection;df-generated | -| p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[0];path-injection;df-generated | -| p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[1];path-injection;df-generated | -| p;Sinks;true;readUrl;(URL,Charset);;Argument[0];request-forgery;df-generated | -| p;Sources;true;readUrl;(URL);;Argument[0];request-forgery;df-generated | +unexpectedModel +expectedModel diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.ql new file mode 100644 index 000000000000..1acde2ade49d --- /dev/null +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.ql @@ -0,0 +1,11 @@ +import java +import utils.modelgenerator.internal.CaptureModels +import TestUtilities.InlineMadTest + +module InlineMadTestConfig implements InlineMadTestConfigSig { + string getCapturedModel(Callable c) { result = captureSink(c) } + + string getKind() { result = "sink" } +} + +import InlineMadTest diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.qlref b/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.qlref deleted file mode 100644 index 36d2f144247f..000000000000 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.qlref +++ /dev/null @@ -1 +0,0 @@ -utils/modelgenerator/CaptureSinkModels.ql \ No newline at end of file diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.expected b/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.expected index 0f8d0ff1f32a..cb6fc390349c 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.expected +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.expected @@ -1,5 +1,2 @@ -| p;Sources;true;readUrl;(URL);;ReturnValue;remote;df-generated | -| p;Sources;true;socketStream;();;ReturnValue;remote;df-generated | -| p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[0].ArrayElement;remote;df-generated | -| p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[1].Element;remote;df-generated | -| p;Sources;true;wrappedSocketStream;();;ReturnValue;remote;df-generated | +unexpectedModel +expectedModel diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.ql new file mode 100644 index 000000000000..7596f4f8cc14 --- /dev/null +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.ql @@ -0,0 +1,11 @@ +import java +import utils.modelgenerator.internal.CaptureModels +import TestUtilities.InlineMadTest + +module InlineMadTestConfig implements InlineMadTestConfigSig { + string getCapturedModel(Callable c) { result = captureSource(c) } + + string getKind() { result = "source" } +} + +import InlineMadTest diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.qlref b/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.qlref deleted file mode 100644 index 6bbb499fc27b..000000000000 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.qlref +++ /dev/null @@ -1 +0,0 @@ -utils/modelgenerator/CaptureSourceModels.ql \ No newline at end of file diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.expected b/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.expected index 50536e850d9a..cb6fc390349c 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.expected +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.expected @@ -1,47 +1,2 @@ -| p;Factory;false;create;(String);;Argument[0];ReturnValue;taint;df-generated | -| p;Factory;false;create;(String,int);;Argument[0];ReturnValue;taint;df-generated | -| p;Factory;false;getValue;();;Argument[this];ReturnValue;taint;df-generated | -| p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated | -| p;FluentAPI;false;returnsThis;(String);;Argument[this];ReturnValue;value;df-generated | -| p;ImmutablePojo;false;ImmutablePojo;(String,int);;Argument[0];Argument[this];taint;df-generated | -| p;ImmutablePojo;false;getValue;();;Argument[this];ReturnValue;taint;df-generated | -| p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;taint;df-generated | -| p;ImmutablePojo;false;or;(String);;Argument[this];ReturnValue;taint;df-generated | -| p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;taint;df-generated | -| p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;taint;df-generated | -| p;InnerHolder;false;append;(String);;Argument[0];Argument[this];taint;df-generated | -| p;InnerHolder;false;explicitSetContext;(String);;Argument[0];Argument[this];taint;df-generated | -| p;InnerHolder;false;getValue;();;Argument[this];ReturnValue;taint;df-generated | -| p;InnerHolder;false;setContext;(String);;Argument[0];Argument[this];taint;df-generated | -| p;Joiner;false;Joiner;(CharSequence);;Argument[0];Argument[this];taint;df-generated | -| p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[0];Argument[this];taint;df-generated | -| p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[1];Argument[this];taint;df-generated | -| p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[2];Argument[this];taint;df-generated | -| p;Joiner;false;add;(CharSequence);;Argument[this];ReturnValue;value;df-generated | -| p;Joiner;false;merge;(Joiner);;Argument[this];ReturnValue;value;df-generated | -| p;Joiner;false;setEmptyValue;(CharSequence);;Argument[0];Argument[this];taint;df-generated | -| p;Joiner;false;setEmptyValue;(CharSequence);;Argument[this];ReturnValue;value;df-generated | -| p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;taint;df-generated | -| p;MultipleImpls$Strat2;true;getValue;();;Argument[this];ReturnValue;taint;df-generated | -| p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];Argument[this];taint;df-generated | -| p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;taint;df-generated | -| p;ParamFlow;true;addTo;(String,List);;Argument[0];Argument[1].Element;taint;df-generated | -| p;ParamFlow;true;returnArrayElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;df-generated | -| p;ParamFlow;true;returnCollectionElement;(List);;Argument[0].Element;ReturnValue;taint;df-generated | -| p;ParamFlow;true;returnIterableElement;(Iterable);;Argument[0].Element;ReturnValue;taint;df-generated | -| p;ParamFlow;true;returnIteratorElement;(Iterator);;Argument[0].Element;ReturnValue;taint;df-generated | -| p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;taint;df-generated | -| p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;taint;df-generated | -| p;ParamFlow;true;returnVarArgElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;df-generated | -| p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated | -| p;ParamFlow;true;writeChunked;(byte[],OutputStream);;Argument[0];Argument[1];taint;df-generated | -| p;ParamFlow;true;writeChunked;(char[],OutputStream);;Argument[0];Argument[1];taint;df-generated | -| p;Pojo;false;fillIn;(List);;Argument[this];Argument[0].Element;taint;df-generated | -| p;Pojo;false;getBoxedBytes;();;Argument[this];ReturnValue;taint;df-generated | -| p;Pojo;false;getBoxedChars;();;Argument[this];ReturnValue;taint;df-generated | -| p;Pojo;false;getByteArray;();;Argument[this];ReturnValue;taint;df-generated | -| p;Pojo;false;getCharArray;();;Argument[this];ReturnValue;taint;df-generated | -| p;Pojo;false;getValue;();;Argument[this];ReturnValue;taint;df-generated | -| p;Pojo;false;setValue;(String);;Argument[0];Argument[this];taint;df-generated | -| p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];ReturnValue;taint;df-generated | -| p;PrivateFlowViaPublicInterface;true;createAnSPI;(File);;Argument[0];ReturnValue;taint;df-generated | +unexpectedModel +expectedModel diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.ql new file mode 100644 index 000000000000..415ebab13439 --- /dev/null +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.ql @@ -0,0 +1,11 @@ +import java +import utils.modelgenerator.internal.CaptureSummaryFlowQuery +import TestUtilities.InlineMadTest + +module InlineMadTestConfig implements InlineMadTestConfigSig { + string getCapturedModel(Callable c) { result = captureFlow(c) } + + string getKind() { result = "summary" } +} + +import InlineMadTest diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.qlref b/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.qlref deleted file mode 100644 index d751f3823f39..000000000000 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.qlref +++ /dev/null @@ -1 +0,0 @@ -utils/modelgenerator/CaptureSummaryModels.ql \ No newline at end of file diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java b/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java index a6e7ce5fff6a..1887e0ca73e2 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java @@ -2,29 +2,32 @@ public final class Factory { - private String value; - - private int intValue; - - public static Factory create(String value, int foo) { - return new Factory(value, foo); - } - - public static Factory create(String value) { - return new Factory(value, 0); - } - - private Factory(String value, int intValue) { - this.value = value; - this.intValue = intValue; - } - - public String getValue() { - return value; - } - - public int getIntValue() { - return intValue; - } - -} \ No newline at end of file + private String value; + + private int intValue; + + // summary=p;Factory;false;create;(String,int);;Argument[0];ReturnValue;taint;df-generated + public static Factory create(String value, int foo) { + return new Factory(value, foo); + } + + // summary=p;Factory;false;create;(String);;Argument[0];ReturnValue;taint;df-generated + public static Factory create(String value) { + return new Factory(value, 0); + } + + private Factory(String value, int intValue) { + this.value = value; + this.intValue = intValue; + } + + // summary=p;Factory;false;getValue;();;Argument[this];ReturnValue;taint;df-generated + public String getValue() { + return value; + } + + // neutral=p;Factory;getIntValue;();summary;df-generated + public int getIntValue() { + return intValue; + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java b/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java index 224fc44a0bc4..2638f818854f 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java @@ -2,14 +2,15 @@ public final class FinalClass { - private static final String C = "constant"; + private static final String C = "constant"; - public String returnsInput(String input) { - return input; - } + // summary=p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated + public String returnsInput(String input) { + return input; + } - public String returnsConstant() { - return C; - } - -} \ No newline at end of file + // neutral=p;FinalClass;returnsConstant;();summary;df-generated + public String returnsConstant() { + return C; + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java b/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java index 65887625d27a..b7793e30666a 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java @@ -2,14 +2,15 @@ public final class FluentAPI { - public FluentAPI returnsThis(String input) { - return this; - } + // summary=p;FluentAPI;false;returnsThis;(String);;Argument[this];ReturnValue;value;df-generated + public FluentAPI returnsThis(String input) { + return this; + } - public class Inner { - public FluentAPI notThis(String input) { - return FluentAPI.this; - } + public class Inner { + // neutral=p;FluentAPI$Inner;notThis;(String);summary;df-generated + public FluentAPI notThis(String input) { + return FluentAPI.this; } - -} \ No newline at end of file + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java b/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java index 660c1970bd3c..0a2cf2d7dbd3 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java @@ -2,25 +2,29 @@ public final class ImmutablePojo { - private final String value; - - private final long x; - - public ImmutablePojo(String value, int x) { - this.value = value; - this.x = x; - } - - public String getValue() { - return value; - } - - public long getX() { - return x; - } - - public String or(String defaultValue) { - return value != null ? value : defaultValue; - } - -} \ No newline at end of file + private final String value; + + private final long x; + + // summary=p;ImmutablePojo;false;ImmutablePojo;(String,int);;Argument[0];Argument[this];taint;df-generated + public ImmutablePojo(String value, int x) { + this.value = value; + this.x = x; + } + + // summary=p;ImmutablePojo;false;getValue;();;Argument[this];ReturnValue;taint;df-generated + public String getValue() { + return value; + } + + // neutral=p;ImmutablePojo;getX;();summary;df-generated + public long getX() { + return x; + } + + // summary=p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;taint;df-generated + // summary=p;ImmutablePojo;false;or;(String);;Argument[this];ReturnValue;taint;df-generated + public String or(String defaultValue) { + return value != null ? value : defaultValue; + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java b/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java index 936166eddf3f..5b6a8427a3f5 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java @@ -1,21 +1,22 @@ package p; public class InnerClasses { - - class IgnoreMe { - public String no(String input) { - return input; - } - } - - public class CaptureMe { - public String yesCm(String input) { - return input; - } + + class IgnoreMe { + public String no(String input) { + return input; } + } - public String yes(String input) { - return input; + public class CaptureMe { + // summary=p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;taint;df-generated + public String yesCm(String input) { + return input; } + } + // summary=p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;taint;df-generated + public String yes(String input) { + return input; + } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java b/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java index 5dc07cadd51c..e09680dad525 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java @@ -2,36 +2,39 @@ public final class InnerHolder { - private class Context { - private String value; + private class Context { + private String value; - Context(String value) { - this.value = value; - } - - public String getValue() { - return value; - } + Context(String value) { + this.value = value; } - private Context context = null; + public String getValue() { + return value; + } + } - private StringBuilder sb = new StringBuilder(); + private Context context = null; - public void setContext(String value) { - context = new Context(value); - } + private StringBuilder sb = new StringBuilder(); - public void explicitSetContext(String value) { - this.context = new Context(value); - } + // summary=p;InnerHolder;false;setContext;(String);;Argument[0];Argument[this];taint;df-generated + public void setContext(String value) { + context = new Context(value); + } - public void append(String value) { - sb.append(value); - } + // summary=p;InnerHolder;false;explicitSetContext;(String);;Argument[0];Argument[this];taint;df-generated + public void explicitSetContext(String value) { + this.context = new Context(value); + } - public String getValue() { - return context.getValue(); - } + // summary=p;InnerHolder;false;append;(String);;Argument[0];Argument[this];taint;df-generated + public void append(String value) { + sb.append(value); + } -} \ No newline at end of file + // summary=p;InnerHolder;false;getValue;();;Argument[this];ReturnValue;taint;df-generated + public String getValue() { + return context.getValue(); + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java b/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java index d9869815bc52..10fc72c907f2 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java @@ -4,115 +4,123 @@ import java.util.Objects; public final class Joiner { - private final String prefix; - private final String delimiter; - private final String suffix; - private String[] elts; - private int size; - private int len; - private String emptyValue; - public Joiner(CharSequence delimiter) { - this(delimiter, "", ""); - } + private final String prefix; + private final String delimiter; + private final String suffix; + private String[] elts; + private int size; + private int len; + private String emptyValue; - public Joiner(CharSequence delimiter, - CharSequence prefix, - CharSequence suffix) { - Objects.requireNonNull(prefix, "The prefix must not be null"); - Objects.requireNonNull(delimiter, "The delimiter must not be null"); - Objects.requireNonNull(suffix, "The suffix must not be null"); - this.prefix = prefix.toString(); - this.delimiter = delimiter.toString(); - this.suffix = suffix.toString(); - checkAddLength(0, 0); - } + // summary=p;Joiner;false;Joiner;(CharSequence);;Argument[0];Argument[this];taint;df-generated + public Joiner(CharSequence delimiter) { + this(delimiter, "", ""); + } - public Joiner setEmptyValue(CharSequence emptyValue) { - this.emptyValue = Objects.requireNonNull(emptyValue, - "The empty value must not be null").toString(); - return this; - } + // summary=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[0];Argument[this];taint;df-generated + // summary=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[1];Argument[this];taint;df-generated + // summary=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[2];Argument[this];taint;df-generated + public Joiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix) { + Objects.requireNonNull(prefix, "The prefix must not be null"); + Objects.requireNonNull(delimiter, "The delimiter must not be null"); + Objects.requireNonNull(suffix, "The suffix must not be null"); + this.prefix = prefix.toString(); + this.delimiter = delimiter.toString(); + this.suffix = suffix.toString(); + checkAddLength(0, 0); + } - private static int getChars(String s, char[] chars, int start) { - int len = s.length(); - s.getChars(0, len, chars, start); - return len; - } + // summary=p;Joiner;false;setEmptyValue;(CharSequence);;Argument[0];Argument[this];taint;df-generated + // summary=p;Joiner;false;setEmptyValue;(CharSequence);;Argument[this];ReturnValue;value;df-generated + public Joiner setEmptyValue(CharSequence emptyValue) { + this.emptyValue = + Objects.requireNonNull(emptyValue, "The empty value must not be null").toString(); + return this; + } - @Override - public String toString() { - final String[] elts = this.elts; - if (elts == null && emptyValue != null) { - return emptyValue; - } - final int size = this.size; - final int addLen = prefix.length() + suffix.length(); - if (addLen == 0) { - compactElts(); - return size == 0 ? "" : elts[0]; - } - final String delimiter = this.delimiter; - final char[] chars = new char[len + addLen]; - int k = getChars(prefix, chars, 0); - if (size > 0) { - k += getChars(elts[0], chars, k); - for (int i = 1; i < size; i++) { - k += getChars(delimiter, chars, k); - k += getChars(elts[i], chars, k); - } - } - k += getChars(suffix, chars, k); - return new String(chars); - } + private static int getChars(String s, char[] chars, int start) { + int len = s.length(); + s.getChars(0, len, chars, start); + return len; + } - public Joiner add(CharSequence newElement) { - final String elt = String.valueOf(newElement); - if (elts == null) { - elts = new String[8]; - } else { - if (size == elts.length) - elts = Arrays.copyOf(elts, 2 * size); - len = checkAddLength(len, delimiter.length()); - } - len = checkAddLength(len, elt.length()); - elts[size++] = elt; - return this; + @Override + public String toString() { + final String[] elts = this.elts; + if (elts == null && emptyValue != null) { + return emptyValue; + } + final int size = this.size; + final int addLen = prefix.length() + suffix.length(); + if (addLen == 0) { + compactElts(); + return size == 0 ? "" : elts[0]; } + final String delimiter = this.delimiter; + final char[] chars = new char[len + addLen]; + int k = getChars(prefix, chars, 0); + if (size > 0) { + k += getChars(elts[0], chars, k); + for (int i = 1; i < size; i++) { + k += getChars(delimiter, chars, k); + k += getChars(elts[i], chars, k); + } + } + k += getChars(suffix, chars, k); + return new String(chars); + } - private int checkAddLength(int oldLen, int inc) { - long newLen = (long)oldLen + (long)inc; - long tmpLen = newLen + (long)prefix.length() + (long)suffix.length(); - if (tmpLen != (int)tmpLen) { - throw new OutOfMemoryError("Requested array size exceeds VM limit"); - } - return (int)newLen; + // summary=p;Joiner;false;add;(CharSequence);;Argument[this];ReturnValue;value;df-generated + public Joiner add(CharSequence newElement) { + final String elt = String.valueOf(newElement); + if (elts == null) { + elts = new String[8]; + } else { + if (size == elts.length) elts = Arrays.copyOf(elts, 2 * size); + len = checkAddLength(len, delimiter.length()); } + len = checkAddLength(len, elt.length()); + elts[size++] = elt; + return this; + } - public Joiner merge(Joiner other) { - Objects.requireNonNull(other); - if (other.elts == null) { - return this; - } - other.compactElts(); - return add(other.elts[0]); + private int checkAddLength(int oldLen, int inc) { + long newLen = (long) oldLen + (long) inc; + long tmpLen = newLen + (long) prefix.length() + (long) suffix.length(); + if (tmpLen != (int) tmpLen) { + throw new OutOfMemoryError("Requested array size exceeds VM limit"); } + return (int) newLen; + } - private void compactElts() { - if (size > 1) { - final char[] chars = new char[len]; - int i = 1, k = getChars(elts[0], chars, 0); - do { - k += getChars(delimiter, chars, k); - k += getChars(elts[i], chars, k); - elts[i] = null; - } while (++i < size); - size = 1; - elts[0] = new String(chars); - } + // summary=p;Joiner;false;merge;(Joiner);;Argument[this];ReturnValue;value;df-generated + public Joiner merge(Joiner other) { + Objects.requireNonNull(other); + if (other.elts == null) { + return this; } + other.compactElts(); + return add(other.elts[0]); + } - public int length() { - return (size == 0 && emptyValue != null) ? emptyValue.length() : - len + prefix.length() + suffix.length(); + private void compactElts() { + if (size > 1) { + final char[] chars = new char[len]; + int i = 1, k = getChars(elts[0], chars, 0); + do { + k += getChars(delimiter, chars, k); + k += getChars(elts[i], chars, k); + elts[i] = null; + } while (++i < size); + size = 1; + elts[0] = new String(chars); } -} \ No newline at end of file + } + + // neutral=p;Joiner;length;();summary;df-generated + public int length() { + return (size == 0 && emptyValue != null) + ? emptyValue.length() + : len + prefix.length() + suffix.length(); + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java index 9de2d59b2e4f..3e5d9abd7687 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java @@ -2,22 +2,23 @@ class MultipleImpl2 { - // Multiple implementations of the same interface. - // This is used to test that we only generate a summary model and - // not neutral summary model for `IInterface.m`. - public interface IInterface { - Object m(Object value); - } + // Multiple implementations of the same interface. + // This is used to test that we only generate a summary model and + // not neutral summary model for `IInterface.m`. + public interface IInterface { + Object m(Object value); + } - public class Impl1 implements IInterface { - public Object m(Object value) { - return null; - } + public class Impl1 implements IInterface { + public Object m(Object value) { + return null; } + } - public class Impl2 implements IInterface { - public Object m(Object value) { - return value; - } + public class Impl2 implements IInterface { + // summary=p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;taint;df-generated + public Object m(Object value) { + return value; } + } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java index a6697393dbc1..d2b4ac133b57 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java @@ -4,35 +4,38 @@ public class MultipleImpls { - public static interface Strategy { - String doSomething(String value); + public static interface Strategy { + String doSomething(String value); + } + + public static class Strat1 implements Strategy { + // summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;taint;df-generated + public String doSomething(String value) { + return value; } + } - public static class Strat1 implements Strategy { - public String doSomething(String value) { - return value; - } + // implements in different library should not count as impl + public static class Strat3 implements Callable { + + @Override + public String call() throws Exception { + return null; + } + } + + public static class Strat2 implements Strategy { + private String foo; + + // summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];Argument[this];taint;df-generated + public String doSomething(String value) { + this.foo = value; + return "none"; } - // implements in different library should not count as impl - public static class Strat3 implements Callable { - - @Override - public String call() throws Exception { - return null; - } - - } - public static class Strat2 implements Strategy { - private String foo; - - public String doSomething(String value) { - this.foo = value; - return "none"; - } - - public String getValue() { - return this.foo; - } + // summary=p;MultipleImpls$Strat2;true;getValue;();;Argument[this];ReturnValue;taint;df-generated + public String getValue() { + return this.foo; } + } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java b/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java index 8b58c3773167..d175ee9c71e6 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java @@ -1,64 +1,73 @@ package p; -import java.util.Iterator; -import java.util.List; import java.io.IOException; import java.io.OutputStream; - +import java.util.Iterator; +import java.util.List; public class ParamFlow { - public String returnsInput(String input) { - return input; - } + // summary=p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated + public String returnsInput(String input) { + return input; + } - public int ignorePrimitiveReturnValue(String input) { - return input.length(); - } + // neutral=p;ParamFlow;ignorePrimitiveReturnValue;(String);summary;df-generated + public int ignorePrimitiveReturnValue(String input) { + return input.length(); + } - public String returnMultipleParameters(String one, String two) { - if (System.currentTimeMillis() > 100) { - return two; - } - return one; + // summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;taint;df-generated + // summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;taint;df-generated + public String returnMultipleParameters(String one, String two) { + if (System.currentTimeMillis() > 100) { + return two; } + return one; + } - public String returnArrayElement(String[] input) { - return input[0]; - } + // summary=p;ParamFlow;true;returnArrayElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;df-generated + public String returnArrayElement(String[] input) { + return input[0]; + } - public String returnVarArgElement(String... input) { - return input[0]; - } + // summary=p;ParamFlow;true;returnVarArgElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;df-generated + public String returnVarArgElement(String... input) { + return input[0]; + } - public String returnCollectionElement(List input) { - return input.get(0); - } + // summary=p;ParamFlow;true;returnCollectionElement;(List);;Argument[0].Element;ReturnValue;taint;df-generated + public String returnCollectionElement(List input) { + return input.get(0); + } - public String returnIteratorElement(Iterator input) { - return input.next(); - } + // summary=p;ParamFlow;true;returnIteratorElement;(Iterator);;Argument[0].Element;ReturnValue;taint;df-generated + public String returnIteratorElement(Iterator input) { + return input.next(); + } - public String returnIterableElement(Iterable input) { - return input.iterator().next(); - } + // summary=p;ParamFlow;true;returnIterableElement;(Iterable);;Argument[0].Element;ReturnValue;taint;df-generated + public String returnIterableElement(Iterable input) { + return input.iterator().next(); + } - public Class mapType(Class input) { - return input; - } + // neutral=p;ParamFlow;mapType;(Class);summary;df-generated + public Class mapType(Class input) { + return input; + } - public void writeChunked(byte[] data, OutputStream output) - throws IOException { - output.write(data, 0, data.length); - } - - public void writeChunked(char[] data, OutputStream output) - throws IOException { - output.write(String.valueOf(data).getBytes(), 0, data.length); - } + // summary=p;ParamFlow;true;writeChunked;(byte[],OutputStream);;Argument[0];Argument[1];taint;df-generated + public void writeChunked(byte[] data, OutputStream output) throws IOException { + output.write(data, 0, data.length); + } - public void addTo(String data, List target) { - target.add(data); - } + // summary=p;ParamFlow;true;writeChunked;(char[],OutputStream);;Argument[0];Argument[1];taint;df-generated + public void writeChunked(char[] data, OutputStream output) throws IOException { + output.write(String.valueOf(data).getBytes(), 0, data.length); + } -} \ No newline at end of file + // summary=p;ParamFlow;true;addTo;(String,List);;Argument[0];Argument[1].Element;taint;df-generated + public void addTo(String data, List target) { + target.add(data); + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java b/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java index 40dfa56ae868..9d5de0517e1e 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java @@ -8,91 +8,106 @@ public final class Pojo { - private class Holder { - private String value; - - Holder(String value) { - this.value = value; - } - - int length() { - return value.length(); - } - } - + private class Holder { private String value; - private int intValue = 2; - - private byte[] byteArray = new byte[] {1, 2, 3} ; - private float[] floatArray = new float[] {1, 2, 3} ; - private char[] charArray = new char[] {'a', 'b', 'c'} ; - private List charList = Arrays.asList('a', 'b', 'c'); - private Byte[] byteObjectArray = new Byte[] { 1, 2, 3 }; - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public int doNotSetValue(String value) { - Holder h = new Holder(value); - return h.length(); - } - - public int getIntValue() { - return intValue; - } - - public Integer getBoxedValue() { - return Integer.valueOf(intValue); - } - - public int[] getPrimitiveArray() { - return new int[] { intValue }; - } - - public char[] getCharArray() { - return charArray; - } - - public byte[] getByteArray() { - return byteArray; - } - - public float[] getFloatArray() { - return floatArray; - } - - public Integer[] getBoxedArray() { - return new Integer[] { Integer.valueOf(intValue) }; - } - - public Collection getBoxedCollection() { - return List.of(Integer.valueOf(intValue)); - } - - public List getBoxedChars() { - return charList; - } - - public Byte[] getBoxedBytes() { - return byteObjectArray; - } - - public BigInteger getBigInt() { - return BigInteger.valueOf(intValue); - } - - public BigDecimal getBigDecimal() { - return new BigDecimal(value); - } - - public void fillIn(List target) { - target.add(value); - } - -} \ No newline at end of file + Holder(String value) { + this.value = value; + } + + int length() { + return value.length(); + } + } + + private String value; + + private int intValue = 2; + + private byte[] byteArray = new byte[] {1, 2, 3}; + private float[] floatArray = new float[] {1, 2, 3}; + private char[] charArray = new char[] {'a', 'b', 'c'}; + private List charList = Arrays.asList('a', 'b', 'c'); + private Byte[] byteObjectArray = new Byte[] {1, 2, 3}; + + // summary=p;Pojo;false;getValue;();;Argument[this];ReturnValue;taint;df-generated + public String getValue() { + return value; + } + + // summary=p;Pojo;false;setValue;(String);;Argument[0];Argument[this];taint;df-generated + public void setValue(String value) { + this.value = value; + } + + // neutral=p;Pojo;doNotSetValue;(String);summary;df-generated + public int doNotSetValue(String value) { + Holder h = new Holder(value); + return h.length(); + } + + // neutral=p;Pojo;getIntValue;();summary;df-generated + public int getIntValue() { + return intValue; + } + + // neutral=p;Pojo;getBoxedValue;();summary;df-generated + public Integer getBoxedValue() { + return Integer.valueOf(intValue); + } + + // neutral=p;Pojo;getPrimitiveArray;();summary;df-generated + public int[] getPrimitiveArray() { + return new int[] {intValue}; + } + + // summary=p;Pojo;false;getCharArray;();;Argument[this];ReturnValue;taint;df-generated + public char[] getCharArray() { + return charArray; + } + + // summary=p;Pojo;false;getByteArray;();;Argument[this];ReturnValue;taint;df-generated + public byte[] getByteArray() { + return byteArray; + } + + // neutral=p;Pojo;getFloatArray;();summary;df-generated + public float[] getFloatArray() { + return floatArray; + } + + // neutral=p;Pojo;getBoxedArray;();summary;df-generated + public Integer[] getBoxedArray() { + return new Integer[] {Integer.valueOf(intValue)}; + } + + // neutral=p;Pojo;getBoxedCollection;();summary;df-generated + public Collection getBoxedCollection() { + return List.of(Integer.valueOf(intValue)); + } + + // summary=p;Pojo;false;getBoxedChars;();;Argument[this];ReturnValue;taint;df-generated + public List getBoxedChars() { + return charList; + } + + // summary=p;Pojo;false;getBoxedBytes;();;Argument[this];ReturnValue;taint;df-generated + public Byte[] getBoxedBytes() { + return byteObjectArray; + } + + // neutral=p;Pojo;getBigInt;();summary;df-generated + public BigInteger getBigInt() { + return BigInteger.valueOf(intValue); + } + + // neutral=p;Pojo;getBigDecimal;();summary;df-generated + public BigDecimal getBigDecimal() { + return new BigDecimal(value); + } + + // summary=p;Pojo;false;fillIn;(List);;Argument[this];Argument[0].Element;taint;df-generated + public void fillIn(List target) { + target.add(value); + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java b/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java index 59247bfe471b..25c62172121a 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java @@ -7,55 +7,58 @@ public class PrivateFlowViaPublicInterface { - static class RandomPojo { - public File someFile = new File("someFile"); - } - public static interface SPI { - OutputStream openStream() throws IOException; - - default OutputStream openStreamNone() throws IOException { - return null; - }; - } + static class RandomPojo { + public File someFile = new File("someFile"); + } - private static final class PrivateImplWithSink implements SPI { + public static interface SPI { + OutputStream openStream() throws IOException; - private File file; + // neutral=p;PrivateFlowViaPublicInterface$SPI;openStreamNone;();summary;df-generated + default OutputStream openStreamNone() throws IOException { + return null; + } + } - public PrivateImplWithSink(File file) { - this.file = file; - } + private static final class PrivateImplWithSink implements SPI { - @Override - public OutputStream openStream() throws IOException { - return new FileOutputStream(file); - } + private File file; + public PrivateImplWithSink(File file) { + this.file = file; } - - private static final class PrivateImplWithRandomField implements SPI { - - public PrivateImplWithRandomField(File file) { - } - - @Override - public OutputStream openStream() throws IOException { - return null; - } - - @Override - public OutputStream openStreamNone() throws IOException { - return new FileOutputStream(new RandomPojo().someFile); - } + // summary=p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];ReturnValue;taint;df-generated + // sink=p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];path-injection;df-generated + @Override + public OutputStream openStream() throws IOException { + return new FileOutputStream(file); } + } - public static SPI createAnSPI(File file) { - return new PrivateImplWithSink(file); + private static final class PrivateImplWithRandomField implements SPI { + + public PrivateImplWithRandomField(File file) {} + + @Override + public OutputStream openStream() throws IOException { + return null; } - - public static SPI createAnSPIWithoutTrackingFile(File file) { - return new PrivateImplWithRandomField(file); + + // neutral=p;PrivateFlowViaPublicInterface$SPI;openStreamNone;();summary;df-generated + @Override + public OutputStream openStreamNone() throws IOException { + return new FileOutputStream(new RandomPojo().someFile); } + } + + // summary=p;PrivateFlowViaPublicInterface;true;createAnSPI;(File);;Argument[0];ReturnValue;taint;df-generated + public static SPI createAnSPI(File file) { + return new PrivateImplWithSink(file); + } -} \ No newline at end of file + // neutral=p;PrivateFlowViaPublicInterface;createAnSPIWithoutTrackingFile;(File);summary;df-generated + public static SPI createAnSPIWithoutTrackingFile(File file) { + return new PrivateImplWithRandomField(file); + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Sinks.java b/java/ql/test/utils/modelgenerator/dataflow/p/Sinks.java index 260f235920a5..e9868b260730 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Sinks.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Sinks.java @@ -3,32 +3,39 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; -import java.nio.file.CopyOption; import java.nio.charset.Charset; +import java.nio.file.CopyOption; import java.nio.file.Files; import java.nio.file.Path; import java.util.logging.Logger; public class Sinks { - - public Path copyFileToDirectory(final Path sourceFile, final Path targetFile, final CopyOption... copyOptions) throws IOException { - return Files.copy(sourceFile, targetFile, copyOptions); - } - public String readUrl(final URL url, Charset encoding) throws IOException { - try (InputStream in = url.openStream()) { - byte[] bytes = in.readAllBytes(); - return new String(bytes, encoding); - } - } + // sink=p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[0];path-injection;df-generated + // sink=p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[1];path-injection;df-generated + // neutral=p;Sinks;copyFileToDirectory;(Path,Path,CopyOption[]);summary;df-generated + public Path copyFileToDirectory( + final Path sourceFile, final Path targetFile, final CopyOption... copyOptions) + throws IOException { + return Files.copy(sourceFile, targetFile, copyOptions); + } - public static void main(String[] args) throws IOException { - String foo = new Sinks().readUrl(new URL(args[0]), Charset.defaultCharset()); + // sink=p;Sinks;true;readUrl;(URL,Charset);;Argument[0];request-forgery;df-generated + // neutral=p;Sinks;readUrl;(URL,Charset);summary;df-generated + public String readUrl(final URL url, Charset encoding) throws IOException { + try (InputStream in = url.openStream()) { + byte[] bytes = in.readAllBytes(); + return new String(bytes, encoding); } + } - public void propagate(String s) { - Logger logger = Logger.getLogger(Sinks.class.getSimpleName()); - logger.warning(s); - } + public static void main(String[] args) throws IOException { + String foo = new Sinks().readUrl(new URL(args[0]), Charset.defaultCharset()); + } + // neutral=p;Sinks;propagate;(String);summary;df-generated + public void propagate(String s) { + Logger logger = Logger.getLogger(Sinks.class.getSimpleName()); + logger.warning(s); + } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Sources.java b/java/ql/test/utils/modelgenerator/dataflow/p/Sources.java index 7b008ff378f2..436bf16797c7 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Sources.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Sources.java @@ -4,29 +4,37 @@ import java.io.InputStream; import java.net.ServerSocket; import java.net.URL; -import java.util.function.Consumer; import java.util.List; - public class Sources { - - public InputStream readUrl(final URL url) throws IOException { - return url.openConnection().getInputStream(); - } - public InputStream socketStream() throws IOException { - ServerSocket socket = new ServerSocket(123); - return socket.accept().getInputStream(); - } + // source=p;Sources;true;readUrl;(URL);;ReturnValue;remote;df-generated + // sink=p;Sources;true;readUrl;(URL);;Argument[0];request-forgery;df-generated + // neutral=p;Sources;readUrl;(URL);summary;df-generated + public InputStream readUrl(final URL url) throws IOException { + return url.openConnection().getInputStream(); + } - public InputStream wrappedSocketStream() throws IOException { - return socketStream(); - } + // source=p;Sources;true;socketStream;();;ReturnValue;remote;df-generated + // neutral=p;Sources;socketStream;();summary;df-generated + public InputStream socketStream() throws IOException { + ServerSocket socket = new ServerSocket(123); + return socket.accept().getInputStream(); + } - public void sourceToParameter(InputStream[] streams, List otherStreams) throws IOException { - ServerSocket socket = new ServerSocket(123); - streams[0] = socket.accept().getInputStream(); - otherStreams.add(socket.accept().getInputStream()); - } + // source=p;Sources;true;wrappedSocketStream;();;ReturnValue;remote;df-generated + // neutral=p;Sources;wrappedSocketStream;();summary;df-generated + public InputStream wrappedSocketStream() throws IOException { + return socketStream(); + } + // source=p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[0].ArrayElement;remote;df-generated + // source=p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[1].Element;remote;df-generated + // neutral=p;Sources;sourceToParameter;(InputStream[],List);summary;df-generated + public void sourceToParameter(InputStream[] streams, List otherStreams) + throws IOException { + ServerSocket socket = new ServerSocket(123); + streams[0] = socket.accept().getInputStream(); + otherStreams.add(socket.accept().getInputStream()); + } } diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.expected b/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.expected index ee55a9c6ba6e..cb6fc390349c 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.expected +++ b/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.expected @@ -1,2 +1,2 @@ -unexpectedSummary -expectedSummary +unexpectedModel +expectedModel diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql b/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql index fe77abaa6df8..2bf4e08d2c17 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql +++ b/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql @@ -1,26 +1,11 @@ import java +import TestUtilities.InlineMadTest import utils.modelgenerator.internal.CaptureTypeBasedSummaryModels -private string expects() { - exists(Javadoc doc | - doc.getChild(0).toString().regexpCapture(" *(SPURIOUS-)?MaD=(.*)", 2) = result - ) -} - -private string flows() { result = captureFlow(_) } +module InlineMadTestConfig implements InlineMadTestConfigSig { + string getCapturedModel(Callable c) { result = captureFlow(c) } -query predicate unexpectedSummary(string msg) { - exists(string flow | - flow = flows() and - not flow = expects() and - msg = "Unexpected summary found: " + flow - ) + string getKind() { result = "summary" } } -query predicate expectedSummary(string msg) { - exists(string e | - e = expects() and - not e = flows() and - msg = "Expected summary missing: " + e - ) -} +import InlineMadTest diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/p/MyFunction.java b/java/ql/test/utils/modelgenerator/typebasedflow/p/MyFunction.java index 04683952f83f..e3589bf5f6ca 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/p/MyFunction.java +++ b/java/ql/test/utils/modelgenerator/typebasedflow/p/MyFunction.java @@ -3,8 +3,8 @@ @FunctionalInterface public interface MyFunction { - // MaD=p;MyFunction;true;apply;(Object,Object);;Argument[this].SyntheticField[ArgType2];ReturnValue;value;tb-generated - // MaD=p;MyFunction;true;apply;(Object,Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated - // MaD=p;MyFunction;true;apply;(Object,Object);;Argument[1];Argument[this].SyntheticField[ArgType1];value;tb-generated - T3 apply(T1 x, T2 y); -} \ No newline at end of file + // summary=p;MyFunction;true;apply;(Object,Object);;Argument[this].SyntheticField[ArgType2];ReturnValue;value;tb-generated + // summary=p;MyFunction;true;apply;(Object,Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated + // summary=p;MyFunction;true;apply;(Object,Object);;Argument[1];Argument[this].SyntheticField[ArgType1];value;tb-generated + T3 apply(T1 x, T2 y); +} diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/p/Stream.java b/java/ql/test/utils/modelgenerator/typebasedflow/p/Stream.java index 86d25088645c..8e99fc7ca7c3 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/p/Stream.java +++ b/java/ql/test/utils/modelgenerator/typebasedflow/p/Stream.java @@ -2,246 +2,244 @@ import java.util.*; import java.util.function.*; -import java.util.stream.LongStream; -import java.util.stream.IntStream; -import java.util.stream.DoubleStream; import java.util.stream.Collector; +import java.util.stream.DoubleStream; +import java.util.stream.IntStream; +import java.util.stream.LongStream; -/** - * This is a stub implementation of the Java Stream API. - */ +/** This is a stub implementation of the Java Stream API. */ public class Stream { - // MaD=p;Stream;true;iterator;();;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Iterator iterator() { - return null; - } - - // MaD=p;Stream;true;allMatch;(Predicate);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public boolean allMatch(Predicate predicate) { - return false; - } - - // MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[this].Element;Argument[1].Parameter[1];value;tb-generated - // MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[2].Parameter[0];value;tb-generated - // MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[2].Parameter[1];value;tb-generated - // MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;ReturnValue;value;tb-generated - public R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner) { - return null; - } - - // Collector is not a functional interface, so this is not supported - public R collect(Collector collector) { - return null; - } - - // MaD=p;Stream;true;concat;(Stream,Stream);;Argument[0].Element;ReturnValue.Element;value;tb-generated - // MaD=p;Stream;true;concat;(Stream,Stream);;Argument[1].Element;ReturnValue.Element;value;tb-generated - public static Stream concat(Stream a, Stream b) { - return null; - } - - // MaD=p;Stream;true;distinct;();;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Stream distinct() { - return null; - } - - public static Stream empty() { - return null; - } - - // MaD=p;Stream;true;filter;(Predicate);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;filter;(Predicate);;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Stream filter(Predicate predicate) { - return null; - } - - // MaD=p;Stream;true;findAny;();;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated - public Optional findAny() { - return null; - } - - // MaD=p;Stream;true;findFirst;();;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated - public Optional findFirst() { - return null; - } - - // MaD=p;Stream;true;flatMap;(Function);;Argument[0].ReturnValue.Element;ReturnValue.Element;value;tb-generated - // MaD=p;Stream;true;flatMap;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public Stream flatMap(Function> mapper) { - return null; - } - - // MaD=p;Stream;true;flatMapToDouble;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public DoubleStream flatMapToDouble(Function mapper) { - return null; - } - - // MaD=p;Stream;true;flatMapToInt;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public IntStream flatMapToInt(Function mapper) { - return null; - } - - // MaD=p;Stream;true;flatMapToLong;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public LongStream flatMapToLong(Function mapper) { - return null; - } - - // MaD=p;Stream;true;forEach;(Consumer);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public void forEach(Consumer action) { - } - - // MaD=p;Stream;true;forEachOrdered;(Consumer);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public void forEachOrdered(Consumer action) { - } - - // MaD=p;Stream;true;generate;(Supplier);;Argument[0].ReturnValue;ReturnValue.Element;value;tb-generated - public static Stream generate(Supplier s) { - return null; - } - - // MaD=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[0];Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[0];ReturnValue.Element;value;tb-generated - // MaD=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[1].ReturnValue;ReturnValue.Element;value;tb-generated - public static Stream iterate(T seed, UnaryOperator f) { - return null; - } - - // MaD=p;Stream;true;limit;(long);;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Stream limit(long maxSize) { - return null; - } - - // MaD=p;Stream;true;map;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;map;(Function);;Argument[0].ReturnValue;ReturnValue.Element;value;tb-generated - public Stream map(Function mapper) { - return null; - } - - // MaD=p;Stream;true;mapToDouble;(ToDoubleFunction);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public DoubleStream mapToDouble(ToDoubleFunction mapper) { - return null; - } - - // MaD=p;Stream;true;mapToInt;(ToIntFunction);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public IntStream mapToInt(ToIntFunction mapper) { - return null; - } - - // MaD=p;Stream;true;mapToLong;(ToLongFunction);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public LongStream mapToLong(ToLongFunction mapper) { - return null; - } - - // MaD=p;Stream;true;max;(Comparator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;max;(Comparator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated - // MaD=p;Stream;true;max;(Comparator);;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated - public Optional max(Comparator comparator) { - return null; - } - - // MaD=p;Stream;true;min;(Comparator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;min;(Comparator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated - // MaD=p;Stream;true;min;(Comparator);;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated - public Optional min(Comparator comparator) { - return null; - } - - // MaD=p;Stream;true;noneMatch;(Predicate);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public boolean noneMatch(Predicate predicate) { - return false; - } - - // MaD=p;Stream;true;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;tb-generated - public static Stream of(T... t) { - return null; - } - - // MaD=p;Stream;true;of;(Object);;Argument[0];ReturnValue.Element;value;tb-generated - public static Stream of(T t) { - return null; - } - - // MaD=p;Stream;true;peek;(Consumer);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;peek;(Consumer);;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Stream peek(Consumer action) { - return null; - } - - // The generated models are only partially correct. - // MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated - // MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[0].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;ReturnValue.SyntheticField[ArgType0];value;tb-generated - // SPURIOUS-MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[this].Element;value;tb-generated - public Optional reduce(BinaryOperator accumulator) { - return null; - } - - // The generated models are only partially correct. - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[this].Element;Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[this].Element;Argument[1].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[1].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];ReturnValue;value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;ReturnValue;value;tb-generated - // SPURIOUS-MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[this].Element;ReturnValue;value;tb-generated - // SPURIOUS-MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[this].Element;value;tb-generated - // SPURIOUS-MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[this].Element;value;tb-generated - public T reduce(T identity, BinaryOperator accumulator) { - return null; - } - - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[this].Element;Argument[1].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[2].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[2].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];ReturnValue;value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[2].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[2].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;ReturnValue;value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[2].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[2].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;ReturnValue;value;tb-generated - public U reduce(U identity, BiFunction accumulator, BinaryOperator combiner) { - return null; - } - - // MaD=p;Stream;true;skip;(long);;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Stream skip(long n) { - return null; - } - - // MaD=p;Stream;true;sorted;();;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Stream sorted() { - return null; - } - - // MaD=p;Stream;true;sorted;(Comparator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;sorted;(Comparator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated - // MaD=p;Stream;true;sorted;(Comparator);;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Stream sorted(Comparator comparator) { - return null; - } - - // Models can never be generated correctly based on the type information - // as it involves downcasting. - public Object[] toArray() { - return null; - } - - // The generated result is only partially correct as there is no mentioning of - // the type T in the method definition. - // MaD=p;Stream;true;toArray;(IntFunction);;Argument[0].ReturnValue.ArrayElement;ReturnValue.ArrayElement;value;tb-generated - public A[] toArray(IntFunction generator) { - return null; - } -} \ No newline at end of file + // summary=p;Stream;true;iterator;();;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Iterator iterator() { + return null; + } + + // summary=p;Stream;true;allMatch;(Predicate);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public boolean allMatch(Predicate predicate) { + return false; + } + + // summary=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[this].Element;Argument[1].Parameter[1];value;tb-generated + // summary=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[2].Parameter[0];value;tb-generated + // summary=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[2].Parameter[1];value;tb-generated + // summary=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;ReturnValue;value;tb-generated + public R collect( + Supplier supplier, BiConsumer accumulator, BiConsumer combiner) { + return null; + } + + // Collector is not a functional interface, so this is not supported + public R collect(Collector collector) { + return null; + } + + // summary=p;Stream;true;concat;(Stream,Stream);;Argument[0].Element;ReturnValue.Element;value;tb-generated + // summary=p;Stream;true;concat;(Stream,Stream);;Argument[1].Element;ReturnValue.Element;value;tb-generated + public static Stream concat(Stream a, Stream b) { + return null; + } + + // summary=p;Stream;true;distinct;();;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Stream distinct() { + return null; + } + + public static Stream empty() { + return null; + } + + // summary=p;Stream;true;filter;(Predicate);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;filter;(Predicate);;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Stream filter(Predicate predicate) { + return null; + } + + // summary=p;Stream;true;findAny;();;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated + public Optional findAny() { + return null; + } + + // summary=p;Stream;true;findFirst;();;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated + public Optional findFirst() { + return null; + } + + // summary=p;Stream;true;flatMap;(Function);;Argument[0].ReturnValue.Element;ReturnValue.Element;value;tb-generated + // summary=p;Stream;true;flatMap;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public Stream flatMap(Function> mapper) { + return null; + } + + // summary=p;Stream;true;flatMapToDouble;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public DoubleStream flatMapToDouble(Function mapper) { + return null; + } + + // summary=p;Stream;true;flatMapToInt;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public IntStream flatMapToInt(Function mapper) { + return null; + } + + // summary=p;Stream;true;flatMapToLong;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public LongStream flatMapToLong(Function mapper) { + return null; + } + + // summary=p;Stream;true;forEach;(Consumer);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public void forEach(Consumer action) {} + + // summary=p;Stream;true;forEachOrdered;(Consumer);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public void forEachOrdered(Consumer action) {} + + // summary=p;Stream;true;generate;(Supplier);;Argument[0].ReturnValue;ReturnValue.Element;value;tb-generated + public static Stream generate(Supplier s) { + return null; + } + + // summary=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[0];Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[0];ReturnValue.Element;value;tb-generated + // summary=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[1].ReturnValue;ReturnValue.Element;value;tb-generated + public static Stream iterate(T seed, UnaryOperator f) { + return null; + } + + // summary=p;Stream;true;limit;(long);;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Stream limit(long maxSize) { + return null; + } + + // summary=p;Stream;true;map;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;map;(Function);;Argument[0].ReturnValue;ReturnValue.Element;value;tb-generated + public Stream map(Function mapper) { + return null; + } + + // summary=p;Stream;true;mapToDouble;(ToDoubleFunction);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public DoubleStream mapToDouble(ToDoubleFunction mapper) { + return null; + } + + // summary=p;Stream;true;mapToInt;(ToIntFunction);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public IntStream mapToInt(ToIntFunction mapper) { + return null; + } + + // summary=p;Stream;true;mapToLong;(ToLongFunction);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public LongStream mapToLong(ToLongFunction mapper) { + return null; + } + + // summary=p;Stream;true;max;(Comparator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;max;(Comparator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated + // summary=p;Stream;true;max;(Comparator);;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated + public Optional max(Comparator comparator) { + return null; + } + + // summary=p;Stream;true;min;(Comparator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;min;(Comparator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated + // summary=p;Stream;true;min;(Comparator);;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated + public Optional min(Comparator comparator) { + return null; + } + + // summary=p;Stream;true;noneMatch;(Predicate);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public boolean noneMatch(Predicate predicate) { + return false; + } + + // summary=p;Stream;true;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;tb-generated + public static Stream of(T... t) { + return null; + } + + // summary=p;Stream;true;of;(Object);;Argument[0];ReturnValue.Element;value;tb-generated + public static Stream of(T t) { + return null; + } + + // summary=p;Stream;true;peek;(Consumer);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;peek;(Consumer);;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Stream peek(Consumer action) { + return null; + } + + // The generated models are only partially correct. + // summary=p;Stream;true;reduce;(BinaryOperator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(BinaryOperator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(BinaryOperator);;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated + // summary=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[0].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;ReturnValue.SyntheticField[ArgType0];value;tb-generated + // SPURIOUS-summary=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[this].Element;value;tb-generated + public Optional reduce(BinaryOperator accumulator) { + return null; + } + + // The generated models are only partially correct. + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[this].Element;Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[this].Element;Argument[1].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[1].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];ReturnValue;value;tb-generated + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;ReturnValue;value;tb-generated + // SPURIOUS-summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[this].Element;ReturnValue;value;tb-generated + // SPURIOUS-summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[this].Element;value;tb-generated + // SPURIOUS-summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[this].Element;value;tb-generated + public T reduce(T identity, BinaryOperator accumulator) { + return null; + } + + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[this].Element;Argument[1].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[2].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[2].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];ReturnValue;value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[2].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[2].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;ReturnValue;value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[2].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[2].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;ReturnValue;value;tb-generated + public U reduce( + U identity, BiFunction accumulator, BinaryOperator combiner) { + return null; + } + + // summary=p;Stream;true;skip;(long);;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Stream skip(long n) { + return null; + } + + // summary=p;Stream;true;sorted;();;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Stream sorted() { + return null; + } + + // summary=p;Stream;true;sorted;(Comparator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;sorted;(Comparator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated + // summary=p;Stream;true;sorted;(Comparator);;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Stream sorted(Comparator comparator) { + return null; + } + + // Models can never be generated correctly based on the type information + // as it involves downcasting. + public Object[] toArray() { + return null; + } + + // The generated result is only partially correct as there is no mentioning of + // the type T in the method definition. + // summary=p;Stream;true;toArray;(IntFunction);;Argument[0].ReturnValue.ArrayElement;ReturnValue.ArrayElement;value;tb-generated + public A[] toArray(IntFunction generator) { + return null; + } +} diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedCollection.java b/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedCollection.java index b1c95dc415a0..e66189e7dedd 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedCollection.java +++ b/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedCollection.java @@ -1,25 +1,23 @@ package p; -import java.util.List; import java.util.ArrayList; +import java.util.List; public class TypeBasedCollection extends ArrayList { - // MaD=p;TypeBasedCollection;true;addT;(Object);;Argument[0];Argument[this].Element;value;tb-generated - public void addT(T x) { - } + // summary=p;TypeBasedCollection;true;addT;(Object);;Argument[0];Argument[this].Element;value;tb-generated + public void addT(T x) {} - // MaD=p;TypeBasedCollection;true;addManyT;(List);;Argument[0].Element;Argument[this].Element;value;tb-generated - public void addManyT(List xs) { - } + // summary=p;TypeBasedCollection;true;addManyT;(List);;Argument[0].Element;Argument[this].Element;value;tb-generated + public void addManyT(List xs) {} - // MaD=p;TypeBasedCollection;true;firstT;();;Argument[this].Element;ReturnValue;value;tb-generated - public T firstT() { - return null; - } + // summary=p;TypeBasedCollection;true;firstT;();;Argument[this].Element;ReturnValue;value;tb-generated + public T firstT() { + return null; + } - // MaD=p;TypeBasedCollection;true;getManyT;();;Argument[this].Element;ReturnValue.Element;value;tb-generated - public List getManyT() { - return null; - } -} \ No newline at end of file + // summary=p;TypeBasedCollection;true;getManyT;();;Argument[this].Element;ReturnValue.Element;value;tb-generated + public List getManyT() { + return null; + } +} diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedComplex.java b/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedComplex.java index ffca17457a0c..a6e6c2204758 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedComplex.java +++ b/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedComplex.java @@ -5,87 +5,85 @@ public class TypeBasedComplex { - // MaD=p;TypeBasedComplex;true;addMany;(List);;Argument[0].Element;Argument[this].SyntheticField[ArgType0];value;tb-generated - public void addMany(List xs) { - } + // summary=p;TypeBasedComplex;true;addMany;(List);;Argument[0].Element;Argument[this].SyntheticField[ArgType0];value;tb-generated + public void addMany(List xs) {} - // MaD=p;TypeBasedComplex;true;getMany;();;Argument[this].SyntheticField[ArgType0];ReturnValue.Element;value;tb-generated - public List getMany() { - return null; - } + // summary=p;TypeBasedComplex;true;getMany;();;Argument[this].SyntheticField[ArgType0];ReturnValue.Element;value;tb-generated + public List getMany() { + return null; + } - // MaD=p;TypeBasedComplex;true;apply;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - public Integer apply(Function f) { - return null; - } + // summary=p;TypeBasedComplex;true;apply;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + public Integer apply(Function f) { + return null; + } - // A method that doesn't mention `T` in its type signature. - // This is for testing that we don't generate a summary that involves the - // implicit field for `T`. - // MaD=p;TypeBasedComplex;true;apply2;(Object,Function);;Argument[0];Argument[1].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;apply2;(Object,Function);;Argument[1].ReturnValue;ReturnValue;value;tb-generated - public T2 apply2(T1 x, Function f) { - return null; - } + // A method that doesn't mention `T` in its type signature. + // This is for testing that we don't generate a summary that involves the + // implicit field for `T`. + // summary=p;TypeBasedComplex;true;apply2;(Object,Function);;Argument[0];Argument[1].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;apply2;(Object,Function);;Argument[1].ReturnValue;ReturnValue;value;tb-generated + public T2 apply2(T1 x, Function f) { + return null; + } - // MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[this].SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;tb-generated - // MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;Argument[this].SyntheticField[ArgType0];value;tb-generated - // MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated - public TypeBasedComplex flatMap(Function> f) { - return null; - } + // summary=p;TypeBasedComplex;true;flatMap;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;flatMap;(Function);;Argument[this].SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;tb-generated + // summary=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;Argument[this].SyntheticField[ArgType0];value;tb-generated + // summary=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated + public TypeBasedComplex flatMap(Function> f) { + return null; + } - // MaD=p;TypeBasedComplex;true;flatMap2;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;flatMap2;(Function);;Argument[0].ReturnValue.Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated - public TypeBasedComplex flatMap2(Function> f) { - return null; - } + // summary=p;TypeBasedComplex;true;flatMap2;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;flatMap2;(Function);;Argument[0].ReturnValue.Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated + public TypeBasedComplex flatMap2(Function> f) { + return null; + } - // MaD=p;TypeBasedComplex;true;map;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;map;(Function);;Argument[0].ReturnValue;ReturnValue;value;tb-generated - public S map(Function f) { - return null; - } + // summary=p;TypeBasedComplex;true;map;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;map;(Function);;Argument[0].ReturnValue;ReturnValue;value;tb-generated + public S map(Function f) { + return null; + } - // MaD=p;TypeBasedComplex;true;mapComplex;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;mapComplex;(Function);;Argument[0].ReturnValue;ReturnValue.SyntheticField[ArgType0];value;tb-generated - public TypeBasedComplex mapComplex(Function f) { - return null; - } + // summary=p;TypeBasedComplex;true;mapComplex;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;mapComplex;(Function);;Argument[0].ReturnValue;ReturnValue.SyntheticField[ArgType0];value;tb-generated + public TypeBasedComplex mapComplex(Function f) { + return null; + } - // MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[this].SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;tb-generated - // MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];Argument[this].SyntheticField[ArgType0];value;tb-generated - // MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;tb-generated - public TypeBasedComplex returnComplex(Function> f) { - return null; - } + // summary=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[this].SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;tb-generated + // summary=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];Argument[this].SyntheticField[ArgType0];value;tb-generated + // summary=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;tb-generated + public TypeBasedComplex returnComplex(Function> f) { + return null; + } - // MaD=p;TypeBasedComplex;true;set;(Integer,Function);;Argument[1].ReturnValue;Argument[this].SyntheticField[ArgType0];value;tb-generated - public void set(Integer x, Function f) { - } + // summary=p;TypeBasedComplex;true;set;(Integer,Function);;Argument[1].ReturnValue;Argument[this].SyntheticField[ArgType0];value;tb-generated + public void set(Integer x, Function f) {} - // MaD=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[0].ReturnValue;Argument[this].SyntheticField[ArgType0];value;tb-generated - // MaD=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[0].ReturnValue;Argument[0].Parameter[0];value;tb-generated - public Integer applyMyFunction(MyFunction f, Integer x) { - return null; - } + // summary=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[0].ReturnValue;Argument[this].SyntheticField[ArgType0];value;tb-generated + // summary=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[0].ReturnValue;Argument[0].Parameter[0];value;tb-generated + public Integer applyMyFunction(MyFunction f, Integer x) { + return null; + } - // MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[0].ReturnValue;ReturnValue;value;tb-generated - // MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[1];Argument[0].Parameter[1];value;tb-generated - public S2 applyMyFunctionGeneric(MyFunction f, S1 x) { - return null; - } + // summary=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[0].ReturnValue;ReturnValue;value;tb-generated + // summary=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[1];Argument[0].Parameter[1];value;tb-generated + public S2 applyMyFunctionGeneric(MyFunction f, S1 x) { + return null; + } - // MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[0].ReturnValue;ReturnValue;value;tb-generated - // MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[1];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[2];Argument[0].Parameter[1];value;tb-generated - public S3 applyMyFunctionGeneric(MyFunction f, S1 x, S2 y) { - return null; - } -} \ No newline at end of file + // summary=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[0].ReturnValue;ReturnValue;value;tb-generated + // summary=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[1];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[2];Argument[0].Parameter[1];value;tb-generated + public S3 applyMyFunctionGeneric(MyFunction f, S1 x, S2 y) { + return null; + } +} diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedSimple.java b/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedSimple.java index 8715bc2feeba..17b710922eb7 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedSimple.java +++ b/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedSimple.java @@ -2,41 +2,37 @@ public class TypeBasedSimple { - // MaD=p;TypeBasedSimple;true;TypeBasedSimple;(Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated - public TypeBasedSimple(T t) { - } - - // MaD=p;TypeBasedSimple;true;get;();;Argument[this].SyntheticField[ArgType0];ReturnValue;value;tb-generated - public T get() { - return null; - } - - // MaD=p;TypeBasedSimple;true;get;(Object);;Argument[this].SyntheticField[ArgType0];ReturnValue;value;tb-generated - public T get(Object o) { - return null; - } - - // MaD=p;TypeBasedSimple;true;id;(Object);;Argument[this].SyntheticField[ArgType0];ReturnValue;value;tb-generated - // MaD=p;TypeBasedSimple;true;id;(Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated - // MaD=p;TypeBasedSimple;true;id;(Object);;Argument[0];ReturnValue;value;tb-generated - public T id(T x) { - return null; - } - - // MaD=p;TypeBasedSimple;true;id2;(Object);;Argument[0];ReturnValue;value;tb-generated - public S id2(S x) { - return null; - } - - // MaD=p;TypeBasedSimple;true;set;(Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated - public void set(T x) { - } - - // MaD=p;TypeBasedSimple;true;set;(int,Object);;Argument[1];Argument[this].SyntheticField[ArgType0];value;tb-generated - public void set(int x, T y) { - } - - // No summary as S is unrelated to T - public void set2(S x) { - } -} \ No newline at end of file + // summary=p;TypeBasedSimple;true;TypeBasedSimple;(Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated + public TypeBasedSimple(T t) {} + + // summary=p;TypeBasedSimple;true;get;();;Argument[this].SyntheticField[ArgType0];ReturnValue;value;tb-generated + public T get() { + return null; + } + + // summary=p;TypeBasedSimple;true;get;(Object);;Argument[this].SyntheticField[ArgType0];ReturnValue;value;tb-generated + public T get(Object o) { + return null; + } + + // summary=p;TypeBasedSimple;true;id;(Object);;Argument[this].SyntheticField[ArgType0];ReturnValue;value;tb-generated + // summary=p;TypeBasedSimple;true;id;(Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated + // summary=p;TypeBasedSimple;true;id;(Object);;Argument[0];ReturnValue;value;tb-generated + public T id(T x) { + return null; + } + + // summary=p;TypeBasedSimple;true;id2;(Object);;Argument[0];ReturnValue;value;tb-generated + public S id2(S x) { + return null; + } + + // summary=p;TypeBasedSimple;true;set;(Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated + public void set(T x) {} + + // summary=p;TypeBasedSimple;true;set;(int,Object);;Argument[1];Argument[this].SyntheticField[ArgType0];value;tb-generated + public void set(int x, T y) {} + + // No summary as S is unrelated to T + public void set2(S x) {} +} diff --git a/javascript/BUILD.bazel b/javascript/BUILD.bazel index eacfa554a8e1..18315a098138 100644 --- a/javascript/BUILD.bazel +++ b/javascript/BUILD.bazel @@ -1,5 +1,5 @@ -load("@semmle_code//:dist.bzl", "dist") load("@rules_pkg//pkg:mappings.bzl", "pkg_files") +load("@semmle_code//:dist.bzl", "dist") load("@semmle_code//buildutils-internal:zipmerge.bzl", "zipmerge") package(default_visibility = ["//visibility:public"]) diff --git a/javascript/extractor/BUILD.bazel b/javascript/extractor/BUILD.bazel index 6793287c22f7..360dc9370f94 100644 --- a/javascript/extractor/BUILD.bazel +++ b/javascript/extractor/BUILD.bazel @@ -1,5 +1,5 @@ -load("@semmle_code//:common.bzl", "codeql_fat_jar", "codeql_java_project") load("@rules_pkg//pkg:mappings.bzl", "pkg_files") +load("@semmle_code//:common.bzl", "codeql_fat_jar", "codeql_java_project") java_library( name = "deps", diff --git a/javascript/extractor/src/com/semmle/js/extractor/AbstractDetector.java b/javascript/extractor/src/com/semmle/js/extractor/AbstractDetector.java new file mode 100644 index 000000000000..b8a5f1df0fcf --- /dev/null +++ b/javascript/extractor/src/com/semmle/js/extractor/AbstractDetector.java @@ -0,0 +1,113 @@ +package com.semmle.js.extractor; + +import com.semmle.js.ast.AssignmentExpression; +import com.semmle.js.ast.BlockStatement; +import com.semmle.js.ast.CallExpression; +import com.semmle.js.ast.Expression; +import com.semmle.js.ast.ExpressionStatement; +import com.semmle.js.ast.IFunction; +import com.semmle.js.ast.Identifier; +import com.semmle.js.ast.IfStatement; +import com.semmle.js.ast.MemberExpression; +import com.semmle.js.ast.Node; +import com.semmle.js.ast.ParenthesizedExpression; +import com.semmle.js.ast.Program; +import com.semmle.js.ast.Statement; +import com.semmle.js.ast.TryStatement; +import com.semmle.js.ast.UnaryExpression; +import com.semmle.js.ast.VariableDeclaration; +import com.semmle.js.ast.VariableDeclarator; +import java.util.List; + +/** + * A utility base class for running detection logic on statements/expressions by + * visiting each node. It performs recursive decent into assignment expressions and + * callee expressions for call-expressions (to handle detection of `foo` in `foo()()`) + * */ +public abstract class AbstractDetector { + protected boolean programDetection(Node ast) { + if (!(ast instanceof Program)) return false; + + return visitStatements(((Program) ast).getBody()); + } + + protected boolean visitStatements(List stmts) { + for (Statement stmt : stmts) if (visitStatement(stmt)) return true; + return false; + } + + protected boolean visitStatement(Statement stmt) { + if (stmt instanceof ExpressionStatement) { + Expression e = stripParens(((ExpressionStatement) stmt).getExpression()); + + // check whether `e` is an iife; if so, recursively check its body + + // strip off unary operators to handle `!function(){...}()` + if (e instanceof UnaryExpression) e = ((UnaryExpression) e).getArgument(); + + if (e instanceof CallExpression && ((CallExpression) e).getArguments().isEmpty()) { + Expression callee = stripParens(((CallExpression) e).getCallee()); + if (callee instanceof IFunction) { + Node body = ((IFunction) callee).getBody(); + if (body instanceof BlockStatement) + return visitStatements(((BlockStatement) body).getBody()); + } + } + + if (visitExpression(e)) return true; + + } else if (stmt instanceof VariableDeclaration) { + for (VariableDeclarator decl : ((VariableDeclaration) stmt).getDeclarations()) { + Expression init = stripParens(decl.getInit()); + if (visitExpression(init)) return true; + } + + } else if (stmt instanceof TryStatement) { + return visitStatement(((TryStatement) stmt).getBlock()); + + } else if (stmt instanceof BlockStatement) { + return visitStatements(((BlockStatement) stmt).getBody()); + + } else if (stmt instanceof IfStatement) { + IfStatement is = (IfStatement) stmt; + return visitStatement(is.getConsequent()) + || visitStatement(is.getAlternate()); + } + + return false; + } + + private static Expression stripParens(Expression e) { + if (e instanceof ParenthesizedExpression) + return stripParens(((ParenthesizedExpression) e).getExpression()); + return e; + } + + /** + * Recursively check {@code e} if it's a call or an assignment. + */ + protected boolean visitExpression(Expression e) { + if (e instanceof CallExpression) { + CallExpression call = (CallExpression) e; + Expression callee = call.getCallee(); + // recurse, to handle things like `foo()()` + if (visitExpression(callee)) return true; + return false; + } else if (e instanceof MemberExpression) { + return visitExpression(((MemberExpression) e).getObject()); + } else if (e instanceof AssignmentExpression) { + AssignmentExpression assgn = (AssignmentExpression) e; + + // filter out compound assignments + if (!"=".equals(assgn.getOperator())) return false; + + return visitExpression(assgn.getRight()); + } + return false; + } + + /** Is {@code e} an identifier with name {@code name}? */ + protected static boolean isIdentifier(Expression e, String name) { + return e instanceof Identifier && name.equals(((Identifier) e).getName()); + } +} diff --git a/javascript/extractor/src/com/semmle/js/extractor/ES2015Detector.java b/javascript/extractor/src/com/semmle/js/extractor/ES2015Detector.java new file mode 100644 index 000000000000..3ba63963dabe --- /dev/null +++ b/javascript/extractor/src/com/semmle/js/extractor/ES2015Detector.java @@ -0,0 +1,34 @@ +package com.semmle.js.extractor; + +import com.semmle.js.ast.DynamicImport; +import com.semmle.js.ast.ExportDeclaration; +import com.semmle.js.ast.Expression; +import com.semmle.js.ast.ImportDeclaration; +import com.semmle.js.ast.Node; +import com.semmle.js.ast.Statement; + +/** A utility class for detecting Node.js code. */ +public class ES2015Detector extends AbstractDetector { + /** + * Is {@code ast} a program that uses ES2015 import/export code? + */ + public static boolean looksLikeES2015(Node ast) { + return new ES2015Detector().programDetection(ast); + } + + @Override + protected boolean visitStatement(Statement stmt) { + if (stmt instanceof ImportDeclaration || stmt instanceof ExportDeclaration) { + return true; + } + return super.visitStatement(stmt); + } + + @Override + protected boolean visitExpression(Expression e) { + if (e instanceof DynamicImport) { + return true; + } + return super.visitExpression(e); + } +} diff --git a/javascript/extractor/src/com/semmle/js/extractor/JSExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/JSExtractor.java index 6b4b05fcf616..a8e20fdc0d90 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/JSExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/JSExtractor.java @@ -58,6 +58,26 @@ public Pair extract( JSParser.Result parserRes = JSParser.parse(config, sourceType, source, textualExtractor.getMetrics()); + + // Check if we guessed wrong with the regex in `establishSourceType`, (which could + // happen due to a block-comment line starting with ' import'). + if (config.getSourceType() == SourceType.AUTO && sourceType != SourceType.SCRIPT) { + boolean wrongGuess = false; + + if (sourceType == SourceType.MODULE) { + // check that we did see an import/export declaration + wrongGuess = ES2015Detector.looksLikeES2015(parserRes.getAST()) == false; + } else if (sourceType == SourceType.CLOSURE_MODULE ) { + // TODO + } + + if (wrongGuess) { + sourceType = SourceType.SCRIPT; + parserRes = + JSParser.parse(config, sourceType, source, textualExtractor.getMetrics()); + } + } + return extract(textualExtractor, source, toplevelKind, scopeManager, sourceType, parserRes); } diff --git a/javascript/extractor/src/com/semmle/js/extractor/NodeJSDetector.java b/javascript/extractor/src/com/semmle/js/extractor/NodeJSDetector.java index d848afd0d87a..a9fa2c9d8500 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/NodeJSDetector.java +++ b/javascript/extractor/src/com/semmle/js/extractor/NodeJSDetector.java @@ -1,132 +1,30 @@ package com.semmle.js.extractor; import com.semmle.js.ast.AssignmentExpression; -import com.semmle.js.ast.BlockStatement; import com.semmle.js.ast.CallExpression; import com.semmle.js.ast.Expression; -import com.semmle.js.ast.ExpressionStatement; -import com.semmle.js.ast.IFunction; -import com.semmle.js.ast.Identifier; -import com.semmle.js.ast.IfStatement; import com.semmle.js.ast.MemberExpression; import com.semmle.js.ast.Node; -import com.semmle.js.ast.ParenthesizedExpression; -import com.semmle.js.ast.Program; -import com.semmle.js.ast.Statement; -import com.semmle.js.ast.TryStatement; -import com.semmle.js.ast.UnaryExpression; -import com.semmle.js.ast.VariableDeclaration; -import com.semmle.js.ast.VariableDeclarator; -import java.util.List; /** A utility class for detecting Node.js code. */ -public class NodeJSDetector { +public class NodeJSDetector extends AbstractDetector { /** * Is {@code ast} a program that looks like Node.js code, that is, does it contain a top-level - * {@code require} or an export? + * {@code require} or an {@code module.exports = ...}/{@code exports = ...}? */ public static boolean looksLikeNodeJS(Node ast) { - if (!(ast instanceof Program)) return false; - - return hasToplevelRequireOrExport(((Program) ast).getBody()); - } - - /** - * Does this program contain a statement that looks like a Node.js {@code require} or an export? - * - *

    We recursively traverse argument-less immediately invoked function expressions (i.e., no UMD - * modules), but not loops or if statements. - */ - private static boolean hasToplevelRequireOrExport(List stmts) { - for (Statement stmt : stmts) if (hasToplevelRequireOrExport(stmt)) return true; - return false; + return new NodeJSDetector().programDetection(ast); } - private static boolean hasToplevelRequireOrExport(Statement stmt) { - if (stmt instanceof ExpressionStatement) { - Expression e = stripParens(((ExpressionStatement) stmt).getExpression()); - - // check whether `e` is an iife; if so, recursively check its body - - // strip off unary operators to handle `!function(){...}()` - if (e instanceof UnaryExpression) e = ((UnaryExpression) e).getArgument(); - - if (e instanceof CallExpression && ((CallExpression) e).getArguments().isEmpty()) { - Expression callee = stripParens(((CallExpression) e).getCallee()); - if (callee instanceof IFunction) { - Node body = ((IFunction) callee).getBody(); - if (body instanceof BlockStatement) - return hasToplevelRequireOrExport(((BlockStatement) body).getBody()); - } - } - - if (isRequireCall(e) || isExport(e)) return true; - - } else if (stmt instanceof VariableDeclaration) { - for (VariableDeclarator decl : ((VariableDeclaration) stmt).getDeclarations()) { - Expression init = stripParens(decl.getInit()); - if (isRequireCall(init) || isExport(init)) return true; - } - - } else if (stmt instanceof TryStatement) { - return hasToplevelRequireOrExport(((TryStatement) stmt).getBlock()); - - } else if (stmt instanceof BlockStatement) { - return hasToplevelRequireOrExport(((BlockStatement) stmt).getBody()); - - } else if (stmt instanceof IfStatement) { - IfStatement is = (IfStatement) stmt; - return hasToplevelRequireOrExport(is.getConsequent()) - || hasToplevelRequireOrExport(is.getAlternate()); - } - - return false; - } - - private static Expression stripParens(Expression e) { - if (e instanceof ParenthesizedExpression) - return stripParens(((ParenthesizedExpression) e).getExpression()); - return e; - } - - /** - * Is {@code e} a call to a function named {@code require} with one argument, or an assignment - * whose right hand side is the result of such a call? - */ - private static boolean isRequireCall(Expression e) { + @Override + protected boolean visitExpression(Expression e) { + // require('...') if (e instanceof CallExpression) { CallExpression call = (CallExpression) e; Expression callee = call.getCallee(); if (isIdentifier(callee, "require") && call.getArguments().size() == 1) return true; - if (isRequireCall(callee)) return true; - return false; - } else if (e instanceof MemberExpression) { - return isRequireCall(((MemberExpression) e).getObject()); - } else if (e instanceof AssignmentExpression) { - AssignmentExpression assgn = (AssignmentExpression) e; - - // filter out compound assignments - if (!"=".equals(assgn.getOperator())) return false; - - return isRequireCall(assgn.getRight()); } - return false; - } - /** - * Does {@code e} look like a Node.js export? - * - *

    Currently, three kinds of exports are recognised: - * - *

      - *
    • exports.foo = ... - *
    • module.exports = ... - *
    • module.exports.foo = ... - *
    - * - * Detection is done recursively, so foo = exports.foo = ... is handled correctly. - */ - private static boolean isExport(Expression e) { if (e instanceof AssignmentExpression) { AssignmentExpression assgn = (AssignmentExpression) e; @@ -149,12 +47,9 @@ private static boolean isExport(Expression e) { if (isModuleExports(targetBase)) return true; } } - - // recursively check right hand side - return isExport(assgn.getRight()); } - return false; + return super.visitExpression(e); } /** Is {@code me} a member expression {@code module.exports}? */ @@ -163,9 +58,4 @@ private static boolean isModuleExports(MemberExpression me) { && isIdentifier(me.getObject(), "module") && isIdentifier(me.getProperty(), "exports"); } - - /** Is {@code e} an identifier with name {@code name}? */ - private static boolean isIdentifier(Expression e, String name) { - return e instanceof Identifier && name.equals(((Identifier) e).getName()); - } } diff --git a/javascript/extractor/test/com/semmle/js/extractor/test/AllTests.java b/javascript/extractor/test/com/semmle/js/extractor/test/AllTests.java index 7487e68efc01..6a51b2e69c4d 100644 --- a/javascript/extractor/test/com/semmle/js/extractor/test/AllTests.java +++ b/javascript/extractor/test/com/semmle/js/extractor/test/AllTests.java @@ -18,6 +18,7 @@ @SuiteClasses({ JSXTests.class, NodeJSDetectorTests.class, + ES2015DetectorTests.class, TrapTests.class, ObjectRestSpreadTests.class, ClassPropertiesTests.class, diff --git a/javascript/extractor/test/com/semmle/js/extractor/test/BUILD.bazel b/javascript/extractor/test/com/semmle/js/extractor/test/BUILD.bazel index 45d6790e8a98..1bad97bb7cc8 100644 --- a/javascript/extractor/test/com/semmle/js/extractor/test/BUILD.bazel +++ b/javascript/extractor/test/com/semmle/js/extractor/test/BUILD.bazel @@ -12,6 +12,9 @@ java_test( "TS_WRAPPER_ZIP": "$(rlocationpath //javascript/extractor/lib/typescript)", }, test_class = "com.semmle.js.extractor.test.AllTests", + # To use `replaceExpectedOutput` you need to uncomment the following line + # (to be allowed to override the .trap files on disk) + # tags = ["no-sandbox"], deps = [ "//javascript/extractor", "//javascript/extractor:deps", diff --git a/javascript/extractor/test/com/semmle/js/extractor/test/ES2015DetectorTests.java b/javascript/extractor/test/com/semmle/js/extractor/test/ES2015DetectorTests.java new file mode 100644 index 000000000000..669824c076f4 --- /dev/null +++ b/javascript/extractor/test/com/semmle/js/extractor/test/ES2015DetectorTests.java @@ -0,0 +1,58 @@ +package com.semmle.js.extractor.test; + +import com.semmle.js.ast.Node; +import com.semmle.js.extractor.ES2015Detector; +import com.semmle.js.extractor.ExtractionMetrics; +import com.semmle.js.extractor.ExtractorConfig; +import com.semmle.js.extractor.ExtractorConfig.SourceType; +import com.semmle.js.parser.JSParser; +import com.semmle.js.parser.JSParser.Result; +import org.junit.Assert; +import org.junit.Test; + +public class ES2015DetectorTests { + // using `experimental: true` as we do in real extractor, see `extractSource` method + // in `AutoBuild.java` + private static final ExtractorConfig CONFIG = new ExtractorConfig(true); + + private void isES2015(String src, boolean expected) { + Result res = JSParser.parse(CONFIG, SourceType.MODULE, src, new ExtractionMetrics()); + Node ast = res.getAST(); + Assert.assertNotNull(ast); + Assert.assertTrue(ES2015Detector.looksLikeES2015(ast) == expected); + } + + @Test + public void testImport() { + isES2015("import * as fs from 'fs';", true); + } + + @Test + public void testExport() { + isES2015("export function foo() { };", true); + } + + @Test + public void testDynamicImport() { + isES2015("import('fs');", true); + } + + @Test + public void testDynamicImportAssign() { + isES2015("var fs = import('fs');", true); + } + + @Test + public void testDynamicImportThen() { + isES2015("import('o').then((o) => {});", true); + } + + @Test + public void importInBlockComment() { + isES2015("/*\n" + + " import * from 'fs';\n" + + "*/\n" + + "const fs = require('fs');", + false); + } +} diff --git a/javascript/extractor/test/com/semmle/js/extractor/test/NodeJSDetectorTests.java b/javascript/extractor/test/com/semmle/js/extractor/test/NodeJSDetectorTests.java index 14d5b323e7c3..ead1d1265612 100644 --- a/javascript/extractor/test/com/semmle/js/extractor/test/NodeJSDetectorTests.java +++ b/javascript/extractor/test/com/semmle/js/extractor/test/NodeJSDetectorTests.java @@ -11,7 +11,9 @@ import org.junit.Test; public class NodeJSDetectorTests { - private static final ExtractorConfig CONFIG = new ExtractorConfig(false); + // using `experimental: true` as we do in real extractor, see `extractSource` method + // in `AutoBuild.java` + private static final ExtractorConfig CONFIG = new ExtractorConfig(true); private void isNodeJS(String src, boolean expected) { Result res = JSParser.parse(CONFIG, SourceType.SCRIPT, src, new ExtractionMetrics()); diff --git a/javascript/extractor/test/com/semmle/js/extractor/test/TrapTests.java b/javascript/extractor/test/com/semmle/js/extractor/test/TrapTests.java index 5991ac6669a4..6daf56cc56e1 100644 --- a/javascript/extractor/test/com/semmle/js/extractor/test/TrapTests.java +++ b/javascript/extractor/test/com/semmle/js/extractor/test/TrapTests.java @@ -161,6 +161,14 @@ public void close() { byte[] actual_utf8_bytes = StringUtil.stringToBytes(sw.toString()); String actual = new String(actual_utf8_bytes, Charset.forName("UTF-8")); File trap = new File(outputDir, f.getName() + ".trap"); + // NOTE: If you want to replace expected output, you MUST change + // the way this test is run under bazel to escape the bazel + // sandbox. Add `tags = ["no-sandbox"]` to the test rule in + // javascript/extractor/test/com/semmle/js/extractor/test/BUILD.bazel + // + // if you have problems with too much caching, you need to find the right bazel command, + // and run `./build --bazel test ... --cache_test_results=no` + // (at least I had problems getting the "no-cache" tag to work) boolean replaceExpectedOutput = false; if (replaceExpectedOutput) { System.out.println("Replacing expected output for " + trap); diff --git a/javascript/extractor/tests/flow/output/trap/anonFunctionWithoutParens.js.trap b/javascript/extractor/tests/flow/output/trap/anonFunctionWithoutParens.js.trap index 999173d6a30d..154751cda15d 100644 --- a/javascript/extractor/tests/flow/output/trap/anonFunctionWithoutParens.js.trap +++ b/javascript/extractor/tests/flow/output/trap/anonFunctionWithoutParens.js.trap @@ -72,20 +72,14 @@ locations_default(#20025,#10000,1,40,1,39) hasLocation(#20024,#20025) toplevels(#20001,0) hasLocation(#20001,#20003) -#20026=@"module;{#10000},1,1" -scopes(#20026,3) -scopenodes(#20001,#20026) -scopenesting(#20026,#20000) -is_module(#20001) -is_es2015_module(#20001) -#20027=* -entry_cfg_node(#20027,#20001) -#20028=@"loc,{#10000},1,1,1,0" -locations_default(#20028,#10000,1,1,1,0) -hasLocation(#20027,#20028) -#20029=* -exit_cfg_node(#20029,#20001) -hasLocation(#20029,#20025) -successor(#20027,#20029) +#20026=* +entry_cfg_node(#20026,#20001) +#20027=@"loc,{#10000},1,1,1,0" +locations_default(#20027,#10000,1,1,1,0) +hasLocation(#20026,#20027) +#20028=* +exit_cfg_node(#20028,#20001) +hasLocation(#20028,#20025) +successor(#20026,#20028) numlines(#10000,1,1,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/flow/output/trap/anonIndexer.js.trap b/javascript/extractor/tests/flow/output/trap/anonIndexer.js.trap index fbfaf50aaee6..6f75d1228b72 100644 --- a/javascript/extractor/tests/flow/output/trap/anonIndexer.js.trap +++ b/javascript/extractor/tests/flow/output/trap/anonIndexer.js.trap @@ -85,20 +85,14 @@ toplevels(#20001,0) #20030=@"loc,{#10000},1,1,2,0" locations_default(#20030,#10000,1,1,2,0) hasLocation(#20001,#20030) -#20031=@"module;{#10000},1,1" -scopes(#20031,3) -scopenodes(#20001,#20031) -scopenesting(#20031,#20000) -is_module(#20001) -is_es2015_module(#20001) -#20032=* -entry_cfg_node(#20032,#20001) -#20033=@"loc,{#10000},1,1,1,0" -locations_default(#20033,#10000,1,1,1,0) -hasLocation(#20032,#20033) -#20034=* -exit_cfg_node(#20034,#20001) -hasLocation(#20034,#20029) -successor(#20032,#20034) +#20031=* +entry_cfg_node(#20031,#20001) +#20032=@"loc,{#10000},1,1,1,0" +locations_default(#20032,#10000,1,1,1,0) +hasLocation(#20031,#20032) +#20033=* +exit_cfg_node(#20033,#20001) +hasLocation(#20033,#20029) +successor(#20031,#20033) numlines(#10000,1,1,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/flow/output/trap/declared-module-imports.js.trap b/javascript/extractor/tests/flow/output/trap/declared-module-imports.js.trap index 1eedda348e34..1588e279e76c 100644 --- a/javascript/extractor/tests/flow/output/trap/declared-module-imports.js.trap +++ b/javascript/extractor/tests/flow/output/trap/declared-module-imports.js.trap @@ -128,20 +128,14 @@ toplevels(#20001,0) #20045=@"loc,{#10000},1,1,5,0" locations_default(#20045,#10000,1,1,5,0) hasLocation(#20001,#20045) -#20046=@"module;{#10000},1,1" -scopes(#20046,3) -scopenodes(#20001,#20046) -scopenesting(#20046,#20000) -is_module(#20001) -is_es2015_module(#20001) -#20047=* -entry_cfg_node(#20047,#20001) -#20048=@"loc,{#10000},1,1,1,0" -locations_default(#20048,#10000,1,1,1,0) -hasLocation(#20047,#20048) -#20049=* -exit_cfg_node(#20049,#20001) -hasLocation(#20049,#20044) -successor(#20047,#20049) +#20046=* +entry_cfg_node(#20046,#20001) +#20047=@"loc,{#10000},1,1,1,0" +locations_default(#20047,#10000,1,1,1,0) +hasLocation(#20046,#20047) +#20048=* +exit_cfg_node(#20048,#20001) +hasLocation(#20048,#20044) +successor(#20046,#20048) numlines(#10000,4,4,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/flow/output/trap/exportOpaqueType.js.trap b/javascript/extractor/tests/flow/output/trap/exportOpaqueType.js.trap index 5cdd7537e30f..5b8c2c2b7d97 100644 --- a/javascript/extractor/tests/flow/output/trap/exportOpaqueType.js.trap +++ b/javascript/extractor/tests/flow/output/trap/exportOpaqueType.js.trap @@ -70,20 +70,14 @@ toplevels(#20001,0) #20024=@"loc,{#10000},1,1,2,0" locations_default(#20024,#10000,1,1,2,0) hasLocation(#20001,#20024) -#20025=@"module;{#10000},1,1" -scopes(#20025,3) -scopenodes(#20001,#20025) -scopenesting(#20025,#20000) -is_module(#20001) -is_es2015_module(#20001) -#20026=* -entry_cfg_node(#20026,#20001) -#20027=@"loc,{#10000},1,1,1,0" -locations_default(#20027,#10000,1,1,1,0) -hasLocation(#20026,#20027) -#20028=* -exit_cfg_node(#20028,#20001) -hasLocation(#20028,#20023) -successor(#20026,#20028) +#20025=* +entry_cfg_node(#20025,#20001) +#20026=@"loc,{#10000},1,1,1,0" +locations_default(#20026,#10000,1,1,1,0) +hasLocation(#20025,#20026) +#20027=* +exit_cfg_node(#20027,#20001) +hasLocation(#20027,#20023) +successor(#20025,#20027) numlines(#10000,1,1,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap b/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap index 188033df9a15..8c4b5a30f4a1 100644 --- a/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap +++ b/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap @@ -205,20 +205,14 @@ toplevels(#20001,0) #20071=@"loc,{#10000},1,1,11,2" locations_default(#20071,#10000,1,1,11,2) hasLocation(#20001,#20071) -#20072=@"module;{#10000},1,1" -scopes(#20072,3) -scopenodes(#20001,#20072) -scopenesting(#20072,#20000) -is_module(#20001) -is_es2015_module(#20001) -#20073=* -entry_cfg_node(#20073,#20001) -#20074=@"loc,{#10000},1,1,1,0" -locations_default(#20074,#10000,1,1,1,0) -hasLocation(#20073,#20074) -#20075=* -exit_cfg_node(#20075,#20001) -hasLocation(#20075,#20070) -successor(#20073,#20075) +#20072=* +entry_cfg_node(#20072,#20001) +#20073=@"loc,{#10000},1,1,1,0" +locations_default(#20073,#10000,1,1,1,0) +hasLocation(#20072,#20073) +#20074=* +exit_cfg_node(#20074,#20001) +hasLocation(#20074,#20070) +successor(#20072,#20074) numlines(#10000,11,10,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/flow/output/trap/variance.js.trap b/javascript/extractor/tests/flow/output/trap/variance.js.trap index b6955639fe9d..cd1ea42f2284 100644 --- a/javascript/extractor/tests/flow/output/trap/variance.js.trap +++ b/javascript/extractor/tests/flow/output/trap/variance.js.trap @@ -160,95 +160,89 @@ toplevels(#20001,0) #20057=@"loc,{#10000},1,1,7,1" locations_default(#20057,#10000,1,1,7,1) hasLocation(#20001,#20057) -#20058=@"module;{#10000},1,1" -scopes(#20058,3) -scopenodes(#20001,#20058) -scopenesting(#20058,#20000) -is_module(#20001) -is_es2015_module(#20001) -#20059=@"var;{Foo};{#20058}" -variables(#20059,"Foo",#20058) -#20060=@"local_type_name;{Foo};{#20058}" -local_type_names(#20060,"Foo",#20058) -#20061=* -stmts(#20061,26,#20001,0,"class F ... : int\n}") -#20062=@"loc,{#10000},5,1,7,1" -locations_default(#20062,#10000,5,1,7,1) -hasLocation(#20061,#20062) -stmt_containers(#20061,#20001) +#20058=@"var;{Foo};{#20000}" +variables(#20058,"Foo",#20000) +#20059=@"local_type_name;{Foo};{#20000}" +local_type_names(#20059,"Foo",#20000) +#20060=* +stmts(#20060,26,#20001,0,"class F ... : int\n}") +#20061=@"loc,{#10000},5,1,7,1" +locations_default(#20061,#10000,5,1,7,1) +hasLocation(#20060,#20061) +stmt_containers(#20060,#20001) +#20062=* +exprs(#20062,78,#20060,0,"Foo") +hasLocation(#20062,#20043) +enclosing_stmt(#20062,#20060) +expr_containers(#20062,#20001) +literals("Foo","Foo",#20062) +decl(#20062,#20058) +typedecl(#20062,#20059) #20063=* -exprs(#20063,78,#20061,0,"Foo") -hasLocation(#20063,#20043) -enclosing_stmt(#20063,#20061) -expr_containers(#20063,#20001) -literals("Foo","Foo",#20063) -decl(#20063,#20059) -typedecl(#20063,#20060) +scopes(#20063,10) +scopenodes(#20060,#20063) +scopenesting(#20063,#20000) #20064=* -scopes(#20064,10) -scopenodes(#20061,#20064) -scopenesting(#20064,#20058) -#20065=* -properties(#20065,#20061,2,8,"+x: int") -#20066=@"loc,{#10000},6,3,6,9" -locations_default(#20066,#10000,6,3,6,9) -hasLocation(#20065,#20066) +properties(#20064,#20060,2,8,"+x: int") +#20065=@"loc,{#10000},6,3,6,9" +locations_default(#20065,#10000,6,3,6,9) +hasLocation(#20064,#20065) +#20066=* #20067=* +exprs(#20067,0,#20064,0,"x") +hasLocation(#20067,#20049) +expr_containers(#20067,#20066) +literals("x","x",#20067) #20068=* -exprs(#20068,0,#20065,0,"x") -hasLocation(#20068,#20049) -expr_containers(#20068,#20067) -literals("x","x",#20068) -#20069=* -properties(#20069,#20061,3,0,"constructor() {}") -#20070=@"loc,{#10000},5,11,5,10" -locations_default(#20070,#10000,5,11,5,10) -hasLocation(#20069,#20070) +properties(#20068,#20060,3,0,"constructor() {}") +#20069=@"loc,{#10000},5,11,5,10" +locations_default(#20069,#10000,5,11,5,10) +hasLocation(#20068,#20069) +#20070=* +exprs(#20070,0,#20068,0,"constructor") +hasLocation(#20070,#20069) +enclosing_stmt(#20070,#20060) +expr_containers(#20070,#20001) +literals("constructor","constructor",#20070) +exprs(#20066,9,#20068,1,"() {}") +hasLocation(#20066,#20069) +enclosing_stmt(#20066,#20060) +expr_containers(#20066,#20001) #20071=* -exprs(#20071,0,#20069,0,"constructor") -hasLocation(#20071,#20070) -enclosing_stmt(#20071,#20061) -expr_containers(#20071,#20001) -literals("constructor","constructor",#20071) -exprs(#20067,9,#20069,1,"() {}") -hasLocation(#20067,#20070) -enclosing_stmt(#20067,#20061) -expr_containers(#20067,#20001) -#20072=* -scopes(#20072,1) -scopenodes(#20067,#20072) -scopenesting(#20072,#20064) -#20073=@"var;{arguments};{#20072}" -variables(#20073,"arguments",#20072) -is_arguments_object(#20073) +scopes(#20071,1) +scopenodes(#20066,#20071) +scopenesting(#20071,#20063) +#20072=@"var;{arguments};{#20071}" +variables(#20072,"arguments",#20071) +is_arguments_object(#20072) +#20073=* +stmts(#20073,1,#20066,-2,"{}") +hasLocation(#20073,#20069) +stmt_containers(#20073,#20066) +is_method(#20068) #20074=* -stmts(#20074,1,#20067,-2,"{}") -hasLocation(#20074,#20070) -stmt_containers(#20074,#20067) -is_method(#20069) -#20075=* -entry_cfg_node(#20075,#20001) -#20076=@"loc,{#10000},1,1,1,0" -locations_default(#20076,#10000,1,1,1,0) -hasLocation(#20075,#20076) +entry_cfg_node(#20074,#20001) +#20075=@"loc,{#10000},1,1,1,0" +locations_default(#20075,#10000,1,1,1,0) +hasLocation(#20074,#20075) +#20076=* +exit_cfg_node(#20076,#20001) +hasLocation(#20076,#20056) +successor(#20067,#20064) +successor(#20066,#20068) #20077=* -exit_cfg_node(#20077,#20001) -hasLocation(#20077,#20056) -successor(#20068,#20065) -successor(#20067,#20069) +entry_cfg_node(#20077,#20066) +hasLocation(#20077,#20069) +successor(#20064,#20073) #20078=* -entry_cfg_node(#20078,#20067) -hasLocation(#20078,#20070) -successor(#20065,#20074) -#20079=* -exit_cfg_node(#20079,#20067) -hasLocation(#20079,#20070) -successor(#20074,#20079) -successor(#20078,#20068) -successor(#20071,#20067) -successor(#20069,#20061) -successor(#20063,#20071) -successor(#20061,#20077) -successor(#20075,#20063) +exit_cfg_node(#20078,#20066) +hasLocation(#20078,#20069) +successor(#20073,#20078) +successor(#20077,#20067) +successor(#20070,#20066) +successor(#20068,#20060) +successor(#20062,#20070) +successor(#20060,#20076) +successor(#20074,#20062) numlines(#10000,7,6,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/node/input/detection.js b/javascript/extractor/tests/node/input/detection.js new file mode 100644 index 000000000000..7c182f394f2a --- /dev/null +++ b/javascript/extractor/tests/node/input/detection.js @@ -0,0 +1,6 @@ +// the comment below (with 'import' on line starting with whitespace) caused the +// extractor to think it was a es2015 module and not a commonjs module. +/* + import +*/ +const fs = require('fs'); diff --git a/javascript/extractor/tests/node/output/trap/detection.js.trap b/javascript/extractor/tests/node/output/trap/detection.js.trap new file mode 100644 index 000000000000..81e56c20609b --- /dev/null +++ b/javascript/extractor/tests/node/output/trap/detection.js.trap @@ -0,0 +1,203 @@ +#10000=@"/detection.js;sourcefile" +files(#10000,"/detection.js") +#10001=@"/;folder" +folders(#10001,"/") +containerparent(#10001,#10000) +#10002=@"loc,{#10000},0,0,0,0" +locations_default(#10002,#10000,0,0,0,0) +hasLocation(#10000,#10002) +#20000=@"global_scope" +scopes(#20000,0) +#20001=@"script;{#10000},1,1" +#20002=* +comments(#20002,0,#20001," the comment below (with 'import' on line starting with whitespace) caused the","// the ... sed the") +#20003=@"loc,{#10000},1,1,1,80" +locations_default(#20003,#10000,1,1,1,80) +hasLocation(#20002,#20003) +#20004=* +comments(#20004,0,#20001," extractor to think it was a es2015 module and not a commonjs module.","// extr ... module.") +#20005=@"loc,{#10000},2,1,2,71" +locations_default(#20005,#10000,2,1,2,71) +hasLocation(#20004,#20005) +#20006=* +comments(#20006,1,#20001," + import +","/*\n import\n*/") +#20007=@"loc,{#10000},3,1,5,2" +locations_default(#20007,#10000,3,1,5,2) +hasLocation(#20006,#20007) +#20008=* +lines(#20008,#20001,"// the comment below (with 'import' on line starting with whitespace) caused the"," +") +hasLocation(#20008,#20003) +#20009=* +lines(#20009,#20001,"// extractor to think it was a es2015 module and not a commonjs module."," +") +hasLocation(#20009,#20005) +#20010=* +lines(#20010,#20001,"/*"," +") +#20011=@"loc,{#10000},3,1,3,2" +locations_default(#20011,#10000,3,1,3,2) +hasLocation(#20010,#20011) +#20012=* +lines(#20012,#20001," import"," +") +#20013=@"loc,{#10000},4,1,4,8" +locations_default(#20013,#10000,4,1,4,8) +hasLocation(#20012,#20013) +indentation(#10000,4," ",2) +#20014=* +lines(#20014,#20001,"*/"," +") +#20015=@"loc,{#10000},5,1,5,2" +locations_default(#20015,#10000,5,1,5,2) +hasLocation(#20014,#20015) +#20016=* +lines(#20016,#20001,"const fs = require('fs');"," +") +#20017=@"loc,{#10000},6,1,6,25" +locations_default(#20017,#10000,6,1,6,25) +hasLocation(#20016,#20017) +numlines(#20001,6,1,5) +#20018=* +tokeninfo(#20018,7,#20001,0,"const") +#20019=@"loc,{#10000},6,1,6,5" +locations_default(#20019,#10000,6,1,6,5) +hasLocation(#20018,#20019) +next_token(#20002,#20018) +next_token(#20004,#20018) +next_token(#20006,#20018) +#20020=* +tokeninfo(#20020,6,#20001,1,"fs") +#20021=@"loc,{#10000},6,7,6,8" +locations_default(#20021,#10000,6,7,6,8) +hasLocation(#20020,#20021) +#20022=* +tokeninfo(#20022,8,#20001,2,"=") +#20023=@"loc,{#10000},6,10,6,10" +locations_default(#20023,#10000,6,10,6,10) +hasLocation(#20022,#20023) +#20024=* +tokeninfo(#20024,6,#20001,3,"require") +#20025=@"loc,{#10000},6,12,6,18" +locations_default(#20025,#10000,6,12,6,18) +hasLocation(#20024,#20025) +#20026=* +tokeninfo(#20026,8,#20001,4,"(") +#20027=@"loc,{#10000},6,19,6,19" +locations_default(#20027,#10000,6,19,6,19) +hasLocation(#20026,#20027) +#20028=* +tokeninfo(#20028,4,#20001,5,"'fs'") +#20029=@"loc,{#10000},6,20,6,23" +locations_default(#20029,#10000,6,20,6,23) +hasLocation(#20028,#20029) +#20030=* +tokeninfo(#20030,8,#20001,6,")") +#20031=@"loc,{#10000},6,24,6,24" +locations_default(#20031,#10000,6,24,6,24) +hasLocation(#20030,#20031) +#20032=* +tokeninfo(#20032,8,#20001,7,";") +#20033=@"loc,{#10000},6,25,6,25" +locations_default(#20033,#10000,6,25,6,25) +hasLocation(#20032,#20033) +#20034=* +tokeninfo(#20034,0,#20001,8,"") +#20035=@"loc,{#10000},7,1,7,0" +locations_default(#20035,#10000,7,1,7,0) +hasLocation(#20034,#20035) +toplevels(#20001,0) +#20036=@"loc,{#10000},1,1,7,0" +locations_default(#20036,#10000,1,1,7,0) +hasLocation(#20001,#20036) +#20037=@"var;{global};{#20000}" +variables(#20037,"global",#20000) +#20038=@"var;{process};{#20000}" +variables(#20038,"process",#20000) +#20039=@"var;{console};{#20000}" +variables(#20039,"console",#20000) +#20040=@"var;{Buffer};{#20000}" +variables(#20040,"Buffer",#20000) +#20041=@"module;{#10000},1,1" +scopes(#20041,3) +scopenodes(#20001,#20041) +scopenesting(#20041,#20000) +#20042=@"var;{require};{#20041}" +variables(#20042,"require",#20041) +#20043=@"var;{module};{#20041}" +variables(#20043,"module",#20041) +#20044=@"var;{exports};{#20041}" +variables(#20044,"exports",#20041) +#20045=@"var;{__filename};{#20041}" +variables(#20045,"__filename",#20041) +#20046=@"var;{__dirname};{#20041}" +variables(#20046,"__dirname",#20041) +#20047=@"var;{arguments};{#20041}" +variables(#20047,"arguments",#20041) +is_module(#20001) +#20048=@"var;{fs};{#20041}" +variables(#20048,"fs",#20041) +#20049=* +stmts(#20049,22,#20001,0,"const f ... ('fs');") +hasLocation(#20049,#20017) +stmt_containers(#20049,#20001) +#20050=* +exprs(#20050,64,#20049,0,"fs = require('fs')") +#20051=@"loc,{#10000},6,7,6,24" +locations_default(#20051,#10000,6,7,6,24) +hasLocation(#20050,#20051) +enclosing_stmt(#20050,#20049) +expr_containers(#20050,#20001) +#20052=* +exprs(#20052,78,#20050,0,"fs") +hasLocation(#20052,#20021) +enclosing_stmt(#20052,#20049) +expr_containers(#20052,#20001) +literals("fs","fs",#20052) +decl(#20052,#20048) +#20053=* +exprs(#20053,13,#20050,1,"require('fs')") +#20054=@"loc,{#10000},6,12,6,24" +locations_default(#20054,#10000,6,12,6,24) +hasLocation(#20053,#20054) +enclosing_stmt(#20053,#20049) +expr_containers(#20053,#20001) +#20055=* +exprs(#20055,79,#20053,-1,"require") +hasLocation(#20055,#20025) +enclosing_stmt(#20055,#20049) +expr_containers(#20055,#20001) +literals("require","require",#20055) +bind(#20055,#20042) +#20056=* +exprs(#20056,4,#20053,0,"'fs'") +hasLocation(#20056,#20029) +enclosing_stmt(#20056,#20049) +expr_containers(#20056,#20001) +literals("fs","'fs'",#20056) +#20057=* +regexpterm(#20057,14,#20056,0,"fs") +#20058=@"loc,{#10000},6,21,6,22" +locations_default(#20058,#10000,6,21,6,22) +hasLocation(#20057,#20058) +regexp_const_value(#20057,"fs") +#20059=* +entry_cfg_node(#20059,#20001) +#20060=@"loc,{#10000},1,1,1,0" +locations_default(#20060,#10000,1,1,1,0) +hasLocation(#20059,#20060) +#20061=* +exit_cfg_node(#20061,#20001) +hasLocation(#20061,#20035) +successor(#20049,#20052) +successor(#20056,#20053) +successor(#20055,#20056) +successor(#20053,#20050) +successor(#20052,#20055) +successor(#20050,#20061) +successor(#20059,#20049) +is_nodejs(#20001) +numlines(#10000,6,1,5) +filetype(#10000,"javascript") diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index 59c3204488d9..abe221bc6d25 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.9.0 + +### Breaking Changes + +* Deleted the deprecated `getInput` predicate from the `CryptographicOperation` class. Use `getAnInput` instead. +* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. +* Deleted the deprecated `semmle/javascript/security/BadTagFilterQuery.qll`, `semmle/javascript/security/OverlyLargeRangeQuery.qll`, `semmle/javascript/security/regexp/RegexpMatching.qll`, and `Security/CWE-020/HostnameRegexpShared.qll` files. + +### Minor Analysis Improvements + +* Improved detection of whether a file uses CommonJS module system. + ## 0.8.14 No user-facing changes. diff --git a/javascript/ql/lib/change-notes/released/0.9.0.md b/javascript/ql/lib/change-notes/released/0.9.0.md new file mode 100644 index 000000000000..d76d2e4d1226 --- /dev/null +++ b/javascript/ql/lib/change-notes/released/0.9.0.md @@ -0,0 +1,11 @@ +## 0.9.0 + +### Breaking Changes + +* Deleted the deprecated `getInput` predicate from the `CryptographicOperation` class. Use `getAnInput` instead. +* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. +* Deleted the deprecated `semmle/javascript/security/BadTagFilterQuery.qll`, `semmle/javascript/security/OverlyLargeRangeQuery.qll`, `semmle/javascript/security/regexp/RegexpMatching.qll`, and `Security/CWE-020/HostnameRegexpShared.qll` files. + +### Minor Analysis Improvements + +* Improved detection of whether a file uses CommonJS module system. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index b36a2e248f34..8b9fc185202d 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.8.14 +lastReleaseVersion: 0.9.0 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 700b48d33202..d0321a60db45 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.8.15-dev +version: 0.9.1-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/lib/semmle/javascript/Concepts.qll b/javascript/ql/lib/semmle/javascript/Concepts.qll index 01970490374c..14102556a874 100644 --- a/javascript/ql/lib/semmle/javascript/Concepts.qll +++ b/javascript/ql/lib/semmle/javascript/Concepts.qll @@ -125,16 +125,7 @@ module Cryptography { * extend `CryptographicOperation::Range` instead. */ class CryptographicOperation extends SC::CryptographicOperation instanceof CryptographicOperation::Range - { - /** - * DEPRECATED. This predicate has been renamed to `getAnInput`. - * - * To implement `CryptographicOperation`, please extend - * `CryptographicOperation::Range` and implement `getAnInput` instead of - * extending this class directly. - */ - deprecated final DataFlow::Node getInput() { result = this.getAnInput() } - } + { } class EncryptionAlgorithm = SC::EncryptionAlgorithm; diff --git a/javascript/ql/lib/semmle/javascript/Regexp.qll b/javascript/ql/lib/semmle/javascript/Regexp.qll index 3c190af44764..27ad339c733e 100644 --- a/javascript/ql/lib/semmle/javascript/Regexp.qll +++ b/javascript/ql/lib/semmle/javascript/Regexp.qll @@ -1022,20 +1022,6 @@ predicate isInterpretedAsRegExp(DataFlow::Node source) { ) } -/** - * Provides utility predicates related to regular expressions. - */ -deprecated module RegExpPatterns { - /** - * Gets a pattern that matches common top-level domain names in lower case. - * DEPRECATED: use the similarly named predicate from `HostnameRegex` from the `regex` pack instead. - */ - deprecated string getACommonTld() { - // according to ranking by http://google.com/search?q=site:.<> - result = "(?:com|org|edu|gov|uk|net|io)(?![a-z0-9])" - } -} - /** * Gets a node whose value may flow (inter-procedurally) to `re`, where it is interpreted * as a part of a regular expression. diff --git a/javascript/ql/lib/semmle/javascript/endpoints/EndpointNaming.qll b/javascript/ql/lib/semmle/javascript/endpoints/EndpointNaming.qll index 9e514d4c9f41..8fcb83729c48 100644 --- a/javascript/ql/lib/semmle/javascript/endpoints/EndpointNaming.qll +++ b/javascript/ql/lib/semmle/javascript/endpoints/EndpointNaming.qll @@ -432,7 +432,7 @@ string renderName(string package, string name) { result = join("(" + package + " * These names are not necessarily part of a package's public API, and so we only used them * as a fallback when a publicly-accessible access path cannot be found. */ -private module InternalModuleNaming { +module InternalModuleNaming { /** Gets the path to `folder` relative to its enclosing non-private `package.json` file. */ private string getPackageRelativePathFromFolder(Folder folder) { exists(PackageJson json | @@ -446,7 +446,10 @@ private module InternalModuleNaming { getPackageRelativePathFromFolder(folder.getParentContainer()) + "/" + folder.getBaseName() } - private string getPackageRelativePath(Module mod) { + /** + * Gets the path to `mod` relative to its enclosing package, including the package name. + */ + string getPackageRelativePath(Module mod) { exists(PackageJson json, string relativePath | not json.isPrivate() and json.getExportedModule(relativePath) = mod and diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll index b3d93383ed78..98bb0f615b67 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll @@ -1003,7 +1003,7 @@ module NodeJSLib { exists(ClientRequestLoginCallback callback | this = callback.getACall().getArgument(0)) } - override string getCredentialsKind() { result = "Node.js http(s) client login username" } + override string getCredentialsKind() { result = "user name" } } /** @@ -1014,7 +1014,7 @@ module NodeJSLib { exists(ClientRequestLoginCallback callback | this = callback.getACall().getArgument(1)) } - override string getCredentialsKind() { result = "Node.js http(s) client login password" } + override string getCredentialsKind() { result = "password" } } /** diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll index adfd683a4977..6e95955749b4 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll @@ -108,7 +108,11 @@ module ModelExport { } predicate exposedName(API::Node node, string type, string path) { - node = API::moduleExport(type) and path = "" + exists(string moduleName | + node = API::moduleExport(moduleName) and + path = "" and + type = "(" + moduleName + ")" + ) } predicate suggestedName(API::Node node, string type) { diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll index 1a7b7e9bf32a..1b616a199bc0 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll @@ -34,6 +34,11 @@ class Location = JS::Location; * * Type names have form `package.type` or just `package` if referring to the package export * object. If `package` contains a `.` character it must be enclosed in single quotes, such as `'package'.type`. + * + * A type name of form `(package)` may also be used when refering to the package export object. + * We allow this syntax as an alternative to the above, so models generated based on `EndpointNaming` look more consistent. + * However, access paths are deliberately not parsed here, as we can not handle aliasing at this stage. + * The model generator must explicitly generate the step between `(package)` and `(package).foo`, for example. */ bindingset[rawType] predicate parseTypeString(string rawType, string package, string qualifiedName) { @@ -42,6 +47,9 @@ predicate parseTypeString(string rawType, string package, string qualifiedName) package = rawType.regexpCapture(regexp, 1).regexpReplaceAll("^'|'$", "") and qualifiedName = rawType.regexpCapture(regexp, 2).regexpReplaceAll("^\\.", "") ) + or + package = rawType.regexpCapture("[(]([^)]+)[)]", 1) and + qualifiedName = "" } /** diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/model.yml b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/empty.model.yml similarity index 81% rename from javascript/ql/lib/semmle/javascript/frameworks/data/internal/model.yml rename to javascript/ql/lib/semmle/javascript/frameworks/data/internal/empty.model.yml index 016192a224ae..12f83f71e55b 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/model.yml +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/empty.model.yml @@ -1,5 +1,6 @@ extensions: - # Contribute empty data sets to avoid errors about an undefined extensionals + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about undefined extensionals. - addsTo: pack: codeql/javascript-all extensible: sourceModel diff --git a/javascript/ql/lib/semmle/javascript/security/BadTagFilterQuery.qll b/javascript/ql/lib/semmle/javascript/security/BadTagFilterQuery.qll deleted file mode 100644 index 0bc83143e8ca..000000000000 --- a/javascript/ql/lib/semmle/javascript/security/BadTagFilterQuery.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Provides predicates for reasoning about bad tag filter vulnerabilities. - */ - -private import regexp.RegExpTreeView::RegExpTreeView as TreeView -// BadTagFilterQuery should be used directly from the shared pack, and not from this file. -deprecated private import codeql.regex.nfa.BadTagFilterQuery::Make as Dep -import Dep diff --git a/javascript/ql/lib/semmle/javascript/security/OverlyLargeRangeQuery.qll b/javascript/ql/lib/semmle/javascript/security/OverlyLargeRangeQuery.qll deleted file mode 100644 index 2053afe95f8c..000000000000 --- a/javascript/ql/lib/semmle/javascript/security/OverlyLargeRangeQuery.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Classes and predicates for working with suspicious character ranges. - */ - -private import regexp.RegExpTreeView::RegExpTreeView as TreeView -// OverlyLargeRangeQuery should be used directly from the shared pack, and not from this file. -deprecated private import codeql.regex.OverlyLargeRangeQuery::Make as Dep -import Dep diff --git a/javascript/ql/lib/semmle/javascript/security/regexp/RegexpMatching.qll b/javascript/ql/lib/semmle/javascript/security/regexp/RegexpMatching.qll deleted file mode 100644 index cfc0f4992406..000000000000 --- a/javascript/ql/lib/semmle/javascript/security/regexp/RegexpMatching.qll +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Provides predicates for reasoning about which strings are matched by a regular expression, - * and for testing which capture groups are filled when a particular regexp matches a string. - */ - -private import RegExpTreeView::RegExpTreeView as TreeView -// RegexpMatching should be used directly from the shared pack, and not from this file. -deprecated private import codeql.regex.nfa.RegexpMatching::Make as Dep -import Dep diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index 51c2e97d9eac..7499f8b36698 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.8.15 + +### Minor Analysis Improvements + +* The JavaScript extractor will on longer report syntax errors related to "strict mode". + Files containing such errors are now being fully analyzed along with other sources files. + This improves our support for source files that technically break the "strict mode" rules, + but where a build steps transforms the code such that it ends up working at runtime. + ## 0.8.14 ### Minor Analysis Improvements diff --git a/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll b/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll deleted file mode 100644 index 524be45c6539..000000000000 --- a/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Provides predicates for reasoning about regular expressions - * that match URLs and hostname patterns. - */ - -deprecated import semmle.javascript.security.regexp.HostnameRegexp as Dep -import Dep diff --git a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp index adcd6fc47159..b2d00e38c284 100644 --- a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp +++ b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp @@ -19,6 +19,10 @@ If possible, store configuration files including credential data separately from the source code, in a secure location with restricted access.

    +

    + If the credentials are a placeholder value, make sure the value is obviously a placeholder by + using a name such as "SampleToken" or "MyPassword". +

    diff --git a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql index 3cc63e51dcfe..1c13ad78bfa2 100644 --- a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql +++ b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql @@ -30,7 +30,7 @@ where // exclude dummy passwords and templates not ( sink.getNode().(Sink).(DefaultCredentialsSink).getKind() = - ["password", "credentials", "token"] and + ["password", "credentials", "token", "key"] and PasswordHeuristics::isDummyPassword(val) or sink.getNode().(Sink).getKind() = "authorization header" and diff --git a/javascript/ql/src/change-notes/2024-04-17-strict-mode.md b/javascript/ql/src/change-notes/released/0.8.15.md similarity index 89% rename from javascript/ql/src/change-notes/2024-04-17-strict-mode.md rename to javascript/ql/src/change-notes/released/0.8.15.md index 65dd10d45eb3..43526f8e132a 100644 --- a/javascript/ql/src/change-notes/2024-04-17-strict-mode.md +++ b/javascript/ql/src/change-notes/released/0.8.15.md @@ -1,6 +1,7 @@ ---- -category: minorAnalysis ---- +## 0.8.15 + +### Minor Analysis Improvements + * The JavaScript extractor will on longer report syntax errors related to "strict mode". Files containing such errors are now being fully analyzed along with other sources files. This improves our support for source files that technically break the "strict mode" rules, diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index b36a2e248f34..2e3c183bb7a2 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.8.14 +lastReleaseVersion: 0.8.15 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index d67a8f387d81..97c6c232c9e2 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.8.15-dev +version: 0.8.16-dev groups: - javascript - queries diff --git a/javascript/ql/test/library-tests/ModelGeneration/ModelGeneration.expected b/javascript/ql/test/library-tests/ModelGeneration/ModelGeneration.expected index 26547b2814f0..d983b77b5383 100644 --- a/javascript/ql/test/library-tests/ModelGeneration/ModelGeneration.expected +++ b/javascript/ql/test/library-tests/ModelGeneration/ModelGeneration.expected @@ -1,17 +1,17 @@ typeModel -| (aliases).Alias1 | aliases | Member[Alias1] | -| (aliases).Alias1 | aliases | Member[Alias2] | -| (aliases).Alias1 | aliases | Member[Alias3].Member[x] | -| (aliases).Alias1 | aliases | Member[Alias4].Member[x].Member[x] | -| (aliases).Alias1 | aliases | Member[AliasedClass] | +| (aliases).Alias1 | (aliases) | Member[Alias1] | +| (aliases).Alias1 | (aliases) | Member[Alias2] | +| (aliases).Alias1 | (aliases) | Member[Alias3].Member[x] | +| (aliases).Alias1 | (aliases) | Member[Alias4].Member[x].Member[x] | +| (aliases).Alias1 | (aliases) | Member[AliasedClass] | | (aliases).Alias1.prototype | (aliases).Alias1 | Instance | | (aliases).Alias1.prototype | (aliases).Alias1.prototype.foo | ReturnValue | | (aliases).Alias1.prototype.foo | (aliases).Alias1.prototype | Member[foo] | -| (long-access-path).a.shortcut.d | long-access-path | Member[a].Member[b].Member[c].Member[d] | -| (long-access-path).a.shortcut.d | long-access-path | Member[a].Member[shortcut].Member[d] | +| (long-access-path).a.shortcut.d | (long-access-path) | Member[a].Member[b].Member[c].Member[d] | +| (long-access-path).a.shortcut.d | (long-access-path) | Member[a].Member[shortcut].Member[d] | | (long-access-path).a.shortcut.d.e | (long-access-path).a.shortcut.d | Member[e] | -| (reexport).func | reexport | Member[func] | -| (return-this).FluentInterface | return-this | Member[FluentInterface] | +| (reexport).func | (reexport) | Member[func] | +| (return-this).FluentInterface | (return-this) | Member[FluentInterface] | | (return-this).FluentInterface.prototype | (return-this).FluentInterface | Instance | | (return-this).FluentInterface.prototype | (return-this).FluentInterface.prototype.bar | ReturnValue | | (return-this).FluentInterface.prototype | (return-this).FluentInterface.prototype.baz | ReturnValue | @@ -21,45 +21,45 @@ typeModel | (return-this).FluentInterface.prototype.foo | (return-this).FluentInterface.prototype | Member[foo] | | (return-this).FluentInterface.prototype.notFluent | (return-this).FluentInterface.prototype | Member[notFluent] | | (return-this).FluentInterface.prototype.notFluent2 | (return-this).FluentInterface.prototype | Member[notFluent2] | -| (root-function).PublicClass | root-function | Member[PublicClass] | +| (root-function).PublicClass | (root-function) | Member[PublicClass] | +| (root-function).PublicClass.prototype | (root-function) | ReturnValue | | (root-function).PublicClass.prototype | (root-function).PublicClass | Instance | -| (root-function).PublicClass.prototype | root-function | ReturnValue | | (root-function).PublicClass.prototype.method | (root-function).PublicClass.prototype | Member[method] | -| (semi-internal-class).PublicClass | semi-internal-class | Member[PublicClass] | +| (semi-internal-class).PublicClass | (semi-internal-class) | Member[PublicClass] | | (semi-internal-class).PublicClass.prototype | (semi-internal-class).PublicClass | Instance | | (semi-internal-class).PublicClass.prototype | (semi-internal-class).SemiInternalClass.prototype.method | ReturnValue | | (semi-internal-class).PublicClass.prototype | (semi-internal-class).getAnonymous~expr2 | ReturnValue | | (semi-internal-class).PublicClass.prototype.publicMethod | (semi-internal-class).PublicClass.prototype | Member[publicMethod] | | (semi-internal-class).SemiInternalClass.prototype | (semi-internal-class).get | ReturnValue | | (semi-internal-class).SemiInternalClass.prototype.method | (semi-internal-class).SemiInternalClass.prototype | Member[method] | -| (semi-internal-class).get | semi-internal-class | Member[get] | -| (semi-internal-class).getAnonymous | semi-internal-class | Member[getAnonymous] | +| (semi-internal-class).get | (semi-internal-class) | Member[get] | +| (semi-internal-class).getAnonymous | (semi-internal-class) | Member[getAnonymous] | | (semi-internal-class).getAnonymous~expr1 | (semi-internal-class).getAnonymous | ReturnValue | | (semi-internal-class).getAnonymous~expr2 | (semi-internal-class).getAnonymous~expr1 | Member[method] | -| (subclass).A | subclass | Member[A] | +| (subclass).A | (subclass) | Member[A] | | (subclass).A.prototype | (subclass).A | Instance | | (subclass).A.prototype | (subclass).B.prototype | | | (subclass).A.prototype | (subclass).ExposedMidSubClass.prototype~expr1 | | | (subclass).A.prototype.a | (subclass).A.prototype | Member[a] | -| (subclass).B | subclass | Member[B] | +| (subclass).B | (subclass) | Member[B] | | (subclass).B.prototype | (subclass).B | Instance | | (subclass).B.prototype | (subclass).C.prototype | | | (subclass).B.prototype.b | (subclass).B.prototype | Member[b] | -| (subclass).C | subclass | Member[C] | +| (subclass).C | (subclass) | Member[C] | | (subclass).C.prototype | (subclass).C | Instance | | (subclass).C.prototype.c | (subclass).C.prototype | Member[c] | -| (subclass).D | subclass | Member[D] | +| (subclass).D | (subclass) | Member[D] | | (subclass).D.prototype | (subclass).D | Instance | | (subclass).D.prototype.d | (subclass).D.prototype | Member[d] | -| (subclass).ExposedMidSubClass | subclass | Member[ExposedMidSubClass] | +| (subclass).ExposedMidSubClass | (subclass) | Member[ExposedMidSubClass] | | (subclass).ExposedMidSubClass.prototype | (subclass).ExposedMidSubClass | Instance | | (subclass).ExposedMidSubClass.prototype.m | (subclass).ExposedMidSubClass.prototype | Member[m] | | (subclass).ExposedMidSubClass.prototype~expr1 | (subclass).ExposedMidSubClass.prototype | | +| upstream-lib | (reexport) | Member[lib] | | upstream-lib | (reexport).func | ReturnValue | -| upstream-lib | reexport | Member[lib] | | upstream-lib.Type | (subclass).D.prototype | | -| upstream-lib.XYZ | reexport | Member[x].Member[y].Member[z] | -| upstream-lib.XYZ | reexport | Member[xy].Member[z] | +| upstream-lib.XYZ | (reexport) | Member[x].Member[y].Member[z] | +| upstream-lib.XYZ | (reexport) | Member[xy].Member[z] | summaryModel | (aliases).Alias1.prototype | | | Member[foo].ReturnValue | type | | (return-this).FluentInterface.prototype | | | Member[bar].ReturnValue | type | diff --git a/javascript/ql/test/library-tests/frameworks/data/test.expected b/javascript/ql/test/library-tests/frameworks/data/test.expected index 843b1f32d5bc..d9b9d7e18e27 100644 --- a/javascript/ql/test/library-tests/frameworks/data/test.expected +++ b/javascript/ql/test/library-tests/frameworks/data/test.expected @@ -78,6 +78,7 @@ taintFlow | test.js:265:6:265:39 | new MyS ... ource() | test.js:265:6:265:39 | new MyS ... ource() | | test.js:269:10:269:31 | this.ba ... ource() | test.js:269:10:269:31 | this.ba ... ource() | | test.js:272:6:272:40 | new MyS ... ource() | test.js:272:6:272:40 | new MyS ... ource() | +| test.js:274:6:274:39 | testlib ... eName() | test.js:274:6:274:39 | testlib ... eName() | isSink | test.js:54:18:54:25 | source() | test-sink | | test.js:55:22:55:29 | source() | test-sink | diff --git a/javascript/ql/test/library-tests/frameworks/data/test.ext.yml b/javascript/ql/test/library-tests/frameworks/data/test.ext.yml index 2387cc03978a..8aec67669138 100644 --- a/javascript/ql/test/library-tests/frameworks/data/test.ext.yml +++ b/javascript/ql/test/library-tests/frameworks/data/test.ext.yml @@ -10,6 +10,7 @@ extensions: - ['testlib', 'Member[MethodDecorator].DecoratedMember.Parameter[0]', 'test-source'] - ['testlib', 'Member[ParamDecoratorSource].DecoratedParameter', 'test-source'] - ['testlib', 'Member[getSource].ReturnValue', 'test-source'] + - ['(testlib)', 'Member[parenthesizedPackageName].ReturnValue', 'test-source'] - addsTo: pack: codeql/javascript-all @@ -73,4 +74,4 @@ extensions: data: - ['ABC', 'Member[a].Member[b].WithArity[0].ReturnValue.Member[c]'] - ['LeftRight', 'Member[left].TypeVar[LeftRight].Member[right]'] - - ['LeftRight', 'Member[x]'] \ No newline at end of file + - ['LeftRight', 'Member[x]'] diff --git a/javascript/ql/test/library-tests/frameworks/data/test.js b/javascript/ql/test/library-tests/frameworks/data/test.js index bbcb10418a12..97bb49f8cf71 100644 --- a/javascript/ql/test/library-tests/frameworks/data/test.js +++ b/javascript/ql/test/library-tests/frameworks/data/test.js @@ -270,3 +270,5 @@ class MySubclass2 extends MySubclass { } } sink(new MySubclass2().baseclassSource()); // NOT OK + +sink(testlib.parenthesizedPackageName()); // NOT OK diff --git a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected index 3635090cb433..fc41f193149c 100644 --- a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected +++ b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected @@ -153,12 +153,12 @@ nodes | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | +| HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | +| HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | +| HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | +| HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | +| HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | +| HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | | HardcodedCredentials.js:164:35:164:45 | 'change_me' | | HardcodedCredentials.js:164:35:164:45 | 'change_me' | | HardcodedCredentials.js:164:35:164:45 | 'change_me' | @@ -271,6 +271,18 @@ nodes | HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | | HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | | HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | +| HardcodedCredentials.js:299:44:299:52 | 'mytoken' | +| HardcodedCredentials.js:299:44:299:52 | 'mytoken' | +| HardcodedCredentials.js:299:44:299:52 | 'mytoken' | +| HardcodedCredentials.js:300:44:300:56 | 'SampleToken' | +| HardcodedCredentials.js:300:44:300:56 | 'SampleToken' | +| HardcodedCredentials.js:300:44:300:56 | 'SampleToken' | +| HardcodedCredentials.js:301:44:301:55 | 'MyPassword' | +| HardcodedCredentials.js:301:44:301:55 | 'MyPassword' | +| HardcodedCredentials.js:301:44:301:55 | 'MyPassword' | +| HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | +| HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | +| HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | edges | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | @@ -326,8 +338,8 @@ edges | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | HardcodedCredentials.js:160:38:160:48 | "change_me" | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | HardcodedCredentials.js:161:41:161:51 | 'change_me' | +| HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | +| HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | | HardcodedCredentials.js:164:35:164:45 | 'change_me' | HardcodedCredentials.js:164:35:164:45 | 'change_me' | | HardcodedCredentials.js:171:11:171:25 | USER | HardcodedCredentials.js:173:35:173:38 | USER | | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:11:171:25 | USER | @@ -399,6 +411,10 @@ edges | HardcodedCredentials.js:293:37:293:65 | `Basic ... xxxxxx` | HardcodedCredentials.js:293:37:293:65 | `Basic ... xxxxxx` | | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | | HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | +| HardcodedCredentials.js:299:44:299:52 | 'mytoken' | HardcodedCredentials.js:299:44:299:52 | 'mytoken' | +| HardcodedCredentials.js:300:44:300:56 | 'SampleToken' | HardcodedCredentials.js:300:44:300:56 | 'SampleToken' | +| HardcodedCredentials.js:301:44:301:55 | 'MyPassword' | HardcodedCredentials.js:301:44:301:55 | 'MyPassword' | +| HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | #select | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | The hard-coded value "dbuser" is used as $@. | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | user name | | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | The hard-coded value "hgfedcba" is used as $@. | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | password | @@ -448,8 +464,8 @@ edges | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | The hard-coded value "hgfedcba" is used as $@. | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | key | | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | The hard-coded value "hgfedcba" is used as $@. | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | key | | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | The hard-coded value "hgfedcba" is used as $@. | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | key | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | HardcodedCredentials.js:160:38:160:48 | "change_me" | HardcodedCredentials.js:160:38:160:48 | "change_me" | The hard-coded value "change_me" is used as $@. | HardcodedCredentials.js:160:38:160:48 | "change_me" | key | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | HardcodedCredentials.js:161:41:161:51 | 'change_me' | HardcodedCredentials.js:161:41:161:51 | 'change_me' | The hard-coded value "change_me" is used as $@. | HardcodedCredentials.js:161:41:161:51 | 'change_me' | key | +| HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | The hard-coded value "oiuneawrgiyubaegr" is used as $@. | HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | key | +| HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | The hard-coded value "oiuneawrgiyubaegr" is used as $@. | HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | key | | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | authorization header | | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | authorization header | | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | authorization header | @@ -464,3 +480,4 @@ edges | HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:246:42:246:51 | privateKey | The hard-coded value "myHardCodedPrivateKey" is used as $@. | HardcodedCredentials.js:246:42:246:51 | privateKey | key | | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | The hard-coded value "Basic sdsdag:sdsdag" is used as $@. | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | authorization header | | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | The hard-coded value "Basic sdsdag:aaaiuogrweuibgbbbbb" is used as $@. | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | authorization header | +| HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | The hard-coded value "iubfewiaaweiybgaeuybgera" is used as $@. | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | key | diff --git a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js index 8482d5106fe4..d1543f16dc75 100644 --- a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js +++ b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js @@ -157,8 +157,8 @@ })(); (function(){ - require("cookie-session")({ secret: "change_me" }); // NOT OK - require('crypto').createHmac('sha256', 'change_me'); // NOT OK + require("cookie-session")({ secret: "oiuneawrgiyubaegr" }); // NOT OK + require('crypto').createHmac('sha256', 'oiuneawrgiyubaegr'); // NOT OK var basicAuth = require('express-basic-auth'); basicAuth({users: { [adminName]: 'change_me' }}); // OK @@ -294,3 +294,10 @@ headers.append("Authorization", `Basic sdsdag:aaaiuogrweuibgbbbbb`); // NOT OK headers.append("Authorization", `Basic sdsdag:000000000000001`); // OK }); + +(function () { + require('crypto').createHmac('sha256', 'mytoken'); // OK + require('crypto').createHmac('sha256', 'SampleToken'); // OK + require('crypto').createHmac('sha256', 'MyPassword'); // OK + require('crypto').createHmac('sha256', 'iubfewiaaweiybgaeuybgera'); // NOT OK +})(); \ No newline at end of file diff --git a/misc/bazel/BUILD.bazel b/misc/bazel/BUILD.bazel index e69de29bb2d1..3ccdcda5f129 100644 --- a/misc/bazel/BUILD.bazel +++ b/misc/bazel/BUILD.bazel @@ -0,0 +1,9 @@ +load("@buildifier_prebuilt//:rules.bzl", "buildifier") + +buildifier( + name = "buildifier", + exclude_patterns = [ + "./.git/*", + ], + lint_mode = "fix", +) diff --git a/python/ql/test/experimental/dataflow/consistency/modeling-consistency.expected b/misc/bazel/internal/BUILD.bazel similarity index 100% rename from python/ql/test/experimental/dataflow/consistency/modeling-consistency.expected rename to misc/bazel/internal/BUILD.bazel diff --git a/misc/bazel/internal/git_lfs_probe.py b/misc/bazel/internal/git_lfs_probe.py new file mode 100755 index 000000000000..018725c82da8 --- /dev/null +++ b/misc/bazel/internal/git_lfs_probe.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 + +""" +Probe lfs files. +For each source file provided as output, this will print: +* "local", if the source file is not an LFS pointer +* the sha256 hash, a space character and a transient download link obtained via the LFS protocol otherwise +""" + +import sys +import pathlib +import subprocess +import os +import shutil +import json +import urllib.request +from urllib.parse import urlparse +import re +import base64 +from dataclasses import dataclass +from typing import Dict + + +@dataclass +class Endpoint: + href: str + headers: Dict[str, str] + + def update_headers(self, d: Dict[str, str]): + self.headers.update((k.capitalize(), v) for k, v in d.items()) + + +sources = [pathlib.Path(arg).resolve() for arg in sys.argv[1:]] +source_dir = pathlib.Path(os.path.commonpath(src.parent for src in sources)) +source_dir = subprocess.check_output(["git", "rev-parse", "--show-toplevel"], cwd=source_dir, text=True).strip() + + +def get_env(s, sep="="): + ret = {} + for m in re.finditer(fr'(.*?){sep}(.*)', s, re.M): + ret.setdefault(*m.groups()) + return ret + + +def git(*args, **kwargs): + return subprocess.run(("git",) + args, stdout=subprocess.PIPE, text=True, cwd=source_dir, **kwargs).stdout.strip() + + +def get_endpoint(): + lfs_env = get_env(subprocess.check_output(["git", "lfs", "env"], text=True, cwd=source_dir)) + endpoint = next(v for k, v in lfs_env.items() if k.startswith('Endpoint')) + endpoint, _, _ = endpoint.partition(' ') + ssh_endpoint = lfs_env.get(" SSH") + endpoint = Endpoint(endpoint, { + "Content-Type": "application/vnd.git-lfs+json", + "Accept": "application/vnd.git-lfs+json", + }) + if ssh_endpoint: + # see https://github.com/git-lfs/git-lfs/blob/main/docs/api/authentication.md + server, _, path = ssh_endpoint.partition(":") + ssh_command = shutil.which(os.environ.get("GIT_SSH", os.environ.get("GIT_SSH_COMMAND", "ssh"))) + assert ssh_command, "no ssh command found" + resp = json.loads(subprocess.check_output([ssh_command, server, "git-lfs-authenticate", path, "download"])) + endpoint.href = resp.get("href", endpoint) + endpoint.update_headers(resp.get("header", {})) + url = urlparse(endpoint.href) + # this is how actions/checkout persist credentials + # see https://github.com/actions/checkout/blob/44c2b7a8a4ea60a981eaca3cf939b5f4305c123b/src/git-auth-helper.ts#L56-L63 + auth = git("config", f"http.{url.scheme}://{url.netloc}/.extraheader") + endpoint.update_headers(get_env(auth, sep=": ")) + if "GITHUB_TOKEN" in os.environ: + endpoint.headers["Authorization"] = f"token {os.environ['GITHUB_TOKEN']}" + if "Authorization" not in endpoint.headers: + # last chance: use git credentials (possibly backed by a credential helper like the one installed by gh) + # see https://git-scm.com/docs/git-credential + credentials = get_env(git("credential", "fill", check=True, + # drop leading / from url.path + input=f"protocol={url.scheme}\nhost={url.netloc}\npath={url.path[1:]}\n")) + auth = base64.b64encode(f'{credentials["username"]}:{credentials["password"]}'.encode()).decode('ascii') + endpoint.headers["Authorization"] = f"Basic {auth}" + return endpoint + + +# see https://github.com/git-lfs/git-lfs/blob/310d1b4a7d01e8d9d884447df4635c7a9c7642c2/docs/api/basic-transfers.md +def get_locations(objects): + ret = ["local" for _ in objects] + endpoint = get_endpoint() + indexes = [i for i, o in enumerate(objects) if o] + if not indexes: + # all objects are local, do not send an empty request as that would be an error + return ret + data = { + "operation": "download", + "transfers": ["basic"], + "objects": [objects[i] for i in indexes], + "hash_algo": "sha256", + } + req = urllib.request.Request( + f"{endpoint.href}/objects/batch", + headers=endpoint.headers, + data=json.dumps(data).encode("ascii"), + ) + with urllib.request.urlopen(req) as resp: + data = json.load(resp) + assert len(data["objects"]) == len(indexes), f"received {len(data)} objects, expected {len(indexes)}" + for i, resp in zip(indexes, data["objects"]): + ret[i] = f'{resp["oid"]} {resp["actions"]["download"]["href"]}' + return ret + + +def get_lfs_object(path): + with open(path, 'rb') as fileobj: + lfs_header = "version https://git-lfs.github.com/spec".encode() + actual_header = fileobj.read(len(lfs_header)) + sha256 = size = None + if lfs_header != actual_header: + return None + data = get_env(fileobj.read().decode('ascii'), sep=' ') + assert data['oid'].startswith('sha256:'), f"unknown oid type: {data['oid']}" + _, _, sha256 = data['oid'].partition(':') + size = int(data['size']) + return {"oid": sha256, "size": size} + + +objects = [get_lfs_object(src) for src in sources] +for resp in get_locations(objects): + print(resp) diff --git a/misc/bazel/lfs.bzl b/misc/bazel/lfs.bzl new file mode 100644 index 000000000000..4ba66c9dbfc6 --- /dev/null +++ b/misc/bazel/lfs.bzl @@ -0,0 +1,94 @@ +def lfs_smudge(repository_ctx, srcs, extract = False, stripPrefix = None): + for src in srcs: + repository_ctx.watch(src) + script = Label("//misc/bazel/internal:git_lfs_probe.py") + python = repository_ctx.which("python3") or repository_ctx.which("python") + if not python: + fail("Neither python3 nor python executables found") + repository_ctx.report_progress("querying LFS url(s) for: %s" % ", ".join([src.basename for src in srcs])) + res = repository_ctx.execute([python, script] + srcs, quiet = True) + if res.return_code != 0: + fail("git LFS probing failed while instantiating @%s:\n%s" % (repository_ctx.name, res.stderr)) + promises = [] + for src, loc in zip(srcs, res.stdout.splitlines()): + if loc == "local": + if extract: + repository_ctx.report_progress("extracting local %s" % src.basename) + repository_ctx.extract(src, stripPrefix = stripPrefix) + else: + repository_ctx.report_progress("symlinking local %s" % src.basename) + repository_ctx.symlink(src, src.basename) + else: + sha256, _, url = loc.partition(" ") + if extract: + # we can't use skylib's `paths.split_extension`, as that only gets the last extension, so `.tar.gz` + # or similar wouldn't work + # it doesn't matter if file is something like some.name.zip and possible_extension == "name.zip", + # download_and_extract will just append ".name.zip" its internal temporary name, so extraction works + possible_extension = ".".join(src.basename.rsplit(".", 2)[-2:]) + repository_ctx.report_progress("downloading and extracting remote %s" % src.basename) + repository_ctx.download_and_extract(url, sha256 = sha256, stripPrefix = stripPrefix, type = possible_extension) + else: + repository_ctx.report_progress("downloading remote %s" % src.basename) + repository_ctx.download(url, src.basename, sha256 = sha256) + +def _download_and_extract_lfs(repository_ctx): + attr = repository_ctx.attr + src = repository_ctx.path(attr.src) + if attr.build_file_content and attr.build_file: + fail("You should specify only one among build_file_content and build_file for rule @%s" % repository_ctx.name) + lfs_smudge(repository_ctx, [src], extract = True, stripPrefix = attr.strip_prefix) + if attr.build_file_content: + repository_ctx.file("BUILD.bazel", attr.build_file_content) + elif attr.build_file: + repository_ctx.symlink(attr.build_file, "BUILD.bazel") + +def _download_lfs(repository_ctx): + attr = repository_ctx.attr + if int(bool(attr.srcs)) + int(bool(attr.dir)) != 1: + fail("Exactly one between `srcs` and `dir` must be defined for @%s" % repository_ctx.name) + if attr.srcs: + srcs = [repository_ctx.path(src) for src in attr.srcs] + else: + dir = repository_ctx.path(attr.dir) + if not dir.is_dir: + fail("`dir` not a directory in @%s" % repository_ctx.name) + srcs = [f for f in dir.readdir() if not f.is_dir] + lfs_smudge(repository_ctx, srcs) + + # with bzlmod the name is qualified with `~` separators, and we want the base name here + name = repository_ctx.name.split("~")[-1] + repository_ctx.file("BUILD.bazel", """ +exports_files({files}) + +filegroup( + name = "{name}", + srcs = {files}, + visibility = ["//visibility:public"], +) +""".format(name = name, files = repr([src.basename for src in srcs]))) + +lfs_archive = repository_rule( + doc = "Export the contents from an on-demand LFS archive. The corresponding path should be added to be ignored " + + "in `.lfsconfig`.", + implementation = _download_and_extract_lfs, + attrs = { + "src": attr.label(mandatory = True, doc = "Local path to the LFS archive to extract."), + "build_file_content": attr.string(doc = "The content for the BUILD file for this repository. " + + "Either build_file or build_file_content can be specified, but not both."), + "build_file": attr.label(doc = "The file to use as the BUILD file for this repository. " + + "Either build_file or build_file_content can be specified, but not both."), + "strip_prefix": attr.string(default = "", doc = "A directory prefix to strip from the extracted files. "), + }, +) + +lfs_files = repository_rule( + doc = "Export LFS files for on-demand download. Exactly one between `srcs` and `dir` must be defined. The " + + "corresponding paths should be added to be ignored in `.lfsconfig`.", + implementation = _download_lfs, + attrs = { + "srcs": attr.label_list(doc = "Local paths to the LFS files to export."), + "dir": attr.label(doc = "Local path to a directory containing LFS files to export. Only the direct contents " + + "of the directory are exported"), + }, +) diff --git a/misc/bazel/registry/AUTHORS b/misc/bazel/registry/AUTHORS new file mode 100644 index 000000000000..42818b292e7c --- /dev/null +++ b/misc/bazel/registry/AUTHORS @@ -0,0 +1,7 @@ +# This is the list of Bazel's significant contributors. +# +# This does not necessarily list everyone who has contributed code, +# especially since many employees of one corporation may be contributing. +# To see the full list of contributors, see the revision history in +# source control. +Google LLC diff --git a/misc/bazel/registry/LICENSE b/misc/bazel/registry/LICENSE new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/misc/bazel/registry/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/misc/bazel/registry/NOTICE b/misc/bazel/registry/NOTICE new file mode 100644 index 000000000000..95329ae18f60 --- /dev/null +++ b/misc/bazel/registry/NOTICE @@ -0,0 +1,3 @@ +The files in this directory where originally taken from http://github.com/bazelbuild/bazel-central-registry and are +a derivative work thereof, distributed under the Apache 2.0 license, with the following exceptions: +* the `fix.py` file was added under the MIT license as the rest of the `codeql` repository. diff --git a/misc/bazel/registry/README.md b/misc/bazel/registry/README.md new file mode 100644 index 000000000000..5d1723d0eacb --- /dev/null +++ b/misc/bazel/registry/README.md @@ -0,0 +1,3 @@ +Versions to be patched can be taken from https://github.com/bazelbuild/bazel-central-repository. After adding patches +inside `//patches`, and eventually renaming ``, run [`fix.py`](./fix.py) to align all metadata +to the renamed version and added patches. diff --git a/misc/bazel/registry/bazel_registry.json b/misc/bazel/registry/bazel_registry.json new file mode 100644 index 000000000000..ea3f94f7a1e4 --- /dev/null +++ b/misc/bazel/registry/bazel_registry.json @@ -0,0 +1,3 @@ +{ + "mirrors": [] +} diff --git a/misc/bazel/registry/fix.py b/misc/bazel/registry/fix.py new file mode 100755 index 000000000000..a2b947e19e20 --- /dev/null +++ b/misc/bazel/registry/fix.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2024 GitHub, Inc. + +""" +Fix metadata in overridden registry, updating `metadata.json` to list correct versions and `source.json` +to list correct patches with sha256 hashes. +""" + +import pathlib +import json +import base64 +import hashlib +import re + +this_dir = pathlib.Path(__file__).resolve().parent + + +def sha256(file): + with open(file, 'rb') as input: + hash = hashlib.sha256(input.read()).digest() + hash = base64.b64encode(hash).decode() + return f"sha256-{hash}" + + +def patch_file(file, f): + try: + data = file.read_text() + except FileNotFoundError: + data = None + file.write_text(f(data)) + + +def patch_json(file, **kwargs): + def update(data): + data = json.loads(data) if data else {} + data.update(kwargs) + return json.dumps(data, indent=4) + "\n" + + patch_file(file, update) + + +for entry in this_dir.joinpath("modules").iterdir(): + if not entry.is_dir(): + continue + versions = [e for e in entry.iterdir() if e.is_dir()] + + patch_json(entry / "metadata.json", versions=[v.name for v in versions]) + + for version in versions: + patch_json(version / "source.json", patches={ + p.name: sha256(p) for p in version.joinpath("patches").iterdir() + }) + patch_file(version / "MODULE.bazel", + lambda s: re.sub(r'''version\s*=\s*['"].*['"]''', f'version = "{version.name}"', s, 1)) diff --git a/misc/codegen/BUILD.bazel b/misc/codegen/BUILD.bazel index 102e52fb10b8..52a5c0011345 100644 --- a/misc/codegen/BUILD.bazel +++ b/misc/codegen/BUILD.bazel @@ -1,5 +1,3 @@ -load("@codegen_deps//:requirements.bzl", "requirement") - py_binary( name = "codegen", srcs = ["codegen.py"], diff --git a/misc/codegen/generators/BUILD.bazel b/misc/codegen/generators/BUILD.bazel index df328a7df7f4..f731c42ce23a 100644 --- a/misc/codegen/generators/BUILD.bazel +++ b/misc/codegen/generators/BUILD.bazel @@ -1,5 +1,3 @@ -load("@codegen_deps//:requirements.bzl", "requirement") - py_library( name = "generators", srcs = glob(["*.py"]), diff --git a/misc/scripts/accept-expected-changes-from-ci.py b/misc/scripts/accept-expected-changes-from-ci.py index bd7071a6c537..a8c86d8f3e45 100755 --- a/misc/scripts/accept-expected-changes-from-ci.py +++ b/misc/scripts/accept-expected-changes-from-ci.py @@ -38,14 +38,13 @@ def _get_codeql_repo_dir() -> Path: - return Path(__file__).parent.parent.parent + return Path(__file__).parent.parent.parent.resolve() CODEQL_REPO_DIR = _get_codeql_repo_dir() - def _get_semmle_code_dir() -> Optional[Path]: - guess = CODEQL_REPO_DIR.parent + guess = CODEQL_REPO_DIR.parent.resolve() try: out = subprocess.check_output( ["git", "remote", "-v"], @@ -221,7 +220,7 @@ def get_log_content(status: GithubStatus) -> str: return content -def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=False): +def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=False, wait_for_ci=True): if not pr_number and not sha_override: raise Exception("Must specify either a PR number or a SHA") @@ -274,17 +273,15 @@ def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=Fal if status.state == "failure": lang_test_failures.append(status) elif status.state == "pending": - LOGGER.error(f"Language tests ({status.context}) are still running, please wait for them to finish before running this script again") - sys.exit(1) + if wait_for_ci: + LOGGER.error(f"Language tests ({status.context}) are still running, please wait for them to finish before running this script again (or run with --dont-wait)") + sys.exit(1) job_failure_urls = set() for lang_test_failure in lang_test_failures: job_failure_urls.add(lang_test_failure.target_url) - if job_failure_urls: - assert len(job_failure_urls) == 1, f"Multiple job failure URLs: {job_failure_urls}" - job_failure_url = job_failure_urls.pop() - + for job_failure_url in job_failure_urls: # fixup URL. On the status, the target URL is the run, and it's really hard to # change this to link to the full `/runs//jobs/` URL, since # the `` is not available in a context: https://github.com/community/community/discussions/40291 @@ -302,6 +299,11 @@ def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=Fal for job in jobs["jobs"]: api_name: str = job["name"] + + if api_name.lower().startswith(expected_workflow_name.lower()): + lang_test_failure.job_id = job["id"] + break + if " / " not in api_name: continue @@ -311,9 +313,11 @@ def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=Fal if workflow_name == expected_workflow_name and job_name.lower().startswith(lang_test_failure.context.lower()): lang_test_failure.job_id = job["id"] break - else: - LOGGER.error(f"Could not find job for {lang_test_failure.context!r}") - sys.exit(1) + + for lang_test_failure in lang_test_failures: + if lang_test_failure.job_id is None: + LOGGER.error(f"Could not find job for {lang_test_failure.context!r}") + sys.exit(1) # Ruby/Swift/C#/Go use github actions, and not internal CI. These are not reported # from the /statuses API, but from the /check-suites API @@ -324,9 +328,10 @@ def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=Fal check_failure_urls = [] for check in check_suites["check_suites"]: if check["status"] != "completed": - print(check) - LOGGER.error("At least one check not completed yet!") - sys.exit(1) + if wait_for_ci: + print(check) + LOGGER.error("At least one check not completed yet!") + sys.exit(1) if check["conclusion"] == "failure": check_failure_urls.append(check["check_runs_url"]) @@ -413,7 +418,7 @@ def ok_job_name(job_name: str) -> bool: subprocess.check_call(["git", "apply", temp.name], cwd=patch.dir) - if "CONSISTENCY" in patch.filename.parts: + if "CONSISTENCY" in patch.filename.parts and patch.filename.exists(): # delete if empty if os.path.getsize(patch.filename) == 1 and patch.filename.read_text() == "\n": os.remove(patch.filename) @@ -457,6 +462,7 @@ def printHelp(): # parse command line arguments parser = argparse.ArgumentParser() parser.add_argument("--force", action="store_true", help="Apply patches even if the local SHA is different from the GitHub PR SHA") + parser.add_argument("--dont-wait", dest="wait_for_ci", action="store_false", help="Do not wait for all CI jobs to finish") parser.add_argument("posarg", nargs="?", default=None) if DEBUG_LOG_FILE: @@ -491,4 +497,4 @@ def printHelp(): else: pr_number = int(args.posarg) - main(pr_number, override_sha, force=args.force) + main(pr_number, override_sha, force=args.force, wait_for_ci=args.wait_for_ci) diff --git a/misc/scripts/generate-code-scanning-query-list.py b/misc/scripts/generate-code-scanning-query-list.py index 606bdf91c559..94b15a33886d 100644 --- a/misc/scripts/generate-code-scanning-query-list.py +++ b/misc/scripts/generate-code-scanning-query-list.py @@ -8,7 +8,7 @@ """ This script collects CodeQL queries that are part of code scanning query packs -and prints CSV data to stdout that describes which packs contain which queries. +and prints CSV data to stdout that describes which suites in the pack contain which queries. Errors are printed to stderr. This script requires that 'git' and 'codeql' commands are on the PATH. It'll try to automatically set the CodeQL search path correctly, @@ -159,7 +159,7 @@ def subprocess_run(cmd): csvwriter = csv.writer(sys.stdout) csvwriter.writerow([ "Query filename", "Suite", "Query name", "Query ID", - "Kind", "Severity", "Precision", "Tags" + "Kind", "Severity", "Precision", "Tags", "Security score" ]) # Iterate over all languages and packs, and resolve which queries are part of those packs @@ -198,5 +198,6 @@ def subprocess_run(cmd): get_query_metadata('kind', meta, queryfile_nwo), get_query_metadata('problem.severity', meta, queryfile_nwo), get_query_metadata('precision', meta, queryfile_nwo), - get_query_metadata('tags', meta, queryfile_nwo) + get_query_metadata('tags', meta, queryfile_nwo), + get_query_metadata('security-severity', meta, queryfile_nwo), ]) diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index ddf1cfabc849..e97a0b0fe5f2 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.15 + +No user-facing changes. + ## 0.7.14 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/0.7.15.md b/misc/suite-helpers/change-notes/released/0.7.15.md new file mode 100644 index 000000000000..8d772280c75e --- /dev/null +++ b/misc/suite-helpers/change-notes/released/0.7.15.md @@ -0,0 +1,3 @@ +## 0.7.15 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index 2189dcea5188..e56b7f6a7b1d 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.14 +lastReleaseVersion: 0.7.15 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 4aa5c302aa8a..1e5655889b82 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 0.7.15-dev +version: 0.7.16-dev groups: shared warnOnImplicitThis: true diff --git a/python/extractor/tsg-python/tsp/BUILD.bazel b/python/extractor/tsg-python/tsp/BUILD.bazel index e3389fce1ccd..1f7ec006c657 100644 --- a/python/extractor/tsg-python/tsp/BUILD.bazel +++ b/python/extractor/tsg-python/tsp/BUILD.bazel @@ -1,6 +1,6 @@ +load("@py_deps//:defs.bzl", "aliases", "all_crate_deps") load("@rules_rust//cargo:defs.bzl", "cargo_build_script") load("@rules_rust//rust:defs.bzl", "rust_library") -load("@py_deps//:defs.bzl", "aliases", "all_crate_deps") package(default_visibility = ["//visibility:public"]) diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index c55b68e36846..3ca353c75060 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,14 @@ +## 0.12.0 + +### Breaking Changes + +* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. +* Deleted the deprecated `Security/CWE-020/HostnameRegexpShared.qll` file. + +### Deprecated APIs + +- Renamed the `StrConst` class to `StringLiteral`, for greater consistency with other languages. The `StrConst` and `Str` classes are now deprecated and will be removed in a future release. + ## 0.11.14 ### Minor Analysis Improvements diff --git a/python/ql/lib/change-notes/2024-04-22-renaming-StrConst-to-StringLiteral.md b/python/ql/lib/change-notes/2024-04-22-renaming-StrConst-to-StringLiteral.md deleted file mode 100644 index 958262dda2bf..000000000000 --- a/python/ql/lib/change-notes/2024-04-22-renaming-StrConst-to-StringLiteral.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: deprecated ---- - -- Renamed the `StrConst` class to `StringLiteral`, for greater consistency with other languages. The `StrConst` and `Str` classes are now deprecated and will be removed in a future release. diff --git a/python/ql/lib/change-notes/released/0.12.0.md b/python/ql/lib/change-notes/released/0.12.0.md new file mode 100644 index 000000000000..2f122ac3bcc4 --- /dev/null +++ b/python/ql/lib/change-notes/released/0.12.0.md @@ -0,0 +1,10 @@ +## 0.12.0 + +### Breaking Changes + +* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. +* Deleted the deprecated `Security/CWE-020/HostnameRegexpShared.qll` file. + +### Deprecated APIs + +- Renamed the `StrConst` class to `StringLiteral`, for greater consistency with other languages. The `StrConst` and `Str` classes are now deprecated and will be removed in a future release. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index 63d619be9acb..5e2fb32b0597 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.11.14 +lastReleaseVersion: 0.12.0 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index c038958349ed..a06d9ac3d492 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.11.15-dev +version: 0.12.1-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/lib/semmle/python/dataflow/new/Regexp.qll b/python/ql/lib/semmle/python/dataflow/new/Regexp.qll index e1f824b2935c..1f13b3847d7b 100644 --- a/python/ql/lib/semmle/python/dataflow/new/Regexp.qll +++ b/python/ql/lib/semmle/python/dataflow/new/Regexp.qll @@ -7,20 +7,6 @@ private import semmle.python.regex private import semmle.python.dataflow.new.DataFlow private import semmle.python.regexp.internal.RegExpTracking -/** - * Provides utility predicates related to regular expressions. - */ -deprecated module RegExpPatterns { - /** - * Gets a pattern that matches common top-level domain names in lower case. - * DEPRECATED: use the similarly named predicate from `HostnameRegex` from the `regex` pack instead. - */ - deprecated string getACommonTld() { - // according to ranking by http://google.com/search?q=site:.<> - result = "(?:com|org|edu|gov|uk|net|io)(?![a-z0-9])" - } -} - /** * A node whose value may flow to a position where it is interpreted * as a part of a regular expression. diff --git a/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll b/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll index 705c4476fb13..c12358f6db91 100644 --- a/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll +++ b/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll @@ -89,7 +89,7 @@ private module SensitiveDataModeling { */ DataFlow::Node sensitiveLookupStringConst(SensitiveDataClassification classification) { // Note: If this is implemented with type-tracking, we will get cross-talk as - // illustrated in python/ql/test/experimental/dataflow/sensitive-data/test.py + // illustrated in python/ql/test/library-tests/dataflow/sensitive-data/test.py exists(DataFlow::LocalSourceNode source | source.asExpr().(StringLiteral).getText() = sensitiveString(classification) and source.flowsTo(result) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index 9b9caf28ad3c..4192241d619a 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -638,7 +638,7 @@ newtype TContent = // name = any(AccessPathToken a).getAnArgument("Attribute") // instead we use a qltest to alert if we write a new summary in QL that uses an // attribute -- see - // python/ql/test/experimental/dataflow/summaries-checks/missing-attribute-content.ql + // python/ql/test/library-tests/dataflow/summaries-checks/missing-attribute-content.ql attr in ["re", "string", "pattern"] or // diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/empty.model.yml b/python/ql/lib/semmle/python/frameworks/data/internal/empty.model.yml index 49a1f01983f2..ea9b9fce546b 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/empty.model.yml +++ b/python/ql/lib/semmle/python/frameworks/data/internal/empty.model.yml @@ -1,5 +1,6 @@ extensions: - # Contribute empty data sets to avoid errors about an undefined extensionals + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about undefined extensionals. - addsTo: pack: codeql/python-all extensible: sourceModel diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index ef271f0654d0..96a2c3cc7dba 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.15 + +No user-facing changes. + ## 0.9.14 No user-facing changes. diff --git a/python/ql/src/Security/CWE-020/HostnameRegexpShared.qll b/python/ql/src/Security/CWE-020/HostnameRegexpShared.qll deleted file mode 100644 index d15714d406aa..000000000000 --- a/python/ql/src/Security/CWE-020/HostnameRegexpShared.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Provides predicates for reasoning about regular expressions - * that match URLs and hostname patterns. - */ - -// HostnameRegexp should be used directly from the shared regex pack, and not from this file. -deprecated private import semmle.python.security.regexp.HostnameRegex as Dep -import Dep diff --git a/python/ql/src/change-notes/released/0.9.15.md b/python/ql/src/change-notes/released/0.9.15.md new file mode 100644 index 000000000000..95252948c0d4 --- /dev/null +++ b/python/ql/src/change-notes/released/0.9.15.md @@ -0,0 +1,3 @@ +## 0.9.15 + +No user-facing changes. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index e4e3bab02833..4896915c2157 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.9.14 +lastReleaseVersion: 0.9.15 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index ce6edd4ef709..4d4432b7fc21 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.9.15-dev +version: 0.9.16-dev groups: - python - queries diff --git a/python/ql/test/experimental/dataflow/TestUtil/DataflowQueryTest.qll b/python/ql/test/TestUtilities/dataflow/DataflowQueryTest.qll similarity index 100% rename from python/ql/test/experimental/dataflow/TestUtil/DataflowQueryTest.qll rename to python/ql/test/TestUtilities/dataflow/DataflowQueryTest.qll diff --git a/python/ql/test/experimental/dataflow/TestUtil/FlowTest.qll b/python/ql/test/TestUtilities/dataflow/FlowTest.qll similarity index 100% rename from python/ql/test/experimental/dataflow/TestUtil/FlowTest.qll rename to python/ql/test/TestUtilities/dataflow/FlowTest.qll diff --git a/python/ql/test/experimental/dataflow/TestUtil/LocalFlowStepTest.qll b/python/ql/test/TestUtilities/dataflow/LocalFlowStepTest.qll similarity index 100% rename from python/ql/test/experimental/dataflow/TestUtil/LocalFlowStepTest.qll rename to python/ql/test/TestUtilities/dataflow/LocalFlowStepTest.qll diff --git a/python/ql/test/experimental/dataflow/TestUtil/MaximalFlowTest.qll b/python/ql/test/TestUtilities/dataflow/MaximalFlowTest.qll similarity index 100% rename from python/ql/test/experimental/dataflow/TestUtil/MaximalFlowTest.qll rename to python/ql/test/TestUtilities/dataflow/MaximalFlowTest.qll diff --git a/python/ql/test/experimental/dataflow/TestUtil/NormalDataflowTest.qll b/python/ql/test/TestUtilities/dataflow/NormalDataflowTest.qll similarity index 93% rename from python/ql/test/experimental/dataflow/TestUtil/NormalDataflowTest.qll rename to python/ql/test/TestUtilities/dataflow/NormalDataflowTest.qll index 51516faac8af..b89738b100ed 100644 --- a/python/ql/test/experimental/dataflow/TestUtil/NormalDataflowTest.qll +++ b/python/ql/test/TestUtilities/dataflow/NormalDataflowTest.qll @@ -1,6 +1,6 @@ import python -import experimental.dataflow.TestUtil.FlowTest -import experimental.dataflow.testConfig +import TestUtilities.dataflow.FlowTest +import TestUtilities.dataflow.testConfig private import semmle.python.dataflow.new.internal.PrintNode module DataFlowTest implements FlowTestSig { diff --git a/python/ql/test/experimental/dataflow/TestUtil/NormalTaintTrackingTest.qll b/python/ql/test/TestUtilities/dataflow/NormalTaintTrackingTest.qll similarity index 92% rename from python/ql/test/experimental/dataflow/TestUtil/NormalTaintTrackingTest.qll rename to python/ql/test/TestUtilities/dataflow/NormalTaintTrackingTest.qll index 23262dfb3e57..e63e962df4d5 100644 --- a/python/ql/test/experimental/dataflow/TestUtil/NormalTaintTrackingTest.qll +++ b/python/ql/test/TestUtilities/dataflow/NormalTaintTrackingTest.qll @@ -1,6 +1,6 @@ import python -import experimental.dataflow.TestUtil.FlowTest -import experimental.dataflow.testTaintConfig +import TestUtilities.dataflow.FlowTest +import TestUtilities.dataflow.testTaintConfig private import semmle.python.dataflow.new.internal.PrintNode module DataFlowTest implements FlowTestSig { diff --git a/python/ql/test/experimental/dataflow/TestUtil/RoutingTest.qll b/python/ql/test/TestUtilities/dataflow/RoutingTest.qll similarity index 100% rename from python/ql/test/experimental/dataflow/TestUtil/RoutingTest.qll rename to python/ql/test/TestUtilities/dataflow/RoutingTest.qll diff --git a/python/ql/test/experimental/dataflow/TestUtil/UnresolvedCalls.qll b/python/ql/test/TestUtilities/dataflow/UnresolvedCalls.qll similarity index 100% rename from python/ql/test/experimental/dataflow/TestUtil/UnresolvedCalls.qll rename to python/ql/test/TestUtilities/dataflow/UnresolvedCalls.qll diff --git a/python/ql/test/experimental/dataflow/callGraphConfig.qll b/python/ql/test/TestUtilities/dataflow/callGraphConfig.qll similarity index 100% rename from python/ql/test/experimental/dataflow/callGraphConfig.qll rename to python/ql/test/TestUtilities/dataflow/callGraphConfig.qll diff --git a/python/ql/test/experimental/dataflow/testConfig.qll b/python/ql/test/TestUtilities/dataflow/testConfig.qll similarity index 100% rename from python/ql/test/experimental/dataflow/testConfig.qll rename to python/ql/test/TestUtilities/dataflow/testConfig.qll diff --git a/python/ql/test/experimental/dataflow/testTaintConfig.qll b/python/ql/test/TestUtilities/dataflow/testTaintConfig.qll similarity index 100% rename from python/ql/test/experimental/dataflow/testTaintConfig.qll rename to python/ql/test/TestUtilities/dataflow/testTaintConfig.qll diff --git a/python/ql/test/experimental/dataflow/basic/localFlowStepTest.ql b/python/ql/test/experimental/dataflow/basic/localFlowStepTest.ql deleted file mode 100644 index 6dca01901569..000000000000 --- a/python/ql/test/experimental/dataflow/basic/localFlowStepTest.ql +++ /dev/null @@ -1 +0,0 @@ -import experimental.dataflow.TestUtil.LocalFlowStepTest diff --git a/python/ql/test/experimental/dataflow/basic/maximalFlowTest.ql b/python/ql/test/experimental/dataflow/basic/maximalFlowTest.ql deleted file mode 100644 index 618dae382f1b..000000000000 --- a/python/ql/test/experimental/dataflow/basic/maximalFlowTest.ql +++ /dev/null @@ -1 +0,0 @@ -import experimental.dataflow.TestUtil.MaximalFlowTest diff --git a/python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.ql b/python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.ql deleted file mode 100644 index 3ee344d0b871..000000000000 --- a/python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.ql +++ /dev/null @@ -1,2 +0,0 @@ -import python -import experimental.dataflow.TestUtil.NormalDataflowTest diff --git a/python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.ql b/python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.ql deleted file mode 100644 index 3ee344d0b871..000000000000 --- a/python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.ql +++ /dev/null @@ -1,2 +0,0 @@ -import python -import experimental.dataflow.TestUtil.NormalDataflowTest diff --git a/python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.ql b/python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.ql deleted file mode 100644 index 3ee344d0b871..000000000000 --- a/python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.ql +++ /dev/null @@ -1,2 +0,0 @@ -import python -import experimental.dataflow.TestUtil.NormalDataflowTest diff --git a/python/ql/test/experimental/dataflow/match/NormalDataflowTest.ql b/python/ql/test/experimental/dataflow/match/NormalDataflowTest.ql deleted file mode 100644 index 3ee344d0b871..000000000000 --- a/python/ql/test/experimental/dataflow/match/NormalDataflowTest.ql +++ /dev/null @@ -1,2 +0,0 @@ -import python -import experimental.dataflow.TestUtil.NormalDataflowTest diff --git a/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ql b/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ql deleted file mode 100644 index 3ee344d0b871..000000000000 --- a/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ql +++ /dev/null @@ -1,2 +0,0 @@ -import python -import experimental.dataflow.TestUtil.NormalDataflowTest diff --git a/python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.ql b/python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.ql deleted file mode 100644 index afb44b6b2edb..000000000000 --- a/python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.ql +++ /dev/null @@ -1,3 +0,0 @@ -import python -private import TestSummaries -import experimental.dataflow.TestUtil.NormalTaintTrackingTest diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql b/python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql deleted file mode 100644 index 3ee344d0b871..000000000000 --- a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql +++ /dev/null @@ -1,2 +0,0 @@ -import python -import experimental.dataflow.TestUtil.NormalDataflowTest diff --git a/python/ql/test/experimental/meta/debug/dataflowTestPaths.ql b/python/ql/test/experimental/meta/debug/dataflowTestPaths.ql index 78d783033f57..4c0ab8986868 100644 --- a/python/ql/test/experimental/meta/debug/dataflowTestPaths.ql +++ b/python/ql/test/experimental/meta/debug/dataflowTestPaths.ql @@ -9,7 +9,7 @@ // 3. if necessary, look at partial paths by (un)commenting appropriate lines import python import semmle.python.dataflow.new.DataFlow -import experimental.dataflow.testConfig +import TestUtilities.dataflow.testConfig module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.ql b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.ql index ed7d650f536d..9cbf6dd6ad8a 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.ql +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python -import experimental.dataflow.TestUtil.DataflowQueryTest +import TestUtilities.dataflow.DataflowQueryTest import experimental.Security.UnsafeUnpackQuery import FromTaintTrackingConfig diff --git a/python/ql/test/experimental/query-tests/Security/CWE-409/DataflowQueryTest.ql b/python/ql/test/experimental/query-tests/Security/CWE-409/DataflowQueryTest.ql index 24a2c302b989..c1724c29d2cf 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-409/DataflowQueryTest.ql +++ b/python/ql/test/experimental/query-tests/Security/CWE-409/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python -import experimental.dataflow.TestUtil.DataflowQueryTest +import TestUtilities.dataflow.DataflowQueryTest import experimental.semmle.python.security.DecompressionBomb import FromTaintTrackingConfig diff --git a/python/ql/test/experimental/dataflow/basic/allFlowsConfig.qll b/python/ql/test/library-tests/dataflow/basic/allFlowsConfig.qll similarity index 100% rename from python/ql/test/experimental/dataflow/basic/allFlowsConfig.qll rename to python/ql/test/library-tests/dataflow/basic/allFlowsConfig.qll diff --git a/python/ql/test/experimental/dataflow/basic/callGraph.expected b/python/ql/test/library-tests/dataflow/basic/callGraph.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/callGraph.expected rename to python/ql/test/library-tests/dataflow/basic/callGraph.expected diff --git a/python/ql/test/experimental/dataflow/basic/callGraph.ql b/python/ql/test/library-tests/dataflow/basic/callGraph.ql similarity index 83% rename from python/ql/test/experimental/dataflow/basic/callGraph.ql rename to python/ql/test/library-tests/dataflow/basic/callGraph.ql index 98416af1d0f3..f0e28c33dc6a 100644 --- a/python/ql/test/experimental/dataflow/basic/callGraph.ql +++ b/python/ql/test/library-tests/dataflow/basic/callGraph.ql @@ -1,4 +1,4 @@ -import experimental.dataflow.callGraphConfig +import TestUtilities.dataflow.callGraphConfig from DataFlow::Node source, DataFlow::Node sink where diff --git a/python/ql/test/experimental/dataflow/basic/callGraphSinks.expected b/python/ql/test/library-tests/dataflow/basic/callGraphSinks.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/callGraphSinks.expected rename to python/ql/test/library-tests/dataflow/basic/callGraphSinks.expected diff --git a/python/ql/test/experimental/dataflow/basic/callGraphSinks.ql b/python/ql/test/library-tests/dataflow/basic/callGraphSinks.ql similarity index 74% rename from python/ql/test/experimental/dataflow/basic/callGraphSinks.ql rename to python/ql/test/library-tests/dataflow/basic/callGraphSinks.ql index 7cdf3cd94d17..472d6ccaa374 100644 --- a/python/ql/test/experimental/dataflow/basic/callGraphSinks.ql +++ b/python/ql/test/library-tests/dataflow/basic/callGraphSinks.ql @@ -1,4 +1,4 @@ -import experimental.dataflow.callGraphConfig +import TestUtilities.dataflow.callGraphConfig from DataFlow::Node sink where diff --git a/python/ql/test/experimental/dataflow/basic/callGraphSources.expected b/python/ql/test/library-tests/dataflow/basic/callGraphSources.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/callGraphSources.expected rename to python/ql/test/library-tests/dataflow/basic/callGraphSources.expected diff --git a/python/ql/test/experimental/dataflow/basic/callGraphSources.ql b/python/ql/test/library-tests/dataflow/basic/callGraphSources.ql similarity index 76% rename from python/ql/test/experimental/dataflow/basic/callGraphSources.ql rename to python/ql/test/library-tests/dataflow/basic/callGraphSources.ql index 8a0229c8f20e..05b26caf3c07 100644 --- a/python/ql/test/experimental/dataflow/basic/callGraphSources.ql +++ b/python/ql/test/library-tests/dataflow/basic/callGraphSources.ql @@ -1,4 +1,4 @@ -import experimental.dataflow.callGraphConfig +import TestUtilities.dataflow.callGraphConfig from DataFlow::Node source where diff --git a/python/ql/test/experimental/dataflow/basic/global.expected b/python/ql/test/library-tests/dataflow/basic/global.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/global.expected rename to python/ql/test/library-tests/dataflow/basic/global.expected diff --git a/python/ql/test/experimental/dataflow/basic/global.ql b/python/ql/test/library-tests/dataflow/basic/global.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/global.ql rename to python/ql/test/library-tests/dataflow/basic/global.ql diff --git a/python/ql/test/experimental/dataflow/basic/globalStep.expected b/python/ql/test/library-tests/dataflow/basic/globalStep.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/globalStep.expected rename to python/ql/test/library-tests/dataflow/basic/globalStep.expected diff --git a/python/ql/test/experimental/dataflow/basic/globalStep.ql b/python/ql/test/library-tests/dataflow/basic/globalStep.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/globalStep.ql rename to python/ql/test/library-tests/dataflow/basic/globalStep.ql diff --git a/python/ql/test/experimental/dataflow/basic/local.expected b/python/ql/test/library-tests/dataflow/basic/local.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/local.expected rename to python/ql/test/library-tests/dataflow/basic/local.expected diff --git a/python/ql/test/experimental/dataflow/basic/local.ql b/python/ql/test/library-tests/dataflow/basic/local.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/local.ql rename to python/ql/test/library-tests/dataflow/basic/local.ql diff --git a/python/ql/test/experimental/dataflow/basic/localFlowStepTest.expected b/python/ql/test/library-tests/dataflow/basic/localFlowStepTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/localFlowStepTest.expected rename to python/ql/test/library-tests/dataflow/basic/localFlowStepTest.expected diff --git a/python/ql/test/library-tests/dataflow/basic/localFlowStepTest.ql b/python/ql/test/library-tests/dataflow/basic/localFlowStepTest.ql new file mode 100644 index 000000000000..881592eeaeb9 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/basic/localFlowStepTest.ql @@ -0,0 +1 @@ +import TestUtilities.dataflow.LocalFlowStepTest diff --git a/python/ql/test/experimental/dataflow/basic/localStep.expected b/python/ql/test/library-tests/dataflow/basic/localStep.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/localStep.expected rename to python/ql/test/library-tests/dataflow/basic/localStep.expected diff --git a/python/ql/test/experimental/dataflow/basic/localStep.ql b/python/ql/test/library-tests/dataflow/basic/localStep.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/localStep.ql rename to python/ql/test/library-tests/dataflow/basic/localStep.ql diff --git a/python/ql/test/experimental/dataflow/basic/maximalFlowTest.expected b/python/ql/test/library-tests/dataflow/basic/maximalFlowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/maximalFlowTest.expected rename to python/ql/test/library-tests/dataflow/basic/maximalFlowTest.expected diff --git a/python/ql/test/library-tests/dataflow/basic/maximalFlowTest.ql b/python/ql/test/library-tests/dataflow/basic/maximalFlowTest.ql new file mode 100644 index 000000000000..64867eb89da5 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/basic/maximalFlowTest.ql @@ -0,0 +1 @@ +import TestUtilities.dataflow.MaximalFlowTest diff --git a/python/ql/test/experimental/dataflow/basic/maximalFlows.expected b/python/ql/test/library-tests/dataflow/basic/maximalFlows.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/maximalFlows.expected rename to python/ql/test/library-tests/dataflow/basic/maximalFlows.expected diff --git a/python/ql/test/experimental/dataflow/basic/maximalFlows.ql b/python/ql/test/library-tests/dataflow/basic/maximalFlows.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/maximalFlows.ql rename to python/ql/test/library-tests/dataflow/basic/maximalFlows.ql diff --git a/python/ql/test/experimental/dataflow/basic/maximalFlowsConfig.qll b/python/ql/test/library-tests/dataflow/basic/maximalFlowsConfig.qll similarity index 100% rename from python/ql/test/experimental/dataflow/basic/maximalFlowsConfig.qll rename to python/ql/test/library-tests/dataflow/basic/maximalFlowsConfig.qll diff --git a/python/ql/test/experimental/dataflow/basic/sinks.expected b/python/ql/test/library-tests/dataflow/basic/sinks.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/sinks.expected rename to python/ql/test/library-tests/dataflow/basic/sinks.expected diff --git a/python/ql/test/experimental/dataflow/basic/sinks.ql b/python/ql/test/library-tests/dataflow/basic/sinks.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/sinks.ql rename to python/ql/test/library-tests/dataflow/basic/sinks.ql diff --git a/python/ql/test/experimental/dataflow/basic/sources.expected b/python/ql/test/library-tests/dataflow/basic/sources.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/sources.expected rename to python/ql/test/library-tests/dataflow/basic/sources.expected diff --git a/python/ql/test/experimental/dataflow/basic/sources.ql b/python/ql/test/library-tests/dataflow/basic/sources.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/sources.ql rename to python/ql/test/library-tests/dataflow/basic/sources.ql diff --git a/python/ql/test/experimental/dataflow/basic/test.py b/python/ql/test/library-tests/dataflow/basic/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/basic/test.py rename to python/ql/test/library-tests/dataflow/basic/test.py diff --git a/python/ql/test/experimental/dataflow/callgraph_crosstalk/Arguments.expected b/python/ql/test/library-tests/dataflow/callgraph_crosstalk/Arguments.expected similarity index 100% rename from python/ql/test/experimental/dataflow/callgraph_crosstalk/Arguments.expected rename to python/ql/test/library-tests/dataflow/callgraph_crosstalk/Arguments.expected diff --git a/python/ql/test/experimental/dataflow/callgraph_crosstalk/Arguments.ql b/python/ql/test/library-tests/dataflow/callgraph_crosstalk/Arguments.ql similarity index 100% rename from python/ql/test/experimental/dataflow/callgraph_crosstalk/Arguments.ql rename to python/ql/test/library-tests/dataflow/callgraph_crosstalk/Arguments.ql diff --git a/python/ql/test/experimental/dataflow/callgraph_crosstalk/options b/python/ql/test/library-tests/dataflow/callgraph_crosstalk/options similarity index 100% rename from python/ql/test/experimental/dataflow/callgraph_crosstalk/options rename to python/ql/test/library-tests/dataflow/callgraph_crosstalk/options diff --git a/python/ql/test/experimental/dataflow/callgraph_crosstalk/test.py b/python/ql/test/library-tests/dataflow/callgraph_crosstalk/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/callgraph_crosstalk/test.py rename to python/ql/test/library-tests/dataflow/callgraph_crosstalk/test.py diff --git a/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.expected b/python/ql/test/library-tests/dataflow/calls/DataFlowCallTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/calls/DataFlowCallTest.expected rename to python/ql/test/library-tests/dataflow/calls/DataFlowCallTest.expected diff --git a/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.ql b/python/ql/test/library-tests/dataflow/calls/DataFlowCallTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/calls/DataFlowCallTest.ql rename to python/ql/test/library-tests/dataflow/calls/DataFlowCallTest.ql diff --git a/python/ql/test/experimental/dataflow/calls/new_cls_param.py b/python/ql/test/library-tests/dataflow/calls/new_cls_param.py similarity index 100% rename from python/ql/test/experimental/dataflow/calls/new_cls_param.py rename to python/ql/test/library-tests/dataflow/calls/new_cls_param.py diff --git a/python/ql/test/experimental/dataflow/calls/test.py b/python/ql/test/library-tests/dataflow/calls/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/calls/test.py rename to python/ql/test/library-tests/dataflow/calls/test.py diff --git a/python/ql/test/experimental/dataflow/consistency/class_scope.py b/python/ql/test/library-tests/dataflow/consistency/class_scope.py similarity index 100% rename from python/ql/test/experimental/dataflow/consistency/class_scope.py rename to python/ql/test/library-tests/dataflow/consistency/class_scope.py diff --git a/python/ql/test/experimental/dataflow/summaries-checks/invalid-spec.expected b/python/ql/test/library-tests/dataflow/consistency/modeling-consistency.expected similarity index 100% rename from python/ql/test/experimental/dataflow/summaries-checks/invalid-spec.expected rename to python/ql/test/library-tests/dataflow/consistency/modeling-consistency.expected diff --git a/python/ql/test/experimental/dataflow/consistency/modeling-consistency.ql b/python/ql/test/library-tests/dataflow/consistency/modeling-consistency.ql similarity index 100% rename from python/ql/test/experimental/dataflow/consistency/modeling-consistency.ql rename to python/ql/test/library-tests/dataflow/consistency/modeling-consistency.ql diff --git a/python/ql/test/experimental/dataflow/consistency/module.py b/python/ql/test/library-tests/dataflow/consistency/module.py similarity index 100% rename from python/ql/test/experimental/dataflow/consistency/module.py rename to python/ql/test/library-tests/dataflow/consistency/module.py diff --git a/python/ql/test/experimental/dataflow/consistency/test.py b/python/ql/test/library-tests/dataflow/consistency/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/consistency/test.py rename to python/ql/test/library-tests/dataflow/consistency/test.py diff --git a/python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.expected b/python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.expected rename to python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.expected diff --git a/python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.qlref b/python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.qlref similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.qlref rename to python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.qlref diff --git a/python/ql/test/experimental/dataflow/coverage-py2/classes.py b/python/ql/test/library-tests/dataflow/coverage-py2/classes.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py2/classes.py rename to python/ql/test/library-tests/dataflow/coverage-py2/classes.py diff --git a/python/ql/test/experimental/dataflow/coverage-py2/options b/python/ql/test/library-tests/dataflow/coverage-py2/options similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py2/options rename to python/ql/test/library-tests/dataflow/coverage-py2/options diff --git a/python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.expected b/python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.expected rename to python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.expected diff --git a/python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.qlref b/python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.qlref similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.qlref rename to python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.qlref diff --git a/python/ql/test/experimental/dataflow/coverage-py3/classes.py b/python/ql/test/library-tests/dataflow/coverage-py3/classes.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py3/classes.py rename to python/ql/test/library-tests/dataflow/coverage-py3/classes.py diff --git a/python/ql/test/experimental/dataflow/coverage-py3/options b/python/ql/test/library-tests/dataflow/coverage-py3/options similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py3/options rename to python/ql/test/library-tests/dataflow/coverage-py3/options diff --git a/python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.expected rename to python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.expected diff --git a/python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.ql new file mode 100644 index 000000000000..f7e55d12ded6 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.ql @@ -0,0 +1,2 @@ +import python +import TestUtilities.dataflow.NormalDataflowTest diff --git a/python/ql/test/experimental/dataflow/coverage/argumentPassing.py b/python/ql/test/library-tests/dataflow/coverage/argumentPassing.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/argumentPassing.py rename to python/ql/test/library-tests/dataflow/coverage/argumentPassing.py diff --git a/python/ql/test/experimental/dataflow/coverage/argumentPassing_bad_flow_test.py b/python/ql/test/library-tests/dataflow/coverage/argumentPassing_bad_flow_test.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/argumentPassing_bad_flow_test.py rename to python/ql/test/library-tests/dataflow/coverage/argumentPassing_bad_flow_test.py diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.expected b/python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.expected rename to python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.expected diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.ql b/python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.ql similarity index 98% rename from python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.ql rename to python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.ql index 1a4e860f555c..02b503824d48 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.ql +++ b/python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.ql @@ -1,7 +1,7 @@ import python import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPrivate -import experimental.dataflow.TestUtil.RoutingTest +import TestUtilities.dataflow.RoutingTest module Argument1RoutingTest implements RoutingTestSig { class Argument = Unit; diff --git a/python/ql/test/experimental/dataflow/coverage/classes.py b/python/ql/test/library-tests/dataflow/coverage/classes.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/classes.py rename to python/ql/test/library-tests/dataflow/coverage/classes.py diff --git a/python/ql/test/experimental/dataflow/coverage/datamodel.py b/python/ql/test/library-tests/dataflow/coverage/datamodel.py similarity index 99% rename from python/ql/test/experimental/dataflow/coverage/datamodel.py rename to python/ql/test/library-tests/dataflow/coverage/datamodel.py index 89d9b0a819a1..22111a0abbd1 100644 --- a/python/ql/test/experimental/dataflow/coverage/datamodel.py +++ b/python/ql/test/library-tests/dataflow/coverage/datamodel.py @@ -6,7 +6,7 @@ # A thorough covering of methods in that document is found in classes.py. # # Intended sources should be the variable `SOURCE` and intended sinks should be -# arguments to the function `SINK` (see python/ql/test/experimental/dataflow/testConfig.qll). +# arguments to the function `SINK` (see python/ql/test/library-tests/dataflow/testConfig.qll). import sys import os diff --git a/python/ql/test/experimental/dataflow/coverage/localFlow.expected b/python/ql/test/library-tests/dataflow/coverage/localFlow.expected similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/localFlow.expected rename to python/ql/test/library-tests/dataflow/coverage/localFlow.expected diff --git a/python/ql/test/experimental/dataflow/coverage/localFlow.ql b/python/ql/test/library-tests/dataflow/coverage/localFlow.ql similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/localFlow.ql rename to python/ql/test/library-tests/dataflow/coverage/localFlow.ql diff --git a/python/ql/test/experimental/dataflow/coverage/loops.py b/python/ql/test/library-tests/dataflow/coverage/loops.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/loops.py rename to python/ql/test/library-tests/dataflow/coverage/loops.py diff --git a/python/ql/test/experimental/dataflow/coverage/module_level.py b/python/ql/test/library-tests/dataflow/coverage/module_level.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/module_level.py rename to python/ql/test/library-tests/dataflow/coverage/module_level.py diff --git a/python/ql/test/experimental/dataflow/coverage/test.py b/python/ql/test/library-tests/dataflow/coverage/test.py similarity index 99% rename from python/ql/test/experimental/dataflow/coverage/test.py rename to python/ql/test/library-tests/dataflow/coverage/test.py index eb14fb1dd0b5..a2ea9cccd676 100644 --- a/python/ql/test/experimental/dataflow/coverage/test.py +++ b/python/ql/test/library-tests/dataflow/coverage/test.py @@ -2,7 +2,7 @@ # Headings refer to https://docs.python.org/3/reference/expressions.html, # and are selected whenever they incur dataflow. # Intended sources should be the variable `SOURCE` and intended sinks should be -# arguments to the function `SINK` (see python/ql/test/experimental/dataflow/testConfig.qll). +# arguments to the function `SINK` (see python/ql/test/library-tests/dataflow/testConfig.qll). # # Functions whose name ends with "_with_local_flow" will also be tested for local flow. # diff --git a/python/ql/test/experimental/dataflow/coverage/test_builtins.py b/python/ql/test/library-tests/dataflow/coverage/test_builtins.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/test_builtins.py rename to python/ql/test/library-tests/dataflow/coverage/test_builtins.py diff --git a/python/ql/test/experimental/dataflow/def-use-flow/def_use_counts.expected b/python/ql/test/library-tests/dataflow/def-use-flow/def_use_counts.expected similarity index 100% rename from python/ql/test/experimental/dataflow/def-use-flow/def_use_counts.expected rename to python/ql/test/library-tests/dataflow/def-use-flow/def_use_counts.expected diff --git a/python/ql/test/experimental/dataflow/def-use-flow/def_use_counts.ql b/python/ql/test/library-tests/dataflow/def-use-flow/def_use_counts.ql similarity index 100% rename from python/ql/test/experimental/dataflow/def-use-flow/def_use_counts.ql rename to python/ql/test/library-tests/dataflow/def-use-flow/def_use_counts.ql diff --git a/python/ql/test/experimental/dataflow/def-use-flow/def_use_flow.py b/python/ql/test/library-tests/dataflow/def-use-flow/def_use_flow.py similarity index 100% rename from python/ql/test/experimental/dataflow/def-use-flow/def_use_flow.py rename to python/ql/test/library-tests/dataflow/def-use-flow/def_use_flow.py diff --git a/python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.expected b/python/ql/test/library-tests/dataflow/enclosing-callable/EnclosingCallable.expected similarity index 100% rename from python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.expected rename to python/ql/test/library-tests/dataflow/enclosing-callable/EnclosingCallable.expected diff --git a/python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.ql b/python/ql/test/library-tests/dataflow/enclosing-callable/EnclosingCallable.ql similarity index 100% rename from python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.ql rename to python/ql/test/library-tests/dataflow/enclosing-callable/EnclosingCallable.ql diff --git a/python/ql/test/experimental/dataflow/enclosing-callable/class_example.py b/python/ql/test/library-tests/dataflow/enclosing-callable/class_example.py similarity index 100% rename from python/ql/test/experimental/dataflow/enclosing-callable/class_example.py rename to python/ql/test/library-tests/dataflow/enclosing-callable/class_example.py diff --git a/python/ql/test/experimental/dataflow/enclosing-callable/generator.py b/python/ql/test/library-tests/dataflow/enclosing-callable/generator.py similarity index 100% rename from python/ql/test/experimental/dataflow/enclosing-callable/generator.py rename to python/ql/test/library-tests/dataflow/enclosing-callable/generator.py diff --git a/python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.expected rename to python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.expected diff --git a/python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.ql new file mode 100644 index 000000000000..f7e55d12ded6 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.ql @@ -0,0 +1,2 @@ +import python +import TestUtilities.dataflow.NormalDataflowTest diff --git a/python/ql/test/experimental/dataflow/exceptions/test.py b/python/ql/test/library-tests/dataflow/exceptions/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/exceptions/test.py rename to python/ql/test/library-tests/dataflow/exceptions/test.py diff --git a/python/ql/test/experimental/dataflow/exceptions/test_group.py b/python/ql/test/library-tests/dataflow/exceptions/test_group.py similarity index 100% rename from python/ql/test/experimental/dataflow/exceptions/test_group.py rename to python/ql/test/library-tests/dataflow/exceptions/test_group.py diff --git a/python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.expected rename to python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.expected diff --git a/python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.ql new file mode 100644 index 000000000000..f7e55d12ded6 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.ql @@ -0,0 +1,2 @@ +import python +import TestUtilities.dataflow.NormalDataflowTest diff --git a/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.expected b/python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.expected similarity index 100% rename from python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.expected rename to python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.expected diff --git a/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.ql b/python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.ql similarity index 89% rename from python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.ql rename to python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.ql index 3c7498bd6518..299339dacf80 100644 --- a/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.ql +++ b/python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.ql @@ -1,5 +1,5 @@ import python -import experimental.dataflow.TestUtil.UnresolvedCalls +import TestUtilities.dataflow.UnresolvedCalls private import semmle.python.dataflow.new.DataFlow module IgnoreDictMethod implements UnresolvedCallExpectationsSig { diff --git a/python/ql/test/experimental/dataflow/fieldflow/options b/python/ql/test/library-tests/dataflow/fieldflow/options similarity index 100% rename from python/ql/test/experimental/dataflow/fieldflow/options rename to python/ql/test/library-tests/dataflow/fieldflow/options diff --git a/python/ql/test/experimental/dataflow/fieldflow/test.py b/python/ql/test/library-tests/dataflow/fieldflow/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/fieldflow/test.py rename to python/ql/test/library-tests/dataflow/fieldflow/test.py diff --git a/python/ql/test/experimental/dataflow/fieldflow/test_dict.py b/python/ql/test/library-tests/dataflow/fieldflow/test_dict.py similarity index 100% rename from python/ql/test/experimental/dataflow/fieldflow/test_dict.py rename to python/ql/test/library-tests/dataflow/fieldflow/test_dict.py diff --git a/python/ql/test/experimental/dataflow/fieldflow/test_global.py b/python/ql/test/library-tests/dataflow/fieldflow/test_global.py similarity index 100% rename from python/ql/test/experimental/dataflow/fieldflow/test_global.py rename to python/ql/test/library-tests/dataflow/fieldflow/test_global.py diff --git a/python/ql/test/experimental/dataflow/global-flow/accesses.expected b/python/ql/test/library-tests/dataflow/global-flow/accesses.expected similarity index 100% rename from python/ql/test/experimental/dataflow/global-flow/accesses.expected rename to python/ql/test/library-tests/dataflow/global-flow/accesses.expected diff --git a/python/ql/test/experimental/dataflow/global-flow/accesses.ql b/python/ql/test/library-tests/dataflow/global-flow/accesses.ql similarity index 100% rename from python/ql/test/experimental/dataflow/global-flow/accesses.ql rename to python/ql/test/library-tests/dataflow/global-flow/accesses.ql diff --git a/python/ql/test/experimental/dataflow/global-flow/known.py b/python/ql/test/library-tests/dataflow/global-flow/known.py similarity index 100% rename from python/ql/test/experimental/dataflow/global-flow/known.py rename to python/ql/test/library-tests/dataflow/global-flow/known.py diff --git a/python/ql/test/experimental/dataflow/global-flow/test.py b/python/ql/test/library-tests/dataflow/global-flow/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/global-flow/test.py rename to python/ql/test/library-tests/dataflow/global-flow/test.py diff --git a/python/ql/test/experimental/dataflow/import-star/deux.py b/python/ql/test/library-tests/dataflow/import-star/deux.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/deux.py rename to python/ql/test/library-tests/dataflow/import-star/deux.py diff --git a/python/ql/test/experimental/dataflow/import-star/global.expected b/python/ql/test/library-tests/dataflow/import-star/global.expected similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/global.expected rename to python/ql/test/library-tests/dataflow/import-star/global.expected diff --git a/python/ql/test/experimental/dataflow/import-star/global.ql b/python/ql/test/library-tests/dataflow/import-star/global.ql similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/global.ql rename to python/ql/test/library-tests/dataflow/import-star/global.ql diff --git a/python/ql/test/experimental/dataflow/import-star/one.py b/python/ql/test/library-tests/dataflow/import-star/one.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/one.py rename to python/ql/test/library-tests/dataflow/import-star/one.py diff --git a/python/ql/test/experimental/dataflow/import-star/test1.py b/python/ql/test/library-tests/dataflow/import-star/test1.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/test1.py rename to python/ql/test/library-tests/dataflow/import-star/test1.py diff --git a/python/ql/test/experimental/dataflow/import-star/test2.py b/python/ql/test/library-tests/dataflow/import-star/test2.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/test2.py rename to python/ql/test/library-tests/dataflow/import-star/test2.py diff --git a/python/ql/test/experimental/dataflow/import-star/test3.py b/python/ql/test/library-tests/dataflow/import-star/test3.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/test3.py rename to python/ql/test/library-tests/dataflow/import-star/test3.py diff --git a/python/ql/test/experimental/dataflow/import-star/three.py b/python/ql/test/library-tests/dataflow/import-star/three.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/three.py rename to python/ql/test/library-tests/dataflow/import-star/three.py diff --git a/python/ql/test/experimental/dataflow/import-star/trois.py b/python/ql/test/library-tests/dataflow/import-star/trois.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/trois.py rename to python/ql/test/library-tests/dataflow/import-star/trois.py diff --git a/python/ql/test/experimental/dataflow/import-star/two.py b/python/ql/test/library-tests/dataflow/import-star/two.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/two.py rename to python/ql/test/library-tests/dataflow/import-star/two.py diff --git a/python/ql/test/experimental/dataflow/import-star/un.py b/python/ql/test/library-tests/dataflow/import-star/un.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/un.py rename to python/ql/test/library-tests/dataflow/import-star/un.py diff --git a/python/ql/test/experimental/dataflow/match/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/match/NormalDataflowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/match/NormalDataflowTest.expected rename to python/ql/test/library-tests/dataflow/match/NormalDataflowTest.expected diff --git a/python/ql/test/library-tests/dataflow/match/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/match/NormalDataflowTest.ql new file mode 100644 index 000000000000..f7e55d12ded6 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/match/NormalDataflowTest.ql @@ -0,0 +1,2 @@ +import python +import TestUtilities.dataflow.NormalDataflowTest diff --git a/python/ql/test/experimental/dataflow/match/test.py b/python/ql/test/library-tests/dataflow/match/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/match/test.py rename to python/ql/test/library-tests/dataflow/match/test.py diff --git a/python/ql/test/experimental/dataflow/method-calls/test.expected b/python/ql/test/library-tests/dataflow/method-calls/test.expected similarity index 100% rename from python/ql/test/experimental/dataflow/method-calls/test.expected rename to python/ql/test/library-tests/dataflow/method-calls/test.expected diff --git a/python/ql/test/experimental/dataflow/method-calls/test.py b/python/ql/test/library-tests/dataflow/method-calls/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/method-calls/test.py rename to python/ql/test/library-tests/dataflow/method-calls/test.py diff --git a/python/ql/test/experimental/dataflow/method-calls/test.ql b/python/ql/test/library-tests/dataflow/method-calls/test.ql similarity index 100% rename from python/ql/test/experimental/dataflow/method-calls/test.ql rename to python/ql/test/library-tests/dataflow/method-calls/test.ql diff --git a/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ext.yml b/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml similarity index 81% rename from python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ext.yml rename to python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml index 10fbd6df7448..0ed4ca9f172d 100644 --- a/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ext.yml +++ b/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml @@ -18,4 +18,7 @@ extensions: - ["foo", "Member[MS_spread]", "Argument[0]", "ReturnValue.TupleElement[0]", "value"] - ["foo", "Member[MS_spread]", "Argument[1]", "ReturnValue.TupleElement[1]", "value"] - ["foo", "Member[MS_spread_all]", "Argument[0]", "ReturnValue.TupleElement[0,1]", "value"] + - ["foo", "Member[MS_Class].Instance.Member[instance_method]", "Argument[self]", "ReturnValue.TupleElement[0]", "value"] + - ["foo", "Member[MS_Class].Instance.Member[instance_method]", "Argument[0]", "ReturnValue.TupleElement[1]", "value"] + - ["foo", "Member[MS_Class].Instance.Member[explicit_self]", "Argument[self:]", "ReturnValue", "value"] - ["json", "Member[MS_loads]", "Argument[0]", "ReturnValue", "taint"] diff --git a/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.expected rename to python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.expected diff --git a/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ext.yml b/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml similarity index 81% rename from python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ext.yml rename to python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml index 10fbd6df7448..0ed4ca9f172d 100644 --- a/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ext.yml +++ b/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml @@ -18,4 +18,7 @@ extensions: - ["foo", "Member[MS_spread]", "Argument[0]", "ReturnValue.TupleElement[0]", "value"] - ["foo", "Member[MS_spread]", "Argument[1]", "ReturnValue.TupleElement[1]", "value"] - ["foo", "Member[MS_spread_all]", "Argument[0]", "ReturnValue.TupleElement[0,1]", "value"] + - ["foo", "Member[MS_Class].Instance.Member[instance_method]", "Argument[self]", "ReturnValue.TupleElement[0]", "value"] + - ["foo", "Member[MS_Class].Instance.Member[instance_method]", "Argument[0]", "ReturnValue.TupleElement[1]", "value"] + - ["foo", "Member[MS_Class].Instance.Member[explicit_self]", "Argument[self:]", "ReturnValue", "value"] - ["json", "Member[MS_loads]", "Argument[0]", "ReturnValue", "taint"] diff --git a/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ql new file mode 100644 index 000000000000..f7e55d12ded6 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ql @@ -0,0 +1,2 @@ +import python +import TestUtilities.dataflow.NormalDataflowTest diff --git a/python/ql/test/experimental/dataflow/model-summaries/model_summaries.py b/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py similarity index 84% rename from python/ql/test/experimental/dataflow/model-summaries/model_summaries.py rename to python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py index 17f831f6ed12..46b3d6a4db85 100644 --- a/python/ql/test/experimental/dataflow/model-summaries/model_summaries.py +++ b/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py @@ -122,6 +122,24 @@ def explicit_identity(x): SINK(a) # $ flow="SOURCE, l:-1 -> a" SINK(b) # $ flow="SOURCE, l:-2 -> b" +from foo import MS_Class + +c = MS_Class() +a, b = c.instance_method(SOURCE) +SINK_F(a) +SINK(b) # $ flow="SOURCE, l:-2 -> b" + +# Call the instance method on the class to expose the self argument +x, y = MS_Class.instance_method(SOURCE, NONSOURCE) +SINK(x) # $ MISSING: flow="SOURCE, l:-1 -> x" +SINK_F(y) + +# Call the instance method on the class to expose the self argument +# That self argument is not referenced by `Argument[self:]` +SINK_F(MS_Class.explicit_self(SOURCE)) +# Instead, `Argument[self:]` refers to a keyword argument named `self` (which you are allowed to do in Python) +SINK(c.explicit_self(self = SOURCE)) # $ flow="SOURCE -> c.explicit_self(..)" + # Modeled flow-summary is not value preserving from json import MS_loads as json_loads diff --git a/python/ql/test/experimental/dataflow/module-initialization/base.py b/python/ql/test/library-tests/dataflow/module-initialization/base.py similarity index 100% rename from python/ql/test/experimental/dataflow/module-initialization/base.py rename to python/ql/test/library-tests/dataflow/module-initialization/base.py diff --git a/python/ql/test/experimental/dataflow/module-initialization/localFlow.expected b/python/ql/test/library-tests/dataflow/module-initialization/localFlow.expected similarity index 100% rename from python/ql/test/experimental/dataflow/module-initialization/localFlow.expected rename to python/ql/test/library-tests/dataflow/module-initialization/localFlow.expected diff --git a/python/ql/test/experimental/dataflow/module-initialization/localFlow.ql b/python/ql/test/library-tests/dataflow/module-initialization/localFlow.ql similarity index 96% rename from python/ql/test/experimental/dataflow/module-initialization/localFlow.ql rename to python/ql/test/library-tests/dataflow/module-initialization/localFlow.ql index 22a0f88d77e9..36aa6e007a75 100644 --- a/python/ql/test/experimental/dataflow/module-initialization/localFlow.ql +++ b/python/ql/test/library-tests/dataflow/module-initialization/localFlow.ql @@ -1,6 +1,6 @@ // This query should be more focused yet. import python -import experimental.dataflow.TestUtil.FlowTest +import TestUtilities.dataflow.FlowTest private import semmle.python.dataflow.new.internal.PrintNode private import semmle.python.dataflow.new.internal.DataFlowPrivate as DP diff --git a/python/ql/test/experimental/dataflow/module-initialization/m1.py b/python/ql/test/library-tests/dataflow/module-initialization/m1.py similarity index 100% rename from python/ql/test/experimental/dataflow/module-initialization/m1.py rename to python/ql/test/library-tests/dataflow/module-initialization/m1.py diff --git a/python/ql/test/experimental/dataflow/module-initialization/multiphase.py b/python/ql/test/library-tests/dataflow/module-initialization/multiphase.py similarity index 100% rename from python/ql/test/experimental/dataflow/module-initialization/multiphase.py rename to python/ql/test/library-tests/dataflow/module-initialization/multiphase.py diff --git a/python/ql/test/experimental/dataflow/module-initialization/test.py b/python/ql/test/library-tests/dataflow/module-initialization/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/module-initialization/test.py rename to python/ql/test/library-tests/dataflow/module-initialization/test.py diff --git a/python/ql/test/experimental/dataflow/module-initialization/testOnce.py b/python/ql/test/library-tests/dataflow/module-initialization/testOnce.py similarity index 100% rename from python/ql/test/experimental/dataflow/module-initialization/testOnce.py rename to python/ql/test/library-tests/dataflow/module-initialization/testOnce.py diff --git a/python/ql/test/experimental/dataflow/options b/python/ql/test/library-tests/dataflow/options similarity index 100% rename from python/ql/test/experimental/dataflow/options rename to python/ql/test/library-tests/dataflow/options diff --git a/python/ql/test/experimental/dataflow/path-graph/PathNodes.expected b/python/ql/test/library-tests/dataflow/path-graph/PathNodes.expected similarity index 100% rename from python/ql/test/experimental/dataflow/path-graph/PathNodes.expected rename to python/ql/test/library-tests/dataflow/path-graph/PathNodes.expected diff --git a/python/ql/test/experimental/dataflow/path-graph/PathNodes.ql b/python/ql/test/library-tests/dataflow/path-graph/PathNodes.ql similarity index 96% rename from python/ql/test/experimental/dataflow/path-graph/PathNodes.ql rename to python/ql/test/library-tests/dataflow/path-graph/PathNodes.ql index c403d588d492..8100e999491c 100644 --- a/python/ql/test/experimental/dataflow/path-graph/PathNodes.ql +++ b/python/ql/test/library-tests/dataflow/path-graph/PathNodes.ql @@ -5,7 +5,7 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking -import experimental.dataflow.testConfig +import TestUtilities.dataflow.testConfig import TestUtilities.InlineExpectationsTest module TestTaintFlow = TaintTracking::Global; diff --git a/python/ql/test/experimental/dataflow/path-graph/test.py b/python/ql/test/library-tests/dataflow/path-graph/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/path-graph/test.py rename to python/ql/test/library-tests/dataflow/path-graph/test.py diff --git a/python/ql/test/experimental/dataflow/pep_328/__init__.py b/python/ql/test/library-tests/dataflow/pep_328/__init__.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/__init__.py rename to python/ql/test/library-tests/dataflow/pep_328/__init__.py diff --git a/python/ql/test/experimental/dataflow/pep_328/package/__init__.py b/python/ql/test/library-tests/dataflow/pep_328/package/__init__.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/package/__init__.py rename to python/ql/test/library-tests/dataflow/pep_328/package/__init__.py diff --git a/python/ql/test/experimental/dataflow/pep_328/package/moduleA.py b/python/ql/test/library-tests/dataflow/pep_328/package/moduleA.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/package/moduleA.py rename to python/ql/test/library-tests/dataflow/pep_328/package/moduleA.py diff --git a/python/ql/test/experimental/dataflow/pep_328/package/subpackage1/__init__.py b/python/ql/test/library-tests/dataflow/pep_328/package/subpackage1/__init__.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/package/subpackage1/__init__.py rename to python/ql/test/library-tests/dataflow/pep_328/package/subpackage1/__init__.py diff --git a/python/ql/test/experimental/dataflow/pep_328/package/subpackage1/moduleX.py b/python/ql/test/library-tests/dataflow/pep_328/package/subpackage1/moduleX.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/package/subpackage1/moduleX.py rename to python/ql/test/library-tests/dataflow/pep_328/package/subpackage1/moduleX.py diff --git a/python/ql/test/experimental/dataflow/pep_328/package/subpackage1/moduleY.py b/python/ql/test/library-tests/dataflow/pep_328/package/subpackage1/moduleY.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/package/subpackage1/moduleY.py rename to python/ql/test/library-tests/dataflow/pep_328/package/subpackage1/moduleY.py diff --git a/python/ql/test/experimental/dataflow/pep_328/package/subpackage2/__init__.py b/python/ql/test/library-tests/dataflow/pep_328/package/subpackage2/__init__.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/package/subpackage2/__init__.py rename to python/ql/test/library-tests/dataflow/pep_328/package/subpackage2/__init__.py diff --git a/python/ql/test/experimental/dataflow/pep_328/package/subpackage2/moduleZ.py b/python/ql/test/library-tests/dataflow/pep_328/package/subpackage2/moduleZ.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/package/subpackage2/moduleZ.py rename to python/ql/test/library-tests/dataflow/pep_328/package/subpackage2/moduleZ.py diff --git a/python/ql/test/experimental/dataflow/pep_328/start.py b/python/ql/test/library-tests/dataflow/pep_328/start.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/start.py rename to python/ql/test/library-tests/dataflow/pep_328/start.py diff --git a/python/ql/test/experimental/dataflow/qll-private-imports/README.md b/python/ql/test/library-tests/dataflow/qll-private-imports/README.md similarity index 100% rename from python/ql/test/experimental/dataflow/qll-private-imports/README.md rename to python/ql/test/library-tests/dataflow/qll-private-imports/README.md diff --git a/python/ql/test/experimental/dataflow/qll-private-imports/Test.expected b/python/ql/test/library-tests/dataflow/qll-private-imports/Test.expected similarity index 100% rename from python/ql/test/experimental/dataflow/qll-private-imports/Test.expected rename to python/ql/test/library-tests/dataflow/qll-private-imports/Test.expected diff --git a/python/ql/test/experimental/dataflow/qll-private-imports/Test.ql b/python/ql/test/library-tests/dataflow/qll-private-imports/Test.ql similarity index 100% rename from python/ql/test/experimental/dataflow/qll-private-imports/Test.ql rename to python/ql/test/library-tests/dataflow/qll-private-imports/Test.ql diff --git a/python/ql/test/experimental/dataflow/qll-private-imports/test.py b/python/ql/test/library-tests/dataflow/qll-private-imports/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/qll-private-imports/test.py rename to python/ql/test/library-tests/dataflow/qll-private-imports/test.py diff --git a/python/ql/test/experimental/dataflow/regression/custom_dataflow.expected b/python/ql/test/library-tests/dataflow/regression/custom_dataflow.expected similarity index 100% rename from python/ql/test/experimental/dataflow/regression/custom_dataflow.expected rename to python/ql/test/library-tests/dataflow/regression/custom_dataflow.expected diff --git a/python/ql/test/experimental/dataflow/regression/custom_dataflow.ql b/python/ql/test/library-tests/dataflow/regression/custom_dataflow.ql similarity index 100% rename from python/ql/test/experimental/dataflow/regression/custom_dataflow.ql rename to python/ql/test/library-tests/dataflow/regression/custom_dataflow.ql diff --git a/python/ql/test/experimental/dataflow/regression/dataflow.expected b/python/ql/test/library-tests/dataflow/regression/dataflow.expected similarity index 100% rename from python/ql/test/experimental/dataflow/regression/dataflow.expected rename to python/ql/test/library-tests/dataflow/regression/dataflow.expected diff --git a/python/ql/test/experimental/dataflow/regression/dataflow.ql b/python/ql/test/library-tests/dataflow/regression/dataflow.ql similarity index 88% rename from python/ql/test/experimental/dataflow/regression/dataflow.ql rename to python/ql/test/library-tests/dataflow/regression/dataflow.ql index 39763fa48143..27645d084b87 100644 --- a/python/ql/test/experimental/dataflow/regression/dataflow.ql +++ b/python/ql/test/library-tests/dataflow/regression/dataflow.ql @@ -6,7 +6,7 @@ */ import python -import experimental.dataflow.testConfig +import TestUtilities.dataflow.testConfig from DataFlow::Node source, DataFlow::Node sink where TestFlow::flow(source, sink) diff --git a/python/ql/test/experimental/dataflow/regression/module.py b/python/ql/test/library-tests/dataflow/regression/module.py similarity index 100% rename from python/ql/test/experimental/dataflow/regression/module.py rename to python/ql/test/library-tests/dataflow/regression/module.py diff --git a/python/ql/test/experimental/dataflow/regression/test.py b/python/ql/test/library-tests/dataflow/regression/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/regression/test.py rename to python/ql/test/library-tests/dataflow/regression/test.py diff --git a/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.expected b/python/ql/test/library-tests/dataflow/sensitive-data/TestSensitiveDataSources.expected similarity index 100% rename from python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.expected rename to python/ql/test/library-tests/dataflow/sensitive-data/TestSensitiveDataSources.expected diff --git a/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.ql b/python/ql/test/library-tests/dataflow/sensitive-data/TestSensitiveDataSources.ql similarity index 100% rename from python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.ql rename to python/ql/test/library-tests/dataflow/sensitive-data/TestSensitiveDataSources.ql diff --git a/python/ql/test/experimental/dataflow/sensitive-data/test.py b/python/ql/test/library-tests/dataflow/sensitive-data/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/sensitive-data/test.py rename to python/ql/test/library-tests/dataflow/sensitive-data/test.py diff --git a/python/ql/test/experimental/dataflow/strange-essaflow/test.py b/python/ql/test/library-tests/dataflow/strange-essaflow/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/strange-essaflow/test.py rename to python/ql/test/library-tests/dataflow/strange-essaflow/test.py diff --git a/python/ql/test/experimental/dataflow/strange-essaflow/testFlow.expected b/python/ql/test/library-tests/dataflow/strange-essaflow/testFlow.expected similarity index 100% rename from python/ql/test/experimental/dataflow/strange-essaflow/testFlow.expected rename to python/ql/test/library-tests/dataflow/strange-essaflow/testFlow.expected diff --git a/python/ql/test/experimental/dataflow/strange-essaflow/testFlow.ql b/python/ql/test/library-tests/dataflow/strange-essaflow/testFlow.ql similarity index 100% rename from python/ql/test/experimental/dataflow/strange-essaflow/testFlow.ql rename to python/ql/test/library-tests/dataflow/strange-essaflow/testFlow.ql diff --git a/python/ql/test/experimental/dataflow/summaries-checks/dummy.py b/python/ql/test/library-tests/dataflow/summaries-checks/dummy.py similarity index 100% rename from python/ql/test/experimental/dataflow/summaries-checks/dummy.py rename to python/ql/test/library-tests/dataflow/summaries-checks/dummy.py diff --git a/python/ql/test/experimental/dataflow/summaries-checks/missing-attribute-content.expected b/python/ql/test/library-tests/dataflow/summaries-checks/invalid-spec.expected similarity index 100% rename from python/ql/test/experimental/dataflow/summaries-checks/missing-attribute-content.expected rename to python/ql/test/library-tests/dataflow/summaries-checks/invalid-spec.expected diff --git a/python/ql/test/experimental/dataflow/summaries-checks/invalid-spec.ql b/python/ql/test/library-tests/dataflow/summaries-checks/invalid-spec.ql similarity index 100% rename from python/ql/test/experimental/dataflow/summaries-checks/invalid-spec.ql rename to python/ql/test/library-tests/dataflow/summaries-checks/invalid-spec.ql diff --git a/python/ql/test/experimental/dataflow/summaries/extracted_package/__init__.py b/python/ql/test/library-tests/dataflow/summaries-checks/missing-attribute-content.expected similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/extracted_package/__init__.py rename to python/ql/test/library-tests/dataflow/summaries-checks/missing-attribute-content.expected diff --git a/python/ql/test/experimental/dataflow/summaries-checks/missing-attribute-content.ql b/python/ql/test/library-tests/dataflow/summaries-checks/missing-attribute-content.ql similarity index 100% rename from python/ql/test/experimental/dataflow/summaries-checks/missing-attribute-content.ql rename to python/ql/test/library-tests/dataflow/summaries-checks/missing-attribute-content.ql diff --git a/python/ql/test/experimental/dataflow/summaries/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/summaries/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/summaries/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/summaries/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/summaries/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/summaries/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.expected b/python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.expected rename to python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.expected diff --git a/python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.ql b/python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.ql new file mode 100644 index 000000000000..59376d7a53c1 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.ql @@ -0,0 +1,3 @@ +import python +private import TestSummaries +import TestUtilities.dataflow.NormalTaintTrackingTest diff --git a/python/ql/test/experimental/dataflow/summaries/TestSummaries.qll b/python/ql/test/library-tests/dataflow/summaries/TestSummaries.qll similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/TestSummaries.qll rename to python/ql/test/library-tests/dataflow/summaries/TestSummaries.qll diff --git a/python/ql/test/experimental/dataflow/summaries/conflicting_summaries.py b/python/ql/test/library-tests/dataflow/summaries/conflicting_summaries.py similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/conflicting_summaries.py rename to python/ql/test/library-tests/dataflow/summaries/conflicting_summaries.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/__init__.py b/python/ql/test/library-tests/dataflow/summaries/extracted_package/__init__.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/__init__.py rename to python/ql/test/library-tests/dataflow/summaries/extracted_package/__init__.py diff --git a/python/ql/test/experimental/dataflow/summaries/extracted_package/functions.py b/python/ql/test/library-tests/dataflow/summaries/extracted_package/functions.py similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/extracted_package/functions.py rename to python/ql/test/library-tests/dataflow/summaries/extracted_package/functions.py diff --git a/python/ql/test/experimental/dataflow/summaries/summaries.expected b/python/ql/test/library-tests/dataflow/summaries/summaries.expected similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/summaries.expected rename to python/ql/test/library-tests/dataflow/summaries/summaries.expected diff --git a/python/ql/test/experimental/dataflow/summaries/summaries.py b/python/ql/test/library-tests/dataflow/summaries/summaries.py similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/summaries.py rename to python/ql/test/library-tests/dataflow/summaries/summaries.py diff --git a/python/ql/test/experimental/dataflow/summaries/summaries.ql b/python/ql/test/library-tests/dataflow/summaries/summaries.ql similarity index 93% rename from python/ql/test/experimental/dataflow/summaries/summaries.ql rename to python/ql/test/library-tests/dataflow/summaries/summaries.ql index e2a61cd6f463..4b5e79d28869 100644 --- a/python/ql/test/experimental/dataflow/summaries/summaries.ql +++ b/python/ql/test/library-tests/dataflow/summaries/summaries.ql @@ -8,7 +8,7 @@ import TestFlow::PathGraph import semmle.python.dataflow.new.TaintTracking import semmle.python.dataflow.new.internal.FlowSummaryImpl import semmle.python.ApiGraphs -import experimental.dataflow.testTaintConfig +import TestUtilities.dataflow.testTaintConfig private import TestSummaries query predicate invalidSpecComponent(SummarizedCallable sc, string s, string c) { diff --git a/python/ql/test/experimental/dataflow/tainttracking/TestTaintLib.qll b/python/ql/test/library-tests/dataflow/tainttracking/TestTaintLib.qll similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/TestTaintLib.qll rename to python/ql/test/library-tests/dataflow/tainttracking/TestTaintLib.qll diff --git a/python/ql/test/experimental/dataflow/tainttracking/basic/GlobalTaintTracking.expected b/python/ql/test/library-tests/dataflow/tainttracking/basic/GlobalTaintTracking.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/basic/GlobalTaintTracking.expected rename to python/ql/test/library-tests/dataflow/tainttracking/basic/GlobalTaintTracking.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/basic/GlobalTaintTracking.ql b/python/ql/test/library-tests/dataflow/tainttracking/basic/GlobalTaintTracking.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/basic/GlobalTaintTracking.ql rename to python/ql/test/library-tests/dataflow/tainttracking/basic/GlobalTaintTracking.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/basic/LocalTaintStep.expected b/python/ql/test/library-tests/dataflow/tainttracking/basic/LocalTaintStep.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/basic/LocalTaintStep.expected rename to python/ql/test/library-tests/dataflow/tainttracking/basic/LocalTaintStep.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/basic/LocalTaintStep.ql b/python/ql/test/library-tests/dataflow/tainttracking/basic/LocalTaintStep.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/basic/LocalTaintStep.ql rename to python/ql/test/library-tests/dataflow/tainttracking/basic/LocalTaintStep.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/basic/test.py b/python/ql/test/library-tests/dataflow/tainttracking/basic/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/basic/test.py rename to python/ql/test/library-tests/dataflow/tainttracking/basic/test.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py b/python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py rename to python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test.py b/python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test.py rename to python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/test.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py b/python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/test_logical.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py rename to python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/test_logical.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_reference.py b/python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/test_reference.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_reference.py rename to python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/test_reference.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/options b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/options similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/options rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/options diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_pathlib.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_pathlib.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_pathlib.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_pathlib.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_unpacking.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_unpacking.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_unpacking.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_unpacking.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_async.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_async.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_async.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_async.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_attr.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_attr.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_attr.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_attr.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_for.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_for.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_for.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_for.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_unpacking.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_unpacking.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_unpacking.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_unpacking.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_with.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_with.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_with.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_with.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/tainttracking/generator-flow/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/tainttracking/generator-flow/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected rename to python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected diff --git a/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql new file mode 100644 index 000000000000..f7e55d12ded6 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql @@ -0,0 +1,2 @@ +import python +import TestUtilities.dataflow.NormalDataflowTest diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/test_dataflow.py b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/test_dataflow.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/generator-flow/test_dataflow.py rename to python/ql/test/library-tests/dataflow/tainttracking/generator-flow/test_dataflow.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/test_taint.py b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/test_taint.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/generator-flow/test_taint.py rename to python/ql/test/library-tests/dataflow/tainttracking/generator-flow/test_taint.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/taintlib.py b/python/ql/test/library-tests/dataflow/tainttracking/taintlib.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/taintlib.py rename to python/ql/test/library-tests/dataflow/tainttracking/taintlib.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/test.py b/python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/test.py rename to python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/test.py diff --git a/python/ql/test/experimental/dataflow/testlib.py b/python/ql/test/library-tests/dataflow/testlib.py similarity index 100% rename from python/ql/test/experimental/dataflow/testlib.py rename to python/ql/test/library-tests/dataflow/testlib.py diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll b/python/ql/test/library-tests/dataflow/typetracking-summaries/TestSummaries.qll similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll rename to python/ql/test/library-tests/dataflow/typetracking-summaries/TestSummaries.qll diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py b/python/ql/test/library-tests/dataflow/typetracking-summaries/summaries.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py rename to python/ql/test/library-tests/dataflow/typetracking-summaries/summaries.py diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/tracked.expected b/python/ql/test/library-tests/dataflow/typetracking-summaries/tracked.expected similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking-summaries/tracked.expected rename to python/ql/test/library-tests/dataflow/typetracking-summaries/tracked.expected diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/tracked.ql b/python/ql/test/library-tests/dataflow/typetracking-summaries/tracked.ql similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking-summaries/tracked.ql rename to python/ql/test/library-tests/dataflow/typetracking-summaries/tracked.ql diff --git a/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py b/python/ql/test/library-tests/dataflow/typetracking/attribute_tests.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/attribute_tests.py rename to python/ql/test/library-tests/dataflow/typetracking/attribute_tests.py diff --git a/python/ql/test/experimental/dataflow/typetracking/content_test.py b/python/ql/test/library-tests/dataflow/typetracking/content_test.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/content_test.py rename to python/ql/test/library-tests/dataflow/typetracking/content_test.py diff --git a/python/ql/test/experimental/dataflow/typetracking/import_as_attr.py b/python/ql/test/library-tests/dataflow/typetracking/import_as_attr.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/import_as_attr.py rename to python/ql/test/library-tests/dataflow/typetracking/import_as_attr.py diff --git a/python/ql/test/experimental/dataflow/typetracking/import_as_attr_dotted.py b/python/ql/test/library-tests/dataflow/typetracking/import_as_attr_dotted.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/import_as_attr_dotted.py rename to python/ql/test/library-tests/dataflow/typetracking/import_as_attr_dotted.py diff --git a/python/ql/test/experimental/dataflow/typetracking/moduleattr.expected b/python/ql/test/library-tests/dataflow/typetracking/moduleattr.expected similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/moduleattr.expected rename to python/ql/test/library-tests/dataflow/typetracking/moduleattr.expected diff --git a/python/ql/test/experimental/dataflow/typetracking/moduleattr.ql b/python/ql/test/library-tests/dataflow/typetracking/moduleattr.ql similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/moduleattr.ql rename to python/ql/test/library-tests/dataflow/typetracking/moduleattr.ql diff --git a/python/ql/test/experimental/dataflow/typetracking/multiple_callables.py b/python/ql/test/library-tests/dataflow/typetracking/multiple_callables.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/multiple_callables.py rename to python/ql/test/library-tests/dataflow/typetracking/multiple_callables.py diff --git a/python/ql/test/experimental/dataflow/typetracking/mymodule.py b/python/ql/test/library-tests/dataflow/typetracking/mymodule.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/mymodule.py rename to python/ql/test/library-tests/dataflow/typetracking/mymodule.py diff --git a/python/ql/test/experimental/dataflow/typetracking/test.py b/python/ql/test/library-tests/dataflow/typetracking/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/test.py rename to python/ql/test/library-tests/dataflow/typetracking/test.py diff --git a/python/ql/test/experimental/dataflow/typetracking/tracked.expected b/python/ql/test/library-tests/dataflow/typetracking/tracked.expected similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/tracked.expected rename to python/ql/test/library-tests/dataflow/typetracking/tracked.expected diff --git a/python/ql/test/experimental/dataflow/typetracking/tracked.ql b/python/ql/test/library-tests/dataflow/typetracking/tracked.ql similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/tracked.ql rename to python/ql/test/library-tests/dataflow/typetracking/tracked.ql diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/README.md b/python/ql/test/library-tests/dataflow/typetracking_imports/README.md similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/README.md rename to python/ql/test/library-tests/dataflow/typetracking_imports/README.md diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/highlight_problem.expected b/python/ql/test/library-tests/dataflow/typetracking_imports/highlight_problem.expected similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/highlight_problem.expected rename to python/ql/test/library-tests/dataflow/typetracking_imports/highlight_problem.expected diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/highlight_problem.ql b/python/ql/test/library-tests/dataflow/typetracking_imports/highlight_problem.ql similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/highlight_problem.ql rename to python/ql/test/library-tests/dataflow/typetracking_imports/highlight_problem.ql diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/options b/python/ql/test/library-tests/dataflow/typetracking_imports/options similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/options rename to python/ql/test/library-tests/dataflow/typetracking_imports/options diff --git a/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/__init__.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_only_direct.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_only_direct.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_only_direct.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_only_direct.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_problem.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_problem.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_problem.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_problem.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_problem_fixed.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_problem_fixed.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_problem_fixed.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_problem_fixed.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_star.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_star.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_star.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_star.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/foo_def.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/foo_def.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/foo_def.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/foo_def.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/other.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/other.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/other.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/other.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/problem_absolute_import.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/problem_absolute_import.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/problem_absolute_import.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/problem_absolute_import.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/use.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/use.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/use.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/use.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/works_absolute_import.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/works_absolute_import.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/works_absolute_import.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/works_absolute_import.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected b/python/ql/test/library-tests/dataflow/typetracking_imports/tracked.expected similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected rename to python/ql/test/library-tests/dataflow/typetracking_imports/tracked.expected diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/tracked.qlref b/python/ql/test/library-tests/dataflow/typetracking_imports/tracked.qlref similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/tracked.qlref rename to python/ql/test/library-tests/dataflow/typetracking_imports/tracked.qlref diff --git a/python/ql/test/experimental/dataflow/use-use-flow/read_explosion.py b/python/ql/test/library-tests/dataflow/use-use-flow/read_explosion.py similarity index 100% rename from python/ql/test/experimental/dataflow/use-use-flow/read_explosion.py rename to python/ql/test/library-tests/dataflow/use-use-flow/read_explosion.py diff --git a/python/ql/test/experimental/dataflow/use-use-flow/use-use-counts.expected b/python/ql/test/library-tests/dataflow/use-use-flow/use-use-counts.expected similarity index 100% rename from python/ql/test/experimental/dataflow/use-use-flow/use-use-counts.expected rename to python/ql/test/library-tests/dataflow/use-use-flow/use-use-counts.expected diff --git a/python/ql/test/experimental/dataflow/use-use-flow/use-use-counts.ql b/python/ql/test/library-tests/dataflow/use-use-flow/use-use-counts.ql similarity index 100% rename from python/ql/test/experimental/dataflow/use-use-flow/use-use-counts.ql rename to python/ql/test/library-tests/dataflow/use-use-flow/use-use-counts.ql diff --git a/python/ql/test/experimental/dataflow/validTest.py b/python/ql/test/library-tests/dataflow/validTest.py similarity index 100% rename from python/ql/test/experimental/dataflow/validTest.py rename to python/ql/test/library-tests/dataflow/validTest.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.expected b/python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/CaptureTest.expected rename to python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.expected diff --git a/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.ql b/python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.ql similarity index 92% rename from python/ql/test/experimental/dataflow/variable-capture/CaptureTest.ql rename to python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.ql index a1c754e8ee54..f81101741517 100644 --- a/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.ql +++ b/python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.ql @@ -1,7 +1,7 @@ import python import semmle.python.dataflow.new.DataFlow import TestUtilities.InlineExpectationsTest -import experimental.dataflow.testConfig +import TestUtilities.dataflow.testConfig module CaptureTest implements TestSig { string getARelevantTag() { result = "captured" } diff --git a/python/ql/test/experimental/dataflow/variable-capture/by_value.py b/python/ql/test/library-tests/dataflow/variable-capture/by_value.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/by_value.py rename to python/ql/test/library-tests/dataflow/variable-capture/by_value.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/dataflow-capture-consistency.expected b/python/ql/test/library-tests/dataflow/variable-capture/dataflow-capture-consistency.expected similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/dataflow-capture-consistency.expected rename to python/ql/test/library-tests/dataflow/variable-capture/dataflow-capture-consistency.expected diff --git a/python/ql/test/experimental/dataflow/variable-capture/dataflow-capture-consistency.ql b/python/ql/test/library-tests/dataflow/variable-capture/dataflow-capture-consistency.ql similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/dataflow-capture-consistency.ql rename to python/ql/test/library-tests/dataflow/variable-capture/dataflow-capture-consistency.ql diff --git a/python/ql/test/experimental/dataflow/variable-capture/dict.py b/python/ql/test/library-tests/dataflow/variable-capture/dict.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/dict.py rename to python/ql/test/library-tests/dataflow/variable-capture/dict.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/global.py b/python/ql/test/library-tests/dataflow/variable-capture/global.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/global.py rename to python/ql/test/library-tests/dataflow/variable-capture/global.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/in.py b/python/ql/test/library-tests/dataflow/variable-capture/in.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/in.py rename to python/ql/test/library-tests/dataflow/variable-capture/in.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/nonlocal.py b/python/ql/test/library-tests/dataflow/variable-capture/nonlocal.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/nonlocal.py rename to python/ql/test/library-tests/dataflow/variable-capture/nonlocal.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/test_collections.py b/python/ql/test/library-tests/dataflow/variable-capture/test_collections.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/test_collections.py rename to python/ql/test/library-tests/dataflow/variable-capture/test_collections.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/test_fields.py b/python/ql/test/library-tests/dataflow/variable-capture/test_fields.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/test_fields.py rename to python/ql/test/library-tests/dataflow/variable-capture/test_fields.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/test_library_calls.py b/python/ql/test/library-tests/dataflow/variable-capture/test_library_calls.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/test_library_calls.py rename to python/ql/test/library-tests/dataflow/variable-capture/test_library_calls.py diff --git a/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.ql b/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.ql index 3ee344d0b871..f7e55d12ded6 100644 --- a/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.ql +++ b/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.ql @@ -1,2 +1,2 @@ import python -import experimental.dataflow.TestUtil.NormalDataflowTest +import TestUtilities.dataflow.NormalDataflowTest diff --git a/python/ql/test/library-tests/frameworks/stdlib-py3/Decoding.py b/python/ql/test/library-tests/frameworks/stdlib-py3/Decoding.py index 11cca46bdf7c..ec82bd2f1a73 100644 --- a/python/ql/test/library-tests/frameworks/stdlib-py3/Decoding.py +++ b/python/ql/test/library-tests/frameworks/stdlib-py3/Decoding.py @@ -1,6 +1,6 @@ import base64 -# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py +# TODO: These tests should be merged with python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py base64.a85decode(payload) # $ decodeInput=payload decodeOutput=base64.a85decode(..) decodeFormat=Ascii85 base64.b85decode(payload) # $ decodeInput=payload decodeOutput=base64.b85decode(..) decodeFormat=Base85 base64.decodebytes(payload) # $ decodeInput=payload decodeOutput=base64.decodebytes(..) decodeFormat=Base64 diff --git a/python/ql/test/library-tests/frameworks/stdlib-py3/Encoding.py b/python/ql/test/library-tests/frameworks/stdlib-py3/Encoding.py index 7aea6a5e579b..493e22a6048b 100644 --- a/python/ql/test/library-tests/frameworks/stdlib-py3/Encoding.py +++ b/python/ql/test/library-tests/frameworks/stdlib-py3/Encoding.py @@ -1,6 +1,6 @@ import base64 -# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py +# TODO: These tests should be merged with python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py base64.a85encode(bs) # $ encodeInput=bs encodeOutput=base64.a85encode(..) encodeFormat=Ascii85 base64.b85encode(bs)# $ encodeInput=bs encodeOutput=base64.b85encode(..) encodeFormat=Base85 base64.encodebytes(bs)# $ encodeInput=bs encodeOutput=base64.encodebytes(..) encodeFormat=Base64 diff --git a/python/ql/test/library-tests/frameworks/stdlib/Decoding.py b/python/ql/test/library-tests/frameworks/stdlib/Decoding.py index a977cb2793a5..6cd0be5740cd 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/Decoding.py +++ b/python/ql/test/library-tests/frameworks/stdlib/Decoding.py @@ -26,7 +26,7 @@ shelve.open(filepath) # $ decodeInput=filepath decodeOutput=shelve.open(..) decodeFormat=pickle decodeMayExecuteInput getAPathArgument=filepath shelve.open(filename=filepath) # $ decodeInput=filepath decodeOutput=shelve.open(..) decodeFormat=pickle decodeMayExecuteInput getAPathArgument=filepath -# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py +# TODO: These tests should be merged with python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py base64.b64decode(payload) # $ decodeInput=payload decodeOutput=base64.b64decode(..) decodeFormat=Base64 base64.standard_b64decode(payload) # $ decodeInput=payload decodeOutput=base64.standard_b64decode(..) decodeFormat=Base64 base64.urlsafe_b64decode(payload) # $ decodeInput=payload decodeOutput=base64.urlsafe_b64decode(..) decodeFormat=Base64 diff --git a/python/ql/test/library-tests/frameworks/stdlib/Encoding.py b/python/ql/test/library-tests/frameworks/stdlib/Encoding.py index 38f4372faa26..5573709a05f8 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/Encoding.py +++ b/python/ql/test/library-tests/frameworks/stdlib/Encoding.py @@ -5,7 +5,7 @@ pickle.dumps(obj) # $ MISSING: encodeInput=obj encodeOutput=pickle.dumps(..) encodeFormat=pickle encodeMayExecuteInput marshal.dumps(obj) # $ MISSING: encodeInput=obj encodeOutput=marshal.dumps(..) encodeFormat=marshal encodeMayExecuteInput -# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py +# TODO: These tests should be merged with python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py base64.b64encode(bs) # $ encodeInput=bs encodeOutput=base64.b64encode(..) encodeFormat=Base64 base64.standard_b64encode(bs) # $ encodeInput=bs encodeOutput=base64.standard_b64encode(..) encodeFormat=Base64 base64.urlsafe_b64encode(bs) # $ encodeInput=bs encodeOutput=base64.urlsafe_b64encode(..) encodeFormat=Base64 diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.ql b/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.ql index 90761391ce79..a0cdc79b17d7 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.ql +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python -import experimental.dataflow.TestUtil.DataflowQueryTest +import TestUtilities.dataflow.DataflowQueryTest import semmle.python.security.dataflow.PathInjectionQuery import FromTaintTrackingStateConfig diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.ql b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.ql index df745b4ee8c3..26350c3db65b 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.ql +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python -import experimental.dataflow.TestUtil.DataflowQueryTest +import TestUtilities.dataflow.DataflowQueryTest import semmle.python.security.dataflow.CommandInjectionQuery import FromTaintTrackingConfig diff --git a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.ql b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.ql index b2602b2b25c7..521527e7e4f0 100644 --- a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.ql +++ b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python -import experimental.dataflow.TestUtil.DataflowQueryTest +import TestUtilities.dataflow.DataflowQueryTest import semmle.python.security.dataflow.UnsafeShellCommandConstructionQuery import FromTaintTrackingConfig diff --git a/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.ql b/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.ql index b665aefd6fb3..5123e883d9cf 100644 --- a/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.ql +++ b/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python -import experimental.dataflow.TestUtil.DataflowQueryTest +import TestUtilities.dataflow.DataflowQueryTest import semmle.python.security.dataflow.NoSqlInjectionQuery import FromTaintTrackingStateConfig diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 1c87f55596f2..685e9b24bd5b 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.9.0 + +### Breaking Changes + +* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. +* Deleted the deprecated `security/cwe-020/HostnameRegexpShared.qll` file. + ## 0.8.14 No user-facing changes. diff --git a/ruby/ql/lib/change-notes/released/0.9.0.md b/ruby/ql/lib/change-notes/released/0.9.0.md new file mode 100644 index 000000000000..534e3ad77234 --- /dev/null +++ b/ruby/ql/lib/change-notes/released/0.9.0.md @@ -0,0 +1,6 @@ +## 0.9.0 + +### Breaking Changes + +* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. +* Deleted the deprecated `security/cwe-020/HostnameRegexpShared.qll` file. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index b36a2e248f34..8b9fc185202d 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.8.14 +lastReleaseVersion: 0.9.0 diff --git a/ruby/ql/lib/codeql/ruby/Regexp.qll b/ruby/ql/lib/codeql/ruby/Regexp.qll index 1abcee8d2d16..124666c95a03 100644 --- a/ruby/ql/lib/codeql/ruby/Regexp.qll +++ b/ruby/ql/lib/codeql/ruby/Regexp.qll @@ -14,20 +14,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.ApiGraphs private import codeql.ruby.Concepts -/** - * Provides utility predicates related to regular expressions. - */ -deprecated module RegExpPatterns { - /** - * Gets a pattern that matches common top-level domain names in lower case. - * DEPRECATED: use the similarly named predicate from `HostnameRegex` from the `regex` pack instead. - */ - deprecated string getACommonTld() { - // according to ranking by http://google.com/search?q=site:.<> - result = "(?:com|org|edu|gov|uk|net|io)(?![a-z0-9])" - } -} - /** * A node whose value may flow to a position where it is interpreted * as a part of a regular expression. @@ -122,7 +108,9 @@ class StdLibRegExpInterpretation extends RegExpInterpretation::Range { mce.getMethodName() = ["match", "match?"] and this = mce.getArgument(0) and // exclude https://ruby-doc.org/core-2.4.0/Regexp.html#method-i-match - not mce.getReceiver() = RegExpTracking::trackRegexpType() + not mce.getReceiver() = RegExpTracking::trackRegexpType() and + // exclude non-stdlib methods + not exists(mce.getATarget()) ) } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/String.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/String.qll index 86246ba80a20..23a902c00195 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/String.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/String.qll @@ -19,9 +19,11 @@ class StringSubstitutionCall extends DataFlow::CallNode { StringSubstitutionCall() { this.getMethodName() = ["sub", "sub!", "gsub", "gsub!"] and exists(this.getReceiver()) and - this.getNumberOfArguments() = 2 - or - this.getNumberOfArguments() = 1 and exists(this.getBlock()) + ( + this.getNumberOfArguments() = 2 + or + this.getNumberOfArguments() = 1 and exists(this.getBlock()) + ) } /** diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/model.yml b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml similarity index 79% rename from ruby/ql/lib/codeql/ruby/frameworks/data/internal/model.yml rename to ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml index 7dd7c7a9c0cb..b887eed7c1c5 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/model.yml +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml @@ -1,5 +1,6 @@ extensions: - # Contribute empty data sets to avoid errors about an undefined extensionals + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about undefined extensionals. - addsTo: pack: codeql/ruby-all extensible: sourceModel diff --git a/ruby/ql/lib/codeql/ruby/security/SensitiveActions.qll b/ruby/ql/lib/codeql/ruby/security/SensitiveActions.qll index cc01ab4078bf..34beb33604b7 100644 --- a/ruby/ql/lib/codeql/ruby/security/SensitiveActions.qll +++ b/ruby/ql/lib/codeql/ruby/security/SensitiveActions.qll @@ -28,17 +28,13 @@ abstract class SensitiveNode extends DataFlow::Node { } /** A method call that might produce sensitive data. */ -class SensitiveCall extends SensitiveNode instanceof DataFlow::CallNode { +abstract class SensitiveCall extends SensitiveNode { } + +private class SensitiveDataMethodNameCall extends SensitiveCall instanceof DataFlow::CallNode { SensitiveDataClassification classification; - SensitiveCall() { + SensitiveDataMethodNameCall() { classification = this.getMethodName().(SensitiveDataMethodName).getClassification() - or - // This is particularly to pick up methods with an argument like "password", which - // may indicate a lookup. - exists(string s | super.getArgument(_).asExpr().getConstantValue().isStringlikeValue(s) | - nameIndicatesSensitiveData(s, classification) - ) } override string describe() { result = "a call to " + super.getMethodName() } @@ -46,6 +42,23 @@ class SensitiveCall extends SensitiveNode instanceof DataFlow::CallNode { override SensitiveDataClassification getClassification() { result = classification } } +private class SensitiveArgumentCall extends SensitiveCall instanceof DataFlow::CallNode { + string argName; + + SensitiveArgumentCall() { + // This is particularly to pick up methods with an argument like "password", which may indicate + // a lookup. + super.getArgument(_).asExpr().getConstantValue().isStringlikeValue(argName) and + nameIndicatesSensitiveData(argName) + } + + override string describe() { result = "a call to " + super.getMethodName() } + + override SensitiveDataClassification getClassification() { + nameIndicatesSensitiveData(argName, result) + } +} + /** An access to a variable or hash value that might contain sensitive data. */ abstract class SensitiveVariableAccess extends SensitiveNode { string name; @@ -93,7 +106,7 @@ private string unprefixedVariableName(string name) { result = name.regexpReplace /** A write to a variable or property that might contain sensitive data. */ private class BasicSensitiveWrite extends SensitiveWrite { - SensitiveDataClassification classification; + string unprefixedName; BasicSensitiveWrite() { exists(string name | @@ -111,23 +124,29 @@ private class BasicSensitiveWrite extends SensitiveWrite { */ writesProperty(this, name) and - nameIndicatesSensitiveData(unprefixedVariableName(name), classification) + unprefixedName = unprefixedVariableName(name) and + nameIndicatesSensitiveData(unprefixedName) ) } /** Gets a classification of the kind of sensitive data the write might handle. */ - SensitiveDataClassification getClassification() { result = classification } + SensitiveDataClassification getClassification() { + nameIndicatesSensitiveData(unprefixedName, result) + } } /** An access to a variable or hash value that might contain sensitive data. */ private class BasicSensitiveVariableAccess extends SensitiveVariableAccess { - SensitiveDataClassification classification; + string unprefixedName; BasicSensitiveVariableAccess() { - nameIndicatesSensitiveData(unprefixedVariableName(name), classification) + unprefixedName = unprefixedVariableName(name) and + nameIndicatesSensitiveData(unprefixedName) } - override SensitiveDataClassification getClassification() { result = classification } + override SensitiveDataClassification getClassification() { + nameIndicatesSensitiveData(unprefixedName, result) + } } /** A method name that suggests it may be sensitive. */ @@ -143,11 +162,11 @@ abstract class SensitiveDataMethodName extends SensitiveMethodName { /** A method name that might return sensitive credential data. */ class CredentialsMethodName extends SensitiveDataMethodName { - SensitiveDataClassification classification; - - CredentialsMethodName() { nameIndicatesSensitiveData(this, classification) } + CredentialsMethodName() { nameIndicatesSensitiveData(this) } - override SensitiveDataClassification getClassification() { result = classification } + override SensitiveDataClassification getClassification() { + nameIndicatesSensitiveData(this, result) + } } /** diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index e14d47178a83..79ec8fc4fb55 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.8.15-dev +version: 0.9.1-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index a95ee7ee1ffb..317d8cf367f9 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.15 + +No user-facing changes. + ## 0.8.14 ### New Queries diff --git a/ruby/ql/src/change-notes/released/0.8.15.md b/ruby/ql/src/change-notes/released/0.8.15.md new file mode 100644 index 000000000000..18c028b4ff00 --- /dev/null +++ b/ruby/ql/src/change-notes/released/0.8.15.md @@ -0,0 +1,3 @@ +## 0.8.15 + +No user-facing changes. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index b36a2e248f34..2e3c183bb7a2 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.8.14 +lastReleaseVersion: 0.8.15 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 4ea0c217f092..b2d690177e0a 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.8.15-dev +version: 0.8.16-dev groups: - ruby - queries diff --git a/ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll b/ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll deleted file mode 100644 index dc3ed9aeaf77..000000000000 --- a/ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Provides predicates for reasoning about regular expressions - * that match URLs and hostname patterns. - */ - -// HostnameRegexp should be used directly from the shared regex pack, and not from this file. -deprecated import codeql.ruby.security.regexp.HostnameRegexp as Dep -import Dep diff --git a/ruby/ql/src/queries/security/cwe-078/examples/file_open.rb b/ruby/ql/src/queries/security/cwe-078/examples/file_open.rb index 3ce1f44817f9..1e0c13d6aca3 100644 --- a/ruby/ql/src/queries/security/cwe-078/examples/file_open.rb +++ b/ruby/ql/src/queries/security/cwe-078/examples/file_open.rb @@ -1,6 +1,9 @@ class UsersController < ActionController::Base - def create - filename = params[:filename] - File.open(filename) - end - end \ No newline at end of file + def create + filename = params[:filename] + File.open(filename) + + web_page = params[:web_page] + Net::HTTP.get(URI.parse(web_page)) + end +end diff --git a/ruby/ql/src/queries/security/cwe-078/examples/kernel_open.rb b/ruby/ql/src/queries/security/cwe-078/examples/kernel_open.rb index 84f8bc8db7d4..ce14c11acede 100644 --- a/ruby/ql/src/queries/security/cwe-078/examples/kernel_open.rb +++ b/ruby/ql/src/queries/security/cwe-078/examples/kernel_open.rb @@ -1,6 +1,11 @@ +require "open-uri" + class UsersController < ActionController::Base def create filename = params[:filename] open(filename) # BAD + + web_page = params[:web_page] + URI.open(web_page) # BAD - calls `Kernel.open` internally end -end \ No newline at end of file +end diff --git a/ruby/ql/src/queries/security/cwe-295/RequestWithoutValidation.ql b/ruby/ql/src/queries/security/cwe-295/RequestWithoutValidation.ql index 783f70426d6b..87c772e1cc13 100644 --- a/ruby/ql/src/queries/security/cwe-295/RequestWithoutValidation.ql +++ b/ruby/ql/src/queries/security/cwe-295/RequestWithoutValidation.ql @@ -29,4 +29,4 @@ where // does NOT hold. if disablingNode.getLocation() = origin.getLocation() then ending = "." else ending = " by $@." select request, "This request may run without certificate validation because $@" + ending, - disablingNode, "the request is disabled", origin, "this value" + disablingNode, "validation is disabled", origin, "this value" diff --git a/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/IncompleteHostnameRegExp.expected b/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/IncompleteHostnameRegExp.expected index 9110e245cd63..097f43c33e70 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/IncompleteHostnameRegExp.expected +++ b/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/IncompleteHostnameRegExp.expected @@ -28,3 +28,4 @@ | tst-IncompleteHostnameRegExp.rb:48:42:48:67 | ^https?://.+.example\\.com/ | This string, which is used as a regular expression $@, has an unescaped '.' before 'example\\.com/', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.rb:48:13:48:69 | ... + ... | here | | tst-IncompleteHostnameRegExp.rb:48:42:48:67 | ^https?://.+.example\\.com/ | This string, which is used as a regular expression $@, has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.rb:48:13:48:69 | ... + ... | here | | tst-IncompleteHostnameRegExp.rb:59:5:59:20 | foo.example\\.com | This regular expression has an unescaped '.' before 'example\\.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.rb:59:2:59:32 | /^(foo.example\\.com\|whatever)$/ | here | +| tst-IncompleteHostnameRegExp.rb:81:11:81:34 | ^http://test.example.com | This string, which is used as a regular expression $@, has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.rb:77:22:77:22 | x | here | diff --git a/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/tst-IncompleteHostnameRegExp.rb b/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/tst-IncompleteHostnameRegExp.rb index 91770040110a..7041e4dc9c46 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/tst-IncompleteHostnameRegExp.rb +++ b/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/tst-IncompleteHostnameRegExp.rb @@ -65,3 +65,17 @@ def convert1(domain) def convert2(domain) return Regexp.new(domain[:hostname]); end + +class A + def self.match?(x) = true +end + +A.match?("^http://test.example.com") # OK + +class B + def self.match?(x) + some_string.match?(x) + end +end + +B.match?("^http://test.example.com") # NOT OK diff --git a/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/tst.rb b/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/tst.rb index 569e8b5ac09a..f59fdd332aed 100644 --- a/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/tst.rb +++ b/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/tst.rb @@ -268,3 +268,8 @@ def bad_path_sanitizer(p1, p2) p1.sub! "/../", "" # NOT OK p2.sub "/../", "" # NOT OK end + +def each_line_sanitizer(p1) + p1.each_line("\n") do |l| # OK - does no sanitization + end +end diff --git a/ruby/ql/test/query-tests/security/cwe-295/RequestWithoutValidation.expected b/ruby/ql/test/query-tests/security/cwe-295/RequestWithoutValidation.expected index 7b5c32c891a5..4f368a250027 100644 --- a/ruby/ql/test/query-tests/security/cwe-295/RequestWithoutValidation.expected +++ b/ruby/ql/test/query-tests/security/cwe-295/RequestWithoutValidation.expected @@ -1,28 +1,28 @@ -| Excon.rb:6:3:6:34 | call to get | This request may run without certificate validation because $@. | Excon.rb:5:38:5:42 | ... = ... | the request is disabled | Excon.rb:5:38:5:42 | false | this value | -| Excon.rb:12:3:12:34 | call to get | This request may run without certificate validation because $@. | Excon.rb:11:27:11:31 | ... = ... | the request is disabled | Excon.rb:11:27:11:31 | false | this value | -| Excon.rb:18:3:18:34 | call to get | This request may run without certificate validation because $@ by $@. | Excon.rb:17:38:17:60 | ... = ... | the request is disabled | Excon.rb:17:55:17:59 | false | this value | -| Excon.rb:24:3:24:10 | call to get | This request may run without certificate validation because $@. | Excon.rb:23:72:23:76 | false | the request is disabled | Excon.rb:23:72:23:76 | false | this value | -| Excon.rb:30:3:30:62 | call to get | This request may run without certificate validation because $@. | Excon.rb:30:53:30:57 | false | the request is disabled | Excon.rb:30:53:30:57 | false | this value | -| Faraday.rb:5:12:5:30 | call to get | This request may run without certificate validation because $@. | Faraday.rb:4:63:4:67 | false | the request is disabled | Faraday.rb:4:63:4:67 | false | this value | -| Faraday.rb:9:12:9:30 | call to get | This request may run without certificate validation because $@. | Faraday.rb:8:68:8:92 | VERIFY_NONE | the request is disabled | Faraday.rb:8:68:8:92 | VERIFY_NONE | this value | -| Faraday.rb:35:16:35:35 | call to get | This request may run without certificate validation because $@ by $@. | Faraday.rb:34:51:34:53 | arg | the request is disabled | Faraday.rb:38:42:38:46 | false | this value | -| Faraday.rb:44:16:44:35 | call to get | This request may run without certificate validation because $@ by $@. | Faraday.rb:43:56:43:58 | arg | the request is disabled | Faraday.rb:47:47:47:71 | VERIFY_NONE | this value | -| HttpClient.rb:6:1:6:33 | call to get | This request may run without certificate validation because $@. | HttpClient.rb:5:33:5:57 | ... = ... | the request is disabled | HttpClient.rb:5:33:5:57 | VERIFY_NONE | this value | -| Httparty.rb:4:1:4:50 | call to get | This request may run without certificate validation because $@. | Httparty.rb:4:45:4:49 | false | the request is disabled | Httparty.rb:4:45:4:49 | false | this value | -| Httparty.rb:7:1:7:55 | call to get | This request may run without certificate validation because $@. | Httparty.rb:7:50:7:54 | false | the request is disabled | Httparty.rb:7:50:7:54 | false | this value | -| Httparty.rb:10:1:10:59 | call to get | This request may run without certificate validation because $@. | Httparty.rb:10:52:10:56 | false | the request is disabled | Httparty.rb:10:52:10:56 | false | this value | -| Httparty.rb:13:1:13:70 | call to post | This request may run without certificate validation because $@. | Httparty.rb:13:65:13:69 | false | the request is disabled | Httparty.rb:13:65:13:69 | false | this value | -| Httparty.rb:16:1:16:74 | call to post | This request may run without certificate validation because $@. | Httparty.rb:16:67:16:71 | false | the request is disabled | Httparty.rb:16:67:16:71 | false | this value | -| NetHttp.rb:9:12:9:31 | call to request | This request may run without certificate validation because $@. | NetHttp.rb:7:20:7:44 | ... = ... | the request is disabled | NetHttp.rb:7:20:7:44 | VERIFY_NONE | this value | -| OpenURI.rb:4:1:4:78 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:4:53:4:77 | VERIFY_NONE | the request is disabled | OpenURI.rb:4:53:4:77 | VERIFY_NONE | this value | -| OpenURI.rb:7:1:7:82 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:7:55:7:79 | VERIFY_NONE | the request is disabled | OpenURI.rb:7:55:7:79 | VERIFY_NONE | this value | -| OpenURI.rb:11:1:11:43 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:10:30:10:54 | VERIFY_NONE | the request is disabled | OpenURI.rb:10:30:10:54 | VERIFY_NONE | this value | -| OpenURI.rb:14:1:14:81 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:14:56:14:80 | VERIFY_NONE | the request is disabled | OpenURI.rb:14:56:14:80 | VERIFY_NONE | this value | -| OpenURI.rb:17:1:17:85 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:17:58:17:82 | VERIFY_NONE | the request is disabled | OpenURI.rb:17:58:17:82 | VERIFY_NONE | this value | -| OpenURI.rb:21:1:21:46 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:20:30:20:54 | VERIFY_NONE | the request is disabled | OpenURI.rb:20:30:20:54 | VERIFY_NONE | this value | -| RestClient.rb:5:12:5:23 | call to get | This request may run without certificate validation because $@. | RestClient.rb:4:72:4:96 | VERIFY_NONE | the request is disabled | RestClient.rb:4:72:4:96 | VERIFY_NONE | this value | -| RestClient.rb:9:12:9:23 | call to get | This request may run without certificate validation because $@. | RestClient.rb:8:74:8:98 | VERIFY_NONE | the request is disabled | RestClient.rb:8:74:8:98 | VERIFY_NONE | this value | -| RestClient.rb:14:12:14:23 | call to get | This request may run without certificate validation because $@. | RestClient.rb:12:25:12:49 | VERIFY_NONE | the request is disabled | RestClient.rb:12:25:12:49 | VERIFY_NONE | this value | -| RestClient.rb:19:12:19:23 | call to get | This request may run without certificate validation because $@ by $@. | RestClient.rb:18:72:18:76 | value | the request is disabled | RestClient.rb:17:9:17:33 | VERIFY_NONE | this value | -| Typhoeus.rb:4:1:4:62 | call to get | This request may run without certificate validation because $@. | Typhoeus.rb:4:57:4:61 | false | the request is disabled | Typhoeus.rb:4:57:4:61 | false | this value | -| Typhoeus.rb:8:1:8:54 | call to post | This request may run without certificate validation because $@. | Typhoeus.rb:7:53:7:57 | false | the request is disabled | Typhoeus.rb:7:53:7:57 | false | this value | +| Excon.rb:6:3:6:34 | call to get | This request may run without certificate validation because $@. | Excon.rb:5:38:5:42 | ... = ... | validation is disabled | Excon.rb:5:38:5:42 | false | this value | +| Excon.rb:12:3:12:34 | call to get | This request may run without certificate validation because $@. | Excon.rb:11:27:11:31 | ... = ... | validation is disabled | Excon.rb:11:27:11:31 | false | this value | +| Excon.rb:18:3:18:34 | call to get | This request may run without certificate validation because $@ by $@. | Excon.rb:17:38:17:60 | ... = ... | validation is disabled | Excon.rb:17:55:17:59 | false | this value | +| Excon.rb:24:3:24:10 | call to get | This request may run without certificate validation because $@. | Excon.rb:23:72:23:76 | false | validation is disabled | Excon.rb:23:72:23:76 | false | this value | +| Excon.rb:30:3:30:62 | call to get | This request may run without certificate validation because $@. | Excon.rb:30:53:30:57 | false | validation is disabled | Excon.rb:30:53:30:57 | false | this value | +| Faraday.rb:5:12:5:30 | call to get | This request may run without certificate validation because $@. | Faraday.rb:4:63:4:67 | false | validation is disabled | Faraday.rb:4:63:4:67 | false | this value | +| Faraday.rb:9:12:9:30 | call to get | This request may run without certificate validation because $@. | Faraday.rb:8:68:8:92 | VERIFY_NONE | validation is disabled | Faraday.rb:8:68:8:92 | VERIFY_NONE | this value | +| Faraday.rb:35:16:35:35 | call to get | This request may run without certificate validation because $@ by $@. | Faraday.rb:34:51:34:53 | arg | validation is disabled | Faraday.rb:38:42:38:46 | false | this value | +| Faraday.rb:44:16:44:35 | call to get | This request may run without certificate validation because $@ by $@. | Faraday.rb:43:56:43:58 | arg | validation is disabled | Faraday.rb:47:47:47:71 | VERIFY_NONE | this value | +| HttpClient.rb:6:1:6:33 | call to get | This request may run without certificate validation because $@. | HttpClient.rb:5:33:5:57 | ... = ... | validation is disabled | HttpClient.rb:5:33:5:57 | VERIFY_NONE | this value | +| Httparty.rb:4:1:4:50 | call to get | This request may run without certificate validation because $@. | Httparty.rb:4:45:4:49 | false | validation is disabled | Httparty.rb:4:45:4:49 | false | this value | +| Httparty.rb:7:1:7:55 | call to get | This request may run without certificate validation because $@. | Httparty.rb:7:50:7:54 | false | validation is disabled | Httparty.rb:7:50:7:54 | false | this value | +| Httparty.rb:10:1:10:59 | call to get | This request may run without certificate validation because $@. | Httparty.rb:10:52:10:56 | false | validation is disabled | Httparty.rb:10:52:10:56 | false | this value | +| Httparty.rb:13:1:13:70 | call to post | This request may run without certificate validation because $@. | Httparty.rb:13:65:13:69 | false | validation is disabled | Httparty.rb:13:65:13:69 | false | this value | +| Httparty.rb:16:1:16:74 | call to post | This request may run without certificate validation because $@. | Httparty.rb:16:67:16:71 | false | validation is disabled | Httparty.rb:16:67:16:71 | false | this value | +| NetHttp.rb:9:12:9:31 | call to request | This request may run without certificate validation because $@. | NetHttp.rb:7:20:7:44 | ... = ... | validation is disabled | NetHttp.rb:7:20:7:44 | VERIFY_NONE | this value | +| OpenURI.rb:4:1:4:78 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:4:53:4:77 | VERIFY_NONE | validation is disabled | OpenURI.rb:4:53:4:77 | VERIFY_NONE | this value | +| OpenURI.rb:7:1:7:82 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:7:55:7:79 | VERIFY_NONE | validation is disabled | OpenURI.rb:7:55:7:79 | VERIFY_NONE | this value | +| OpenURI.rb:11:1:11:43 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:10:30:10:54 | VERIFY_NONE | validation is disabled | OpenURI.rb:10:30:10:54 | VERIFY_NONE | this value | +| OpenURI.rb:14:1:14:81 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:14:56:14:80 | VERIFY_NONE | validation is disabled | OpenURI.rb:14:56:14:80 | VERIFY_NONE | this value | +| OpenURI.rb:17:1:17:85 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:17:58:17:82 | VERIFY_NONE | validation is disabled | OpenURI.rb:17:58:17:82 | VERIFY_NONE | this value | +| OpenURI.rb:21:1:21:46 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:20:30:20:54 | VERIFY_NONE | validation is disabled | OpenURI.rb:20:30:20:54 | VERIFY_NONE | this value | +| RestClient.rb:5:12:5:23 | call to get | This request may run without certificate validation because $@. | RestClient.rb:4:72:4:96 | VERIFY_NONE | validation is disabled | RestClient.rb:4:72:4:96 | VERIFY_NONE | this value | +| RestClient.rb:9:12:9:23 | call to get | This request may run without certificate validation because $@. | RestClient.rb:8:74:8:98 | VERIFY_NONE | validation is disabled | RestClient.rb:8:74:8:98 | VERIFY_NONE | this value | +| RestClient.rb:14:12:14:23 | call to get | This request may run without certificate validation because $@. | RestClient.rb:12:25:12:49 | VERIFY_NONE | validation is disabled | RestClient.rb:12:25:12:49 | VERIFY_NONE | this value | +| RestClient.rb:19:12:19:23 | call to get | This request may run without certificate validation because $@ by $@. | RestClient.rb:18:72:18:76 | value | validation is disabled | RestClient.rb:17:9:17:33 | VERIFY_NONE | this value | +| Typhoeus.rb:4:1:4:62 | call to get | This request may run without certificate validation because $@. | Typhoeus.rb:4:57:4:61 | false | validation is disabled | Typhoeus.rb:4:57:4:61 | false | this value | +| Typhoeus.rb:8:1:8:54 | call to post | This request may run without certificate validation because $@. | Typhoeus.rb:7:53:7:57 | false | validation is disabled | Typhoeus.rb:7:53:7:57 | false | this value | diff --git a/shared/controlflow/CHANGELOG.md b/shared/controlflow/CHANGELOG.md index b2cc0c1080dc..7e1a517c4a95 100644 --- a/shared/controlflow/CHANGELOG.md +++ b/shared/controlflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.15 + +No user-facing changes. + ## 0.1.14 No user-facing changes. diff --git a/shared/controlflow/change-notes/released/0.1.15.md b/shared/controlflow/change-notes/released/0.1.15.md new file mode 100644 index 000000000000..ce8f7b7f0149 --- /dev/null +++ b/shared/controlflow/change-notes/released/0.1.15.md @@ -0,0 +1,3 @@ +## 0.1.15 + +No user-facing changes. diff --git a/shared/controlflow/codeql-pack.release.yml b/shared/controlflow/codeql-pack.release.yml index 76f7b27fb4e4..747196347438 100644 --- a/shared/controlflow/codeql-pack.release.yml +++ b/shared/controlflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.14 +lastReleaseVersion: 0.1.15 diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index f1f79c6d9396..0cb89d3b4162 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 0.1.15-dev +version: 0.1.16-dev groups: shared library: true dependencies: diff --git a/shared/dataflow/CHANGELOG.md b/shared/dataflow/CHANGELOG.md index 22bec6239eb4..180ffb852071 100644 --- a/shared/dataflow/CHANGELOG.md +++ b/shared/dataflow/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.2.6 + +### Major Analysis Improvements + +* The data flow library performs heuristic filtering of code paths that have a high degree of control-flow uncertainty for improved performance in cases that are deemed unlikely to yield true positive flow paths. This filtering can be controlled with the `fieldFlowBranchLimit` predicate in configurations. Two bugs have been fixed in relation to this: Some cases of high uncertainty were not being correctly identified. This fix improves performance in certain scenarios. Another group of cases of low uncertainty were also being misidentified, which led to false negatives. Taken together, we generally expect some additional query results with more true positives and fewer false positives. + ## 0.2.5 ### New Features diff --git a/shared/dataflow/change-notes/2024-04-19-fieldflowbranchlimit.md b/shared/dataflow/change-notes/released/0.2.6.md similarity index 94% rename from shared/dataflow/change-notes/2024-04-19-fieldflowbranchlimit.md rename to shared/dataflow/change-notes/released/0.2.6.md index 887d17f28664..d928a91c5b62 100644 --- a/shared/dataflow/change-notes/2024-04-19-fieldflowbranchlimit.md +++ b/shared/dataflow/change-notes/released/0.2.6.md @@ -1,4 +1,5 @@ ---- -category: majorAnalysis ---- +## 0.2.6 + +### Major Analysis Improvements + * The data flow library performs heuristic filtering of code paths that have a high degree of control-flow uncertainty for improved performance in cases that are deemed unlikely to yield true positive flow paths. This filtering can be controlled with the `fieldFlowBranchLimit` predicate in configurations. Two bugs have been fixed in relation to this: Some cases of high uncertainty were not being correctly identified. This fix improves performance in certain scenarios. Another group of cases of low uncertainty were also being misidentified, which led to false negatives. Taken together, we generally expect some additional query results with more true positives and fewer false positives. diff --git a/shared/dataflow/codeql-pack.release.yml b/shared/dataflow/codeql-pack.release.yml index 211454ed3064..248dd0f4594b 100644 --- a/shared/dataflow/codeql-pack.release.yml +++ b/shared/dataflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.5 +lastReleaseVersion: 0.2.6 diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 9dfbc3e0bcda..022174124ba7 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1119,9 +1119,10 @@ module MakeImpl Lang> { pragma[nomagic] private SndLevelScopeOption getScope(RetNodeEx ret) { - result = SndLevelScopeOption::some(getSecondLevelScope(ret.asNode())) + result = SndLevelScopeOption::some(getSecondLevelScopeCached(ret.asNode())) or - result instanceof SndLevelScopeOption::None and not exists(getSecondLevelScope(ret.asNode())) + result instanceof SndLevelScopeOption::None and + not exists(getSecondLevelScopeCached(ret.asNode())) } pragma[nomagic] @@ -1142,6 +1143,14 @@ module MakeImpl Lang> { ) } + pragma[nomagic] + private predicate returnCallEdgeInCtx1( + DataFlowCallable c, SndLevelScopeOption scope, DataFlowCall call, NodeEx out, DataFlowCall ctx + ) { + returnCallEdge1(c, scope, call, out) and + c = viableImplInCallContextExt(call, ctx) + } + private int ctxDispatchFanoutOnReturn(NodeEx out, DataFlowCall ctx) { exists(DataFlowCall call, DataFlowCallable c | simpleDispatchFanoutOnReturn(call, out) > 1 and @@ -1151,8 +1160,7 @@ module MakeImpl Lang> { mayBenefitFromCallContextExt(call, _) and result = count(DataFlowCallable tgt, SndLevelScopeOption scope | - tgt = viableImplInCallContextExt(call, ctx) and - returnCallEdge1(tgt, scope, call, out) + returnCallEdgeInCtx1(tgt, scope, call, out, ctx) ) ) } @@ -3874,7 +3882,12 @@ module MakeImpl Lang> { n1.getANonHiddenSuccessor(_) = n2 and directReach(n2) } - private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2) + private predicate tcSrc(PathNodeImpl n) { n.isFlowSource() or n.isSource(_) } + + private predicate tcSink(PathNodeImpl n) { n.isFlowSink() or n instanceof PathNodeSink } + + private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = + doublyBoundedFastTC(pathSucc/2, tcSrc/1, tcSink/1)(n1, n2) /** * A `Node` augmented with a call context (except for sinks) and an access path. diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll index 38c3bba3254f..9524ca9d9aba 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll @@ -616,6 +616,9 @@ module MakeImplCommon Lang> { cached predicate forceCachingInSameStage() { any() } + cached + DataFlowSecondLevelScope getSecondLevelScopeCached(Node n) { result = getSecondLevelScope(n) } + cached predicate nodeEnclosingCallable(Node n, DataFlowCallable c) { c = nodeGetEnclosingCallable(n) } diff --git a/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll b/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll index 89a2a23d53bb..78950806f7d6 100644 --- a/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll @@ -1286,10 +1286,8 @@ module Make< * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnKind rk, SummaryNode ret, DataFlowCall call | - summaryLocalStep(summaryArgParam(call, arg, sc), ret, true, _) and - summaryReturnNode(ret, pragma[only_bind_into](rk)) and - out = getAnOutNode(call, pragma[only_bind_into](rk)) + exists(SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, true, _) ) } diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 028aadc50917..14e318dced6b 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 0.2.6-dev +version: 0.2.7-dev groups: shared library: true dependencies: diff --git a/shared/mad/CHANGELOG.md b/shared/mad/CHANGELOG.md index 70e6a3e254c6..6f1322a26ffb 100644 --- a/shared/mad/CHANGELOG.md +++ b/shared/mad/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/mad/change-notes/released/0.2.15.md b/shared/mad/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/mad/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/mad/codeql-pack.release.yml b/shared/mad/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/mad/codeql-pack.release.yml +++ b/shared/mad/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index 2da72ddffac3..82dd88dcb56d 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 0.2.15-dev +version: 0.2.16-dev groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/CHANGELOG.md b/shared/rangeanalysis/CHANGELOG.md index cc3ed2692e73..0c0ae0d04f66 100644 --- a/shared/rangeanalysis/CHANGELOG.md +++ b/shared/rangeanalysis/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.14 + +No user-facing changes. + ## 0.0.13 No user-facing changes. diff --git a/shared/rangeanalysis/change-notes/released/0.0.14.md b/shared/rangeanalysis/change-notes/released/0.0.14.md new file mode 100644 index 000000000000..63b4d50ca454 --- /dev/null +++ b/shared/rangeanalysis/change-notes/released/0.0.14.md @@ -0,0 +1,3 @@ +## 0.0.14 + +No user-facing changes. diff --git a/shared/rangeanalysis/codeql-pack.release.yml b/shared/rangeanalysis/codeql-pack.release.yml index 044e54e4f7e5..ca29e45d0a67 100644 --- a/shared/rangeanalysis/codeql-pack.release.yml +++ b/shared/rangeanalysis/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.13 +lastReleaseVersion: 0.0.14 diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index 11e6ae0c5f84..309d8214fc05 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 0.0.14-dev +version: 0.0.15-dev groups: shared library: true dependencies: diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md index 23e63b6a8b6d..a974d3bb9a16 100644 --- a/shared/regex/CHANGELOG.md +++ b/shared/regex/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/regex/change-notes/released/0.2.15.md b/shared/regex/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/regex/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/regex/codeql-pack.release.yml +++ b/shared/regex/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 8ca0e7569341..bbd72f8b24cc 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 0.2.15-dev +version: 0.2.16-dev groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index 10af5c066847..2126603d56ae 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/ssa/change-notes/released/0.2.15.md b/shared/ssa/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/ssa/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 7a7752cabcdb..a824d260d607 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 0.2.15-dev +version: 0.2.16-dev groups: shared library: true dependencies: diff --git a/shared/threat-models/CHANGELOG.md b/shared/threat-models/CHANGELOG.md index 29ece641a7e3..ad4781e2cbda 100644 --- a/shared/threat-models/CHANGELOG.md +++ b/shared/threat-models/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.14 + +No user-facing changes. + ## 0.0.13 No user-facing changes. diff --git a/shared/threat-models/change-notes/released/0.0.14.md b/shared/threat-models/change-notes/released/0.0.14.md new file mode 100644 index 000000000000..63b4d50ca454 --- /dev/null +++ b/shared/threat-models/change-notes/released/0.0.14.md @@ -0,0 +1,3 @@ +## 0.0.14 + +No user-facing changes. diff --git a/shared/threat-models/codeql-pack.release.yml b/shared/threat-models/codeql-pack.release.yml index 044e54e4f7e5..ca29e45d0a67 100644 --- a/shared/threat-models/codeql-pack.release.yml +++ b/shared/threat-models/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.13 +lastReleaseVersion: 0.0.14 diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index 4c4a19afafd9..915ae1b88fd1 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 0.0.14-dev +version: 0.0.15-dev library: true groups: shared dataExtensions: diff --git a/shared/tutorial/CHANGELOG.md b/shared/tutorial/CHANGELOG.md index ed8307d3c525..953f7f46f4ea 100644 --- a/shared/tutorial/CHANGELOG.md +++ b/shared/tutorial/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/tutorial/change-notes/released/0.2.15.md b/shared/tutorial/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/tutorial/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/tutorial/codeql-pack.release.yml b/shared/tutorial/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/tutorial/codeql-pack.release.yml +++ b/shared/tutorial/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index 7b8488aacf13..4c5c4ed20cdf 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,7 +1,7 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 0.2.15-dev +version: 0.2.16-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/CHANGELOG.md b/shared/typeflow/CHANGELOG.md index 01b03981cd49..ac82f761c1d9 100644 --- a/shared/typeflow/CHANGELOG.md +++ b/shared/typeflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.2 + +No user-facing changes. + ## 0.0.1 ### New Features diff --git a/shared/typeflow/change-notes/released/0.0.2.md b/shared/typeflow/change-notes/released/0.0.2.md new file mode 100644 index 000000000000..5ab250998ed4 --- /dev/null +++ b/shared/typeflow/change-notes/released/0.0.2.md @@ -0,0 +1,3 @@ +## 0.0.2 + +No user-facing changes. diff --git a/shared/typeflow/codeql-pack.release.yml b/shared/typeflow/codeql-pack.release.yml index c6933410b71c..55dc06fbd76a 100644 --- a/shared/typeflow/codeql-pack.release.yml +++ b/shared/typeflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.1 +lastReleaseVersion: 0.0.2 diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index b0a2bf9a7484..365c17b83041 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 0.0.2-dev +version: 0.0.3-dev groups: shared library: true dependencies: diff --git a/shared/typetracking/CHANGELOG.md b/shared/typetracking/CHANGELOG.md index c259d339ee6b..57b0a29dd6c4 100644 --- a/shared/typetracking/CHANGELOG.md +++ b/shared/typetracking/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/typetracking/change-notes/released/0.2.15.md b/shared/typetracking/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/typetracking/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/typetracking/codeql-pack.release.yml b/shared/typetracking/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/typetracking/codeql-pack.release.yml +++ b/shared/typetracking/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 4317864eb39b..5f568fad1c30 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 0.2.15-dev +version: 0.2.16-dev groups: shared library: true dependencies: diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index 8f6f77b20d06..335d25587375 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/typos/change-notes/released/0.2.15.md b/shared/typos/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/typos/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index a0d2e5036c9f..a50a2dae34b9 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 0.2.15-dev +version: 0.2.16-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/CHANGELOG.md b/shared/util/CHANGELOG.md index b7d7602c5a9a..e583745ef4a8 100644 --- a/shared/util/CHANGELOG.md +++ b/shared/util/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/util/change-notes/released/0.2.15.md b/shared/util/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/util/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/util/codeql-pack.release.yml b/shared/util/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/util/codeql-pack.release.yml +++ b/shared/util/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index 13114a094664..602b3353d902 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 0.2.15-dev +version: 0.2.16-dev groups: shared library: true dependencies: null diff --git a/shared/xml/CHANGELOG.md b/shared/xml/CHANGELOG.md index 59b60bad0f37..7668a5ba39d5 100644 --- a/shared/xml/CHANGELOG.md +++ b/shared/xml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.2 + +No user-facing changes. + ## 0.0.1 No user-facing changes. diff --git a/shared/xml/change-notes/released/0.0.2.md b/shared/xml/change-notes/released/0.0.2.md new file mode 100644 index 000000000000..5ab250998ed4 --- /dev/null +++ b/shared/xml/change-notes/released/0.0.2.md @@ -0,0 +1,3 @@ +## 0.0.2 + +No user-facing changes. diff --git a/shared/xml/codeql-pack.release.yml b/shared/xml/codeql-pack.release.yml index c6933410b71c..55dc06fbd76a 100644 --- a/shared/xml/codeql-pack.release.yml +++ b/shared/xml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.1 +lastReleaseVersion: 0.0.2 diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index aac15f40851b..f4de1f7ea4f0 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 0.0.2-dev +version: 0.0.3-dev groups: shared library: true dependencies: diff --git a/shared/yaml/CHANGELOG.md b/shared/yaml/CHANGELOG.md index 379fbd1bee3a..c2982987f8a2 100644 --- a/shared/yaml/CHANGELOG.md +++ b/shared/yaml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/yaml/change-notes/released/0.2.15.md b/shared/yaml/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/yaml/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/yaml/codeql-pack.release.yml b/shared/yaml/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/yaml/codeql-pack.release.yml +++ b/shared/yaml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index b1b9e5e13523..598b37055db8 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 0.2.15-dev +version: 0.2.16-dev groups: shared library: true warnOnImplicitThis: true diff --git a/swift/extractor/BUILD.bazel b/swift/extractor/BUILD.bazel index 42c1105053cc..3acdbf014e34 100644 --- a/swift/extractor/BUILD.bazel +++ b/swift/extractor/BUILD.bazel @@ -1,5 +1,5 @@ -load("//swift:rules.bzl", "swift_cc_binary") load("//misc/bazel:pkg_runfiles.bzl", "pkg_runfiles") +load("//swift:rules.bzl", "swift_cc_binary") swift_cc_binary( name = "extractor.real", @@ -7,6 +7,10 @@ swift_cc_binary( "*.h", "*.cpp", ]), + linkopts = select({ + "@platforms//os:macos": ["-headerpad_max_install_names"], + "//conditions:default": [], + }), visibility = ["//swift:__pkg__"], deps = [ "//swift/extractor/config", @@ -17,10 +21,6 @@ swift_cc_binary( "//swift/third_party/swift-llvm-support", "@absl//absl/strings", ], - linkopts = select({ - "@platforms//os:macos": ["-headerpad_max_install_names"], - "//conditions:default": [], - }), ) sh_binary( diff --git a/swift/logging/BUILD.bazel b/swift/logging/BUILD.bazel index cd2f33441664..1d6192b3c13a 100644 --- a/swift/logging/BUILD.bazel +++ b/swift/logging/BUILD.bazel @@ -4,10 +4,10 @@ cc_library( hdrs = glob(["*.h"]), visibility = ["//visibility:public"], deps = [ + "//shared/cpp:extractor_shared", "@absl//absl/strings", "@binlog", "@fmt", "@json", - "//shared/cpp:extractor_shared", ], ) diff --git a/swift/ql/lib/CHANGELOG.md b/swift/ql/lib/CHANGELOG.md index 565902398bdb..48bd64147649 100644 --- a/swift/ql/lib/CHANGELOG.md +++ b/swift/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.15 + +No user-facing changes. + ## 0.3.14 No user-facing changes. diff --git a/swift/ql/lib/change-notes/released/0.3.15.md b/swift/ql/lib/change-notes/released/0.3.15.md new file mode 100644 index 000000000000..11fa7599e324 --- /dev/null +++ b/swift/ql/lib/change-notes/released/0.3.15.md @@ -0,0 +1,3 @@ +## 0.3.15 + +No user-facing changes. diff --git a/swift/ql/lib/codeql-pack.release.yml b/swift/ql/lib/codeql-pack.release.yml index 1ff0ab05e829..469af066c19c 100644 --- a/swift/ql/lib/codeql-pack.release.yml +++ b/swift/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.14 +lastReleaseVersion: 0.3.15 diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index 3c6c268ced85..0db44bbb5dae 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 0.3.15-dev +version: 0.3.16-dev groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/CHANGELOG.md b/swift/ql/src/CHANGELOG.md index 05ea3aed885b..c780f5cd2860 100644 --- a/swift/ql/src/CHANGELOG.md +++ b/swift/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.15 + +No user-facing changes. + ## 0.3.14 No user-facing changes. diff --git a/swift/ql/src/change-notes/released/0.3.15.md b/swift/ql/src/change-notes/released/0.3.15.md new file mode 100644 index 000000000000..11fa7599e324 --- /dev/null +++ b/swift/ql/src/change-notes/released/0.3.15.md @@ -0,0 +1,3 @@ +## 0.3.15 + +No user-facing changes. diff --git a/swift/ql/src/codeql-pack.release.yml b/swift/ql/src/codeql-pack.release.yml index 1ff0ab05e829..469af066c19c 100644 --- a/swift/ql/src/codeql-pack.release.yml +++ b/swift/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.14 +lastReleaseVersion: 0.3.15 diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 735197aa4270..759f8ba34d17 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 0.3.15-dev +version: 0.3.16-dev groups: - swift - queries diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 5a1e142d9457..4456b1a4ac2d 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -794,8 +794,10 @@ | test.swift:680:10:680:11 | &... | test.swift:681:15:681:15 | x | | test.swift:680:11:680:11 | [post] x | test.swift:680:10:680:11 | &... | | test.swift:680:11:680:11 | x | test.swift:680:10:680:11 | &... | +| test.swift:680:11:680:11 | x | test.swift:680:15:680:15 | [post] y | | test.swift:680:14:680:15 | &... | test.swift:682:15:682:15 | y | | test.swift:680:15:680:15 | [post] y | test.swift:680:14:680:15 | &... | +| test.swift:680:15:680:15 | y | test.swift:680:11:680:11 | [post] x | | test.swift:680:15:680:15 | y | test.swift:680:14:680:15 | &... | | test.swift:686:9:686:9 | SSA def(arr1) | test.swift:687:15:687:15 | arr1 | | test.swift:686:9:686:9 | arr1 | test.swift:686:9:686:9 | SSA def(arr1) |