diff --git a/.codeqlmanifest.json b/.codeqlmanifest.json
index 58157b912c6..421284bc4b9 100644
--- a/.codeqlmanifest.json
+++ b/.codeqlmanifest.json
@@ -1,4 +1,6 @@
{ "provide": [ "*/ql/src/qlpack.yml",
+ "*/ql/test/qlpack.yml",
+ "*/upgrades/qlpack.yml",
"misc/legacy-support/*/qlpack.yml",
"misc/suite-helpers/qlpack.yml",
"codeql/.codeqlmanifest.json" ] }
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6c0714571fc..e074b1c2079 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,4 +1,4 @@
-# Contributing to QL
+# Contributing to CodeQL
We welcome contributions to our standard library and standard checks. Got an idea for a new check, or how to improve an existing query? Then please go ahead and open a pull request!
@@ -9,13 +9,13 @@ Before we accept your pull request, we require that you have agreed to our Contr
If you have an idea for a query that you would like to share with other Semmle users, please open a pull request to add it to this repository.
Follow the steps below to help other users understand what your query does, and to ensure that your query is consistent with the other Semmle queries.
-1. **Consult the QL documentation for query writers**
+1. **Consult the documentation for query writers**
- There is lots of useful documentation to help you write QL, ranging from information about query file structure to language-specific tutorials. For more information on the documentation available, see [Writing QL queries](https://help.semmle.com/QL/learn-ql/writing-queries/writing-queries.html) on [help.semmle.com](https://help.semmle.com).
+ There is lots of useful documentation to help you write queries, ranging from information about query file structure to tutorials for specific target languages. For more information on the documentation available, see [Writing CodeQL queries](https://help.semmle.com/QL/learn-ql/writing-queries/writing-queries.html) on [help.semmle.com](https://help.semmle.com).
-2. **Format your QL correctly**
+2. **Format your code correctly**
- All of Semmle's standard QL queries and libraries are uniformly formatted for clarity and consistency, so we strongly recommend that all QL contributions follow the same formatting guidelines. If you use QL for Eclipse, you can auto-format your query in the [QL editor](https://help.semmle.com/ql-for-eclipse/Content/WebHelp/ql-editor.html). For more information, see the [QL style guide](https://github.com/Semmle/ql/blob/master/docs/ql-style-guide.md).
+ All of Semmle's standard queries and libraries are uniformly formatted for clarity and consistency, so we strongly recommend that all contributions follow the same formatting guidelines. If you use QL for Eclipse, you can auto-format your query in the [QL editor](https://help.semmle.com/ql-for-eclipse/Content/WebHelp/ql-editor.html). For more information, see the [CodeQL style guide](https://github.com/Semmle/ql/blob/master/docs/ql-style-guide.md).
3. **Make sure your query has the correct metadata**
@@ -29,7 +29,7 @@ Follow the steps below to help other users understand what your query does, and
The `select` statement of your query must be compatible with the query type (determined by the `@kind` metadata property) for alert or path results to be displayed correctly in LGTM and QL for Eclipse.
For more information on `select` statement format, see [Introduction to query files](https://help.semmle.com/QL/learn-ql/writing-queries/introduction-to-queries.html#select-clause) on help.semmle.com.
-5. **Save your query in a `.ql` file in correct language directory in this repository**
+5. **Save your query in a `.ql` file in the correct language directory in this repository**
There are five language-specific directories in this repository:
@@ -54,7 +54,7 @@ repositories, which might be made public. We might also use this information
to contact you in relation to your contributions, as well as in the
normal course of software development. We also store records of your
CLA agreements. Under GDPR legislation, we do this
-on the basis of our legitimate interest in creating the QL product.
+on the basis of our legitimate interest in creating the CodeQL product.
Please do get in touch (privacy@semmle.com) if you have any questions about
this or our data protection policies.
diff --git a/README.md b/README.md
index b483d29cae2..3c73253b6df 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,16 @@
-# Semmle QL
+# CodeQL
-This open source repository contains the standard QL libraries and queries that power [LGTM](https://lgtm.com), and the other products that [Semmle](https://semmle.com) makes available to its customers worldwide.
+This open source repository contains the standard CodeQL libraries and queries that power [LGTM](https://lgtm.com), and the other products that [Semmle](https://semmle.com) makes available to its customers worldwide.
-## How do I learn QL and run queries?
+## How do I learn CodeQL and run queries?
-There is [extensive documentation](https://help.semmle.com/QL/learn-ql/) on getting started with writing QL.
-You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [QL for Eclipse](https://lgtm.com/help/lgtm/running-queries-ide) plugin to try out your queries on any open-source project that's currently being analyzed.
+There is [extensive documentation](https://help.semmle.com/QL/learn-ql/) on getting started with writing CodeQL.
+You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [QL for Eclipse](https://lgtm.com/help/lgtm/running-queries-ide) plugin to try out your queries on any open source project that's currently being analyzed.
## Contributing
-We welcome contributions to our standard library and standard checks. Do you have an idea for a new check, or how to improve an existing query? Then please go ahead and open a pull request! Before you do, though, please take the time to read our [contributing guidelines](CONTRIBUTING.md). You can also consult our [style guides](https://github.com/Semmle/ql/tree/master/docs) to learn how to format your QL for consistency and clarity, how to write query metadata, and how to write query help documentation for your query.
+We welcome contributions to our standard library and standard checks. Do you have an idea for a new check, or how to improve an existing query? Then please go ahead and open a pull request! Before you do, though, please take the time to read our [contributing guidelines](CONTRIBUTING.md). You can also consult our [style guides](https://github.com/Semmle/ql/tree/master/docs) to learn how to format your code for consistency and clarity, how to write query metadata, and how to write query help documentation for your query.
## License
-The QL queries in this repository are licensed under [Apache License 2.0](LICENSE) by [Semmle](https://semmle.com).
+The code in this repository is licensed under [Apache License 2.0](LICENSE) by [Semmle](https://semmle.com).
diff --git a/change-notes/1.23/analysis-cpp.md b/change-notes/1.23/analysis-cpp.md
index 64e9b98fcfb..87910b0d6a5 100644
--- a/change-notes/1.23/analysis-cpp.md
+++ b/change-notes/1.23/analysis-cpp.md
@@ -9,6 +9,7 @@ The following changes in version 1.23 affect C/C++ analysis in all applications.
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
| Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) | reliability, japanese-era | This query is a combination of two old queries that were identical in purpose but separate as an implementation detail. This new query replaces Hard-coded Japanese era start date in call (`cpp/japanese-era/constructor-or-method-with-exact-era-date`) and Hard-coded Japanese era start date in struct (`cpp/japanese-era/struct-with-exact-era-date`). |
+| Signed overflow check (`cpp/signed-overflow-check`) | correctness, reliability | Finds overflow checks that rely on signed integer addition to overflow, which has undefined behavior. Example: `a + b < a`. |
## Changes to existing queries
@@ -23,8 +24,10 @@ The following changes in version 1.23 affect C/C++ analysis in all applications.
| Too many arguments to formatting function (`cpp/too-many-format-arguments`) | Fewer false positive results | Fixed false positives resulting from mistmatching declarations of a formatting function. |
| Unclear comparison precedence (`cpp/comparison-precedence`) | Fewer false positive results | False positives involving template classes and functions have been fixed. |
| Comparison of narrow type with wide type in loop condition (`cpp/comparison-with-wider-type`) | Higher precision | The precision of this query has been increased to "high" as the alerts from this query have proved to be valuable on real-world projects. With this precision, results are now displayed by default in LGTM. |
+| Non-constant format string (`cpp/non-constant-format`) | Fewer false positive results | Fixed false positives resulting from mistmatching declarations of a formatting function. |
+| Wrong type of arguments to formatting function (`cpp/wrong-type-format-argument`) | More correct results and fewer false positive results | This query now understands explicitly specified argument numbers in format strings, such as the `1$` in `%1$s`. |
-## Changes to QL libraries
+## Changes to libraries
* The data-flow library has been extended with a new feature to aid debugging.
Instead of specifying `isSink(Node n) { any() }` on a configuration to
@@ -39,6 +42,10 @@ The following changes in version 1.23 affect C/C++ analysis in all applications.
definition of `x` when `x` is a variable of pointer type. It no longer
considers deep paths such as `f(&x.myField)` to be definitions of `x`. These
changes are in line with the user expectations we've observed.
+* The data-flow library now makes it easier to specify barriers/sanitizers
+ arising from guards by overriding the predicate
+ `isBarrierGuard`/`isSanitizerGuard` on data-flow and taint-tracking
+ configurations respectively.
* There is now a `DataFlow::localExprFlow` predicate and a
`TaintTracking::localExprTaint` predicate to make it easy to use the most
common case of local data flow and taint: from one `Expr` to another.
@@ -46,7 +53,14 @@ The following changes in version 1.23 affect C/C++ analysis in all applications.
clarity (e.g. `isOutReturnPointer()` to `isReturnValueDeref()`). The existing member predicates
have been deprecated, and will be removed in a future release. Code that uses the old member
predicates should be updated to use the corresponding new member predicate.
+* The predicates `Declaration.hasStdName()` and `Declaration.hasGlobalOrStdName`
+ have been added, simplifying handling of C++ standard library functions.
* The control-flow graph is now computed in QL, not in the extractor. This can
lead to regressions (or improvements) in how queries are optimized because
optimization in QL relies on static size estimates, and the control-flow edge
relations will now have different size estimates than before.
+* Support has been added for non-type template arguments. This means that the
+ return type of `Declaration::getTemplateArgument()` and
+ `Declaration::getATemplateArgument` have changed to `Locatable`. See the
+ documentation for `Declaration::getTemplateArgument()` and
+ `Declaration::getTemplateArgumentKind()` for details.
diff --git a/change-notes/1.23/analysis-csharp.md b/change-notes/1.23/analysis-csharp.md
index 7ec412a0eb2..c5bdae38dcd 100644
--- a/change-notes/1.23/analysis-csharp.md
+++ b/change-notes/1.23/analysis-csharp.md
@@ -8,7 +8,10 @@ The following changes in version 1.23 affect C# analysis in all applications.
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
+| Deserialized delegate (`cs/deserialized-delegate`) | security, external/cwe/cwe-502 | Finds unsafe deserialization of delegate types. |
+| Deserialization of untrusted data (`cs/unsafe-deserialization-untrusted-input`) | security, external/cwe/cwe-502 | Finds flow of untrusted input to calls to unsafe deserializers. |
| Unsafe year argument for 'DateTime' constructor (`cs/unsafe-year-construction`) | reliability, date-time | Finds incorrect manipulation of `DateTime` values, which could lead to invalid dates. |
+| Unsafe deserializer (`cs/unsafe-deserialization`) | security, external/cwe/cwe-502 | Finds calls to unsafe deserializers. |
| Mishandling the Japanese era start date (`cs/mishandling-japanese-era`) | reliability, date-time | Finds hard-coded Japanese era start dates that could be invalid. |
## Changes to existing queries
@@ -24,7 +27,7 @@ The following changes in version 1.23 affect C# analysis in all applications.
* `nameof` expressions are now extracted correctly when the name is a namespace.
-## Changes to QL libraries
+## Changes to libraries
* The new class `NamespaceAccess` models accesses to namespaces, for example in `nameof` expressions.
* The data-flow library now makes it easier to specify barriers/sanitizers
@@ -43,5 +46,7 @@ The following changes in version 1.23 affect C# analysis in all applications.
* There is now a `DataFlow::localExprFlow` predicate and a
`TaintTracking::localExprTaint` predicate to make it easy to use the most
common case of local data flow and taint: from one `Expr` to another.
+* Data is now tracked through null-coalescing expressions (`??`).
+* A new library `semmle.code.csharp.Unification` has been added. This library exposes two predicates `unifiable` and `subsumes` for calculating type unification and type subsumption, respectively.
## Changes to autobuilder
diff --git a/change-notes/1.23/analysis-java.md b/change-notes/1.23/analysis-java.md
index b81b681aac5..8c38f57e9d2 100644
--- a/change-notes/1.23/analysis-java.md
+++ b/change-notes/1.23/analysis-java.md
@@ -19,7 +19,7 @@ The following changes in version 1.23 affect Java analysis in all applications.
| Query built without neutralizing special characters (`java/concatenated-sql-query`) | More results | The query now identifies arguments to `Statement.executeLargeUpdate` and `Connection.prepareCall` as SQL expressions sinks. |
| Useless comparison test (`java/constant-comparison`) | Fewer false positives | Additional overflow check patterns are now recognized and no longer reported. |
-## Changes to QL libraries
+## Changes to libraries
* The data-flow library has been extended with a new feature to aid debugging.
Instead of specifying `isSink(Node n) { any() }` on a configuration to
diff --git a/change-notes/1.23/analysis-javascript.md b/change-notes/1.23/analysis-javascript.md
index aa9d2086d14..b70ec5d47ba 100644
--- a/change-notes/1.23/analysis-javascript.md
+++ b/change-notes/1.23/analysis-javascript.md
@@ -2,7 +2,9 @@
## General improvements
-* Suppor for `globalThis` has been added.
+* Automatic classification of generated and minified files has been improved, in particular files generated by Doxygen are now recognized.
+
+* Support for `globalThis` has been added.
* Support for the following frameworks and libraries has been improved:
- [firebase](https://www.npmjs.com/package/firebase)
@@ -12,8 +14,7 @@
* The call graph has been improved to resolve method calls in more cases. This may produce more security alerts.
-* TypeScript 3.6 features are supported.
-
+* TypeScript 3.6 and 3.7 features are now supported.
## New queries
@@ -26,6 +27,7 @@
| Use of returnless function (`js/use-of-returnless-function`) | maintainability, correctness | Highlights calls where the return value is used, but the callee never returns a value. Results are shown on LGTM by default. |
| Useless regular expression character escape (`js/useless-regexp-character-escape`) | correctness, security, external/cwe/cwe-20 | Highlights regular expression strings with useless character escapes, indicating a possible violation of [CWE-20](https://cwe.mitre.org/data/definitions/20.html). Results are shown on LGTM by default. |
| Unreachable method overloads (`js/unreachable-method-overloads`) | correctness, typescript | Highlights method overloads that are impossible to use from client code. Results are shown on LGTM by default. |
+| Ignoring result from pure array method (`js/ignore-array-result`) | maintainability, correctness | Highlights calls to array methods without side effects where the return value is ignored. Results are shown on LGTM by default. |
## Changes to existing queries
@@ -44,8 +46,9 @@
| Stored cross-site scripting (`js/stored-xss`) | Fewer false-positive results | The query now recognizes more sanitizers. |
| Uncontrolled command line (`js/command-line-injection`) | More results | This query now treats responses from servers as untrusted. |
| Uncontrolled data used in path expression (`js/path-injection`) | Fewer false-positive results | This query now recognizes calls to Express `sendFile` as safe in some cases. |
+| Unknown directive (`js/unknown-directive`) | Fewer false positive results | This query no longer flags uses of ":", which is sometimes used like a directive. |
-## Changes to QL libraries
+## Changes to libraries
* `Expr.getDocumentation()` now handles chain assignments.
diff --git a/change-notes/1.23/analysis-python.md b/change-notes/1.23/analysis-python.md
index 00fab13e098..6cea1745284 100644
--- a/change-notes/1.23/analysis-python.md
+++ b/change-notes/1.23/analysis-python.md
@@ -20,3 +20,8 @@
|----------------------------|------------------------|------------|
| Unreachable code | Fewer false positives | Analysis now accounts for uses of `contextlib.suppress` to suppress exceptions. |
| `__iter__` method returns a non-iterator | Better alert message | Alert now highlights which class is expected to be an iterator. |
+
+
+## Changes to QL libraries
+
+* Django library now recognizes positional arguments from a `django.conf.urls.url` regex (Django version 1.x)
diff --git a/change-notes/support/README.md b/change-notes/support/README.md
index 7813c69523d..f111a437183 100644
--- a/change-notes/support/README.md
+++ b/change-notes/support/README.md
@@ -1,6 +1,6 @@
# Files moved to ``docs`` directory
-Now that all of the QL documentation is in this repository,
+Now that all of the CodeQL documentation is in this repository,
notes on the languages, compilers, and frameworks supported have moved.
They're now stored as part of the Sphinx ``support`` project with the other documentation:
``docs/language/support``.
diff --git a/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.ql b/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.ql
index 26cf42521e5..3ad43998d18 100644
--- a/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.ql
+++ b/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.ql
@@ -21,6 +21,7 @@ from Variable v
where
v.isStatic() and
v.hasDefinition() and
+ not v.isConstexpr() and
not exists(VariableAccess a | a.getTarget() = v) and
not v instanceof MemberVariable and
not declarationHasSideEffects(v) and
diff --git a/cpp/ql/src/Critical/DescriptorMayNotBeClosed.ql b/cpp/ql/src/Critical/DescriptorMayNotBeClosed.ql
index 9c93e066119..47401c6eea5 100644
--- a/cpp/ql/src/Critical/DescriptorMayNotBeClosed.ql
+++ b/cpp/ql/src/Critical/DescriptorMayNotBeClosed.ql
@@ -13,7 +13,7 @@ import semmle.code.cpp.pointsto.PointsTo
import Negativity
predicate closeCall(FunctionCall fc, Variable v) {
- fc.getTarget().hasGlobalName("close") and v.getAnAccess() = fc.getArgument(0)
+ fc.getTarget().hasGlobalOrStdName("close") and v.getAnAccess() = fc.getArgument(0)
or
exists(FunctionCall midcall, Function mid, int arg |
fc.getArgument(arg) = v.getAnAccess() and
diff --git a/cpp/ql/src/Critical/DescriptorNeverClosed.ql b/cpp/ql/src/Critical/DescriptorNeverClosed.ql
index b52af1bf2a3..f06708f4ae3 100644
--- a/cpp/ql/src/Critical/DescriptorNeverClosed.ql
+++ b/cpp/ql/src/Critical/DescriptorNeverClosed.ql
@@ -13,7 +13,7 @@ import semmle.code.cpp.pointsto.PointsTo
predicate closed(Expr e) {
exists(FunctionCall fc |
- fc.getTarget().hasGlobalName("close") and
+ fc.getTarget().hasGlobalOrStdName("close") and
fc.getArgument(0) = e
)
}
diff --git a/cpp/ql/src/Critical/MemoryMayNotBeFreed.ql b/cpp/ql/src/Critical/MemoryMayNotBeFreed.ql
index 9bba8e9896d..2bede681912 100644
--- a/cpp/ql/src/Critical/MemoryMayNotBeFreed.ql
+++ b/cpp/ql/src/Critical/MemoryMayNotBeFreed.ql
@@ -53,7 +53,7 @@ predicate allocCallOrIndirect(Expr e) {
* can cause memory leaks.
*/
predicate verifiedRealloc(FunctionCall reallocCall, Variable v, ControlFlowNode verified) {
- reallocCall.getTarget().hasGlobalName("realloc") and
+ reallocCall.getTarget().hasGlobalOrStdName("realloc") and
reallocCall.getArgument(0) = v.getAnAccess() and
(
exists(Variable newV, ControlFlowNode node |
@@ -79,7 +79,7 @@ predicate verifiedRealloc(FunctionCall reallocCall, Variable v, ControlFlowNode
predicate freeCallOrIndirect(ControlFlowNode n, Variable v) {
// direct free call
freeCall(n, v.getAnAccess()) and
- not n.(FunctionCall).getTarget().hasGlobalName("realloc")
+ not n.(FunctionCall).getTarget().hasGlobalOrStdName("realloc")
or
// verified realloc call
verifiedRealloc(_, v, n)
diff --git a/cpp/ql/src/Critical/OverflowCalculated.ql b/cpp/ql/src/Critical/OverflowCalculated.ql
index 36ee0140cf7..fbca4a20a8f 100644
--- a/cpp/ql/src/Critical/OverflowCalculated.ql
+++ b/cpp/ql/src/Critical/OverflowCalculated.ql
@@ -13,10 +13,7 @@
import cpp
class MallocCall extends FunctionCall {
- MallocCall() {
- this.getTarget().hasGlobalName("malloc") or
- this.getTarget().hasQualifiedName("std", "malloc")
- }
+ MallocCall() { this.getTarget().hasGlobalOrStdName("malloc") }
Expr getAllocatedSize() {
if this.getArgument(0) instanceof VariableAccess
@@ -36,12 +33,12 @@ predicate spaceProblem(FunctionCall append, string msg) {
malloc.getAllocatedSize() = add and
buffer.getAnAccess() = strlen.getStringExpr() and
(
- insert.getTarget().hasGlobalName("strcpy") or
- insert.getTarget().hasGlobalName("strncpy")
+ insert.getTarget().hasGlobalOrStdName("strcpy") or
+ insert.getTarget().hasGlobalOrStdName("strncpy")
) and
(
- append.getTarget().hasGlobalName("strcat") or
- append.getTarget().hasGlobalName("strncat")
+ append.getTarget().hasGlobalOrStdName("strcat") or
+ append.getTarget().hasGlobalOrStdName("strncat")
) and
malloc.getASuccessor+() = insert and
insert.getArgument(1) = buffer.getAnAccess() and
diff --git a/cpp/ql/src/Critical/OverflowDestination.ql b/cpp/ql/src/Critical/OverflowDestination.ql
index d7b02b5d8d5..ad925daed62 100644
--- a/cpp/ql/src/Critical/OverflowDestination.ql
+++ b/cpp/ql/src/Critical/OverflowDestination.ql
@@ -25,7 +25,7 @@ import semmle.code.cpp.security.TaintTracking
predicate sourceSized(FunctionCall fc, Expr src) {
exists(string name |
(name = "strncpy" or name = "strncat" or name = "memcpy" or name = "memmove") and
- fc.getTarget().hasGlobalName(name)
+ fc.getTarget().hasGlobalOrStdName(name)
) and
exists(Expr dest, Expr size, Variable v |
fc.getArgument(0) = dest and
diff --git a/cpp/ql/src/Critical/OverflowStatic.ql b/cpp/ql/src/Critical/OverflowStatic.ql
index 1892d5acff1..82ffc879331 100644
--- a/cpp/ql/src/Critical/OverflowStatic.ql
+++ b/cpp/ql/src/Critical/OverflowStatic.ql
@@ -60,19 +60,19 @@ predicate overflowOffsetInLoop(BufferAccess bufaccess, string msg) {
predicate bufferAndSizeFunction(Function f, int buf, int size) {
f.hasGlobalName("read") and buf = 1 and size = 2
or
- f.hasGlobalName("fgets") and buf = 0 and size = 1
+ f.hasGlobalOrStdName("fgets") and buf = 0 and size = 1
or
- f.hasGlobalName("strncpy") and buf = 0 and size = 2
+ f.hasGlobalOrStdName("strncpy") and buf = 0 and size = 2
or
- f.hasGlobalName("strncat") and buf = 0 and size = 2
+ f.hasGlobalOrStdName("strncat") and buf = 0 and size = 2
or
- f.hasGlobalName("memcpy") and buf = 0 and size = 2
+ f.hasGlobalOrStdName("memcpy") and buf = 0 and size = 2
or
- f.hasGlobalName("memmove") and buf = 0 and size = 2
+ f.hasGlobalOrStdName("memmove") and buf = 0 and size = 2
or
- f.hasGlobalName("snprintf") and buf = 0 and size = 1
+ f.hasGlobalOrStdName("snprintf") and buf = 0 and size = 1
or
- f.hasGlobalName("vsnprintf") and buf = 0 and size = 1
+ f.hasGlobalOrStdName("vsnprintf") and buf = 0 and size = 1
}
class CallWithBufferSize extends FunctionCall {
diff --git a/cpp/ql/src/Critical/SizeCheck.ql b/cpp/ql/src/Critical/SizeCheck.ql
index da841b73c9b..313763ba56c 100644
--- a/cpp/ql/src/Critical/SizeCheck.ql
+++ b/cpp/ql/src/Critical/SizeCheck.ql
@@ -17,12 +17,12 @@ import cpp
class Allocation extends FunctionCall {
Allocation() {
exists(string name |
- this.getTarget().hasGlobalName(name) and
+ this.getTarget().hasGlobalOrStdName(name) and
(name = "malloc" or name = "calloc" or name = "realloc")
)
}
- private string getName() { this.getTarget().hasGlobalName(result) }
+ private string getName() { this.getTarget().hasGlobalOrStdName(result) }
int getSize() {
this.getName() = "malloc" and
diff --git a/cpp/ql/src/Critical/SizeCheck2.ql b/cpp/ql/src/Critical/SizeCheck2.ql
index 3cb5d1d28b0..1b716d79d49 100644
--- a/cpp/ql/src/Critical/SizeCheck2.ql
+++ b/cpp/ql/src/Critical/SizeCheck2.ql
@@ -17,12 +17,12 @@ import cpp
class Allocation extends FunctionCall {
Allocation() {
exists(string name |
- this.getTarget().hasGlobalName(name) and
+ this.getTarget().hasGlobalOrStdName(name) and
(name = "malloc" or name = "calloc" or name = "realloc")
)
}
- private string getName() { this.getTarget().hasGlobalName(result) }
+ private string getName() { this.getTarget().hasGlobalOrStdName(result) }
int getSize() {
this.getName() = "malloc" and
diff --git a/cpp/ql/src/Critical/UseAfterFree.ql b/cpp/ql/src/Critical/UseAfterFree.ql
index db78c206ea1..9efbb6c3b44 100644
--- a/cpp/ql/src/Critical/UseAfterFree.ql
+++ b/cpp/ql/src/Critical/UseAfterFree.ql
@@ -16,7 +16,7 @@ import semmle.code.cpp.controlflow.LocalScopeVariableReachability
predicate isFreeExpr(Expr e, LocalScopeVariable v) {
exists(VariableAccess va | va.getTarget() = v |
exists(FunctionCall fc | fc = e |
- fc.getTarget().hasGlobalName("free") and
+ fc.getTarget().hasGlobalOrStdName("free") and
va = fc.getArgument(0)
)
or
diff --git a/cpp/ql/src/DefaultOptions.qll b/cpp/ql/src/DefaultOptions.qll
index 27e5584369e..3e03ec9ee65 100644
--- a/cpp/ql/src/DefaultOptions.qll
+++ b/cpp/ql/src/DefaultOptions.qll
@@ -59,7 +59,7 @@ class Options extends string {
predicate exits(Function f) {
f.getAnAttribute().hasName("noreturn")
or
- exists(string name | f.hasGlobalName(name) |
+ exists(string name | f.hasGlobalOrStdName(name) |
name = "exit" or
name = "_exit" or
name = "abort" or
@@ -91,7 +91,7 @@ class Options extends string {
* By default holds only for `fgets`.
*/
predicate alwaysCheckReturnValue(Function f) {
- f.hasGlobalName("fgets") or
+ f.hasGlobalOrStdName("fgets") or
CustomOptions::alwaysCheckReturnValue(f) // old Options.qll
}
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql
index afe49a1053b..c89ba211bbc 100644
--- a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql
@@ -19,6 +19,7 @@ where
pointlessSelfComparison(cmp) and
not nanTest(cmp) and
not overflowTest(cmp) and
+ not cmp.isFromTemplateInstantiation(_) and
not exists(MacroInvocation mi |
// cmp is in mi
mi.getAnExpandedElement() = cmp and
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-bad1.cpp b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-bad1.cpp
new file mode 100644
index 00000000000..e50273aacde
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-bad1.cpp
@@ -0,0 +1,3 @@
+bool foo(int n1, unsigned short delta) {
+ return n1 + delta < n1; // BAD
+}
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-bad2.cpp b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-bad2.cpp
new file mode 100644
index 00000000000..7f69e374ed1
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-bad2.cpp
@@ -0,0 +1,4 @@
+bool bar(unsigned short n1, unsigned short delta) {
+ // NB: Comparison is always false
+ return n1 + delta < n1; // GOOD (but misleading)
+}
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-good1.cpp b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-good1.cpp
new file mode 100644
index 00000000000..424684ee2ec
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-good1.cpp
@@ -0,0 +1,4 @@
+#include
+bool foo(int n1, unsigned short delta) {
+ return n1 > INT_MAX - delta; // GOOD
+}
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-good2.cpp b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-good2.cpp
new file mode 100644
index 00000000000..de8de2b9847
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-good2.cpp
@@ -0,0 +1,3 @@
+bool bar(unsigned short n1, unsigned short delta) {
+ return (unsigned short)(n1 + delta) < n1; // GOOD
+}
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.qhelp b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.qhelp
new file mode 100644
index 00000000000..621ae3273fd
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.qhelp
@@ -0,0 +1,115 @@
+
+
+
+
+When checking for integer overflow, you may often write tests like
+a + b < a. This works fine if a or
+b are unsigned integers, since any overflow in the addition
+will cause the value to simply "wrap around." However, using
+signed integers is problematic because signed overflow has undefined
+behavior according to the C and C++ standards. If the addition overflows
+and has an undefined result, the comparison will likewise be undefined;
+it may produce an unintended result, or may be deleted entirely by an
+optimizing compiler.
+
+
+
+
+Solutions to this problem can be thought of as falling into one of two
+categories: (1) rewrite the signed expression so that overflow cannot occur
+but the signedness remains, or (2) rewrite (or cast) the signed expression
+into unsigned form.
+
+
+
+Below we list examples of expressions where signed overflow may
+occur, along with proposed solutions. The list should not be
+considered exhaustive.
+
+
+
+Given unsigned short i, delta and i + delta < i,
+it is possible to rewrite it as (unsigned short)(i + delta) < i.
+Note that i + deltadoes not actually overflow, due to int promotion
+
+
+
+Given unsigned short i, delta and i + delta < i,
+it is also possible to rewrite it as USHORT_MAX - delta. It must be true
+that delta > 0 and the limits.h or climits
+header has been included.
+
+
+
+Given int i, delta and i + delta < i,
+it is possible to rewrite it as INT_MAX - delta. It must be true
+that delta > 0 and the limits.h or climits
+header has been included.
+
+
+
+Given int i, delta and i + delta < i,
+it is also possible to rewrite it as (unsigned)i + delta < i.
+Note that program semantics are affected by this change.
+
+
+
+Given int i, delta and i + delta < i,
+it is also possible to rewrite it as unsigned int i, delta and
+i + delta < i. Note that program semantics are
+affected by this change.
+
+
+
+
+
+In the following example, even though delta has been declared
+unsigned short, C/C++ type promotion rules require that its
+type is promoted to the larger type used in the addition and comparison,
+namely a signed int. Addition is performed on
+signed integers, and may have undefined behavior if an overflow occurs.
+As a result, the entire (comparison) expression may also have an undefined
+result.
+
+
+
+The following example builds upon the previous one. Instead of
+performing an addition (which could overflow), we have re-framed the
+solution so that a subtraction is used instead. Since delta
+is promoted to a signed int and INT_MAX denotes
+the largest possible positive value for an signed int,
+the expression INT_MAX - delta can never be less than zero
+or more than INT_MAX. Hence, any overflow and underflow
+are avoided.
+
+
+
+In the following example, even though both n and delta
+have been declared unsigned short, both are promoted to
+signed int prior to addition. Because we started out with the
+narrower short type, the addition is guaranteed not to overflow
+and is therefore defined. But the fact that n1 + delta never
+overflows means that the condition n1 + delta < n1 will never
+hold true, which likely is not what the programmer intended. (see also the
+cpp/bad-addition-overflow-check query).
+
+
+
+The next example provides a solution to the previous one. Even though
+i + delta does not overflow, casting it to an
+unsigned short truncates the addition modulo 2^16,
+so that unsigned short "wrap around" may now be observed.
+Furthermore, since the left-hand side is now of type unsigned short,
+the right-hand side does not need to be promoted to a signed int.
+
+
+
+
+
+comp.lang.c FAQ list ยท Question 3.19 (Preserving rules)
+INT31-C. Ensure that integer conversions do not result in lost or misinterpreted data
+W. Dietz, P. Li, J. Regehr, V. Adve. Understanding Integer Overflow in C/C++
+
+
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.ql b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.ql
new file mode 100644
index 00000000000..648846a7dc1
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.ql
@@ -0,0 +1,31 @@
+/**
+ * @name Undefined result of signed test for overflow
+ * @description Testing for overflow by adding a value to a variable
+ * to see if it "wraps around" works only for
+ * unsigned integer values.
+ * @kind problem
+ * @problem.severity warning
+ * @precision high
+ * @id cpp/signed-overflow-check
+ * @tags reliability
+ * security
+ */
+
+import cpp
+private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
+private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
+
+from RelationalOperation ro, AddExpr add, Expr expr1, Expr expr2
+where
+ ro.getAnOperand() = add and
+ add.getAnOperand() = expr1 and
+ ro.getAnOperand() = expr2 and
+ globalValueNumber(expr1) = globalValueNumber(expr2) and
+ add.getUnspecifiedType().(IntegralType).isSigned() and
+ not exists(MacroInvocation mi | mi.getAnAffectedElement() = add) and
+ exprMightOverflowPositively(add) and
+ exists(Compilation c | c.getAFileCompiled() = ro.getFile() |
+ not c.getAnArgument() = "-fwrapv" and
+ not c.getAnArgument() = "-fno-strict-overflow"
+ )
+select ro, "Testing for signed overflow may produce undefined results."
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBound.qll b/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBound.qll
deleted file mode 100644
index 3e1f74bfbed..00000000000
--- a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBound.qll
+++ /dev/null
@@ -1,33 +0,0 @@
-import cpp
-import semmle.code.cpp.dataflow.DataFlow
-import semmle.code.cpp.controlflow.Guards
-import BufferAccess
-import semmle.code.cpp.valuenumbering.GlobalValueNumbering
-
-class NetworkFunctionCall extends FunctionCall {
- NetworkFunctionCall() {
- getTarget().hasName("ntohd") or
- getTarget().hasName("ntohf") or
- getTarget().hasName("ntohl") or
- getTarget().hasName("ntohll") or
- getTarget().hasName("ntohs")
- }
-}
-
-class NetworkToBufferSizeConfiguration extends DataFlow::Configuration {
- NetworkToBufferSizeConfiguration() { this = "NetworkToBufferSizeConfiguration" }
-
- override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof NetworkFunctionCall }
-
- override predicate isSink(DataFlow::Node node) {
- node.asExpr() = any(BufferAccess ba).getAccessedLength()
- }
-
- override predicate isBarrier(DataFlow::Node node) {
- exists(GuardCondition gc, GVN gvn |
- gc.getAChild*() = gvn.getAnExpr() and
- globalValueNumber(node.asExpr()) = gvn and
- gc.controls(node.asExpr().getBasicBlock(), _)
- )
- }
-}
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayBad.cpp b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound-bad.cpp
similarity index 100%
rename from cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayBad.cpp
rename to cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound-bad.cpp
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayGood.cpp b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound-good.cpp
similarity index 100%
rename from cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayGood.cpp
rename to cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound-good.cpp
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBoundOpenSource.qhelp b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qhelp
similarity index 90%
rename from cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBoundOpenSource.qhelp
rename to cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qhelp
index 522d6cde74c..3556df38c58 100644
--- a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBoundOpenSource.qhelp
+++ b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qhelp
@@ -14,7 +14,7 @@ byte order function, such as ntohl.
The use of a network-to-host byte order function is therefore a good indicator that the returned
value is unvalidated data retrieved from the network, and should not be used without further
validation. In particular, the returned value should not be used as an array index or array length
-value without validation, which may result in a buffer overflow vulnerability.
+value without validation, as this could result in a buffer overflow vulnerability.
@@ -31,10 +31,10 @@ it to host byte order. The data is then used as an index in an array access expr
there is no validation that the data returned by ntohl is within the bounds of the array,
which could lead to reading outside the bounds of the buffer.
-
+
In the corrected example, the returned data is validated against the known size of the buffer,
before being used as an array index.
-
+
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBoundOpenSource.ql b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.ql
similarity index 100%
rename from cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBoundOpenSource.ql
rename to cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.ql
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/BufferAccess.qll b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll
similarity index 71%
rename from cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/BufferAccess.qll
rename to cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll
index 286db31020f..0871da2f92e 100644
--- a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/BufferAccess.qll
+++ b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll
@@ -1,55 +1,7 @@
import cpp
-import semmle.code.cpp.dataflow.TaintTracking
-private import semmle.code.cpp.dataflow.RecursionPrevention
-
-/**
- * A buffer which includes an allocation size.
- */
-abstract class BufferWithSize extends DataFlow::Node {
- abstract Expr getSizeExpr();
-
- BufferAccess getAnAccess() {
- any(BufferWithSizeConfig bsc).hasFlow(this, DataFlow::exprNode(result.getPointer()))
- }
-}
-
-/** An allocation function. */
-abstract class Alloc extends Function { }
-
-/**
- * Allocation functions identified by the QL for C/C++ standard library.
- */
-class DefaultAlloc extends Alloc {
- DefaultAlloc() { allocationFunction(this) }
-}
-
-/** A buffer created through a call to an allocation function. */
-class AllocBuffer extends BufferWithSize {
- FunctionCall call;
-
- AllocBuffer() {
- asExpr() = call and
- call.getTarget() instanceof Alloc
- }
-
- override Expr getSizeExpr() { result = call.getArgument(0) }
-}
-
-/**
- * Find accesses of buffers for which we have a size expression.
- */
-private class BufferWithSizeConfig extends TaintTracking::Configuration {
- BufferWithSizeConfig() { this = "BufferWithSize" }
-
- override predicate isSource(DataFlow::Node n) { n = any(BufferWithSize b) }
-
- override predicate isSink(DataFlow::Node n) { n.asExpr() = any(BufferAccess ae).getPointer() }
-
- override predicate isSanitizer(DataFlow::Node s) {
- s = any(BufferWithSize b) and
- s.asExpr().getControlFlowScope() instanceof Alloc
- }
-}
+import semmle.code.cpp.dataflow.DataFlow
+import semmle.code.cpp.controlflow.Guards
+import semmle.code.cpp.valuenumbering.GlobalValueNumbering
/**
* An access (read or write) to a buffer, provided as a pair of
@@ -172,3 +124,31 @@ class MallocSizeExpr extends BufferAccess, FunctionCall {
override Expr getAccessedLength() { result = getArgument(1) }
}
+
+class NetworkFunctionCall extends FunctionCall {
+ NetworkFunctionCall() {
+ getTarget().hasName("ntohd") or
+ getTarget().hasName("ntohf") or
+ getTarget().hasName("ntohl") or
+ getTarget().hasName("ntohll") or
+ getTarget().hasName("ntohs")
+ }
+}
+
+class NetworkToBufferSizeConfiguration extends DataFlow::Configuration {
+ NetworkToBufferSizeConfiguration() { this = "NetworkToBufferSizeConfiguration" }
+
+ override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof NetworkFunctionCall }
+
+ override predicate isSink(DataFlow::Node node) {
+ node.asExpr() = any(BufferAccess ba).getAccessedLength()
+ }
+
+ override predicate isBarrier(DataFlow::Node node) {
+ exists(GuardCondition gc, GVN gvn |
+ gc.getAChild*() = gvn.getAnExpr() and
+ globalValueNumber(node.asExpr()) = gvn and
+ gc.controls(node.asExpr().getBasicBlock(), _)
+ )
+ }
+}
diff --git a/cpp/ql/src/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.qhelp b/cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.qhelp
similarity index 100%
rename from cpp/ql/src/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.qhelp
rename to cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.qhelp
diff --git a/cpp/ql/src/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.ql b/cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.ql
similarity index 50%
rename from cpp/ql/src/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.ql
rename to cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.ql
index 83ed90bafab..53ad71cb22d 100644
--- a/cpp/ql/src/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.ql
+++ b/cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.ql
@@ -13,32 +13,33 @@ import semmle.code.cpp.security.boostorg.asio.protocols
class ExistsAnyFlowConfig extends DataFlow::Configuration {
ExistsAnyFlowConfig() { this = "ExistsAnyFlowConfig" }
- override predicate isSource(DataFlow::Node source) { any() }
+ override predicate isSource(DataFlow::Node source) {
+ exists(BoostorgAsio::SslContextClass c | c.getAContructorCall() = source.asExpr())
+ }
- override predicate isSink(DataFlow::Node sink) { any() }
+ override predicate isSink(DataFlow::Node sink) {
+ exists(BoostorgAsio::SslSetOptionsFunction f, FunctionCall fcSetOptions |
+ f.getACallToThisFunction() = fcSetOptions and
+ fcSetOptions.getQualifier() = sink.asExpr()
+ )
+ }
}
bindingset[flag]
predicate isOptionSet(ConstructorCall cc, int flag, FunctionCall fcSetOptions) {
- exists(
- BoostorgAsio::SslContextFlowsToSetOptionConfig config, ExistsAnyFlowConfig testConfig,
- Expr optionsSink
- |
- config.hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(optionsSink)) and
- exists(VariableAccess contextSetOptions |
- testConfig.hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(contextSetOptions)) and
- exists(BoostorgAsio::SslSetOptionsFunction f | f.getACallToThisFunction() = fcSetOptions |
- contextSetOptions = fcSetOptions.getQualifier() and
- forall(
- Expr optionArgument, BoostorgAsio::SslOptionConfig optionArgConfig,
- Expr optionArgumentSource
- |
- optionArgument = fcSetOptions.getArgument(0) and
- optionArgConfig
- .hasFlow(DataFlow::exprNode(optionArgumentSource), DataFlow::exprNode(optionArgument))
- |
- optionArgument.getValue().toInt().bitShiftRight(16).bitAnd(flag) = flag
- )
+ exists(ExistsAnyFlowConfig anyFlowConfig, VariableAccess contextSetOptions |
+ anyFlowConfig.hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(contextSetOptions)) and
+ exists(BoostorgAsio::SslSetOptionsFunction f | f.getACallToThisFunction() = fcSetOptions |
+ contextSetOptions = fcSetOptions.getQualifier() and
+ forall(
+ Expr optionArgument, BoostorgAsio::SslOptionConfig optionArgConfig,
+ Expr optionArgumentSource
+ |
+ optionArgument = fcSetOptions.getArgument(0) and
+ optionArgConfig
+ .hasFlow(DataFlow::exprNode(optionArgumentSource), DataFlow::exprNode(optionArgument))
+ |
+ optionArgument.getValue().toInt().bitShiftRight(16).bitAnd(flag) = flag
)
)
)
@@ -46,43 +47,18 @@ predicate isOptionSet(ConstructorCall cc, int flag, FunctionCall fcSetOptions) {
bindingset[flag]
predicate isOptionNotSet(ConstructorCall cc, int flag) {
- not exists(
- BoostorgAsio::SslContextFlowsToSetOptionConfig config, ExistsAnyFlowConfig testConfig,
- Expr optionsSink
- |
- config.hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(optionsSink)) and
- exists(VariableAccess contextSetOptions |
- testConfig.hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(contextSetOptions)) and
- exists(FunctionCall fcSetOptions, BoostorgAsio::SslSetOptionsFunction f |
- f.getACallToThisFunction() = fcSetOptions
- |
- contextSetOptions = fcSetOptions.getQualifier() and
- forall(
- Expr optionArgument, BoostorgAsio::SslOptionConfig optionArgConfig,
- Expr optionArgumentSource
- |
- optionArgument = fcSetOptions.getArgument(0) and
- optionArgConfig
- .hasFlow(DataFlow::exprNode(optionArgumentSource), DataFlow::exprNode(optionArgument))
- |
- optionArgument.getValue().toInt().bitShiftRight(16).bitAnd(flag) = flag
- )
- )
- )
- )
+ not exists(FunctionCall fcSetOptions | isOptionSet(cc, flag, fcSetOptions))
}
from
- BoostorgAsio::SslContextCallTlsProtocolConfig configConstructor,
- BoostorgAsio::SslContextFlowsToSetOptionConfig config, Expr protocolSource, Expr protocolSink,
- ConstructorCall cc, Expr e, string msg
+ BoostorgAsio::SslContextCallTlsProtocolConfig configConstructor, Expr protocolSource,
+ Expr protocolSink, ConstructorCall cc, Expr e, string msg
where
configConstructor.hasFlow(DataFlow::exprNode(protocolSource), DataFlow::exprNode(protocolSink)) and
cc.getArgument(0) = protocolSink and
(
BoostorgAsio::isExprSslV23BoostProtocol(protocolSource) and
- not exists(Expr optionsSink |
- config.hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(optionsSink)) and
+ not (
isOptionSet(cc, BoostorgAsio::getShiftedSslOptionsNoSsl3(), _) and
isOptionSet(cc, BoostorgAsio::getShiftedSslOptionsNoTls1(), _) and
isOptionSet(cc, BoostorgAsio::getShiftedSslOptionsNoTls1_1(), _) and
@@ -91,8 +67,7 @@ where
or
BoostorgAsio::isExprTlsBoostProtocol(protocolSource) and
not BoostorgAsio::isExprSslV23BoostProtocol(protocolSource) and
- not exists(Expr optionsSink |
- config.hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(optionsSink)) and
+ not (
isOptionSet(cc, BoostorgAsio::getShiftedSslOptionsNoTls1(), _) and
isOptionSet(cc, BoostorgAsio::getShiftedSslOptionsNoTls1_1(), _) and
isOptionNotSet(cc, BoostorgAsio::getShiftedSslOptionsNoTls1_2())
diff --git a/cpp/ql/src/Likely Bugs/Protocols/boostorg/UseOfDeprecatedHardcodedProtocol.qhelp b/cpp/ql/src/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.qhelp
similarity index 100%
rename from cpp/ql/src/Likely Bugs/Protocols/boostorg/UseOfDeprecatedHardcodedProtocol.qhelp
rename to cpp/ql/src/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.qhelp
diff --git a/cpp/ql/src/Likely Bugs/Protocols/boostorg/UseOfDeprecatedHardcodedProtocol.ql b/cpp/ql/src/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.ql
similarity index 100%
rename from cpp/ql/src/Likely Bugs/Protocols/boostorg/UseOfDeprecatedHardcodedProtocol.ql
rename to cpp/ql/src/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.ql
diff --git a/cpp/ql/src/Microsoft/IgnoreReturnValueSAL.ql b/cpp/ql/src/Microsoft/IgnoreReturnValueSAL.ql
index 64f398fa855..fb25a93963d 100644
--- a/cpp/ql/src/Microsoft/IgnoreReturnValueSAL.ql
+++ b/cpp/ql/src/Microsoft/IgnoreReturnValueSAL.ql
@@ -7,6 +7,10 @@
* @id cpp/ignore-return-value-sal
* @problem.severity warning
* @tags reliability
+ * external/cwe/cwe-573
+ * external/cwe/cwe-252
+ * @opaque-id SM02344
+ * @microsoft.severity Important
*/
import SAL
diff --git a/cpp/ql/src/Microsoft/SAL.qll b/cpp/ql/src/Microsoft/SAL.qll
index fe6b455fa9b..963a726ae54 100644
--- a/cpp/ql/src/Microsoft/SAL.qll
+++ b/cpp/ql/src/Microsoft/SAL.qll
@@ -126,7 +126,7 @@ class SALParameter extends Parameter {
}
/**
- * A SAL element, i.e. a SAL annotation or a declaration entry
+ * A SAL element, that is, a SAL annotation or a declaration entry
* that may have SAL annotations.
*/
library class SALElement extends Element {
diff --git a/cpp/ql/src/Microsoft/SAL/IgnoreReturnValueSAL.ql b/cpp/ql/src/Microsoft/SAL/IgnoreReturnValueSAL.ql
deleted file mode 100644
index 569f684a4c3..00000000000
--- a/cpp/ql/src/Microsoft/SAL/IgnoreReturnValueSAL.ql
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * @name SAL requires inspecting return value
- * @description When a return value is discarded even though the SAL annotation
- * requires inspecting it, a recoverable error may turn into a
- * whole-program crash.
- * @kind problem
- * @problem.severity warning
- * @tags reliability
- * external/cwe/cwe-573
- * external/cwe/cwe-252
- * @opaque-id SM02344
- * @microsoft.severity Important
- * @id cpp/ignorereturnvaluesal
- */
-
-import Microsoft.SAL
-
-from Function f, FunctionCall call
-where
- call.getTarget() = f and
- call instanceof ExprInVoidContext and
- any(SALCheckReturn a).getDeclaration() = f and
- not any(Options o).okToIgnoreReturnValue(call)
-select call, "Return value of $@ discarded although a SAL annotation " + "requires inspecting it.",
- f, f.getName()
diff --git a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql
index 096b1468bb9..42a29b96268 100644
--- a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql
+++ b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql
@@ -34,8 +34,10 @@ class FileFunction extends FunctionWithWrappers {
nme.matches("CreateFile%")
)
or
+ this.hasQualifiedName("std", "fopen")
+ or
// on any of the fstream classes, or filebuf
- exists(string nme | this.getDeclaringType().getSimpleName() = nme |
+ exists(string nme | this.getDeclaringType().hasQualifiedName("std", nme) |
nme = "basic_fstream" or
nme = "basic_ifstream" or
nme = "basic_ofstream" or
diff --git a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.qhelp b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.qhelp
index ccd297c3b36..4ad7a40fed6 100644
--- a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.qhelp
+++ b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.qhelp
@@ -34,7 +34,7 @@ characters before writing to the HTML page.
OWASP:
-XSS
+XSS
(Cross Site Scripting) Prevention Cheat Sheet.
diff --git a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql
index 4469517c369..8b7fb83df81 100644
--- a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql
+++ b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql
@@ -17,8 +17,8 @@ import semmle.code.cpp.security.TaintTracking
/** A call that prints its arguments to `stdout`. */
class PrintStdoutCall extends FunctionCall {
PrintStdoutCall() {
- getTarget().hasGlobalName("puts") or
- getTarget().hasGlobalName("printf")
+ getTarget().hasGlobalOrStdName("puts") or
+ getTarget().hasGlobalOrStdName("printf")
}
}
diff --git a/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql b/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
index 575752f0b74..ff17daca05c 100644
--- a/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
+++ b/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
@@ -19,10 +19,7 @@ import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.models.implementations.Memcpy
class MallocCall extends FunctionCall {
- MallocCall() {
- this.getTarget().hasGlobalName("malloc") or
- this.getTarget().hasQualifiedName("std", "malloc")
- }
+ MallocCall() { this.getTarget().hasGlobalOrStdName("malloc") }
Expr getAllocatedSize() {
if this.getArgument(0) instanceof VariableAccess
diff --git a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.qhelp b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.qhelp
index b9118edc736..8e6a8903483 100644
--- a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.qhelp
+++ b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.qhelp
@@ -37,7 +37,7 @@ which is then subsequently accessed to fetch properties of the device. However,
check the return value from the function call to initDeviceConfig. If the
device number passed to the notify function was invalid, the
initDeviceConfig function will leave the config variable uninitialized,
-which would result in the notify function accessing uninitialized memory.
+which will result in the notify function accessing uninitialized memory.
diff --git a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.ql b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.ql
index eb00fb9ea10..f9eb2fe5400 100644
--- a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.ql
+++ b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.ql
@@ -2,7 +2,7 @@
* @name Conditionally uninitialized variable
* @description When an initialization function is used to initialize a local variable, but the
* returned status code is not checked, the variable may be left in an uninitialized
- * state, and reading the variable may result in undefined behaviour.
+ * state, and reading the variable may result in undefined behavior.
* @kind problem
* @problem.severity warning
* @opaque-id SM02313
diff --git a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableBad.c b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableBad.c
index 1f281f3cfd9..73a01c2d900 100644
--- a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableBad.c
+++ b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableBad.c
@@ -19,7 +19,7 @@ int notify(int deviceNumber) {
DeviceConfig config;
initDeviceConfig(&config, deviceNumber);
// BAD: Using config without checking the status code that is returned
- if (config->isEnabled) {
- notifyChannel(config->channel);
+ if (config.isEnabled) {
+ notifyChannel(config.channel);
}
-}
\ No newline at end of file
+}
diff --git a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableGood.c b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableGood.c
index a9dcc06c9a5..ced43a66cfc 100644
--- a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableGood.c
+++ b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableGood.c
@@ -20,8 +20,8 @@ void notify(int deviceNumber) {
int statusCode = initDeviceConfig(&config, deviceNumber);
if (statusCode == 0) {
// GOOD: Status code returned by initialization function is checked, so this is safe
- if (config->isEnabled) {
- notifyChannel(config->channel);
+ if (config.isEnabled) {
+ notifyChannel(config.channel);
}
}
-}
\ No newline at end of file
+}
diff --git a/cpp/ql/src/Security/CWE/CWE-457/InitializationFunctions.qll b/cpp/ql/src/Security/CWE/CWE-457/InitializationFunctions.qll
index 240bd7aa25e..8f2950c9123 100644
--- a/cpp/ql/src/Security/CWE/CWE-457/InitializationFunctions.qll
+++ b/cpp/ql/src/Security/CWE/CWE-457/InitializationFunctions.qll
@@ -4,7 +4,7 @@
import cpp
import external.ExternalArtifact
-private import semmle.code.cpp.dispatch.VirtualDispatch
+private import semmle.code.cpp.dispatch.VirtualDispatchPrototype
import semmle.code.cpp.NestedFields
import Microsoft.SAL
import semmle.code.cpp.controlflow.Guards
@@ -89,9 +89,9 @@ class ParameterNullCheck extends ParameterCheck {
(
va = this.(NotExpr).getOperand() or
va = any(EQExpr eq | eq = this and eq.getAnOperand().getValue() = "0").getAnOperand() or
- va = getAssertedFalseCondition(this) or
+ va = getCheckedFalseCondition(this) or
va = any(NEExpr eq |
- eq = getAssertedFalseCondition(this) and eq.getAnOperand().getValue() = "0"
+ eq = getCheckedFalseCondition(this) and eq.getAnOperand().getValue() = "0"
).getAnOperand()
)
or
@@ -101,7 +101,7 @@ class ParameterNullCheck extends ParameterCheck {
va = this or
va = any(NEExpr eq | eq = this and eq.getAnOperand().getValue() = "0").getAnOperand() or
va = any(EQExpr eq |
- eq = getAssertedFalseCondition(this) and eq.getAnOperand().getValue() = "0"
+ eq = getCheckedFalseCondition(this) and eq.getAnOperand().getValue() = "0"
).getAnOperand()
)
)
@@ -567,7 +567,7 @@ Expr getAnInitializedArgument(Call call) { result = call.getArgument(initialized
* the call, under the given context and evidence.
*/
pragma[nomagic]
-int conditionallyInitializedArgument(
+private int conditionallyInitializedArgument(
Call call, ConditionalInitializationFunction target, Context c, Evidence e
) {
target = getTarget(call) and
@@ -588,7 +588,7 @@ Expr getAConditionallyInitializedArgument(
/**
* Gets the type signature for the functions parameters.
*/
-string typeSig(Function f) {
+private string typeSig(Function f) {
result = concat(int i, Type pt |
pt = f.getParameter(i).getType()
|
@@ -599,7 +599,7 @@ string typeSig(Function f) {
/**
* Holds where qualifiedName and typeSig make up the signature for the function.
*/
-predicate functionSignature(Function f, string qualifiedName, string typeSig) {
+private predicate functionSignature(Function f, string qualifiedName, string typeSig) {
qualifiedName = f.getQualifiedName() and
typeSig = typeSig(f)
}
@@ -611,7 +611,7 @@ predicate functionSignature(Function f, string qualifiedName, string typeSig) {
* This is useful for identifying call to target dependencies across libraries, where the libraries
* are never statically linked together.
*/
-Function getAPossibleDefinition(Function undefinedFunction) {
+private Function getAPossibleDefinition(Function undefinedFunction) {
not undefinedFunction.isDefined() and
exists(string qn, string typeSig |
functionSignature(undefinedFunction, qn, typeSig) and functionSignature(result, qn, typeSig)
@@ -620,32 +620,47 @@ Function getAPossibleDefinition(Function undefinedFunction) {
}
/**
- * Gets a possible target for the Call, using the name and parameter matching if we did not associate
+ * Helper predicate for `getTarget`, that computes possible targets of a `Call`.
+ *
+ * If there is at least one defined target after performing some simple virtual dispatch
+ * resolution, then the result is all the defined targets.
+ */
+private Function getTarget1(Call c) {
+ result = VirtualDispatch::getAViableTarget(c) and
+ result.isDefined()
+}
+
+/**
+ * Helper predicate for `getTarget`, that computes possible targets of a `Call`.
+ *
+ * If we can use the heuristic matching of functions to find definitions for some of the viable
+ * targets, return those.
+ */
+private Function getTarget2(Call c) {
+ not exists(getTarget1(c)) and
+ result = getAPossibleDefinition(VirtualDispatch::getAViableTarget(c))
+}
+
+/**
+ * Helper predicate for `getTarget`, that computes possible targets of a `Call`.
+ *
+ * Otherwise, the result is the undefined `Function` instances.
+ */
+private Function getTarget3(Call c) {
+ not exists(getTarget1(c)) and
+ not exists(getTarget2(c)) and
+ result = VirtualDispatch::getAViableTarget(c)
+}
+
+/**
+ * Gets a possible target for the `Call`, using the name and parameter matching if we did not associate
* this call with a specific definition at link or compile time, and performing simple virtual
* dispatch resolution.
*/
Function getTarget(Call c) {
- if VirtualDispatch::getAViableTarget(c).isDefined()
- then
- /*
- * If there is at least one defined target after performing some simple virtual dispatch
- * resolution, then the result is all the defined targets.
- */
-
- result = VirtualDispatch::getAViableTarget(c) and
- result.isDefined()
- else
- if exists(getAPossibleDefinition(VirtualDispatch::getAViableTarget(c)))
- then
- /*
- * If we can use the heuristic matching of functions to find definitions for some of the viable
- * targets, return those.
- */
-
- result = getAPossibleDefinition(VirtualDispatch::getAViableTarget(c))
- else
- // Otherwise, the result is the undefined `Function` instances
- result = VirtualDispatch::getAViableTarget(c)
+ result = getTarget1(c) or
+ result = getTarget2(c) or
+ result = getTarget3(c)
}
/**
@@ -669,7 +684,7 @@ FieldAccess getAFieldAccess(Variable v) {
}
/**
- * Gets a condition which is asserted to be false by the given `ne` expression, according to this pattern:
+ * Gets a condition which is checked to be false by the given `ne` expression, according to this pattern:
* ```
* int a = !!result;
* if (!a) { // <- ne
@@ -677,7 +692,7 @@ FieldAccess getAFieldAccess(Variable v) {
* }
* ```
*/
-Expr getAssertedFalseCondition(NotExpr ne) {
+private Expr getCheckedFalseCondition(NotExpr ne) {
exists(LocalVariable v |
result = v.getInitializer().getExpr().(NotExpr).getOperand().(NotExpr).getOperand() and
ne.getOperand() = v.getAnAccess() and
diff --git a/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql b/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql
index fa74c85555d..63eca292297 100644
--- a/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql
+++ b/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql
@@ -190,11 +190,11 @@ private predicate windowsSystemInfo(FunctionCall source, Element use) {
// void WINAPI GetSystemInfo(_Out_ LPSYSTEM_INFO lpSystemInfo);
// void WINAPI GetNativeSystemInfo(_Out_ LPSYSTEM_INFO lpSystemInfo);
(
- source.getTarget().hasName("GetVersionEx") or
- source.getTarget().hasName("GetVersionExA") or
- source.getTarget().hasName("GetVersionExW") or
- source.getTarget().hasName("GetSystemInfo") or
- source.getTarget().hasName("GetNativeSystemInfo")
+ source.getTarget().hasGlobalName("GetVersionEx") or
+ source.getTarget().hasGlobalName("GetVersionExA") or
+ source.getTarget().hasGlobalName("GetVersionExW") or
+ source.getTarget().hasGlobalName("GetSystemInfo") or
+ source.getTarget().hasGlobalName("GetNativeSystemInfo")
) and
use = source.getArgument(0)
}
@@ -216,9 +216,9 @@ private predicate windowsFolderPath(FunctionCall source, Element use) {
// _In_ BOOL fCreate
// );
(
- source.getTarget().hasName("SHGetSpecialFolderPath") or
- source.getTarget().hasName("SHGetSpecialFolderPathA") or
- source.getTarget().hasName("SHGetSpecialFolderPathW")
+ source.getTarget().hasGlobalName("SHGetSpecialFolderPath") or
+ source.getTarget().hasGlobalName("SHGetSpecialFolderPathA") or
+ source.getTarget().hasGlobalName("SHGetSpecialFolderPathW")
) and
use = source.getArgument(1)
or
@@ -228,7 +228,7 @@ private predicate windowsFolderPath(FunctionCall source, Element use) {
// _In_opt_ HANDLE hToken,
// _Out_ PWSTR *ppszPath
// );
- source.getTarget().hasName("SHGetKnownFolderPath") and
+ source.getTarget().hasGlobalName("SHGetKnownFolderPath") and
use = source.getArgument(3)
or
// HRESULT SHGetFolderPath(
@@ -239,9 +239,9 @@ private predicate windowsFolderPath(FunctionCall source, Element use) {
// _Out_ LPTSTR pszPath
// );
(
- source.getTarget().hasName("SHGetFolderPath") or
- source.getTarget().hasName("SHGetFolderPathA") or
- source.getTarget().hasName("SHGetFolderPathW")
+ source.getTarget().hasGlobalName("SHGetFolderPath") or
+ source.getTarget().hasGlobalName("SHGetFolderPathA") or
+ source.getTarget().hasGlobalName("SHGetFolderPathW")
) and
use = source.getArgument(4)
or
@@ -254,9 +254,9 @@ private predicate windowsFolderPath(FunctionCall source, Element use) {
// _Out_ LPTSTR pszPath
// );
(
- source.getTarget().hasName("SHGetFolderPathAndSubDir") or
- source.getTarget().hasName("SHGetFolderPathAndSubDirA") or
- source.getTarget().hasName("SHGetFolderPathAndSubDirW")
+ source.getTarget().hasGlobalName("SHGetFolderPathAndSubDir") or
+ source.getTarget().hasGlobalName("SHGetFolderPathAndSubDirA") or
+ source.getTarget().hasGlobalName("SHGetFolderPathAndSubDirW")
) and
use = source.getArgument(5)
}
@@ -273,9 +273,9 @@ class WindowsFolderPath extends SystemData {
private predicate logonUser(FunctionCall source, VariableAccess use) {
(
- source.getTarget().hasName("LogonUser") or
- source.getTarget().hasName("LogonUserW") or
- source.getTarget().hasName("LogonUserA")
+ source.getTarget().hasGlobalName("LogonUser") or
+ source.getTarget().hasGlobalName("LogonUserW") or
+ source.getTarget().hasGlobalName("LogonUserA")
) and
use = source.getAnArgument()
}
@@ -297,9 +297,9 @@ private predicate regQuery(FunctionCall source, VariableAccess use) {
// _Inout_opt_ PLONG lpcbValue
// );
(
- source.getTarget().hasName("RegQueryValue") or
- source.getTarget().hasName("RegQueryValueA") or
- source.getTarget().hasName("RegQueryValueW")
+ source.getTarget().hasGlobalName("RegQueryValue") or
+ source.getTarget().hasGlobalName("RegQueryValueA") or
+ source.getTarget().hasGlobalName("RegQueryValueW")
) and
use = source.getArgument(2)
or
@@ -311,9 +311,9 @@ private predicate regQuery(FunctionCall source, VariableAccess use) {
// _Inout_opt_ LPDWORD ldwTotsize
// );
(
- source.getTarget().hasName("RegQueryMultipleValues") or
- source.getTarget().hasName("RegQueryMultipleValuesA") or
- source.getTarget().hasName("RegQueryMultipleValuesW")
+ source.getTarget().hasGlobalName("RegQueryMultipleValues") or
+ source.getTarget().hasGlobalName("RegQueryMultipleValuesA") or
+ source.getTarget().hasGlobalName("RegQueryMultipleValuesW")
) and
use = source.getArgument(3)
or
@@ -326,9 +326,9 @@ private predicate regQuery(FunctionCall source, VariableAccess use) {
// _Inout_opt_ LPDWORD lpcbData
// );
(
- source.getTarget().hasName("RegQueryValueEx") or
- source.getTarget().hasName("RegQueryValueExA") or
- source.getTarget().hasName("RegQueryValueExW")
+ source.getTarget().hasGlobalName("RegQueryValueEx") or
+ source.getTarget().hasGlobalName("RegQueryValueExA") or
+ source.getTarget().hasGlobalName("RegQueryValueExW")
) and
use = source.getArgument(4)
or
@@ -342,9 +342,9 @@ private predicate regQuery(FunctionCall source, VariableAccess use) {
// _Inout_opt_ LPDWORD pcbData
// );
(
- source.getTarget().hasName("RegGetValue") or
- source.getTarget().hasName("RegGetValueA") or
- source.getTarget().hasName("RegGetValueW")
+ source.getTarget().hasGlobalName("RegGetValue") or
+ source.getTarget().hasGlobalName("RegGetValueA") or
+ source.getTarget().hasGlobalName("RegGetValueW")
) and
use = source.getArgument(5)
}
diff --git a/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.ql b/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.ql
index 84d7b48e265..fe9b56bd521 100644
--- a/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.ql
+++ b/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.ql
@@ -15,5 +15,5 @@ import cpp
from FunctionCall call, Function target
where
call.getTarget() = target and
- target.hasGlobalName("gets")
+ target.hasGlobalOrStdName("gets")
select call, "gets does not guard against buffer overflow"
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql
index 4b1f45185d1..f2512b93003 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql
@@ -22,7 +22,7 @@ predicate acquireExpr(Expr acquire, string kind) {
exists(FunctionCall fc, Function f, string name |
fc = acquire and
f = fc.getTarget() and
- f.hasGlobalName(name) and
+ f.hasGlobalOrStdName(name) and
(
name = "fopen" and
kind = "file"
@@ -46,7 +46,7 @@ predicate releaseExpr(Expr release, Expr resource, string kind) {
exists(FunctionCall fc, Function f, string name |
fc = release and
f = fc.getTarget() and
- f.hasGlobalName(name) and
+ f.hasGlobalOrStdName(name) and
(
name = "fclose" and
resource = fc.getArgument(0) and
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql
index 501101f706c..872a7443e6e 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql
@@ -22,8 +22,8 @@ predicate containsArray(Type t) {
or
containsArray(t.getUnderlyingType()) and
not exists(TypedefType allowed | allowed = t |
- allowed.hasGlobalName("jmp_buf") or
- allowed.hasGlobalName("va_list")
+ allowed.hasGlobalOrStdName("jmp_buf") or
+ allowed.hasGlobalOrStdName("va_list")
)
}
diff --git a/cpp/ql/src/semmle/code/cpp/Class.qll b/cpp/ql/src/semmle/code/cpp/Class.qll
index 5ac4f52392e..297654a1afa 100644
--- a/cpp/ql/src/semmle/code/cpp/Class.qll
+++ b/cpp/ql/src/semmle/code/cpp/Class.qll
@@ -605,15 +605,6 @@ class Class extends UserType {
class_instantiation(underlyingElement(this), unresolveElement(c))
}
- /**
- * Gets the `i`th template argument used to instantiate this class from a
- * class template. When called on a class template, this will return the
- * `i`th template parameter.
- */
- override Type getTemplateArgument(int i) {
- class_template_argument(underlyingElement(this), i, unresolveElement(result))
- }
-
/**
* Holds if this class/struct is polymorphic (has a virtual function, or
* inherits one).
@@ -623,7 +614,7 @@ class Class extends UserType {
}
override predicate involvesTemplateParameter() {
- getATemplateArgument().involvesTemplateParameter()
+ getATemplateArgument().(Type).involvesTemplateParameter()
}
/** Holds if this class, struct or union was declared 'final'. */
diff --git a/cpp/ql/src/semmle/code/cpp/Declaration.qll b/cpp/ql/src/semmle/code/cpp/Declaration.qll
index 5d13bf4883a..f2f31a51d29 100644
--- a/cpp/ql/src/semmle/code/cpp/Declaration.qll
+++ b/cpp/ql/src/semmle/code/cpp/Declaration.qll
@@ -123,6 +123,13 @@ abstract class Declaration extends Locatable, @declaration {
/** Holds if this declaration has the given name in the global namespace. */
predicate hasGlobalName(string name) { this.hasQualifiedName("", "", name) }
+ /** Holds if this declaration has the given name in the global namespace or the `std` namespace. */
+ predicate hasGlobalOrStdName(string name) {
+ this.hasGlobalName(name)
+ or
+ this.hasQualifiedName("std", "", name)
+ }
+
/** Gets a specifier of this declaration. */
abstract Specifier getASpecifier();
@@ -193,20 +200,83 @@ abstract class Declaration extends Locatable, @declaration {
/**
* Gets a template argument used to instantiate this declaration from a template.
- * When called on a template, this will return a template parameter.
+ * When called on a template, this will return a template parameter type for
+ * both typed and non-typed parameters.
*/
- final Type getATemplateArgument() { result = getTemplateArgument(_) }
+ final Locatable getATemplateArgument() { result = getTemplateArgument(_) }
+
+ /**
+ * Gets a template argument used to instantiate this declaration from a template.
+ * When called on a template, this will return a non-typed template
+ * parameter value.
+ */
+ final Locatable getATemplateArgumentKind() { result = getTemplateArgumentKind(_) }
/**
* Gets the `i`th template argument used to instantiate this declaration from a
- * template. When called on a template, this will return the `i`th template parameter.
+ * template.
+ *
+ * For example:
+ *
+ * `template class Foo;`
+ *
+ * Will have `getTemplateArgument(0)` return `T`, and
+ * `getTemplateArgument(1)` return `X`.
+ *
+ * `Foo bar;
+ *
+ * Will have `getTemplateArgument())` return `int`, and
+ * `getTemplateArgument(1)` return `1`.
*/
- Type getTemplateArgument(int index) { none() }
+ final Locatable getTemplateArgument(int index) {
+ if exists(getTemplateArgumentValue(index))
+ then result = getTemplateArgumentValue(index)
+ else result = getTemplateArgumentType(index)
+ }
+
+ /**
+ * Gets the `i`th template argument value used to instantiate this declaration
+ * from a template. When called on a template, this will return the `i`th template
+ * parameter value if it exists.
+ *
+ * For example:
+ *
+ * `template class Foo;`
+ *
+ * Will have `getTemplateArgumentKind(1)` return `T`, and no result for
+ * `getTemplateArgumentKind(0)`.
+ *
+ * `Foo bar;
+ *
+ * Will have `getTemplateArgumentKind(1)` return `int`, and no result for
+ * `getTemplateArgumentKind(0)`.
+ */
+ final Locatable getTemplateArgumentKind(int index) {
+ if exists(getTemplateArgumentValue(index))
+ then result = getTemplateArgumentType(index)
+ else none()
+ }
/** Gets the number of template arguments for this declaration. */
final int getNumberOfTemplateArguments() {
result = count(int i | exists(getTemplateArgument(i)))
}
+
+ private Type getTemplateArgumentType(int index) {
+ class_template_argument(underlyingElement(this), index, unresolveElement(result))
+ or
+ function_template_argument(underlyingElement(this), index, unresolveElement(result))
+ or
+ variable_template_argument(underlyingElement(this), index, unresolveElement(result))
+ }
+
+ private Expr getTemplateArgumentValue(int index) {
+ class_template_argument_value(underlyingElement(this), index, unresolveElement(result))
+ or
+ function_template_argument_value(underlyingElement(this), index, unresolveElement(result))
+ or
+ variable_template_argument_value(underlyingElement(this), index, unresolveElement(result))
+ }
}
/**
diff --git a/cpp/ql/src/semmle/code/cpp/Function.qll b/cpp/ql/src/semmle/code/cpp/Function.qll
index 94d11d63575..85c277f945b 100644
--- a/cpp/ql/src/semmle/code/cpp/Function.qll
+++ b/cpp/ql/src/semmle/code/cpp/Function.qll
@@ -343,15 +343,6 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
function_instantiation(underlyingElement(this), unresolveElement(f))
}
- /**
- * Gets the `i`th template argument used to instantiate this function from a
- * function template. When called on a function template, this will return the
- * `i`th template parameter.
- */
- override Type getTemplateArgument(int index) {
- function_template_argument(underlyingElement(this), index, unresolveElement(result))
- }
-
/**
* Holds if this function is defined in several files. This is illegal in
* C (though possible in some C++ compilers), and likely indicates that
@@ -434,7 +425,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
// ... and likewise for destructors.
this.(Destructor).getADestruction().mayBeGloballyImpure()
else
- not exists(string name | this.hasGlobalName(name) |
+ not exists(string name | this.hasGlobalOrStdName(name) |
// Unless it's a function that we know is side-effect-free, it may
// have side-effects.
name = "strcmp" or
diff --git a/cpp/ql/src/semmle/code/cpp/NestedFields.qll b/cpp/ql/src/semmle/code/cpp/NestedFields.qll
index 12109be8ece..c4be8b8b9ff 100644
--- a/cpp/ql/src/semmle/code/cpp/NestedFields.qll
+++ b/cpp/ql/src/semmle/code/cpp/NestedFields.qll
@@ -1,9 +1,8 @@
import cpp
/**
- * Gets a `Field` that is nested within the given `Struct`.
- *
- * This identifies `Field`s which are located in the same memory
+ * Gets a `Field` that is within the given `Struct`, either directly or nested
+ * inside one or more levels of member structs.
*/
private Field getANestedField(Struct s) {
result = s.getAField()
@@ -15,7 +14,7 @@ private Field getANestedField(Struct s) {
}
/**
- * Unwraps a series of field accesses to determine the inner-most qualifier.
+ * Unwraps a series of field accesses to determine the outer-most qualifier.
*/
private Expr getUltimateQualifier(FieldAccess fa) {
exists(Expr qualifier | qualifier = fa.getQualifier() |
diff --git a/cpp/ql/src/semmle/code/cpp/Print.qll b/cpp/ql/src/semmle/code/cpp/Print.qll
index ab979d89b03..e3ad19f6028 100644
--- a/cpp/ql/src/semmle/code/cpp/Print.qll
+++ b/cpp/ql/src/semmle/code/cpp/Print.qll
@@ -35,6 +35,14 @@ private string getParameterTypeString(Type parameterType) {
else result = parameterType.(DumpType).getTypeIdentityString()
}
+private string getTemplateArgumentString(Declaration d, int i) {
+ if exists(d.getTemplateArgumentKind(i))
+ then
+ result = d.getTemplateArgumentKind(i).(DumpType).getTypeIdentityString() + " " +
+ d.getTemplateArgument(i)
+ else result = d.getTemplateArgument(i).(DumpType).getTypeIdentityString()
+}
+
/**
* A `Declaration` extended to add methods for generating strings useful only for dumps and debugging.
*/
@@ -56,7 +64,7 @@ abstract private class DumpDeclaration extends Declaration {
strictconcat(int i |
exists(this.getTemplateArgument(i))
|
- this.getTemplateArgument(i).(DumpType).getTypeIdentityString(), ", " order by i
+ getTemplateArgumentString(this, i), ", " order by i
) + ">"
else result = ""
}
diff --git a/cpp/ql/src/semmle/code/cpp/PrintAST.ql b/cpp/ql/src/semmle/code/cpp/PrintAST.ql
index 6fc40dd0525..e4c53030da5 100644
--- a/cpp/ql/src/semmle/code/cpp/PrintAST.ql
+++ b/cpp/ql/src/semmle/code/cpp/PrintAST.ql
@@ -7,3 +7,15 @@
import cpp
import PrintAST
+
+/**
+ * Temporarily tweak this class or make a copy to control which functions are
+ * printed.
+ */
+class Cfg extends PrintASTConfiguration {
+ /**
+ * TWEAK THIS PREDICATE AS NEEDED.
+ * Holds if the AST for `func` should be printed.
+ */
+ override predicate shouldPrintFunction(Function func) { any() }
+}
diff --git a/cpp/ql/src/semmle/code/cpp/Type.qll b/cpp/ql/src/semmle/code/cpp/Type.qll
index 10a1b6b1724..ea1e7fd5026 100644
--- a/cpp/ql/src/semmle/code/cpp/Type.qll
+++ b/cpp/ql/src/semmle/code/cpp/Type.qll
@@ -210,7 +210,7 @@ class Type extends Locatable, @type {
// A function call that provides an explicit template argument that refers to T uses T.
// We exclude calls within instantiations, since they do not appear directly in the source.
exists(FunctionCall c |
- c.getAnExplicitTemplateArgument().refersTo(this) and
+ c.getAnExplicitTemplateArgument().(Type).refersTo(this) and
result = c and
not c.getEnclosingFunction().isConstructedFrom(_)
)
diff --git a/cpp/ql/src/semmle/code/cpp/Variable.qll b/cpp/ql/src/semmle/code/cpp/Variable.qll
index 6fd33d9a037..194cc5333c7 100644
--- a/cpp/ql/src/semmle/code/cpp/Variable.qll
+++ b/cpp/ql/src/semmle/code/cpp/Variable.qll
@@ -155,15 +155,6 @@ class Variable extends Declaration, @variable {
variable_instantiation(underlyingElement(this), unresolveElement(v))
}
- /**
- * Gets the `i`th template argument used to instantiate this variable from a
- * variable template. When called on a variable template, this will return the
- * `i`th template parameter.
- */
- override Type getTemplateArgument(int index) {
- variable_template_argument(underlyingElement(this), index, unresolveElement(result))
- }
-
/**
* Holds if this is a compiler-generated variable. For example, a
* [range-based for loop](http://en.cppreference.com/w/cpp/language/range-for)
diff --git a/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll b/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll
index e90aea37781..8462cb13b1d 100644
--- a/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll
+++ b/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll
@@ -5,13 +5,17 @@ import cpp
*/
predicate allocationFunction(Function f) {
exists(string name |
- f.hasGlobalName(name) and
+ f.hasGlobalOrStdName(name) and
(
name = "malloc" or
name = "calloc" or
name = "realloc" or
name = "strdup" or
- name = "wcsdup" or
+ name = "wcsdup"
+ )
+ or
+ f.hasGlobalName(name) and
+ (
name = "_strdup" or
name = "_wcsdup" or
name = "_mbsdup" or
@@ -59,7 +63,7 @@ predicate allocationCall(FunctionCall fc) {
allocationFunction(fc.getTarget()) and
(
// realloc(ptr, 0) only frees the pointer
- fc.getTarget().hasGlobalName("realloc") implies not fc.getArgument(1).getValue() = "0"
+ fc.getTarget().hasGlobalOrStdName("realloc") implies not fc.getArgument(1).getValue() = "0"
)
}
@@ -73,7 +77,10 @@ predicate freeFunction(Function f, int argNum) {
name = "free" and argNum = 0
or
name = "realloc" and argNum = 0
- or
+ )
+ or
+ f.hasGlobalOrStdName(name) and
+ (
name = "ExFreePoolWithTag" and argNum = 0
or
name = "ExFreeToLookasideListEx" and argNum = 1
diff --git a/cpp/ql/src/semmle/code/cpp/commons/Environment.qll b/cpp/ql/src/semmle/code/cpp/commons/Environment.qll
index e36244f4d5c..f3f1759dd5c 100644
--- a/cpp/ql/src/semmle/code/cpp/commons/Environment.qll
+++ b/cpp/ql/src/semmle/code/cpp/commons/Environment.qll
@@ -28,7 +28,7 @@ class EnvironmentRead extends Expr {
private predicate readsEnvironment(Expr read, string sourceDescription) {
exists(FunctionCall call, string name |
read = call and
- call.getTarget().hasGlobalName(name) and
+ call.getTarget().hasGlobalOrStdName(name) and
(name = "getenv" or name = "secure_getenv" or name = "_wgetenv") and
sourceDescription = name
)
diff --git a/cpp/ql/src/semmle/code/cpp/commons/File.qll b/cpp/ql/src/semmle/code/cpp/commons/File.qll
index 192918d25b3..5808d704e38 100644
--- a/cpp/ql/src/semmle/code/cpp/commons/File.qll
+++ b/cpp/ql/src/semmle/code/cpp/commons/File.qll
@@ -5,7 +5,7 @@ import cpp
*/
predicate fopenCall(FunctionCall fc) {
exists(Function f | f = fc.getTarget() |
- f.hasGlobalName("fopen") or
+ f.hasGlobalOrStdName("fopen") or
f.hasGlobalName("open") or
f.hasGlobalName("_open") or
f.hasGlobalName("_wopen") or
@@ -23,7 +23,7 @@ predicate fopenCall(FunctionCall fc) {
*/
predicate fcloseCall(FunctionCall fc, Expr closed) {
exists(Function f | f = fc.getTarget() |
- f.hasGlobalName("fclose") and
+ f.hasGlobalOrStdName("fclose") and
closed = fc.getArgument(0)
or
f.hasGlobalName("close") and
@@ -32,7 +32,7 @@ predicate fcloseCall(FunctionCall fc, Expr closed) {
f.hasGlobalName("_close") and
closed = fc.getArgument(0)
or
- f.hasGlobalName("CloseHandle") and
+ f.hasGlobalOrStdName("CloseHandle") and
closed = fc.getArgument(0)
)
}
diff --git a/cpp/ql/src/semmle/code/cpp/commons/Printf.qll b/cpp/ql/src/semmle/code/cpp/commons/Printf.qll
index bd179fe27cc..5bb60564c1b 100644
--- a/cpp/ql/src/semmle/code/cpp/commons/Printf.qll
+++ b/cpp/ql/src/semmle/code/cpp/commons/Printf.qll
@@ -8,25 +8,32 @@ import semmle.code.cpp.commons.StringAnalysis
import semmle.code.cpp.models.interfaces.FormattingFunction
import semmle.code.cpp.models.implementations.Printf
+class PrintfFormatAttribute extends FormatAttribute {
+ PrintfFormatAttribute() {
+ getArchetype() = "printf" or
+ getArchetype() = "__printf__"
+ }
+}
+
/**
* A function that can be identified as a `printf` style formatting
* function by its use of the GNU `format` attribute.
*/
class AttributeFormattingFunction extends FormattingFunction {
- FormatAttribute printf_attrib;
-
override string getCanonicalQLClass() { result = "AttributeFormattingFunction" }
AttributeFormattingFunction() {
- printf_attrib = getAnAttribute() and
- (
- printf_attrib.getArchetype() = "printf" or
- printf_attrib.getArchetype() = "__printf__"
- ) and
- exists(printf_attrib.getFirstFormatArgIndex()) // exclude `vprintf` style format functions
+ exists(PrintfFormatAttribute printf_attrib |
+ printf_attrib = getAnAttribute() and
+ exists(printf_attrib.getFirstFormatArgIndex()) // exclude `vprintf` style format functions
+ )
}
- override int getFormatParameterIndex() { result = printf_attrib.getFormatIndex() }
+ override int getFormatParameterIndex() {
+ forex(PrintfFormatAttribute printf_attrib | printf_attrib = getAnAttribute() |
+ result = printf_attrib.getFormatIndex()
+ )
+ }
}
/**
@@ -124,15 +131,17 @@ class FormattingFunctionCall extends Expr {
}
/**
- * Gets the argument corresponding to the nth conversion specifier
+ * Gets the argument corresponding to the nth conversion specifier.
*/
Expr getConversionArgument(int n) {
- exists(FormatLiteral fl, int b, int o |
+ exists(FormatLiteral fl |
fl = this.getFormat() and
- b = sum(int i, int toSum | i < n and toSum = fl.getNumArgNeeded(i) | toSum) and
- o = fl.getNumArgNeeded(n) and
- o > 0 and
- result = this.getFormatArgument(b + o - 1)
+ (
+ result = this.getFormatArgument(fl.getParameterFieldValue(n))
+ or
+ result = this.getFormatArgument(fl.getFormatArgumentIndexFor(n, 2)) and
+ not exists(fl.getParameterFieldValue(n))
+ )
)
}
@@ -142,11 +151,14 @@ class FormattingFunctionCall extends Expr {
* an explicit minimum field width).
*/
Expr getMinFieldWidthArgument(int n) {
- exists(FormatLiteral fl, int b |
+ exists(FormatLiteral fl |
fl = this.getFormat() and
- b = sum(int i, int toSum | i < n and toSum = fl.getNumArgNeeded(i) | toSum) and
- fl.hasImplicitMinFieldWidth(n) and
- result = this.getFormatArgument(b)
+ (
+ result = this.getFormatArgument(fl.getMinFieldWidthParameterFieldValue(n))
+ or
+ result = this.getFormatArgument(fl.getFormatArgumentIndexFor(n, 0)) and
+ not exists(fl.getMinFieldWidthParameterFieldValue(n))
+ )
)
}
@@ -156,12 +168,14 @@ class FormattingFunctionCall extends Expr {
* precision).
*/
Expr getPrecisionArgument(int n) {
- exists(FormatLiteral fl, int b, int o |
+ exists(FormatLiteral fl |
fl = this.getFormat() and
- b = sum(int i, int toSum | i < n and toSum = fl.getNumArgNeeded(i) | toSum) and
- (if fl.hasImplicitMinFieldWidth(n) then o = 1 else o = 0) and
- fl.hasImplicitPrecision(n) and
- result = this.getFormatArgument(b + o)
+ (
+ result = this.getFormatArgument(fl.getPrecisionParameterFieldValue(n))
+ or
+ result = this.getFormatArgument(fl.getFormatArgumentIndexFor(n, 1)) and
+ not exists(fl.getPrecisionParameterFieldValue(n))
+ )
)
}
@@ -361,6 +375,14 @@ class FormatLiteral extends Literal {
*/
string getParameterField(int n) { this.parseConvSpec(n, _, result, _, _, _, _, _) }
+ /**
+ * Gets the parameter field of the nth conversion specifier (if it has one) as a
+ * zero-based number.
+ */
+ int getParameterFieldValue(int n) {
+ result = this.getParameterField(n).regexpCapture("([0-9]*)\\$", 1).toInt() - 1
+ }
+
/**
* Gets the flags of the nth conversion specifier.
*/
@@ -430,6 +452,14 @@ class FormatLiteral extends Literal {
*/
int getMinFieldWidth(int n) { result = this.getMinFieldWidthOpt(n).toInt() }
+ /**
+ * Gets the zero-based parameter number of the minimum field width of the nth
+ * conversion specifier, if it is implicit and uses a parameter field (such as `*1$`).
+ */
+ int getMinFieldWidthParameterFieldValue(int n) {
+ result = this.getMinFieldWidthOpt(n).regexpCapture("\\*([0-9]*)\\$", 1).toInt() - 1
+ }
+
/**
* Gets the precision of the nth conversion specifier (empty string if none is given).
*/
@@ -460,6 +490,14 @@ class FormatLiteral extends Literal {
else result = this.getPrecisionOpt(n).regexpCapture("\\.([0-9]*)", 1).toInt()
}
+ /**
+ * Gets the zero-based parameter number of the precision of the nth conversion
+ * specifier, if it is implicit and uses a parameter field (such as `*1$`).
+ */
+ int getPrecisionParameterFieldValue(int n) {
+ result = this.getPrecisionOpt(n).regexpCapture("\\.\\*([0-9]*)\\$", 1).toInt() - 1
+ }
+
/**
* Gets the length flag of the nth conversion specifier.
*/
@@ -777,19 +815,49 @@ class FormatLiteral extends Literal {
)
}
+ /**
+ * Holds if the nth conversion specifier of this format string (if `mode = 2`), it's
+ * minimum field width (if `mode = 0`) or it's precision (if `mode = 1`) requires a
+ * format argument.
+ *
+ * Most conversion specifiers require a format argument, whereas minimum field width
+ * and precision only require a format argument if they are present and a `*` was
+ * used for it's value in the format string.
+ */
+ private predicate hasFormatArgumentIndexFor(int n, int mode) {
+ mode = 0 and
+ this.hasImplicitMinFieldWidth(n)
+ or
+ mode = 1 and
+ this.hasImplicitPrecision(n)
+ or
+ mode = 2 and
+ exists(this.getConvSpecOffset(n)) and
+ not this.getConversionChar(n) = "m"
+ }
+
+ /**
+ * Gets the computed format argument index for the nth conversion specifier of this
+ * format string (if `mode = 2`), it's minimum field width (if `mode = 0`) or it's
+ * precision (if `mode = 1`). Has no result if that element is not present. Does
+ * not account for positional arguments (`$`).
+ */
+ int getFormatArgumentIndexFor(int n, int mode) {
+ hasFormatArgumentIndexFor(n, mode) and
+ (3 * n) + mode = rank[result + 1](int n2, int mode2 |
+ hasFormatArgumentIndexFor(n2, mode2)
+ |
+ (3 * n2) + mode2
+ )
+ }
+
/**
* Gets the number of arguments required by the nth conversion specifier
* of this format string.
*/
int getNumArgNeeded(int n) {
exists(this.getConvSpecOffset(n)) and
- not this.getConversionChar(n) = "%" and
- exists(int n1, int n2, int n3 |
- (if this.hasImplicitMinFieldWidth(n) then n1 = 1 else n1 = 0) and
- (if this.hasImplicitPrecision(n) then n2 = 1 else n2 = 0) and
- (if this.getConversionChar(n) = "m" then n3 = 0 else n3 = 1) and
- result = n1 + n2 + n3
- )
+ result = count(int mode | hasFormatArgumentIndexFor(n, mode))
}
/**
@@ -801,7 +869,7 @@ class FormatLiteral extends Literal {
// At least one conversion specifier has a parameter field, in which case,
// they all should have.
result = max(string s | this.getParameterField(_) = s + "$" | s.toInt())
- else result = sum(int n, int toSum | toSum = this.getNumArgNeeded(n) | toSum)
+ else result = count(int n, int mode | hasFormatArgumentIndexFor(n, mode))
}
/**
diff --git a/cpp/ql/src/semmle/code/cpp/commons/StringAnalysis.qll b/cpp/ql/src/semmle/code/cpp/commons/StringAnalysis.qll
index e10e52df07d..772bb42e319 100644
--- a/cpp/ql/src/semmle/code/cpp/commons/StringAnalysis.qll
+++ b/cpp/ql/src/semmle/code/cpp/commons/StringAnalysis.qll
@@ -53,8 +53,8 @@ class AnalysedString extends Expr {
*/
class StrlenCall extends FunctionCall {
StrlenCall() {
- this.getTarget().hasGlobalName("strlen") or
- this.getTarget().hasGlobalName("wcslen") or
+ this.getTarget().hasGlobalOrStdName("strlen") or
+ this.getTarget().hasGlobalOrStdName("wcslen") or
this.getTarget().hasGlobalName("_mbslen") or
this.getTarget().hasGlobalName("_mbslen_l") or
this.getTarget().hasGlobalName("_mbstrlen") or
diff --git a/cpp/ql/src/semmle/code/cpp/controlflow/Dereferenced.qll b/cpp/ql/src/semmle/code/cpp/controlflow/Dereferenced.qll
index cfd3efa91f3..69c5963af30 100644
--- a/cpp/ql/src/semmle/code/cpp/controlflow/Dereferenced.qll
+++ b/cpp/ql/src/semmle/code/cpp/controlflow/Dereferenced.qll
@@ -6,7 +6,7 @@ import Nullness
*/
predicate callDereferences(FunctionCall fc, int i) {
exists(string name |
- fc.getTarget().hasGlobalName(name) and
+ fc.getTarget().hasGlobalOrStdName(name) and
(
name = "bcopy" and i in [0 .. 1]
or
diff --git a/cpp/ql/src/semmle/code/cpp/controlflow/Nullness.qll b/cpp/ql/src/semmle/code/cpp/controlflow/Nullness.qll
index 54b14aadd9d..caaa5b54e8c 100644
--- a/cpp/ql/src/semmle/code/cpp/controlflow/Nullness.qll
+++ b/cpp/ql/src/semmle/code/cpp/controlflow/Nullness.qll
@@ -264,9 +264,9 @@ predicate callMayReturnNull(Call call) {
* Holds if `f` may, directly or indirectly, return a null literal.
*/
predicate mayReturnNull(Function f) {
- f.hasGlobalName("malloc")
+ f.hasGlobalOrStdName("malloc")
or
- f.hasGlobalName("calloc")
+ f.hasGlobalOrStdName("calloc")
or
// f.hasGlobalName("strchr")
// or
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
index 0caa2ab05df..fc0b5a90882 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
@@ -5,6 +5,8 @@
private import cpp
private import semmle.code.cpp.dataflow.internal.FlowVar
private import semmle.code.cpp.models.interfaces.DataFlow
+private import semmle.code.cpp.controlflow.Guards
+private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
cached
private newtype TNode =
@@ -680,12 +682,16 @@ VariableAccess getAnAccessToAssignedVariable(Expr assign) {
*
* It is important that all extending classes in scope are disjoint.
*/
-class BarrierGuard extends Expr {
- /** NOT YET SUPPORTED. Holds if this guard validates `e` upon evaluating to `branch`. */
- abstract deprecated predicate checks(Expr e, boolean branch);
+class BarrierGuard extends GuardCondition {
+ /** Override this predicate to hold if this guard validates `e` upon evaluating to `b`. */
+ abstract predicate checks(Expr e, boolean b);
/** Gets a node guarded by this guard. */
- final Node getAGuardedNode() {
- none() // stub
+ final ExprNode getAGuardedNode() {
+ exists(GVN value, boolean branch |
+ result.getExpr() = value.getAnExpr() and
+ this.checks(value.getAnExpr(), branch) and
+ this.controls(result.getExpr().getBasicBlock(), branch)
+ )
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/dispatch/VirtualDispatch.qll b/cpp/ql/src/semmle/code/cpp/dispatch/VirtualDispatchPrototype.qll
similarity index 77%
rename from cpp/ql/src/semmle/code/cpp/dispatch/VirtualDispatch.qll
rename to cpp/ql/src/semmle/code/cpp/dispatch/VirtualDispatchPrototype.qll
index 2fa9322843e..9992f88867b 100644
--- a/cpp/ql/src/semmle/code/cpp/dispatch/VirtualDispatch.qll
+++ b/cpp/ql/src/semmle/code/cpp/dispatch/VirtualDispatchPrototype.qll
@@ -28,6 +28,19 @@ module VirtualDispatch {
not result.hasName("IUnknown")
}
+ /**
+ * Helper predicate for `getAViableTarget`, which computes the viable targets for
+ * virtual calls based on the qualifier type.
+ */
+ private Function getAViableVirtualCallTarget(Class qualifierType, MemberFunction staticTarget) {
+ exists(Class qualifierSubType |
+ result = getAPossibleImplementation(staticTarget) and
+ qualifierType = qualifierSubType.getABaseClass*() and
+ mayInherit(qualifierSubType, result) and
+ not cannotInherit(qualifierSubType, result)
+ )
+ }
+
/**
* Gets a viable target for the given function call.
*
@@ -42,18 +55,9 @@ module VirtualDispatch {
* If `c` is not a virtual call, the result will be `c.getTarget()`.
*/
Function getAViableTarget(Call c) {
- exists(Function staticTarget | staticTarget = c.getTarget() |
- if c.(FunctionCall).isVirtual() and staticTarget instanceof MemberFunction
- then
- exists(Class qualifierType, Class qualifierSubType |
- result = getAPossibleImplementation(staticTarget) and
- qualifierType = getCallQualifierType(c) and
- qualifierType = qualifierSubType.getABaseClass*() and
- mayInherit(qualifierSubType, result) and
- not cannotInherit(qualifierSubType, result)
- )
- else result = staticTarget
- )
+ if c.(FunctionCall).isVirtual() and c.getTarget() instanceof MemberFunction
+ then result = getAViableVirtualCallTarget(getCallQualifierType(c), c.getTarget())
+ else result = c.getTarget()
}
/** Holds if `f` is declared in `c` or a transitive base class of `c`. */
@@ -63,7 +67,7 @@ module VirtualDispatch {
/**
* Holds if `c` cannot inherit the member function `f`,
- * i.e. `c` or one of its supertypes overrides `f`.
+ * that is, `c` or one of its supertypes overrides `f`.
*/
private predicate cannotInherit(Class c, MemberFunction f) {
exists(Class overridingType, MemberFunction override |
diff --git a/cpp/ql/src/semmle/code/cpp/exprs/Call.qll b/cpp/ql/src/semmle/code/cpp/exprs/Call.qll
index 882918316f6..22a25969a8f 100644
--- a/cpp/ql/src/semmle/code/cpp/exprs/Call.qll
+++ b/cpp/ql/src/semmle/code/cpp/exprs/Call.qll
@@ -139,17 +139,29 @@ class FunctionCall extends Call, @funbindexpr {
override string getCanonicalQLClass() { result = "FunctionCall" }
/** Gets an explicit template argument for this call. */
- Type getAnExplicitTemplateArgument() { result = getExplicitTemplateArgument(_) }
+ Locatable getAnExplicitTemplateArgument() { result = getExplicitTemplateArgument(_) }
+
+ /** Gets an explicit template argument value for this call. */
+ Locatable getAnExplicitTemplateArgumentKind() { result = getExplicitTemplateArgumentKind(_) }
/** Gets a template argument for this call. */
- Type getATemplateArgument() { result = getTarget().getATemplateArgument() }
+ Locatable getATemplateArgument() { result = getTarget().getATemplateArgument() }
+
+ /** Gets a template argument value for this call. */
+ Locatable getATemplateArgumentKind() { result = getTarget().getATemplateArgumentKind() }
/** Gets the nth explicit template argument for this call. */
- Type getExplicitTemplateArgument(int n) {
+ Locatable getExplicitTemplateArgument(int n) {
n < getNumberOfExplicitTemplateArguments() and
result = getTemplateArgument(n)
}
+ /** Gets the nth explicit template argument value for this call. */
+ Locatable getExplicitTemplateArgumentKind(int n) {
+ n < getNumberOfExplicitTemplateArguments() and
+ result = getTemplateArgumentKind(n)
+ }
+
/** Gets the number of explicit template arguments for this call. */
int getNumberOfExplicitTemplateArguments() {
if numtemplatearguments(underlyingElement(this), _)
@@ -161,7 +173,10 @@ class FunctionCall extends Call, @funbindexpr {
int getNumberOfTemplateArguments() { result = count(int i | exists(getTemplateArgument(i))) }
/** Gets the nth template argument for this call (indexed from 0). */
- Type getTemplateArgument(int n) { result = getTarget().getTemplateArgument(n) }
+ Locatable getTemplateArgument(int n) { result = getTarget().getTemplateArgument(n) }
+
+ /** Gets the nth template argument value for this call (indexed from 0). */
+ Locatable getTemplateArgumentKind(int n) { result = getTarget().getTemplateArgumentKind(n) }
/** Holds if any template arguments for this call are implicit / deduced. */
predicate hasImplicitTemplateArguments() {
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll
index 08556a4af39..e0135e0ad2f 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll
@@ -2,6 +2,7 @@ import cpp
import semmle.code.cpp.security.Security
private import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.IR
+private import semmle.code.cpp.ir.dataflow.internal.DataFlowDispatch as Dispatch
/**
* A predictable instruction is one where an external user can predict
@@ -37,7 +38,7 @@ private class DefaultTaintTrackingCfg extends DataFlow::Configuration {
}
private predicate accessesVariable(CopyInstruction copy, Variable var) {
- exists(VariableAddressInstruction va | va.getVariable().getAST() = var |
+ exists(VariableAddressInstruction va | va.getASTVariable() = var |
copy.(StoreInstruction).getDestinationAddress() = va
or
copy.(LoadInstruction).getSourceAddress() = va
@@ -145,7 +146,8 @@ GlobalOrNamespaceVariable globalVarFromId(string id) {
}
Function resolveCall(Call call) {
- // TODO: improve virtual dispatch. This will help in the test for
- // `UncontrolledProcessOperation.ql`.
- result = call.getTarget()
+ exists(CallInstruction callInstruction |
+ callInstruction.getAST() = call and
+ result = Dispatch::viableCallable(callInstruction)
+ )
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll
index d0325a28d3e..9572639de59 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll
@@ -1,5 +1,6 @@
private import cpp
private import semmle.code.cpp.ir.IR
+private import semmle.code.cpp.ir.dataflow.DataFlow
Function viableImpl(CallInstruction call) { result = viableCallable(call) }
@@ -20,6 +21,58 @@ Function viableCallable(CallInstruction call) {
functionSignatureWithBody(qualifiedName, nparams, result) and
strictcount(Function other | functionSignatureWithBody(qualifiedName, nparams, other)) = 1
)
+ or
+ // Rudimentary virtual dispatch support. It's essentially local data flow
+ // where the source is a derived-to-base conversion and the target is the
+ // qualifier of a call.
+ exists(Class derived, DataFlow::Node thisArgument |
+ nodeMayHaveClass(derived, thisArgument) and
+ overrideMayAffectCall(derived, thisArgument, _, result, call)
+ )
+}
+
+/**
+ * Holds if `call` is a virtual function call with qualifier `thisArgument` in
+ * `enclosingFunction`, whose static target is overridden by
+ * `overridingFunction` in `overridingClass`.
+ */
+pragma[noinline]
+private predicate overrideMayAffectCall(
+ Class overridingClass, DataFlow::Node thisArgument, Function enclosingFunction,
+ MemberFunction overridingFunction, CallInstruction call
+) {
+ call.getEnclosingFunction() = enclosingFunction and
+ overridingFunction.getAnOverriddenFunction+() = call.getStaticCallTarget() and
+ overridingFunction.getDeclaringType() = overridingClass and
+ thisArgument = DataFlow::instructionNode(call.getThisArgument())
+}
+
+/**
+ * Holds if `node` may have dynamic class `derived`, where `derived` is a class
+ * that may affect virtual dispatch within the enclosing function.
+ *
+ * For the sake of performance, this recursion is written out manually to make
+ * it a relation on `Class x Node` rather than `Node x Node` or `MemberFunction
+ * x Node`, both of which would be larger. It's a forward search since there
+ * should usually be fewer classes than calls.
+ *
+ * If a value is cast several classes up in the hierarchy, that will be modeled
+ * as a chain of `ConvertToBaseInstruction`s and will cause the search to start
+ * from each of them and pass through subsequent ones. There might be
+ * performance to gain by stopping before a second upcast and reconstructing
+ * the full chain in a "big-step" recursion after this one.
+ */
+private predicate nodeMayHaveClass(Class derived, DataFlow::Node node) {
+ exists(ConvertToBaseInstruction toBase |
+ derived = toBase.getDerivedClass() and
+ overrideMayAffectCall(derived, _, toBase.getEnclosingFunction(), _, _) and
+ node.asInstruction() = toBase
+ )
+ or
+ exists(DataFlow::Node prev |
+ nodeMayHaveClass(derived, prev) and
+ DataFlow::localFlowStep(prev, node)
+ )
}
/**
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
index 0476ea3c30a..4e84424fcb7 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
@@ -5,6 +5,7 @@
private import cpp
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.controlflow.IRGuards
+private import semmle.code.cpp.ir.ValueNumbering
/**
* A newtype wrapper to prevent accidental casts between `Node` and
@@ -204,7 +205,8 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
iTo.(CopyInstruction).getSourceValue() = iFrom or
iTo.(PhiInstruction).getAnOperand().getDef() = iFrom or
// Treat all conversions as flow, even conversions between different numeric types.
- iTo.(ConvertInstruction).getUnary() = iFrom
+ iTo.(ConvertInstruction).getUnary() = iFrom or
+ iTo.(InheritanceConversionInstruction).getUnary() = iFrom
}
/**
@@ -213,6 +215,14 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
*/
predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
+/**
+ * Holds if data can flow from `i1` to `i2` in zero or more
+ * local (intra-procedural) steps.
+ */
+predicate localInstructionFlow(Instruction e1, Instruction e2) {
+ localFlow(instructionNode(e1), instructionNode(e2))
+}
+
/**
* Holds if data can flow from `e1` to `e2` in zero or more
* local (intra-procedural) steps.
@@ -220,7 +230,7 @@ predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)) }
/**
- * A guard that validates some expression.
+ * A guard that validates some instruction.
*
* To use this in a configuration, extend the class and provide a
* characteristic predicate precisely specifying the guard, and override
@@ -229,11 +239,15 @@ predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)
* It is important that all extending classes in scope are disjoint.
*/
class BarrierGuard extends IRGuardCondition {
- /** NOT YET SUPPORTED. Holds if this guard validates `e` upon evaluating to `b`. */
- abstract deprecated predicate checks(Instruction e, boolean b);
+ /** Override this predicate to hold if this guard validates `instr` upon evaluating to `b`. */
+ abstract predicate checks(Instruction instr, boolean b);
/** Gets a node guarded by this guard. */
final Node getAGuardedNode() {
- none() // stub
+ exists(ValueNumber value, boolean edge |
+ result.asInstruction() = value.getAnInstruction() and
+ this.checks(value.getAnInstruction(), edge) and
+ this.controls(result.asInstruction().getBlock(), edge)
+ )
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll
index e34709e94ec..8d7c9194f4f 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll
@@ -53,6 +53,14 @@ private predicate localInstructionTaintStep(Instruction nodeFrom, Instruction no
*/
predicate localTaint(DataFlow::Node source, DataFlow::Node sink) { localTaintStep*(source, sink) }
+/**
+ * Holds if taint can flow from `i1` to `i2` in zero or more
+ * local (intra-procedural) steps.
+ */
+predicate localInstructionTaint(Instruction i1, Instruction i2) {
+ localTaint(DataFlow::instructionNode(i1), DataFlow::instructionNode(i2))
+}
+
/**
* Holds if taint can flow from `e1` to `e2` in zero or more
* local (intra-procedural) steps.
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll
index 0abfa14023d..73cdbd20989 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll
@@ -4,6 +4,7 @@
private import internal.IRTypeInternal
+cached
private newtype TIRType =
TIRVoidType() or
TIRUnknownType() or
@@ -42,6 +43,10 @@ class IRType extends TIRType {
*
* This will hold for all `IRType` objects except `IRUnknownType`.
*/
+ // This predicate is overridden with `pragma[noinline]` in every leaf subclass.
+ // This allows callers to ask for things like _the_ floating-point type of
+ // size 4 without getting a join that first finds all types of size 4 and
+ // _then_ restricts them to floating-point types.
int getByteSize() { none() }
/**
@@ -104,8 +109,6 @@ private class IRSizedType extends IRType {
this = TIRFunctionAddressType(byteSize) or
this = TIROpaqueType(_, byteSize)
}
-
- final override int getByteSize() { result = byteSize }
}
/**
@@ -117,6 +120,9 @@ class IRBooleanType extends IRSizedType, TIRBooleanType {
final override Language::LanguageType getCanonicalLanguageType() {
result = Language::getCanonicalBooleanType(byteSize)
}
+
+ pragma[noinline]
+ final override int getByteSize() { result = byteSize }
}
/**
@@ -141,6 +147,9 @@ class IRSignedIntegerType extends IRNumericType, TIRSignedIntegerType {
final override Language::LanguageType getCanonicalLanguageType() {
result = Language::getCanonicalSignedIntegerType(byteSize)
}
+
+ pragma[noinline]
+ final override int getByteSize() { result = byteSize }
}
/**
@@ -153,6 +162,9 @@ class IRUnsignedIntegerType extends IRNumericType, TIRUnsignedIntegerType {
final override Language::LanguageType getCanonicalLanguageType() {
result = Language::getCanonicalUnsignedIntegerType(byteSize)
}
+
+ pragma[noinline]
+ final override int getByteSize() { result = byteSize }
}
/**
@@ -164,6 +176,9 @@ class IRFloatingPointType extends IRNumericType, TIRFloatingPointType {
final override Language::LanguageType getCanonicalLanguageType() {
result = Language::getCanonicalFloatingPointType(byteSize)
}
+
+ pragma[noinline]
+ final override int getByteSize() { result = byteSize }
}
/**
@@ -178,6 +193,9 @@ class IRAddressType extends IRSizedType, TIRAddressType {
final override Language::LanguageType getCanonicalLanguageType() {
result = Language::getCanonicalAddressType(byteSize)
}
+
+ pragma[noinline]
+ final override int getByteSize() { result = byteSize }
}
/**
@@ -190,6 +208,9 @@ class IRFunctionAddressType extends IRSizedType, TIRFunctionAddressType {
final override Language::LanguageType getCanonicalLanguageType() {
result = Language::getCanonicalFunctionAddressType(byteSize)
}
+
+ pragma[noinline]
+ final override int getByteSize() { result = byteSize }
}
/**
@@ -218,6 +239,9 @@ class IROpaqueType extends IRSizedType, TIROpaqueType {
* same size.
*/
final Language::OpaqueTypeTag getTag() { result = tag }
+
+ pragma[noinline]
+ final override int getByteSize() { result = byteSize }
}
module IRTypeSanity {
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/MemoryAccessKind.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/MemoryAccessKind.qll
index d4f1599d78e..a71608ee855 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/MemoryAccessKind.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/MemoryAccessKind.qll
@@ -5,6 +5,7 @@ private newtype TMemoryAccessKind =
TBufferMayMemoryAccess() or
TEscapedMemoryAccess() or
TEscapedMayMemoryAccess() or
+ TNonLocalMayMemoryAccess() or
TPhiMemoryAccess() or
TUnmodeledMemoryAccess() or
TChiTotalMemoryAccess() or
@@ -80,6 +81,14 @@ class EscapedMayMemoryAccess extends MemoryAccessKind, TEscapedMayMemoryAccess {
override string toString() { result = "escaped(may)" }
}
+/**
+ * The operand or result may access all memory whose address has escaped, other than data on the
+ * stack frame of the current function.
+ */
+class NonLocalMayMemoryAccess extends MemoryAccessKind, TNonLocalMayMemoryAccess {
+ override string toString() { result = "nonlocal(may)" }
+}
+
/**
* The operand is a Phi operand, which accesses the same memory as its
* definition.
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll
index 713893f52f7..edbec38d5b9 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll
@@ -36,7 +36,7 @@ private newtype TOpcode =
TPointerSub() or
TPointerDiff() or
TConvert() or
- TConvertToBase() or
+ TConvertToNonVirtualBase() or
TConvertToVirtualBase() or
TConvertToDerived() or
TCheckedConvertOrNull() or
@@ -59,6 +59,7 @@ private newtype TOpcode =
TUnmodeledDefinition() or
TUnmodeledUse() or
TAliasedDefinition() or
+ TAliasedUse() or
TPhi() or
TBuiltIn() or
TVarArgsStart() or
@@ -111,6 +112,8 @@ abstract class RelationalOpcode extends CompareOpcode { }
abstract class CopyOpcode extends Opcode { }
+abstract class ConvertToBaseOpcode extends UnaryOpcode { }
+
abstract class MemoryAccessOpcode extends Opcode { }
abstract class ReturnOpcode extends Opcode { }
@@ -311,11 +314,11 @@ module Opcode {
final override string toString() { result = "Convert" }
}
- class ConvertToBase extends UnaryOpcode, TConvertToBase {
- final override string toString() { result = "ConvertToBase" }
+ class ConvertToNonVirtualBase extends ConvertToBaseOpcode, TConvertToNonVirtualBase {
+ final override string toString() { result = "ConvertToNonVirtualBase" }
}
- class ConvertToVirtualBase extends UnaryOpcode, TConvertToVirtualBase {
+ class ConvertToVirtualBase extends ConvertToBaseOpcode, TConvertToVirtualBase {
final override string toString() { result = "ConvertToVirtualBase" }
}
@@ -403,6 +406,10 @@ module Opcode {
final override string toString() { result = "AliasedDefinition" }
}
+ class AliasedUse extends Opcode, TAliasedUse {
+ final override string toString() { result = "AliasedUse" }
+ }
+
class Phi extends Opcode, TPhi {
final override string toString() { result = "Phi" }
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll
index 1a607f82c29..e10e266b2ab 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll
@@ -22,6 +22,12 @@ abstract class IRVariable extends TIRVariable {
abstract string toString();
+ /**
+ * Holds if this variable's value cannot be changed within a function. Currently used for string
+ * literals, but could also apply to `const` global and static variables.
+ */
+ predicate isReadOnly() { none() }
+
/**
* Gets the type of the variable.
*/
@@ -113,34 +119,43 @@ class IRStaticUserVariable extends IRUserVariable {
final override Language::StaticVariable getVariable() { result = var }
}
+abstract class IRGeneratedVariable extends IRVariable {
+ Language::AST ast;
+ Language::LanguageType type;
+
+ final override Language::LanguageType getLanguageType() { result = type }
+
+ final override Language::AST getAST() { result = ast }
+
+ override string toString() { result = getBaseString() + getLocationString() }
+
+ override string getUniqueId() { none() }
+
+ final string getLocationString() {
+ result = ast.getLocation().getStartLine().toString() + ":" +
+ ast.getLocation().getStartColumn().toString()
+ }
+
+ string getBaseString() { none() }
+}
+
IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
result.getAST() = ast and
result.getTag() = tag
}
-class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable {
- Language::AST ast;
+class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable {
TempVariableTag tag;
- Language::LanguageType type;
IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) }
- final override Language::LanguageType getLanguageType() { result = type }
-
- final override Language::AST getAST() { result = ast }
-
final override string getUniqueId() {
result = "Temp: " + Construction::getTempVariableUniqueId(this)
}
final TempVariableTag getTag() { result = tag }
- override string toString() {
- result = getBaseString() + ast.getLocation().getStartLine().toString() + ":" +
- ast.getLocation().getStartColumn().toString()
- }
-
- string getBaseString() { result = "#temp" }
+ override string getBaseString() { result = "#temp" }
}
class IRReturnVariable extends IRTempVariable {
@@ -154,3 +169,19 @@ class IRThrowVariable extends IRTempVariable {
override string getBaseString() { result = "#throw" }
}
+
+class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
+ Language::StringLiteral literal;
+
+ IRStringLiteral() { this = TIRStringLiteral(func, ast, type, literal) }
+
+ final override predicate isReadOnly() { any() }
+
+ final override string getUniqueId() {
+ result = "String: " + getLocationString() + "=" + Language::getStringLiteralText(literal)
+ }
+
+ override string getBaseString() { result = "#string" }
+
+ final Language::StringLiteral getLiteral() { result = literal }
+}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
index a2a39e4d42e..8e785015828 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
@@ -51,7 +51,8 @@ module InstructionSanity {
opcode instanceof ReadSideEffectOpcode or
opcode instanceof Opcode::InlineAsm or
opcode instanceof Opcode::CallSideEffect or
- opcode instanceof Opcode::ReturnIndirection
+ opcode instanceof Opcode::ReturnIndirection or
+ opcode instanceof Opcode::AliasedUse
) and
tag instanceof SideEffectOperandTag
)
@@ -124,6 +125,16 @@ module InstructionSanity {
)
}
+ query predicate duplicateChiOperand(
+ ChiInstruction chi, string message, IRFunction func, string funcText
+ ) {
+ chi.getTotal() = chi.getPartial() and
+ message = "Chi instruction for " + chi.getPartial().toString() +
+ " has duplicate operands in function $@" and
+ func = chi.getEnclosingIRFunction() and
+ funcText = Language::getIdentityString(func.getFunction())
+ }
+
query predicate sideEffectWithoutPrimary(
SideEffectInstruction instr, string message, IRFunction func, string funcText
) {
@@ -264,6 +275,7 @@ module InstructionSanity {
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
+ not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
@@ -827,14 +839,12 @@ class FloatConstantInstruction extends ConstantInstruction {
FloatConstantInstruction() { getResultType() instanceof Language::FloatingPointType }
}
-class StringConstantInstruction extends Instruction {
- Language::StringLiteral value;
+class StringConstantInstruction extends VariableInstruction {
+ override IRStringLiteral var;
- StringConstantInstruction() { value = Construction::getInstructionStringLiteral(this) }
+ final override string getImmediateString() { result = Language::getStringLiteralText(getValue()) }
- final override string getImmediateString() { result = Language::getStringLiteralText(value) }
-
- final Language::StringLiteral getValue() { result = value }
+ final Language::StringLiteral getValue() { result = var.getLiteral() }
}
class BinaryInstruction extends Instruction {
@@ -1002,14 +1012,22 @@ class InheritanceConversionInstruction extends UnaryInstruction {
* to the address of a direct non-virtual base class.
*/
class ConvertToBaseInstruction extends InheritanceConversionInstruction {
- ConvertToBaseInstruction() { getOpcode() instanceof Opcode::ConvertToBase }
+ ConvertToBaseInstruction() { getOpcode() instanceof ConvertToBaseOpcode }
+}
+
+/**
+ * Represents an instruction that converts from the address of a derived class
+ * to the address of a direct non-virtual base class.
+ */
+class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction {
+ ConvertToNonVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToNonVirtualBase }
}
/**
* Represents an instruction that converts from the address of a derived class
* to the address of a virtual base class.
*/
-class ConvertToVirtualBaseInstruction extends InheritanceConversionInstruction {
+class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction {
ConvertToVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToVirtualBase }
}
@@ -1442,6 +1460,13 @@ class AliasedDefinitionInstruction extends Instruction {
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
}
+/**
+ * An instruction that consumes all escaped memory on exit from the function.
+ */
+class AliasedUseInstruction extends Instruction {
+ AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
+}
+
class UnmodeledUseInstruction extends Instruction {
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll
index c85d609d200..8042dfa6a69 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll
@@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override MemoryAccessKind getMemoryAccess() {
+ useInstr instanceof AliasedUseInstruction and
+ result instanceof NonLocalMayMemoryAccess
+ or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess
or
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll
index 74c288d3468..2768f910120 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll
@@ -110,7 +110,7 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset) {
instr = operand.getUse() and
(
// Converting to a non-virtual base class adds the offset of the base class.
- exists(ConvertToBaseInstruction convert |
+ exists(ConvertToNonVirtualBaseInstruction convert |
convert = instr and
bitOffset = Ints::mul(convert.getDerivation().getByteOffset(), 8)
)
@@ -309,6 +309,10 @@ predicate resultPointsTo(Instruction instr, IRVariable var, IntValue bitOffset)
instr.(VariableAddressInstruction).getIRVariable() = var and
bitOffset = 0
or
+ // A string literal is just a special read-only global variable.
+ instr.(StringConstantInstruction).getIRVariable() = var and
+ bitOffset = 0
+ or
exists(Operand operand, IntValue originalBitOffset, IntValue propagatedBitOffset |
operand = instr.getAnOperand() and
// If an operand is propagated, then the result points to the same variable,
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll
index e53a41e3f2a..0835ffb7da6 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll
@@ -45,6 +45,7 @@ private newtype TMemoryLocation =
languageType = type.getCanonicalLanguageType()
} or
TUnknownMemoryLocation(IRFunction irFunc) or
+ TUnknownNonLocalMemoryLocation(IRFunction irFunc) or
TUnknownVirtualVariable(IRFunction irFunc)
/**
@@ -162,6 +163,26 @@ class UnknownMemoryLocation extends TUnknownMemoryLocation, MemoryLocation {
final override string getUniqueId() { result = "{Unknown}" }
}
+/**
+ * An access to memory that is not known to be confined to a specific `IRVariable`, but is known to
+ * not access memory on the current function's stack frame.
+ */
+class UnknownNonLocalMemoryLocation extends TUnknownNonLocalMemoryLocation, MemoryLocation {
+ IRFunction irFunc;
+
+ UnknownNonLocalMemoryLocation() { this = TUnknownNonLocalMemoryLocation(irFunc) }
+
+ final override string toString() { result = "{UnknownNonLocal}" }
+
+ final override VirtualVariable getVirtualVariable() { result = TUnknownVirtualVariable(irFunc) }
+
+ final override Language::LanguageType getType() {
+ result = any(IRUnknownType type).getCanonicalLanguageType()
+ }
+
+ final override string getUniqueId() { result = "{UnknownNonLocal}" }
+}
+
/**
* An access to all aliased memory.
*/
@@ -189,10 +210,21 @@ Overlap getOverlap(MemoryLocation def, MemoryLocation use) {
def instanceof UnknownVirtualVariable and
result instanceof MustTotallyOverlap
or
- // An UnknownMemoryLocation may partially overlap any Location within the same virtual variable.
+ // An UnknownMemoryLocation may partially overlap any Location within the same virtual variable,
+ // unless the location is read-only.
def.getVirtualVariable() = use.getVirtualVariable() and
def instanceof UnknownMemoryLocation and
- result instanceof MayPartiallyOverlap
+ result instanceof MayPartiallyOverlap and
+ not use.(VariableMemoryLocation).getVariable().isReadOnly()
+ or
+ // An UnknownNonLocalMemoryLocation may partially overlap any location within the same virtual
+ // variable, except a local variable or read-only variable.
+ def.getVirtualVariable() = use.getVirtualVariable() and
+ def instanceof UnknownNonLocalMemoryLocation and
+ result instanceof MayPartiallyOverlap and
+ not exists(IRVariable var | var = use.(VariableMemoryLocation).getVariable() |
+ var instanceof IRAutomaticVariable or var.isReadOnly()
+ )
or
exists(VariableMemoryLocation defVariableLocation |
defVariableLocation = def and
@@ -202,6 +234,13 @@ Overlap getOverlap(MemoryLocation def, MemoryLocation use) {
(use instanceof UnknownMemoryLocation or use instanceof UnknownVirtualVariable) and
result instanceof MayPartiallyOverlap
or
+ // A VariableMemoryLocation that is not a local variable may partially overlap an unknown
+ // non-local location within the same virtual variable.
+ def.getVirtualVariable() = use.getVirtualVariable() and
+ use instanceof UnknownNonLocalMemoryLocation and
+ result instanceof MayPartiallyOverlap and
+ not defVariableLocation.getVariable() instanceof IRAutomaticVariable
+ or
// A VariableMemoryLocation overlaps another location within the same variable based on the relationship
// of the two offset intervals.
exists(Overlap intervalOverlap |
@@ -327,6 +366,9 @@ MemoryLocation getResultMemoryLocation(Instruction instr) {
or
kind instanceof EscapedMayMemoryAccess and
result = TUnknownMemoryLocation(instr.getEnclosingIRFunction())
+ or
+ kind instanceof NonLocalMayMemoryAccess and
+ result = TUnknownNonLocalMemoryLocation(instr.getEnclosingIRFunction())
)
)
}
@@ -351,6 +393,9 @@ MemoryLocation getOperandMemoryLocation(MemoryOperand operand) {
or
kind instanceof EscapedMayMemoryAccess and
result = TUnknownMemoryLocation(operand.getEnclosingIRFunction())
+ or
+ kind instanceof NonLocalMayMemoryAccess and
+ result = TUnknownNonLocalMemoryLocation(operand.getEnclosingIRFunction())
)
)
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll
index 7152dec5c4a..a789edc7590 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll
@@ -341,11 +341,6 @@ private module Cached {
result = getOldInstruction(instruction).(OldIR::ConstantValueInstruction).getValue()
}
- cached
- Language::StringLiteral getInstructionStringLiteral(Instruction instruction) {
- result = getOldInstruction(instruction).(OldIR::StringConstantInstruction).getValue()
- }
-
cached
Language::BuiltInOperation getInstructionBuiltInOperation(Instruction instruction) {
result = getOldInstruction(instruction)
@@ -401,7 +396,11 @@ private predicate hasChiNode(Alias::VirtualVariable vvar, OldInstruction def) {
defLocation.getVirtualVariable() = vvar and
// If the definition totally (or exactly) overlaps the virtual variable, then there's no need for a `Chi`
// instruction.
- Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap
+ (
+ Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap or
+ def.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or
+ def.getResultMemoryAccess() instanceof BufferMayMemoryAccess
+ )
)
}
@@ -714,7 +713,10 @@ module DefUse {
defLocation = Alias::getResultMemoryLocation(def) and
block.getInstruction(index) = def and
overlap = Alias::getOverlap(defLocation, useLocation) and
- if overlap instanceof MayPartiallyOverlap
+ if
+ overlap instanceof MayPartiallyOverlap or
+ def.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or
+ def.getResultMemoryAccess() instanceof BufferMayMemoryAccess
then offset = (index * 2) + 1 // The use will be connected to the definition on the `Chi` instruction.
else offset = index * 2 // The use will be connected to the definition on the original instruction.
)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll
index fea67ef5ecd..01c135abf13 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll
@@ -9,4 +9,10 @@ newtype TIRVariable =
Language::Function func, Language::AST ast, TempVariableTag tag, Language::LanguageType type
) {
Construction::hasTempVariable(func, ast, tag, type)
+ } or
+ TIRStringLiteral(
+ Language::Function func, Language::AST ast, Language::LanguageType type,
+ Language::StringLiteral literal
+ ) {
+ Construction::hasStringLiteral(func, ast, type, literal)
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll
index 1a607f82c29..e10e266b2ab 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll
@@ -22,6 +22,12 @@ abstract class IRVariable extends TIRVariable {
abstract string toString();
+ /**
+ * Holds if this variable's value cannot be changed within a function. Currently used for string
+ * literals, but could also apply to `const` global and static variables.
+ */
+ predicate isReadOnly() { none() }
+
/**
* Gets the type of the variable.
*/
@@ -113,34 +119,43 @@ class IRStaticUserVariable extends IRUserVariable {
final override Language::StaticVariable getVariable() { result = var }
}
+abstract class IRGeneratedVariable extends IRVariable {
+ Language::AST ast;
+ Language::LanguageType type;
+
+ final override Language::LanguageType getLanguageType() { result = type }
+
+ final override Language::AST getAST() { result = ast }
+
+ override string toString() { result = getBaseString() + getLocationString() }
+
+ override string getUniqueId() { none() }
+
+ final string getLocationString() {
+ result = ast.getLocation().getStartLine().toString() + ":" +
+ ast.getLocation().getStartColumn().toString()
+ }
+
+ string getBaseString() { none() }
+}
+
IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
result.getAST() = ast and
result.getTag() = tag
}
-class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable {
- Language::AST ast;
+class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable {
TempVariableTag tag;
- Language::LanguageType type;
IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) }
- final override Language::LanguageType getLanguageType() { result = type }
-
- final override Language::AST getAST() { result = ast }
-
final override string getUniqueId() {
result = "Temp: " + Construction::getTempVariableUniqueId(this)
}
final TempVariableTag getTag() { result = tag }
- override string toString() {
- result = getBaseString() + ast.getLocation().getStartLine().toString() + ":" +
- ast.getLocation().getStartColumn().toString()
- }
-
- string getBaseString() { result = "#temp" }
+ override string getBaseString() { result = "#temp" }
}
class IRReturnVariable extends IRTempVariable {
@@ -154,3 +169,19 @@ class IRThrowVariable extends IRTempVariable {
override string getBaseString() { result = "#throw" }
}
+
+class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
+ Language::StringLiteral literal;
+
+ IRStringLiteral() { this = TIRStringLiteral(func, ast, type, literal) }
+
+ final override predicate isReadOnly() { any() }
+
+ final override string getUniqueId() {
+ result = "String: " + getLocationString() + "=" + Language::getStringLiteralText(literal)
+ }
+
+ override string getBaseString() { result = "#string" }
+
+ final Language::StringLiteral getLiteral() { result = literal }
+}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll
index a2a39e4d42e..8e785015828 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll
@@ -51,7 +51,8 @@ module InstructionSanity {
opcode instanceof ReadSideEffectOpcode or
opcode instanceof Opcode::InlineAsm or
opcode instanceof Opcode::CallSideEffect or
- opcode instanceof Opcode::ReturnIndirection
+ opcode instanceof Opcode::ReturnIndirection or
+ opcode instanceof Opcode::AliasedUse
) and
tag instanceof SideEffectOperandTag
)
@@ -124,6 +125,16 @@ module InstructionSanity {
)
}
+ query predicate duplicateChiOperand(
+ ChiInstruction chi, string message, IRFunction func, string funcText
+ ) {
+ chi.getTotal() = chi.getPartial() and
+ message = "Chi instruction for " + chi.getPartial().toString() +
+ " has duplicate operands in function $@" and
+ func = chi.getEnclosingIRFunction() and
+ funcText = Language::getIdentityString(func.getFunction())
+ }
+
query predicate sideEffectWithoutPrimary(
SideEffectInstruction instr, string message, IRFunction func, string funcText
) {
@@ -264,6 +275,7 @@ module InstructionSanity {
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
+ not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
@@ -827,14 +839,12 @@ class FloatConstantInstruction extends ConstantInstruction {
FloatConstantInstruction() { getResultType() instanceof Language::FloatingPointType }
}
-class StringConstantInstruction extends Instruction {
- Language::StringLiteral value;
+class StringConstantInstruction extends VariableInstruction {
+ override IRStringLiteral var;
- StringConstantInstruction() { value = Construction::getInstructionStringLiteral(this) }
+ final override string getImmediateString() { result = Language::getStringLiteralText(getValue()) }
- final override string getImmediateString() { result = Language::getStringLiteralText(value) }
-
- final Language::StringLiteral getValue() { result = value }
+ final Language::StringLiteral getValue() { result = var.getLiteral() }
}
class BinaryInstruction extends Instruction {
@@ -1002,14 +1012,22 @@ class InheritanceConversionInstruction extends UnaryInstruction {
* to the address of a direct non-virtual base class.
*/
class ConvertToBaseInstruction extends InheritanceConversionInstruction {
- ConvertToBaseInstruction() { getOpcode() instanceof Opcode::ConvertToBase }
+ ConvertToBaseInstruction() { getOpcode() instanceof ConvertToBaseOpcode }
+}
+
+/**
+ * Represents an instruction that converts from the address of a derived class
+ * to the address of a direct non-virtual base class.
+ */
+class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction {
+ ConvertToNonVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToNonVirtualBase }
}
/**
* Represents an instruction that converts from the address of a derived class
* to the address of a virtual base class.
*/
-class ConvertToVirtualBaseInstruction extends InheritanceConversionInstruction {
+class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction {
ConvertToVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToVirtualBase }
}
@@ -1442,6 +1460,13 @@ class AliasedDefinitionInstruction extends Instruction {
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
}
+/**
+ * An instruction that consumes all escaped memory on exit from the function.
+ */
+class AliasedUseInstruction extends Instruction {
+ AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
+}
+
class UnmodeledUseInstruction extends Instruction {
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Operand.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Operand.qll
index c85d609d200..8042dfa6a69 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Operand.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Operand.qll
@@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override MemoryAccessKind getMemoryAccess() {
+ useInstr instanceof AliasedUseInstruction and
+ result instanceof NonLocalMayMemoryAccess
+ or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess
or
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll
index fbf6b7e3d08..628aae26995 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll
@@ -44,6 +44,13 @@ private module Cached {
)
}
+ cached
+ predicate hasStringLiteral(Function func, Locatable ast, CppType type, StringLiteral literal) {
+ literal = ast and
+ literal.getEnclosingFunction() = func and
+ getTypeForPRValue(literal.getType()) = type
+ }
+
cached
predicate hasModeledMemoryResult(Instruction instruction) { none() }
@@ -51,20 +58,23 @@ private module Cached {
Expr getInstructionConvertedResultExpression(Instruction instruction) {
exists(TranslatedExpr translatedExpr |
translatedExpr = getTranslatedExpr(result) and
- instruction = translatedExpr.getResult()
+ instruction = translatedExpr.getResult() and
+ // Only associate `instruction` with this expression if the translated
+ // expression actually produced the instruction; not if it merely
+ // forwarded the result of another translated expression.
+ instruction = translatedExpr.getInstruction(_)
)
}
cached
Expr getInstructionUnconvertedResultExpression(Instruction instruction) {
- exists(Expr converted, TranslatedExpr translatedExpr |
+ exists(Expr converted |
result = converted.(Conversion).getExpr+()
or
result = converted
|
not result instanceof Conversion and
- translatedExpr = getTranslatedExpr(converted) and
- instruction = translatedExpr.getResult()
+ converted = getInstructionConvertedResultExpression(instruction)
)
}
@@ -231,8 +241,14 @@ private module Cached {
cached
IRVariable getInstructionVariable(Instruction instruction) {
- result = getInstructionTranslatedElement(instruction)
- .getInstructionVariable(getInstructionTag(instruction))
+ exists(TranslatedElement element, InstructionTag tag |
+ element = getInstructionTranslatedElement(instruction) and
+ tag = getInstructionTag(instruction) and
+ (
+ result = element.getInstructionVariable(tag) or
+ result.(IRStringLiteral).getAST() = element.getInstructionStringLiteral(tag)
+ )
+ )
}
cached
@@ -263,12 +279,6 @@ private module Cached {
)
}
- cached
- StringLiteral getInstructionStringLiteral(Instruction instruction) {
- result = getInstructionTranslatedElement(instruction)
- .getInstructionStringLiteral(getInstructionTag(instruction))
- }
-
cached
BuiltInOperation getInstructionBuiltInOperation(Instruction instruction) {
result = getInstructionTranslatedElement(instruction)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll
index 228ceec4822..0a809be2dfa 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll
@@ -28,6 +28,7 @@ newtype TInstructionTag =
UnmodeledDefinitionTag() or
UnmodeledUseTag() or
AliasedDefinitionTag() or
+ AliasedUseTag() or
SwitchBranchTag() or
CallTargetTag() or
CallTag() or
@@ -46,6 +47,7 @@ newtype TInstructionTag =
ConditionValueResultLoadTag() or
BoolConversionConstantTag() or
BoolConversionCompareTag() or
+ ResultCopyTag() or
LoadTag() or // Implicit load due to lvalue-to-rvalue conversion
CatchTag() or
ThrowTag() or
@@ -124,6 +126,8 @@ string getInstructionTagId(TInstructionTag tag) {
or
tag = AliasedDefinitionTag() and result = "AliasedDef"
or
+ tag = AliasedUseTag() and result = "AliasedUse"
+ or
tag = SwitchBranchTag() and result = "SwitchBranch"
or
tag = CallTargetTag() and result = "CallTarget"
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll
index 2b1d006d48c..ae9e6f1d3bd 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll
@@ -352,6 +352,11 @@ class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects {
none()
}
+ override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
+ tag = OnlyInstructionTag() and
+ result = getTranslatedExpr(expr).getInstruction(CallTag())
+ }
+
/**
* Gets the `TranslatedFunction` containing this expression.
*/
@@ -365,6 +370,39 @@ class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects {
override Function getFunction() { result = expr.getEnclosingFunction() }
}
+class TranslatedStructorCallSideEffects extends TranslatedSideEffects {
+ TranslatedStructorCallSideEffects() { getParent().(TranslatedStructorCall).hasQualifier() }
+
+ override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType t) {
+ opcode instanceof Opcode::IndirectMayWriteSideEffect and
+ tag instanceof OnlyInstructionTag and
+ t = getTypeForPRValue(expr.getTarget().getDeclaringType())
+ }
+
+ override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
+ (
+ if exists(getChild(0))
+ then result = getChild(0).getFirstInstruction()
+ else result = getParent().getChildSuccessor(this)
+ ) and
+ tag = OnlyInstructionTag() and
+ kind instanceof GotoEdge
+ }
+
+ override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
+
+ override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
+ tag instanceof OnlyInstructionTag and
+ operandTag instanceof AddressOperandTag and
+ result = getParent().(TranslatedStructorCall).getQualifierResult()
+ }
+
+ final override int getInstructionIndex(InstructionTag tag) {
+ tag = OnlyInstructionTag() and
+ result = -1
+ }
+}
+
class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEffect {
Call call;
Expr arg;
@@ -447,20 +485,26 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
}
override CppType getInstructionOperandType(InstructionTag tag, TypedOperandTag operandTag) {
- exists(Type operandType |
+ if hasSpecificReadSideEffect(any(Opcode::BufferReadSideEffect op))
+ then
+ result = getUnknownType() and
tag instanceof OnlyInstructionTag and
- operandType = arg.getType().getUnspecifiedType().(DerivedType).getBaseType() and
operandTag instanceof SideEffectOperandTag
- or
- tag instanceof OnlyInstructionTag and
- operandType = arg.getType().getUnspecifiedType() and
- not operandType instanceof DerivedType and
- operandTag instanceof SideEffectOperandTag
- |
- // If the type we select is an incomplete type (e.g. a forward-declared `struct`), there will
- // not be a `CppType` that represents that type. In that case, fall back to `UnknownCppType`.
- result = getTypeForPRValueOrUnknown(operandType)
- )
+ else
+ exists(Type operandType |
+ tag instanceof OnlyInstructionTag and
+ operandType = arg.getType().getUnspecifiedType().(DerivedType).getBaseType() and
+ operandTag instanceof SideEffectOperandTag
+ or
+ tag instanceof OnlyInstructionTag and
+ operandType = arg.getType().getUnspecifiedType() and
+ not operandType instanceof DerivedType and
+ operandTag instanceof SideEffectOperandTag
+ |
+ // If the type we select is an incomplete type (e.g. a forward-declared `struct`), there will
+ // not be a `CppType` that represents that type. In that case, fall back to `UnknownCppType`.
+ result = getTypeForPRValueOrUnknown(operandType)
+ )
}
predicate hasSpecificWriteSideEffect(Opcode op) {
@@ -510,7 +554,7 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
)
or
not call.getTarget() instanceof SideEffectFunction and
- op instanceof Opcode::IndirectReadSideEffect
+ op instanceof Opcode::BufferReadSideEffect
}
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll
index 294a539ec31..87fd781fd95 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll
@@ -120,7 +120,9 @@ abstract class TranslatedVariableDeclaration extends TranslatedElement, Initiali
private predicate hasUninitializedInstruction() {
not exists(getInitialization()) or
- getInitialization() instanceof TranslatedListInitialization
+ getInitialization() instanceof TranslatedListInitialization or
+ getInitialization() instanceof TranslatedConstructorInitialization or
+ getInitialization().(TranslatedStringLiteralInitialization).zeroInitRange(_, _)
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
index 3e29b1bad07..edca6e21039 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
@@ -9,6 +9,7 @@ private import InstructionTag
private import TranslatedCondition
private import TranslatedFunction
private import TranslatedStmt
+private import TranslatedExpr
private import IRConstruction
private import semmle.code.cpp.models.interfaces.SideEffect
@@ -235,6 +236,15 @@ newtype TTranslatedElement =
expr.hasLValueToRValueConversion() and
not ignoreLoad(expr)
} or
+ TTranslatedResultCopy(Expr expr) {
+ not ignoreExpr(expr) and
+ exprNeedsCopyIfNotLoaded(expr) and
+ // Doesn't have a TTranslatedLoad
+ not (
+ expr.hasLValueToRValueConversion() and
+ not ignoreLoad(expr)
+ )
+ } or
// An expression most naturally translated as control flow.
TTranslatedNativeCondition(Expr expr) {
not ignoreExpr(expr) and
@@ -380,8 +390,10 @@ newtype TTranslatedElement =
TTranslatedAllocationSize(NewOrNewArrayExpr newExpr) { not ignoreExpr(newExpr) } or
// The declaration/initialization part of a `ConditionDeclExpr`
TTranslatedConditionDecl(ConditionDeclExpr expr) { not ignoreExpr(expr) } or
- // The side effects of a `Call` {
- TTranslatedSideEffects(Call expr) { exists(TTranslatedArgumentSideEffect(expr, _, _, _)) } or // A precise side effect of an argument to a `Call` {
+ // The side effects of a `Call`
+ TTranslatedSideEffects(Call expr) {
+ exists(TTranslatedArgumentSideEffect(expr, _, _, _)) or expr instanceof ConstructorCall
+ } or // A precise side effect of an argument to a `Call`
TTranslatedArgumentSideEffect(Call call, Expr expr, int n, boolean isWrite) {
(
expr = call.getArgument(n).getFullyConverted()
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
index 3fc73d66878..9db42c742ac 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
@@ -62,12 +62,11 @@ abstract class TranslatedExpr extends TranslatedElement {
/**
* Holds if the result of this `TranslatedExpr` is a glvalue.
*/
- private predicate isResultGLValue() {
+ predicate isResultGLValue() {
+ // This implementation is overridden in `TranslatedCoreExpr` to mark them
+ // as glvalues if they have loads on them. It's not overridden in
+ // `TranslatedResultCopy` since result copies never have loads.
expr.isGLValueCategory()
- or
- // If this TranslatedExpr doesn't produce the result, then it must represent
- // a glvalue that is then loaded by a TranslatedLoad.
- not producesExprResult()
}
final override Locatable getAST() { result = expr }
@@ -96,14 +95,28 @@ abstract class TranslatedExpr extends TranslatedElement {
abstract class TranslatedCoreExpr extends TranslatedExpr {
final override string toString() { result = expr.toString() }
+ /**
+ * Holds if the result of this `TranslatedExpr` is a glvalue.
+ */
+ override predicate isResultGLValue() {
+ super.isResultGLValue()
+ or
+ // If this TranslatedExpr doesn't produce the result, then it must represent
+ // a glvalue that is then loaded by a TranslatedLoad.
+ hasLoad()
+ }
+
+ final predicate hasLoad() {
+ expr.hasLValueToRValueConversion() and
+ not ignoreLoad(expr)
+ }
+
final override predicate producesExprResult() {
// If there's no load, then this is the only TranslatedExpr for this
// expression.
- not expr.hasLValueToRValueConversion()
- or
- // If we're supposed to ignore the load on this expression, then this
- // is the only TranslatedExpr.
- ignoreLoad(expr)
+ not hasLoad() and
+ // If there's a result copy, then this expression's result is the copy.
+ not exprNeedsCopyIfNotLoaded(expr)
}
}
@@ -288,6 +301,48 @@ class TranslatedLoad extends TranslatedExpr, TTranslatedLoad {
private TranslatedCoreExpr getOperand() { result.getExpr() = expr }
}
+/**
+ * IR translation of an implicit lvalue-to-rvalue conversion on the result of
+ * an expression.
+ */
+class TranslatedResultCopy extends TranslatedExpr, TTranslatedResultCopy {
+ TranslatedResultCopy() { this = TTranslatedResultCopy(expr) }
+
+ override string toString() { result = "Result of " + expr.toString() }
+
+ override Instruction getFirstInstruction() { result = getOperand().getFirstInstruction() }
+
+ override TranslatedElement getChild(int id) { id = 0 and result = getOperand() }
+
+ override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
+ tag = ResultCopyTag() and
+ opcode instanceof Opcode::CopyValue and
+ resultType = getOperand().getResultType()
+ }
+
+ override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
+ tag = ResultCopyTag() and
+ result = getParent().getChildSuccessor(this) and
+ kind instanceof GotoEdge
+ }
+
+ override Instruction getChildSuccessor(TranslatedElement child) {
+ child = getOperand() and result = getInstruction(ResultCopyTag())
+ }
+
+ override Instruction getResult() { result = getInstruction(ResultCopyTag()) }
+
+ override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
+ tag = ResultCopyTag() and
+ operandTag instanceof UnaryOperandTag and
+ result = getOperand().getResult()
+ }
+
+ final override predicate producesExprResult() { any() }
+
+ private TranslatedCoreExpr getOperand() { result.getExpr() = expr }
+}
+
class TranslatedCommaExpr extends TranslatedNonConstantExpr {
override CommaExpr expr;
@@ -983,7 +1038,7 @@ class TranslatedInheritanceConversion extends TranslatedSingleInstructionConvers
then
if expr.(BaseClassConversion).isVirtual()
then result instanceof Opcode::ConvertToVirtualBase
- else result instanceof Opcode::ConvertToBase
+ else result instanceof Opcode::ConvertToNonVirtualBase
else result instanceof Opcode::ConvertToDerived
}
}
@@ -2403,6 +2458,58 @@ class TranslatedErrorExpr extends TranslatedSingleInstructionExpr {
final override Opcode getOpcode() { result instanceof Opcode::Error }
}
+/**
+ * Holds if the translation of `expr` will not directly generate any
+ * `Instruction` for use as result. For such instructions we can synthesize a
+ * `CopyValue` instruction to ensure that there is a 1-to-1 mapping between
+ * expressions and result-bearing instructions.
+ */
+// This should ideally be a dispatch predicate on TranslatedNonConstantExpr,
+// but it doesn't look monotonic to QL.
+predicate exprNeedsCopyIfNotLoaded(Expr expr) {
+ (
+ expr instanceof AssignExpr
+ or
+ expr instanceof AssignOperation and
+ not expr.isPRValueCategory() // is C++
+ or
+ expr instanceof PrefixCrementOperation and
+ not expr.isPRValueCategory() // is C++
+ or
+ expr instanceof PointerDereferenceExpr
+ or
+ expr instanceof AddressOfExpr
+ or
+ expr instanceof BuiltInOperationBuiltInAddressOf
+ or
+ // No case for ParenthesisExpr to avoid getting too many instructions
+ expr instanceof ReferenceDereferenceExpr
+ or
+ expr instanceof ReferenceToExpr
+ or
+ expr instanceof CommaExpr
+ or
+ expr instanceof ConditionDeclExpr
+ // TODO: simplify TranslatedStmtExpr too
+ ) and
+ not exprImmediatelyDiscarded(expr)
+}
+
+/**
+ * Holds if `expr` is immediately discarded. Such expressions do not need a
+ * `CopyValue` because it's unlikely that anyone is interested in their value.
+ */
+private predicate exprImmediatelyDiscarded(Expr expr) {
+ exists(ExprStmt s |
+ s = expr.getParent() and
+ not exists(StmtExpr se | s = se.getStmt().(Block).getLastStmt())
+ )
+ or
+ exists(CommaExpr c | c.getLeftOperand() = expr)
+ or
+ exists(ForStmt for | for.getUpdate() = expr)
+}
+
/**
* The IR translation of an `__assume` expression. We currently translate these as `NoOp`. In the
* future, we will probably want to do something better. At a minimum, we can model `__assume(0)` as
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll
index fd8f4579e32..b0a3c153085 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll
@@ -100,6 +100,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
result = getInstruction(UnmodeledUseTag())
or
tag = UnmodeledUseTag() and
+ result = getInstruction(AliasedUseTag())
+ or
+ tag = AliasedUseTag() and
result = getInstruction(ExitFunctionTag())
)
}
@@ -172,6 +175,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
opcode instanceof Opcode::UnmodeledUse and
resultType = getVoidType()
or
+ tag = AliasedUseTag() and
+ opcode instanceof Opcode::AliasedUse and
+ resultType = getVoidType()
+ or
tag = ExitFunctionTag() and
opcode instanceof Opcode::ExitFunction and
resultType = getVoidType()
@@ -192,6 +199,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
operandTag instanceof UnmodeledUseOperandTag and
result = getUnmodeledDefinitionInstruction()
or
+ tag = AliasedUseTag() and
+ operandTag instanceof SideEffectOperandTag and
+ result = getUnmodeledDefinitionInstruction()
+ or
tag = ReturnTag() and
hasReturnValue() and
(
@@ -208,6 +219,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
hasReturnValue() and
operandTag instanceof LoadOperandTag and
result = getTypeForPRValue(getReturnType())
+ or
+ tag = AliasedUseTag() and
+ operandTag instanceof SideEffectOperandTag and
+ result = getUnknownType()
}
final override IRVariable getInstructionVariable(InstructionTag tag) {
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll
index 21ad11513bd..609f8276640 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll
@@ -340,7 +340,7 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
* Holds if the `elementCount` array elements starting at `startIndex` must be
* zero initialized.
*/
- private predicate zeroInitRange(int startIndex, int elementCount) {
+ predicate zeroInitRange(int startIndex, int elementCount) {
exists(int targetCount |
startIndex = expr.getUnspecifiedType().(ArrayType).getArraySize() and
targetCount = getContext().getTargetType().getUnspecifiedType().(ArrayType).getArraySize() and
@@ -752,7 +752,7 @@ abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStru
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
- opcode instanceof Opcode::ConvertToBase and
+ opcode instanceof Opcode::ConvertToNonVirtualBase and
resultType = getTypeForGLValue(call.getTarget().getDeclaringType())
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll
index 1a607f82c29..e10e266b2ab 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll
@@ -22,6 +22,12 @@ abstract class IRVariable extends TIRVariable {
abstract string toString();
+ /**
+ * Holds if this variable's value cannot be changed within a function. Currently used for string
+ * literals, but could also apply to `const` global and static variables.
+ */
+ predicate isReadOnly() { none() }
+
/**
* Gets the type of the variable.
*/
@@ -113,34 +119,43 @@ class IRStaticUserVariable extends IRUserVariable {
final override Language::StaticVariable getVariable() { result = var }
}
+abstract class IRGeneratedVariable extends IRVariable {
+ Language::AST ast;
+ Language::LanguageType type;
+
+ final override Language::LanguageType getLanguageType() { result = type }
+
+ final override Language::AST getAST() { result = ast }
+
+ override string toString() { result = getBaseString() + getLocationString() }
+
+ override string getUniqueId() { none() }
+
+ final string getLocationString() {
+ result = ast.getLocation().getStartLine().toString() + ":" +
+ ast.getLocation().getStartColumn().toString()
+ }
+
+ string getBaseString() { none() }
+}
+
IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
result.getAST() = ast and
result.getTag() = tag
}
-class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable {
- Language::AST ast;
+class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable {
TempVariableTag tag;
- Language::LanguageType type;
IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) }
- final override Language::LanguageType getLanguageType() { result = type }
-
- final override Language::AST getAST() { result = ast }
-
final override string getUniqueId() {
result = "Temp: " + Construction::getTempVariableUniqueId(this)
}
final TempVariableTag getTag() { result = tag }
- override string toString() {
- result = getBaseString() + ast.getLocation().getStartLine().toString() + ":" +
- ast.getLocation().getStartColumn().toString()
- }
-
- string getBaseString() { result = "#temp" }
+ override string getBaseString() { result = "#temp" }
}
class IRReturnVariable extends IRTempVariable {
@@ -154,3 +169,19 @@ class IRThrowVariable extends IRTempVariable {
override string getBaseString() { result = "#throw" }
}
+
+class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
+ Language::StringLiteral literal;
+
+ IRStringLiteral() { this = TIRStringLiteral(func, ast, type, literal) }
+
+ final override predicate isReadOnly() { any() }
+
+ final override string getUniqueId() {
+ result = "String: " + getLocationString() + "=" + Language::getStringLiteralText(literal)
+ }
+
+ override string getBaseString() { result = "#string" }
+
+ final Language::StringLiteral getLiteral() { result = literal }
+}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
index a2a39e4d42e..8e785015828 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
@@ -51,7 +51,8 @@ module InstructionSanity {
opcode instanceof ReadSideEffectOpcode or
opcode instanceof Opcode::InlineAsm or
opcode instanceof Opcode::CallSideEffect or
- opcode instanceof Opcode::ReturnIndirection
+ opcode instanceof Opcode::ReturnIndirection or
+ opcode instanceof Opcode::AliasedUse
) and
tag instanceof SideEffectOperandTag
)
@@ -124,6 +125,16 @@ module InstructionSanity {
)
}
+ query predicate duplicateChiOperand(
+ ChiInstruction chi, string message, IRFunction func, string funcText
+ ) {
+ chi.getTotal() = chi.getPartial() and
+ message = "Chi instruction for " + chi.getPartial().toString() +
+ " has duplicate operands in function $@" and
+ func = chi.getEnclosingIRFunction() and
+ funcText = Language::getIdentityString(func.getFunction())
+ }
+
query predicate sideEffectWithoutPrimary(
SideEffectInstruction instr, string message, IRFunction func, string funcText
) {
@@ -264,6 +275,7 @@ module InstructionSanity {
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
+ not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
@@ -827,14 +839,12 @@ class FloatConstantInstruction extends ConstantInstruction {
FloatConstantInstruction() { getResultType() instanceof Language::FloatingPointType }
}
-class StringConstantInstruction extends Instruction {
- Language::StringLiteral value;
+class StringConstantInstruction extends VariableInstruction {
+ override IRStringLiteral var;
- StringConstantInstruction() { value = Construction::getInstructionStringLiteral(this) }
+ final override string getImmediateString() { result = Language::getStringLiteralText(getValue()) }
- final override string getImmediateString() { result = Language::getStringLiteralText(value) }
-
- final Language::StringLiteral getValue() { result = value }
+ final Language::StringLiteral getValue() { result = var.getLiteral() }
}
class BinaryInstruction extends Instruction {
@@ -1002,14 +1012,22 @@ class InheritanceConversionInstruction extends UnaryInstruction {
* to the address of a direct non-virtual base class.
*/
class ConvertToBaseInstruction extends InheritanceConversionInstruction {
- ConvertToBaseInstruction() { getOpcode() instanceof Opcode::ConvertToBase }
+ ConvertToBaseInstruction() { getOpcode() instanceof ConvertToBaseOpcode }
+}
+
+/**
+ * Represents an instruction that converts from the address of a derived class
+ * to the address of a direct non-virtual base class.
+ */
+class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction {
+ ConvertToNonVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToNonVirtualBase }
}
/**
* Represents an instruction that converts from the address of a derived class
* to the address of a virtual base class.
*/
-class ConvertToVirtualBaseInstruction extends InheritanceConversionInstruction {
+class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction {
ConvertToVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToVirtualBase }
}
@@ -1442,6 +1460,13 @@ class AliasedDefinitionInstruction extends Instruction {
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
}
+/**
+ * An instruction that consumes all escaped memory on exit from the function.
+ */
+class AliasedUseInstruction extends Instruction {
+ AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
+}
+
class UnmodeledUseInstruction extends Instruction {
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll
index c85d609d200..8042dfa6a69 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll
@@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override MemoryAccessKind getMemoryAccess() {
+ useInstr instanceof AliasedUseInstruction and
+ result instanceof NonLocalMayMemoryAccess
+ or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess
or
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll
index 74c288d3468..2768f910120 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll
@@ -110,7 +110,7 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset) {
instr = operand.getUse() and
(
// Converting to a non-virtual base class adds the offset of the base class.
- exists(ConvertToBaseInstruction convert |
+ exists(ConvertToNonVirtualBaseInstruction convert |
convert = instr and
bitOffset = Ints::mul(convert.getDerivation().getByteOffset(), 8)
)
@@ -309,6 +309,10 @@ predicate resultPointsTo(Instruction instr, IRVariable var, IntValue bitOffset)
instr.(VariableAddressInstruction).getIRVariable() = var and
bitOffset = 0
or
+ // A string literal is just a special read-only global variable.
+ instr.(StringConstantInstruction).getIRVariable() = var and
+ bitOffset = 0
+ or
exists(Operand operand, IntValue originalBitOffset, IntValue propagatedBitOffset |
operand = instr.getAnOperand() and
// If an operand is propagated, then the result points to the same variable,
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
index 7152dec5c4a..a789edc7590 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
@@ -341,11 +341,6 @@ private module Cached {
result = getOldInstruction(instruction).(OldIR::ConstantValueInstruction).getValue()
}
- cached
- Language::StringLiteral getInstructionStringLiteral(Instruction instruction) {
- result = getOldInstruction(instruction).(OldIR::StringConstantInstruction).getValue()
- }
-
cached
Language::BuiltInOperation getInstructionBuiltInOperation(Instruction instruction) {
result = getOldInstruction(instruction)
@@ -401,7 +396,11 @@ private predicate hasChiNode(Alias::VirtualVariable vvar, OldInstruction def) {
defLocation.getVirtualVariable() = vvar and
// If the definition totally (or exactly) overlaps the virtual variable, then there's no need for a `Chi`
// instruction.
- Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap
+ (
+ Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap or
+ def.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or
+ def.getResultMemoryAccess() instanceof BufferMayMemoryAccess
+ )
)
}
@@ -714,7 +713,10 @@ module DefUse {
defLocation = Alias::getResultMemoryLocation(def) and
block.getInstruction(index) = def and
overlap = Alias::getOverlap(defLocation, useLocation) and
- if overlap instanceof MayPartiallyOverlap
+ if
+ overlap instanceof MayPartiallyOverlap or
+ def.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or
+ def.getResultMemoryAccess() instanceof BufferMayMemoryAccess
then offset = (index * 2) + 1 // The use will be connected to the definition on the `Chi` instruction.
else offset = index * 2 // The use will be connected to the definition on the original instruction.
)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll
index 5925631b67c..49bb908265c 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll
@@ -30,7 +30,11 @@ private predicate isVariableModeled(IRVariable var) {
hasResultMemoryAccess(instr, var, type, bitOffset)
|
bitOffset = 0 and
- type.getIRType() = var.getIRType()
+ type.getIRType() = var.getIRType() and
+ not (
+ instr.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or
+ instr.getResultMemoryAccess() instanceof BufferMayMemoryAccess
+ )
) and
forall(MemoryOperand operand, Language::LanguageType type, IntValue bitOffset |
hasOperandMemoryAccess(operand, var, type, bitOffset)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/internal/CppType.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/CppType.qll
index 88184d90345..e967dc9920c 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/internal/CppType.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/internal/CppType.qll
@@ -175,6 +175,7 @@ private IRType getIRTypeForPRValue(Type type) {
)
}
+cached
private newtype TCppType =
TPRValueType(Type type) { exists(getIRTypeForPRValue(type)) } or
TFunctionGLValueType() or
@@ -203,6 +204,7 @@ class CppType extends TCppType {
* Gets the `IRType` that represents this `CppType`. Many different `CppType`s can map to a single
* `IRType`.
*/
+ cached
IRType getIRType() { none() }
/**
diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Printf.qll
index 5654c1a9c99..58721897802 100644
--- a/cpp/ql/src/semmle/code/cpp/models/implementations/Printf.qll
+++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Printf.qll
@@ -7,9 +7,9 @@ class Printf extends FormattingFunction {
Printf() {
this instanceof TopLevelFunction and
(
- hasGlobalName("printf") or
+ hasGlobalOrStdName("printf") or
hasGlobalName("printf_s") or
- hasGlobalName("wprintf") or
+ hasGlobalOrStdName("wprintf") or
hasGlobalName("wprintf_s") or
hasGlobalName("g_printf")
) and
@@ -19,7 +19,7 @@ class Printf extends FormattingFunction {
override int getFormatParameterIndex() { result = 0 }
override predicate isWideCharDefault() {
- hasGlobalName("wprintf") or
+ hasGlobalOrStdName("wprintf") or
hasGlobalName("wprintf_s")
}
}
@@ -31,8 +31,8 @@ class Fprintf extends FormattingFunction {
Fprintf() {
this instanceof TopLevelFunction and
(
- hasGlobalName("fprintf") or
- hasGlobalName("fwprintf") or
+ hasGlobalOrStdName("fprintf") or
+ hasGlobalOrStdName("fwprintf") or
hasGlobalName("g_fprintf")
) and
not exists(getDefinition().getFile().getRelativePath())
@@ -40,7 +40,7 @@ class Fprintf extends FormattingFunction {
override int getFormatParameterIndex() { result = 1 }
- override predicate isWideCharDefault() { hasGlobalName("fwprintf") }
+ override predicate isWideCharDefault() { hasGlobalOrStdName("fwprintf") }
override int getOutputParameterIndex() { result = 0 }
}
@@ -52,10 +52,10 @@ class Sprintf extends FormattingFunction {
Sprintf() {
this instanceof TopLevelFunction and
(
- hasGlobalName("sprintf") or
+ hasGlobalOrStdName("sprintf") or
hasGlobalName("_sprintf_l") or
hasGlobalName("__swprintf_l") or
- hasGlobalName("wsprintf") or
+ hasGlobalOrStdName("wsprintf") or
hasGlobalName("g_strdup_printf") or
hasGlobalName("g_sprintf") or
hasGlobalName("__builtin___sprintf_chk")
@@ -99,8 +99,8 @@ class Snprintf extends FormattingFunction {
Snprintf() {
this instanceof TopLevelFunction and
(
- hasGlobalName("snprintf") or // C99 defines snprintf
- hasGlobalName("swprintf") or // The s version of wide-char printf is also always the n version
+ hasGlobalOrStdName("snprintf") or // C99 defines snprintf
+ hasGlobalOrStdName("swprintf") or // The s version of wide-char printf is also always the n version
// Microsoft has _snprintf as well as several other variations
hasGlobalName("sprintf_s") or
hasGlobalName("snprintf_s") or
@@ -160,7 +160,7 @@ class Snprintf extends FormattingFunction {
*/
predicate returnsFullFormatLength() {
(
- hasGlobalName("snprintf") or
+ hasGlobalOrStdName("snprintf") or
hasGlobalName("g_snprintf") or
hasGlobalName("__builtin___snprintf_chk") or
hasGlobalName("snprintf_s")
diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Pure.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Pure.qll
index c5729c5d0f6..59b8c25700f 100644
--- a/cpp/ql/src/semmle/code/cpp/models/implementations/Pure.qll
+++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Pure.qll
@@ -6,7 +6,7 @@ import semmle.code.cpp.models.interfaces.SideEffect
class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction, SideEffectFunction {
PureStrFunction() {
exists(string name |
- hasGlobalName(name) and
+ hasGlobalOrStdName(name) and
(
name = "atof" or
name = "atoi" or
@@ -75,7 +75,7 @@ class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction, SideE
class PureFunction extends TaintFunction, SideEffectFunction {
PureFunction() {
exists(string name |
- hasGlobalName(name) and
+ hasGlobalOrStdName(name) and
(
name = "abs" or
name = "labs"
diff --git a/cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll b/cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll
index 50fe6ab9a55..b663f336d0a 100644
--- a/cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll
+++ b/cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll
@@ -80,7 +80,7 @@ private module RangeAnalysisCache {
cached
module RangeAnalysisPublic {
/**
- * Holds if `b + delta` is a valid bound for `i`.
+ * Holds if `b + delta` is a valid bound for `i` and this is the best such delta.
* - `upper = true` : `i <= b + delta`
* - `upper = false` : `i >= b + delta`
*
@@ -90,11 +90,12 @@ private module RangeAnalysisCache {
*/
cached
predicate boundedInstruction(Instruction i, Bound b, int delta, boolean upper, Reason reason) {
- boundedInstruction(i, b, delta, upper, _, _, reason)
+ boundedInstruction(i, b, delta, upper, _, _, reason) and
+ bestInstructionBound(i, b, delta, upper)
}
/**
- * Holds if `b + delta` is a valid bound for `op`.
+ * Holds if `b + delta` is a valid bound for `op` and this is the best such delta.
* - `upper = true` : `op <= b + delta`
* - `upper = false` : `op >= b + delta`
*
@@ -104,9 +105,8 @@ private module RangeAnalysisCache {
*/
cached
predicate boundedOperand(Operand op, Bound b, int delta, boolean upper, Reason reason) {
- boundedNonPhiOperand(op, b, delta, upper, _, _, reason)
- or
- boundedPhiOperand(op, b, delta, upper, _, _, reason)
+ boundedOperandCand(op, b, delta, upper, reason) and
+ bestOperandBound(op, b, delta, upper)
}
}
@@ -124,6 +124,43 @@ private module RangeAnalysisCache {
private import RangeAnalysisCache
import RangeAnalysisPublic
+/**
+ * Holds if `b + delta` is a valid bound for `e` and this is the best such delta.
+ * - `upper = true` : `e <= b + delta`
+ * - `upper = false` : `e >= b + delta`
+ */
+private predicate bestInstructionBound(Instruction i, Bound b, int delta, boolean upper) {
+ delta = min(int d | boundedInstruction(i, b, d, upper, _, _, _)) and upper = true
+ or
+ delta = max(int d | boundedInstruction(i, b, d, upper, _, _, _)) and upper = false
+}
+
+/**
+ * Holds if `b + delta` is a valid bound for `op`.
+ * - `upper = true` : `op <= b + delta`
+ * - `upper = false` : `op >= b + delta`
+ *
+ * The reason for the bound is given by `reason` and may be either a condition
+ * or `NoReason` if the bound was proven directly without the use of a bounding
+ * condition.
+ */
+private predicate boundedOperandCand(Operand op, Bound b, int delta, boolean upper, Reason reason) {
+ boundedNonPhiOperand(op, b, delta, upper, _, _, reason)
+ or
+ boundedPhiOperand(op, b, delta, upper, _, _, reason)
+}
+
+/**
+ * Holds if `b + delta` is a valid bound for `op` and this is the best such delta.
+ * - `upper = true` : `op <= b + delta`
+ * - `upper = false` : `op >= b + delta`
+ */
+private predicate bestOperandBound(Operand op, Bound b, int delta, boolean upper) {
+ delta = min(int d | boundedOperandCand(op, b, d, upper, _)) and upper = true
+ or
+ delta = max(int d | boundedOperandCand(op, b, d, upper, _)) and upper = false
+}
+
/**
* Gets a condition that tests whether `vn` equals `bound + delta`.
*
diff --git a/cpp/ql/src/semmle/code/cpp/security/CommandExecution.qll b/cpp/ql/src/semmle/code/cpp/security/CommandExecution.qll
index 9988e20290c..c7bea7eede7 100644
--- a/cpp/ql/src/semmle/code/cpp/security/CommandExecution.qll
+++ b/cpp/ql/src/semmle/code/cpp/security/CommandExecution.qll
@@ -8,7 +8,7 @@ import semmle.code.cpp.security.FunctionWithWrappers
*/
class SystemFunction extends FunctionWithWrappers {
SystemFunction() {
- hasGlobalName("system") or
+ hasGlobalOrStdName("system") or
hasGlobalName("popen") or
// Windows variants
hasGlobalName("_popen") or
diff --git a/cpp/ql/src/semmle/code/cpp/security/FileWrite.qll b/cpp/ql/src/semmle/code/cpp/security/FileWrite.qll
index 6363e3a5d14..219f3d0a75b 100644
--- a/cpp/ql/src/semmle/code/cpp/security/FileWrite.qll
+++ b/cpp/ql/src/semmle/code/cpp/security/FileWrite.qll
@@ -125,7 +125,7 @@ private predicate fileWrite(Call write, Expr source, Expr dest) {
exists(Function f, int s, int d |
f = write.getTarget() and source = write.getArgument(s) and dest = write.getArgument(d)
|
- exists(string name | f.hasGlobalName(name) |
+ exists(string name | f.hasGlobalOrStdName(name) |
// named functions
name = "fwrite" and s = 0 and d = 3
or
diff --git a/cpp/ql/src/semmle/code/cpp/security/OutputWrite.qll b/cpp/ql/src/semmle/code/cpp/security/OutputWrite.qll
index 751a7a71ec7..06abfdb454d 100644
--- a/cpp/ql/src/semmle/code/cpp/security/OutputWrite.qll
+++ b/cpp/ql/src/semmle/code/cpp/security/OutputWrite.qll
@@ -63,8 +63,8 @@ private predicate outputWrite(Expr write, Expr source) {
or
// puts, putchar
(
- f.hasGlobalName("puts") or
- f.hasGlobalName("putchar")
+ f.hasGlobalOrStdName("puts") or
+ f.hasGlobalOrStdName("putchar")
) and
arg = 0
or
diff --git a/cpp/ql/src/semmle/code/cpp/security/Security.qll b/cpp/ql/src/semmle/code/cpp/security/Security.qll
index 1a1c1d61ce8..c12a70b52c6 100644
--- a/cpp/ql/src/semmle/code/cpp/security/Security.qll
+++ b/cpp/ql/src/semmle/code/cpp/security/Security.qll
@@ -70,11 +70,9 @@ class SecurityOptions extends string {
*/
predicate userInputArgument(FunctionCall functionCall, int arg) {
exists(string fname |
- functionCall.getTarget().hasGlobalName(fname) and
+ functionCall.getTarget().hasGlobalOrStdName(fname) and
exists(functionCall.getArgument(arg)) and
(
- fname = "read" and arg = 1
- or
fname = "fread" and arg = 0
or
fname = "fgets" and arg = 0
@@ -83,6 +81,16 @@ class SecurityOptions extends string {
or
fname = "gets" and arg = 0
or
+ fname = "scanf" and arg >= 1
+ or
+ fname = "fscanf" and arg >= 2
+ )
+ or
+ functionCall.getTarget().hasGlobalName(fname) and
+ exists(functionCall.getArgument(arg)) and
+ (
+ fname = "read" and arg = 1
+ or
fname = "getaddrinfo" and arg = 3
or
fname = "recv" and arg = 1
@@ -91,10 +99,6 @@ class SecurityOptions extends string {
(arg = 1 or arg = 4 or arg = 5)
or
fname = "recvmsg" and arg = 1
- or
- fname = "scanf" and arg >= 1
- or
- fname = "fscanf" and arg >= 2
)
)
}
diff --git a/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll b/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll
index 1ef0a6f7092..31d8ad00f9c 100644
--- a/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll
+++ b/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll
@@ -425,41 +425,41 @@ private int maxArgIndex(Function f) {
/** Functions that copy the value of one argument to another */
private predicate copyValueBetweenArguments(Function f, int sourceArg, int destArg) {
- f.hasGlobalName("memcpy") and sourceArg = 1 and destArg = 0
+ f.hasGlobalOrStdName("memcpy") and sourceArg = 1 and destArg = 0
or
f.hasGlobalName("__builtin___memcpy_chk") and sourceArg = 1 and destArg = 0
or
- f.hasGlobalName("memmove") and sourceArg = 1 and destArg = 0
+ f.hasGlobalOrStdName("memmove") and sourceArg = 1 and destArg = 0
or
- f.hasGlobalName("strcat") and sourceArg = 1 and destArg = 0
+ f.hasGlobalOrStdName("strcat") and sourceArg = 1 and destArg = 0
or
f.hasGlobalName("_mbscat") and sourceArg = 1 and destArg = 0
or
- f.hasGlobalName("wcsncat") and sourceArg = 1 and destArg = 0
+ f.hasGlobalOrStdName("wcscat") and sourceArg = 1 and destArg = 0
or
- f.hasGlobalName("strncat") and sourceArg = 1 and destArg = 0
+ f.hasGlobalOrStdName("strncat") and sourceArg = 1 and destArg = 0
or
f.hasGlobalName("_mbsncat") and sourceArg = 1 and destArg = 0
or
f.hasGlobalName("wcsncat") and sourceArg = 1 and destArg = 0
or
- f.hasGlobalName("strcpy") and sourceArg = 1 and destArg = 0
+ f.hasGlobalOrStdName("strcpy") and sourceArg = 1 and destArg = 0
or
f.hasGlobalName("_mbscpy") and sourceArg = 1 and destArg = 0
or
- f.hasGlobalName("wcscpy") and sourceArg = 1 and destArg = 0
+ f.hasGlobalOrStdName("wcscpy") and sourceArg = 1 and destArg = 0
or
- f.hasGlobalName("strncpy") and sourceArg = 1 and destArg = 0
+ f.hasGlobalOrStdName("strncpy") and sourceArg = 1 and destArg = 0
or
f.hasGlobalName("_mbsncpy") and sourceArg = 1 and destArg = 0
or
- f.hasGlobalName("wcsncpy") and sourceArg = 1 and destArg = 0
+ f.hasGlobalOrStdName("wcsncpy") and sourceArg = 1 and destArg = 0
or
f.hasGlobalName("inet_aton") and sourceArg = 0 and destArg = 1
or
f.hasGlobalName("inet_pton") and sourceArg = 1 and destArg = 2
or
- f.hasGlobalName("strftime") and sourceArg in [2 .. maxArgIndex(f)] and destArg = 0
+ f.hasGlobalOrStdName("strftime") and sourceArg in [2 .. maxArgIndex(f)] and destArg = 0
or
exists(FormattingFunction ff | ff = f |
sourceArg in [ff.getFormatParameterIndex() .. maxArgIndex(f)] and
@@ -473,31 +473,31 @@ private predicate returnArgument(Function f, int sourceArg) {
or
f.hasGlobalName("__builtin___memcpy_chk") and sourceArg = 0
or
- f.hasGlobalName("memmove") and sourceArg = 0
+ f.hasGlobalOrStdName("memmove") and sourceArg = 0
or
- f.hasGlobalName("strcat") and sourceArg = 0
+ f.hasGlobalOrStdName("strcat") and sourceArg = 0
or
f.hasGlobalName("_mbscat") and sourceArg = 0
or
- f.hasGlobalName("wcsncat") and sourceArg = 0
+ f.hasGlobalOrStdName("wcsncat") and sourceArg = 0
or
- f.hasGlobalName("strncat") and sourceArg = 0
+ f.hasGlobalOrStdName("strncat") and sourceArg = 0
or
f.hasGlobalName("_mbsncat") and sourceArg = 0
or
- f.hasGlobalName("wcsncat") and sourceArg = 0
+ f.hasGlobalOrStdName("wcsncat") and sourceArg = 0
or
- f.hasGlobalName("strcpy") and sourceArg = 0
+ f.hasGlobalOrStdName("strcpy") and sourceArg = 0
or
f.hasGlobalName("_mbscpy") and sourceArg = 0
or
- f.hasGlobalName("wcscpy") and sourceArg = 0
+ f.hasGlobalOrStdName("wcscpy") and sourceArg = 0
or
- f.hasGlobalName("strncpy") and sourceArg = 0
+ f.hasGlobalOrStdName("strncpy") and sourceArg = 0
or
f.hasGlobalName("_mbsncpy") and sourceArg = 0
or
- f.hasGlobalName("wcsncpy") and sourceArg = 0
+ f.hasGlobalOrStdName("wcsncpy") and sourceArg = 0
or
f.hasGlobalName("inet_ntoa") and sourceArg = 0
or
diff --git a/cpp/ql/src/semmle/code/cpp/security/boostorg/asio/protocols.qll b/cpp/ql/src/semmle/code/cpp/security/boostorg/asio/protocols.qll
index ae3733473ad..e113d5e5745 100644
--- a/cpp/ql/src/semmle/code/cpp/security/boostorg/asio/protocols.qll
+++ b/cpp/ql/src/semmle/code/cpp/security/boostorg/asio/protocols.qll
@@ -3,7 +3,7 @@ import semmle.code.cpp.dataflow.DataFlow
module BoostorgAsio {
/**
- * Represents boost::asio::ssl::context enum
+ * Represents the `boost::asio::ssl::context` enum.
*/
class SslContextMethod extends Enum {
SslContextMethod() {
@@ -12,7 +12,7 @@ module BoostorgAsio {
}
/**
- * returns the value for a banned protocol
+ * Gets an enumeration constant for a banned protocol.
*/
EnumConstant getABannedProtocolConstant() {
result = this.getAnEnumConstant() and
@@ -56,14 +56,15 @@ module BoostorgAsio {
}
/**
- * returns the value for a approved protocols, but that are hard-coded (i.e. no protocol negotiation)
+ * Gets an enumeration constant for an approved protocol, that is hard-coded
+ * (no protocol negotiation).
*/
EnumConstant getAnApprovedButHardcodedProtocolConstant() {
result = this.getATls12ProtocolConstant()
}
/**
- * returns the value for a TLS v1.2 protocol
+ * Gets an enumeration constant for a TLS v1.2 protocol.
*/
EnumConstant getATls12ProtocolConstant() {
result = this.getAnEnumConstant() and
@@ -80,7 +81,7 @@ module BoostorgAsio {
}
/**
- * returns the value for a TLS v1.3 protocol
+ * Gets an enumeration constant for a TLS v1.3 protocol.
*/
EnumConstant getATls13ProtocolConstant() {
result = this.getAnEnumConstant() and
@@ -97,7 +98,7 @@ module BoostorgAsio {
}
/**
- * returns the value of a generic TLS or SSL/TLS protocol
+ * Gets an enumeration constant for a generic TLS or SSL/TLS protocol.
*/
EnumConstant getAGenericTlsProtocolConstant() {
result = this.getAnEnumConstant() and
@@ -116,7 +117,7 @@ module BoostorgAsio {
}
/**
- * returns the value of a generic SSL/TLS protocol
+ * Gets an enumeration constant for a generic SSL/TLS protocol.
*/
EnumConstant getASslv23ProtocolConstant() {
result = this.getAnEnumConstant() and
@@ -135,7 +136,9 @@ module BoostorgAsio {
}
/**
- * NOTE: ignore - Modern versions of OpenSSL do not support SSL v2 anymore, so this option is for backwards compatibility only
+ * Gets the value for the no_sslv2 constant, right shifted by 16 bits.
+ *
+ * Note that modern versions of OpelSSL do not support SSL v2, so this option is for backwards compatibility only.
*/
int getShiftedSslOptionsNoSsl2() {
// SSL_OP_NO_SSLv2 was removed from modern OpenSSL versions
@@ -143,7 +146,7 @@ module BoostorgAsio {
}
/**
- * RightShift(16) value for no_sslv3 constant
+ * Gets the value for the no_sslv3 constant, right shifted by 16 bits.
*/
int getShiftedSslOptionsNoSsl3() {
// SSL_OP_NO_SSLv3 == 0x02000000U
@@ -151,7 +154,7 @@ module BoostorgAsio {
}
/**
- * RightShift(16) value for no_tlsv1 constant
+ * Gets the value for the no_tlsv1 constant, right shifted by 16 bits.
*/
int getShiftedSslOptionsNoTls1() {
// SSL_OP_NO_TLSv1 == 0x04000000U
@@ -159,7 +162,7 @@ module BoostorgAsio {
}
/**
- * RightShift(16) value for no_tlsv1_1 constant
+ * Gets the value for the no_tlsv1_1 constant, right shifted by 16 bits.
*/
int getShiftedSslOptionsNoTls1_1() {
// SSL_OP_NO_TLSv1_1 == 0x10000000U
@@ -167,7 +170,7 @@ module BoostorgAsio {
}
/**
- * RightShift(16) value for no_tlsv1_2 constant
+ * Gets the value for the no_tlsv1_2 constant, right shifted by 16 bits.
*/
int getShiftedSslOptionsNoTls1_2() {
// SSL_OP_NO_TLSv1_2 == 0x08000000U
@@ -175,7 +178,7 @@ module BoostorgAsio {
}
/**
- * RightShift(16) value for no_tlsv1_3 constant
+ * Gets the value for the no_tlsv1_3 constant, right shifted by 16 bits.
*/
int getShiftedSslOptionsNoTls1_3() {
// SSL_OP_NO_TLSv1_2 == 0x20000000U
@@ -183,7 +186,7 @@ module BoostorgAsio {
}
/**
- * Represents boost::asio::ssl::context class
+ * Represents the `boost::asio::ssl::context` class.
*/
class SslContextClass extends Class {
SslContextClass() { this.getQualifiedName() = "boost::asio::ssl::context" }
@@ -196,7 +199,7 @@ module BoostorgAsio {
}
/**
- * Represents boost::asio::ssl::context::set_options member function
+ * Represents `boost::asio::ssl::context::set_options` member function.
*/
class SslSetOptionsFunction extends Function {
SslSetOptionsFunction() {
@@ -205,7 +208,7 @@ module BoostorgAsio {
}
/**
- * holds if the expression represents a banned protocol
+ * Holds if the expression represents a banned protocol.
*/
predicate isExprBannedBoostProtocol(Expr e) {
exists(Literal va | va = e |
@@ -244,7 +247,7 @@ module BoostorgAsio {
}
/**
- * holds if the expression represents a TLS v1.2 protocol
+ * Holds if the expression represents a TLS v1.2 protocol.
*/
predicate isExprTls12BoostProtocol(Expr e) {
exists(Literal va | va = e |
@@ -269,7 +272,7 @@ module BoostorgAsio {
}
/**
- * holds if the expression represents a protocol that requires Crypto Board approval
+ * Holds if the expression represents a protocol that requires Crypto Board approval.
*/
predicate isExprTls13BoostProtocol(Expr e) {
exists(Literal va | va = e |
@@ -294,7 +297,7 @@ module BoostorgAsio {
}
/**
- * holds if the expression represents a generic TLS or SSL/TLS protocol
+ * Holds if the expression represents a generic TLS or SSL/TLS protocol.
*/
predicate isExprTlsBoostProtocol(Expr e) {
exists(Literal va | va = e |
@@ -325,7 +328,7 @@ module BoostorgAsio {
}
/**
- * holds if the expression represents a generic SSl/TLS protocol
+ * Holds if the expression represents a generic SSl/TLS protocol.
*/
predicate isExprSslV23BoostProtocol(Expr e) {
exists(Literal va | va = e |
@@ -351,7 +354,8 @@ module BoostorgAsio {
//////////////////////// Dataflow /////////////////////
/**
- * Abstract - Protocol value Flows to the first argument of the context constructor
+ * Abstract class for flows of protocol values to the first argument of a context
+ * constructor.
*/
abstract class SslContextCallAbstractConfig extends DataFlow::Configuration {
bindingset[this]
@@ -366,7 +370,7 @@ module BoostorgAsio {
}
/**
- * any Protocol value Flows to the first argument of the context constructor
+ * Any protocol value that flows to the first argument of a context constructor.
*/
class SslContextCallConfig extends SslContextCallAbstractConfig {
SslContextCallConfig() { this = "SslContextCallConfig" }
@@ -380,7 +384,7 @@ module BoostorgAsio {
}
/**
- * a banned protocol value Flows to the first argument of the context constructor
+ * A banned protocol value that flows to the first argument of a context constructor.
*/
class SslContextCallBannedProtocolConfig extends SslContextCallAbstractConfig {
SslContextCallBannedProtocolConfig() { this = "SslContextCallBannedProtocolConfig" }
@@ -395,7 +399,7 @@ module BoostorgAsio {
}
/**
- * a TLS 1.2 protocol value Flows to the first argument of the context constructor
+ * A TLS 1.2 protocol value that flows to the first argument of a context constructor.
*/
class SslContextCallTls12ProtocolConfig extends SslContextCallAbstractConfig {
SslContextCallTls12ProtocolConfig() { this = "SslContextCallTls12ProtocolConfig" }
@@ -410,7 +414,7 @@ module BoostorgAsio {
}
/**
- * a TLS 1.3 protocol value Flows to the first argument of the context constructor
+ * A TLS 1.3 protocol value that flows to the first argument of a context constructor.
*/
class SslContextCallTls13ProtocolConfig extends SslContextCallAbstractConfig {
SslContextCallTls13ProtocolConfig() { this = "SslContextCallTls12ProtocolConfig" }
@@ -425,7 +429,7 @@ module BoostorgAsio {
}
/**
- * a generic TLS protocol value Flows to the first argument of the context constructor
+ * A generic TLS protocol value that flows to the first argument of a context constructor.
*/
class SslContextCallTlsProtocolConfig extends SslContextCallAbstractConfig {
SslContextCallTlsProtocolConfig() { this = "SslContextCallTlsProtocolConfig" }
@@ -440,7 +444,7 @@ module BoostorgAsio {
}
/**
- * a context constructor call flows to a call calling SetOptions()
+ * A context constructor call that flows to a call to `SetOptions()`.
*/
class SslContextFlowsToSetOptionConfig extends DataFlow::Configuration {
SslContextFlowsToSetOptionConfig() { this = "SslContextFlowsToSetOptionConfig" }
@@ -464,7 +468,7 @@ module BoostorgAsio {
}
/**
- * an option value flows to the 1st parameter of SetOptions()
+ * An option value that flows to the first parameter of a call to `SetOptions()`.
*/
class SslOptionConfig extends DataFlow::Configuration {
SslOptionConfig() { this = "SslOptionConfig" }
diff --git a/cpp/ql/src/semmlecode.cpp.dbscheme b/cpp/ql/src/semmlecode.cpp.dbscheme
index 98a075d5495..bd182f697bf 100644
--- a/cpp/ql/src/semmlecode.cpp.dbscheme
+++ b/cpp/ql/src/semmlecode.cpp.dbscheme
@@ -731,6 +731,11 @@ class_template_argument(
int index: int ref,
int arg_type: @type ref
);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
is_proxy_class_for(
unique int id: @usertype ref,
@@ -755,6 +760,11 @@ function_template_argument(
int index: int ref,
int arg_type: @type ref
);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
is_variable_template(unique int id: @variable ref);
variable_instantiation(
@@ -766,6 +776,11 @@ variable_template_argument(
int index: int ref,
int arg_type: @type ref
);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
/*
Fixed point types
diff --git a/cpp/ql/src/semmlecode.cpp.dbscheme.stats b/cpp/ql/src/semmlecode.cpp.dbscheme.stats
index bd1964b0d4f..3a73724456a 100644
--- a/cpp/ql/src/semmlecode.cpp.dbscheme.stats
+++ b/cpp/ql/src/semmlecode.cpp.dbscheme.stats
@@ -1,15 +1,15 @@
@compilation
-10588
+10177
@externalDataElement
-72
+70
@duplication
-185332
+185440
@similarity
@@ -17,7 +17,7 @@
@external_package
-133
+128
@svnentry
@@ -25,67 +25,67 @@
@location_default
-9664446
+9335283
@location_stmt
-2176932
+2178211
@location_expr
-9745314
+9746017
@diagnostic
-76160
+73204
@file
-66167
+63599
@folder
-12107
+11637
@macroinvocation
-40814994
+39320374
@function
-3565918
+3552236
@fun_decl
-3657006
+3635139
@var_decl
-5579181
+5495954
@type_decl
-1469165
+1413769
@namespace_decl
-151627
+145743
@using
-320601
+308161
@static_assert
-132358
+131017
@parameter
-4779409
+4724692
@membervariable
-325099
+321201
@globalvariable
@@ -93,47 +93,47 @@
@localvariable
-527101
+521758
@enumconstant
-94487
+94097
@builtintype
-559
+537
@derivedtype
-4572495
+4651908
@decltype
-45841
+44063
@usertype
-4363319
+4337028
@mangledname
-532986
+514256
@type_mention
-1699359
+1682135
@routinetype
-444572
+436132
@ptrtomember
-12180
+13227
@specifier
-547
+525
@gnuattribute
@@ -141,11 +141,11 @@
@stdattribute
-369
+365
@declspec
-58441
+57849
@msattribute
@@ -153,7 +153,7 @@
@alignas
-267
+257
@attribute_arg_empty
@@ -161,55 +161,55 @@
@attribute_arg_token
-15930
+15768
@attribute_arg_constant
-111500
+111565
@attribute_arg_type
-60
+58
@derivation
-370309
+392220
@frienddecl
-231178
+222208
@comment
-1743633
+1675974
@namespace
-8497
+8167
@specialnamequalifyingelement
-12
+11
@namequalifier
-1125621
+1116919
@value
-8776796
+8788031
@initialiser
-1685017
+1668506
@literal
-4374193
+4381545
@errorexpr
-48066
+46201
@address_of
@@ -217,15 +217,15 @@
@reference_to
-1077837
+1039133
@indirect
-294638
+294811
@ref_indirect
-1267903
+1225212
@array_to_pointer
@@ -233,31 +233,31 @@
@vacuous_destructor_call
-4449
+4288
@assume
-3328
+3294
@parexpr
-3001187
+3002950
@arithnegexpr
-654789
+654792
@unaryplusexpr
-206
+198
@complementexpr
-28027
+28043
@notexpr
-357915
+358125
@conjugation
@@ -265,51 +265,51 @@
@realpartexpr
-72
+70
@imagpartexpr
-72
+70
@postincrexpr
-43039
+43064
@postdecrexpr
-5401
+5404
@preincrexpr
-63954
+61508
@predecrexpr
-26586
+25554
@conditionalexpr
-154429
+154519
@addexpr
-209503
+209626
@subexpr
-134974
+135053
@mulexpr
-91616
+91670
@divexpr
-63973
+64010
@remexpr
-4657
+4660
@jmulexpr
@@ -337,59 +337,59 @@
@paddexpr
-87252
+87303
@psubexpr
-23151
+23165
@pdiffexpr
-25868
+24865
@lshiftexpr
-347564
+347768
@rshiftexpr
-59286
+59321
@andexpr
-236938
+237077
@orexpr
-145217
+143745
@xorexpr
-37281
+37303
@eqexpr
-212621
+212746
@neexpr
-88456
+88508
@gtexpr
-43936
+43962
@ltexpr
-54831
+54863
@geexpr
-22361
+22374
@leexpr
-213875
+214001
@minexpr
@@ -401,7 +401,7 @@
@assignexpr
-551713
+552037
@assignaddexpr
@@ -413,15 +413,15 @@
@assignmulexpr
-7597
+7302
@assigndivexpr
-2297
+2208
@assignremexpr
-303
+292
@assignlshiftexpr
@@ -433,39 +433,39 @@
@assignandexpr
-7740
+7744
@assignorexpr
-18663
+18674
@assignxorexpr
-21992
+22005
@assignpaddexpr
-13214
+13080
@assignpsubexpr
-583
+577
@andlogicalexpr
-116840
+116908
@orlogicalexpr
-57827
+57861
@commaexpr
-10721
+10329
@subscriptexpr
-165754
+165851
@virtfunptrexpr
@@ -473,15 +473,15 @@
@callexpr
-248513
+239197
@vastartexpr
-3710
+3673
@vaargexpr
-1094
+1051
@vaendexpr
@@ -493,63 +493,63 @@
@varaccess
-5376400
+5325591
@thisaccess
-1181340
+1169367
@new_expr
-29515
+28370
@delete_expr
-6564
+6309
@throw_expr
-23777
+22855
@condition_decl
-7646
+7349
@braced_init_list
-133
+128
@type_id
-4899
+4708
@runtime_sizeof
-281622
+281787
@runtime_alignof
-1560
+1561
@sizeof_pack
-267
+502
@expr_stmt
-160546
+160640
@routineexpr
-2309113
+2232038
@type_operand
-127928
+128003
@offsetofexpr
-35356
+35377
@hasassignexpr
@@ -597,11 +597,11 @@
@isbaseofexpr
-19
+39
@isclassexpr
-6
+215
@isconvtoexpr
@@ -609,15 +609,15 @@
@isemptyexpr
-5
+175
@isenumexpr
-3
+23
@ispodexpr
-3
+11
@ispolyexpr
@@ -629,7 +629,7 @@
@typescompexpr
-46285
+46312
@intaddrexpr
@@ -637,11 +637,11 @@
@hastrivialdestructor
-97
+105
@uuidof
-856
+848
@aggregateliteral
@@ -649,11 +649,11 @@
@delete_array_expr
-1495
+1437
@new_array_expr
-5364
+5310
@foldexpr
@@ -661,59 +661,59 @@
@ctordirectinit
-93264
+89645
@ctorvirtualinit
-6904
+6636
@ctorfieldinit
-209661
+201538
@ctordelegatinginit
-741
+712
@dtordirectdestruct
-30828
+30111
@dtorvirtualdestruct
-2698
+2594
@dtorfielddestruct
-32542
+31279
@static_cast
-224735
+226064
@reinterpret_cast
-31207
+30891
@const_cast
-5847
+5643
@dynamic_cast
-1094
+1051
@c_style_cast
-4242732
+4244118
@lambdaexpr
-12641
+12513
@param_ref
-53208
+51144
@noopexpr
@@ -745,7 +745,7 @@
@istrivialexpr
-2565
+2512
@isstandardlayoutexpr
@@ -753,7 +753,7 @@
@istriviallycopyableexpr
-48
+46
@isliteraltypeexpr
@@ -813,11 +813,11 @@
@isfinalexpr
-2
+175
@noexceptexpr
-449
+432
@builtinshufflevector
@@ -825,11 +825,11 @@
@builtinchooseexpr
-7028
+7032
@builtinaddressof
-4388
+4218
@vec_fill
@@ -845,67 +845,67 @@
@lambdacapture
-21730
+21509
@stmt_expr
-1284462
+1271443
@stmt_if
-524558
+524866
@stmt_while
-32907
+31630
@stmt_goto
-111432
+111498
@stmt_label
-85508
+85558
@stmt_return
-1197201
+1154730
@stmt_block
-1398281
+1348007
@stmt_end_test_while
-149900
+149988
@stmt_for
-32387
+32059
@stmt_switch_case
-281530
+281695
@stmt_switch
-55225
+55258
@stmt_asm
-251715
+251863
@stmt_try_block
-18964
+18228
@stmt_microsoft_try
-171
+169
@stmt_decl
-647378
+623601
@stmt_set_vla_size
@@ -917,27 +917,27 @@
@stmt_assigned_goto
-9137
+9142
@stmt_empty
-103681
+102630
@stmt_continue
-8603
+8608
@stmt_break
-232406
+232543
@stmt_range_based_for
-24
+23
@stmt_handler
-21888
+21666
@stmt_constexpr_if
@@ -945,51 +945,51 @@
@ppd_plain_include
-321707
+309224
@ppd_define
-349947
+336367
@ppd_if
-171077
+164439
@ppd_ifdef
-66823
+64230
@ppd_ifndef
-91793
+88231
@ppd_elif
-22768
+21885
@ppd_else
-63638
+61169
@ppd_endif
-329694
+316901
@ppd_undef
-21152
+20331
@ppd_line
-12523
+12530
@ppd_error
-48
+46
@ppd_pragma
-37040
+36665
@ppd_objc_import
@@ -997,7 +997,7 @@
@ppd_include_next
-97
+93
@ppd_warning
@@ -1005,7 +1005,7 @@
@link_target
-644
+619
@xmldtd
@@ -1034,15 +1034,15 @@
compilations
-10588
+10177
id
-10588
+10177
cwd
-12
+11
@@ -1056,7 +1056,7 @@
1
2
-10588
+10177
@@ -1072,7 +1072,7 @@
871
872
-12
+11
@@ -1082,11 +1082,11 @@
compilation_args
-394124
+394355
id
-4637
+4640
num
@@ -1094,7 +1094,7 @@
arg
-20097
+20109
@@ -1113,7 +1113,7 @@
87
88
-3527
+3529
88
@@ -1149,7 +1149,7 @@
86
87
-3529
+3531
87
@@ -1322,12 +1322,12 @@
1
2
-19123
+19134
2
2575
-974
+975
@@ -1343,7 +1343,7 @@
1
2
-19748
+19760
2
@@ -1358,19 +1358,19 @@
compilation_compiling_files
-10588
+10177
id
-10588
+10177
num
-12
+11
file
-5373
+5164
@@ -1384,7 +1384,7 @@
1
2
-10588
+10177
@@ -1400,7 +1400,7 @@
1
2
-10588
+10177
@@ -1416,7 +1416,7 @@
871
872
-12
+11
@@ -1432,7 +1432,7 @@
442
443
-12
+11
@@ -1448,17 +1448,17 @@
1
2
-303
+292
2
3
-5044
+4849
3
14
-24
+23
@@ -1474,7 +1474,7 @@
1
2
-5373
+5164
@@ -1484,23 +1484,23 @@
compilation_time
-42255
+40616
id
-10563
+10154
num
-12
+11
kind
-48
+46
seconds
-12375
+11965
@@ -1514,7 +1514,7 @@
1
2
-10563
+10154
@@ -1530,7 +1530,7 @@
4
5
-10563
+10154
@@ -1544,14 +1544,19 @@
12
+2
+3
+58
+
+
3
4
-3160
+2792
4
5
-7403
+7302
@@ -1567,7 +1572,7 @@
869
870
-12
+11
@@ -1583,7 +1588,7 @@
4
5
-12
+11
@@ -1597,9 +1602,9 @@
12
-1018
-1019
-12
+1024
+1025
+11
@@ -1615,7 +1620,7 @@
869
870
-48
+46
@@ -1631,7 +1636,7 @@
1
2
-48
+46
@@ -1645,24 +1650,24 @@
12
-6
-7
-12
+7
+8
+11
-9
-10
-12
+10
+11
+11
-561
-562
-12
+560
+561
+11
-597
-598
-12
+591
+592
+11
@@ -1678,27 +1683,27 @@
1
2
-7755
+7501
2
3
-2613
+2617
3
4
-1045
+759
4
-324
-936
+8
+899
-417
-614
-24
+8
+632
+186
@@ -1714,7 +1719,7 @@
1
2
-12375
+11965
@@ -1730,12 +1735,17 @@
1
2
-10490
+10305
2
3
-1884
+1635
+
+
+3
+4
+23
@@ -1745,23 +1755,23 @@
diagnostic_for
-940397
+903906
diagnostic
-940397
+73204
compilation
-10223
+9826
file_number
-12
+11
file_number_diagnostic_number
-7208
+6929
@@ -1775,7 +1785,17 @@
1
2
-940397
+9861
+
+
+2
+3
+60456
+
+
+118
+840
+2886
@@ -1791,7 +1811,7 @@
1
2
-940397
+73204
@@ -1807,7 +1827,12 @@
1
2
-940397
+73181
+
+
+2
+3
+23
@@ -1823,37 +1848,37 @@
2
3
-24
+23
7
8
-5227
+5024
8
9
-1665
+1600
9
10
-218
+210
247
248
-2066
+1986
263
444
-802
+771
446
594
-218
+210
@@ -1869,7 +1894,7 @@
1
2
-10223
+9826
@@ -1885,37 +1910,37 @@
2
3
-24
+23
7
8
-5227
+5024
8
9
-1665
+1600
9
10
-218
+210
247
248
-2066
+1986
263
444
-802
+771
446
594
-218
+210
@@ -1931,7 +1956,7 @@
6265
6266
-12
+11
@@ -1947,7 +1972,7 @@
841
842
-12
+11
@@ -1963,7 +1988,7 @@
593
594
-12
+11
@@ -1979,47 +2004,47 @@
1
2
-2954
+2839
2
5
-656
+630
5
6
-1057
+1016
7
14
-571
+549
15
16
-60
+58
17
18
-632
+607
18
23
-486
+467
26
40
-583
+560
42
842
-206
+198
@@ -2035,52 +2060,52 @@
4
9
-619
+595
10
11
-1057
+1016
14
27
-571
+549
30
31
-60
+58
34
35
-632
+607
36
45
-486
+467
52
79
-583
+560
84
85
-194
+186
254
255
-2893
+2780
272
842
-109
+105
@@ -2096,7 +2121,7 @@
1
2
-7208
+6929
@@ -2106,19 +2131,19 @@
compilation_finished
-10588
+10177
id
-10588
+10177
cpu_seconds
-8436
+7957
elapsed_seconds
-182
+186
@@ -2132,7 +2157,7 @@
1
2
-10588
+10177
@@ -2148,7 +2173,7 @@
1
2
-10588
+10177
@@ -2164,17 +2189,17 @@
1
2
-7184
+6730
2
3
-850
+712
3
-12
-401
+9
+514
@@ -2190,12 +2215,12 @@
1
2
-8023
+7560
2
3
-413
+397
@@ -2211,67 +2236,62 @@
1
2
-36
+35
2
3
-12
+35
3
4
-12
+11
-4
-5
-12
-
-
-8
-9
-12
+7
+8
+11
10
11
-12
+11
-20
-21
-12
+21
+22
+11
-22
-23
-12
+27
+28
+11
53
54
-12
+11
-124
-125
-12
+120
+121
+11
-134
-135
-12
+125
+126
+11
-230
-231
-12
+233
+234
+11
-258
-259
-12
+263
+264
+11
@@ -2287,67 +2307,62 @@
1
2
-36
+35
2
3
-12
+35
3
4
-12
+11
-4
-5
-12
-
-
-8
-9
-12
+7
+8
+11
10
11
-12
+11
-20
-21
-12
+21
+22
+11
-22
-23
-12
+26
+27
+11
-49
-50
-12
+51
+52
+11
-100
-101
-12
+92
+93
+11
118
119
-12
+11
-172
-173
-12
+163
+164
+11
-217
-218
-12
+215
+216
+11
@@ -2357,23 +2372,23 @@
externalData
-145
+140
id
-72
+70
path
-12
+11
column
-24
+23
value
-145
+140
@@ -2387,7 +2402,7 @@
1
2
-72
+70
@@ -2403,7 +2418,7 @@
2
3
-72
+70
@@ -2419,7 +2434,7 @@
2
3
-72
+70
@@ -2435,7 +2450,7 @@
6
7
-12
+11
@@ -2451,7 +2466,7 @@
2
3
-12
+11
@@ -2467,7 +2482,7 @@
12
13
-12
+11
@@ -2483,7 +2498,7 @@
6
7
-24
+23
@@ -2499,7 +2514,7 @@
1
2
-24
+23
@@ -2515,7 +2530,7 @@
6
7
-24
+23
@@ -2531,7 +2546,7 @@
1
2
-145
+140
@@ -2547,7 +2562,7 @@
1
2
-145
+140
@@ -2563,7 +2578,7 @@
1
2
-145
+140
@@ -2573,41 +2588,41 @@
snapshotDate
-12
+11
snapshotDate
-12
+11
sourceLocationPrefix
-12
+11
prefix
-12
+11
duplicateCode
-185332
+185440
id
-185332
+185440
relativePath
-761
+762
equivClass
-76596
+76641
@@ -2621,7 +2636,7 @@
1
2
-185332
+185440
@@ -2637,7 +2652,7 @@
1
2
-185332
+185440
@@ -2765,27 +2780,27 @@
1
2
-20462
+20474
2
3
-32635
+32655
3
4
-10716
+10723
4
5
-6015
+6019
5
9
-5954
+5957
9
@@ -2806,7 +2821,7 @@
1
2
-75730
+75775
2
@@ -3122,27 +3137,27 @@
tokens
-39620249
+39643528
id
-279171
+279335
offset
-21169
+21181
beginLine
-785436
+785898
beginColumn
-1302
+1303
endLine
-785436
+785898
endColumn
@@ -3160,72 +3175,72 @@
100
101
-8596
+8601
101
102
-27640
+27656
102
105
-22613
+22626
105
108
-24506
+24520
108
111
-13844
+13852
111
114
-23787
+23801
114
116
-22681
+22694
116
124
-23658
+23672
124
132
-21660
+21673
132
154
-21347
+21360
154
186
-21323
+21335
186
202
-23418
+23432
202
416
-20978
+20991
416
3446
-3115
+3117
@@ -3246,47 +3261,47 @@
5
6
-109755
+109819
6
7
-15399
+15408
7
8
-28395
+28412
8
12
-23645
+23659
12
17
-22797
+22811
17
19
-18969
+18980
19
22
-22791
+22805
22
28
-21470
+21483
28
151
-14545
+14553
@@ -3302,42 +3317,42 @@
2
26
-22933
+22946
26
31
-22318
+22331
31
32
-2642
+2643
32
33
-163572
+163668
33
51
-21310
+21323
51
61
-22472
+22485
61
80
-21058
+21071
80
132
-2863
+2865
@@ -3358,47 +3373,47 @@
5
6
-109755
+109819
6
7
-15399
+15408
7
8
-28395
+28412
8
12
-23645
+23659
12
17
-22797
+22811
17
19
-18969
+18980
19
22
-22791
+22805
22
28
-21470
+21483
28
151
-14545
+14553
@@ -3414,42 +3429,42 @@
2
26
-21667
+21679
26
31
-24352
+24366
31
32
-1622
+1623
32
33
-163861
+163957
33
54
-22103
+22116
54
63
-20942
+20954
63
82
-21488
+21501
82
133
-3133
+3135
@@ -3465,17 +3480,17 @@
2
3
-4559
+4562
4
5
-1339
+1340
6
7
-2593
+2594
8
@@ -3485,37 +3500,37 @@
11
12
-1609
+1610
13
23
-1855
+1856
24
62
-1622
+1623
64
130
-1646
+1647
141
250
-1597
+1598
251
982
-1591
+1592
986
45432
-1929
+1930
@@ -3531,17 +3546,17 @@
2
3
-4559
+4562
4
5
-1339
+1340
6
7
-2593
+2594
8
@@ -3551,42 +3566,42 @@
11
12
-1609
+1610
13
23
-1855
+1856
24
62
-1622
+1623
64
130
-1646
+1647
141
246
-1597
+1598
247
964
-1591
+1592
969
32541
-1591
+1592
32546
33841
-337
+338
@@ -3602,47 +3617,47 @@
1
2
-5899
+5902
2
3
-3416
+3418
3
4
-1609
+1610
4
7
-1886
+1887
7
12
-1837
+1838
12
15
-1640
+1641
15
23
-1591
+1592
23
68
-1609
+1610
68
161
-1591
+1592
161
@@ -3663,17 +3678,17 @@
2
3
-4559
+4562
4
5
-1339
+1340
6
7
-2593
+2594
8
@@ -3683,42 +3698,42 @@
11
12
-1609
+1610
13
23
-1855
+1856
24
62
-1622
+1623
64
130
-1646
+1647
141
246
-1597
+1598
247
964
-1591
+1592
969
32541
-1591
+1592
32546
33841
-337
+338
@@ -3734,47 +3749,47 @@
1
2
-5899
+5902
2
3
-3416
+3418
3
4
-1609
+1610
4
7
-1911
+1912
7
12
-1825
+1826
12
15
-1609
+1610
15
24
-1677
+1678
24
74
-1616
+1617
74
169
-1591
+1592
170
@@ -3795,37 +3810,37 @@
1
2
-403939
+404176
2
3
-103118
+103179
3
4
-44274
+44300
4
6
-70568
+70610
6
8
-58457
+58491
8
13
-65861
+65900
13
138
-39217
+39240
@@ -3841,52 +3856,52 @@
1
7
-64810
+64849
7
12
-64350
+64387
12
23
-60079
+60114
23
32
-36740
+36762
32
33
-267244
+267401
33
41
-62672
+62709
41
55
-61271
+61307
55
69
-61541
+61577
69
94
-59243
+59278
94
248
-47482
+47510
@@ -3902,47 +3917,47 @@
1
5
-64429
+64467
5
9
-62611
+62647
9
15
-63016
+63053
15
29
-59870
+59905
29
32
-9205
+9210
32
33
-349310
+349515
33
37
-61959
+61996
37
42
-61400
+61436
42
122
-53633
+53664
@@ -3958,7 +3973,7 @@
1
2
-785436
+785898
@@ -3974,47 +3989,47 @@
1
5
-64294
+64332
5
9
-62611
+62647
9
15
-63133
+63170
15
29
-59735
+59770
29
32
-9254
+9259
32
33
-350355
+350560
33
37
-63588
+63625
37
43
-65241
+65279
43
123
-47224
+47251
@@ -4430,37 +4445,37 @@
1
2
-403939
+404176
2
3
-103118
+103179
3
4
-44274
+44300
4
6
-70568
+70610
6
8
-58457
+58491
8
13
-65861
+65900
13
138
-39217
+39240
@@ -4476,52 +4491,52 @@
1
7
-64810
+64849
7
12
-64350
+64387
12
23
-60079
+60114
23
32
-36740
+36762
32
33
-267244
+267401
33
41
-62672
+62709
41
55
-61271
+61307
55
69
-61541
+61577
69
94
-59243
+59278
94
248
-47482
+47510
@@ -4537,7 +4552,7 @@
1
2
-785436
+785898
@@ -4553,47 +4568,47 @@
1
5
-64429
+64467
5
9
-62611
+62647
9
15
-63016
+63053
15
29
-59870
+59905
29
32
-9205
+9210
32
33
-349310
+349515
33
37
-61959
+61996
37
42
-61400
+61436
42
122
-53633
+53664
@@ -4609,47 +4624,47 @@
1
5
-64294
+64332
5
9
-62611
+62647
9
15
-63133
+63170
15
29
-59735
+59770
29
32
-9254
+9259
32
33
-350355
+350560
33
37
-63588
+63625
37
43
-65241
+65279
43
123
-47224
+47251
@@ -5039,23 +5054,23 @@
external_packages
-133
+128
id
-133
+128
namespace
-12
+11
package_name
-133
+128
version
-133
+128
@@ -5069,7 +5084,7 @@
1
2
-133
+128
@@ -5085,7 +5100,7 @@
1
2
-133
+128
@@ -5101,7 +5116,7 @@
1
2
-133
+128
@@ -5117,7 +5132,7 @@
11
12
-12
+11
@@ -5133,7 +5148,7 @@
11
12
-12
+11
@@ -5149,7 +5164,7 @@
11
12
-12
+11
@@ -5165,7 +5180,7 @@
1
2
-133
+128
@@ -5181,7 +5196,7 @@
1
2
-133
+128
@@ -5197,7 +5212,7 @@
1
2
-133
+128
@@ -5213,7 +5228,7 @@
1
2
-133
+128
@@ -5229,7 +5244,7 @@
1
2
-133
+128
@@ -5245,7 +5260,7 @@
1
2
-133
+128
@@ -5255,15 +5270,15 @@
header_to_external_package
-9093
+8740
fileid
-9093
+8740
package
-133
+128
@@ -5277,7 +5292,7 @@
1
2
-9093
+8740
@@ -5293,42 +5308,42 @@
1
2
-36
+35
2
3
-12
+11
15
16
-24
+23
63
64
-12
+11
71
72
-12
+11
85
86
-12
+11
243
244
-12
+11
251
252
-12
+11
@@ -6546,31 +6561,31 @@
locations_default
-9664446
+9335283
id
-9664446
+9335283
container
-78275
+75237
startLine
-161084
+154834
startColumn
-6017
+5818
endLine
-160902
+154658
endColumn
-8169
+11182
@@ -6584,7 +6599,7 @@
1
2
-9664446
+9335283
@@ -6600,7 +6615,7 @@
1
2
-9664446
+9335283
@@ -6616,7 +6631,7 @@
1
2
-9664446
+9335283
@@ -6632,7 +6647,7 @@
1
2
-9664446
+9335283
@@ -6648,7 +6663,7 @@
1
2
-9664446
+9335283
@@ -6664,62 +6679,62 @@
1
2
-12752
+12257
2
19
-6625
+6368
19
25
-6090
+5818
25
31
-6066
+5830
31
41
-6491
+6204
41
54
-6138
+5854
54
72
-6175
+5877
72
-99
-5968
+98
+5690
-99
-137
-5944
+98
+136
+5702
-137
-221
-5895
+136
+216
+5690
-221
-431
-5871
+216
+417
+5655
-431
+417
19703
-4254
+4288
@@ -6735,62 +6750,62 @@
1
2
-12752
+12257
2
15
-6503
+6251
15
20
-6758
+6496
20
25
-6102
+5842
25
32
-6710
+6461
32
41
-6284
+6052
41
53
-6321
+6064
53
70
-5932
+5690
70
96
-5908
+5678
96
152
-5883
+5667
152
-325
-5871
+322
+5643
-325
+324
8863
-3245
+3131
@@ -6806,62 +6821,62 @@
1
2
-12752
+12257
2
4
-6722
+6461
4
8
-7087
+6812
8
11
-5895
+5632
11
14
-6418
+6099
14
18
-6880
+6601
18
23
-6394
+6134
23
29
-6455
+6227
29
37
-6260
+6029
37
50
-6224
+6052
50
78
-5944
+5737
78
-167
-1239
+168
+1191
@@ -6877,62 +6892,62 @@
1
2
-12752
+12257
2
15
-6479
+6227
15
20
-6795
+6531
20
25
-6029
+5772
25
32
-6710
+6473
32
41
-6297
+6052
41
53
-6309
+6052
53
70
-6017
+5772
70
96
-5920
+5690
96
153
-5932
+5725
153
332
-5883
+5643
332
8863
-3148
+3038
@@ -6948,62 +6963,62 @@
1
2
-12752
+12257
2
14
-6236
+5994
14
19
-6710
+6414
19
23
-6224
+5994
23
27
-6005
+5690
27
32
-6187
+5994
32
38
-6005
+5690
38
45
-6138
+5830
45
54
-5920
+5713
54
65
-5993
+5807
65
-79
-5883
+80
+5842
-79
-184
-4218
+80
+336
+4007
@@ -7019,62 +7034,62 @@
1
2
-31193
+29982
2
3
-19802
+19034
3
4
-18234
+17527
4
5
-10260
+9861
5
6
-9129
+8775
6
7
-6734
+6473
7
9
-14344
+13787
9
13
-13943
+13390
13
30
-12350
+11871
30
112
-12119
+11637
112
-2168
-12083
+2116
+11614
-2193
+2135
6440
-887
+876
@@ -7090,42 +7105,42 @@
1
2
-57268
+55046
2
3
-35496
+34119
3
4
-11341
+10901
4
5
-8983
+8635
5
8
-14794
+14220
8
26
-12363
+11871
26
115
-12095
+11637
115
6440
-8740
+8401
@@ -7141,57 +7156,57 @@
1
2
-32287
+31034
2
3
-19693
+18929
3
4
-20544
+19747
4
5
-9737
+9359
5
6
-9384
+9020
6
7
-6856
+6590
7
9
-14612
+14033
9
13
-14028
+13495
13
27
-12436
+11953
27
60
-12132
+11637
60
153
-9372
+9032
@@ -7207,22 +7222,22 @@
1
2
-119911
+115246
2
3
-18976
+18239
3
7
-13530
+13016
7
184
-8667
+8331
@@ -7238,57 +7253,57 @@
1
2
-32311
+31057
2
3
-19584
+18824
3
4
-19024
+18286
4
5
-10247
+9850
5
6
-9409
+9043
6
7
-6637
+6379
7
9
-14636
+14068
9
13
-13700
+13168
13
28
-12144
+11673
28
-68
-12119
+69
+11813
-68
-190
-11269
+69
+258
+10668
@@ -7304,57 +7319,57 @@
1
2
-948
+934
2
3
-1142
+1074
3
5
-534
+537
5
8
-547
+514
8
16
-474
+467
16
-38
-461
+37
+444
-39
-126
-461
+37
+119
+444
-135
-517
-461
+125
+511
+444
-553
-5009
-461
+518
+4987
+444
-5423
-19562
-461
+5021
+19113
+444
-23702
-199709
-60
+19590
+199744
+70
@@ -7370,47 +7385,47 @@
1
2
-2589
+2500
2
3
-522
+525
3
6
-474
+455
6
15
-486
+467
15
55
-461
+444
59
-223
-461
+226
+444
229
-1196
-461
+1198
+444
-1266
+1275
2344
-461
+444
-2536
+2542
6440
-97
+93
@@ -7426,57 +7441,57 @@
1
2
-984
+969
2
3
-1130
+1063
3
4
-291
+280
4
6
-498
+502
6
10
-486
+455
10
-21
-474
+20
+444
-21
-60
-461
+20
+55
+444
-60
-208
-461
+56
+195
+444
-209
-929
-461
+196
+829
+444
-957
-1965
-461
+851
+1958
+444
-1969
+1958
6490
-303
+327
@@ -7492,55 +7507,55 @@
1
2
-984
+969
2
3
-1130
+1063
3
4
-291
+280
4
6
-498
+502
6
10
-486
+455
10
-21
-474
+20
+444
-21
-60
-461
+20
+55
+444
-60
-208
-461
+56
+195
+444
-209
-931
-461
+205
+828
+444
-958
-1966
-461
+851
+1962
+467
-1969
+1965
6462
303
@@ -7558,42 +7573,42 @@
1
2
-2735
+2640
2
3
-522
+525
3
7
-547
+525
7
13
-474
+455
13
29
-498
+479
29
-51
-474
+54
+455
-51
-90
-461
+54
+109
+444
-91
+110
428
-303
+292
@@ -7609,62 +7624,62 @@
1
2
-30670
+29480
2
3
-20240
+19455
3
4
-17979
+17281
4
5
-10430
+10025
5
6
-8898
+8553
6
7
-6868
+6601
7
9
-14368
+13811
9
13
-13992
+13437
13
30
-12302
+11824
30
111
-12144
+11649
111
-2100
-12071
+2058
+11602
-2100
+2083
6440
-936
+934
@@ -7680,42 +7695,42 @@
1
2
-56758
+54555
2
3
-35654
+34271
3
4
-11341
+10901
4
5
-9105
+8751
5
7
-11949
+11474
7
19
-12338
+11859
19
76
-12083
+11614
76
6440
-11670
+11229
@@ -7731,22 +7746,22 @@
1
2
-118792
+114171
2
3
-19267
+18508
3
7
-12983
+12502
7
46
-9858
+9476
@@ -7762,57 +7777,57 @@
1
2
-31752
+30520
2
3
-20082
+19303
3
4
-20252
+19466
4
5
-9992
+9604
5
6
-9263
+8903
6
7
-6977
+6707
7
9
-14599
+14021
9
13
-14101
+13565
13
27
-12350
+11871
27
60
-12107
+11626
60
153
-9421
+9067
@@ -7828,57 +7843,57 @@
1
2
-31801
+30567
2
3
-19973
+19197
3
4
-18745
+18017
4
5
-10490
+10083
5
6
-9263
+8903
6
7
-6710
+6449
7
9
-14526
+13963
9
13
-14174
+13612
13
29
-12350
+11871
29
71
-12132
+11602
71
-190
-10734
+258
+10387
@@ -7894,52 +7909,47 @@
1
2
-2309
+4428
2
3
-1094
+1180
3
4
-607
+888
4
-7
-753
+6
+1004
-7
-17
-656
+6
+13
+841
-17
-49
-619
+13
+61
+841
-55
-236
-619
+61
+698
+841
-241
-4440
-619
+705
+10765
+841
-4617
-11969
-619
-
-
-12066
-25444
-267
+11014
+25447
+315
@@ -7955,47 +7965,42 @@
1
2
-3257
+5106
2
3
-1033
+1285
3
4
-583
+1028
4
-9
-644
+7
+969
-9
-29
-619
+7
+33
+841
-29
-166
-619
+33
+376
+841
-172
-1667
-619
+387
+2684
+841
-1667
-2846
-619
-
-
-2870
+2688
6440
-170
+268
@@ -8011,52 +8016,47 @@
1
2
-2334
+4463
2
3
-1106
+1180
3
4
-632
+899
4
-7
-741
+6
+1004
-7
-17
-632
+6
+14
+852
-17
-45
-619
+14
+57
+852
-45
-189
-619
+58
+510
+841
-192
-1191
-619
+518
+2401
+841
-1218
-2414
-619
-
-
-2469
+2415
4808
-243
+245
@@ -8072,42 +8072,42 @@
1
2
-3367
+5141
2
3
-1130
+1343
3
4
-595
+1028
4
-11
-668
+7
+969
-11
+7
23
-632
+852
23
-40
-632
+47
+864
-40
-68
-632
+47
+81
+864
-68
-82
-510
+81
+83
+116
@@ -8123,52 +8123,47 @@
1
2
-2334
+4463
2
3
-1106
+1180
3
4
-632
+911
4
-7
-741
+6
+993
-7
-17
-644
+6
+13
+841
-17
-46
-619
+13
+56
+841
-46
-194
-619
+56
+501
+841
-202
-1220
-619
+505
+2374
+841
-1252
-2470
-619
-
-
-2481
+2398
4808
-230
+268
@@ -8178,31 +8173,31 @@
locations_stmt
-2176932
+2178211
id
-2176932
+2178211
container
-3078
+3080
startLine
-296727
+296902
startColumn
-1228
+1229
endLine
-294872
+295045
endColumn
-1493
+1494
@@ -8216,7 +8211,7 @@
1
2
-2176932
+2178211
@@ -8232,7 +8227,7 @@
1
2
-2176932
+2178211
@@ -8248,7 +8243,7 @@
1
2
-2176932
+2178211
@@ -8264,7 +8259,7 @@
1
2
-2176932
+2178211
@@ -8280,7 +8275,7 @@
1
2
-2176932
+2178211
@@ -8493,7 +8488,7 @@
38
48
-251
+252
48
@@ -8534,7 +8529,7 @@
6
15
-251
+252
15
@@ -8681,37 +8676,37 @@
1
2
-113847
+113914
2
3
-78993
+79039
3
4
-31327
+31345
4
6
-24942
+24957
6
16
-22619
+22632
16
129
-22275
+22288
129
222
-2722
+2723
@@ -8727,32 +8722,32 @@
1
2
-175967
+176070
2
3
-51906
+51936
3
5
-22552
+22565
5
13
-22373
+22386
13
125
-22257
+22270
125
176
-1671
+1672
@@ -8768,32 +8763,32 @@
1
2
-130943
+131019
2
3
-73506
+73549
3
4
-30767
+30785
4
7
-26583
+26598
7
16
-22312
+22325
16
45
-12615
+12623
@@ -8809,27 +8804,27 @@
1
2
-192251
+192364
2
3
-47310
+47337
3
4
-21765
+21778
4
9
-23264
+23278
9
30
-12136
+12143
@@ -8845,32 +8840,32 @@
1
2
-156444
+156536
2
3
-62371
+62408
3
4
-20782
+20794
4
9
-24659
+24674
9
30
-22398
+22411
30
73
-10071
+10077
@@ -9266,37 +9261,37 @@
1
2
-116305
+116374
2
3
-72848
+72891
3
4
-31996
+32015
4
6
-25618
+25633
6
16
-23031
+23044
16
126
-22121
+22134
126
228
-2949
+2951
@@ -9312,27 +9307,27 @@
1
2
-175604
+175707
2
3
-52066
+52096
3
5
-22207
+22220
5
14
-23375
+23389
14
173
-21617
+21630
@@ -9348,27 +9343,27 @@
1
2
-194592
+194706
2
3
-42314
+42339
3
4
-20677
+20689
4
8
-22760
+22774
8
32
-14526
+14535
@@ -9384,32 +9379,32 @@
1
2
-133173
+133251
2
3
-67871
+67910
3
4
-32611
+32630
4
7
-26503
+26518
7
16
-22183
+22196
16
46
-12529
+12536
@@ -9425,32 +9420,32 @@
1
2
-156272
+156364
2
3
-62230
+62266
3
4
-21132
+21144
4
9
-23756
+23770
9
33
-22318
+22331
33
73
-9162
+9167
@@ -9830,15 +9825,15 @@
locations_expr
-9745314
+9746017
id
-9745314
+9746017
container
-3559
+3563
startLine
@@ -9868,7 +9863,7 @@
1
2
-9745314
+9746017
@@ -9884,7 +9879,7 @@
1
2
-9745314
+9746017
@@ -9900,7 +9895,7 @@
1
2
-9745314
+9746017
@@ -9916,7 +9911,7 @@
1
2
-9745314
+9746017
@@ -9932,7 +9927,7 @@
1
2
-9745314
+9746017
@@ -9953,67 +9948,67 @@
4
11
-280
+284
11
-36
-267
+37
+272
-36
-112
-270
+37
+114
+269
-112
-207
+114
+210
+269
+
+
+210
+328
268
-207
-326
+328
+498
268
-326
-493
-267
+499
+771
+269
-493
-760
-267
+772
+1223
+268
-760
-1208
-267
+1223
+1918
+268
-1210
-1899
-267
+1918
+3307
+268
-1900
-3251
-267
+3322
+7569
+268
-3258
-7330
-267
+7607
+160039
+268
-7359
-51115
-267
-
-
-51126
+170837
491727
-16
+3
@@ -10029,17 +10024,17 @@
1
3
-300
+296
3
7
-315
+319
7
17
-271
+272
17
@@ -10049,47 +10044,47 @@
35
59
-279
+278
59
88
-270
+271
88
138
-268
+271
138
-206
-267
+207
+271
-206
-336
+207
+339
268
-336
-525
+339
+532
268
-525
-946
-267
+532
+949
+268
-947
-2013
-267
+951
+2069
+268
-2019
+2076
142752
-248
+242
@@ -10105,67 +10100,67 @@
1
3
-308
+307
3
7
-293
+296
7
17
-273
+274
17
-35
-267
+36
+283
-35
-51
-278
+36
+52
+287
-51
-63
-289
+52
+64
+297
-63
-73
-290
+64
+74
+279
-73
-83
+74
+84
+296
+
+
+84
+93
+270
+
+
+93
+106
282
-83
-92
-276
+106
+122
+271
-92
-104
-270
+122
+150
+268
-104
-120
-276
-
-
-120
-145
-270
-
-
-145
+150
330
-187
+153
@@ -10181,17 +10176,17 @@
1
3
-300
+296
3
7
-312
+316
7
17
-274
+275
17
@@ -10201,17 +10196,17 @@
35
59
-278
+277
59
89
-275
+277
89
139
-271
+273
139
@@ -10230,18 +10225,18 @@
547
-971
-267
+973
+269
-972
-2152
-267
+975
+2167
+268
-2152
+2170
143560
-242
+239
@@ -10257,7 +10252,7 @@
1
3
-278
+279
3
@@ -10267,57 +10262,57 @@
7
19
-278
+281
19
-41
-268
+42
+275
-41
+42
60
-279
+272
60
-72
-267
+73
+294
-72
-83
-280
+73
+84
+277
-83
-94
-283
+84
+95
+291
-94
-105
-292
-
-
-105
-119
-278
-
-
-119
-136
+95
+106
279
-136
-162
-269
+106
+120
+282
-162
+120
+138
+275
+
+
+138
+166
+270
+
+
+166
416
-210
+190
@@ -10667,22 +10662,22 @@
16130
-46279
+46280
29
-48722
-86671
+48729
+86681
29
-87010
-224371
+87033
+224378
29
-237409
-710014
+237411
+710028
6
@@ -10743,17 +10738,17 @@
1424
-2061
+2063
29
-2064
-2425
+2066
+2429
29
-2427
-2796
+2429
+2797
22
@@ -11336,18 +11331,18 @@
35
-20304
-51564
+20305
+51570
35
-54934
+54937
117747
35
-117846
-185890
+117863
+185908
35
@@ -11408,12 +11403,12 @@
1983
-2458
+2459
35
-2468
-2637
+2470
+2640
32
@@ -11469,7 +11464,7 @@
2070
-5989
+5990
35
@@ -11616,7 +11611,7 @@
2067
-5989
+5990
35
@@ -11647,23 +11642,23 @@
numlines
-544741
+523603
element_id
-537168
+516324
num_lines
-10272
+9873
num_code
-7938
+7630
num_comment
-4364
+4194
@@ -11677,12 +11672,12 @@
1
2
-529679
+509126
2
7
-7488
+7197
@@ -11698,12 +11693,12 @@
1
2
-529740
+509184
2
7
-7427
+7139
@@ -11719,12 +11714,12 @@
1
2
-537083
+516242
2
3
-85
+81
@@ -11740,393 +11735,41 @@
1
2
-4655
+4475
2
3
-1325
+1273
3
4
-765
+736
4
6
-838
+806
6
12
-814
+782
12
24
-778
+747
24
118
-778
+747
118
7658
-316
-
-
-
-
-
-
-num_lines
-num_code
-
-
-12
-
-
-1
-2
-4728
-
-
-2
-3
-1337
-
-
-3
-4
-802
-
-
-4
-6
-850
-
-
-6
-11
-923
-
-
-11
-18
-790
-
-
-18
-29
-790
-
-
-29
-32
-48
-
-
-
-
-
-
-num_lines
-num_comment
-
-
-12
-
-
-1
-2
-4716
-
-
-2
-3
-1337
-
-
-3
-4
-826
-
-
-4
-6
-838
-
-
-6
-10
-802
-
-
-10
-16
-899
-
-
-16
-26
-814
-
-
-26
-27
-36
-
-
-
-
-
-
-num_code
-element_id
-
-
-12
-
-
-1
-2
-3184
-
-
-2
-3
-1239
-
-
-3
-4
-632
-
-
-4
-6
-607
-
-
-6
-10
-619
-
-
-10
-21
-619
-
-
-21
-67
-595
-
-
-68
-7861
-437
-
-
-
-
-
-
-num_code
-num_lines
-
-
-12
-
-
-1
-2
-3209
-
-
-2
-3
-1264
-
-
-3
-4
-644
-
-
-4
-6
-607
-
-
-6
-10
-692
-
-
-10
-21
-644
-
-
-21
-34
-607
-
-
-34
-42
-267
-
-
-
-
-
-
-num_code
-num_comment
-
-
-12
-
-
-1
-2
-3233
-
-
-2
-3
-1227
-
-
-3
-4
-680
-
-
-4
-6
-619
-
-
-6
-10
-680
-
-
-10
-19
-668
-
-
-19
-28
-595
-
-
-28
-33
-230
-
-
-
-
-
-
-num_comment
-element_id
-
-
-12
-
-
-1
-2
-2030
-
-
-2
-3
-559
-
-
-3
-4
-328
-
-
-4
-7
-340
-
-
-7
-14
-340
-
-
-14
-38
-328
-
-
-39
-280
-328
-
-
-283
-35679
-109
-
-
-
-
-
-
-num_comment
-num_lines
-
-
-12
-
-
-1
-2
-2042
-
-
-2
-3
-571
-
-
-3
-5
-389
-
-
-5
-8
-364
-
-
-8
-18
-364
-
-
-18
-58
-328
-
-
-61
-118
303
@@ -12134,6 +11777,358 @@
+num_lines
+num_code
+
+
+12
+
+
+1
+2
+4545
+
+
+2
+3
+1285
+
+
+3
+4
+771
+
+
+4
+6
+817
+
+
+6
+11
+888
+
+
+11
+18
+759
+
+
+18
+29
+759
+
+
+29
+32
+46
+
+
+
+
+
+
+num_lines
+num_comment
+
+
+12
+
+
+1
+2
+4533
+
+
+2
+3
+1285
+
+
+3
+4
+794
+
+
+4
+6
+806
+
+
+6
+10
+771
+
+
+10
+16
+864
+
+
+16
+26
+782
+
+
+26
+27
+35
+
+
+
+
+
+
+num_code
+element_id
+
+
+12
+
+
+1
+2
+3061
+
+
+2
+3
+1191
+
+
+3
+4
+607
+
+
+4
+6
+584
+
+
+6
+10
+595
+
+
+10
+21
+595
+
+
+21
+67
+572
+
+
+68
+7861
+420
+
+
+
+
+
+
+num_code
+num_lines
+
+
+12
+
+
+1
+2
+3084
+
+
+2
+3
+1215
+
+
+3
+4
+619
+
+
+4
+6
+584
+
+
+6
+10
+666
+
+
+10
+21
+619
+
+
+21
+34
+584
+
+
+34
+42
+257
+
+
+
+
+
+
+num_code
+num_comment
+
+
+12
+
+
+1
+2
+3108
+
+
+2
+3
+1180
+
+
+3
+4
+654
+
+
+4
+6
+595
+
+
+6
+10
+654
+
+
+10
+19
+642
+
+
+19
+28
+572
+
+
+28
+33
+222
+
+
+
+
+
+
+num_comment
+element_id
+
+
+12
+
+
+1
+2
+1951
+
+
+2
+3
+537
+
+
+3
+4
+315
+
+
+4
+7
+327
+
+
+7
+14
+327
+
+
+14
+38
+315
+
+
+39
+280
+315
+
+
+283
+35679
+105
+
+
+
+
+
+
+num_comment
+num_lines
+
+
+12
+
+
+1
+2
+1963
+
+
+2
+3
+549
+
+
+3
+5
+373
+
+
+5
+8
+350
+
+
+8
+18
+350
+
+
+18
+58
+315
+
+
+61
+118
+292
+
+
+
+
+
+
num_comment
num_code
@@ -12143,37 +12138,37 @@
1
2
-2042
+1963
2
3
-571
+549
3
5
-389
+373
5
8
-364
+350
8
17
-340
+327
17
52
-328
+315
56
108
-328
+315
@@ -12183,31 +12178,31 @@
diagnostics
-76160
+73204
id
-76160
+73204
severity
-36
+35
error_tag
-97
+93
error_message
-121
+116
full_error_message
-65948
+63389
location
-145
+140
@@ -12221,7 +12216,7 @@
1
2
-76160
+73204
@@ -12237,7 +12232,7 @@
1
2
-76160
+73204
@@ -12253,7 +12248,7 @@
1
2
-76160
+73204
@@ -12269,7 +12264,7 @@
1
2
-76160
+73204
@@ -12285,7 +12280,7 @@
1
2
-76160
+73204
@@ -12301,17 +12296,17 @@
1
2
-12
+11
2
3
-12
+11
6262
6263
-12
+11
@@ -12327,12 +12322,12 @@
1
2
-24
+23
6
7
-12
+11
@@ -12348,12 +12343,12 @@
1
2
-24
+23
8
9
-12
+11
@@ -12369,17 +12364,17 @@
1
2
-12
+11
2
3
-12
+11
5422
5423
-12
+11
@@ -12395,17 +12390,17 @@
1
2
-12
+11
2
3
-12
+11
9
10
-12
+11
@@ -12421,32 +12416,32 @@
1
2
-24
+23
2
3
-24
+23
5
6
-12
+11
417
418
-12
+11
841
842
-12
+11
4996
4997
-12
+11
@@ -12462,7 +12457,7 @@
1
2
-97
+93
@@ -12478,12 +12473,12 @@
1
2
-85
+81
3
4
-12
+11
@@ -12499,27 +12494,27 @@
1
2
-36
+35
2
3
-24
+23
5
6
-12
+11
417
418
-12
+11
4996
4997
-12
+11
@@ -12535,17 +12530,17 @@
1
2
-60
+58
2
3
-24
+23
5
6
-12
+11
@@ -12561,42 +12556,42 @@
1
2
-24
+23
2
3
-24
+23
5
6
-12
+11
10
11
-12
+11
75
76
-12
+11
332
333
-12
+11
841
842
-12
+11
4996
4997
-12
+11
@@ -12612,7 +12607,7 @@
1
2
-121
+116
@@ -12628,7 +12623,7 @@
1
2
-121
+116
@@ -12644,37 +12639,37 @@
1
2
-36
+35
2
3
-24
+23
5
6
-12
+11
10
11
-12
+11
75
76
-12
+11
332
333
-12
+11
4996
4997
-12
+11
@@ -12690,17 +12685,17 @@
1
2
-85
+81
2
3
-24
+23
5
6
-12
+11
@@ -12716,12 +12711,12 @@
1
2
-65936
+63377
841
842
-12
+11
@@ -12737,7 +12732,7 @@
1
2
-65948
+63389
@@ -12753,7 +12748,7 @@
1
2
-65948
+63389
@@ -12769,7 +12764,7 @@
1
2
-65948
+63389
@@ -12785,7 +12780,7 @@
1
2
-65948
+63389
@@ -12801,12 +12796,12 @@
1
2
-133
+128
6254
6255
-12
+11
@@ -12822,7 +12817,7 @@
1
2
-145
+140
@@ -12838,12 +12833,12 @@
1
2
-133
+128
3
4
-12
+11
@@ -12859,12 +12854,12 @@
1
2
-133
+128
5
6
-12
+11
@@ -12880,12 +12875,12 @@
1
2
-133
+128
5414
5415
-12
+11
@@ -12895,27 +12890,27 @@
files
-66167
+63599
id
-66167
+63599
name
-66167
+63599
simple
-45148
+43397
ext
-109
+105
fromSource
-12
+11
@@ -12929,7 +12924,7 @@
1
2
-66167
+63599
@@ -12945,7 +12940,7 @@
1
2
-66167
+63599
@@ -12961,7 +12956,7 @@
1
2
-66167
+63599
@@ -12977,7 +12972,7 @@
1
2
-66167
+63599
@@ -12993,7 +12988,7 @@
1
2
-66167
+63599
@@ -13009,7 +13004,7 @@
1
2
-66167
+63599
@@ -13025,7 +13020,7 @@
1
2
-66167
+63599
@@ -13041,7 +13036,7 @@
1
2
-66167
+63599
@@ -13057,22 +13052,22 @@
1
2
-34196
+32869
2
3
-6868
+6601
3
7
-3586
+3446
7
42
-498
+479
@@ -13088,22 +13083,22 @@
1
2
-34196
+32869
2
3
-6868
+6601
3
7
-3586
+3446
7
42
-498
+479
@@ -13119,17 +13114,17 @@
1
2
-40322
+38758
2
3
-4193
+4031
3
6
-632
+607
@@ -13145,7 +13140,7 @@
1
2
-45148
+43397
@@ -13161,47 +13156,47 @@
1
2
-12
+11
3
4
-12
+11
15
16
-12
+11
38
39
-12
+11
80
81
-12
+11
114
115
-12
+11
441
442
-12
+11
738
739
-12
+11
4013
4014
-12
+11
@@ -13217,47 +13212,47 @@
1
2
-12
+11
3
4
-12
+11
15
16
-12
+11
38
39
-12
+11
80
81
-12
+11
114
115
-12
+11
441
442
-12
+11
738
739
-12
+11
4013
4014
-12
+11
@@ -13273,47 +13268,47 @@
1
2
-12
+11
3
4
-12
+11
15
16
-12
+11
38
39
-12
+11
75
76
-12
+11
112
113
-12
+11
428
429
-12
+11
658
659
-12
+11
2838
2839
-12
+11
@@ -13329,7 +13324,7 @@
1
2
-109
+105
@@ -13345,7 +13340,7 @@
5443
5444
-12
+11
@@ -13361,7 +13356,7 @@
5443
5444
-12
+11
@@ -13377,7 +13372,7 @@
3714
3715
-12
+11
@@ -13393,7 +13388,7 @@
9
10
-12
+11
@@ -13403,19 +13398,19 @@
folders
-12107
+11637
id
-12107
+11637
name
-12107
+11637
simple
-3476
+3341
@@ -13429,7 +13424,7 @@
1
2
-12107
+11637
@@ -13445,7 +13440,7 @@
1
2
-12107
+11637
@@ -13461,7 +13456,7 @@
1
2
-12107
+11637
@@ -13477,7 +13472,7 @@
1
2
-12107
+11637
@@ -13493,27 +13488,27 @@
1
2
-1872
+1799
2
3
-741
+712
3
4
-498
+479
4
28
-279
+268
28
121
-85
+81
@@ -13529,27 +13524,27 @@
1
2
-1872
+1799
2
3
-741
+712
3
4
-498
+479
4
28
-279
+268
28
121
-85
+81
@@ -13559,15 +13554,15 @@
containerparent
-78250
+75214
parent
-12107
+11637
child
-78250
+75214
@@ -13581,42 +13576,42 @@
1
2
-5506
+5293
2
3
-1568
+1507
3
4
-668
+642
4
6
-1118
+1074
6
10
-899
+864
10
14
-960
+923
14
30
-923
+888
30
153
-461
+444
@@ -13632,7 +13627,7 @@
1
2
-78250
+75214
@@ -13642,23 +13637,23 @@
fileannotations
-5688625
+5467887
id
-5348
+5141
kind
-24
+23
name
-60186
+57851
value
-49318
+47404
@@ -13672,12 +13667,12 @@
1
2
-145
+140
2
3
-5202
+5001
@@ -13693,62 +13688,62 @@
1
96
-401
+385
96
219
-401
+385
221
285
-401
+385
285
444
-401
+385
445
521
-401
+385
526
619
-425
+408
619
708
-401
+385
708
895
-401
+385
896
928
-97
+93
930
931
-1531
+1472
1076
1667
-401
+385
1689
2272
-85
+81
@@ -13764,57 +13759,57 @@
1
108
-401
+385
108
269
-401
+385
269
356
-401
+385
371
630
-401
+385
630
729
-401
+385
733
948
-401
+385
948
1062
-401
+385
1079
1494
-279
+268
1495
1496
-1531
+1472
1496
1865
-401
+385
1963
4058
-328
+315
@@ -13830,12 +13825,12 @@
428
429
-12
+11
440
441
-12
+11
@@ -13851,12 +13846,12 @@
2
3
-12
+11
4949
4950
-12
+11
@@ -13872,12 +13867,12 @@
1
2
-12
+11
4057
4058
-12
+11
@@ -13893,62 +13888,62 @@
1
2
-9871
+9487
2
3
-6491
+6239
3
6
-4996
+4802
6
8
-4935
+4743
8
14
-4850
+4662
14
18
-4424
+4253
18
21
-4619
+4440
21
34
-4862
+4673
34
128
-4813
+4627
129
236
-4595
+4416
236
395
-4558
+4381
395
440
-1167
+1121
@@ -13964,7 +13959,7 @@
1
2
-60186
+57851
@@ -13980,62 +13975,62 @@
1
2
-11038
+10609
2
3
-8728
+8389
3
4
-2808
+2699
4
6
-4352
+4183
6
10
-5470
+5258
10
14
-3586
+3446
14
17
-4643
+4463
17
22
-4643
+4463
22
40
-4558
+4381
40
83
-4582
+4405
83
163
-4534
+4358
164
1933
-1239
+1191
@@ -14051,67 +14046,67 @@
1
2
-7524
+7232
2
5
-2419
+2325
5
8
-3573
+3435
8
21
-3804
+3657
21
23
-2735
+2629
23
25
-4461
+4288
25
40
-3586
+3446
40
195
-3890
+3739
195
207
-3902
+3750
207
273
-4048
+3891
273
327
-3744
+3598
328
407
-4315
+4148
407
441
-1312
+1261
@@ -14127,12 +14122,12 @@
1
2
-49306
+47393
2
3
-12
+11
@@ -14148,67 +14143,67 @@
1
2
-7549
+7256
2
5
-2795
+2687
5
8
-3610
+3470
8
16
-4060
+3902
16
18
-3343
+3213
18
21
-4072
+3914
21
31
-4461
+4288
31
42
-4023
+3867
42
54
-3768
+3622
54
81
-3780
+3633
81
109
-3829
+3680
109
133
-3756
+3610
133
149
-267
+257
@@ -14218,15 +14213,15 @@
inmacroexpansion
-57126596
+57160160
id
-15544516
+15553649
inv
-2493763
+2495229
@@ -14240,42 +14235,42 @@
1
2
-3895411
+3897700
2
3
-2466113
+2467562
3
4
-2018102
+2019287
4
5
-1769908
+1770948
5
6
-1845270
+1846354
6
7
-884925
+885445
7
8
-1535759
+1536661
8
6265
-1129025
+1129688
@@ -14291,52 +14286,52 @@
1
2
-651228
+651611
2
3
-350884
+351091
3
4
-145822
+145908
4
5
-276335
+276498
5
8
-230677
+230812
8
11
-202111
+202230
11
19
-210471
+210594
19
34
-192538
+192651
34
167
-188020
+188130
167
153127
-45673
+45699
@@ -14346,15 +14341,15 @@
affectedbymacroexpansion
-35527526
+35548400
id
-4083475
+4085874
inv
-3282712
+3284641
@@ -14368,42 +14363,42 @@
1
2
-1341531
+1342319
2
3
-719304
+719727
3
4
-682963
+683364
4
6
-320945
+321133
6
10
-313534
+313718
10
24
-308059
+308240
24
64
-309945
+310127
64
9803
-87190
+87242
@@ -14419,72 +14414,72 @@
1
2
-253184
+253333
2
3
-209979
+210102
3
4
-202347
+202466
4
5
-258125
+258276
5
6
-301422
+301599
6
7
-247881
+248027
7
8
-231148
+231284
8
9
-228002
+228136
9
10
-182499
+182606
10
12
-285679
+285847
12
16
-297410
+297584
16
23
-275398
+275560
23
60
-248963
+249109
60
526
-60669
+60704
@@ -14494,23 +14489,23 @@
macroinvocations
-40814994
+39320374
id
-40814994
+39320374
macro_id
-89374
+85906
location
-836970
+804492
kind
-24
+23
@@ -14524,7 +14519,7 @@
1
2
-40814994
+39320374
@@ -14540,7 +14535,7 @@
1
2
-40814994
+39320374
@@ -14556,7 +14551,7 @@
1
2
-40814994
+39320374
@@ -14572,52 +14567,52 @@
1
2
-19267
+18286
2
3
-16946
+16475
3
4
-3744
+3598
4
6
-7925
+7630
6
11
-7658
+7326
11
21
-7160
+6823
21
41
-6758
+6555
41
-104
-6710
+107
+6485
-104
-454
-6710
+107
+450
+6449
-454
-201153
-6491
+453
+201240
+6274
@@ -14633,37 +14628,37 @@
1
2
-47483
+45640
2
3
-11803
+11345
3
4
-5895
+5667
4
6
-7682
+7384
6
13
-7403
+7115
13
65
-6734
+6473
65
3614
-2370
+2278
@@ -14679,12 +14674,12 @@
1
2
-82566
+79362
2
3
-6807
+6543
@@ -14700,42 +14695,42 @@
1
2
-314219
+299713
2
3
-186394
+180341
3
4
-44431
+42999
4
5
-58533
+56378
5
8
-67687
+65247
8
16
-64113
+61777
16
46
-64830
+62536
46
-262302
-36761
+262546
+35498
@@ -14751,12 +14746,12 @@
1
2
-783044
+752659
2
353
-53925
+51833
@@ -14772,7 +14767,7 @@
1
2
-836970
+804492
@@ -14788,12 +14783,12 @@
37566
37567
-12
+11
-3319916
-3319917
-12
+3327545
+3327546
+11
@@ -14809,12 +14804,12 @@
2199
2200
-12
+11
5713
5714
-12
+11
@@ -14830,12 +14825,12 @@
6537
6538
-12
+11
62313
62314
-12
+11
@@ -14845,15 +14840,15 @@
macroparent
-35822215
+34476404
id
-35822215
+34476404
parent_id
-27895299
+26856682
@@ -14867,7 +14862,7 @@
1
2
-35822215
+34476404
@@ -14883,17 +14878,17 @@
1
2
-21477676
+20687700
2
3
-5474478
+5262423
3
88
-943144
+906558
@@ -14903,15 +14898,15 @@
macrolocationbind
-4016679
+4019039
id
-2801506
+2803152
location
-2004363
+2005541
@@ -14925,22 +14920,22 @@
1
2
-2200726
+2202019
2
3
-339324
+339524
3
7
-231800
+231936
7
57
-29655
+29673
@@ -14956,22 +14951,22 @@
1
2
-1602305
+1603246
2
3
-171008
+171108
3
8
-155504
+155595
8
723
-75546
+75590
@@ -14981,19 +14976,19 @@
macro_argument_unexpanded
-104803767
+100941827
invocation
-31131960
+30008413
argument_index
-802
+771
text
-345935
+332512
@@ -15007,22 +15002,22 @@
1
2
-8804221
+8477672
2
3
-12965574
+12498009
3
4
-7092535
+6840222
4
67
-2269629
+2192508
@@ -15038,22 +15033,22 @@
1
2
-8880284
+8550795
2
3
-13152746
+12678071
3
4
-6885304
+6640869
4
67
-2213625
+2138677
@@ -15069,17 +15064,17 @@
51815
51816
-705
+677
52017
-186703
-60
+187640
+58
-770141
-2560947
-36
+773038
+2568177
+35
@@ -15095,17 +15090,17 @@
2
3
-705
+677
13
1002
-60
+58
6617
19688
-36
+35
@@ -15121,62 +15116,62 @@
1
2
-42535
+39868
2
3
-69291
+64826
3
4
-15621
+15435
4
5
-46376
+44296
5
8
-26513
+26980
8
12
-15560
+15447
12
16
-24531
+23275
16
22
-26403
+25414
22
-42
-26257
+41
+25075
-42
-113
-25978
+41
+101
+24970
-113
-51881
-25953
+101
+4363
+24958
-51881
-580841
-911
+4608
+581891
+1963
@@ -15192,17 +15187,17 @@
1
2
-250082
+240378
2
3
-84450
+81173
3
9
-11402
+10960
@@ -15212,19 +15207,19 @@
macro_argument_expanded
-104803767
+100941827
invocation
-31131960
+30008413
argument_index
-802
+771
text
-209491
+201362
@@ -15238,22 +15233,22 @@
1
2
-8804221
+8477672
2
3
-12965574
+12498009
3
4
-7092535
+6840222
4
67
-2269629
+2192508
@@ -15269,22 +15264,22 @@
1
2
-12795323
+12315365
2
3
-11169279
+10770085
3
4
-5961987
+5753415
4
9
-1205370
+1169546
@@ -15300,17 +15295,17 @@
51815
51816
-705
+677
52017
-186703
-60
+187640
+58
-770141
-2560947
-36
+773038
+2568177
+35
@@ -15326,17 +15321,17 @@
1
2
-692
+666
2
75
-60
+58
867
13964
-48
+46
@@ -15352,62 +15347,57 @@
1
2
-25820
+23871
2
3
-42583
+40791
3
4
-6758
+6636
4
-5
-15791
-
-
-5
6
-3367
+18450
6
7
-24555
+23743
7
9
-16702
+16475
9
15
-19146
+17597
15
31
-15851
+15984
31
-87
-15912
+86
+15108
-87
-393
-15742
+86
+365
+15225
-396
-1164221
-7257
+365
+1165688
+7478
@@ -15423,22 +15413,22 @@
1
2
-105651
+101551
2
3
-87976
+84562
3
6
-15779
+15166
6
66
-85
+81
@@ -15448,19 +15438,19 @@
functions
-3565918
+3552236
id
-3565918
+3552236
name
-315848
+303954
kind
-85
+81
@@ -15474,7 +15464,7 @@
1
2
-3565918
+3552236
@@ -15490,7 +15480,7 @@
1
2
-3565918
+3552236
@@ -15506,27 +15496,27 @@
1
2
-214682
+206387
2
3
-31266
+29924
3
5
-28360
+27435
5
13
-23826
+23100
13
-109484
-17711
+118759
+17106
@@ -15542,12 +15532,12 @@
1
2
-314231
+302400
2
3
-1616
+1554
@@ -15563,37 +15553,37 @@
32
33
-12
+11
-477
-478
-12
+478
+479
+11
2735
2736
-12
+11
-5928
-5929
-12
+6052
+6053
+11
-43779
-43780
-12
+43879
+43880
+11
-108979
-108980
-12
+109948
+109949
+11
-131406
-131407
-12
+140883
+140884
+11
@@ -15609,37 +15599,37 @@
11
12
-12
+11
42
43
-12
+11
-228
-229
-12
+229
+230
+11
-1485
-1486
-12
+1494
+1495
+11
2735
2736
-12
+11
-2858
-2859
-12
+2879
+2880
+11
18756
18757
-12
+11
@@ -15649,15 +15639,15 @@
function_entry_point
-1068501
+1030977
id
-1065255
+1027857
entry_point
-1068501
+1030977
@@ -15671,12 +15661,12 @@
1
2
-1062313
+1025030
2
9
-2941
+2827
@@ -15692,7 +15682,7 @@
1
2
-1068501
+1030977
@@ -15702,15 +15692,15 @@
function_return_type
-3577065
+3562951
id
-3565347
+3551686
return_type
-1033588
+1048715
@@ -15724,12 +15714,12 @@
1
2
-3554126
+3540901
2
6
-11220
+10784
@@ -15745,17 +15735,17 @@
1
2
-319945
+309177
2
3
-649566
+677865
3
-81742
-64076
+82133
+61671
@@ -15765,60 +15755,60 @@
purefunctions
-21018
+20805
id
-21018
+20805
function_deleted
-51251
+49379
id
-51251
+49379
function_defaulted
-9554
+9184
id
-9554
+9184
fun_decls
-3668324
+3646017
id
-3657006
+3635139
function
-3484737
+3469555
type_id
-1026294
+1041634
name
-281968
+271389
location
-875943
+843835
@@ -15832,7 +15822,7 @@
1
2
-3657006
+3635139
@@ -15848,12 +15838,12 @@
1
2
-3646053
+3624611
2
6
-10952
+10527
@@ -15869,7 +15859,7 @@
1
2
-3657006
+3635139
@@ -15885,7 +15875,7 @@
1
2
-3657006
+3635139
@@ -15901,12 +15891,12 @@
1
2
-3343699
+3333988
2
9
-141038
+135566
@@ -15922,12 +15912,12 @@
1
2
-3466345
+3451876
2
6
-18392
+17678
@@ -15943,7 +15933,7 @@
1
2
-3484737
+3469555
@@ -15959,12 +15949,12 @@
1
2
-3389832
+3378332
2
9
-94905
+91222
@@ -15980,17 +15970,17 @@
1
2
-305953
+295716
2
3
-648059
+676381
3
-87017
-72282
+87408
+69535
@@ -16006,17 +15996,17 @@
1
2
-318972
+308231
2
3
-644096
+672572
3
-80918
-63225
+81309
+60830
@@ -16032,12 +16022,12 @@
1
2
-956638
+974669
2
-7429
-69656
+7459
+66965
@@ -16053,17 +16043,17 @@
1
2
-921129
+940538
2
5
-81642
+78474
5
-22296
-23522
+22349
+22621
@@ -16079,32 +16069,32 @@
1
2
-169351
+162826
2
3
-32554
+31420
3
4
-18866
+17994
4
7
-25650
+24841
7
19
-21261
+20518
19
-109747
-14283
+119022
+13787
@@ -16120,32 +16110,32 @@
1
2
-181155
+174172
2
3
-31412
+30099
3
4
-16654
+16171
4
7
-22623
+21862
7
-26
-21383
+25
+20366
-26
-109468
-8740
+25
+118743
+8716
@@ -16161,17 +16151,17 @@
1
2
-246046
+236860
2
5
-23170
+22271
5
-56245
-12752
+60936
+12257
@@ -16187,27 +16177,27 @@
1
2
-180486
+173599
2
3
-47823
+46213
3
4
-18040
+17340
4
8
-22696
+21815
8
-8793
-12922
+8910
+12420
@@ -16223,27 +16213,27 @@
1
2
-589769
+567012
2
3
-147895
+142319
3
5
-69790
+67350
5
-179
-65766
+141
+63307
-179
-3027
-2723
+142
+3039
+3844
@@ -16259,22 +16249,22 @@
1
2
-602727
+579468
2
3
-164743
+158514
3
9
-69753
+67747
9
-3027
-38718
+3039
+38103
@@ -16290,17 +16280,17 @@
1
2
-773854
+744445
2
4
-68209
+65890
4
-1514
-33879
+1520
+33500
@@ -16316,12 +16306,12 @@
1
2
-848299
+817018
2
134
-27643
+26816
@@ -16331,22 +16321,22 @@
fun_def
-1296860
+1250592
id
-1296860
+1250592
fun_specialized
-6505
+6439
id
-6505
+6439
@@ -16364,11 +16354,11 @@
fun_decl_specifiers
-512313
+512614
id
-274687
+274848
name
@@ -16386,17 +16376,17 @@
1
2
-72048
+72090
2
3
-167651
+167750
3
4
-34987
+35007
@@ -16583,26 +16573,26 @@
fun_decl_empty_throws
-1416734
+1471304
fun_decl
-1416734
+1471304
fun_decl_noexcept
-16569
+15937
fun_decl
-15693
+15096
constant
-16435
+15809
@@ -16616,12 +16606,12 @@
1
2
-14818
+14255
2
3
-875
+841
@@ -16637,12 +16627,12 @@
1
2
-16301
+15680
2
3
-133
+128
@@ -16652,26 +16642,26 @@
fun_decl_empty_noexcept
-364559
+350681
fun_decl
-364559
+350681
fun_decl_typedef_type
-194
+186
fun_decl
-194
+186
typedeftype_id
-97
+93
@@ -16685,7 +16675,7 @@
1
2
-194
+186
@@ -16701,7 +16691,7 @@
2
3
-97
+93
@@ -16711,19 +16701,19 @@
param_decl_bind
-4830661
+4766932
id
-4830661
+4766932
index
-389
+373
fun_decl
-3158896
+3153051
@@ -16737,7 +16727,7 @@
1
2
-4830661
+4766932
@@ -16753,7 +16743,7 @@
1
2
-4830661
+4766932
@@ -16769,57 +16759,57 @@
2
3
-158
+151
4
10
-24
+23
15
44
-24
+23
115
191
-24
+23
263
337
-24
+23
422
615
-24
+23
885
1215
-24
+23
1695
2656
-24
+23
4907
-13240
-24
+13252
+23
-34828
-76062
-24
+34902
+76574
+23
-259854
-259855
-12
+269844
+269845
+11
@@ -16835,57 +16825,57 @@
2
3
-158
+151
4
10
-24
+23
15
44
-24
+23
115
191
-24
+23
263
337
-24
+23
422
615
-24
+23
885
1215
-24
+23
1695
2656
-24
+23
4907
-13240
-24
+13252
+23
-34828
-76062
-24
+34902
+76574
+23
-259854
-259855
-12
+269844
+269845
+11
@@ -16901,22 +16891,22 @@
1
2
-2234266
+2258317
2
3
-501246
+486913
3
4
-262445
+252985
4
33
-160938
+154834
@@ -16932,22 +16922,22 @@
1
2
-2234266
+2258317
2
3
-501246
+486913
3
4
-262445
+252985
4
33
-160938
+154834
@@ -16957,27 +16947,27 @@
var_decls
-5602108
+5518014
id
-5579181
+5495954
variable
-5340611
+5266618
type_id
-2038268
+2068405
name
-139592
+134175
location
-1358468
+1305755
@@ -16991,7 +16981,7 @@
1
2
-5579181
+5495954
@@ -17007,12 +16997,12 @@
1
2
-5556716
+5474337
2
7
-22465
+21616
@@ -17028,7 +17018,7 @@
1
2
-5579181
+5495954
@@ -17044,12 +17034,12 @@
1
2
-5579132
+5495907
2
3
-48
+46
@@ -17065,12 +17055,12 @@
1
2
-5146145
+5079674
2
9
-194466
+186943
@@ -17086,12 +17076,12 @@
1
2
-5290709
+5218605
2
7
-49902
+48012
@@ -17107,12 +17097,12 @@
1
2
-5321866
+5248600
2
3
-18745
+18017
@@ -17128,12 +17118,12 @@
1
2
-5225490
+5155963
2
9
-115121
+110654
@@ -17149,22 +17139,22 @@
1
2
-1580700
+1627085
2
3
-244952
+236522
3
-9
-154629
+10
+155430
-9
-5708
-57986
+10
+5721
+49367
@@ -17180,22 +17170,22 @@
1
2
-1607080
+1652441
2
3
-234777
+226741
3
-11
-155359
+13
+156353
-11
-5254
-41052
+13
+5267
+32869
@@ -17211,17 +17201,17 @@
1
2
-1850925
+1888086
2
5
-162458
+156341
5
770
-24884
+23977
@@ -17237,17 +17227,17 @@
1
2
-1771751
+1811867
2
4
-165132
+159052
4
3604
-101384
+97485
@@ -17263,42 +17253,42 @@
1
2
-58861
+56530
2
3
-20860
+20039
3
4
-12290
+11801
4
6
-12715
+12268
6
10
-11524
+11088
10
22
-10673
+10270
22
255
-10490
+10083
263
-149390
-2176
+159500
+2091
@@ -17314,37 +17304,37 @@
1
2
-62277
+59814
2
3
-20118
+19314
3
4
-13359
+12841
4
6
-11949
+11532
6
11
-11499
+11077
11
28
-10515
+10095
28
-148426
-9871
+158536
+9499
@@ -17360,32 +17350,32 @@
1
2
-84973
+81606
2
3
-18149
+17445
3
4
-9676
+9347
4
7
-11706
+11275
7
28
-10576
+10165
28
-111448
-4510
+120730
+4335
@@ -17401,32 +17391,32 @@
1
2
-80329
+77212
2
3
-21273
+20448
3
4
-7780
+7478
4
7
-12423
+11941
7
21
-10563
+10154
21
9993
-7220
+6940
@@ -17442,22 +17432,22 @@
1
2
-1008108
+967927
2
3
-144734
+139422
3
6
-124044
+119546
6
-114124
-81581
+123459
+78860
@@ -17473,22 +17463,22 @@
1
2
-1060320
+1018112
2
3
-107961
+103970
3
6
-111863
+107943
6
-113877
-78323
+123212
+75728
@@ -17504,17 +17494,17 @@
1
2
-1166129
+1119863
2
3
-93045
+89797
3
-104379
-99293
+113652
+96095
@@ -17530,12 +17520,12 @@
1
2
-1348524
+1296197
2
52
-9943
+9558
@@ -17545,11 +17535,11 @@
var_def
-2573394
+2477557
id
-2573394
+2477557
@@ -17619,19 +17609,19 @@
type_decls
-1469165
+1413769
id
-1469165
+1413769
type_id
-1433996
+1379965
location
-1203571
+1156868
@@ -17645,7 +17635,7 @@
1
2
-1469165
+1413769
@@ -17661,7 +17651,7 @@
1
2
-1469165
+1413769
@@ -17677,12 +17667,12 @@
1
2
-1408431
+1355392
2
24
-25564
+24572
@@ -17698,12 +17688,12 @@
1
2
-1409866
+1356771
2
24
-24130
+23194
@@ -17719,12 +17709,12 @@
1
2
-1142582
+1098234
2
469
-60988
+58633
@@ -17740,12 +17730,12 @@
1
2
-1144223
+1099812
2
469
-59347
+57056
@@ -17755,45 +17745,45 @@
type_def
-1035654
+995467
id
-1035654
+995467
type_decl_top
-297552
+286006
type_decl
-297552
+286006
namespace_decls
-151627
+145743
id
-151627
+145743
namespace_id
-8485
+8155
location
-135422
+130167
bodylocation
-135787
+130518
@@ -17807,7 +17797,7 @@
1
2
-151627
+145743
@@ -17823,7 +17813,7 @@
1
2
-151627
+145743
@@ -17839,7 +17829,7 @@
1
2
-151627
+145743
@@ -17855,42 +17845,42 @@
1
2
-4011
+3855
2
3
-1191
+1145
3
4
-449
+432
4
7
-717
+689
7
13
-656
+630
13
27
-656
+630
28
163
-644
+619
172
3743
-158
+151
@@ -17906,42 +17896,42 @@
1
2
-4011
+3855
2
3
-1191
+1145
3
4
-449
+432
4
7
-717
+689
7
13
-656
+630
13
27
-656
+630
28
163
-644
+619
172
3743
-158
+151
@@ -17957,42 +17947,42 @@
1
2
-4011
+3855
2
3
-1191
+1145
3
4
-449
+432
4
7
-717
+689
7
13
-656
+630
13
27
-656
+630
28
163
-644
+619
172
3742
-158
+151
@@ -18008,12 +17998,12 @@
1
2
-126135
+121240
2
8
-9287
+8927
@@ -18029,12 +18019,12 @@
1
2
-126135
+121240
2
8
-9287
+8927
@@ -18050,12 +18040,12 @@
1
2
-134595
+129373
2
3
-826
+794
@@ -18071,12 +18061,12 @@
1
2
-126900
+121976
2
11
-8886
+8541
@@ -18092,12 +18082,12 @@
1
2
-126900
+121976
2
9
-8886
+8541
@@ -18113,12 +18103,12 @@
1
2
-135349
+130097
2
5
-437
+420
@@ -18128,19 +18118,19 @@
usings
-320601
+308161
id
-320601
+308161
element_id
-49002
+47101
location
-26464
+25437
@@ -18154,7 +18144,7 @@
1
2
-320601
+308161
@@ -18170,7 +18160,7 @@
1
2
-320601
+308161
@@ -18186,17 +18176,17 @@
1
2
-41234
+39634
2
4
-4169
+4007
4
127
-3598
+3458
@@ -18212,17 +18202,17 @@
1
2
-41234
+39634
2
4
-4169
+4007
4
127
-3598
+3458
@@ -18238,22 +18228,22 @@
1
2
-20033
+19256
2
3
-2540
+2442
3
21
-2054
+1974
21
347
-1835
+1764
@@ -18269,22 +18259,22 @@
1
2
-20033
+19256
2
3
-2540
+2442
3
21
-2054
+1974
21
347
-1835
+1764
@@ -18294,15 +18284,15 @@
using_container
-485187
+466360
parent
-8667
+8331
child
-301029
+289348
@@ -18316,47 +18306,47 @@
1
2
-3379
+3248
2
3
-559
+537
3
6
-668
+642
6
15
-656
+630
16
31
-705
+677
31
143
-291
+280
178
179
-1397
+1343
179
182
-765
+736
182
501
-243
+233
@@ -18372,22 +18362,22 @@
1
2
-217478
+209039
2
3
-55773
+53609
3
6
-22659
+21780
6
47
-5117
+4919
@@ -18397,23 +18387,23 @@
static_asserts
-132358
+131017
id
-132358
+131017
condition
-132358
+131017
message
-30094
+29789
location
-16938
+16766
@@ -18427,7 +18417,7 @@
1
2
-132358
+131017
@@ -18443,7 +18433,7 @@
1
2
-132358
+131017
@@ -18459,7 +18449,7 @@
1
2
-132358
+131017
@@ -18475,7 +18465,7 @@
1
2
-132358
+131017
@@ -18491,7 +18481,7 @@
1
2
-132358
+131017
@@ -18507,7 +18497,7 @@
1
2
-132358
+131017
@@ -18523,32 +18513,32 @@
1
2
-22395
+22168
2
3
-428
+424
3
4
-2867
+2837
4
11
-1463
+1448
12
17
-2379
+2355
17
513
-560
+554
@@ -18564,32 +18554,32 @@
1
2
-22395
+22168
2
3
-428
+424
3
4
-2867
+2837
4
11
-1463
+1448
12
17
-2379
+2355
17
513
-560
+554
@@ -18605,12 +18595,12 @@
1
2
-27912
+27629
2
33
-2181
+2159
@@ -18626,32 +18616,32 @@
1
2
-2939
+2909
2
3
-2801
+2772
3
4
-1344
+1330
5
6
-3776
+3738
6
7
-177
+176
14
15
-2062
+2042
16
@@ -18661,12 +18651,12 @@
17
18
-3447
+3412
19
52
-349
+345
@@ -18682,32 +18672,32 @@
1
2
-2939
+2909
2
3
-2801
+2772
3
4
-1344
+1330
5
6
-3776
+3738
6
7
-177
+176
14
15
-2062
+2042
16
@@ -18717,12 +18707,12 @@
17
18
-3447
+3412
19
52
-349
+345
@@ -18738,22 +18728,22 @@
1
2
-4475
+4429
2
3
-6063
+6002
3
4
-6208
+6145
4
7
-191
+189
@@ -18763,23 +18753,23 @@
params
-4803552
+4749557
id
-4779409
+4724692
function
-3118318
+3117564
index
-389
+373
type_id
-1865866
+1906163
@@ -18793,12 +18783,12 @@
1
2
-4778668
+4723979
2
69
-741
+712
@@ -18814,7 +18804,7 @@
1
2
-4779409
+4724692
@@ -18830,12 +18820,12 @@
1
2
-4757747
+4702211
2
7
-21662
+22481
@@ -18851,22 +18841,22 @@
1
2
-2207692
+2232786
2
3
-482853
+472740
3
4
-264220
+254691
4
33
-163552
+157346
@@ -18882,22 +18872,22 @@
1
2
-2207692
+2232786
2
3
-482853
+472740
3
4
-264220
+254691
4
33
-163552
+157346
@@ -18913,22 +18903,22 @@
1
2
-2314438
+2335471
2
3
-493113
+480884
3
5
-270978
+262941
5
20
-39787
+38267
@@ -18944,57 +18934,57 @@
2
3
-158
+151
4
10
-24
+23
15
44
-24
+23
115
191
-24
+23
263
337
-24
+23
422
615
-24
+23
883
1209
-24
+23
1659
2596
-24
+23
4880
-13455
-24
+13467
+23
-35189
-74910
-24
+35263
+75722
+23
-256345
-256346
-12
+266636
+266637
+11
@@ -19010,57 +19000,57 @@
2
3
-158
+151
4
10
-24
+23
15
44
-24
+23
115
191
-24
+23
263
337
-24
+23
422
615
-24
+23
883
1209
-24
+23
1659
2596
-24
+23
4880
-13455
-24
+13467
+23
-35189
-74910
-24
+35263
+75722
+23
-256516
-256517
-12
+266807
+266808
+11
@@ -19076,57 +19066,57 @@
1
2
-158
+151
3
7
-24
+23
8
20
-24
+23
36
40
-24
+23
42
45
-24
+23
61
105
-24
+23
173
257
-24
+23
406
661
-24
+23
1178
2710
-24
+23
-7491
-16702
-24
+7492
+16795
+23
-135733
-135734
-12
+145286
+145287
+11
@@ -19142,22 +19132,22 @@
1
2
-1495095
+1547921
2
3
-199608
+193171
3
-13
-141671
+18
+144002
-13
-5275
-29491
+18
+5288
+21067
@@ -19173,22 +19163,22 @@
1
2
-1517195
+1569164
2
3
-187245
+181276
3
-17
-140893
+25
+143324
-17
-4798
-20532
+25
+4811
+12397
@@ -19204,12 +19194,12 @@
1
2
-1751170
+1795906
2
33
-114695
+110257
@@ -19219,15 +19209,15 @@
overrides
-161127
+159494
new
-126169
+124890
old
-15666
+15507
@@ -19241,12 +19231,12 @@
1
2
-91218
+90293
2
3
-34944
+34590
3
@@ -19267,37 +19257,37 @@
1
2
-8232
+8148
2
3
-2043
+2022
3
4
-883
+874
4
5
-1278
+1265
5
10
-1245
+1233
10
43
-1179
+1167
44
218
-804
+795
@@ -19307,19 +19297,19 @@
membervariables
-329658
+325582
id
-325099
+321201
type_id
-145086
+139772
name
-59068
+56776
@@ -19333,12 +19323,12 @@
1
2
-320637
+316912
2
7
-4461
+4288
@@ -19354,7 +19344,7 @@
1
2
-325099
+321201
@@ -19370,22 +19360,22 @@
1
2
-118391
+113949
2
3
-13396
+12934
3
11
-10989
+10656
11
-1212
-2309
+1715
+2231
@@ -19401,17 +19391,17 @@
1
2
-125916
+121310
2
3
-9883
+9511
3
266
-9287
+8950
@@ -19427,32 +19417,32 @@
1
2
-31217
+29971
2
3
-9056
+8705
3
4
-5944
+5725
4
6
-4485
+4311
6
15
-4534
+4358
15
-1317
-3829
+1953
+3704
@@ -19468,32 +19458,32 @@
1
2
-38256
+36736
2
3
-7524
+7232
3
4
-4035
+3891
4
7
-4765
+4592
7
-319
-4437
+291
+4264
-323
+318
605
-48
+58
@@ -19674,19 +19664,19 @@
localvariables
-527180
+521836
id
-527101
+521758
type_id
-48087
+47599
name
-76217
+75444
@@ -19700,12 +19690,12 @@
1
2
-527022
+521680
2
3
-79
+78
@@ -19721,7 +19711,7 @@
1
2
-527101
+521758
@@ -19737,32 +19727,32 @@
1
2
-26759
+26487
2
3
-6841
+6772
3
4
-2893
+2864
4
6
-4119
+4077
6
13
-3862
+3823
13
4908
-3611
+3575
@@ -19778,22 +19768,22 @@
1
2
-36072
+35706
2
3
-4969
+4919
3
5
-4323
+4279
5
1158
-2722
+2694
@@ -19809,32 +19799,32 @@
1
2
-43526
+43085
2
3
-13096
+12963
3
4
-5140
+5088
4
7
-6821
+6752
7
31
-5767
+5708
31
6112
-1865
+1846
@@ -19850,17 +19840,17 @@
1
2
-64564
+63910
2
3
-6472
+6406
3
819
-5180
+5127
@@ -19870,11 +19860,11 @@
autoderivation
-19759
+19559
var
-19759
+19559
derivation_type
@@ -19892,7 +19882,7 @@
1
2
-19759
+19559
@@ -19938,31 +19928,31 @@
enumconstants
-94487
+94097
id
-94487
+94097
parent
-7539
+8031
index
-7678
+7600
type_id
-7394
+7887
name
-73851
+73102
location
-76856
+76077
@@ -19976,7 +19966,7 @@
1
2
-94487
+94097
@@ -19992,7 +19982,7 @@
1
2
-94487
+94097
@@ -20008,7 +19998,7 @@
1
2
-94487
+94097
@@ -20024,7 +20014,7 @@
1
2
-94487
+94097
@@ -20040,7 +20030,7 @@
1
2
-94487
+94097
@@ -20056,47 +20046,47 @@
1
2
-1041
+1598
2
3
-830
+822
3
4
-2484
+2459
4
5
-586
+580
5
6
-586
+580
6
-8
-540
+9
+730
-8
-13
-659
+9
+16
+613
-13
-46
-573
+16
+392
+606
-46
+426
1166
-237
+39
@@ -20112,47 +20102,42 @@
1
2
-1041
+1598
2
3
-843
+835
3
4
-2530
+2505
4
5
-579
+574
5
6
-593
+587
6
-8
-527
+9
+704
-8
-13
-632
+9
+17
+626
-13
-49
-566
-
-
-50
+17
1166
-224
+600
@@ -20168,12 +20153,12 @@
1
2
-6788
+7287
2
3
-751
+743
@@ -20189,47 +20174,42 @@
1
2
-1041
+1598
2
3
-843
+835
3
4
-2530
+2505
4
5
-579
+574
5
6
-593
+587
6
-8
-527
+9
+704
-8
-13
-632
+9
+17
+626
-13
-49
-566
-
-
-50
+17
1166
-224
+600
@@ -20245,47 +20225,47 @@
1
2
-1080
+1637
2
3
-843
+835
3
4
-2484
+2459
4
5
-586
+580
5
6
-566
+561
6
-8
-514
+9
+704
-8
-13
-659
+9
+16
+613
-13
-46
-566
+16
+427
+606
-46
+466
1166
-237
+32
@@ -20301,47 +20281,47 @@
1
2
-2642
+2616
2
3
-942
+932
3
4
-935
+926
4
7
-579
+574
7
10
-698
+691
10
11
-355
+352
11
12
-560
+554
12
30
-606
+600
30
-1166
-355
+1253
+352
@@ -20357,47 +20337,47 @@
1
2
-2642
+2616
2
3
-942
+932
3
4
-935
+926
4
7
-579
+574
7
9
-685
+678
9
11
-369
+365
11
12
-560
+554
12
29
-606
+600
29
-1145
-355
+1232
+352
@@ -20413,47 +20393,47 @@
1
2
-2642
+2616
2
3
-942
+932
3
4
-935
+926
4
7
-579
+574
7
9
-685
+678
9
11
-369
+365
11
12
-560
+554
12
28
-606
+600
28
-1123
-355
+1210
+352
@@ -20469,47 +20449,47 @@
1
2
-2642
+2616
2
3
-942
+932
3
4
-935
+926
4
7
-579
+574
7
10
-698
+691
10
11
-355
+352
11
12
-560
+554
12
28
-606
+600
28
674
-355
+352
@@ -20525,47 +20505,47 @@
1
2
-2642
+2616
2
3
-942
+932
3
4
-935
+926
4
7
-579
+574
7
10
-698
+691
10
11
-355
+352
11
12
-560
+554
12
28
-606
+600
28
774
-355
+352
@@ -20581,47 +20561,47 @@
1
2
-1041
+1598
2
3
-810
+802
3
4
-2458
+2433
4
5
-566
+561
5
6
-566
+561
6
-8
-520
+9
+704
-8
-13
-639
+9
+16
+600
-13
-46
-560
+16
+470
+593
-46
+479
1166
-230
+32
@@ -20637,7 +20617,7 @@
1
2
-7388
+7881
137
@@ -20658,47 +20638,42 @@
1
2
-1041
+1598
2
3
-823
+815
3
4
-2504
+2479
4
5
-560
+554
5
6
-573
+567
6
-8
-507
+9
+678
-8
-13
-612
+9
+17
+613
-13
-51
-560
-
-
-52
+17
1166
-210
+580
@@ -20714,47 +20689,42 @@
1
2
-1041
+1598
2
3
-823
+815
3
4
-2504
+2479
4
5
-560
+554
5
6
-573
+567
6
-8
-507
+9
+678
-8
-13
-612
+9
+17
+613
-13
-51
-560
-
-
-52
+17
1166
-210
+580
@@ -20770,47 +20740,47 @@
1
2
-1080
+1637
2
3
-823
+815
3
4
-2458
+2433
4
5
-566
+561
5
6
-547
+541
6
-8
-494
+9
+678
-8
-13
-639
+9
+16
+600
-13
-47
-560
+16
+470
+593
-48
+621
1166
-224
+26
@@ -20826,17 +20796,17 @@
1
2
-66396
+65723
2
3
-6927
+6856
3
239
-527
+521
@@ -20852,17 +20822,17 @@
1
2
-67049
+66369
2
3
-6274
+6210
3
239
-527
+521
@@ -20878,12 +20848,12 @@
1
2
-68762
+68065
2
13
-5088
+5036
@@ -20899,17 +20869,17 @@
1
2
-61941
+61313
2
3
-11382
+11267
3
239
-527
+521
@@ -20925,12 +20895,12 @@
1
2
-71346
+70623
2
23
-2504
+2479
@@ -20946,12 +20916,12 @@
1
2
-71531
+70773
2
229
-5325
+5304
@@ -20967,12 +20937,12 @@
1
2
-71643
+70884
2
229
-5213
+5193
@@ -20988,12 +20958,12 @@
1
2
-73211
+72469
2
17
-3644
+3607
@@ -21009,17 +20979,17 @@
1
2
-66535
+65828
2
3
-10090
+9994
3
229
-230
+254
@@ -21035,12 +21005,12 @@
1
2
-76685
+75907
2
27
-171
+169
@@ -21050,31 +21020,31 @@
builtintypes
-559
+537
id
-559
+537
name
-559
+537
kind
-559
+537
size
-85
+81
sign
-36
+35
alignment
-60
+58
@@ -21088,7 +21058,7 @@
1
2
-559
+537
@@ -21104,7 +21074,7 @@
1
2
-559
+537
@@ -21120,7 +21090,7 @@
1
2
-559
+537
@@ -21136,7 +21106,7 @@
1
2
-559
+537
@@ -21152,7 +21122,7 @@
1
2
-559
+537
@@ -21168,7 +21138,7 @@
1
2
-559
+537
@@ -21184,7 +21154,7 @@
1
2
-559
+537
@@ -21200,7 +21170,7 @@
1
2
-559
+537
@@ -21216,7 +21186,7 @@
1
2
-559
+537
@@ -21232,7 +21202,7 @@
1
2
-559
+537
@@ -21248,7 +21218,7 @@
1
2
-559
+537
@@ -21264,7 +21234,7 @@
1
2
-559
+537
@@ -21280,7 +21250,7 @@
1
2
-559
+537
@@ -21296,7 +21266,7 @@
1
2
-559
+537
@@ -21312,7 +21282,7 @@
1
2
-559
+537
@@ -21328,37 +21298,37 @@
1
2
-12
+11
2
3
-12
+11
4
5
-12
+11
6
7
-12
+11
9
10
-12
+11
11
12
-12
+11
13
14
-12
+11
@@ -21374,37 +21344,37 @@
1
2
-12
+11
2
3
-12
+11
4
5
-12
+11
6
7
-12
+11
9
10
-12
+11
11
12
-12
+11
13
14
-12
+11
@@ -21420,37 +21390,37 @@
1
2
-12
+11
2
3
-12
+11
4
5
-12
+11
6
7
-12
+11
9
10
-12
+11
11
12
-12
+11
13
14
-12
+11
@@ -21466,12 +21436,12 @@
1
2
-24
+23
3
4
-60
+58
@@ -21487,12 +21457,12 @@
1
2
-60
+58
2
3
-24
+23
@@ -21508,17 +21478,17 @@
6
7
-12
+11
12
13
-12
+11
28
29
-12
+11
@@ -21534,17 +21504,17 @@
6
7
-12
+11
12
13
-12
+11
28
29
-12
+11
@@ -21560,17 +21530,17 @@
6
7
-12
+11
12
13
-12
+11
28
29
-12
+11
@@ -21586,12 +21556,12 @@
5
6
-24
+23
7
8
-12
+11
@@ -21607,7 +21577,7 @@
5
6
-36
+35
@@ -21623,27 +21593,27 @@
4
5
-12
+11
7
8
-12
+11
10
11
-12
+11
12
13
-12
+11
13
14
-12
+11
@@ -21659,27 +21629,27 @@
4
5
-12
+11
7
8
-12
+11
10
11
-12
+11
12
13
-12
+11
13
14
-12
+11
@@ -21695,27 +21665,27 @@
4
5
-12
+11
7
8
-12
+11
10
11
-12
+11
12
13
-12
+11
13
14
-12
+11
@@ -21731,12 +21701,12 @@
1
2
-12
+11
2
3
-48
+46
@@ -21752,7 +21722,7 @@
3
4
-60
+58
@@ -21762,23 +21732,23 @@
derivedtypes
-4572495
+4651908
id
-4572495
+4651908
name
-2240442
+2328554
kind
-97
+93
type_id
-2743147
+2780308
@@ -21792,7 +21762,7 @@
1
2
-4572495
+4651908
@@ -21808,7 +21778,7 @@
1
2
-4572495
+4651908
@@ -21824,7 +21794,7 @@
1
2
-4572495
+4651908
@@ -21840,17 +21810,17 @@
1
2
-1640327
+1709696
2
3
-479376
+500222
3
-42612
-120737
+43371
+118634
@@ -21866,12 +21836,12 @@
1
2
-2240417
+2328530
2
3
-24
+23
@@ -21887,17 +21857,17 @@
1
2
-1640607
+1709965
2
3
-479097
+499954
3
-42594
-120737
+43353
+118634
@@ -21913,42 +21883,42 @@
21
22
-12
+11
61
62
-12
+11
2051
2052
-12
+11
-25122
-25123
-12
+27346
+27347
+11
-42664
-42665
-12
+43423
+43424
+11
-53936
-53937
-12
+58521
+58522
+11
-97759
-97760
-12
+102765
+102766
+11
-154522
-154523
-12
+163929
+163930
+11
@@ -21964,42 +21934,42 @@
1
2
-12
+11
13
14
-12
+11
38
39
-12
+11
1152
1153
-12
+11
-13367
-13368
-12
+15027
+15028
+11
-36098
-36099
-12
+39331
+39332
+11
-50248
-50249
-12
+53789
+53790
+11
-83386
-83387
-12
+89933
+89934
+11
@@ -22015,42 +21985,42 @@
12
13
-12
+11
21
22
-12
+11
969
970
-12
+11
-25122
-25123
-12
+27346
+27347
+11
-42664
-42665
-12
+43423
+43424
+11
-53936
-53937
-12
+58521
+58522
+11
-97431
-97432
-12
+102434
+102435
+11
-154522
-154523
-12
+163929
+163930
+11
@@ -22066,22 +22036,22 @@
1
2
-1661856
+1683160
2
3
-405550
+392781
3
4
-615674
+646083
4
202
-60064
+58283
@@ -22097,22 +22067,22 @@
1
2
-1663206
+1684457
2
3
-405380
+392618
3
4
-614495
+644949
4
198
-60064
+58283
@@ -22128,22 +22098,22 @@
1
2
-1663534
+1684784
2
3
-406814
+393985
3
4
-614446
+644902
4
7
-58350
+56635
@@ -22153,19 +22123,19 @@
pointerishsize
-3358396
+3426426
id
-3358396
+3426426
size
-24
+23
alignment
-12
+11
@@ -22179,7 +22149,7 @@
1
2
-3358396
+3426426
@@ -22195,7 +22165,7 @@
1
2
-3358396
+3426426
@@ -22211,12 +22181,12 @@
21
22
-12
+11
-276244
-276245
-12
+293219
+293220
+11
@@ -22232,7 +22202,7 @@
1
2
-24
+23
@@ -22246,9 +22216,9 @@
12
-276265
-276266
-12
+293240
+293241
+11
@@ -22264,7 +22234,7 @@
2
3
-12
+11
@@ -22274,23 +22244,23 @@
arraysizes
-18830
+18099
id
-18830
+18099
num_elements
-2394
+2301
bytesize
-2783
+2675
alignment
-85
+81
@@ -22304,7 +22274,7 @@
1
2
-18830
+18099
@@ -22320,7 +22290,7 @@
1
2
-18830
+18099
@@ -22336,7 +22306,7 @@
1
2
-18830
+18099
@@ -22352,37 +22322,37 @@
1
2
-182
+175
2
3
-1422
+1367
3
4
-85
+81
4
5
-182
+175
5
13
-182
+175
13
25
-182
+175
38
116
-158
+151
@@ -22398,27 +22368,27 @@
1
2
-1762
+1694
2
3
-243
+233
3
4
-133
+128
4
6
-182
+175
6
11
-72
+70
@@ -22434,27 +22404,27 @@
1
2
-1774
+1705
2
3
-255
+245
3
4
-158
+151
4
7
-182
+175
7
8
-24
+23
@@ -22470,42 +22440,42 @@
1
2
-170
+163
2
3
-1556
+1495
3
4
-133
+128
4
6
-218
+210
6
9
-218
+210
9
17
-218
+210
17
53
-218
+210
55
75
-48
+46
@@ -22521,22 +22491,22 @@
1
2
-2115
+2033
2
3
-389
+373
3
6
-243
+233
6
7
-36
+35
@@ -22552,22 +22522,22 @@
1
2
-2176
+2091
2
3
-303
+292
3
5
-255
+245
5
7
-48
+46
@@ -22583,37 +22553,37 @@
17
18
-12
+11
18
19
-12
+11
33
34
-12
+11
50
51
-12
+11
181
182
-12
+11
389
390
-12
+11
861
862
-12
+11
@@ -22629,37 +22599,37 @@
4
5
-12
+11
5
6
-12
+11
13
14
-12
+11
16
17
-12
+11
39
40
-12
+11
40
41
-12
+11
190
191
-12
+11
@@ -22675,37 +22645,37 @@
1
2
-12
+11
2
3
-12
+11
14
15
-12
+11
17
18
-12
+11
41
42
-12
+11
53
54
-12
+11
191
192
-12
+11
@@ -22715,15 +22685,15 @@
typedefbase
-1919913
+1867884
id
-1919913
+1867884
type_id
-899600
+871937
@@ -22737,7 +22707,7 @@
1
2
-1919913
+1867884
@@ -22753,22 +22723,22 @@
1
2
-698168
+676919
2
3
-93312
+90264
3
6
-72975
+70856
6
-5423
-35144
+5485
+33897
@@ -22778,23 +22748,23 @@
decltypes
-45841
+44063
id
-45841
+44063
expr
-43325
+41644
base_type
-6479
+6227
parentheses_would_change_meaning
-24
+23
@@ -22808,7 +22778,7 @@
1
2
-45841
+44063
@@ -22824,7 +22794,7 @@
1
2
-45841
+44063
@@ -22840,7 +22810,7 @@
1
2
-45841
+44063
@@ -22856,12 +22826,12 @@
1
2
-40809
+39225
2
3
-2516
+2418
@@ -22877,12 +22847,12 @@
1
2
-40809
+39225
2
3
-2516
+2418
@@ -22898,7 +22868,7 @@
1
2
-43325
+41644
@@ -22914,17 +22884,17 @@
1
2
-3622
+3482
2
3
-2552
+2453
3
277
-303
+292
@@ -22940,22 +22910,22 @@
1
2
-2540
+2442
2
3
-3282
+3154
3
12
-522
+502
13
2445
-133
+128
@@ -22971,7 +22941,7 @@
1
2
-6479
+6227
@@ -22987,12 +22957,12 @@
8
9
-12
+11
1082
1083
-12
+11
@@ -23008,12 +22978,12 @@
8
9
-12
+11
3556
3557
-12
+11
@@ -23029,12 +22999,12 @@
8
9
-12
+11
525
526
-12
+11
@@ -23044,19 +23014,19 @@
usertypes
-4363319
+4337028
id
-4363319
+4337028
name
-899429
+917472
kind
-133
+128
@@ -23070,7 +23040,7 @@
1
2
-4363319
+4337028
@@ -23086,7 +23056,7 @@
1
2
-4363319
+4337028
@@ -23102,22 +23072,22 @@
1
2
-596127
+606962
2
3
-199888
+203676
3
8
-67589
+69886
8
-31201
-35824
+32070
+36947
@@ -23133,12 +23103,12 @@
1
2
-842355
+861619
2
10
-57074
+55852
@@ -23154,57 +23124,57 @@
23
24
-12
+11
372
373
-12
+11
773
774
-12
+11
-1526
-1527
-12
+1856
+1857
+11
-4123
-4124
-12
+4195
+4196
+11
14604
14605
-12
+11
-17528
-17529
-12
+17544
+17545
+11
-20287
-20288
-12
+20425
+20426
+11
-75247
-75248
-12
+75551
+75552
+11
-81118
-81119
-12
+90575
+90576
+11
-143330
-143331
-12
+145253
+145254
+11
@@ -23220,52 +23190,52 @@
16
17
-12
+11
38
39
-24
+23
404
405
-12
+11
548
549
-12
+11
-776
-777
-12
+777
+778
+11
-2846
-2847
-12
+2848
+2849
+11
4545
4546
-12
+11
-9121
-9122
-12
+9129
+9130
+11
11659
11660
-12
+11
-49218
-49219
-12
+53824
+53825
+11
@@ -23275,19 +23245,19 @@
usertypesize
-1364814
+1420908
id
-1364814
+1420908
size
-1641
+1577
alignment
-97
+93
@@ -23301,7 +23271,7 @@
1
2
-1364814
+1420908
@@ -23317,7 +23287,7 @@
1
2
-1364814
+1420908
@@ -23333,52 +23303,52 @@
1
2
-474
+455
2
3
-218
+210
3
4
-72
+70
4
5
-109
+105
5
8
-121
+116
8
12
-109
+105
12
16
-133
+128
16
36
-133
+128
37
170
-133
+128
260
-86086
-133
+95028
+128
@@ -23394,17 +23364,17 @@
1
2
-1349
+1297
2
3
-194
+186
3
6
-97
+93
@@ -23420,42 +23390,42 @@
1
2
-12
+11
3
4
-12
+11
7
8
-12
+11
50
51
-12
+11
54
55
-12
+11
-1916
-1917
-12
+2246
+2247
+11
-9656
-9657
-12
+9717
+9718
+11
-100584
-100585
-12
+109526
+109527
+11
@@ -23471,37 +23441,37 @@
1
2
-24
+23
3
4
-12
+11
8
9
-12
+11
12
13
-12
+11
17
18
-12
+11
25
26
-12
+11
106
107
-12
+11
@@ -23511,26 +23481,26 @@
usertype_final
-1331
+1317
id
-1331
+1317
usertype_uuid
-4897
+4847
id
-4897
+4847
uuid
-4897
+4847
@@ -23544,7 +23514,7 @@
1
2
-4897
+4847
@@ -23560,7 +23530,7 @@
1
2
-4897
+4847
@@ -23570,15 +23540,15 @@
mangled_name
-4359684
+4333558
id
-4359684
+4333558
mangled_name
-532986
+514256
@@ -23592,7 +23562,7 @@
1
2
-4359684
+4333558
@@ -23608,32 +23578,32 @@
1
2
-325269
+310895
2
3
-68246
+66497
3
4
-35958
+35217
4
-8
-45307
+7
+39225
-8
-34
-40237
+7
+23
+38664
-34
-8470
-17967
+23
+8589
+23755
@@ -23643,59 +23613,59 @@
is_pod_class
-1041477
+1104649
id
-1041477
+1104649
is_standard_layout_class
-1118962
+1180366
id
-1118962
+1180366
is_complete
-1345984
+1398952
id
-1345984
+1398952
is_class_template
-246617
+238660
id
-246617
+238660
class_instantiation
-1108921
+1176522
to
-1107195
+1174863
from
-72513
+72363
@@ -23709,12 +23679,12 @@
1
2
-1105566
+1173297
2
4
-1628
+1565
@@ -23730,47 +23700,47 @@
1
2
-21601
+21289
2
3
-12897
+12771
3
4
-7488
+7314
4
5
-4789
+4942
5
7
-5871
+5994
7
11
-6503
+6438
11
20
-5555
+5585
20
-89
-5470
+87
+5456
-89
-2079
-2334
+87
+3629
+2570
@@ -23780,19 +23750,19 @@
class_template_argument
-2800063
+3135757
type_id
-1339675
+1428725
index
-1361
+1308
arg_type
-921287
+904899
@@ -23806,27 +23776,27 @@
1
2
-593732
+586000
2
3
-438105
+428957
3
4
-175599
+258501
4
7
-108629
+129501
7
113
-23607
+25764
@@ -23842,22 +23812,22 @@
1
2
-619710
+613658
2
3
-445691
+442173
3
4
-187999
+272382
4
113
-86274
+100511
@@ -23873,37 +23843,37 @@
1
2
-12
+11
2
3
-863
+829
3
26
-109
+105
29
64
-109
+105
69
-427
-109
+435
+105
-594
-8438
-109
+616
+9263
+105
-11951
-101100
-48
+13601
+119714
+46
@@ -23919,37 +23889,37 @@
1
2
-12
+11
2
3
-863
+829
3
14
-121
+116
14
26
-109
+105
29
-147
-109
+148
+105
-191
-3560
-109
+198
+3591
+105
-11321
-39550
-36
+11582
+41130
+35
@@ -23965,22 +23935,27 @@
1
2
-571096
+550198
2
3
-205784
+200100
3
-5
-75369
+4
+54918
-5
-5259
-69036
+4
+10
+70727
+
+
+10
+11421
+28954
@@ -23996,17 +23971,253 @@
1
2
-805922
+786767
2
3
-96011
+98069
3
22
-19353
+20062
+
+
+
+
+
+
+
+
+class_template_argument_value
+362635
+
+
+type_id
+233565
+
+
+index
+163
+
+
+arg_value
+345447
+
+
+
+
+type_id
+index
+
+
+12
+
+
+1
+2
+209845
+
+
+2
+3
+14512
+
+
+3
+14
+9207
+
+
+
+
+
+
+type_id
+arg_value
+
+
+12
+
+
+1
+2
+197436
+
+
+2
+3
+17971
+
+
+3
+22
+17527
+
+
+24
+173
+630
+
+
+
+
+
+
+index
+type_id
+
+
+12
+
+
+8
+9
+58
+
+
+20
+21
+11
+
+
+25
+26
+11
+
+
+206
+207
+11
+
+
+389
+390
+11
+
+
+552
+553
+11
+
+
+1312
+1313
+11
+
+
+5393
+5394
+11
+
+
+5423
+5424
+11
+
+
+9668
+9669
+11
+
+
+
+
+
+
+index
+arg_value
+
+
+12
+
+
+8
+9
+58
+
+
+20
+21
+11
+
+
+42
+43
+11
+
+
+311
+312
+11
+
+
+514
+515
+11
+
+
+715
+716
+11
+
+
+1585
+1586
+11
+
+
+6302
+6303
+11
+
+
+8160
+8161
+11
+
+
+11875
+11876
+11
+
+
+
+
+
+
+arg_value
+type_id
+
+
+12
+
+
+1
+2
+328387
+
+
+2
+4
+17059
+
+
+
+
+
+
+arg_value
+index
+
+
+12
+
+
+1
+2
+345447
@@ -24016,15 +24227,15 @@
is_proxy_class_for
-50120
+49017
id
-50120
+49017
templ_param_id
-50120
+49017
@@ -24038,7 +24249,7 @@
1
2
-50120
+49017
@@ -24054,7 +24265,7 @@
1
2
-50120
+49017
@@ -24064,19 +24275,19 @@
type_mentions
-1699359
+1682135
id
-1699359
+1682135
type_id
-68077
+67387
location
-1668455
+1651543
kind
@@ -24094,7 +24305,7 @@
1
2
-1699359
+1682135
@@ -24110,7 +24321,7 @@
1
2
-1699359
+1682135
@@ -24126,7 +24337,7 @@
1
2
-1699359
+1682135
@@ -24142,37 +24353,37 @@
1
2
-30463
+30154
2
3
-12463
+12337
3
4
-3684
+3646
4
7
-6142
+6080
7
13
-5213
+5160
13
35
-5259
+5206
35
9490
-4850
+4801
@@ -24188,37 +24399,37 @@
1
2
-30463
+30154
2
3
-12463
+12337
3
4
-3684
+3646
4
7
-6142
+6080
7
13
-5213
+5160
13
35
-5259
+5206
35
9490
-4850
+4801
@@ -24234,12 +24445,12 @@
1
2
-66818
+66141
2
3
-1258
+1246
@@ -24255,12 +24466,12 @@
1
2
-1637892
+1621291
2
5
-30562
+30252
@@ -24276,12 +24487,12 @@
1
2
-1637892
+1621291
2
5
-30562
+30252
@@ -24297,7 +24508,7 @@
1
2
-1668455
+1651543
@@ -24370,26 +24581,26 @@
is_function_template
-1058083
+1023581
id
-1058083
+1023581
function_instantiation
-739463
+719194
to
-739463
+719194
from
-136103
+134923
@@ -24403,7 +24614,7 @@
1
2
-739463
+719194
@@ -24419,37 +24630,32 @@
1
2
-63018
+64125
2
3
-32396
+31385
3
4
-8193
+7898
4
-5
-9299
+6
+12467
-5
-10
-10940
+6
+15
+10434
-10
-57
-10223
-
-
-58
+15
645
-2030
+8611
@@ -24459,19 +24665,19 @@
function_template_argument
-1910796
+1981225
function_id
-1112422
+1088560
index
-243
+233
arg_type
-369847
+359386
@@ -24485,22 +24691,22 @@
1
2
-634796
+600045
2
3
-361033
+302330
3
-5
-84645
+4
+131242
-5
+4
21
-31947
+54941
@@ -24516,22 +24722,22 @@
1
2
-657966
+618530
2
3
-332393
+293520
3
-5
-90905
+4
+116683
-5
+4
21
-31156
+59825
@@ -24547,102 +24753,102 @@
4
5
-12
+11
7
8
-12
+11
17
18
-12
+11
39
40
-12
+11
65
66
-12
+11
152
153
-12
+11
-238
-239
-12
+241
+242
+11
-325
-326
-12
+328
+329
+11
-422
-423
-12
+425
+426
+11
-520
-521
-12
+523
+524
+11
-754
-755
-12
+758
+759
+11
-1007
-1008
-12
+1011
+1012
+11
-1259
-1260
-12
+1520
+1521
+11
-1514
-1515
-12
+1701
+1702
+11
-2559
-2560
-12
+2566
+2567
+11
-2804
-2805
-12
+2917
+2918
+11
-4818
-4819
-12
+5686
+5687
+11
-13309
-13310
-12
+17602
+17603
+11
-40569
-40570
-12
+42858
+42859
+11
-84931
-84932
-12
+88286
+88287
+11
@@ -24658,102 +24864,102 @@
4
5
-12
+11
7
8
-12
+11
14
15
-12
+11
22
23
-12
+11
32
33
-12
+11
54
55
-12
+11
-57
-58
-12
+60
+61
+11
-61
-62
-12
+62
+63
+11
-75
-76
-12
+78
+79
+11
-90
-91
-12
+91
+92
+11
-137
-138
-12
+140
+141
+11
214
215
-12
+11
-238
-239
-12
+242
+243
+11
-316
-317
-12
+317
+318
+11
-517
-518
-12
+521
+522
+11
-695
-696
-12
+700
+701
+11
-1468
-1469
-12
+1491
+1492
+11
-3652
-3653
-12
+3698
+3699
+11
-8773
-8774
-12
+8798
+8799
+11
-17388
-17389
-12
+17653
+17654
+11
@@ -24769,27 +24975,27 @@
1
2
-249547
+242738
2
3
-48698
+46902
3
6
-29783
+28756
6
-19
-27996
+20
+27704
-19
-906
-13821
+20
+1989
+13285
@@ -24805,17 +25011,238 @@
1
2
-341230
+331740
2
5
-28129
+27131
5
-10
-486
+12
+514
+
+
+
+
+
+
+
+
+function_template_argument_value
+209892
+
+
+function_id
+113037
+
+
+index
+163
+
+
+arg_value
+181755
+
+
+
+
+function_id
+index
+
+
+12
+
+
+1
+2
+107207
+
+
+2
+14
+5830
+
+
+
+
+
+
+function_id
+arg_value
+
+
+12
+
+
+1
+2
+89610
+
+
+2
+3
+17106
+
+
+3
+113
+6321
+
+
+
+
+
+
+index
+function_id
+
+
+12
+
+
+3
+4
+70
+
+
+5
+6
+11
+
+
+6
+7
+11
+
+
+111
+112
+11
+
+
+441
+442
+11
+
+
+857
+858
+11
+
+
+2136
+2137
+11
+
+
+2428
+2429
+11
+
+
+4217
+4218
+11
+
+
+
+
+
+
+index
+arg_value
+
+
+12
+
+
+5
+6
+70
+
+
+7
+8
+11
+
+
+8
+9
+11
+
+
+157
+158
+11
+
+
+405
+406
+11
+
+
+973
+974
+11
+
+
+2523
+2524
+11
+
+
+4848
+4849
+11
+
+
+6604
+6605
+11
+
+
+
+
+
+
+arg_value
+function_id
+
+
+12
+
+
+1
+2
+153712
+
+
+2
+3
+27949
+
+
+3
+4
+93
+
+
+
+
+
+
+arg_value
+index
+
+
+12
+
+
+1
+2
+181755
@@ -24825,26 +25252,26 @@
is_variable_template
-19778
+19011
id
-19778
+19011
variable_instantiation
-31837
+38057
to
-31837
+38057
from
-6734
+6929
@@ -24858,7 +25285,7 @@
1
2
-31837
+38057
@@ -24874,37 +25301,37 @@
1
2
-2382
+2383
2
3
-2030
+2033
3
4
-449
+432
4
5
-692
+782
5
9
-534
+560
9
-29
-534
+21
+525
-42
-214
-109
+24
+286
+210
@@ -24914,11 +25341,11 @@
variable_template_argument
-5529
+5499
variable_id
-843
+848
index
@@ -24926,7 +25353,7 @@
arg_type
-4257
+4214
@@ -24940,12 +25367,12 @@
1
2
-692
+685
2
3
-112
+123
3
@@ -24966,12 +25393,12 @@
1
2
-369
+371
2
3
-125
+130
3
@@ -24981,12 +25408,12 @@
4
6
-72
+71
6
8
-72
+71
8
@@ -25025,13 +25452,13 @@
6
-9
-10
+10
+11
6
-17
-18
+20
+21
6
@@ -25066,8 +25493,8 @@
6
-137
-138
+139
+140
6
@@ -25089,17 +25516,17 @@
1
2
-3532
+3490
2
3
-481
+476
3
11
-243
+247
@@ -25115,12 +25542,148 @@
1
2
-4046
+3999
+
+
+2
+4
+215
+
+
+
+
+
+
+
+
+variable_template_argument_value
+137
+
+
+variable_id
+19
+
+
+index
+13
+
+
+arg_value
+137
+
+
+
+
+variable_id
+index
+
+
+12
+
+
+1
+2
+13
2
3
-210
+6
+
+
+
+
+
+
+variable_id
+arg_value
+
+
+12
+
+
+3
+4
+13
+
+
+15
+16
+6
+
+
+
+
+
+
+index
+variable_id
+
+
+12
+
+
+1
+2
+6
+
+
+3
+4
+6
+
+
+
+
+
+
+index
+arg_value
+
+
+12
+
+
+6
+7
+6
+
+
+15
+16
+6
+
+
+
+
+
+
+arg_value
+variable_id
+
+
+12
+
+
+1
+2
+137
+
+
+
+
+
+
+arg_value
+index
+
+
+12
+
+
+1
+2
+137
@@ -25130,15 +25693,15 @@
routinetypes
-444572
+436132
id
-444572
+436132
return_type
-184814
+178086
@@ -25152,7 +25715,7 @@
1
2
-444572
+436132
@@ -25168,22 +25731,22 @@
1
2
-148344
+142985
2
3
-21030
+20191
3
-18
-13943
+17
+13367
-18
-7709
-1495
+17
+8001
+1542
@@ -25193,19 +25756,19 @@
routinetypeargs
-741201
+726544
routine
-362760
+357377
index
-389
+373
type_id
-209394
+208724
@@ -25219,27 +25782,27 @@
1
2
-169412
+166448
2
3
-95355
+96574
3
4
-58144
+55888
4
6
-31351
+30298
6
33
-8497
+8167
@@ -25255,22 +25818,22 @@
1
2
-194831
+190916
2
3
-95853
+97018
3
4
-49707
+47778
4
22
-22367
+21663
@@ -25286,62 +25849,62 @@
1
2
-133
+128
2
7
-24
+23
10
16
-24
+23
19
33
-24
+23
52
74
-24
+23
93
115
-24
+23
139
199
-24
+23
269
364
-24
+23
473
700
-24
+23
1319
-3279
-24
+3293
+23
-8061
-15906
-24
+8075
+16341
+23
-29841
-29842
-12
+30585
+30586
+11
@@ -25357,62 +25920,62 @@
1
2
-133
+128
2
5
-24
+23
6
10
-24
+23
11
22
-24
+23
33
37
-24
+23
38
42
-24
+23
44
83
-24
+23
124
183
-24
+23
248
346
-24
+23
463
950
-24
+23
-2463
-5546
-24
+2464
+5642
+23
-12306
-12307
-12
+12850
+12851
+11
@@ -25428,27 +25991,27 @@
1
2
-123691
+124231
2
3
-40869
+41258
3
4
-13505
+13016
4
7
-17942
+17293
7
-1097
-13384
+1099
+12923
@@ -25464,17 +26027,17 @@
1
2
-156830
+158176
2
3
-41161
+39576
3
33
-11402
+10971
@@ -25484,19 +26047,19 @@
ptrtomembers
-12180
+13227
id
-12180
+13227
type_id
-10247
+10013
class_id
-5519
+6601
@@ -25510,7 +26073,7 @@
1
2
-12180
+13227
@@ -25526,7 +26089,7 @@
1
2
-12180
+13227
@@ -25542,12 +26105,12 @@
1
2
-9895
+9628
2
-65
-352
+100
+385
@@ -25563,12 +26126,12 @@
1
2
-9895
+9628
2
-65
-352
+100
+385
@@ -25584,22 +26147,22 @@
1
2
-4619
+5573
2
-7
-352
+3
+490
8
-9
-461
+17
+502
-16
+64
65
-85
+35
@@ -25615,22 +26178,22 @@
1
2
-4619
+5573
2
-7
-352
+3
+490
8
-9
-461
+17
+502
-16
+64
65
-85
+35
@@ -25640,15 +26203,15 @@
specifiers
-547
+525
id
-547
+525
str
-547
+525
@@ -25662,7 +26225,7 @@
1
2
-547
+525
@@ -25678,7 +26241,7 @@
1
2
-547
+525
@@ -25688,15 +26251,15 @@
typespecifiers
-1464874
+1479986
type_id
-1460193
+1472695
spec_id
-85
+81
@@ -25710,12 +26273,12 @@
1
2
-1455513
+1465403
2
3
-4680
+7291
@@ -25731,37 +26294,37 @@
102
103
-12
+11
222
223
-12
+11
518
519
-12
+11
-718
-719
-12
+957
+958
+11
2323
2324
-12
+11
-19328
-19329
-12
+20241
+20242
+11
-97291
-97292
-12
+102297
+102298
+11
@@ -25771,15 +26334,15 @@
funspecifiers
-11370456
+11412148
func_id
-3511992
+3500391
spec_id
-194
+186
@@ -25793,27 +26356,27 @@
1
2
-342616
+329999
2
3
-464083
+448167
3
4
-909155
+883458
4
5
-1670402
+1717910
5
8
-125733
+120855
@@ -25829,82 +26392,82 @@
22
23
-12
+11
169
170
-12
+11
491
492
-12
+11
-506
-507
-12
+598
+599
+11
632
633
-12
+11
5650
5651
-12
+11
9530
9531
-12
+11
10451
10452
-12
+11
-11821
-11822
-12
+11834
+11835
+11
14848
14849
-12
+11
-25330
-25331
-12
+26196
+26197
+11
-33532
-33533
-12
+33724
+33725
+11
-122462
-122463
-12
+131801
+131802
+11
-204591
-204592
-12
+214925
+214926
+11
-232301
-232302
-12
+242884
+242885
+11
-263009
-263010
-12
+272918
+272919
+11
@@ -25914,11 +26477,11 @@
varspecifiers
-1124158
+1113938
var_id
-935091
+926194
spec_id
@@ -25936,17 +26499,17 @@
1
2
-795258
+787198
2
3
-92279
+91911
3
5
-47553
+47084
@@ -25980,13 +26543,13 @@
6
-8409
-8410
+8411
+8412
6
-8751
-8752
+8753
+8754
6
@@ -25995,13 +26558,13 @@
6
-13352
-13353
+13439
+13440
6
-42323
-42324
+42412
+42413
6
@@ -26590,11 +27153,11 @@
attribute_args
-118319
+118389
id
-118319
+118389
kind
@@ -26602,7 +27165,7 @@
attribute
-116952
+117020
index
@@ -26610,7 +27173,7 @@
location
-58256
+58290
@@ -26624,7 +27187,7 @@
1
2
-118319
+118389
@@ -26640,7 +27203,7 @@
1
2
-118319
+118389
@@ -26656,7 +27219,7 @@
1
2
-118319
+118389
@@ -26672,7 +27235,7 @@
1
2
-118319
+118389
@@ -26772,12 +27335,12 @@
1
2
-116132
+116200
2
4
-819
+820
@@ -26793,7 +27356,7 @@
1
2
-116431
+116499
2
@@ -26814,12 +27377,12 @@
1
2
-116132
+116200
2
4
-819
+820
@@ -26835,7 +27398,7 @@
1
2
-116137
+116205
2
@@ -26955,22 +27518,22 @@
1
2
-28468
+28485
2
3
-7516
+7521
3
4
-19458
+19469
4
25
-2812
+2814
@@ -26986,12 +27549,12 @@
1
2
-52020
+52051
2
3
-6235
+6239
@@ -27007,22 +27570,22 @@
1
2
-28452
+28469
2
3
-7534
+7539
3
4
-19454
+19466
4
25
-2814
+2815
@@ -27038,7 +27601,7 @@
1
2
-58250
+58285
3
@@ -27053,15 +27616,15 @@
attribute_arg_value
-118292
+118362
arg
-118292
+118362
value
-2257
+2258
@@ -27075,7 +27638,7 @@
1
2
-118292
+118362
@@ -27091,7 +27654,7 @@
1
2
-1808
+1809
2
@@ -27116,15 +27679,15 @@
attribute_arg_type
-60
+58
arg
-60
+58
type_id
-36
+35
@@ -27138,7 +27701,7 @@
1
2
-60
+58
@@ -27154,12 +27717,12 @@
1
2
-12
+11
2
3
-24
+23
@@ -27222,15 +27785,15 @@
typeattributes
-12119
+12701
type_id
-10831
+11462
spec_id
-12119
+12701
@@ -27244,12 +27807,12 @@
1
2
-10296
+10948
2
34
-534
+514
@@ -27265,7 +27828,7 @@
1
2
-12119
+12701
@@ -27275,15 +27838,15 @@
funcattributes
-327044
+314529
func_id
-174943
+168330
spec_id
-327044
+314529
@@ -27297,22 +27860,22 @@
1
2
-94078
+90603
2
3
-13554
+13028
3
4
-65134
+62606
4
14
-2176
+2091
@@ -27328,7 +27891,7 @@
1
2
-327044
+314529
@@ -27444,15 +28007,15 @@
unspecifiedtype
-9406353
+9451546
type_id
-9406353
+9451546
unspecified_type_id
-5062897
+5133540
@@ -27466,7 +28029,7 @@
1
2
-9406353
+9451546
@@ -27482,22 +28045,17 @@
1
2
-2733810
+2776289
2
3
-1943594
+1978655
3
-30
-379779
-
-
-30
-7873
-5713
+7936
+378596
@@ -27507,19 +28065,19 @@
member
-5112192
+5066844
parent
-809800
+833190
index
-2966
+2851
child
-5095258
+5050544
@@ -27533,47 +28091,47 @@
1
2
-46948
+45126
2
3
-191658
+219789
3
4
-208336
+209109
4
5
-90285
+90638
5
7
-65073
+67210
7
9
-67212
+65539
9
15
-68221
+66497
15
-39
-62471
+45
+62758
-39
+45
245
-9591
+6520
@@ -27589,47 +28147,47 @@
1
2
-46218
+44425
2
3
-191719
+219824
3
4
-202769
+203723
4
5
-93154
+93454
5
7
-65766
+67876
7
9
-67346
+65668
9
15
-68999
+67245
15
-38
-61462
+41
+62641
-38
+41
281
-12363
+8331
@@ -27645,62 +28203,62 @@
1
2
-547
+525
2
5
-267
+257
5
9
-255
+245
9
18
-230
+222
23
100
-230
+222
122
186
-230
+222
188
293
-230
+222
296
374
-230
+222
375
542
-230
+222
572
3257
-230
+222
3427
-21556
-230
+22111
+222
-29162
-65993
-48
+30337
+70680
+46
@@ -27716,62 +28274,62 @@
1
2
-534
+514
2
5
-218
+210
5
7
-230
+222
7
13
-230
+222
13
70
-230
+222
71
160
-230
+222
160
256
-230
+222
263
345
-230
+222
346
476
-243
+233
492
1685
-230
+222
1926
-8765
-230
+8775
+222
-10213
-66838
-121
+10226
+71530
+116
@@ -27787,7 +28345,7 @@
1
2
-5095258
+5050544
@@ -27803,12 +28361,12 @@
1
2
-5078555
+5034466
2
7
-16702
+16078
@@ -27818,15 +28376,15 @@
enclosingfunction
-131751
+127164
child
-131751
+127164
parent
-74239
+71639
@@ -27840,7 +28398,7 @@
1
2
-131751
+127164
@@ -27856,27 +28414,27 @@
1
2
-39240
+37811
2
3
-21930
+21231
3
4
-7208
+6952
4
6
-5652
+5445
6
45
-206
+198
@@ -27886,27 +28444,27 @@
derivations
-370309
+392220
derivation
-370309
+392220
sub
-346555
+367484
index
-72
+70
super
-237840
+236475
location
-96351
+92613
@@ -27920,7 +28478,7 @@
1
2
-370309
+392220
@@ -27936,7 +28494,7 @@
1
2
-370309
+392220
@@ -27952,7 +28510,7 @@
1
2
-370309
+392220
@@ -27968,7 +28526,7 @@
1
2
-370309
+392220
@@ -27984,12 +28542,12 @@
1
2
-326108
+345926
2
7
-20447
+21558
@@ -28005,12 +28563,12 @@
1
2
-334933
+356161
2
7
-11621
+11322
@@ -28026,12 +28584,12 @@
1
2
-326120
+345937
2
7
-20434
+21546
@@ -28047,12 +28605,12 @@
1
2
-334921
+356150
2
7
-11633
+11334
@@ -28068,32 +28626,32 @@
1
2
-12
+11
4
5
-12
+11
44
45
-12
+11
220
221
-12
+11
-957
-958
-12
+970
+971
+11
-29236
-29237
-12
+32328
+32329
+11
@@ -28109,32 +28667,32 @@
1
2
-12
+11
4
5
-12
+11
44
45
-12
+11
220
221
-12
+11
-956
-957
-12
+969
+970
+11
-28508
-28509
-12
+31450
+31451
+11
@@ -28150,32 +28708,32 @@
1
2
-12
+11
3
4
-12
+11
29
30
-12
+11
84
85
-12
+11
-441
-442
-12
+452
+453
+11
-19051
-19052
-12
+19713
+19714
+11
@@ -28191,32 +28749,32 @@
1
2
-12
+11
4
5
-12
+11
17
18
-12
+11
51
52
-12
+11
254
255
-12
+11
7602
7603
-12
+11
@@ -28232,12 +28790,12 @@
1
2
-222438
+221343
2
-766
-15402
+1134
+15131
@@ -28253,12 +28811,12 @@
1
2
-222450
+221355
2
-766
-15390
+1134
+15120
@@ -28274,12 +28832,12 @@
1
2
-237342
+235996
2
4
-498
+479
@@ -28295,12 +28853,12 @@
1
2
-229780
+228634
2
439
-8059
+7840
@@ -28316,22 +28874,22 @@
1
2
-74652
+70786
2
3
-9336
+8985
3
8
-7306
+7606
8
-682
-5057
+698
+5234
@@ -28347,22 +28905,22 @@
1
2
-77193
+73146
2
3
-7002
+6858
3
-9
-7609
+8
+7443
-9
-682
-4546
+8
+698
+5164
@@ -28378,12 +28936,12 @@
1
2
-96327
+92589
2
4
-24
+23
@@ -28399,22 +28957,22 @@
1
2
-77655
+73882
2
3
-9056
+8833
3
-11
-7269
+10
+7326
-11
-682
-2370
+10
+698
+2570
@@ -28424,15 +28982,15 @@
derspecifiers
-372947
+394756
der_id
-370272
+392185
spec_id
-48
+46
@@ -28446,12 +29004,12 @@
1
2
-367598
+389615
2
3
-2674
+2570
@@ -28467,22 +29025,22 @@
220
221
-12
+11
242
243
-12
+11
979
980
-12
+11
-29238
-29239
-12
+32343
+32344
+11
@@ -28492,15 +29050,15 @@
direct_base_offsets
-282029
+307366
der_id
-282029
+307366
offset
-206
+210
@@ -28514,7 +29072,7 @@
1
2
-282029
+307366
@@ -28530,62 +29088,67 @@
1
2
-36
+46
2
3
-12
+11
4
5
-24
+23
5
6
-12
+11
6
7
-24
+11
7
8
-12
+23
8
9
-24
+11
+
+
+10
+11
+11
11
12
-12
+11
21
22
-12
+11
-78
-79
-12
+85
+86
+11
200
201
-12
+11
-22837
-22838
-12
+25931
+25932
+11
@@ -28595,19 +29158,19 @@
virtual_base_offsets
-7026
+6753
sub
-3890
+3739
super
-534
+514
offset
-267
+257
@@ -28621,22 +29184,22 @@
1
2
-3063
+2944
2
4
-340
+327
4
7
-279
+268
7
11
-206
+198
@@ -28652,17 +29215,17 @@
1
2
-3282
+3154
2
4
-328
+315
4
8
-279
+268
@@ -28678,52 +29241,52 @@
1
2
-85
+81
2
3
-48
+46
3
4
-60
+58
4
5
-97
+93
5
7
-36
+35
8
13
-48
+46
13
15
-48
+46
15
23
-48
+46
24
60
-48
+46
196
197
-12
+11
@@ -28739,32 +29302,32 @@
1
2
-303
+292
2
3
-85
+81
4
6
-36
+35
6
8
-48
+46
8
10
-48
+46
14
15
-12
+11
@@ -28780,57 +29343,57 @@
2
3
-36
+35
4
5
-12
+11
5
6
-24
+23
6
8
-24
+23
8
9
-36
+35
10
12
-24
+23
14
19
-24
+23
20
27
-24
+23
28
31
-24
+23
36
97
-24
+23
97
98
-12
+11
@@ -28846,37 +29409,37 @@
1
2
-85
+81
2
3
-36
+35
3
4
-48
+46
5
7
-24
+23
7
10
-24
+23
12
14
-24
+23
21
29
-24
+23
@@ -28886,23 +29449,23 @@
frienddecls
-231178
+222208
id
-231178
+222208
type_id
-19511
+18753
decl_id
-28810
+27692
location
-8096
+7782
@@ -28916,7 +29479,7 @@
1
2
-231178
+222208
@@ -28932,7 +29495,7 @@
1
2
-231178
+222208
@@ -28948,7 +29511,7 @@
1
2
-231178
+222208
@@ -28964,47 +29527,47 @@
1
2
-6856
+6590
2
3
-2467
+2371
3
4
-1191
+1145
4
6
-1714
+1647
6
10
-1556
+1495
10
16
-1470
+1413
16
34
-1786
+1717
36
59
-1470
+1413
59
129
-996
+958
@@ -29020,47 +29583,47 @@
1
2
-6856
+6590
2
3
-2467
+2371
3
4
-1191
+1145
4
6
-1714
+1647
6
10
-1556
+1495
10
16
-1470
+1413
16
34
-1786
+1717
36
59
-1470
+1413
59
129
-996
+958
@@ -29076,17 +29639,17 @@
1
2
-17748
+17059
2
5
-1543
+1483
5
31
-218
+210
@@ -29102,37 +29665,37 @@
1
2
-15815
+15201
2
3
-2261
+2173
3
5
-2479
+2383
5
9
-2188
+2103
9
20
-2030
+1951
20
28
-2467
+2371
28
390
-1568
+1507
@@ -29148,37 +29711,37 @@
1
2
-15815
+15201
2
3
-2261
+2173
3
5
-2479
+2383
5
9
-2188
+2103
9
20
-2030
+1951
20
28
-2467
+2371
28
390
-1568
+1507
@@ -29194,12 +29757,12 @@
1
2
-28215
+27120
2
46
-595
+572
@@ -29215,17 +29778,17 @@
1
2
-6917
+6648
2
3
-1045
+1004
3
18239
-133
+128
@@ -29241,12 +29804,12 @@
1
2
-7609
+7314
2
1215
-486
+467
@@ -29262,17 +29825,17 @@
1
2
-6929
+6660
2
3
-1033
+993
3
1734
-133
+128
@@ -29282,19 +29845,19 @@
comments
-1743633
+1675974
id
-1743633
+1675974
contents
-864492
+830947
location
-1743633
+1675974
@@ -29308,7 +29871,7 @@
1
2
-1743633
+1675974
@@ -29324,7 +29887,7 @@
1
2
-1743633
+1675974
@@ -29340,17 +29903,17 @@
1
2
-731525
+703139
2
3
-83149
+79923
3
10736
-49817
+47883
@@ -29366,17 +29929,17 @@
1
2
-731525
+703139
2
3
-83149
+79923
3
10736
-49817
+47883
@@ -29392,7 +29955,7 @@
1
2
-1743633
+1675974
@@ -29408,7 +29971,7 @@
1
2
-1743633
+1675974
@@ -29418,15 +29981,15 @@
commentbinding
-778436
+748230
id
-679021
+652673
element
-747438
+718434
@@ -29440,17 +30003,17 @@
1
2
-616002
+592099
2
4
-58545
+56273
4
97
-4473
+4299
@@ -29466,12 +30029,12 @@
1
2
-716439
+688638
2
3
-30998
+29796
@@ -29481,15 +30044,15 @@
exprconv
-6445331
+6446816
converted
-6445038
+6446523
conversion
-6445331
+6446816
@@ -29503,7 +30066,7 @@
1
2
-6444746
+6446231
2
@@ -29524,7 +30087,7 @@
1
2
-6445331
+6446816
@@ -29534,30 +30097,30 @@
compgenerated
-6720341
+6652484
id
-6720341
+6652484
synthetic_destructor_call
-59493
+57185
element
-47422
+45582
i
-340
+327
destructor_call
-49573
+47650
@@ -29571,17 +30134,17 @@
1
2
-38791
+37285
2
3
-6321
+6076
3
29
-2309
+2220
@@ -29597,17 +30160,17 @@
1
2
-38791
+37285
2
3
-6321
+6076
3
29
-2309
+2220
@@ -29623,27 +30186,27 @@
1
2
-255
+245
2
7
-24
+23
22
43
-24
+23
190
711
-24
+23
3901
3902
-12
+11
@@ -29659,27 +30222,27 @@
1
2
-255
+245
2
7
-24
+23
21
37
-24
+23
146
550
-24
+23
3297
3298
-12
+11
@@ -29695,17 +30258,17 @@
1
2
-43823
+42123
2
3
-3719
+3575
3
26
-2030
+1951
@@ -29721,7 +30284,7 @@
1
2
-49573
+47650
@@ -29731,15 +30294,15 @@
namespaces
-8497
+8167
id
-8497
+8167
name
-4570
+4393
@@ -29753,7 +30316,7 @@
1
2
-8497
+8167
@@ -29769,17 +30332,17 @@
1
2
-3841
+3692
2
3
-461
+444
3
139
-267
+257
@@ -29789,26 +30352,26 @@
namespace_inline
-170
+163
id
-170
+163
namespacembrs
-1570027
+1616300
parentid
-7913
+7606
memberid
-1570027
+1616300
@@ -29822,62 +30385,67 @@
1
2
-875
+829
2
3
-826
+794
3
4
-644
+385
4
-6
-680
-
-
-6
-9
+5
607
-9
-16
-680
+5
+8
+666
-16
-27
-607
+8
+14
+677
-27
-46
-619
-
-
-46
-85
-607
-
-
-85
-169
-607
-
-
-169
-444
+14
+22
595
-475
-29073
-559
+22
+42
+595
+
+
+42
+63
+572
+
+
+63
+127
+572
+
+
+127
+304
+572
+
+
+321
+1041
+572
+
+
+1101
+32701
+163
@@ -29893,7 +30461,7 @@
1
2
-1570027
+1616300
@@ -29903,19 +30471,19 @@
exprparents
-13615303
+13481241
expr_id
-13615112
+13481052
child_index
-3163
+3131
parent_id
-9644209
+9549204
@@ -29929,7 +30497,7 @@
1
2
-13615105
+13481045
2
@@ -29950,12 +30518,12 @@
1
2
-13614927
+13480869
2
4
-184
+182
@@ -29971,37 +30539,37 @@
1
2
-72
+71
2
3
-652
+645
3
4
-1674
+1657
4
46
-243
+241
46
56
-237
+234
56
3660
-237
+234
6434
-1187727
-46
+1188148
+45
@@ -30017,37 +30585,37 @@
1
2
-72
+71
2
3
-652
+645
3
4
-1674
+1657
4
31
-243
+241
31
41
-237
+234
41
3645
-237
+234
6419
-1187740
-46
+1188161
+45
@@ -30063,17 +30631,17 @@
1
2
-6840662
+6772879
2
3
-2212086
+2190858
3
1681
-591461
+585466
@@ -30089,17 +30657,17 @@
1
2
-6840682
+6772898
2
3
-2212066
+2190839
3
480
-591461
+585466
@@ -30109,22 +30677,22 @@
expr_isload
-5063114
+5014574
expr_id
-5063114
+5014574
conversionkinds
-4254113
+4255501
expr_id
-4254113
+4255501
kind
@@ -30142,7 +30710,7 @@
1
2
-4254113
+4255501
@@ -30166,8 +30734,8 @@
1
-13109
-13110
+13672
+13673
1
@@ -30181,8 +30749,8 @@
1
-4161592
-4161593
+4162417
+4162418
1
@@ -30193,15 +30761,15 @@
iscall
-2365240
+2284876
caller
-2365240
+2284876
kind
-36
+35
@@ -30215,7 +30783,7 @@
1
2
-2365240
+2284876
@@ -30231,17 +30799,17 @@
1319
1320
-12
+11
-5604
-5605
-12
+5643
+5644
+11
-187644
-187645
-12
+188582
+188583
+11
@@ -30251,15 +30819,15 @@
numtemplatearguments
-157948
+152181
expr_id
-157948
+152181
num
-48
+46
@@ -30273,7 +30841,7 @@
1
2
-157948
+152181
@@ -30289,22 +30857,22 @@
3
4
-12
+11
41
42
-12
+11
651
652
-12
+11
-12298
-12299
-12
+12329
+12330
+11
@@ -30314,15 +30882,15 @@
specialnamequalifyingelements
-12
+11
id
-12
+11
name
-12
+11
@@ -30336,7 +30904,7 @@
1
2
-12
+11
@@ -30352,7 +30920,7 @@
1
2
-12
+11
@@ -30362,23 +30930,23 @@
namequalifiers
-1125621
+1116919
id
-1125621
+1116919
qualifiableelement
-1125621
+1116919
qualifyingelement
-37001
+38961
location
-509589
+506087
@@ -30392,7 +30960,7 @@
1
2
-1125621
+1116919
@@ -30408,7 +30976,7 @@
1
2
-1125621
+1116919
@@ -30424,7 +30992,7 @@
1
2
-1125621
+1116919
@@ -30440,7 +31008,7 @@
1
2
-1125621
+1116919
@@ -30456,7 +31024,7 @@
1
2
-1125621
+1116919
@@ -30472,7 +31040,7 @@
1
2
-1125621
+1116919
@@ -30488,109 +31056,109 @@
1
2
-17109
+18965
2
3
-7935
+8142
3
4
-5081
-
-
-4
-10
-2860
-
-
-10
-86
-2781
-
-
-86
-24926
-1232
-
-
-
-
-
-
-qualifyingelement
-qualifiableelement
-
-
-12
-
-
-1
-2
-17109
-
-
-2
-3
-7935
-
-
-3
-4
-5081
-
-
-4
-10
-2860
-
-
-10
-86
-2781
-
-
-86
-24926
-1232
-
-
-
-
-
-
-qualifyingelement
-location
-
-
-12
-
-
-1
-2
-22745
-
-
-2
-3
-4817
-
-
-3
-4
-3802
+5043
4
11
-3018
+3027
+
+
+11
+129
+2935
+
+
+132
+24926
+848
+
+
+
+
+
+
+qualifyingelement
+qualifiableelement
+
+
+12
+
+
+1
+2
+18965
+
+
+2
+3
+8142
+
+
+3
+4
+5043
+
+
+4
+11
+3027
+
+
+11
+129
+2935
+
+
+132
+24926
+848
+
+
+
+
+
+
+qualifyingelement
+location
+
+
+12
+
+
+1
+2
+24850
+
+
+2
+3
+4762
+
+
+3
+4
+3770
+
+
+4
+11
+2974
11
16728
-2616
+2603
@@ -30606,22 +31174,22 @@
1
2
-387650
+384719
2
3
-57004
+56877
3
7
-39037
+38851
7
381
-25895
+25639
@@ -30637,22 +31205,22 @@
1
2
-387650
+384719
2
3
-57004
+56877
3
7
-39037
+38851
7
381
-25895
+25639
@@ -30668,17 +31236,17 @@
1
2
-452478
+449080
2
3
-44785
+44650
3
190
-12324
+12356
@@ -30688,15 +31256,15 @@
varbind
-5497554
+5445518
expr
-5497428
+5445394
var
-1549133
+1534266
@@ -30710,12 +31278,12 @@
1
2
-5497303
+5445270
2
3
-125
+123
@@ -30731,32 +31299,32 @@
1
2
-685882
+679661
2
3
-311295
+308179
3
4
-236831
+234430
4
5
-93953
+93020
5
9
-134777
+133430
9
6150
-86393
+85544
@@ -30766,15 +31334,15 @@
funbind
-2442767
+2419854
expr
-2142538
+2122577
fun
-438611
+434205
@@ -30788,17 +31356,17 @@
1
2
-1842553
+1825541
2
3
-299807
+296859
3
5
-177
+176
@@ -30814,32 +31382,32 @@
1
2
-255153
+252065
2
3
-76151
+75516
3
4
-31642
+31302
4
7
-33910
+33957
7
37
-33831
+33520
37
6664
-7922
+7841
@@ -30849,19 +31417,19 @@
expr_allocator
-27692
+26617
expr
-27692
+26617
func
-133
+128
form
-12
+11
@@ -30875,7 +31443,7 @@
1
2
-27692
+26617
@@ -30891,7 +31459,7 @@
1
2
-27692
+26617
@@ -30907,42 +31475,42 @@
1
2
-36
+35
3
4
-12
+11
4
5
-12
+11
5
6
-12
+11
7
8
-24
+23
39
40
-12
+11
973
974
-12
+11
1237
1238
-12
+11
@@ -30958,7 +31526,7 @@
1
2
-133
+128
@@ -30974,7 +31542,7 @@
2278
2279
-12
+11
@@ -30990,7 +31558,7 @@
11
12
-12
+11
@@ -31000,19 +31568,19 @@
expr_deallocator
-30998
+29796
expr
-30998
+29796
func
-145
+140
form
-24
+23
@@ -31026,7 +31594,7 @@
1
2
-30998
+29796
@@ -31042,7 +31610,7 @@
1
2
-30998
+29796
@@ -31058,42 +31626,42 @@
1
2
-36
+35
2
3
-24
+23
3
4
-12
+11
4
5
-12
+11
7
8
-24
+23
118
119
-12
+11
883
884
-12
+11
1521
1522
-12
+11
@@ -31109,7 +31677,7 @@
1
2
-145
+140
@@ -31125,12 +31693,12 @@
891
892
-12
+11
1659
1660
-12
+11
@@ -31146,12 +31714,12 @@
4
5
-12
+11
8
9
-12
+11
@@ -31161,26 +31729,26 @@
expr_cond_two_operand
-610
+611
cond
-610
+611
expr_cond_guard
-154429
+154519
cond
-154429
+154519
guard
-154429
+154519
@@ -31194,7 +31762,7 @@
1
2
-154429
+154519
@@ -31210,7 +31778,7 @@
1
2
-154429
+154519
@@ -31220,15 +31788,15 @@
expr_cond_true
-154429
+154519
cond
-154429
+154519
true
-154429
+154519
@@ -31242,7 +31810,7 @@
1
2
-154429
+154519
@@ -31258,7 +31826,7 @@
1
2
-154429
+154519
@@ -31268,15 +31836,15 @@
expr_cond_false
-154429
+154519
cond
-154429
+154519
false
-154429
+154519
@@ -31290,7 +31858,7 @@
1
2
-154429
+154519
@@ -31306,7 +31874,7 @@
1
2
-154429
+154519
@@ -31316,15 +31884,15 @@
values
-8776796
+8788031
id
-8776796
+8788031
str
-651390
+651491
@@ -31338,7 +31906,7 @@
1
2
-8776796
+8788031
@@ -31354,17 +31922,17 @@
1
2
-540103
+540120
2
3
-65463
+65472
3
-4044535
-45824
+4046841
+45899
@@ -31374,15 +31942,15 @@
valuetext
-4759381
+4766569
id
-4759381
+4766569
text
-704971
+705085
@@ -31396,7 +31964,7 @@
1
2
-4759381
+4766569
@@ -31412,22 +31980,22 @@
1
2
-528095
+528108
2
3
-102815
+102830
3
7
-56849
+56879
7
427516
-17212
+17268
@@ -31437,15 +32005,15 @@
valuebind
-9499071
+9509366
val
-8769631
+8779926
expr
-9499071
+9509366
@@ -31459,7 +32027,7 @@
1
2
-8040923
+8051218
2
@@ -31485,7 +32053,7 @@
1
2
-9499071
+9509366
@@ -31495,19 +32063,19 @@
fieldoffsets
-259539
+251575
id
-259539
+251575
byteoffset
-3914
+9022
bitoffset
-85
+52
@@ -31521,7 +32089,7 @@
1
2
-259539
+251575
@@ -31537,7 +32105,7 @@
1
2
-259539
+251575
@@ -31553,42 +32121,27 @@
1
2
-1689
+6132
2
3
-534
+782
3
-4
-194
-
-
-4
6
-340
+750
6
-11
-328
+17
+678
-11
-23
-328
-
-
-23
-84
-303
-
-
-90
-12369
-194
+17
+11685
+678
@@ -31604,12 +32157,12 @@
1
2
-3853
+8579
2
-8
-60
+9
+443
@@ -31623,29 +32176,44 @@
12
-1
-2
-36
+83
+84
+6
-2
-3
-12
+87
+88
+6
-3
-4
-12
+102
+103
+6
-4
-5
-12
+122
+123
+6
-21338
-21339
-12
+127
+128
+6
+
+
+153
+154
+6
+
+
+195
+196
+6
+
+
+37692
+37693
+6
@@ -31659,24 +32227,44 @@
12
-1
-2
-36
+40
+41
+6
-2
-3
-24
+44
+45
+6
-3
-4
-12
+45
+46
+6
-322
-323
-12
+52
+53
+6
+
+
+54
+55
+6
+
+
+58
+59
+6
+
+
+66
+67
+6
+
+
+1383
+1384
+6
@@ -31686,11 +32274,11 @@
bitfield
-13357
+13365
id
-13357
+13365
bits
@@ -31712,7 +32300,7 @@
1
2
-13357
+13365
@@ -31728,7 +32316,7 @@
1
2
-13357
+13365
@@ -31892,23 +32480,23 @@
initialisers
-1685017
+1668506
init
-1685017
+1668506
var
-649685
+643667
expr
-1685017
+1668506
location
-321906
+318643
@@ -31922,7 +32510,7 @@
1
2
-1685017
+1668506
@@ -31938,7 +32526,7 @@
1
2
-1685017
+1668506
@@ -31954,7 +32542,7 @@
1
2
-1685017
+1668506
@@ -31970,22 +32558,22 @@
1
2
-562000
+556871
2
16
-29079
+28784
16
17
-49688
+49185
17
53
-8917
+8827
@@ -32001,22 +32589,22 @@
1
2
-562000
+556871
2
16
-29079
+28784
16
17
-49688
+49185
17
53
-8917
+8827
@@ -32032,7 +32620,7 @@
1
2
-649672
+643654
2
@@ -32053,7 +32641,7 @@
1
2
-1685017
+1668506
@@ -32069,7 +32657,7 @@
1
2
-1685017
+1668506
@@ -32085,7 +32673,7 @@
1
2
-1685017
+1668506
@@ -32101,27 +32689,27 @@
1
2
-248450
+245906
2
3
-24096
+23845
3
7
-24485
+24243
7
65
-24346
+24126
67
109238
-527
+521
@@ -32137,22 +32725,22 @@
1
2
-271334
+268551
2
3
-25342
+25091
3
-24
-24155
+23
+23904
-24
+23
12632
-1074
+1096
@@ -32168,27 +32756,27 @@
1
2
-248450
+245906
2
3
-24096
+23845
3
7
-24485
+24243
7
65
-24346
+24126
67
109238
-527
+521
@@ -32198,15 +32786,15 @@
expr_ancestor
-67772
+68706
exp
-67176
+68133
ancestor
-49695
+51330
@@ -32220,12 +32808,12 @@
1
2
-66605
+67584
2
4
-571
+549
@@ -32241,17 +32829,17 @@
1
2
-37405
+39517
2
3
-10150
+9756
3
29
-2139
+2056
@@ -32261,19 +32849,19 @@
exprs
-18449753
+18460593
id
-18449753
+18460593
kind
-393
+1168
location
-6150603
+3836046
@@ -32287,7 +32875,7 @@
1
2
-18449753
+18460593
@@ -32303,7 +32891,7 @@
1
2
-18449753
+18460593
@@ -32317,69 +32905,69 @@
12
-5
-28
-30
+1
+14
+105
-71
-82
-30
+15
+44
+93
-94
-255
-30
+47
+86
+93
-271
-627
-30
+90
+223
+93
-858
-1879
-30
+296
+463
+93
-2191
-3716
-30
+483
+715
+93
-4305
-6068
-30
+788
+2129
+93
-7004
-11661
-30
+2165
+2950
+93
-12107
-20202
-30
+3030
+4378
+93
-21965
-29561
-30
+4477
+6077
+93
-32830
-41032
-30
+6490
+17249
+93
-44670
-145995
-30
+19347
+188353
+93
-447805
-725766
-24
+191022
+403956
+35
@@ -32394,68 +32982,68 @@
1
+4
+105
+
+
+6
+13
+105
+
+
+13
24
-30
+93
-27
-72
-30
+24
+38
+93
-77
-157
-30
+38
+134
+93
-171
-402
-30
+144
+259
+93
-422
-1083
-30
+269
+480
+93
-1179
-1862
-30
+481
+1074
+93
-2201
-4268
-30
+1095
+1411
+93
-4679
-6584
-30
+1422
+2045
+93
-6624
-11083
-30
+2059
+4557
+93
-11359
-12983
-30
+5888
+59687
+93
-17158
-28621
-30
-
-
-29980
-88945
-30
-
-
-128315
-425042
-24
+72153
+117893
+23
@@ -32471,22 +33059,37 @@
1
2
-4450587
+1838158
2
3
-874643
+753582
3
-6
-496205
+4
+356208
-6
-22445
-329167
+4
+5
+276250
+
+
+5
+9
+301489
+
+
+9
+72
+287759
+
+
+72
+136887
+22598
@@ -32502,22 +33105,17 @@
1
2
-4599301
+2734142
2
3
-812812
+859259
3
-5
-498909
-
-
-5
-33
-239579
+30
+242644
@@ -32527,19 +33125,19 @@
expr_types
-18617706
+18629051
id
-18444987
+18456012
typeid
-1372691
+1345343
value_category
-36
+35
@@ -32553,12 +33151,12 @@
1
2
-18272500
+18283254
2
4
-172487
+172758
@@ -32574,7 +33172,7 @@
1
2
-18444987
+18456012
@@ -32590,42 +33188,42 @@
1
2
-530591
+526443
2
3
-259102
+254107
3
4
-113553
+110864
4
5
-95427
+92110
5
8
-122925
+118483
8
14
-105736
+102381
14
-46
-103864
+47
+101797
-46
-111456
-41489
+47
+123210
+39155
@@ -32641,17 +33239,17 @@
1
2
-1207109
+1185928
2
3
-157753
+151877
3
4
-7828
+7536
@@ -32667,17 +33265,17 @@
4533
4534
-12
+11
-340895
-340896
-12
+342547
+342548
+11
-1171875
-1171876
-12
+1232420
+1232421
+11
@@ -32691,19 +33289,19 @@
12
-1340
-1341
-12
+1341
+1342
+11
-29733
-29734
-12
+29841
+29842
+11
-96111
-96112
-12
+98243
+98244
+11
@@ -32713,15 +33311,15 @@
new_allocated_type
-29527
+28382
expr
-29527
+28382
type_id
-18234
+17527
@@ -32735,7 +33333,7 @@
1
2
-29527
+28382
@@ -32751,22 +33349,22 @@
1
2
-12667
+12175
2
3
-4035
+3879
3
9
-1446
+1390
10
92
-85
+81
@@ -32776,15 +33374,15 @@
new_array_allocated_type
-5364
+5310
expr
-5364
+5310
type_id
-2306
+2283
@@ -32798,7 +33396,7 @@
1
2
-5364
+5310
@@ -32819,12 +33417,12 @@
2
3
-2043
+2022
3
7
-177
+176
8
@@ -33376,15 +33974,15 @@
condition_decl_bind
-7646
+7349
expr
-7646
+7349
decl
-7646
+7349
@@ -33398,7 +33996,7 @@
1
2
-7646
+7349
@@ -33414,7 +34012,7 @@
1
2
-7646
+7349
@@ -33424,15 +34022,15 @@
typeid_bind
-4899
+4708
expr
-4899
+4708
type_id
-2601
+2500
@@ -33446,7 +34044,7 @@
1
2
-4899
+4708
@@ -33462,22 +34060,22 @@
1
2
-1300
+1250
2
3
-996
+958
3
6
-230
+222
6
17
-72
+70
@@ -33487,15 +34085,15 @@
uuidof_bind
-856
+848
expr
-856
+848
type_id
-652
+645
@@ -33509,7 +34107,7 @@
1
2
-856
+848
@@ -33525,12 +34123,12 @@
1
2
-481
+476
2
3
-138
+137
3
@@ -33545,15 +34143,15 @@
sizeof_bind
-156997
+157089
expr
-156997
+157089
type_id
-2673
+2674
@@ -33567,7 +34165,7 @@
1
2
-156997
+157089
@@ -33583,7 +34181,7 @@
1
2
-1044
+1045
2
@@ -33681,11 +34279,11 @@
lambdas
-12641
+12513
expr
-12641
+12513
default_capture
@@ -33707,7 +34305,7 @@
1
2
-12641
+12513
@@ -33723,7 +34321,7 @@
1
2
-12641
+12513
@@ -33812,23 +34410,23 @@
lambda_capture
-21730
+21509
id
-21730
+21509
lambda
-10097
+9994
index
-112
+110
field
-21730
+21509
captured_by_reference
@@ -33840,7 +34438,7 @@
location
-14051
+13909
@@ -33854,7 +34452,7 @@
1
2
-21730
+21509
@@ -33870,7 +34468,7 @@
1
2
-21730
+21509
@@ -33886,7 +34484,7 @@
1
2
-21730
+21509
@@ -33902,7 +34500,7 @@
1
2
-21730
+21509
@@ -33918,7 +34516,7 @@
1
2
-21730
+21509
@@ -33934,7 +34532,7 @@
1
2
-21730
+21509
@@ -33950,27 +34548,27 @@
1
2
-5002
+4951
2
3
-2379
+2355
3
4
-1265
+1252
4
6
-922
+913
6
18
-527
+521
@@ -33986,27 +34584,27 @@
1
2
-5002
+4951
2
3
-2379
+2355
3
4
-1265
+1252
4
6
-922
+913
6
18
-527
+521
@@ -34022,27 +34620,27 @@
1
2
-5002
+4951
2
3
-2379
+2355
3
4
-1265
+1252
4
6
-922
+913
6
18
-527
+521
@@ -34058,12 +34656,12 @@
1
2
-9629
+9531
2
3
-467
+463
@@ -34079,7 +34677,7 @@
1
2
-10077
+9975
2
@@ -34100,27 +34698,27 @@
1
2
-5483
+5428
2
3
-2504
+2479
3
4
-1041
+1030
4
7
-823
+815
7
18
-243
+241
@@ -34429,7 +35027,7 @@
2
3
-85
+84
@@ -34450,7 +35048,7 @@
2
3
-46
+45
@@ -34562,7 +35160,7 @@
1
2
-21730
+21509
@@ -34578,7 +35176,7 @@
1
2
-21730
+21509
@@ -34594,7 +35192,7 @@
1
2
-21730
+21509
@@ -34610,7 +35208,7 @@
1
2
-21730
+21509
@@ -34626,7 +35224,7 @@
1
2
-21730
+21509
@@ -34642,7 +35240,7 @@
1
2
-21730
+21509
@@ -34900,17 +35498,17 @@
1
2
-12667
+12539
2
6
-1061
+1050
6
68
-322
+319
@@ -34926,12 +35524,12 @@
1
2
-13115
+12982
2
68
-935
+926
@@ -34947,12 +35545,12 @@
1
2
-13511
+13374
2
8
-540
+534
@@ -34968,17 +35566,17 @@
1
2
-12667
+12539
2
6
-1061
+1050
6
68
-322
+319
@@ -34994,7 +35592,7 @@
1
2
-14032
+13889
2
@@ -35015,7 +35613,7 @@
1
2
-14051
+13909
@@ -35141,19 +35739,19 @@
stmts
-4943740
+4765273
id
-4943740
+4765273
kind
-230
+222
location
-1317574
+1266448
@@ -35167,7 +35765,7 @@
1
2
-4943740
+4765273
@@ -35183,7 +35781,7 @@
1
2
-4943740
+4765273
@@ -35199,97 +35797,97 @@
2
3
-12
+11
28
29
-12
+11
338
339
-12
+11
473
474
-12
+11
690
691
-12
+11
1560
1561
-12
+11
1757
1758
-12
+11
-2076
-2077
-12
+2080
+2081
+11
-2191
-2192
-12
+2193
+2194
+11
2707
2708
-12
+11
2748
2749
-12
+11
-2944
-2945
-12
+2946
+2947
+11
3296
3297
-12
+11
4540
4541
-12
+11
-28688
-28689
-12
+28694
+28695
+11
-53254
-53255
-12
+53369
+53370
+11
-85878
-85879
-12
+86211
+86212
+11
-98483
-98484
-12
+98824
+98825
+11
-115024
-115025
-12
+115365
+115366
+11
@@ -35305,97 +35903,97 @@
2
3
-12
+11
23
24
-12
+11
106
107
-12
+11
112
113
-12
+11
178
179
-12
+11
252
253
-12
+11
296
297
-12
+11
661
662
-12
+11
663
664
-12
+11
991
992
-12
+11
1030
1031
-12
+11
1408
1409
-12
+11
1918
1919
-12
+11
2676
2677
-12
+11
10172
10173
-12
+11
10231
10232
-12
+11
22268
22269
-12
+11
26534
26535
-12
+11
31957
31958
-12
+11
@@ -35411,32 +36009,32 @@
1
2
-779628
+747015
2
3
-179173
+173050
3
4
-120275
+116169
4
6
-106891
+103199
6
19
-102794
+99168
19
-4895
-28810
+4923
+27844
@@ -35452,12 +36050,12 @@
1
2
-1291693
+1241571
2
9
-25881
+24876
@@ -35563,15 +36161,15 @@
if_then
-524558
+524866
if_stmt
-524558
+524866
then_id
-524558
+524866
@@ -35585,7 +36183,7 @@
1
2
-524558
+524866
@@ -35601,7 +36199,7 @@
1
2
-524558
+524866
@@ -35611,15 +36209,15 @@
if_else
-148234
+148322
if_stmt
-148234
+148322
else_id
-148234
+148322
@@ -35633,7 +36231,7 @@
1
2
-148234
+148322
@@ -35649,7 +36247,7 @@
1
2
-148234
+148322
@@ -35755,15 +36353,15 @@
while_body
-32907
+31630
while_stmt
-32907
+31630
body_id
-32907
+31630
@@ -35777,7 +36375,7 @@
1
2
-32907
+31630
@@ -35793,7 +36391,7 @@
1
2
-32907
+31630
@@ -35803,15 +36401,15 @@
do_body
-149900
+149988
do_stmt
-149900
+149988
body_id
-149900
+149988
@@ -35825,7 +36423,7 @@
1
2
-149900
+149988
@@ -35841,7 +36439,7 @@
1
2
-149900
+149988
@@ -35851,11 +36449,11 @@
switch_case
-281530
+281695
switch_stmt
-55225
+55258
index
@@ -35863,7 +36461,7 @@
case_id
-281530
+281695
@@ -35877,17 +36475,17 @@
1
5
-4288
+4290
5
6
-48725
+48753
6
156
-2212
+2213
@@ -35903,17 +36501,17 @@
1
5
-4288
+4290
5
6
-48725
+48753
6
156
-2212
+2213
@@ -36031,7 +36629,7 @@
1
2
-281530
+281695
@@ -36047,7 +36645,7 @@
1
2
-281530
+281695
@@ -36057,15 +36655,15 @@
switch_body
-55225
+55258
switch_stmt
-55225
+55258
body_id
-55225
+55258
@@ -36079,7 +36677,7 @@
1
2
-55225
+55258
@@ -36095,7 +36693,7 @@
1
2
-55225
+55258
@@ -36105,15 +36703,15 @@
for_initialization
-29922
+29619
for_stmt
-29922
+29619
init_id
-29922
+29619
@@ -36127,7 +36725,7 @@
1
2
-29922
+29619
@@ -36143,7 +36741,7 @@
1
2
-29922
+29619
@@ -36153,15 +36751,15 @@
for_condition
-31781
+31459
for_stmt
-31781
+31459
condition_id
-31781
+31459
@@ -36175,7 +36773,7 @@
1
2
-31781
+31459
@@ -36191,7 +36789,7 @@
1
2
-31781
+31459
@@ -36201,15 +36799,15 @@
for_update
-29659
+29358
for_stmt
-29659
+29358
update_id
-29659
+29358
@@ -36223,7 +36821,7 @@
1
2
-29659
+29358
@@ -36239,7 +36837,7 @@
1
2
-29659
+29358
@@ -36249,15 +36847,15 @@
for_body
-32387
+32059
for_stmt
-32387
+32059
body_id
-32387
+32059
@@ -36271,7 +36869,7 @@
1
2
-32387
+32059
@@ -36287,7 +36885,7 @@
1
2
-32387
+32059
@@ -36297,19 +36895,19 @@
stmtparents
-4168478
+4131960
id
-4168478
+4131960
index
-12799
+836
parent
-1762006
+1583254
@@ -36323,7 +36921,7 @@
1
2
-4168478
+4131960
@@ -36339,7 +36937,7 @@
1
2
-4168478
+4131960
@@ -36355,52 +36953,57 @@
1
2
-4020
+182
2
3
-1094
+149
3
-4
-520
+5
+41
-4
-5
-1496
+5
+7
+72
7
-8
-1047
+9
+68
-8
-12
-830
+9
+18
+63
-12
-29
-1127
+18
+39
+64
-29
-37
-909
+39
+111
+63
-37
-74
-975
+112
+836
+63
-74
-191996
-777
+920
+136298
+63
+
+
+254134
+706946
+5
@@ -36416,52 +37019,57 @@
1
2
-4020
+182
2
3
-1094
+149
3
-4
-520
+5
+41
-4
-5
-1496
+5
+7
+72
7
-8
-1047
+9
+68
-8
-12
-830
+9
+18
+63
-12
-29
-1127
+18
+39
+64
-29
-37
-909
+39
+111
+63
-37
-74
-975
+112
+836
+63
-74
-191996
-777
+920
+136298
+63
+
+
+254134
+706946
+5
@@ -36477,32 +37085,27 @@
1
2
-1004414
+841847
2
3
-386602
+376317
3
4
-109343
+145318
4
-6
-115439
+9
+119501
-6
-17
-133386
-
-
-17
-1943
-12819
+9
+465
+100269
@@ -36518,32 +37121,27 @@
1
2
-1004414
+841847
2
3
-386602
+376317
3
4
-109343
+145318
4
-6
-115439
+9
+119501
-6
-17
-133386
-
-
-17
-1943
-12819
+9
+465
+100269
@@ -36553,26 +37151,26 @@
ishandler
-21888
+21666
block
-21888
+21666
successors
-17214104
+17224218
from
-16042874
+16052300
to
-16040997
+16050421
@@ -36586,12 +37184,12 @@
1
2
-15044821
+15053661
2
156
-998052
+998638
@@ -36607,12 +37205,12 @@
1
2
-15328885
+15337891
2
419
-712111
+712530
@@ -36622,15 +37220,15 @@
truecond
-966805
+967373
from
-966805
+967373
to
-937112
+937663
@@ -36644,7 +37242,7 @@
1
2
-966805
+967373
@@ -36660,12 +37258,12 @@
1
2
-913540
+914077
2
21
-23572
+23585
@@ -36675,15 +37273,15 @@
falsecond
-966805
+967373
from
-966805
+967373
to
-812105
+812583
@@ -36697,7 +37295,7 @@
1
2
-966805
+967373
@@ -36713,17 +37311,17 @@
1
2
-698749
+699160
2
3
-87006
+87057
3
25
-26349
+26365
@@ -36733,11 +37331,11 @@
stmt_decl_bind
-538233
+532777
stmt
-531279
+525894
num
@@ -36745,7 +37343,7 @@
decl
-538233
+532777
@@ -36759,12 +37357,12 @@
1
2
-525776
+520447
2
9
-5503
+5447
@@ -36780,12 +37378,12 @@
1
2
-525756
+520427
2
9
-5523
+5467
@@ -36903,7 +37501,7 @@
1
2
-538233
+532777
@@ -36919,7 +37517,7 @@
1
2
-538233
+532777
@@ -36929,19 +37527,19 @@
stmt_decl_entry_bind
-519726
+520031
stmt
-474524
+474803
num
-491
+492
decl_entry
-495657
+495948
@@ -36955,12 +37553,12 @@
1
2
-441842
+442101
2
274
-32682
+32702
@@ -36976,12 +37574,12 @@
1
2
-441842
+442101
2
15
-32682
+32702
@@ -37064,12 +37662,12 @@
1
2
-483634
+483918
2
85
-12022
+12029
@@ -37085,7 +37683,7 @@
1
2
-495588
+495879
2
@@ -37100,15 +37698,15 @@
blockscope
-1398256
+1347984
block
-1398256
+1347984
enclosing
-1254288
+1209602
@@ -37122,7 +37720,7 @@
1
2
-1398256
+1347984
@@ -37138,12 +37736,12 @@
1
2
-1171636
+1130157
2
509
-82651
+79444
@@ -37153,19 +37751,19 @@
jumpinfo
-366503
+366719
id
-366503
+366719
str
-6361
+6365
target
-85508
+85558
@@ -37179,7 +37777,7 @@
1
2
-366503
+366719
@@ -37195,7 +37793,7 @@
1
2
-366503
+366719
@@ -37216,12 +37814,12 @@
2
3
-3507
+3509
3
4
-835
+836
4
@@ -37231,12 +37829,12 @@
5
7
-491
+492
7
15
-500
+501
15
@@ -37257,12 +37855,12 @@
1
2
-5095
+5098
2
3
-700
+701
3
@@ -37293,32 +37891,32 @@
2
3
-21251
+21263
3
4
-7559
+7564
4
5
-3816
+3818
5
6
-39695
+39718
6
7
-11019
+11025
7
162
-1880
+1882
@@ -37334,7 +37932,7 @@
1
2
-85508
+85558
@@ -37344,19 +37942,19 @@
preprocdirects
-1456121
+1399618
id
-1456121
+1399618
kind
-158
+151
location
-1449131
+1392900
@@ -37370,7 +37968,7 @@
1
2
-1456121
+1399618
@@ -37386,7 +37984,7 @@
1
2
-1456121
+1399618
@@ -37402,67 +38000,67 @@
4
5
-12
+11
8
9
-12
+11
500
501
-12
+11
929
930
-12
+11
1740
1741
-12
+11
1873
1874
-12
+11
5235
5236
-12
+11
5497
5498
-12
+11
7551
7552
-12
+11
14073
14074
-12
+11
26464
26465
-12
+11
27121
27122
-12
+11
28787
28788
-12
+11
@@ -37478,67 +38076,67 @@
4
5
-12
+11
7
8
-12
+11
500
501
-12
+11
929
930
-12
+11
1740
1741
-12
+11
1873
1874
-12
+11
5235
5236
-12
+11
5497
5498
-12
+11
7551
7552
-12
+11
14073
14074
-12
+11
26122
26123
-12
+11
27121
27122
-12
+11
28555
28556
-12
+11
@@ -37554,12 +38152,12 @@
1
2
-1448766
+1392549
2
234
-364
+350
@@ -37575,7 +38173,7 @@
1
2
-1449131
+1392900
@@ -37585,15 +38183,15 @@
preprocpair
-416102
+399956
begin
-329694
+316901
elseelifend
-416102
+399956
@@ -37607,17 +38205,17 @@
1
2
-261399
+251256
2
3
-60247
+57909
3
53
-8047
+7735
@@ -37633,7 +38231,7 @@
1
2
-416102
+399956
@@ -37643,41 +38241,41 @@
preproctrue
-183112
+176006
branch
-183112
+176006
preprocfalse
-130000
+124956
branch
-130000
+124956
preproctext
-1062775
+1021536
id
-1062775
+1021536
head
-510083
+490290
body
-192959
+185471
@@ -37691,7 +38289,7 @@
1
2
-1062775
+1021536
@@ -37707,7 +38305,7 @@
1
2
-1062775
+1021536
@@ -37723,22 +38321,22 @@
1
2
-380459
+365696
2
3
-86116
+82774
3
19
-38414
+36923
19
752
-5093
+4895
@@ -37754,12 +38352,12 @@
1
2
-486208
+467341
2
38
-23875
+22948
@@ -37775,12 +38373,12 @@
1
2
-181252
+174219
2
64395
-11706
+11252
@@ -37796,12 +38394,12 @@
1
2
-182893
+175796
2
21671
-10065
+9674
@@ -37811,15 +38409,15 @@
includes
-321805
+309317
id
-321805
+309317
included
-60162
+57827
@@ -37833,7 +38431,7 @@
1
2
-321805
+309317
@@ -37849,37 +38447,37 @@
1
2
-29503
+28358
2
3
-9895
+9511
3
4
-5117
+4919
4
6
-5348
+5141
6
11
-4643
+4463
11
41
-4558
+4381
41
763
-1094
+1051
@@ -37889,15 +38487,15 @@
link_targets
-644
+619
id
-644
+619
binary
-644
+619
@@ -37911,7 +38509,7 @@
1
2
-644
+619
@@ -37927,7 +38525,7 @@
1
2
-644
+619
@@ -37937,15 +38535,15 @@
link_parent
-19143690
+19072521
element
-5076549
+5117392
link_target
-644
+619
@@ -37959,32 +38557,32 @@
1
2
-1439430
+1455425
2
3
-1904730
+1924496
3
4
-772395
+779113
4
6
-426167
+434215
6
-27
-383109
+28
+394382
-27
+28
45
-150715
+129758
@@ -38000,67 +38598,67 @@
2
3
-97
+93
5
557
-48
+46
-2555
-5912
-48
+2662
+6059
+46
-6322
-8240
-48
+6479
+8402
+46
-9873
-12705
-48
+10060
+12929
+46
-12726
-19568
-48
+13044
+20082
+46
-24613
-26319
-48
+24978
+26985
+46
-26410
-31881
-48
+27088
+32537
+46
-32502
-37729
-48
+33104
+38465
+46
-39858
-40615
-48
+41123
+42511
+46
-43096
-52498
-48
+44410
+55889
+46
-53361
-126529
-48
+55937
+132605
+46
-345660
-345661
-12
+362472
+362473
+11
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/BarrierGuard.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/BarrierGuard.cpp
new file mode 100644
index 00000000000..9c3c8bc4569
--- /dev/null
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/BarrierGuard.cpp
@@ -0,0 +1,68 @@
+int source();
+void sink(int);
+bool guarded(int);
+
+void bg_basic(int source) {
+ if (guarded(source)) {
+ sink(source); // no flow
+ } else {
+ sink(source); // flow
+ }
+}
+
+void bg_not(int source) {
+ if (!guarded(source)) {
+ sink(source); // flow
+ } else {
+ sink(source); // no flow
+ }
+}
+
+void bg_and(int source, bool arbitrary) {
+ if (guarded(source) && arbitrary) {
+ sink(source); // no flow
+ } else {
+ sink(source); // flow
+ }
+}
+
+void bg_or(int source, bool arbitrary) {
+ if (guarded(source) || arbitrary) {
+ sink(source); // flow
+ } else {
+ sink(source); // flow
+ }
+}
+
+void bg_return(int source) {
+ if (!guarded(source)) {
+ return;
+ }
+ sink(source); // no flow
+}
+
+struct XY {
+ int x, y;
+};
+
+void bg_stackstruct(XY s1, XY s2) {
+ s1.x = source();
+ if (guarded(s1.x)) {
+ sink(s1.x); // no flow
+ } else if (guarded(s1.y)) {
+ sink(s1.x); // flow
+ } else if (guarded(s2.y)) {
+ sink(s1.x); // flow
+ }
+}
+
+void bg_structptr(XY *p1, XY *p2) {
+ p1->x = source();
+ if (guarded(p1->x)) {
+ sink(p1->x); // no flow [FALSE POSITIVE in AST]
+ } else if (guarded(p1->y)) {
+ sink(p1->x); // flow [NOT DETECTED in IR]
+ } else if (guarded(p2->x)) {
+ sink(p1->x); // flow [NOT DETECTED in IR]
+ }
+}
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/DataflowTestCommon.qll b/cpp/ql/test/library-tests/dataflow/dataflow-tests/DataflowTestCommon.qll
index 02ee4d45380..a81394640ee 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/DataflowTestCommon.qll
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/DataflowTestCommon.qll
@@ -1,6 +1,20 @@
import cpp
import semmle.code.cpp.dataflow.DataFlow
+/**
+ * A `BarrierGuard` that stops flow to all occurrences of `x` within statement
+ * S in `if (guarded(x)) S`.
+ */
+// This is tested in `BarrierGuard.cpp`.
+class TestBarrierGuard extends DataFlow::BarrierGuard {
+ TestBarrierGuard() { this.(FunctionCall).getTarget().getName() = "guarded" }
+
+ override predicate checks(Expr checked, boolean isTrue) {
+ checked = this.(FunctionCall).getArgument(0) and
+ isTrue = true
+ }
+}
+
/** Common data flow configuration to be used by tests. */
class TestAllocationConfig extends DataFlow::Configuration {
TestAllocationConfig() { this = "TestAllocationConfig" }
@@ -26,4 +40,6 @@ class TestAllocationConfig extends DataFlow::Configuration {
override predicate isBarrier(DataFlow::Node barrier) {
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier")
}
+
+ override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard }
}
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/IRDataflowTestCommon.qll b/cpp/ql/test/library-tests/dataflow/dataflow-tests/IRDataflowTestCommon.qll
index eb5fa14e2e0..490f7e4290a 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/IRDataflowTestCommon.qll
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/IRDataflowTestCommon.qll
@@ -1,5 +1,20 @@
import cpp
import semmle.code.cpp.ir.dataflow.DataFlow
+import semmle.code.cpp.ir.IR
+
+/**
+ * A `BarrierGuard` that stops flow to all occurrences of `x` within statement
+ * S in `if (guarded(x)) S`.
+ */
+// This is tested in `BarrierGuard.cpp`.
+class TestBarrierGuard extends DataFlow::BarrierGuard {
+ TestBarrierGuard() { this.(CallInstruction).getStaticCallTarget().getName() = "guarded" }
+
+ override predicate checks(Instruction checked, boolean isTrue) {
+ checked = this.(CallInstruction).getPositionalArgument(0) and
+ isTrue = true
+ }
+}
/** Common data flow configuration to be used by tests. */
class TestAllocationConfig extends DataFlow::Configuration {
@@ -24,4 +39,6 @@ class TestAllocationConfig extends DataFlow::Configuration {
override predicate isBarrier(DataFlow::Node barrier) {
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier")
}
+
+ override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard }
}
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp
new file mode 100644
index 00000000000..5e4f2f97f46
--- /dev/null
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp
@@ -0,0 +1,46 @@
+int source();
+void sink(int);
+
+// This class has the opposite behavior of what the member function names suggest.
+struct Top {
+ virtual int isSource1() { return 0; }
+ virtual int isSource2() { return 0; }
+ virtual void isSink(int x) { }
+ virtual int notSource1() { return source(); }
+ virtual int notSource2() { return source(); }
+ virtual void notSink(int x) { sink(x); }
+};
+
+// This class has the correct behavior for just the functions ending in 2.
+struct Middle : Top {
+ int isSource2() override { return source(); }
+ int notSource2() override { return 0; }
+};
+
+// This class has all the behavior suggested by the function names.
+struct Bottom : Middle {
+ int isSource1() override { return source(); }
+ void isSink(int x) override { sink(x); }
+ int notSource1() override { return 0; }
+ void notSink(int x) override { }
+};
+
+void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) {
+ Top *topPtr = bottomPtr, &topRef = bottomRef;
+
+ sink(topPtr->isSource1()); // flow [NOT DETECTED by AST]
+ sink(topPtr->isSource2()); // flow [NOT DETECTED by AST]
+ topPtr->isSink(source()); // flow [NOT DETECTED by AST]
+
+ sink(topPtr->notSource1()); // no flow [FALSE POSITIVE]
+ sink(topPtr->notSource2()); // no flow [FALSE POSITIVE]
+ topPtr->notSink(source()); // no flow [FALSE POSITIVE]
+
+ sink(topRef.isSource1()); // flow [NOT DETECTED by AST]
+ sink(topRef.isSource2()); // flow [NOT DETECTED by AST]
+ topRef.isSink(source()); // flow [NOT DETECTED by AST]
+
+ sink(topRef.notSource1()); // no flow [FALSE POSITIVE]
+ sink(topRef.notSource2()); // no flow [FALSE POSITIVE]
+ topRef.notSink(source()); // no flow [FALSE POSITIVE]
+}
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected
index b9fca1f678f..24fa6fdb5bd 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected
@@ -1,3 +1,13 @@
+| BarrierGuard.cpp:9:10:9:15 | source | BarrierGuard.cpp:5:19:5:24 | source |
+| BarrierGuard.cpp:15:10:15:15 | source | BarrierGuard.cpp:13:17:13:22 | source |
+| BarrierGuard.cpp:25:10:25:15 | source | BarrierGuard.cpp:21:17:21:22 | source |
+| BarrierGuard.cpp:31:10:31:15 | source | BarrierGuard.cpp:29:16:29:21 | source |
+| BarrierGuard.cpp:33:10:33:15 | source | BarrierGuard.cpp:29:16:29:21 | source |
+| BarrierGuard.cpp:53:13:53:13 | x | BarrierGuard.cpp:49:10:49:15 | call to source |
+| BarrierGuard.cpp:55:13:55:13 | x | BarrierGuard.cpp:49:10:49:15 | call to source |
+| BarrierGuard.cpp:62:14:62:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source |
+| BarrierGuard.cpp:64:14:64:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source |
+| BarrierGuard.cpp:66:14:66:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source |
| acrossLinkTargets.cpp:12:8:12:8 | x | acrossLinkTargets.cpp:19:27:19:32 | call to source |
| clang.cpp:18:8:18:19 | sourceArray1 | clang.cpp:12:9:12:20 | sourceArray1 |
| clang.cpp:22:8:22:20 | & ... | clang.cpp:12:9:12:20 | sourceArray1 |
@@ -5,6 +15,12 @@
| clang.cpp:30:27:30:34 | call to getFirst | clang.cpp:28:27:28:32 | call to source |
| clang.cpp:37:10:37:11 | m2 | clang.cpp:34:32:34:37 | call to source |
| clang.cpp:45:17:45:18 | m2 | clang.cpp:43:35:43:40 | call to source |
+| dispatch.cpp:11:38:11:38 | x | dispatch.cpp:37:19:37:24 | call to source |
+| dispatch.cpp:11:38:11:38 | x | dispatch.cpp:45:18:45:23 | call to source |
+| dispatch.cpp:35:16:35:25 | call to notSource1 | dispatch.cpp:9:37:9:42 | call to source |
+| dispatch.cpp:36:16:36:25 | call to notSource2 | dispatch.cpp:10:37:10:42 | call to source |
+| dispatch.cpp:43:15:43:24 | call to notSource1 | dispatch.cpp:9:37:9:42 | call to source |
+| dispatch.cpp:44:15:44:24 | call to notSource2 | dispatch.cpp:10:37:10:42 | call to source |
| lambdas.cpp:14:3:14:6 | t | lambdas.cpp:8:10:8:15 | call to source |
| lambdas.cpp:18:8:18:8 | call to operator() | lambdas.cpp:8:10:8:15 | call to source |
| lambdas.cpp:21:3:21:6 | t | lambdas.cpp:8:10:8:15 | call to source |
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_diff.expected
index 0af544675d7..d0961962f29 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_diff.expected
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_diff.expected
@@ -1,8 +1,17 @@
+| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:62:14:62:14 | AST only |
+| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:64:14:64:14 | AST only |
+| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:66:14:66:14 | AST only |
| clang.cpp:12:9:12:20 | clang.cpp:18:8:18:19 | AST only |
| clang.cpp:12:9:12:20 | clang.cpp:22:8:22:20 | AST only |
| clang.cpp:28:27:28:32 | clang.cpp:29:27:29:28 | AST only |
| clang.cpp:28:27:28:32 | clang.cpp:30:27:30:34 | AST only |
| clang.cpp:39:42:39:47 | clang.cpp:41:18:41:19 | IR only |
+| dispatch.cpp:16:37:16:42 | dispatch.cpp:32:16:32:24 | IR only |
+| dispatch.cpp:16:37:16:42 | dispatch.cpp:40:15:40:23 | IR only |
+| dispatch.cpp:22:37:22:42 | dispatch.cpp:31:16:31:24 | IR only |
+| dispatch.cpp:22:37:22:42 | dispatch.cpp:39:15:39:23 | IR only |
+| dispatch.cpp:33:18:33:23 | dispatch.cpp:23:38:23:38 | IR only |
+| dispatch.cpp:41:17:41:22 | dispatch.cpp:23:38:23:38 | IR only |
| lambdas.cpp:8:10:8:15 | lambdas.cpp:14:3:14:6 | AST only |
| lambdas.cpp:8:10:8:15 | lambdas.cpp:18:8:18:8 | AST only |
| lambdas.cpp:8:10:8:15 | lambdas.cpp:21:3:21:6 | AST only |
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_ir.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_ir.expected
index ec1fc39b04e..2e97f6812f4 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_ir.expected
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_ir.expected
@@ -1,8 +1,27 @@
+| BarrierGuard.cpp:9:10:9:15 | Load: source | BarrierGuard.cpp:5:19:5:24 | InitializeParameter: source |
+| BarrierGuard.cpp:15:10:15:15 | Load: source | BarrierGuard.cpp:13:17:13:22 | InitializeParameter: source |
+| BarrierGuard.cpp:25:10:25:15 | Load: source | BarrierGuard.cpp:21:17:21:22 | InitializeParameter: source |
+| BarrierGuard.cpp:31:10:31:15 | Load: source | BarrierGuard.cpp:29:16:29:21 | InitializeParameter: source |
+| BarrierGuard.cpp:33:10:33:15 | Load: source | BarrierGuard.cpp:29:16:29:21 | InitializeParameter: source |
+| BarrierGuard.cpp:53:13:53:13 | Load: x | BarrierGuard.cpp:49:10:49:15 | Call: call to source |
+| BarrierGuard.cpp:55:13:55:13 | Load: x | BarrierGuard.cpp:49:10:49:15 | Call: call to source |
| acrossLinkTargets.cpp:12:8:12:8 | Convert: (int)... | acrossLinkTargets.cpp:19:27:19:32 | Call: call to source |
| acrossLinkTargets.cpp:12:8:12:8 | Load: x | acrossLinkTargets.cpp:19:27:19:32 | Call: call to source |
| clang.cpp:37:10:37:11 | Load: m2 | clang.cpp:34:32:34:37 | Call: call to source |
| clang.cpp:41:18:41:19 | Load: m2 | clang.cpp:39:42:39:47 | Call: call to source |
| clang.cpp:45:17:45:18 | Load: m2 | clang.cpp:43:35:43:40 | Call: call to source |
+| dispatch.cpp:11:38:11:38 | Load: x | dispatch.cpp:37:19:37:24 | Call: call to source |
+| dispatch.cpp:11:38:11:38 | Load: x | dispatch.cpp:45:18:45:23 | Call: call to source |
+| dispatch.cpp:23:38:23:38 | Load: x | dispatch.cpp:33:18:33:23 | Call: call to source |
+| dispatch.cpp:23:38:23:38 | Load: x | dispatch.cpp:41:17:41:22 | Call: call to source |
+| dispatch.cpp:31:16:31:24 | Call: call to isSource1 | dispatch.cpp:22:37:22:42 | Call: call to source |
+| dispatch.cpp:32:16:32:24 | Call: call to isSource2 | dispatch.cpp:16:37:16:42 | Call: call to source |
+| dispatch.cpp:35:16:35:25 | Call: call to notSource1 | dispatch.cpp:9:37:9:42 | Call: call to source |
+| dispatch.cpp:36:16:36:25 | Call: call to notSource2 | dispatch.cpp:10:37:10:42 | Call: call to source |
+| dispatch.cpp:39:15:39:23 | Call: call to isSource1 | dispatch.cpp:22:37:22:42 | Call: call to source |
+| dispatch.cpp:40:15:40:23 | Call: call to isSource2 | dispatch.cpp:16:37:16:42 | Call: call to source |
+| dispatch.cpp:43:15:43:24 | Call: call to notSource1 | dispatch.cpp:9:37:9:42 | Call: call to source |
+| dispatch.cpp:44:15:44:24 | Call: call to notSource2 | dispatch.cpp:10:37:10:42 | Call: call to source |
| test.cpp:7:8:7:9 | Load: t1 | test.cpp:6:12:6:17 | Call: call to source |
| test.cpp:9:8:9:9 | Load: t1 | test.cpp:6:12:6:17 | Call: call to source |
| test.cpp:10:8:10:9 | Load: t2 | test.cpp:6:12:6:17 | Call: call to source |
diff --git a/cpp/ql/test/library-tests/ir/escape/points_to.expected b/cpp/ql/test/library-tests/ir/escape/points_to.expected
index f40460f4d91..ac518b5dd79 100644
--- a/cpp/ql/test/library-tests/ir/escape/points_to.expected
+++ b/cpp/ql/test/library-tests/ir/escape/points_to.expected
@@ -1,6 +1,16 @@
+| escape.cpp:111:18:111:21 | CopyValue | no_+0:0 | no_+0:0 |
| escape.cpp:115:19:115:28 | PointerAdd[4] | no_+0:0 | no_+0:0 |
+| escape.cpp:115:20:115:23 | CopyValue | no_+0:0 | no_+0:0 |
| escape.cpp:116:19:116:28 | PointerSub[4] | no_+0:0 | no_+0:0 |
+| escape.cpp:116:20:116:23 | CopyValue | no_+0:0 | no_+0:0 |
| escape.cpp:117:19:117:26 | PointerAdd[4] | no_+0:0 | no_+0:0 |
+| escape.cpp:117:23:117:26 | CopyValue | no_+0:0 | no_+0:0 |
+| escape.cpp:118:9:118:12 | CopyValue | no_+0:0 | no_+0:0 |
+| escape.cpp:120:12:120:15 | CopyValue | no_+0:0 | no_+0:0 |
+| escape.cpp:123:14:123:17 | CopyValue | no_+0:0 | no_+0:0 |
+| escape.cpp:124:15:124:18 | CopyValue | no_+0:0 | no_+0:0 |
+| escape.cpp:127:9:127:12 | CopyValue | no_+0:0 | no_+0:0 |
+| escape.cpp:129:12:129:15 | CopyValue | no_+0:0 | no_+0:0 |
| escape.cpp:134:5:134:18 | Convert | no_Array+0:0 | no_Array+0:0 |
| escape.cpp:134:11:134:18 | Convert | no_Array+0:0 | no_Array+0:0 |
| escape.cpp:135:5:135:12 | Convert | no_Array+0:0 | no_Array+0:0 |
@@ -16,32 +26,61 @@
| escape.cpp:140:21:140:32 | FieldAddress[z] | no_Point+8:0 | no_Point+8:0 |
| escape.cpp:141:27:141:27 | FieldAddress[x] | no_Point+0:0 | no_Point+0:0 |
| escape.cpp:142:14:142:14 | FieldAddress[y] | no_Point+4:0 | no_Point+4:0 |
+| escape.cpp:143:19:143:27 | CopyValue | no_Point+0:0 | no_Point+0:0 |
| escape.cpp:143:31:143:31 | FieldAddress[y] | no_Point+4:0 | no_Point+4:0 |
+| escape.cpp:144:6:144:14 | CopyValue | no_Point+0:0 | no_Point+0:0 |
| escape.cpp:144:18:144:18 | FieldAddress[y] | no_Point+4:0 | no_Point+4:0 |
+| escape.cpp:145:20:145:30 | CopyValue | no_Point+8:0 | no_Point+8:0 |
| escape.cpp:145:30:145:30 | FieldAddress[z] | no_Point+8:0 | no_Point+8:0 |
+| escape.cpp:146:5:146:18 | CopyValue | no_Point+8:0 | no_Point+8:0 |
+| escape.cpp:146:7:146:17 | CopyValue | no_Point+8:0 | no_Point+8:0 |
| escape.cpp:146:17:146:17 | FieldAddress[z] | no_Point+8:0 | no_Point+8:0 |
-| escape.cpp:149:5:149:14 | ConvertToBase[Derived : Intermediate1] | no_Derived+0:0 | no_Derived+0:0 |
-| escape.cpp:149:5:149:14 | ConvertToBase[Intermediate1 : Base] | no_Derived+0:0 | no_Derived+0:0 |
+| escape.cpp:149:5:149:14 | ConvertToNonVirtualBase[Derived : Intermediate1] | no_Derived+0:0 | no_Derived+0:0 |
+| escape.cpp:149:5:149:14 | ConvertToNonVirtualBase[Intermediate1 : Base] | no_Derived+0:0 | no_Derived+0:0 |
| escape.cpp:149:16:149:16 | FieldAddress[b] | no_Derived+0:0 | no_Derived+0:0 |
-| escape.cpp:150:18:150:27 | ConvertToBase[Derived : Intermediate1] | no_Derived+0:0 | no_Derived+0:0 |
-| escape.cpp:150:18:150:27 | ConvertToBase[Intermediate1 : Base] | no_Derived+0:0 | no_Derived+0:0 |
+| escape.cpp:150:18:150:27 | ConvertToNonVirtualBase[Derived : Intermediate1] | no_Derived+0:0 | no_Derived+0:0 |
+| escape.cpp:150:18:150:27 | ConvertToNonVirtualBase[Intermediate1 : Base] | no_Derived+0:0 | no_Derived+0:0 |
| escape.cpp:150:29:150:29 | FieldAddress[b] | no_Derived+0:0 | no_Derived+0:0 |
-| escape.cpp:151:5:151:14 | ConvertToBase[Derived : Intermediate2] | no_Derived+12:0 | no_Derived+12:0 |
+| escape.cpp:151:5:151:14 | ConvertToNonVirtualBase[Derived : Intermediate2] | no_Derived+12:0 | no_Derived+12:0 |
| escape.cpp:151:16:151:17 | FieldAddress[i2] | no_Derived+16:0 | no_Derived+16:0 |
-| escape.cpp:152:19:152:28 | ConvertToBase[Derived : Intermediate2] | no_Derived+12:0 | no_Derived+12:0 |
+| escape.cpp:152:19:152:28 | ConvertToNonVirtualBase[Derived : Intermediate2] | no_Derived+12:0 | no_Derived+12:0 |
| escape.cpp:152:30:152:31 | FieldAddress[i2] | no_Derived+16:0 | no_Derived+16:0 |
+| escape.cpp:155:17:155:30 | CopyValue | no_ssa_addrOf+0:0 | no_ssa_addrOf+0:0 |
| escape.cpp:155:17:155:30 | Store | no_ssa_addrOf+0:0 | no_ssa_addrOf+0:0 |
+| escape.cpp:158:17:158:28 | CopyValue | no_ssa_refTo+0:0 | no_ssa_refTo+0:0 |
| escape.cpp:158:17:158:28 | Store | no_ssa_refTo+0:0 | no_ssa_refTo+0:0 |
| escape.cpp:161:19:161:42 | Convert | no_ssa_refToArrayElement+0:0 | no_ssa_refToArrayElement+0:0 |
+| escape.cpp:161:19:161:45 | CopyValue | no_ssa_refToArrayElement+20:0 | no_ssa_refToArrayElement+20:0 |
| escape.cpp:161:19:161:45 | PointerAdd[4] | no_ssa_refToArrayElement+20:0 | no_ssa_refToArrayElement+20:0 |
| escape.cpp:161:19:161:45 | Store | no_ssa_refToArrayElement+20:0 | no_ssa_refToArrayElement+20:0 |
+| escape.cpp:164:24:164:40 | CopyValue | no_ssa_refToArray+0:0 | no_ssa_refToArray+0:0 |
| escape.cpp:164:24:164:40 | Store | no_ssa_refToArray+0:0 | no_ssa_refToArray+0:0 |
+| escape.cpp:167:19:167:28 | CopyValue | passByPtr+0:0 | passByPtr+0:0 |
+| escape.cpp:170:21:170:29 | CopyValue | passByRef+0:0 | passByRef+0:0 |
+| escape.cpp:173:22:173:38 | CopyValue | no_ssa_passByPtr+0:0 | no_ssa_passByPtr+0:0 |
+| escape.cpp:176:24:176:39 | CopyValue | no_ssa_passByRef+0:0 | no_ssa_passByRef+0:0 |
+| escape.cpp:179:22:179:42 | CopyValue | no_ssa_passByPtr_ret+0:0 | no_ssa_passByPtr_ret+0:0 |
+| escape.cpp:182:24:182:43 | CopyValue | no_ssa_passByRef_ret+0:0 | no_ssa_passByRef_ret+0:0 |
+| escape.cpp:185:30:185:40 | CopyValue | passByPtr2+0:0 | passByPtr2+0:0 |
+| escape.cpp:188:32:188:41 | CopyValue | passByRef2+0:0 | passByRef2+0:0 |
| escape.cpp:191:30:191:42 | Call | none | passByPtr3+0:0 |
+| escape.cpp:191:44:191:54 | CopyValue | passByPtr3+0:0 | passByPtr3+0:0 |
| escape.cpp:194:32:194:46 | Call | none | passByRef3+0:0 |
+| escape.cpp:194:32:194:59 | CopyValue | none | passByRef3+0:0 |
+| escape.cpp:194:48:194:57 | CopyValue | passByRef3+0:0 | passByRef3+0:0 |
+| escape.cpp:199:17:199:34 | CopyValue | no_ssa_passByPtr4+0:0 | no_ssa_passByPtr4+0:0 |
+| escape.cpp:199:37:199:54 | CopyValue | no_ssa_passByPtr5+0:0 | no_ssa_passByPtr5+0:0 |
| escape.cpp:202:5:202:19 | Call | none | passByRef6+0:0 |
+| escape.cpp:202:5:202:32 | CopyValue | none | passByRef6+0:0 |
+| escape.cpp:202:21:202:30 | CopyValue | passByRef6+0:0 | passByRef6+0:0 |
| escape.cpp:205:5:205:19 | Call | none | no_ssa_passByRef7+0:0 |
+| escape.cpp:205:5:205:39 | CopyValue | none | no_ssa_passByRef7+0:0 |
+| escape.cpp:205:21:205:37 | CopyValue | no_ssa_passByRef7+0:0 | no_ssa_passByRef7+0:0 |
| escape.cpp:209:14:209:25 | Call | none | no_ssa_c+0:0 |
+| escape.cpp:217:14:217:16 | CopyValue | c2+0:0 | c2+0:0 |
| escape.cpp:221:8:221:19 | Call | none | c3+0:0 |
| escape.cpp:225:17:225:28 | Call | none | c4+0:0 |
| escape.cpp:247:2:247:27 | Store | condEscape1+0:0 | condEscape1+0:0 |
+| escape.cpp:247:16:247:27 | CopyValue | condEscape1+0:0 | condEscape1+0:0 |
| escape.cpp:249:9:249:34 | Store | condEscape2+0:0 | condEscape2+0:0 |
+| escape.cpp:249:23:249:34 | CopyValue | condEscape2+0:0 | condEscape2+0:0 |
diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
index 3e393151f9b..dab6a40fae6 100644
--- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
+++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
@@ -67,7 +67,7 @@ bad_asts.cpp:
# 5| params:
#-----| 0: [Parameter] p#0
#-----| Type = [RValueReferenceType] S &&
-# 9| [FunctionTemplateInstantiation,MemberFunction] int Bad::S::MemberFunction(int)
+# 9| [FunctionTemplateInstantiation,MemberFunction] int Bad::S::MemberFunction(int)
# 9| params:
# 9| 0: [Parameter] y
# 9| Type = [IntType] int
@@ -92,7 +92,7 @@ bad_asts.cpp:
# 10| 1: [VariableAccess] y
# 10| Type = [IntType] int
# 10| ValueCategory = prvalue(load)
-# 9| [MemberFunction,TemplateFunction] int Bad::S::MemberFunction(int)
+# 9| [MemberFunction,TemplateFunction] int Bad::S::MemberFunction(int)
# 9| params:
# 9| 0: [Parameter] y
# 9| Type = [IntType] int
diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_sanity.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_sanity.expected
index 928f535f9d8..e5e666c020b 100644
--- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_sanity.expected
+++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_sanity.expected
@@ -1,8 +1,13 @@
missingOperand
+| ir.cpp:809:7:809:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() |
+| ir.cpp:810:7:810:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() |
+| ir.cpp:823:7:823:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() |
+| ir.cpp:824:7:824:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() |
unexpectedOperand
duplicateOperand
missingPhiOperand
missingOperandType
+duplicateChiOperand
sideEffectWithoutPrimary
instructionWithoutSuccessor
ambiguousSuccessors
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 e31be3c0034..948b031e18c 100644
--- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected
+++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected
@@ -1,5 +1,5 @@
bad_asts.cpp:
-# 9| int Bad::S::MemberFunction(int)
+# 9| int Bad::S::MemberFunction(int)
# 9| Block 0
# 9| v0_0(void) = EnterFunction :
# 9| mu0_1(unknown) = AliasedDefinition :
@@ -20,7 +20,8 @@ bad_asts.cpp:
# 9| r0_16(glval) = VariableAddress[#return] :
# 9| v0_17(void) = ReturnValue : &:r0_16, ~mu0_2
# 9| v0_18(void) = UnmodeledUse : mu*
-# 9| v0_19(void) = ExitFunction :
+# 9| v0_19(void) = AliasedUse : ~mu0_2
+# 9| v0_20(void) = ExitFunction :
# 14| void Bad::CallBadMemberFunction()
# 14| Block 0
@@ -37,12 +38,13 @@ bad_asts.cpp:
# 16| r0_10(int) = Constant[1] :
# 16| r0_11(int) = Call : func:r0_9, this:r0_8, 0:r0_10
# 16| mu0_12(unknown) = ^CallSideEffect : ~mu0_2
-# 16| v0_13(void) = ^IndirectReadSideEffect[-1] : &:r0_8, ~mu0_2
+# 16| v0_13(void) = ^BufferReadSideEffect[-1] : &:r0_8, ~mu0_2
# 16| mu0_14(S) = ^IndirectMayWriteSideEffect[-1] : &:r0_8
# 17| v0_15(void) = NoOp :
# 14| v0_16(void) = ReturnVoid :
# 14| v0_17(void) = UnmodeledUse : mu*
-# 14| v0_18(void) = ExitFunction :
+# 14| v0_18(void) = AliasedUse : ~mu0_2
+# 14| v0_19(void) = ExitFunction :
# 22| void Bad::Point::Point()
# 22| Block 0
@@ -53,7 +55,8 @@ bad_asts.cpp:
# 23| v0_4(void) = NoOp :
# 22| v0_5(void) = ReturnVoid :
# 22| v0_6(void) = UnmodeledUse : mu*
-# 22| v0_7(void) = ExitFunction :
+# 22| v0_7(void) = AliasedUse : ~mu0_2
+# 22| v0_8(void) = ExitFunction :
# 26| void Bad::CallCopyConstructor(Bad::Point const&)
# 26| Block 0
@@ -67,14 +70,16 @@ bad_asts.cpp:
# 27| r0_7(glval) = VariableAddress[b] :
# 27| r0_8(glval) = VariableAddress[a] :
# 27| r0_9(Point &) = Load : &:r0_8, ~mu0_2
-# 27| r0_10(glval) = Convert : r0_9
-# 27| r0_11(Point) = Load : &:r0_10, ~mu0_2
-# 27| mu0_12(Point) = Store : &:r0_7, r0_11
-# 28| v0_13(void) = NoOp :
-# 26| v0_14(void) = ReturnIndirection : &:r0_5, ~mu0_2
-# 26| v0_15(void) = ReturnVoid :
-# 26| v0_16(void) = UnmodeledUse : mu*
-# 26| v0_17(void) = ExitFunction :
+# 27| r0_10(glval) = CopyValue : r0_9
+# 27| r0_11(glval) = Convert : r0_10
+# 27| r0_12(Point) = Load : &:r0_11, ~mu0_2
+# 27| mu0_13(Point) = Store : &:r0_7, r0_12
+# 28| v0_14(void) = NoOp :
+# 26| v0_15(void) = ReturnIndirection : &:r0_5, ~mu0_2
+# 26| v0_16(void) = ReturnVoid :
+# 26| v0_17(void) = UnmodeledUse : mu*
+# 26| v0_18(void) = AliasedUse : ~mu0_2
+# 26| v0_19(void) = ExitFunction :
# 30| void Bad::errorExpr()
# 30| Block 0
@@ -94,7 +99,8 @@ bad_asts.cpp:
# 34| v0_13(void) = NoOp :
# 30| v0_14(void) = ReturnVoid :
# 30| v0_15(void) = UnmodeledUse : mu*
-# 30| v0_16(void) = ExitFunction :
+# 30| v0_16(void) = AliasedUse : ~mu0_2
+# 30| v0_17(void) = ExitFunction :
clang.cpp:
# 5| int* globalIntAddress()
@@ -104,11 +110,13 @@ clang.cpp:
# 5| mu0_2(unknown) = UnmodeledDefinition :
# 6| r0_3(glval) = VariableAddress[#return] :
# 6| r0_4(glval) = VariableAddress[globalInt] :
-# 6| mu0_5(int *) = Store : &:r0_3, r0_4
-# 5| r0_6(glval) = VariableAddress[#return] :
-# 5| v0_7(void) = ReturnValue : &:r0_6, ~mu0_2
-# 5| v0_8(void) = UnmodeledUse : mu*
-# 5| v0_9(void) = ExitFunction :
+# 6| r0_5(int *) = CopyValue : r0_4
+# 6| mu0_6(int *) = Store : &:r0_3, r0_5
+# 5| r0_7(glval) = VariableAddress[#return] :
+# 5| v0_8(void) = ReturnValue : &:r0_7, ~mu0_2
+# 5| v0_9(void) = UnmodeledUse : mu*
+# 5| v0_10(void) = AliasedUse : ~mu0_2
+# 5| v0_11(void) = ExitFunction :
ir.cpp:
# 1| void Constants()
@@ -203,7 +211,8 @@ ir.cpp:
# 41| v0_87(void) = NoOp :
# 1| v0_88(void) = ReturnVoid :
# 1| v0_89(void) = UnmodeledUse : mu*
-# 1| v0_90(void) = ExitFunction :
+# 1| v0_90(void) = AliasedUse : ~mu0_2
+# 1| v0_91(void) = ExitFunction :
# 43| void Foo()
# 43| Block 0
@@ -236,7 +245,8 @@ ir.cpp:
# 48| v0_26(void) = NoOp :
# 43| v0_27(void) = ReturnVoid :
# 43| v0_28(void) = UnmodeledUse : mu*
-# 43| v0_29(void) = ExitFunction :
+# 43| v0_29(void) = AliasedUse : ~mu0_2
+# 43| v0_30(void) = ExitFunction :
# 50| void IntegerOps(int, int)
# 50| Block 0
@@ -409,7 +419,8 @@ ir.cpp:
# 85| v0_166(void) = NoOp :
# 50| v0_167(void) = ReturnVoid :
# 50| v0_168(void) = UnmodeledUse : mu*
-# 50| v0_169(void) = ExitFunction :
+# 50| v0_169(void) = AliasedUse : ~mu0_2
+# 50| v0_170(void) = ExitFunction :
# 87| void IntegerCompare(int, int)
# 87| Block 0
@@ -467,7 +478,8 @@ ir.cpp:
# 96| v0_51(void) = NoOp :
# 87| v0_52(void) = ReturnVoid :
# 87| v0_53(void) = UnmodeledUse : mu*
-# 87| v0_54(void) = ExitFunction :
+# 87| v0_54(void) = AliasedUse : ~mu0_2
+# 87| v0_55(void) = ExitFunction :
# 98| void IntegerCrement(int)
# 98| Block 0
@@ -509,7 +521,8 @@ ir.cpp:
# 105| v0_35(void) = NoOp :
# 98| v0_36(void) = ReturnVoid :
# 98| v0_37(void) = UnmodeledUse : mu*
-# 98| v0_38(void) = ExitFunction :
+# 98| v0_38(void) = AliasedUse : ~mu0_2
+# 98| v0_39(void) = ExitFunction :
# 107| void IntegerCrement_LValue(int)
# 107| Block 0
@@ -525,19 +538,24 @@ ir.cpp:
# 110| r0_9(int) = Constant[1] :
# 110| r0_10(int) = Add : r0_8, r0_9
# 110| mu0_11(int) = Store : &:r0_7, r0_10
-# 110| r0_12(glval) = VariableAddress[p] :
-# 110| mu0_13(int *) = Store : &:r0_12, r0_7
-# 111| r0_14(glval) = VariableAddress[x] :
-# 111| r0_15(int) = Load : &:r0_14, ~mu0_2
-# 111| r0_16(int) = Constant[1] :
-# 111| r0_17(int) = Sub : r0_15, r0_16
-# 111| mu0_18(int) = Store : &:r0_14, r0_17
-# 111| r0_19(glval) = VariableAddress[p] :
-# 111| mu0_20(int *) = Store : &:r0_19, r0_14
-# 112| v0_21(void) = NoOp :
-# 107| v0_22(void) = ReturnVoid :
-# 107| v0_23(void) = UnmodeledUse : mu*
-# 107| v0_24(void) = ExitFunction :
+# 110| r0_12(glval) = CopyValue : r0_7
+# 110| r0_13(int *) = CopyValue : r0_12
+# 110| r0_14(glval) = VariableAddress[p] :
+# 110| mu0_15(int *) = Store : &:r0_14, r0_13
+# 111| r0_16(glval) = VariableAddress[x] :
+# 111| r0_17(int) = Load : &:r0_16, ~mu0_2
+# 111| r0_18(int) = Constant[1] :
+# 111| r0_19(int) = Sub : r0_17, r0_18
+# 111| mu0_20(int) = Store : &:r0_16, r0_19
+# 111| r0_21(glval) = CopyValue : r0_16
+# 111| r0_22(int *) = CopyValue : r0_21
+# 111| r0_23(glval) = VariableAddress[p] :
+# 111| mu0_24(int *) = Store : &:r0_23, r0_22
+# 112| v0_25(void) = NoOp :
+# 107| v0_26(void) = ReturnVoid :
+# 107| v0_27(void) = UnmodeledUse : mu*
+# 107| v0_28(void) = AliasedUse : ~mu0_2
+# 107| v0_29(void) = ExitFunction :
# 114| void FloatOps(double, double)
# 114| Block 0
@@ -619,7 +637,8 @@ ir.cpp:
# 131| v0_75(void) = NoOp :
# 114| v0_76(void) = ReturnVoid :
# 114| v0_77(void) = UnmodeledUse : mu*
-# 114| v0_78(void) = ExitFunction :
+# 114| v0_78(void) = AliasedUse : ~mu0_2
+# 114| v0_79(void) = ExitFunction :
# 133| void FloatCompare(double, double)
# 133| Block 0
@@ -677,7 +696,8 @@ ir.cpp:
# 142| v0_51(void) = NoOp :
# 133| v0_52(void) = ReturnVoid :
# 133| v0_53(void) = UnmodeledUse : mu*
-# 133| v0_54(void) = ExitFunction :
+# 133| v0_54(void) = AliasedUse : ~mu0_2
+# 133| v0_55(void) = ExitFunction :
# 144| void FloatCrement(float)
# 144| Block 0
@@ -719,7 +739,8 @@ ir.cpp:
# 151| v0_35(void) = NoOp :
# 144| v0_36(void) = ReturnVoid :
# 144| v0_37(void) = UnmodeledUse : mu*
-# 144| v0_38(void) = ExitFunction :
+# 144| v0_38(void) = AliasedUse : ~mu0_2
+# 144| v0_39(void) = ExitFunction :
# 153| void PointerOps(int*, int)
# 153| Block 0
@@ -798,7 +819,8 @@ ir.cpp:
# 153| v0_72(void) = ReturnIndirection : &:r0_5, ~mu0_2
# 153| v0_73(void) = ReturnVoid :
# 153| v0_74(void) = UnmodeledUse : mu*
-# 153| v0_75(void) = ExitFunction :
+# 153| v0_75(void) = AliasedUse : ~mu0_2
+# 153| v0_76(void) = ExitFunction :
# 171| void ArrayAccess(int*, int)
# 171| Block 0
@@ -883,7 +905,8 @@ ir.cpp:
# 171| v0_78(void) = ReturnIndirection : &:r0_5, ~mu0_2
# 171| v0_79(void) = ReturnVoid :
# 171| v0_80(void) = UnmodeledUse : mu*
-# 171| v0_81(void) = ExitFunction :
+# 171| v0_81(void) = AliasedUse : ~mu0_2
+# 171| v0_82(void) = ExitFunction :
# 187| void StringLiteral(int)
# 187| Block 0
@@ -916,7 +939,8 @@ ir.cpp:
# 191| v0_26(void) = NoOp :
# 187| v0_27(void) = ReturnVoid :
# 187| v0_28(void) = UnmodeledUse : mu*
-# 187| v0_29(void) = ExitFunction :
+# 187| v0_29(void) = AliasedUse : ~mu0_2
+# 187| v0_30(void) = ExitFunction :
# 193| void PointerCompare(int*, int*)
# 193| Block 0
@@ -980,7 +1004,8 @@ ir.cpp:
# 193| v0_57(void) = ReturnIndirection : &:r0_9, ~mu0_2
# 193| v0_58(void) = ReturnVoid :
# 193| v0_59(void) = UnmodeledUse : mu*
-# 193| v0_60(void) = ExitFunction :
+# 193| v0_60(void) = AliasedUse : ~mu0_2
+# 193| v0_61(void) = ExitFunction :
# 204| void PointerCrement(int*)
# 204| Block 0
@@ -1025,7 +1050,8 @@ ir.cpp:
# 204| v0_38(void) = ReturnIndirection : &:r0_5, ~mu0_2
# 204| v0_39(void) = ReturnVoid :
# 204| v0_40(void) = UnmodeledUse : mu*
-# 204| v0_41(void) = ExitFunction :
+# 204| v0_41(void) = AliasedUse : ~mu0_2
+# 204| v0_42(void) = ExitFunction :
# 213| void CompoundAssignment()
# 213| Block 0
@@ -1069,7 +1095,8 @@ ir.cpp:
# 228| v0_37(void) = NoOp :
# 213| v0_38(void) = ReturnVoid :
# 213| v0_39(void) = UnmodeledUse : mu*
-# 213| v0_40(void) = ExitFunction :
+# 213| v0_40(void) = AliasedUse : ~mu0_2
+# 213| v0_41(void) = ExitFunction :
# 230| void UninitializedVariables()
# 230| Block 0
@@ -1085,7 +1112,8 @@ ir.cpp:
# 233| v0_9(void) = NoOp :
# 230| v0_10(void) = ReturnVoid :
# 230| v0_11(void) = UnmodeledUse : mu*
-# 230| v0_12(void) = ExitFunction :
+# 230| v0_12(void) = AliasedUse : ~mu0_2
+# 230| v0_13(void) = ExitFunction :
# 235| int Parameters(int, int)
# 235| Block 0
@@ -1106,7 +1134,8 @@ ir.cpp:
# 235| r0_14(glval) = VariableAddress[#return] :
# 235| v0_15(void) = ReturnValue : &:r0_14, ~mu0_2
# 235| v0_16(void) = UnmodeledUse : mu*
-# 235| v0_17(void) = ExitFunction :
+# 235| v0_17(void) = AliasedUse : ~mu0_2
+# 235| v0_18(void) = ExitFunction :
# 239| void IfStatements(bool, int, int)
# 239| Block 0
@@ -1164,7 +1193,8 @@ ir.cpp:
# 251| v6_0(void) = NoOp :
# 239| v6_1(void) = ReturnVoid :
# 239| v6_2(void) = UnmodeledUse : mu*
-# 239| v6_3(void) = ExitFunction :
+# 239| v6_3(void) = AliasedUse : ~mu0_2
+# 239| v6_4(void) = ExitFunction :
# 240| Block 7
# 240| v7_0(void) = NoOp :
@@ -1191,7 +1221,8 @@ ir.cpp:
# 257| v2_0(void) = NoOp :
# 253| v2_1(void) = ReturnVoid :
# 253| v2_2(void) = UnmodeledUse : mu*
-# 253| v2_3(void) = ExitFunction :
+# 253| v2_3(void) = AliasedUse : ~mu0_2
+# 253| v2_4(void) = ExitFunction :
# 254| Block 3
# 254| r3_0(glval) = VariableAddress[n] :
@@ -1229,7 +1260,8 @@ ir.cpp:
# 263| v2_0(void) = NoOp :
# 259| v2_1(void) = ReturnVoid :
# 259| v2_2(void) = UnmodeledUse : mu*
-# 259| v2_3(void) = ExitFunction :
+# 259| v2_3(void) = AliasedUse : ~mu0_2
+# 259| v2_4(void) = ExitFunction :
# 265| void For_Empty()
# 265| Block 0
@@ -1243,7 +1275,8 @@ ir.cpp:
# 265| Block 1
# 265| v1_0(void) = ReturnVoid :
# 265| v1_1(void) = UnmodeledUse : mu*
-# 265| v1_2(void) = ExitFunction :
+# 265| v1_2(void) = AliasedUse : ~mu0_2
+# 265| v1_3(void) = ExitFunction :
# 268| Block 2
# 268| v2_0(void) = NoOp :
@@ -1262,7 +1295,8 @@ ir.cpp:
# 272| Block 1
# 272| v1_0(void) = ReturnVoid :
# 272| v1_1(void) = UnmodeledUse : mu*
-# 272| v1_2(void) = ExitFunction :
+# 272| v1_2(void) = AliasedUse : ~mu0_2
+# 272| v1_3(void) = ExitFunction :
# 274| Block 2
# 274| v2_0(void) = NoOp :
@@ -1295,7 +1329,8 @@ ir.cpp:
# 283| v3_0(void) = NoOp :
# 278| v3_1(void) = ReturnVoid :
# 278| v3_2(void) = UnmodeledUse : mu*
-# 278| v3_3(void) = ExitFunction :
+# 278| v3_3(void) = AliasedUse : ~mu0_2
+# 278| v3_4(void) = ExitFunction :
# 285| void For_Update()
# 285| Block 0
@@ -1310,7 +1345,8 @@ ir.cpp:
# 285| Block 1
# 285| v1_0(void) = ReturnVoid :
# 285| v1_1(void) = UnmodeledUse : mu*
-# 285| v1_2(void) = ExitFunction :
+# 285| v1_2(void) = AliasedUse : ~mu0_2
+# 285| v1_3(void) = ExitFunction :
# 288| Block 2
# 288| v2_0(void) = NoOp :
@@ -1348,7 +1384,8 @@ ir.cpp:
# 296| v3_0(void) = NoOp :
# 292| v3_1(void) = ReturnVoid :
# 292| v3_2(void) = UnmodeledUse : mu*
-# 292| v3_3(void) = ExitFunction :
+# 292| v3_3(void) = AliasedUse : ~mu0_2
+# 292| v3_4(void) = ExitFunction :
# 298| void For_InitUpdate()
# 298| Block 0
@@ -1363,7 +1400,8 @@ ir.cpp:
# 298| Block 1
# 298| v1_0(void) = ReturnVoid :
# 298| v1_1(void) = UnmodeledUse : mu*
-# 298| v1_2(void) = ExitFunction :
+# 298| v1_2(void) = AliasedUse : ~mu0_2
+# 298| v1_3(void) = ExitFunction :
# 300| Block 2
# 300| v2_0(void) = NoOp :
@@ -1406,7 +1444,8 @@ ir.cpp:
# 309| v3_0(void) = NoOp :
# 304| v3_1(void) = ReturnVoid :
# 304| v3_2(void) = UnmodeledUse : mu*
-# 304| v3_3(void) = ExitFunction :
+# 304| v3_3(void) = AliasedUse : ~mu0_2
+# 304| v3_4(void) = ExitFunction :
# 311| void For_InitConditionUpdate()
# 311| Block 0
@@ -1440,7 +1479,8 @@ ir.cpp:
# 315| v3_0(void) = NoOp :
# 311| v3_1(void) = ReturnVoid :
# 311| v3_2(void) = UnmodeledUse : mu*
-# 311| v3_3(void) = ExitFunction :
+# 311| v3_3(void) = AliasedUse : ~mu0_2
+# 311| v3_4(void) = ExitFunction :
# 317| void For_Break()
# 317| Block 0
@@ -1487,7 +1527,8 @@ ir.cpp:
# 323| v5_1(void) = NoOp :
# 317| v5_2(void) = ReturnVoid :
# 317| v5_3(void) = UnmodeledUse : mu*
-# 317| v5_4(void) = ExitFunction :
+# 317| v5_4(void) = AliasedUse : ~mu0_2
+# 317| v5_5(void) = ExitFunction :
# 325| void For_Continue_Update()
# 325| Block 0
@@ -1534,7 +1575,8 @@ ir.cpp:
# 331| v5_0(void) = NoOp :
# 325| v5_1(void) = ReturnVoid :
# 325| v5_2(void) = UnmodeledUse : mu*
-# 325| v5_3(void) = ExitFunction :
+# 325| v5_3(void) = AliasedUse : ~mu0_2
+# 325| v5_4(void) = ExitFunction :
# 333| void For_Continue_NoUpdate()
# 333| Block 0
@@ -1576,7 +1618,8 @@ ir.cpp:
# 339| v5_0(void) = NoOp :
# 333| v5_1(void) = ReturnVoid :
# 333| v5_2(void) = UnmodeledUse : mu*
-# 333| v5_3(void) = ExitFunction :
+# 333| v5_3(void) = AliasedUse : ~mu0_2
+# 333| v5_4(void) = ExitFunction :
# 341| int Dereference(int*)
# 341| Block 0
@@ -1590,17 +1633,19 @@ ir.cpp:
# 342| r0_7(int) = Constant[1] :
# 342| r0_8(glval) = VariableAddress[p] :
# 342| r0_9(int *) = Load : &:r0_8, ~mu0_2
-# 342| mu0_10(int) = Store : &:r0_9, r0_7
-# 343| r0_11(glval) = VariableAddress[#return] :
-# 343| r0_12(glval) = VariableAddress[p] :
-# 343| r0_13(int *) = Load : &:r0_12, ~mu0_2
-# 343| r0_14(int) = Load : &:r0_13, ~mu0_2
-# 343| mu0_15(int) = Store : &:r0_11, r0_14
-# 341| v0_16(void) = ReturnIndirection : &:r0_5, ~mu0_2
-# 341| r0_17(glval) = VariableAddress[#return] :
-# 341| v0_18(void) = ReturnValue : &:r0_17, ~mu0_2
-# 341| v0_19(void) = UnmodeledUse : mu*
-# 341| v0_20(void) = ExitFunction :
+# 342| r0_10(glval) = CopyValue : r0_9
+# 342| mu0_11(int) = Store : &:r0_10, r0_7
+# 343| r0_12(glval) = VariableAddress[#return] :
+# 343| r0_13(glval) = VariableAddress[p] :
+# 343| r0_14(int *) = Load : &:r0_13, ~mu0_2
+# 343| r0_15(int) = Load : &:r0_14, ~mu0_2
+# 343| mu0_16(int) = Store : &:r0_12, r0_15
+# 341| v0_17(void) = ReturnIndirection : &:r0_5, ~mu0_2
+# 341| r0_18(glval) = VariableAddress[#return] :
+# 341| v0_19(void) = ReturnValue : &:r0_18, ~mu0_2
+# 341| v0_20(void) = UnmodeledUse : mu*
+# 341| v0_21(void) = AliasedUse : ~mu0_2
+# 341| v0_22(void) = ExitFunction :
# 348| int* AddressOf()
# 348| Block 0
@@ -1609,11 +1654,13 @@ ir.cpp:
# 348| mu0_2(unknown) = UnmodeledDefinition :
# 349| r0_3(glval) = VariableAddress[#return] :
# 349| r0_4(glval) = VariableAddress[g] :
-# 349| mu0_5(int *) = Store : &:r0_3, r0_4
-# 348| r0_6(glval) = VariableAddress[#return] :
-# 348| v0_7(void) = ReturnValue : &:r0_6, ~mu0_2
-# 348| v0_8(void) = UnmodeledUse : mu*
-# 348| v0_9(void) = ExitFunction :
+# 349| r0_5(int *) = CopyValue : r0_4
+# 349| mu0_6(int *) = Store : &:r0_3, r0_5
+# 348| r0_7(glval) = VariableAddress[#return] :
+# 348| v0_8(void) = ReturnValue : &:r0_7, ~mu0_2
+# 348| v0_9(void) = UnmodeledUse : mu*
+# 348| v0_10(void) = AliasedUse : ~mu0_2
+# 348| v0_11(void) = ExitFunction :
# 352| void Break(int)
# 352| Block 0
@@ -1650,7 +1697,8 @@ ir.cpp:
# 358| v4_1(void) = NoOp :
# 352| v4_2(void) = ReturnVoid :
# 352| v4_3(void) = UnmodeledUse : mu*
-# 352| v4_4(void) = ExitFunction :
+# 352| v4_4(void) = AliasedUse : ~mu0_2
+# 352| v4_5(void) = ExitFunction :
# 353| Block 5
# 353| r5_0(glval) = VariableAddress[n] :
@@ -1705,7 +1753,8 @@ ir.cpp:
# 367| v5_0(void) = NoOp :
# 360| v5_1(void) = ReturnVoid :
# 360| v5_2(void) = UnmodeledUse : mu*
-# 360| v5_3(void) = ExitFunction :
+# 360| v5_3(void) = AliasedUse : ~mu0_2
+# 360| v5_4(void) = ExitFunction :
# 372| void Call()
# 372| Block 0
@@ -1718,7 +1767,8 @@ ir.cpp:
# 374| v0_6(void) = NoOp :
# 372| v0_7(void) = ReturnVoid :
# 372| v0_8(void) = UnmodeledUse : mu*
-# 372| v0_9(void) = ExitFunction :
+# 372| v0_9(void) = AliasedUse : ~mu0_2
+# 372| v0_10(void) = ExitFunction :
# 376| int CallAdd(int, int)
# 376| Block 0
@@ -1741,7 +1791,8 @@ ir.cpp:
# 376| r0_16(glval) = VariableAddress[#return] :
# 376| v0_17(void) = ReturnValue : &:r0_16, ~mu0_2
# 376| v0_18(void) = UnmodeledUse : mu*
-# 376| v0_19(void) = ExitFunction :
+# 376| v0_19(void) = AliasedUse : ~mu0_2
+# 376| v0_20(void) = ExitFunction :
# 380| int Comma(int, int)
# 380| Block 0
@@ -1763,11 +1814,13 @@ ir.cpp:
# 381| r0_15(int) = Load : &:r0_14, ~mu0_2
# 381| r0_16(int) = Call : func:r0_11, 0:r0_13, 1:r0_15
# 381| mu0_17(unknown) = ^CallSideEffect : ~mu0_2
-# 381| mu0_18(int) = Store : &:r0_7, r0_16
-# 380| r0_19(glval) = VariableAddress[#return] :
-# 380| v0_20(void) = ReturnValue : &:r0_19, ~mu0_2
-# 380| v0_21(void) = UnmodeledUse : mu*
-# 380| v0_22(void) = ExitFunction :
+# 381| r0_18(int) = CopyValue : r0_16
+# 381| mu0_19(int) = Store : &:r0_7, r0_18
+# 380| r0_20(glval) = VariableAddress[#return] :
+# 380| v0_21(void) = ReturnValue : &:r0_20, ~mu0_2
+# 380| v0_22(void) = UnmodeledUse : mu*
+# 380| v0_23(void) = AliasedUse : ~mu0_2
+# 380| v0_24(void) = ExitFunction :
# 384| void Switch(int)
# 384| Block 0
@@ -1848,7 +1901,8 @@ ir.cpp:
# 410| v9_1(void) = NoOp :
# 384| v9_2(void) = ReturnVoid :
# 384| v9_3(void) = UnmodeledUse : mu*
-# 384| v9_4(void) = ExitFunction :
+# 384| v9_4(void) = AliasedUse : ~mu0_2
+# 384| v9_5(void) = ExitFunction :
# 422| Point ReturnStruct(Point)
# 422| Block 0
@@ -1864,7 +1918,8 @@ ir.cpp:
# 422| r0_9(glval) = VariableAddress[#return] :
# 422| v0_10(void) = ReturnValue : &:r0_9, ~mu0_2
# 422| v0_11(void) = UnmodeledUse : mu*
-# 422| v0_12(void) = ExitFunction :
+# 422| v0_12(void) = AliasedUse : ~mu0_2
+# 422| v0_13(void) = ExitFunction :
# 426| void FieldAccess()
# 426| Block 0
@@ -1886,11 +1941,13 @@ ir.cpp:
# 430| r0_15(glval) = VariableAddress[p] :
# 430| r0_16(glval) = VariableAddress[pt] :
# 430| r0_17(glval) = FieldAddress[y] : r0_16
-# 430| mu0_18(int *) = Store : &:r0_15, r0_17
-# 431| v0_19(void) = NoOp :
-# 426| v0_20(void) = ReturnVoid :
-# 426| v0_21(void) = UnmodeledUse : mu*
-# 426| v0_22(void) = ExitFunction :
+# 430| r0_18(int *) = CopyValue : r0_17
+# 430| mu0_19(int *) = Store : &:r0_15, r0_18
+# 431| v0_20(void) = NoOp :
+# 426| v0_21(void) = ReturnVoid :
+# 426| v0_22(void) = UnmodeledUse : mu*
+# 426| v0_23(void) = AliasedUse : ~mu0_2
+# 426| v0_24(void) = ExitFunction :
# 433| void LogicalOr(bool, bool)
# 433| Block 0
@@ -1952,7 +2009,8 @@ ir.cpp:
# 445| v7_0(void) = NoOp :
# 433| v7_1(void) = ReturnVoid :
# 433| v7_2(void) = UnmodeledUse : mu*
-# 433| v7_3(void) = ExitFunction :
+# 433| v7_3(void) = AliasedUse : ~mu0_2
+# 433| v7_4(void) = ExitFunction :
# 447| void LogicalAnd(bool, bool)
# 447| Block 0
@@ -2014,7 +2072,8 @@ ir.cpp:
# 459| v7_0(void) = NoOp :
# 447| v7_1(void) = ReturnVoid :
# 447| v7_2(void) = UnmodeledUse : mu*
-# 447| v7_3(void) = ExitFunction :
+# 447| v7_3(void) = AliasedUse : ~mu0_2
+# 447| v7_4(void) = ExitFunction :
# 461| void LogicalNot(bool, bool)
# 461| Block 0
@@ -2069,7 +2128,8 @@ ir.cpp:
# 473| v6_0(void) = NoOp :
# 461| v6_1(void) = ReturnVoid :
# 461| v6_2(void) = UnmodeledUse : mu*
-# 461| v6_3(void) = ExitFunction :
+# 461| v6_3(void) = AliasedUse : ~mu0_2
+# 461| v6_4(void) = ExitFunction :
# 475| void ConditionValues(bool, bool)
# 475| Block 0
@@ -2140,7 +2200,8 @@ ir.cpp:
# 480| v7_5(void) = NoOp :
# 475| v7_6(void) = ReturnVoid :
# 475| v7_7(void) = UnmodeledUse : mu*
-# 475| v7_8(void) = ExitFunction :
+# 475| v7_8(void) = AliasedUse : ~mu0_2
+# 475| v7_9(void) = ExitFunction :
# 479| Block 8
# 479| r8_0(glval) = VariableAddress[#temp479:11] :
@@ -2217,7 +2278,8 @@ ir.cpp:
# 484| v3_3(void) = NoOp :
# 482| v3_4(void) = ReturnVoid :
# 482| v3_5(void) = UnmodeledUse : mu*
-# 482| v3_6(void) = ExitFunction :
+# 482| v3_6(void) = AliasedUse : ~mu0_2
+# 482| v3_7(void) = ExitFunction :
# 486| void Conditional_LValue(bool)
# 486| Block 0
@@ -2244,7 +2306,8 @@ ir.cpp:
# 490| v1_3(void) = NoOp :
# 486| v1_4(void) = ReturnVoid :
# 486| v1_5(void) = UnmodeledUse : mu*
-# 486| v1_6(void) = ExitFunction :
+# 486| v1_6(void) = AliasedUse : ~mu0_2
+# 486| v1_7(void) = ExitFunction :
# 489| Block 2
# 489| r2_0(glval) = VariableAddress[x] :
@@ -2281,7 +2344,8 @@ ir.cpp:
# 494| v2_0(void) = NoOp :
# 492| v2_1(void) = ReturnVoid :
# 492| v2_2(void) = UnmodeledUse : mu*
-# 492| v2_3(void) = ExitFunction :
+# 492| v2_3(void) = AliasedUse : ~mu0_2
+# 492| v2_4(void) = ExitFunction :
# 493| Block 3
# 493| r3_0(glval) = FunctionAddress[VoidFunc] :
@@ -2309,7 +2373,8 @@ ir.cpp:
# 501| v0_15(void) = NoOp :
# 496| v0_16(void) = ReturnVoid :
# 496| v0_17(void) = UnmodeledUse : mu*
-# 496| v0_18(void) = ExitFunction :
+# 496| v0_18(void) = AliasedUse : ~mu0_2
+# 496| v0_19(void) = ExitFunction :
# 503| void InitList(int, float)
# 503| Block 0
@@ -2357,7 +2422,8 @@ ir.cpp:
# 510| v0_41(void) = NoOp :
# 503| v0_42(void) = ReturnVoid :
# 503| v0_43(void) = UnmodeledUse : mu*
-# 503| v0_44(void) = ExitFunction :
+# 503| v0_44(void) = AliasedUse : ~mu0_2
+# 503| v0_45(void) = ExitFunction :
# 512| void NestedInitList(int, float)
# 512| Block 0
@@ -2434,7 +2500,8 @@ ir.cpp:
# 517| v0_70(void) = NoOp :
# 512| v0_71(void) = ReturnVoid :
# 512| v0_72(void) = UnmodeledUse : mu*
-# 512| v0_73(void) = ExitFunction :
+# 512| v0_73(void) = AliasedUse : ~mu0_2
+# 512| v0_74(void) = ExitFunction :
# 519| void ArrayInit(int, float)
# 519| Block 0
@@ -2482,7 +2549,8 @@ ir.cpp:
# 523| v0_41(void) = NoOp :
# 519| v0_42(void) = ReturnVoid :
# 519| v0_43(void) = UnmodeledUse : mu*
-# 519| v0_44(void) = ExitFunction :
+# 519| v0_44(void) = AliasedUse : ~mu0_2
+# 519| v0_45(void) = ExitFunction :
# 530| void UnionInit(int, float)
# 530| Block 0
@@ -2503,7 +2571,8 @@ ir.cpp:
# 533| v0_14(void) = NoOp :
# 530| v0_15(void) = ReturnVoid :
# 530| v0_16(void) = UnmodeledUse : mu*
-# 530| v0_17(void) = ExitFunction :
+# 530| v0_17(void) = AliasedUse : ~mu0_2
+# 530| v0_18(void) = ExitFunction :
# 535| void EarlyReturn(int, int)
# 535| Block 0
@@ -2526,7 +2595,8 @@ ir.cpp:
# 535| Block 1
# 535| v1_0(void) = ReturnVoid :
# 535| v1_1(void) = UnmodeledUse : mu*
-# 535| v1_2(void) = ExitFunction :
+# 535| v1_2(void) = AliasedUse : ~mu0_2
+# 535| v1_3(void) = ExitFunction :
# 537| Block 2
# 537| v2_0(void) = NoOp :
@@ -2562,7 +2632,8 @@ ir.cpp:
# 543| r1_0(glval) = VariableAddress[#return] :
# 543| v1_1(void) = ReturnValue : &:r1_0, ~mu0_2
# 543| v1_2(void) = UnmodeledUse : mu*
-# 543| v1_3(void) = ExitFunction :
+# 543| v1_3(void) = AliasedUse : ~mu0_2
+# 543| v1_4(void) = ExitFunction :
# 545| Block 2
# 545| r2_0(glval) = VariableAddress[#return] :
@@ -2598,7 +2669,8 @@ ir.cpp:
# 551| r0_12(glval) = VariableAddress[#return] :
# 551| v0_13(void) = ReturnValue : &:r0_12, ~mu0_2
# 551| v0_14(void) = UnmodeledUse : mu*
-# 551| v0_15(void) = ExitFunction :
+# 551| v0_15(void) = AliasedUse : ~mu0_2
+# 551| v0_16(void) = ExitFunction :
# 560| int EnumSwitch(E)
# 560| Block 0
@@ -2619,7 +2691,8 @@ ir.cpp:
# 560| r1_0(glval) = VariableAddress[#return] :
# 560| v1_1(void) = ReturnValue : &:r1_0, ~mu0_2
# 560| v1_2(void) = UnmodeledUse : mu*
-# 560| v1_3(void) = ExitFunction :
+# 560| v1_3(void) = AliasedUse : ~mu0_2
+# 560| v1_4(void) = ExitFunction :
# 564| Block 2
# 564| v2_0(void) = NoOp :
@@ -2648,63 +2721,65 @@ ir.cpp:
# 571| mu0_1(unknown) = AliasedDefinition :
# 571| mu0_2(unknown) = UnmodeledDefinition :
# 572| r0_3(glval) = VariableAddress[a_pad] :
-# 572| r0_4(glval) = StringConstant[""] :
-# 572| r0_5(char[1]) = Load : &:r0_4, ~mu0_2
-# 572| mu0_6(char[1]) = Store : &:r0_3, r0_5
-# 572| r0_7(unknown[31]) = Constant[0] :
-# 572| r0_8(int) = Constant[1] :
-# 572| r0_9(glval) = PointerAdd[1] : r0_3, r0_8
-# 572| mu0_10(unknown[31]) = Store : &:r0_9, r0_7
-# 573| r0_11(glval) = VariableAddress[a_nopad] :
-# 573| r0_12(glval) = StringConstant["foo"] :
-# 573| r0_13(char[4]) = Load : &:r0_12, ~mu0_2
-# 573| mu0_14(char[4]) = Store : &:r0_11, r0_13
-# 574| r0_15(glval) = VariableAddress[a_infer] :
-# 574| r0_16(glval) = StringConstant["blah"] :
-# 574| r0_17(char[5]) = Load : &:r0_16, ~mu0_2
-# 574| mu0_18(char[5]) = Store : &:r0_15, r0_17
-# 575| r0_19(glval) = VariableAddress[b] :
-# 575| mu0_20(char[2]) = Uninitialized[b] : &:r0_19
-# 576| r0_21(glval) = VariableAddress[c] :
-# 576| mu0_22(char[2]) = Uninitialized[c] : &:r0_21
-# 576| r0_23(int) = Constant[0] :
-# 576| r0_24(glval) = PointerAdd[1] : r0_21, r0_23
-# 576| r0_25(unknown[2]) = Constant[0] :
-# 576| mu0_26(unknown[2]) = Store : &:r0_24, r0_25
-# 577| r0_27(glval) = VariableAddress[d] :
-# 577| mu0_28(char[2]) = Uninitialized[d] : &:r0_27
-# 577| r0_29(int) = Constant[0] :
-# 577| r0_30(glval) = PointerAdd[1] : r0_27, r0_29
-# 577| r0_31(char) = Constant[0] :
-# 577| mu0_32(char) = Store : &:r0_30, r0_31
-# 577| r0_33(int) = Constant[1] :
-# 577| r0_34(glval) = PointerAdd[1] : r0_27, r0_33
-# 577| r0_35(char) = Constant[0] :
-# 577| mu0_36(char) = Store : &:r0_34, r0_35
-# 578| r0_37(glval) = VariableAddress[e] :
-# 578| mu0_38(char[2]) = Uninitialized[e] : &:r0_37
-# 578| r0_39(int) = Constant[0] :
-# 578| r0_40(glval) = PointerAdd[1] : r0_37, r0_39
-# 578| r0_41(char) = Constant[0] :
-# 578| mu0_42(char) = Store : &:r0_40, r0_41
-# 578| r0_43(int) = Constant[1] :
-# 578| r0_44(glval) = PointerAdd[1] : r0_37, r0_43
-# 578| r0_45(char) = Constant[1] :
-# 578| mu0_46(char) = Store : &:r0_44, r0_45
-# 579| r0_47(glval) = VariableAddress[f] :
-# 579| mu0_48(char[3]) = Uninitialized[f] : &:r0_47
-# 579| r0_49(int) = Constant[0] :
-# 579| r0_50(glval) = PointerAdd[1] : r0_47, r0_49
-# 579| r0_51(char) = Constant[0] :
-# 579| mu0_52(char) = Store : &:r0_50, r0_51
-# 579| r0_53(int) = Constant[1] :
-# 579| r0_54(glval) = PointerAdd[1] : r0_47, r0_53
-# 579| r0_55(unknown[2]) = Constant[0] :
-# 579| mu0_56(unknown[2]) = Store : &:r0_54, r0_55
-# 580| v0_57(void) = NoOp :
-# 571| v0_58(void) = ReturnVoid :
-# 571| v0_59(void) = UnmodeledUse : mu*
-# 571| v0_60(void) = ExitFunction :
+# 572| mu0_4(char[32]) = Uninitialized[a_pad] : &:r0_3
+# 572| r0_5(glval) = StringConstant[""] :
+# 572| r0_6(char[1]) = Load : &:r0_5, ~mu0_2
+# 572| mu0_7(char[1]) = Store : &:r0_3, r0_6
+# 572| r0_8(unknown[31]) = Constant[0] :
+# 572| r0_9(int) = Constant[1] :
+# 572| r0_10(glval) = PointerAdd[1] : r0_3, r0_9
+# 572| mu0_11(unknown[31]) = Store : &:r0_10, r0_8
+# 573| r0_12(glval) = VariableAddress[a_nopad] :
+# 573| r0_13(glval) = StringConstant["foo"] :
+# 573| r0_14(char[4]) = Load : &:r0_13, ~mu0_2
+# 573| mu0_15(char[4]) = Store : &:r0_12, r0_14
+# 574| r0_16(glval) = VariableAddress[a_infer] :
+# 574| r0_17(glval) = StringConstant["blah"] :
+# 574| r0_18(char[5]) = Load : &:r0_17, ~mu0_2
+# 574| mu0_19(char[5]) = Store : &:r0_16, r0_18
+# 575| r0_20(glval) = VariableAddress[b] :
+# 575| mu0_21(char[2]) = Uninitialized[b] : &:r0_20
+# 576| r0_22(glval) = VariableAddress[c] :
+# 576| mu0_23(char[2]) = Uninitialized[c] : &:r0_22
+# 576| r0_24(int) = Constant[0] :
+# 576| r0_25(glval) = PointerAdd[1] : r0_22, r0_24
+# 576| r0_26(unknown[2]) = Constant[0] :
+# 576| mu0_27(unknown[2]) = Store : &:r0_25, r0_26
+# 577| r0_28(glval) = VariableAddress[d] :
+# 577| mu0_29(char[2]) = Uninitialized[d] : &:r0_28
+# 577| r0_30(int) = Constant[0] :
+# 577| r0_31(glval) = PointerAdd[1] : r0_28, r0_30
+# 577| r0_32(char) = Constant[0] :
+# 577| mu0_33(char) = Store : &:r0_31, r0_32
+# 577| r0_34(int) = Constant[1] :
+# 577| r0_35(glval) = PointerAdd[1] : r0_28, r0_34
+# 577| r0_36(char) = Constant[0] :
+# 577| mu0_37(char) = Store : &:r0_35, r0_36
+# 578| r0_38(glval) = VariableAddress[e] :
+# 578| mu0_39(char[2]) = Uninitialized[e] : &:r0_38
+# 578| r0_40(int) = Constant[0] :
+# 578| r0_41(glval) = PointerAdd[1] : r0_38, r0_40
+# 578| r0_42(char) = Constant[0] :
+# 578| mu0_43(char) = Store : &:r0_41, r0_42
+# 578| r0_44(int) = Constant[1] :
+# 578| r0_45(glval) = PointerAdd[1] : r0_38, r0_44
+# 578| r0_46(char) = Constant[1] :
+# 578| mu0_47(char) = Store : &:r0_45, r0_46
+# 579| r0_48(glval) = VariableAddress[f] :
+# 579| mu0_49(char[3]) = Uninitialized[f] : &:r0_48
+# 579| r0_50(int) = Constant[0] :
+# 579| r0_51(glval) = PointerAdd[1] : r0_48, r0_50
+# 579| r0_52(char) = Constant[0] :
+# 579| mu0_53(char) = Store : &:r0_51, r0_52
+# 579| r0_54(int) = Constant[1] :
+# 579| r0_55(glval) = PointerAdd[1] : r0_48, r0_54
+# 579| r0_56(unknown[2]) = Constant[0] :
+# 579| mu0_57(unknown[2]) = Store : &:r0_55, r0_56
+# 580| v0_58(void) = NoOp :
+# 571| v0_59(void) = ReturnVoid :
+# 571| v0_60(void) = UnmodeledUse : mu*
+# 571| v0_61(void) = AliasedUse : ~mu0_2
+# 571| v0_62(void) = ExitFunction :
# 584| void VarArgs()
# 584| Block 0
@@ -2719,14 +2794,15 @@ ir.cpp:
# 585| r0_8(char *) = Convert : r0_7
# 585| v0_9(void) = Call : func:r0_3, 0:r0_5, 1:r0_6, 2:r0_8
# 585| mu0_10(unknown) = ^CallSideEffect : ~mu0_2
-# 585| v0_11(void) = ^IndirectReadSideEffect[0] : &:r0_5, ~mu0_2
-# 585| v0_12(void) = ^IndirectReadSideEffect[2] : &:r0_8, ~mu0_2
+# 585| v0_11(void) = ^BufferReadSideEffect[0] : &:r0_5, ~mu0_2
+# 585| v0_12(void) = ^BufferReadSideEffect[2] : &:r0_8, ~mu0_2
# 585| mu0_13(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_5
# 585| mu0_14(unknown) = ^BufferMayWriteSideEffect[2] : &:r0_8
# 586| v0_15(void) = NoOp :
# 584| v0_16(void) = ReturnVoid :
# 584| v0_17(void) = UnmodeledUse : mu*
-# 584| v0_18(void) = ExitFunction :
+# 584| v0_18(void) = AliasedUse : ~mu0_2
+# 584| v0_19(void) = ExitFunction :
# 590| void SetFuncPtr()
# 590| Block 0
@@ -2737,53 +2813,67 @@ ir.cpp:
# 591| r0_4(..(*)(..)) = FunctionAddress[FuncPtrTarget] :
# 591| mu0_5(..(*)(..)) = Store : &:r0_3, r0_4
# 592| r0_6(glval<..()(..)>) = FunctionAddress[FuncPtrTarget] :
-# 592| r0_7(glval<..(*)(..)>) = VariableAddress[pfn] :
-# 592| mu0_8(..(*)(..)) = Store : &:r0_7, r0_6
-# 593| r0_9(..(*)(..)) = FunctionAddress[FuncPtrTarget] :
-# 593| r0_10(glval<..(*)(..)>) = VariableAddress[pfn] :
-# 593| mu0_11(..(*)(..)) = Store : &:r0_10, r0_9
-# 594| r0_12(glval<..()(..)>) = FunctionAddress[FuncPtrTarget] :
-# 594| r0_13(glval<..(*)(..)>) = VariableAddress[pfn] :
-# 594| mu0_14(..(*)(..)) = Store : &:r0_13, r0_12
-# 595| v0_15(void) = NoOp :
-# 590| v0_16(void) = ReturnVoid :
-# 590| v0_17(void) = UnmodeledUse : mu*
-# 590| v0_18(void) = ExitFunction :
+# 592| r0_7(..(*)(..)) = CopyValue : r0_6
+# 592| r0_8(glval<..(*)(..)>) = VariableAddress[pfn] :
+# 592| mu0_9(..(*)(..)) = Store : &:r0_8, r0_7
+# 593| r0_10(..(*)(..)) = FunctionAddress[FuncPtrTarget] :
+# 593| r0_11(..(*)(..)) = CopyValue : r0_10
+# 593| r0_12(glval<..(*)(..)>) = VariableAddress[pfn] :
+# 593| mu0_13(..(*)(..)) = Store : &:r0_12, r0_11
+# 594| r0_14(glval<..()(..)>) = FunctionAddress[FuncPtrTarget] :
+# 594| r0_15(..(*)(..)) = CopyValue : r0_14
+# 594| r0_16(..(*)(..)) = CopyValue : r0_15
+# 594| r0_17(..(*)(..)) = CopyValue : r0_16
+# 594| r0_18(..(*)(..)) = CopyValue : r0_17
+# 594| r0_19(glval<..(*)(..)>) = VariableAddress[pfn] :
+# 594| mu0_20(..(*)(..)) = Store : &:r0_19, r0_18
+# 595| v0_21(void) = NoOp :
+# 590| v0_22(void) = ReturnVoid :
+# 590| v0_23(void) = UnmodeledUse : mu*
+# 590| v0_24(void) = AliasedUse : ~mu0_2
+# 590| v0_25(void) = ExitFunction :
# 615| void DeclareObject()
# 615| Block 0
-# 615| v0_0(void) = EnterFunction :
-# 615| mu0_1(unknown) = AliasedDefinition :
-# 615| mu0_2(unknown) = UnmodeledDefinition :
-# 616| r0_3(glval) = VariableAddress[s1] :
-# 616| r0_4(glval) = FunctionAddress[String] :
-# 616| v0_5(void) = Call : func:r0_4, this:r0_3
-# 616| mu0_6(unknown) = ^CallSideEffect : ~mu0_2
-# 617| r0_7(glval) = VariableAddress[s2] :
-# 617| r0_8(glval) = FunctionAddress[String] :
-# 617| r0_9(glval) = StringConstant["hello"] :
-# 617| r0_10(char *) = Convert : r0_9
-# 617| v0_11(void) = Call : func:r0_8, this:r0_7, 0:r0_10
-# 617| mu0_12(unknown) = ^CallSideEffect : ~mu0_2
-# 617| v0_13(void) = ^IndirectReadSideEffect[0] : &:r0_10, ~mu0_2
-# 617| mu0_14(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_10
-# 618| r0_15(glval) = VariableAddress[s3] :
-# 618| r0_16(glval) = FunctionAddress[ReturnObject] :
-# 618| r0_17(String) = Call : func:r0_16
-# 618| mu0_18(unknown) = ^CallSideEffect : ~mu0_2
-# 618| mu0_19(String) = Store : &:r0_15, r0_17
-# 619| r0_20(glval) = VariableAddress[s4] :
-# 619| r0_21(glval) = FunctionAddress[String] :
-# 619| r0_22(glval) = StringConstant["test"] :
-# 619| r0_23(char *) = Convert : r0_22
-# 619| v0_24(void) = Call : func:r0_21, this:r0_20, 0:r0_23
-# 619| mu0_25(unknown) = ^CallSideEffect : ~mu0_2
-# 619| v0_26(void) = ^IndirectReadSideEffect[0] : &:r0_23, ~mu0_2
-# 619| mu0_27(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_23
-# 620| v0_28(void) = NoOp :
-# 615| v0_29(void) = ReturnVoid :
-# 615| v0_30(void) = UnmodeledUse : mu*
-# 615| v0_31(void) = ExitFunction :
+# 615| v0_0(void) = EnterFunction :
+# 615| mu0_1(unknown) = AliasedDefinition :
+# 615| mu0_2(unknown) = UnmodeledDefinition :
+# 616| r0_3(glval) = VariableAddress[s1] :
+# 616| mu0_4(String) = Uninitialized[s1] : &:r0_3
+# 616| r0_5(glval) = FunctionAddress[String] :
+# 616| v0_6(void) = Call : func:r0_5, this:r0_3
+# 616| mu0_7(unknown) = ^CallSideEffect : ~mu0_2
+# 616| mu0_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_3
+# 617| r0_9(glval) = VariableAddress[s2] :
+# 617| mu0_10(String) = Uninitialized[s2] : &:r0_9
+# 617| r0_11(glval) = FunctionAddress[String] :
+# 617| r0_12(glval) = StringConstant["hello"] :
+# 617| r0_13(char *) = Convert : r0_12
+# 617| v0_14(void) = Call : func:r0_11, this:r0_9, 0:r0_13
+# 617| mu0_15(unknown) = ^CallSideEffect : ~mu0_2
+# 617| mu0_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9
+# 617| v0_17(void) = ^BufferReadSideEffect[0] : &:r0_13, ~mu0_2
+# 617| mu0_18(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_13
+# 618| r0_19(glval) = VariableAddress[s3] :
+# 618| r0_20(glval) = FunctionAddress[ReturnObject] :
+# 618| r0_21(String) = Call : func:r0_20
+# 618| mu0_22(unknown) = ^CallSideEffect : ~mu0_2
+# 618| mu0_23(String) = Store : &:r0_19, r0_21
+# 619| r0_24(glval) = VariableAddress[s4] :
+# 619| mu0_25(String) = Uninitialized[s4] : &:r0_24
+# 619| r0_26(glval) = FunctionAddress[String] :
+# 619| r0_27(glval) = StringConstant["test"] :
+# 619| r0_28(char *) = Convert : r0_27
+# 619| v0_29(void) = Call : func:r0_26, this:r0_24, 0:r0_28
+# 619| mu0_30(unknown) = ^CallSideEffect : ~mu0_2
+# 619| mu0_31(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_24
+# 619| v0_32(void) = ^BufferReadSideEffect[0] : &:r0_28, ~mu0_2
+# 619| mu0_33(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_28
+# 620| v0_34(void) = NoOp :
+# 615| v0_35(void) = ReturnVoid :
+# 615| v0_36(void) = UnmodeledUse : mu*
+# 615| v0_37(void) = AliasedUse : ~mu0_2
+# 615| v0_38(void) = ExitFunction :
# 622| void CallMethods(String&, String*, String)
# 622| Block 0
@@ -2802,33 +2892,35 @@ ir.cpp:
# 622| mu0_12(String) = InitializeParameter[s] : &:r0_11
# 623| r0_13(glval) = VariableAddress[r] :
# 623| r0_14(String &) = Load : &:r0_13, ~mu0_2
-# 623| r0_15(glval) = Convert : r0_14
-# 623| r0_16(glval) = FunctionAddress[c_str] :
-# 623| r0_17(char *) = Call : func:r0_16, this:r0_15
-# 623| mu0_18(unknown) = ^CallSideEffect : ~mu0_2
-# 623| v0_19(void) = ^IndirectReadSideEffect[-1] : &:r0_15, ~mu0_2
-# 623| mu0_20(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_15
-# 624| r0_21(glval) = VariableAddress[p] :
-# 624| r0_22(String *) = Load : &:r0_21, ~mu0_2
-# 624| r0_23(String *) = Convert : r0_22
-# 624| r0_24(glval) = FunctionAddress[c_str] :
-# 624| r0_25(char *) = Call : func:r0_24, this:r0_23
-# 624| mu0_26(unknown) = ^CallSideEffect : ~mu0_2
-# 624| v0_27(void) = ^IndirectReadSideEffect[-1] : &:r0_23, ~mu0_2
-# 624| mu0_28(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_23
-# 625| r0_29(glval) = VariableAddress[s] :
-# 625| r0_30(glval) = Convert : r0_29
-# 625| r0_31(glval) = FunctionAddress[c_str] :
-# 625| r0_32(char *) = Call : func:r0_31, this:r0_30
-# 625| mu0_33(unknown) = ^CallSideEffect : ~mu0_2
-# 625| v0_34(void) = ^IndirectReadSideEffect[-1] : &:r0_30, ~mu0_2
-# 625| mu0_35(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_30
-# 626| v0_36(void) = NoOp :
-# 622| v0_37(void) = ReturnIndirection : &:r0_5, ~mu0_2
-# 622| v0_38(void) = ReturnIndirection : &:r0_9, ~mu0_2
-# 622| v0_39(void) = ReturnVoid :
-# 622| v0_40(void) = UnmodeledUse : mu*
-# 622| v0_41(void) = ExitFunction :
+# 623| r0_15(glval) = CopyValue : r0_14
+# 623| r0_16(glval) = Convert : r0_15
+# 623| r0_17(glval) = FunctionAddress[c_str] :
+# 623| r0_18(char *) = Call : func:r0_17, this:r0_16
+# 623| mu0_19(unknown) = ^CallSideEffect : ~mu0_2
+# 623| v0_20(void) = ^BufferReadSideEffect[-1] : &:r0_16, ~mu0_2
+# 623| mu0_21(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_16
+# 624| r0_22(glval) = VariableAddress[p] :
+# 624| r0_23(String *) = Load : &:r0_22, ~mu0_2
+# 624| r0_24(String *) = Convert : r0_23
+# 624| r0_25(glval) = FunctionAddress[c_str] :
+# 624| r0_26(char *) = Call : func:r0_25, this:r0_24
+# 624| mu0_27(unknown) = ^CallSideEffect : ~mu0_2
+# 624| v0_28(void) = ^BufferReadSideEffect[-1] : &:r0_24, ~mu0_2
+# 624| mu0_29(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_24
+# 625| r0_30(glval) = VariableAddress[s] :
+# 625| r0_31(glval) = Convert : r0_30
+# 625| r0_32(glval) = FunctionAddress[c_str] :
+# 625| r0_33(char *) = Call : func:r0_32, this:r0_31
+# 625| mu0_34(unknown) = ^CallSideEffect : ~mu0_2
+# 625| v0_35(void) = ^BufferReadSideEffect[-1] : &:r0_31, ~mu0_2
+# 625| mu0_36(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_31
+# 626| v0_37(void) = NoOp :
+# 622| v0_38(void) = ReturnIndirection : &:r0_5, ~mu0_2
+# 622| v0_39(void) = ReturnIndirection : &:r0_9, ~mu0_2
+# 622| v0_40(void) = ReturnVoid :
+# 622| v0_41(void) = UnmodeledUse : mu*
+# 622| v0_42(void) = AliasedUse : ~mu0_2
+# 622| v0_43(void) = ExitFunction :
# 630| int C::StaticMemberFunction(int)
# 630| Block 0
@@ -2844,7 +2936,8 @@ ir.cpp:
# 630| r0_9(glval) = VariableAddress[#return] :
# 630| v0_10(void) = ReturnValue : &:r0_9, ~mu0_2
# 630| v0_11(void) = UnmodeledUse : mu*
-# 630| v0_12(void) = ExitFunction :
+# 630| v0_12(void) = AliasedUse : ~mu0_2
+# 630| v0_13(void) = ExitFunction :
# 634| int C::InstanceMemberFunction(int)
# 634| Block 0
@@ -2861,7 +2954,8 @@ ir.cpp:
# 634| r0_10(glval) = VariableAddress[#return] :
# 634| v0_11(void) = ReturnValue : &:r0_10, ~mu0_2
# 634| v0_12(void) = UnmodeledUse : mu*
-# 634| v0_13(void) = ExitFunction :
+# 634| v0_13(void) = AliasedUse : ~mu0_2
+# 634| v0_14(void) = ExitFunction :
# 638| int C::VirtualMemberFunction(int)
# 638| Block 0
@@ -2878,7 +2972,8 @@ ir.cpp:
# 638| r0_10(glval) = VariableAddress[#return] :
# 638| v0_11(void) = ReturnValue : &:r0_10, ~mu0_2
# 638| v0_12(void) = UnmodeledUse : mu*
-# 638| v0_13(void) = ExitFunction :
+# 638| v0_13(void) = AliasedUse : ~mu0_2
+# 638| v0_14(void) = ExitFunction :
# 642| void C::FieldAccess()
# 642| Block 0
@@ -2892,33 +2987,36 @@ ir.cpp:
# 643| mu0_7(int) = Store : &:r0_6, r0_4
# 644| r0_8(int) = Constant[1] :
# 644| r0_9(C *) = CopyValue : r0_3
-# 644| r0_10(glval) = FieldAddress[m_a] : r0_9
-# 644| mu0_11(int) = Store : &:r0_10, r0_8
-# 645| r0_12(int) = Constant[2] :
-#-----| r0_13(C *) = CopyValue : r0_3
-# 645| r0_14(glval) = FieldAddress[m_a] : r0_13
-# 645| mu0_15(int) = Store : &:r0_14, r0_12
-# 646| r0_16(glval) = VariableAddress[x] :
-# 646| mu0_17(int) = Uninitialized[x] : &:r0_16
-# 647| r0_18(C *) = CopyValue : r0_3
-# 647| r0_19(glval) = FieldAddress[m_a] : r0_18
-# 647| r0_20(int) = Load : &:r0_19, ~mu0_2
-# 647| r0_21(glval) = VariableAddress[x] :
-# 647| mu0_22(int) = Store : &:r0_21, r0_20
-# 648| r0_23(C *) = CopyValue : r0_3
-# 648| r0_24(glval) = FieldAddress[m_a] : r0_23
-# 648| r0_25(int) = Load : &:r0_24, ~mu0_2
-# 648| r0_26(glval) = VariableAddress[x] :
-# 648| mu0_27(int) = Store : &:r0_26, r0_25
-#-----| r0_28(C *) = CopyValue : r0_3
-# 649| r0_29(glval) = FieldAddress[m_a] : r0_28
-# 649| r0_30(int) = Load : &:r0_29, ~mu0_2
-# 649| r0_31(glval) = VariableAddress[x] :
-# 649| mu0_32(int) = Store : &:r0_31, r0_30
-# 650| v0_33(void) = NoOp :
-# 642| v0_34(void) = ReturnVoid :
-# 642| v0_35(void) = UnmodeledUse : mu*
-# 642| v0_36(void) = ExitFunction :
+# 644| r0_10(glval) = CopyValue : r0_9
+# 644| r0_11(glval) = FieldAddress[m_a] : r0_10
+# 644| mu0_12(int) = Store : &:r0_11, r0_8
+# 645| r0_13(int) = Constant[2] :
+#-----| r0_14(C *) = CopyValue : r0_3
+# 645| r0_15(glval) = FieldAddress[m_a] : r0_14
+# 645| mu0_16(int) = Store : &:r0_15, r0_13
+# 646| r0_17(glval) = VariableAddress[x] :
+# 646| mu0_18(int) = Uninitialized[x] : &:r0_17
+# 647| r0_19(C *) = CopyValue : r0_3
+# 647| r0_20(glval) = FieldAddress[m_a] : r0_19
+# 647| r0_21(int) = Load : &:r0_20, ~mu0_2
+# 647| r0_22(glval) = VariableAddress[x] :
+# 647| mu0_23(int) = Store : &:r0_22, r0_21
+# 648| r0_24(C *) = CopyValue : r0_3
+# 648| r0_25(glval) = CopyValue : r0_24
+# 648| r0_26(glval) = FieldAddress[m_a] : r0_25
+# 648| r0_27(int) = Load : &:r0_26, ~mu0_2
+# 648| r0_28(glval) = VariableAddress[x] :
+# 648| mu0_29(int) = Store : &:r0_28, r0_27
+#-----| r0_30(C *) = CopyValue : r0_3
+# 649| r0_31(glval) = FieldAddress[m_a] : r0_30
+# 649| r0_32(int) = Load : &:r0_31, ~mu0_2
+# 649| r0_33(glval) = VariableAddress[x] :
+# 649| mu0_34(int) = Store : &:r0_33, r0_32
+# 650| v0_35(void) = NoOp :
+# 642| v0_36(void) = ReturnVoid :
+# 642| v0_37(void) = UnmodeledUse : mu*
+# 642| v0_38(void) = AliasedUse : ~mu0_2
+# 642| v0_39(void) = ExitFunction :
# 652| void C::MethodCalls()
# 652| Block 0
@@ -2931,58 +3029,63 @@ ir.cpp:
# 653| r0_6(int) = Constant[0] :
# 653| r0_7(int) = Call : func:r0_5, this:r0_4, 0:r0_6
# 653| mu0_8(unknown) = ^CallSideEffect : ~mu0_2
-# 653| v0_9(void) = ^IndirectReadSideEffect[-1] : &:r0_4, ~mu0_2
+# 653| v0_9(void) = ^BufferReadSideEffect[-1] : &:r0_4, ~mu0_2
# 653| mu0_10(C) = ^IndirectMayWriteSideEffect[-1] : &:r0_4
# 654| r0_11(C *) = CopyValue : r0_3
-# 654| r0_12(glval) = FunctionAddress[InstanceMemberFunction] :
-# 654| r0_13(int) = Constant[1] :
-# 654| r0_14(int) = Call : func:r0_12, this:r0_11, 0:r0_13
-# 654| mu0_15(unknown) = ^CallSideEffect : ~mu0_2
-# 654| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_11, ~mu0_2
-# 654| mu0_17(C) = ^IndirectMayWriteSideEffect[-1] : &:r0_11
-#-----| r0_18(C *) = CopyValue : r0_3
-# 655| r0_19(glval) = FunctionAddress[InstanceMemberFunction] :
-# 655| r0_20(int) = Constant[2] :
-# 655| r0_21(int) = Call : func:r0_19, this:r0_18, 0:r0_20
-# 655| mu0_22(unknown) = ^CallSideEffect : ~mu0_2
-#-----| v0_23(void) = ^IndirectReadSideEffect[-1] : &:r0_18, ~mu0_2
-#-----| mu0_24(C) = ^IndirectMayWriteSideEffect[-1] : &:r0_18
-# 656| v0_25(void) = NoOp :
-# 652| v0_26(void) = ReturnVoid :
-# 652| v0_27(void) = UnmodeledUse : mu*
-# 652| v0_28(void) = ExitFunction :
+# 654| r0_12(glval) = CopyValue : r0_11
+# 654| r0_13(glval) = FunctionAddress[InstanceMemberFunction] :
+# 654| r0_14(int) = Constant[1] :
+# 654| r0_15(int) = Call : func:r0_13, this:r0_12, 0:r0_14
+# 654| mu0_16(unknown) = ^CallSideEffect : ~mu0_2
+# 654| v0_17(void) = ^BufferReadSideEffect[-1] : &:r0_12, ~mu0_2
+# 654| mu0_18(C) = ^IndirectMayWriteSideEffect[-1] : &:r0_12
+#-----| r0_19(C *) = CopyValue : r0_3
+# 655| r0_20(glval) = FunctionAddress[InstanceMemberFunction] :
+# 655| r0_21(int) = Constant[2] :
+# 655| r0_22(int) = Call : func:r0_20, this:r0_19, 0:r0_21
+# 655| mu0_23(unknown) = ^CallSideEffect : ~mu0_2
+#-----| v0_24(void) = ^BufferReadSideEffect[-1] : &:r0_19, ~mu0_2
+#-----| mu0_25(C) = ^IndirectMayWriteSideEffect[-1] : &:r0_19
+# 656| v0_26(void) = NoOp :
+# 652| v0_27(void) = ReturnVoid :
+# 652| v0_28(void) = UnmodeledUse : mu*
+# 652| v0_29(void) = AliasedUse : ~mu0_2
+# 652| v0_30(void) = ExitFunction :
# 658| void C::C()
# 658| Block 0
-# 658| v0_0(void) = EnterFunction :
-# 658| mu0_1(unknown) = AliasedDefinition :
-# 658| mu0_2(unknown) = UnmodeledDefinition :
-# 658| r0_3(glval) = InitializeThis :
-# 659| r0_4(glval) = FieldAddress[m_a] : r0_3
-# 659| r0_5(int) = Constant[1] :
-# 659| mu0_6(int) = Store : &:r0_4, r0_5
-# 663| r0_7(glval) = FieldAddress[m_b] : r0_3
-# 663| r0_8(glval) = FunctionAddress[String] :
-# 663| v0_9(void) = Call : func:r0_8, this:r0_7
-# 663| mu0_10(unknown) = ^CallSideEffect : ~mu0_2
-# 660| r0_11(glval) = FieldAddress[m_c] : r0_3
-# 660| r0_12(char) = Constant[3] :
-# 660| mu0_13(char) = Store : &:r0_11, r0_12
-# 661| r0_14(glval) = FieldAddress[m_e] : r0_3
-# 661| r0_15(void *) = Constant[0] :
-# 661| mu0_16(void *) = Store : &:r0_14, r0_15
-# 662| r0_17(glval) = FieldAddress[m_f] : r0_3
-# 662| r0_18(glval) = FunctionAddress[String] :
-# 662| r0_19(glval) = StringConstant["test"] :
-# 662| r0_20(char *) = Convert : r0_19
-# 662| v0_21(void) = Call : func:r0_18, this:r0_17, 0:r0_20
-# 662| mu0_22(unknown) = ^CallSideEffect : ~mu0_2
-# 662| v0_23(void) = ^IndirectReadSideEffect[0] : &:r0_20, ~mu0_2
-# 662| mu0_24(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_20
-# 664| v0_25(void) = NoOp :
-# 658| v0_26(void) = ReturnVoid :
-# 658| v0_27(void) = UnmodeledUse : mu*
-# 658| v0_28(void) = ExitFunction :
+# 658| v0_0(void) = EnterFunction :
+# 658| mu0_1(unknown) = AliasedDefinition :
+# 658| mu0_2(unknown) = UnmodeledDefinition :
+# 658| r0_3(glval) = InitializeThis :
+# 659| r0_4(glval) = FieldAddress[m_a] : r0_3
+# 659| r0_5(int) = Constant[1] :
+# 659| mu0_6(int) = Store : &:r0_4, r0_5
+# 663| r0_7(glval) = FieldAddress[m_b] : r0_3
+# 663| r0_8(glval) = FunctionAddress[String] :
+# 663| v0_9(void) = Call : func:r0_8, this:r0_7
+# 663| mu0_10(unknown) = ^CallSideEffect : ~mu0_2
+# 663| mu0_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_7
+# 660| r0_12(glval) = FieldAddress[m_c] : r0_3
+# 660| r0_13(char) = Constant[3] :
+# 660| mu0_14(char) = Store : &:r0_12, r0_13
+# 661| r0_15(glval) = FieldAddress[m_e] : r0_3
+# 661| r0_16(void *) = Constant[0] :
+# 661| mu0_17(void *) = Store : &:r0_15, r0_16
+# 662| r0_18(glval) = FieldAddress[m_f] : r0_3
+# 662| r0_19(glval) = FunctionAddress[String] :
+# 662| r0_20(glval) = StringConstant["test"] :
+# 662| r0_21(char *) = Convert : r0_20
+# 662| v0_22(void) = Call : func:r0_19, this:r0_18, 0:r0_21
+# 662| mu0_23(unknown) = ^CallSideEffect : ~mu0_2
+# 662| mu0_24(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_18
+# 662| v0_25(void) = ^BufferReadSideEffect[0] : &:r0_21, ~mu0_2
+# 662| mu0_26(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_21
+# 664| v0_27(void) = NoOp :
+# 658| v0_28(void) = ReturnVoid :
+# 658| v0_29(void) = UnmodeledUse : mu*
+# 658| v0_30(void) = AliasedUse : ~mu0_2
+# 658| v0_31(void) = ExitFunction :
# 675| int DerefReference(int&)
# 675| Block 0
@@ -3002,7 +3105,8 @@ ir.cpp:
# 675| r0_13(glval) = VariableAddress[#return] :
# 675| v0_14(void) = ReturnValue : &:r0_13, ~mu0_2
# 675| v0_15(void) = UnmodeledUse : mu*
-# 675| v0_16(void) = ExitFunction :
+# 675| v0_16(void) = AliasedUse : ~mu0_2
+# 675| v0_17(void) = ExitFunction :
# 679| int& TakeReference()
# 679| Block 0
@@ -3011,11 +3115,13 @@ ir.cpp:
# 679| mu0_2(unknown) = UnmodeledDefinition :
# 680| r0_3(glval) = VariableAddress[#return] :
# 680| r0_4(glval) = VariableAddress[g] :
-# 680| mu0_5(int &) = Store : &:r0_3, r0_4
-# 679| r0_6(glval) = VariableAddress[#return] :
-# 679| v0_7(void) = ReturnValue : &:r0_6, ~mu0_2
-# 679| v0_8(void) = UnmodeledUse : mu*
-# 679| v0_9(void) = ExitFunction :
+# 680| r0_5(int &) = CopyValue : r0_4
+# 680| mu0_6(int &) = Store : &:r0_3, r0_5
+# 679| r0_7(glval) = VariableAddress[#return] :
+# 679| v0_8(void) = ReturnValue : &:r0_7, ~mu0_2
+# 679| v0_9(void) = UnmodeledUse : mu*
+# 679| v0_10(void) = AliasedUse : ~mu0_2
+# 679| v0_11(void) = ExitFunction :
# 685| void InitReference(int)
# 685| Block 0
@@ -3026,44 +3132,53 @@ ir.cpp:
# 685| mu0_4(int) = InitializeParameter[x] : &:r0_3
# 686| r0_5(glval) = VariableAddress[r] :
# 686| r0_6(glval) = VariableAddress[x] :
-# 686| mu0_7(int &) = Store : &:r0_5, r0_6
-# 687| r0_8(glval) = VariableAddress[r2] :
-# 687| r0_9(glval) = VariableAddress[r] :
-# 687| r0_10(int &) = Load : &:r0_9, ~mu0_2
-# 687| mu0_11(int &) = Store : &:r0_8, r0_10
-# 688| r0_12(glval) = VariableAddress[r3] :
-# 688| r0_13(glval) = FunctionAddress[ReturnReference] :
-# 688| r0_14(String &) = Call : func:r0_13
-# 688| mu0_15(unknown) = ^CallSideEffect : ~mu0_2
-# 688| r0_16(glval) = Convert : r0_14
-# 688| mu0_17(String &) = Store : &:r0_12, r0_16
-# 689| v0_18(void) = NoOp :
-# 685| v0_19(void) = ReturnVoid :
-# 685| v0_20(void) = UnmodeledUse : mu*
-# 685| v0_21(void) = ExitFunction :
+# 686| r0_7(int &) = CopyValue : r0_6
+# 686| mu0_8(int &) = Store : &:r0_5, r0_7
+# 687| r0_9(glval) = VariableAddress[r2] :
+# 687| r0_10(glval) = VariableAddress[r] :
+# 687| r0_11(int &) = Load : &:r0_10, ~mu0_2
+# 687| r0_12(glval) = CopyValue : r0_11
+# 687| r0_13(int &) = CopyValue : r0_12
+# 687| mu0_14(int &) = Store : &:r0_9, r0_13
+# 688| r0_15(glval) = VariableAddress[r3] :
+# 688| r0_16(glval) = FunctionAddress[ReturnReference] :
+# 688| r0_17(String &) = Call : func:r0_16
+# 688| mu0_18(unknown) = ^CallSideEffect : ~mu0_2
+# 688| r0_19(glval) = CopyValue : r0_17
+# 688| r0_20(glval) = Convert : r0_19
+# 688| r0_21(String &) = CopyValue : r0_20
+# 688| mu0_22(String &) = Store : &:r0_15, r0_21
+# 689| v0_23(void) = NoOp :
+# 685| v0_24(void) = ReturnVoid :
+# 685| v0_25(void) = UnmodeledUse : mu*
+# 685| v0_26(void) = AliasedUse : ~mu0_2
+# 685| v0_27(void) = ExitFunction :
# 691| void ArrayReferences()
# 691| Block 0
-# 691| v0_0(void) = EnterFunction :
-# 691| mu0_1(unknown) = AliasedDefinition :
-# 691| mu0_2(unknown) = UnmodeledDefinition :
-# 692| r0_3(glval) = VariableAddress[a] :
-# 692| mu0_4(int[10]) = Uninitialized[a] : &:r0_3
-# 693| r0_5(glval) = VariableAddress[ra] :
-# 693| r0_6(glval) = VariableAddress[a] :
-# 693| mu0_7(int(&)[10]) = Store : &:r0_5, r0_6
-# 694| r0_8(glval) = VariableAddress[x] :
-# 694| r0_9(glval) = VariableAddress[ra] :
-# 694| r0_10(int(&)[10]) = Load : &:r0_9, ~mu0_2
-# 694| r0_11(int *) = Convert : r0_10
-# 694| r0_12(int) = Constant[5] :
-# 694| r0_13(glval) = PointerAdd[4] : r0_11, r0_12
-# 694| r0_14(int) = Load : &:r0_13, ~mu0_2
-# 694| mu0_15(int) = Store : &:r0_8, r0_14
-# 695| v0_16(void) = NoOp :
-# 691| v0_17(void) = ReturnVoid :
-# 691| v0_18(void) = UnmodeledUse : mu*
-# 691| v0_19(void) = ExitFunction :
+# 691| v0_0(void) = EnterFunction :
+# 691| mu0_1(unknown) = AliasedDefinition :
+# 691| mu0_2(unknown) = UnmodeledDefinition :
+# 692| r0_3(glval) = VariableAddress[a] :
+# 692| mu0_4(int[10]) = Uninitialized[a] : &:r0_3
+# 693| r0_5(glval) = VariableAddress[ra] :
+# 693| r0_6(glval) = VariableAddress[a] :
+# 693| r0_7(int(&)[10]) = CopyValue : r0_6
+# 693| mu0_8(int(&)[10]) = Store : &:r0_5, r0_7
+# 694| r0_9(glval) = VariableAddress[x] :
+# 694| r0_10(glval) = VariableAddress[ra] :
+# 694| r0_11(int(&)[10]) = Load : &:r0_10, ~mu0_2
+# 694| r0_12(glval) = CopyValue : r0_11
+# 694| r0_13(int *) = Convert : r0_12
+# 694| r0_14(int) = Constant[5] :
+# 694| r0_15(glval) = PointerAdd[4] : r0_13, r0_14
+# 694| r0_16(int) = Load : &:r0_15, ~mu0_2
+# 694| mu0_17(int) = Store : &:r0_9, r0_16
+# 695| v0_18(void) = NoOp :
+# 691| v0_19(void) = ReturnVoid :
+# 691| v0_20(void) = UnmodeledUse : mu*
+# 691| v0_21(void) = AliasedUse : ~mu0_2
+# 691| v0_22(void) = ExitFunction :
# 697| void FunctionReferences()
# 697| Block 0
@@ -3072,20 +3187,24 @@ ir.cpp:
# 697| mu0_2(unknown) = UnmodeledDefinition :
# 698| r0_3(glval<..(&)(..)>) = VariableAddress[rfn] :
# 698| r0_4(glval<..()(..)>) = FunctionAddress[FuncPtrTarget] :
-# 698| mu0_5(..(&)(..)) = Store : &:r0_3, r0_4
-# 699| r0_6(glval<..(*)(..)>) = VariableAddress[pfn] :
-# 699| r0_7(glval<..(&)(..)>) = VariableAddress[rfn] :
-# 699| r0_8(..(&)(..)) = Load : &:r0_7, ~mu0_2
-# 699| mu0_9(..(*)(..)) = Store : &:r0_6, r0_8
-# 700| r0_10(glval<..(&)(..)>) = VariableAddress[rfn] :
-# 700| r0_11(..(&)(..)) = Load : &:r0_10, ~mu0_2
-# 700| r0_12(int) = Constant[5] :
-# 700| r0_13(int) = Call : func:r0_11, 0:r0_12
-# 700| mu0_14(unknown) = ^CallSideEffect : ~mu0_2
-# 701| v0_15(void) = NoOp :
-# 697| v0_16(void) = ReturnVoid :
-# 697| v0_17(void) = UnmodeledUse : mu*
-# 697| v0_18(void) = ExitFunction :
+# 698| r0_5(..(&)(..)) = CopyValue : r0_4
+# 698| mu0_6(..(&)(..)) = Store : &:r0_3, r0_5
+# 699| r0_7(glval<..(*)(..)>) = VariableAddress[pfn] :
+# 699| r0_8(glval<..(&)(..)>) = VariableAddress[rfn] :
+# 699| r0_9(..(&)(..)) = Load : &:r0_8, ~mu0_2
+# 699| r0_10(..(*)(..)) = CopyValue : r0_9
+# 699| mu0_11(..(*)(..)) = Store : &:r0_7, r0_10
+# 700| r0_12(glval<..(&)(..)>) = VariableAddress[rfn] :
+# 700| r0_13(..(&)(..)) = Load : &:r0_12, ~mu0_2
+# 700| r0_14(..(*)(..)) = CopyValue : r0_13
+# 700| r0_15(int) = Constant[5] :
+# 700| r0_16(int) = Call : func:r0_14, 0:r0_15
+# 700| mu0_17(unknown) = ^CallSideEffect : ~mu0_2
+# 701| v0_18(void) = NoOp :
+# 697| v0_19(void) = ReturnVoid :
+# 697| v0_20(void) = UnmodeledUse : mu*
+# 697| v0_21(void) = AliasedUse : ~mu0_2
+# 697| v0_22(void) = ExitFunction :
# 704| int min(int, int)
# 704| Block 0
@@ -3127,7 +3246,8 @@ ir.cpp:
# 704| r3_3(glval) = VariableAddress[#return] :
# 704| v3_4(void) = ReturnValue : &:r3_3, ~mu0_2
# 704| v3_5(void) = UnmodeledUse : mu*
-# 704| v3_6(void) = ExitFunction :
+# 704| v3_6(void) = AliasedUse : ~mu0_2
+# 704| v3_7(void) = ExitFunction :
# 708| int CallMin(int, int)
# 708| Block 0
@@ -3150,7 +3270,8 @@ ir.cpp:
# 708| r0_16(glval) = VariableAddress[#return] :
# 708| v0_17(void) = ReturnValue : &:r0_16, ~mu0_2
# 708| v0_18(void) = UnmodeledUse : mu*
-# 708| v0_19(void) = ExitFunction :
+# 708| v0_19(void) = AliasedUse : ~mu0_2
+# 708| v0_20(void) = ExitFunction :
# 715| long Outer::Func(void*, char)
# 715| Block 0
@@ -3170,7 +3291,8 @@ ir.cpp:
# 715| r0_13(glval) = VariableAddress[#return] :
# 715| v0_14(void) = ReturnValue : &:r0_13, ~mu0_2
# 715| v0_15(void) = UnmodeledUse : mu*
-# 715| v0_16(void) = ExitFunction :
+# 715| v0_16(void) = AliasedUse : ~mu0_2
+# 715| v0_17(void) = ExitFunction :
# 720| double CallNestedTemplateFunc()
# 720| Block 0
@@ -3183,14 +3305,15 @@ ir.cpp:
# 721| r0_6(char) = Constant[111] :
# 721| r0_7(long) = Call : func:r0_4, 0:r0_5, 1:r0_6
# 721| mu0_8(unknown) = ^CallSideEffect : ~mu0_2
-# 721| v0_9(void) = ^IndirectReadSideEffect[0] : &:r0_5, ~mu0_2
+# 721| v0_9(void) = ^BufferReadSideEffect[0] : &:r0_5, ~mu0_2
# 721| mu0_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_5
# 721| r0_11(double) = Convert : r0_7
# 721| mu0_12(double) = Store : &:r0_3, r0_11
# 720| r0_13(glval) = VariableAddress[#return] :
# 720| v0_14(void) = ReturnValue : &:r0_13, ~mu0_2
# 720| v0_15(void) = UnmodeledUse : mu*
-# 720| v0_16(void) = ExitFunction :
+# 720| v0_16(void) = AliasedUse : ~mu0_2
+# 720| v0_17(void) = ExitFunction :
# 724| void TryCatch(bool)
# 724| Block 0
@@ -3210,7 +3333,8 @@ ir.cpp:
# 724| Block 1
# 724| v1_0(void) = UnmodeledUse : mu*
-# 724| v1_1(void) = ExitFunction :
+# 724| v1_1(void) = AliasedUse : ~mu0_2
+# 724| v1_2(void) = ExitFunction :
# 724| Block 2
# 724| v2_0(void) = Unwind :
@@ -3257,9 +3381,10 @@ ir.cpp:
# 731| r7_3(char *) = Convert : r7_2
# 731| v7_4(void) = Call : func:r7_1, this:r7_0, 0:r7_3
# 731| mu7_5(unknown) = ^CallSideEffect : ~mu0_2
-# 731| v7_6(void) = ^IndirectReadSideEffect[0] : &:r7_3, ~mu0_2
-# 731| mu7_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r7_3
-# 731| v7_8(void) = ThrowValue : &:r7_0, ~mu0_2
+# 731| mu7_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r7_0
+# 731| v7_7(void) = ^BufferReadSideEffect[0] : &:r7_3, ~mu0_2
+# 731| mu7_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r7_3
+# 731| v7_9(void) = ThrowValue : &:r7_0, ~mu0_2
#-----| Exception -> Block 9
# 733| Block 8
@@ -3274,19 +3399,20 @@ ir.cpp:
#-----| Goto -> Block 10
# 735| Block 10
-# 735| r10_0(glval) = VariableAddress[s] :
-# 735| mu10_1(char *) = InitializeParameter[s] : &:r10_0
-# 735| r10_2(char *) = Load : &:r10_0, ~mu10_1
-# 735| mu10_3(unknown) = InitializeIndirection[s] : &:r10_2
-# 736| r10_4(glval) = VariableAddress[#throw736:5] :
-# 736| r10_5(glval) = FunctionAddress[String] :
-# 736| r10_6(glval) = VariableAddress[s] :
-# 736| r10_7(char *) = Load : &:r10_6, ~mu0_2
-# 736| v10_8(void) = Call : func:r10_5, this:r10_4, 0:r10_7
-# 736| mu10_9(unknown) = ^CallSideEffect : ~mu0_2
-# 736| v10_10(void) = ^IndirectReadSideEffect[0] : &:r10_7, ~mu0_2
-# 736| mu10_11(unknown) = ^BufferMayWriteSideEffect[0] : &:r10_7
-# 736| v10_12(void) = ThrowValue : &:r10_4, ~mu0_2
+# 735| r10_0(glval) = VariableAddress[s] :
+# 735| mu10_1(char *) = InitializeParameter[s] : &:r10_0
+# 735| r10_2(char *) = Load : &:r10_0, ~mu10_1
+# 735| mu10_3(unknown) = InitializeIndirection[s] : &:r10_2
+# 736| r10_4(glval) = VariableAddress[#throw736:5] :
+# 736| r10_5(glval) = FunctionAddress[String] :
+# 736| r10_6(glval) = VariableAddress[s] :
+# 736| r10_7(char *) = Load : &:r10_6, ~mu0_2
+# 736| v10_8(void) = Call : func:r10_5, this:r10_4, 0:r10_7
+# 736| mu10_9(unknown) = ^CallSideEffect : ~mu0_2
+# 736| mu10_10(String) = ^IndirectMayWriteSideEffect[-1] : &:r10_4
+# 736| v10_11(void) = ^BufferReadSideEffect[0] : &:r10_7, ~mu0_2
+# 736| mu10_12(unknown) = ^BufferMayWriteSideEffect[0] : &:r10_7
+# 736| v10_13(void) = ThrowValue : &:r10_4, ~mu0_2
#-----| Exception -> Block 2
# 738| Block 11
@@ -3324,59 +3450,70 @@ ir.cpp:
#-----| mu0_7(unknown) = InitializeIndirection[p#0] : &:r0_6
#-----| r0_8(Base *) = CopyValue : r0_3
#-----| r0_9(glval) = FieldAddress[base_s] : r0_8
-# 745| r0_10(glval) = FunctionAddress[operator=] :
-#-----| r0_11(glval) = VariableAddress[p#0] :
-#-----| r0_12(Base &) = Load : &:r0_11, ~mu0_2
-#-----| r0_13(glval) = FieldAddress[base_s] : r0_12
-# 745| r0_14(String &) = Call : func:r0_10, this:r0_9, 0:r0_13
-# 745| mu0_15(unknown) = ^CallSideEffect : ~mu0_2
-#-----| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~mu0_2
-#-----| v0_17(void) = ^IndirectReadSideEffect[0] : &:r0_13, ~mu0_2
-#-----| mu0_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9
-#-----| mu0_19(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_13
-#-----| r0_20(glval) = VariableAddress[#return] :
-#-----| r0_21(Base *) = CopyValue : r0_3
-#-----| mu0_22(Base &) = Store : &:r0_20, r0_21
-#-----| v0_23(void) = ReturnIndirection : &:r0_6, ~mu0_2
-# 745| r0_24(glval) = VariableAddress[#return] :
-# 745| v0_25(void) = ReturnValue : &:r0_24, ~mu0_2
-# 745| v0_26(void) = UnmodeledUse : mu*
-# 745| v0_27(void) = ExitFunction :
+#-----| r0_10(String *) = CopyValue : r0_9
+# 745| r0_11(glval) = FunctionAddress[operator=] :
+#-----| r0_12(glval) = VariableAddress[p#0] :
+#-----| r0_13(Base &) = Load : &:r0_12, ~mu0_2
+#-----| r0_14(glval) = CopyValue : r0_13
+#-----| r0_15(glval) = FieldAddress[base_s] : r0_14
+#-----| r0_16(String &) = CopyValue : r0_15
+# 745| r0_17(String &) = Call : func:r0_11, this:r0_10, 0:r0_16
+# 745| mu0_18(unknown) = ^CallSideEffect : ~mu0_2
+#-----| v0_19(void) = ^BufferReadSideEffect[-1] : &:r0_10, ~mu0_2
+#-----| v0_20(void) = ^BufferReadSideEffect[0] : &:r0_16, ~mu0_2
+#-----| mu0_21(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_10
+#-----| mu0_22(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_16
+#-----| r0_23(glval) = CopyValue : r0_17
+#-----| r0_24(glval) = VariableAddress[#return] :
+#-----| r0_25(Base *) = CopyValue : r0_3
+#-----| r0_26(glval) = CopyValue : r0_25
+#-----| r0_27(Base &) = CopyValue : r0_26
+#-----| mu0_28(Base &) = Store : &:r0_24, r0_27
+#-----| v0_29(void) = ReturnIndirection : &:r0_6, ~mu0_2
+# 745| r0_30(glval) = VariableAddress[#return] :
+# 745| v0_31(void) = ReturnValue : &:r0_30, ~mu0_2
+# 745| v0_32(void) = UnmodeledUse : mu*
+# 745| v0_33(void) = AliasedUse : ~mu0_2
+# 745| v0_34(void) = ExitFunction :
# 745| void Base::Base(Base const&)
# 745| Block 0
-# 745| v0_0(void) = EnterFunction :
-# 745| mu0_1(unknown) = AliasedDefinition :
-# 745| mu0_2(unknown) = UnmodeledDefinition :
-# 745| r0_3(glval) = InitializeThis :
-#-----| r0_4(glval) = VariableAddress[p#0] :
-#-----| mu0_5(Base &) = InitializeParameter[p#0] : &:r0_4
-#-----| r0_6(Base &) = Load : &:r0_4, ~mu0_5
-#-----| mu0_7(unknown) = InitializeIndirection[p#0] : &:r0_6
-# 745| r0_8(glval) = FieldAddress[base_s] : r0_3
-# 745| r0_9(glval) = FunctionAddress[String] :
-# 745| v0_10(void) = Call : func:r0_9, this:r0_8
-# 745| mu0_11(unknown) = ^CallSideEffect : ~mu0_2
-# 745| v0_12(void) = NoOp :
-#-----| v0_13(void) = ReturnIndirection : &:r0_6, ~mu0_2
-# 745| v0_14(void) = ReturnVoid :
-# 745| v0_15(void) = UnmodeledUse : mu*
-# 745| v0_16(void) = ExitFunction :
+# 745| v0_0(void) = EnterFunction :
+# 745| mu0_1(unknown) = AliasedDefinition :
+# 745| mu0_2(unknown) = UnmodeledDefinition :
+# 745| r0_3(glval) = InitializeThis :
+#-----| r0_4(glval) = VariableAddress[p#0] :
+#-----| mu0_5(Base &) = InitializeParameter[p#0] : &:r0_4
+#-----| r0_6(Base &) = Load : &:r0_4, ~mu0_5
+#-----| mu0_7(unknown) = InitializeIndirection[p#0] : &:r0_6
+# 745| r0_8(glval) = FieldAddress[base_s] : r0_3
+# 745| r0_9(glval) = FunctionAddress[String] :
+# 745| v0_10(void) = Call : func:r0_9, this:r0_8
+# 745| mu0_11(unknown) = ^CallSideEffect : ~mu0_2
+# 745| mu0_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_8
+# 745| v0_13(void) = NoOp :
+#-----| v0_14(void) = ReturnIndirection : &:r0_6, ~mu0_2
+# 745| v0_15(void) = ReturnVoid :
+# 745| v0_16(void) = UnmodeledUse : mu*
+# 745| v0_17(void) = AliasedUse : ~mu0_2
+# 745| v0_18(void) = ExitFunction :
# 748| void Base::Base()
# 748| Block 0
-# 748| v0_0(void) = EnterFunction :
-# 748| mu0_1(unknown) = AliasedDefinition :
-# 748| mu0_2(unknown) = UnmodeledDefinition :
-# 748| r0_3(glval) = InitializeThis :
-# 748| r0_4(glval) = FieldAddress[base_s] : r0_3
-# 748| r0_5(glval) = FunctionAddress[String] :
-# 748| v0_6(void) = Call : func:r0_5, this:r0_4
-# 748| mu0_7(unknown) = ^CallSideEffect : ~mu0_2
-# 749| v0_8(void) = NoOp :
-# 748| v0_9(void) = ReturnVoid :
-# 748| v0_10(void) = UnmodeledUse : mu*
-# 748| v0_11(void) = ExitFunction :
+# 748| v0_0(void) = EnterFunction :
+# 748| mu0_1(unknown) = AliasedDefinition :
+# 748| mu0_2(unknown) = UnmodeledDefinition :
+# 748| r0_3(glval) = InitializeThis :
+# 748| r0_4(glval) = FieldAddress[base_s] : r0_3
+# 748| r0_5(glval) = FunctionAddress[String] :
+# 748| v0_6(void) = Call : func:r0_5, this:r0_4
+# 748| mu0_7(unknown) = ^CallSideEffect : ~mu0_2
+# 748| mu0_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_4
+# 749| v0_9(void) = NoOp :
+# 748| v0_10(void) = ReturnVoid :
+# 748| v0_11(void) = UnmodeledUse : mu*
+# 748| v0_12(void) = AliasedUse : ~mu0_2
+# 748| v0_13(void) = ExitFunction :
# 750| void Base::~Base()
# 750| Block 0
@@ -3391,554 +3528,639 @@ ir.cpp:
# 751| mu0_8(unknown) = ^CallSideEffect : ~mu0_2
# 750| v0_9(void) = ReturnVoid :
# 750| v0_10(void) = UnmodeledUse : mu*
-# 750| v0_11(void) = ExitFunction :
+# 750| v0_11(void) = AliasedUse : ~mu0_2
+# 750| v0_12(void) = ExitFunction :
# 754| Middle& Middle::operator=(Middle const&)
# 754| Block 0
-# 754| v0_0(void) = EnterFunction :
-# 754| mu0_1(unknown) = AliasedDefinition :
-# 754| mu0_2(unknown) = UnmodeledDefinition :
-# 754| r0_3(glval) = InitializeThis :
-#-----| r0_4(glval) = VariableAddress[p#0] :
-#-----| mu0_5(Middle &) = InitializeParameter[p#0] : &:r0_4
-#-----| r0_6(Middle &) = Load : &:r0_4, ~mu0_5
-#-----| mu0_7(unknown) = InitializeIndirection[p#0] : &:r0_6
-#-----| r0_8(Middle *) = CopyValue : r0_3
-#-----| r0_9(Base *) = ConvertToBase[Middle : Base] : r0_8
-# 754| r0_10(glval) = FunctionAddress[operator=] :
-#-----| r0_11(glval) = VariableAddress[p#0] :
-#-----| r0_12(Middle &) = Load : &:r0_11, ~mu0_2
-#-----| r0_13(Base *) = ConvertToBase[Middle : Base] : r0_12
-# 754| r0_14(Base &) = Call : func:r0_10, this:r0_9, 0:r0_13
-# 754| mu0_15(unknown) = ^CallSideEffect : ~mu0_2
-#-----| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~mu0_2
-#-----| v0_17(void) = ^IndirectReadSideEffect[0] : &:r0_13, ~mu0_2
-#-----| mu0_18(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_9
-#-----| mu0_19(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_13
-#-----| r0_20(Middle *) = CopyValue : r0_3
-#-----| r0_21(glval) = FieldAddress[middle_s] : r0_20
-# 754| r0_22(glval) = FunctionAddress[operator=] :
-#-----| r0_23(glval) = VariableAddress[p#0] :
-#-----| r0_24(Middle &) = Load : &:r0_23, ~mu0_2
-#-----| r0_25(glval) = FieldAddress[middle_s] : r0_24
-# 754| r0_26(String &) = Call : func:r0_22, this:r0_21, 0:r0_25
-# 754| mu0_27(unknown) = ^CallSideEffect : ~mu0_2
-#-----| v0_28(void) = ^IndirectReadSideEffect[-1] : &:r0_21, ~mu0_2
-#-----| v0_29(void) = ^IndirectReadSideEffect[0] : &:r0_25, ~mu0_2
-#-----| mu0_30(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_21
-#-----| mu0_31(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_25
-#-----| r0_32(glval) = VariableAddress[#return] :
-#-----| r0_33(Middle *) = CopyValue : r0_3
-#-----| mu0_34(Middle &) = Store : &:r0_32, r0_33
-#-----| v0_35(void) = ReturnIndirection : &:r0_6, ~mu0_2
-# 754| r0_36(glval) = VariableAddress[#return] :
-# 754| v0_37(void) = ReturnValue : &:r0_36, ~mu0_2
-# 754| v0_38(void) = UnmodeledUse : mu*
-# 754| v0_39(void) = ExitFunction :
+# 754| v0_0(void) = EnterFunction :
+# 754| mu0_1(unknown) = AliasedDefinition :
+# 754| mu0_2(unknown) = UnmodeledDefinition :
+# 754| r0_3(glval