From 49a4318ab1af354c3b335b448a33696c635833cd Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 20 Aug 2024 00:30:16 -0400 Subject: [PATCH 001/470] DRAFT: Go MaD docs first draft (still need to change Select example) --- .../customizing-library-models-for-go.rst | 413 ++++++++++++++++++ 1 file changed, 413 insertions(+) create mode 100644 docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst new file mode 100644 index 00000000000..61861039f03 --- /dev/null +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -0,0 +1,413 @@ +.. _customizing-library-models-for-csharp: + +Customizing library models for Go +================================= + +You can model the methods and callables that control data flow in any framework or library. This is especially useful for custom frameworks or niche libraries, that are not supported by the standard CodeQL libraries. + +.. include:: ../reusables/beta-note-customizing-library-models.rst + +About this article +------------------ + +This article contains reference material about how to define custom models for sources, sinks, and flow summaries for Go dependencies in data extension files. + +About data extensions +--------------------- + +You can customize analysis by defining models (summaries, sinks, and sources) of your code's Go dependencies in data extension files. Each model defines the behavior of one or more elements of your library or framework, such as methods, properties, and callables. When you run dataflow analysis, these models expand the potential sources and sinks tracked by dataflow analysis and improve the precision of results. + +Most of the security queries search for paths from a source of untrusted input to a sink that represents a vulnerability. This is known as taint tracking. Each source is a starting point for dataflow analysis to track tainted data and each sink is an end point. + +Taint tracking queries also need to know how data can flow through elements that are not included in the source code. These are modeled as summaries. A summary model enables queries to synthesize the flow behavior through elements in dependency code that is not stored in your repository. + +Syntax used to define an element in an extension file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Each model of an element is defined using a data extension where each tuple constitutes a model. +A data extension file to extend the standard Go queries included with CodeQL is a YAML file with the form: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/go-all + extensible: + data: + - + - + - ... + +Each YAML file may contain one or more top-level extensions. + +- ``addsTo`` defines the CodeQL pack name and extensible predicate that the extension is injected into. +- ``data`` defines one or more rows of tuples that are injected as values into the extensible predicate. The number of columns and their types must match the definition of the extensible predicate. + +Data extensions use union semantics, which means that the tuples of all extensions for a single extensible predicate are combined, duplicates are removed, and all of the remaining tuples are queryable by referencing the extensible predicate. + +Publish data extension files in a CodeQL model pack to share +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can group one or more data extension files into a CodeQL model pack and publish it to the GitHub Container Registry. This makes it easy for anyone to download the model pack and use it to extend their analysis. For more information, see `Creating a CodeQL model pack `__ and `Publishing and using CodeQL packs `__ in the CodeQL CLI documentation. + +Extensible predicates used to create custom models in Go +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The CodeQL library for Go analysis exposes the following extensible predicates: + +- ``sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance)``. This is used to model sources of potentially tainted data. The ``kind`` of the sources defined using this predicate determine which threat model they are associated with. Different threat models can be used to customize the sources used in an analysis. For more information, see ":ref:`Threat models `." +- ``sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance)``. This is used to model sinks where tainted data may be used in a way that makes the code vulnerable. +- ``summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance)``. This is used to model flow through elements. +- ``neutralModel(namespace, type, name, signature, kind, provenance)``. This is similar to a summary model but used to model the flow of values that have only a minor impact on the dataflow analysis. Manual neutral models (those with a provenance such as ``manual`` or ``ai-manual``) can be used to override generated summary models (those with a provenance such as ``df-generated``), so that the summary model will be ignored. Other than that, neutral models have no effect. + +The extensible predicates are populated using the models defined in data extension files. + +Examples of custom model definitions +------------------------------------ + +The examples in this section are taken from the standard CodeQL Go query pack published by GitHub. They demonstrate how to add tuples to extend extensible predicates that are used by the standard queries. + +Example: Taint sink in the ``database/sql`` package +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This example shows how the Go query pack models the argument of the ``Prepare`` method as a SQL injection sink. +This is the ``Prepare`` method of the ``DB`` type in the ``database/sql`` package which creates a prepared statement. + +.. code-block:: go + + func Tainted(db *sql.DB, name string) { + stmt, err := db.Prepare("SELECT * FROM users WHERE name = " + name) // The argument to this method is a SQL injection sink. + ... + } + +We need to add a tuple to the ``sinkModel``\(namespace, type, subtypes, name, signature, ext, input, kind, provenance) extensible predicate by updating a data extension file. + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["database/sql", "DB", False, "Prepare", "(string)", "", "Argument[0]", "sql-injection", "manual"] + +Since we want to add a new sink, we need to add a tuple to the ``sinkModel`` extensible predicate. +The first five values identify the callable (in this case a method) to be modeled as a sink. + +- The first value ``database/sql`` is the package name. +- The second value ``DB`` is the name of the type that the method is associated with. +- The third value ``False`` is a flag that indicates whether or not the sink also applies to all overrides of the method. +- The fourth value ``Prepare`` is the method name. Constructors are named after the class. +- The fifth value ``(string)`` is the method input type signature. This value is often excluded and is simply set to an empty string since Go does not allow for a given type to have multiple methods with the same type. + +The sixth value should be left empty and is out of scope for this documentation. +The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the sink. + +- The seventh value ``Argument[0]`` is the ``access path`` to the first argument passed to the method, which means that this is the location of the sink. +- The eighth value ``sql-injection`` is the kind of the sink. The sink kind is used to define the queries where the sink is in scope. In this case - the SQL injection queries. +- The ninth value ``manual`` is the provenance of the sink, which is used to identify the origin of the sink. + +Example: Taint source from the ``net`` package +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This example shows how the Go query pack models the return value from the ``Listen`` method as a ``remote`` source. +This is the ``Listen`` function which is located in the ``net`` package. + +.. code-block:: go + + func Tainted() { + ln, err := net.Listen("tcp", ":8080") // The return value of this method is a remote source. + ... + } + + +We need to add a tuple to the ``sourceModel``\(namespace, type, subtypes, name, signature, ext, output, kind, provenance) extensible predicate by updating a data extension file. + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/go-all + extensible: sourceModel + data: + - ["net", "", False, "Listen", "(string,string)", "", "ReturnValue", "remote", "manual"] + + +Since we are adding a new source, we need to add a tuple to the ``sourceModel`` extensible predicate. +The first five values identify the callable (in this case a function) to be modeled as a source. + +- The first value ``net`` is the namespace name. +- The second value ``""`` is left blank, since the function is not a method of a type. +- The third value ``False`` is a flag that indicates whether or not the source also applies to all overrides of the method. +- The fourth value ``Listen`` is the function name. +- The fifth value ``(string,string)`` is the method input type signature. + +The sixth value should be left empty and is out of scope for this documentation. +The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the source. + +- The seventh value ``ReturnValue`` is the access path to the return of the method, which means that it is the return value that should be considered a source of tainted input. +- The eighth value ``remote`` is the kind of the source. The source kind is used to define the threat model where the source is in scope. ``remote`` applies to many of the security related queries as it means a remote source of untrusted data. As an example the SQL injection query uses ``remote`` sources. For more information, see ":ref:`Threat models `." +- The ninth value ``manual`` is the provenance of the source, which is used to identify the origin of the source. + +Example: Add flow through the ``Join`` function +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This example shows how the Go query pack models flow through a method for a simple case. +This pattern covers many of the cases where we need to summarize flow through a function that is stored in a library or framework outside the repository. + +.. code-block:: go + + func TaintFlow() { + ss := []string{"Hello", "World"} + sep := " " + t := strings.Join(ss, sep) // There is taint flow from s1 and s2 to t. + ... + } + +We need to add tuples to the ``summaryModel``\(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) extensible predicate by updating a data extension file: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["strings", "", False, "Join", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "Join", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + +Since we are adding flow through a method, we need to add tuples to the ``summaryModel`` extensible predicate. +Each tuple defines flow from one argument to the return value. +The first row defines flow from the first argument (``ss`` in the example) to the return value (``t`` in the example) and the second row defines flow from the second argument (``sep`` in the example) to the return value (``t`` in the example). + +The first five values identify the callable (in this case a method) to be modeled as a summary. +These are the same for both of the rows above as we are adding two summaries for the same method. + +- The first value ``strings`` is the pacakge name. +- The second value ``""`` is left blank, since the function is not a method of a type. +- The third value ``False`` is a flag that indicates whether or not the summary also applies to all overrides of the method. +- The fourth value ``Join`` is the function name. +- The fifth value ``""`` is left blank, since specifying the signature is optional and Go does not allow multiple signature overloads for the same function. + +The sixth value should be left empty and is out of scope for this documentation. +The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the summary. + +- The seventh value is the access path to the input (where data flows from). ``Argument[0]`` is the access path to the first argument (``ss`` in the example) and ``Argument[1]`` is the access path to the second argument (``sep`` in the example). +- The eighth value ``ReturnValue`` is the access path to the output (where data flows to), in this case ``ReturnValue``, which means that the input flows to the return value. +- The ninth value ``taint`` is the kind of the flow. ``taint`` means that taint is propagated through the call. +- The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. + +It would also be possible to merge the two rows into one by using a comma-separated list in the seventh value. This would be useful if the method has many arguments and the flow is the same for all of them. + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["strings", "", False, "Join", "", "", "Argument[0,1]", "ReturnValue", "taint", "manual"] + +This row defines flow from both the first and the second argument to the return value. The seventh value ``Argument[0,1]`` is shorthand for specifying an access path to both ``Argument[0]`` and ``Argument[1]``. + +Example: Add flow through the ``Hostname`` method +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This example shows how the Go query pack models flow through a method for a simple case. + +.. code-block:: go + + func TaintFlow(u *url.URL) { + host := u.Hostname() // There is taint flow from u to s. + ... + } + +We need to add a tuple to the ``summaryModel``\(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) extensible predicate by updating a data extension file: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["net/url", "URL", False, "Hostname", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + +Since we are adding flow through a method, we need to add tuples to the ``summaryModel`` extensible predicate. +Each tuple defines flow from one argument to the return value. +The first row defines flow from the qualifier of the method call (``u`` in the example) to the return value (``host`` in the example). + +The first five values identify the callable (in this case a method) to be modeled as a summary. +These are the same for both of the rows above as we are adding two summaries for the same method. + +- The first value ``net/url`` is the package name. +- The second value ``URL`` is the receiver type. +- The third value ``True`` is a flag that indicates whether or not the summary also applies to all overrides of the method. +- The fourth value ``Hostname`` is the method name. +- The fifth value ``()`` is the method input type signature. + +The sixth value should be left empty and is out of scope for this documentation. +The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the summary. + +- The seventh value is the access path to the input (where data flows from). ``Argument[this]`` is the access path to the qualifier (``u`` in the example). +- The eighth value ``ReturnValue`` is the access path to the output (where data flows to), in this case ``ReturnValue``, which means that the input flows to the return value. +- The ninth value ``taint`` is the kind of the flow. ``taint`` means that taint is propagated through the call. +- The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. + +Example: Add flow through the ``Select`` method +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This example shows how the C# query pack models a more complex flow through a method. +Here we model flow through higher order methods and collection types, as well as how to handle extension methods and generics. + +.. code-block:: csharp + + public static void TaintFlow(IEnumerable stream) { + IEnumerable lines = stream.Select(item => item + "\n"); + ... + } + +We need to add tuples to the ``summaryModel``\(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) extensible predicate by updating a data extension file: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/csharp-all + extensible: summaryModel + data: + - ["System.Linq", "Enumerable", False, "Select", "(System.Collections.Generic.IEnumerable,System.Func)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"] + - ["System.Linq", "Enumerable", False, "Select", "(System.Collections.Generic.IEnumerable,System.Func)", "", "Argument[1].ReturnValue", "ReturnValue.Element", "value", "manual"] + + +Since we are adding flow through a method, we need to add tuples to the ``summaryModel`` extensible predicate. +Each tuple defines part of the flow that comprises the total flow through the ``Select`` method. +The first five values identify the callable (in this case a method) to be modeled as a summary. +These are the same for both of the rows above as we are adding two summaries for the same method. + +- The first value ``System.Linq`` is the namespace name. +- The second value ``Enumerable`` is the class (type) name. +- The third value ``False`` is a flag that indicates whether or not the summary also applies to all overrides of the method. +- The fourth value ``Select`` is the method name, along with the type parameters for the method. The names of the generic type parameters provided in the model must match the names of the generic type parameters in the method signature in the source code. +- The fifth value ``(System.Collections.Generic.IEnumerable,System.Func)`` is the method input type signature. The generics in the signature must match the generics in the method signature in the source code. + +The sixth value should be left empty and is out of scope for this documentation. +The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the summary definition. + +- The seventh value is the access path to the ``input`` (where data flows from). +- The eighth value is the access path to the ``output`` (where data flows to). + +For the first row: + +- The seventh value is ``Argument[0].Element``, which is the access path to the elements of the qualifier (the elements of the enumerable ``stream`` in the example). +- The eight value is ``Argument[1].Parameter[0]``, which is the access path to the first parameter of the ``System.Func`` argument of ``Select`` (the lambda parameter ``item`` in the example). + +For the second row: + +- The seventh value is ``Argument[1].ReturnValue``, which is the access path to the return value of the ``System.Func`` argument of ``Select`` (the return value of the lambda in the example). +- The eighth value is ``ReturnValue.Element``, which is the access path to the elements of the return value of ``Select`` (the elements of the enumerable ``lines`` in the example). + +For the remaining values for both rows: + +- The ninth value ``value`` is the kind of the flow. ``value`` means that the value is preserved. +- The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. + +That is, the first row specifies that values can flow from the elements of the qualifier enumerable into the first argument of the function provided to ``Select``. The second row specifies that values can flow from the return value of the function to the elements of the enumerable returned from ``Select``. + +Example: Add a ``neutral`` method +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This example shows how we can model a method as being neutral with respect to flow. We will also cover how to model a property by modeling the getter of the ``Now`` property of the ``DateTime`` class as neutral. +A neutral model is used to define that there is no flow through a method. + +.. code-block:: csharp + + public static void TaintFlow() { + System.DateTime t = System.DateTime.Now; // There is no flow from Now to t. + ... + } + +We need to add a tuple to the ``neutralModel``\(namespace, type, name, signature, kind, provenance) extensible predicate by updating a data extension file. + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/csharp-all + extensible: neutralModel + data: + - ["System", "DateTime", "get_Now", "()", "summary", "manual"] + + +Since we are adding a neutral model, we need to add tuples to the ``neutralModel`` extensible predicate. +The first four values identify the callable (in this case the getter of the ``Now`` property) to be modeled as a neutral, the fifth value is the kind, and the sixth value is the provenance (origin) of the neutral. + +- The first value ``System`` is the namespace name. +- The second value ``DateTime`` is the class (type) name. +- The third value ``get_Now`` is the method name. Getter and setter methods are named ``get_`` and ``set_`` respectively. +- The fourth value ``()`` is the method input type signature. +- The fifth value ``summary`` is the kind of the neutral. +- The sixth value ``manual`` is the provenance of the neutral. + +Example: Accessing the ``Body`` field of an HTTP request +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This example shows how we can model a field as a source of tainted data. + +.. code-block:: go + + func TaintFlow(w http.ResponseWriter, r *http.Request) { + body := r.Body // The Body field of an HTTP request is a source of tainted data. + ... + } + +We need to add a tuple to the ``sourceModel``\(namespace, type, subtypes, name, signature, ext, output, kind, provenance) extensible predicate by updating a data extension file. + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/go-all + extensible: sourceModel + data: + - ["net/http", "Request", True, "Body", "", "", "", "remote", "manual"] + +Since we are adding a new source, we need to add a tuple to the ``sourceModel`` extensible predicate. +The first five values identify the field to be modeled as a source. + +- The first value ``net/http`` is the package name. +- The second value ``Request`` is the name of the type that the field is associated with. +- The third value ``True`` is a flag that indicates whether or not the source also applies to all overrides of the field. +- The fourth value ``Body`` is the field name. +- The fifth value ``""`` is blank since it is a field access and field accesses do not have method signatures in Go. + +The sixth value should be left empty and is out of scope for this documentation. +The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the source. + +- The seventh value ``""`` is left blank. Leaving the access path of a source model blank indicates that it is a field access. +- The eighth value ``remote`` is the source kind. This indicates that the source is a remote source of untrusted data. +- The ninth value ``manual`` is the provenance of the source, which is used to identify the origin of the source. + +Package grouping +~~~~~~~~~~~~~~~~ + +Since Go uses URLs for package identifiers, it is possible for packages to be imported with different paths. For example, the ``glog`` package can be imported using both the ``github.com/golang/glog`` and ``gopkg.in/glog`` paths. + +To handle this, the CodeQL Go library uses a mapping from the package path to a name for the package. This mapping can be specified using the ``packageGrouping`` extensible predicate, and then the models for the APIs in the package +will use the group name in place of the package path. The package field in models will be the prefix ``group:`` followed by the group name. + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/go + extensible: packageGrouping + data: + - ["glog", "github.com/golang/glog"] + - ["glog", "gopkg.in/glog"] + - addsTo: + pack: codeql/go + extensible: sinkModel + data: + - ["group:glog", "Info", "()", "Argument[0]", "log-injection", "manual"] + +.. _threat-models-go: + +Threat models +------------- + +.. include:: ../reusables/threat-model-description.rst From cfa1ad65c8d24c7900ffed90a69e7064c16c0ebc Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Tue, 20 Aug 2024 17:00:32 -0400 Subject: [PATCH 002/470] Consistently replace usage of `namespace` with `package` Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- .../customizing-library-models-for-go.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index 61861039f03..c871c240dc7 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -55,10 +55,10 @@ Extensible predicates used to create custom models in Go The CodeQL library for Go analysis exposes the following extensible predicates: -- ``sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance)``. This is used to model sources of potentially tainted data. The ``kind`` of the sources defined using this predicate determine which threat model they are associated with. Different threat models can be used to customize the sources used in an analysis. For more information, see ":ref:`Threat models `." -- ``sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance)``. This is used to model sinks where tainted data may be used in a way that makes the code vulnerable. -- ``summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance)``. This is used to model flow through elements. -- ``neutralModel(namespace, type, name, signature, kind, provenance)``. This is similar to a summary model but used to model the flow of values that have only a minor impact on the dataflow analysis. Manual neutral models (those with a provenance such as ``manual`` or ``ai-manual``) can be used to override generated summary models (those with a provenance such as ``df-generated``), so that the summary model will be ignored. Other than that, neutral models have no effect. +- ``sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance)``. This is used to model sources of potentially tainted data. The ``kind`` of the sources defined using this predicate determine which threat model they are associated with. Different threat models can be used to customize the sources used in an analysis. For more information, see ":ref:`Threat models `." +- ``sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance)``. This is used to model sinks where tainted data may be used in a way that makes the code vulnerable. +- ``summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance)``. This is used to model flow through elements. +- ``neutralModel(package, type, name, signature, kind, provenance)``. This is similar to a summary model but used to model the flow of values that have only a minor impact on the dataflow analysis. Manual neutral models (those with a provenance such as ``manual`` or ``ai-manual``) can be used to override generated summary models (those with a provenance such as ``df-generated``), so that the summary model will be ignored. Other than that, neutral models have no effect. The extensible predicates are populated using the models defined in data extension files. @@ -135,7 +135,7 @@ We need to add a tuple to the ``sourceModel``\(namespace, type, subtypes, name, Since we are adding a new source, we need to add a tuple to the ``sourceModel`` extensible predicate. The first five values identify the callable (in this case a function) to be modeled as a source. -- The first value ``net`` is the namespace name. +- The first value ``net`` is the package name. - The second value ``""`` is left blank, since the function is not a method of a type. - The third value ``False`` is a flag that indicates whether or not the source also applies to all overrides of the method. - The fourth value ``Listen`` is the function name. From 211cda390d1212cbf6eb0717bb8e1b92014d5c02 Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Tue, 20 Aug 2024 17:01:45 -0400 Subject: [PATCH 003/470] Method signatures and receiver/qualifier language Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- .../customizing-library-models-for-go.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index c871c240dc7..ac7f6d3cc3e 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -89,7 +89,7 @@ We need to add a tuple to the ``sinkModel``\(namespace, type, subtypes, name, si pack: codeql/go-all extensible: sinkModel data: - - ["database/sql", "DB", False, "Prepare", "(string)", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "DB", False, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] Since we want to add a new sink, we need to add a tuple to the ``sinkModel`` extensible predicate. The first five values identify the callable (in this case a method) to be modeled as a sink. @@ -98,7 +98,7 @@ The first five values identify the callable (in this case a method) to be modele - The second value ``DB`` is the name of the type that the method is associated with. - The third value ``False`` is a flag that indicates whether or not the sink also applies to all overrides of the method. - The fourth value ``Prepare`` is the method name. Constructors are named after the class. -- The fifth value ``(string)`` is the method input type signature. This value is often excluded and is simply set to an empty string since Go does not allow for a given type to have multiple methods with the same type. +- The fifth value ``""`` is the method input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions or methods may have the same name and they need to be distinguished by the number and types of the arguments. The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the sink. @@ -228,7 +228,7 @@ We need to add a tuple to the ``summaryModel``\(namespace, type, subtypes, name, pack: codeql/go-all extensible: summaryModel data: - - ["net/url", "URL", False, "Hostname", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["net/url", "URL", False, "Hostname", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] Since we are adding flow through a method, we need to add tuples to the ``summaryModel`` extensible predicate. Each tuple defines flow from one argument to the return value. @@ -241,12 +241,12 @@ These are the same for both of the rows above as we are adding two summaries for - The second value ``URL`` is the receiver type. - The third value ``True`` is a flag that indicates whether or not the summary also applies to all overrides of the method. - The fourth value ``Hostname`` is the method name. -- The fifth value ``()`` is the method input type signature. +- The fifth value ``""`` is left blank, since specifying the signature is optional and Go does not allow multiple signature overloads for the same function. The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the summary. -- The seventh value is the access path to the input (where data flows from). ``Argument[this]`` is the access path to the qualifier (``u`` in the example). +- The seventh value is the access path to the input (where data flows from). ``Argument[receiver]`` is the access path to the receiver (``u`` in the example). - The eighth value ``ReturnValue`` is the access path to the output (where data flows to), in this case ``ReturnValue``, which means that the input flows to the return value. - The ninth value ``taint`` is the kind of the flow. ``taint`` means that taint is propagated through the call. - The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. From 9b92ff7e78c6ccb7ed3629fe866a61915f5d8bd4 Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Tue, 20 Aug 2024 17:02:24 -0400 Subject: [PATCH 004/470] Typos and minor wording Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- .../customizing-library-models-for-go.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index ac7f6d3cc3e..9bd619511a3 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -97,7 +97,7 @@ The first five values identify the callable (in this case a method) to be modele - The first value ``database/sql`` is the package name. - The second value ``DB`` is the name of the type that the method is associated with. - The third value ``False`` is a flag that indicates whether or not the sink also applies to all overrides of the method. -- The fourth value ``Prepare`` is the method name. Constructors are named after the class. +- The fourth value ``Prepare`` is the method name. - The fifth value ``""`` is the method input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions or methods may have the same name and they need to be distinguished by the number and types of the arguments. The sixth value should be left empty and is out of scope for this documentation. @@ -158,7 +158,7 @@ This pattern covers many of the cases where we need to summarize flow through a func TaintFlow() { ss := []string{"Hello", "World"} sep := " " - t := strings.Join(ss, sep) // There is taint flow from s1 and s2 to t. + t := strings.Join(ss, sep) // There is taint flow from ss and sep to t. ... } @@ -235,7 +235,6 @@ Each tuple defines flow from one argument to the return value. The first row defines flow from the qualifier of the method call (``u`` in the example) to the return value (``host`` in the example). The first five values identify the callable (in this case a method) to be modeled as a summary. -These are the same for both of the rows above as we are adding two summaries for the same method. - The first value ``net/url`` is the package name. - The second value ``URL`` is the receiver type. @@ -346,7 +345,7 @@ The first four values identify the callable (in this case the getter of the ``No Example: Accessing the ``Body`` field of an HTTP request ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This example shows how we can model a field as a source of tainted data. +This example shows how we can model a field read as a source of tainted data. .. code-block:: go @@ -387,7 +386,7 @@ Package grouping Since Go uses URLs for package identifiers, it is possible for packages to be imported with different paths. For example, the ``glog`` package can be imported using both the ``github.com/golang/glog`` and ``gopkg.in/glog`` paths. -To handle this, the CodeQL Go library uses a mapping from the package path to a name for the package. This mapping can be specified using the ``packageGrouping`` extensible predicate, and then the models for the APIs in the package +To handle this, the CodeQL Go library uses a mapping from the package path to a group name for the package. This mapping can be specified using the ``packageGrouping`` extensible predicate, and then the models for the APIs in the package will use the group name in place of the package path. The package field in models will be the prefix ``group:`` followed by the group name. .. code-block:: yaml @@ -403,7 +402,7 @@ will use the group name in place of the package path. The package field in model pack: codeql/go extensible: sinkModel data: - - ["group:glog", "Info", "()", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "", False, "Info", "", "", "Argument[0]", "log-injection", "manual"] .. _threat-models-go: From 2bfca21a2ff8c0ee689a9bd9057d05baacf8b3be Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Tue, 20 Aug 2024 17:04:42 -0400 Subject: [PATCH 005/470] Replace `ss` with `elems` --- .../customizing-library-models-for-go.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index 9bd619511a3..36bfd6c9d9e 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -156,9 +156,9 @@ This pattern covers many of the cases where we need to summarize flow through a .. code-block:: go func TaintFlow() { - ss := []string{"Hello", "World"} + elems := []string{"Hello", "World"} sep := " " - t := strings.Join(ss, sep) // There is taint flow from ss and sep to t. + t := strings.Join(elems, sep) // There is taint flow from ss and sep to t. ... } @@ -176,7 +176,7 @@ We need to add tuples to the ``summaryModel``\(namespace, type, subtypes, name, Since we are adding flow through a method, we need to add tuples to the ``summaryModel`` extensible predicate. Each tuple defines flow from one argument to the return value. -The first row defines flow from the first argument (``ss`` in the example) to the return value (``t`` in the example) and the second row defines flow from the second argument (``sep`` in the example) to the return value (``t`` in the example). +The first row defines flow from the first argument (``elems`` in the example) to the return value (``t`` in the example) and the second row defines flow from the second argument (``sep`` in the example) to the return value (``t`` in the example). The first five values identify the callable (in this case a method) to be modeled as a summary. These are the same for both of the rows above as we are adding two summaries for the same method. @@ -190,7 +190,7 @@ These are the same for both of the rows above as we are adding two summaries for The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the summary. -- The seventh value is the access path to the input (where data flows from). ``Argument[0]`` is the access path to the first argument (``ss`` in the example) and ``Argument[1]`` is the access path to the second argument (``sep`` in the example). +- The seventh value is the access path to the input (where data flows from). ``Argument[0]`` is the access path to the first argument (``elems`` in the example) and ``Argument[1]`` is the access path to the second argument (``sep`` in the example). - The eighth value ``ReturnValue`` is the access path to the output (where data flows to), in this case ``ReturnValue``, which means that the input flows to the return value. - The ninth value ``taint`` is the kind of the flow. ``taint`` means that taint is propagated through the call. - The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. From 27ad882f543ff967225bf1ca29d2d193f966b357 Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Tue, 20 Aug 2024 17:05:33 -0400 Subject: [PATCH 006/470] Usage range pattern instead of comma separation Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- .../customizing-library-models-for-go.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index 36bfd6c9d9e..50f832f2ca5 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -195,7 +195,7 @@ The remaining values are used to define the ``access path``, the ``kind``, and t - The ninth value ``taint`` is the kind of the flow. ``taint`` means that taint is propagated through the call. - The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. -It would also be possible to merge the two rows into one by using a comma-separated list in the seventh value. This would be useful if the method has many arguments and the flow is the same for all of them. +It would also be possible to merge the two rows into one by using ".." to indicate a range in the seventh value. This would be useful if the method has many arguments and the flow is the same for all of them. .. code-block:: yaml @@ -204,9 +204,9 @@ It would also be possible to merge the two rows into one by using a comma-separa pack: codeql/go-all extensible: summaryModel data: - - ["strings", "", False, "Join", "", "", "Argument[0,1]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "Join", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] -This row defines flow from both the first and the second argument to the return value. The seventh value ``Argument[0,1]`` is shorthand for specifying an access path to both ``Argument[0]`` and ``Argument[1]``. +This row defines flow from both the first and the second argument to the return value. The seventh value ``Argument[0..1]`` is shorthand for specifying an access path to both ``Argument[0]`` and ``Argument[1]``. Example: Add flow through the ``Hostname`` method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From e8aac2be9aed061990aaf2276f44f90c920d087b Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Tue, 20 Aug 2024 17:06:58 -0400 Subject: [PATCH 007/470] Remove `neutral` example Go currently does not use `neutralModel`s and they are less relevant for Go than for Java/C#. --- .../customizing-library-models-for-go.rst | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index 50f832f2ca5..2ed3ab3e659 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -309,40 +309,6 @@ For the remaining values for both rows: That is, the first row specifies that values can flow from the elements of the qualifier enumerable into the first argument of the function provided to ``Select``. The second row specifies that values can flow from the return value of the function to the elements of the enumerable returned from ``Select``. -Example: Add a ``neutral`` method -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This example shows how we can model a method as being neutral with respect to flow. We will also cover how to model a property by modeling the getter of the ``Now`` property of the ``DateTime`` class as neutral. -A neutral model is used to define that there is no flow through a method. - -.. code-block:: csharp - - public static void TaintFlow() { - System.DateTime t = System.DateTime.Now; // There is no flow from Now to t. - ... - } - -We need to add a tuple to the ``neutralModel``\(namespace, type, name, signature, kind, provenance) extensible predicate by updating a data extension file. - -.. code-block:: yaml - - extensions: - - addsTo: - pack: codeql/csharp-all - extensible: neutralModel - data: - - ["System", "DateTime", "get_Now", "()", "summary", "manual"] - - -Since we are adding a neutral model, we need to add tuples to the ``neutralModel`` extensible predicate. -The first four values identify the callable (in this case the getter of the ``Now`` property) to be modeled as a neutral, the fifth value is the kind, and the sixth value is the provenance (origin) of the neutral. - -- The first value ``System`` is the namespace name. -- The second value ``DateTime`` is the class (type) name. -- The third value ``get_Now`` is the method name. Getter and setter methods are named ``get_`` and ``set_`` respectively. -- The fourth value ``()`` is the method input type signature. -- The fifth value ``summary`` is the kind of the neutral. -- The sixth value ``manual`` is the provenance of the neutral. - Example: Accessing the ``Body`` field of an HTTP request ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This example shows how we can model a field read as a source of tainted data. From e142818fe5f6c03a166b743bed8d8dc7835cd337 Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Tue, 20 Aug 2024 17:08:50 -0400 Subject: [PATCH 008/470] Remove `Select` example. Go does not currently have any equivalent with regards to lambda flow --- .../customizing-library-models-for-go.rst | 59 ------------------- 1 file changed, 59 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index 2ed3ab3e659..d11eda01e2d 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -250,65 +250,6 @@ The remaining values are used to define the ``access path``, the ``kind``, and t - The ninth value ``taint`` is the kind of the flow. ``taint`` means that taint is propagated through the call. - The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. -Example: Add flow through the ``Select`` method -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This example shows how the C# query pack models a more complex flow through a method. -Here we model flow through higher order methods and collection types, as well as how to handle extension methods and generics. - -.. code-block:: csharp - - public static void TaintFlow(IEnumerable stream) { - IEnumerable lines = stream.Select(item => item + "\n"); - ... - } - -We need to add tuples to the ``summaryModel``\(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) extensible predicate by updating a data extension file: - -.. code-block:: yaml - - extensions: - - addsTo: - pack: codeql/csharp-all - extensible: summaryModel - data: - - ["System.Linq", "Enumerable", False, "Select", "(System.Collections.Generic.IEnumerable,System.Func)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"] - - ["System.Linq", "Enumerable", False, "Select", "(System.Collections.Generic.IEnumerable,System.Func)", "", "Argument[1].ReturnValue", "ReturnValue.Element", "value", "manual"] - - -Since we are adding flow through a method, we need to add tuples to the ``summaryModel`` extensible predicate. -Each tuple defines part of the flow that comprises the total flow through the ``Select`` method. -The first five values identify the callable (in this case a method) to be modeled as a summary. -These are the same for both of the rows above as we are adding two summaries for the same method. - -- The first value ``System.Linq`` is the namespace name. -- The second value ``Enumerable`` is the class (type) name. -- The third value ``False`` is a flag that indicates whether or not the summary also applies to all overrides of the method. -- The fourth value ``Select`` is the method name, along with the type parameters for the method. The names of the generic type parameters provided in the model must match the names of the generic type parameters in the method signature in the source code. -- The fifth value ``(System.Collections.Generic.IEnumerable,System.Func)`` is the method input type signature. The generics in the signature must match the generics in the method signature in the source code. - -The sixth value should be left empty and is out of scope for this documentation. -The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the summary definition. - -- The seventh value is the access path to the ``input`` (where data flows from). -- The eighth value is the access path to the ``output`` (where data flows to). - -For the first row: - -- The seventh value is ``Argument[0].Element``, which is the access path to the elements of the qualifier (the elements of the enumerable ``stream`` in the example). -- The eight value is ``Argument[1].Parameter[0]``, which is the access path to the first parameter of the ``System.Func`` argument of ``Select`` (the lambda parameter ``item`` in the example). - -For the second row: - -- The seventh value is ``Argument[1].ReturnValue``, which is the access path to the return value of the ``System.Func`` argument of ``Select`` (the return value of the lambda in the example). -- The eighth value is ``ReturnValue.Element``, which is the access path to the elements of the return value of ``Select`` (the elements of the enumerable ``lines`` in the example). - -For the remaining values for both rows: - -- The ninth value ``value`` is the kind of the flow. ``value`` means that the value is preserved. -- The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. - -That is, the first row specifies that values can flow from the elements of the qualifier enumerable into the first argument of the function provided to ``Select``. The second row specifies that values can flow from the return value of the function to the elements of the enumerable returned from ``Select``. - Example: Accessing the ``Body`` field of an HTTP request ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This example shows how we can model a field read as a source of tainted data. From de2f8a15770166ec190fbdf714548162d3eaf054 Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Tue, 20 Aug 2024 17:09:47 -0400 Subject: [PATCH 009/470] Make field consistent with existing model --- .../customizing-library-models-for-go.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index d11eda01e2d..f7ad0aebbca 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -228,7 +228,7 @@ We need to add a tuple to the ``summaryModel``\(namespace, type, subtypes, name, pack: codeql/go-all extensible: summaryModel data: - - ["net/url", "URL", False, "Hostname", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["net/url", "URL", True, "Hostname", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] Since we are adding flow through a method, we need to add tuples to the ``summaryModel`` extensible predicate. Each tuple defines flow from one argument to the return value. From a99dd69d87f28445f948a88b76ceb1bc5f618c76 Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Tue, 20 Aug 2024 17:12:07 -0400 Subject: [PATCH 010/470] Remove function signature --- .../customizing-library-models-for-go.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index f7ad0aebbca..4448b8d7968 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -129,7 +129,7 @@ We need to add a tuple to the ``sourceModel``\(namespace, type, subtypes, name, pack: codeql/go-all extensible: sourceModel data: - - ["net", "", False, "Listen", "(string,string)", "", "ReturnValue", "remote", "manual"] + - ["net", "", False, "Listen", "", "", "ReturnValue", "remote", "manual"] Since we are adding a new source, we need to add a tuple to the ``sourceModel`` extensible predicate. @@ -139,7 +139,7 @@ The first five values identify the callable (in this case a function) to be mode - The second value ``""`` is left blank, since the function is not a method of a type. - The third value ``False`` is a flag that indicates whether or not the source also applies to all overrides of the method. - The fourth value ``Listen`` is the function name. -- The fifth value ``(string,string)`` is the method input type signature. +- The fifth value ``""`` is the function input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions or methods may have the same name and they need to be distinguished by the number and types of the arguments. The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the source. From cc6b09da4898f02b201beafa6315322674a705fc Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Tue, 20 Aug 2024 17:16:29 -0400 Subject: [PATCH 011/470] Fix name of section --- .../customizing-library-models-for-go.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index 4448b8d7968..3701a41aa02 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -1,4 +1,4 @@ -.. _customizing-library-models-for-csharp: +.. _customizing-library-models-for-go: Customizing library models for Go ================================= From 107948603277f597ff1ea70ff498a1798fbca0c9 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 20 Aug 2024 17:31:20 -0400 Subject: [PATCH 012/470] Mention Go in codeql-for-go toctree --- docs/codeql/codeql-language-guides/codeql-for-go.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/codeql/codeql-language-guides/codeql-for-go.rst b/docs/codeql/codeql-language-guides/codeql-for-go.rst index 0eaefbb5922..040a4e3b6d3 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-go.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-go.rst @@ -12,6 +12,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat codeql-library-for-go abstract-syntax-tree-classes-for-working-with-go-programs modeling-data-flow-in-go-libraries + customizing-library-models-for-go - :doc:`Basic query for Go code `: Learn to write and run a simple CodeQL query. @@ -21,3 +22,5 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat - :doc:`Modeling data flow in Go libraries `: When analyzing a Go program, CodeQL does not examine the source code for external packages. To track the flow of untrusted data through a library, you can create a model of the library. + +- :doc:`Customizing library models for Go `: You can model frameworks and libraries that your codebase depends on using data extensions and publish them as CodeQL model packs. From 8b73d4af869c631daf04085494a70372d660078d Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Tue, 20 Aug 2024 21:19:11 -0400 Subject: [PATCH 013/470] Fix typo Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- .../customizing-library-models-for-go.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index 3701a41aa02..72f80d4b606 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -158,7 +158,7 @@ This pattern covers many of the cases where we need to summarize flow through a func TaintFlow() { elems := []string{"Hello", "World"} sep := " " - t := strings.Join(elems, sep) // There is taint flow from ss and sep to t. + t := strings.Join(elems, sep) // There is taint flow from elems and sep to t. ... } From 1e1bbe92a3d25ad8ed53994d26c28cd5faa27316 Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Wed, 21 Aug 2024 18:12:40 -0400 Subject: [PATCH 014/470] Wording and typo Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- .../customizing-library-models-for-go.rst | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index 72f80d4b606..47e98871c0b 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -3,7 +3,7 @@ Customizing library models for Go ================================= -You can model the methods and callables that control data flow in any framework or library. This is especially useful for custom frameworks or niche libraries, that are not supported by the standard CodeQL libraries. +You can model the methods and functions that control data flow in any framework or library. This is especially useful for custom frameworks or niche libraries, that are not supported by the standard CodeQL libraries. .. include:: ../reusables/beta-note-customizing-library-models.rst @@ -15,7 +15,7 @@ This article contains reference material about how to define custom models for s About data extensions --------------------- -You can customize analysis by defining models (summaries, sinks, and sources) of your code's Go dependencies in data extension files. Each model defines the behavior of one or more elements of your library or framework, such as methods, properties, and callables. When you run dataflow analysis, these models expand the potential sources and sinks tracked by dataflow analysis and improve the precision of results. +You can customize analysis by defining models (summaries, sinks, and sources) of your code's Go dependencies in data extension files. Each model defines the behavior of one or more elements of your library or framework, such as functions, methods, and fields. When you run dataflow analysis, these models expand the potential sources and sinks tracked by dataflow analysis and improve the precision of results. Most of the security queries search for paths from a source of untrusted input to a sink that represents a vulnerability. This is known as taint tracking. Each source is a starting point for dataflow analysis to track tainted data and each sink is an end point. @@ -80,7 +80,7 @@ This is the ``Prepare`` method of the ``DB`` type in the ``database/sql`` packag ... } -We need to add a tuple to the ``sinkModel``\(namespace, type, subtypes, name, signature, ext, input, kind, provenance) extensible predicate by updating a data extension file. +We need to add a tuple to the ``sinkModel``\(package, type, subtypes, name, signature, ext, input, kind, provenance) extensible predicate by updating a data extension file. .. code-block:: yaml @@ -92,7 +92,7 @@ We need to add a tuple to the ``sinkModel``\(namespace, type, subtypes, name, si - ["database/sql", "DB", False, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] Since we want to add a new sink, we need to add a tuple to the ``sinkModel`` extensible predicate. -The first five values identify the callable (in this case a method) to be modeled as a sink. +The first five values identify the function (in this case a method) to be modeled as a sink. - The first value ``database/sql`` is the package name. - The second value ``DB`` is the name of the type that the method is associated with. @@ -120,7 +120,7 @@ This is the ``Listen`` function which is located in the ``net`` package. } -We need to add a tuple to the ``sourceModel``\(namespace, type, subtypes, name, signature, ext, output, kind, provenance) extensible predicate by updating a data extension file. +We need to add a tuple to the ``sourceModel``\(package, type, subtypes, name, signature, ext, output, kind, provenance) extensible predicate by updating a data extension file. .. code-block:: yaml @@ -133,7 +133,7 @@ We need to add a tuple to the ``sourceModel``\(namespace, type, subtypes, name, Since we are adding a new source, we need to add a tuple to the ``sourceModel`` extensible predicate. -The first five values identify the callable (in this case a function) to be modeled as a source. +The first five values identify the function to be modeled as a source. - The first value ``net`` is the package name. - The second value ``""`` is left blank, since the function is not a method of a type. @@ -162,7 +162,7 @@ This pattern covers many of the cases where we need to summarize flow through a ... } -We need to add tuples to the ``summaryModel``\(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) extensible predicate by updating a data extension file: +We need to add tuples to the ``summaryModel``\(package, type, subtypes, name, signature, ext, input, output, kind, provenance) extensible predicate by updating a data extension file: .. code-block:: yaml @@ -178,10 +178,10 @@ Since we are adding flow through a method, we need to add tuples to the ``summar Each tuple defines flow from one argument to the return value. The first row defines flow from the first argument (``elems`` in the example) to the return value (``t`` in the example) and the second row defines flow from the second argument (``sep`` in the example) to the return value (``t`` in the example). -The first five values identify the callable (in this case a method) to be modeled as a summary. +The first five values identify the function to be modeled as a summary. These are the same for both of the rows above as we are adding two summaries for the same method. -- The first value ``strings`` is the pacakge name. +- The first value ``strings`` is the package name. - The second value ``""`` is left blank, since the function is not a method of a type. - The third value ``False`` is a flag that indicates whether or not the summary also applies to all overrides of the method. - The fourth value ``Join`` is the function name. @@ -219,7 +219,7 @@ This example shows how the Go query pack models flow through a method for a simp ... } -We need to add a tuple to the ``summaryModel``\(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) extensible predicate by updating a data extension file: +We need to add a tuple to the ``summaryModel``\(package, type, subtypes, name, signature, ext, input, output, kind, provenance) extensible predicate by updating a data extension file: .. code-block:: yaml @@ -234,7 +234,7 @@ Since we are adding flow through a method, we need to add tuples to the ``summar Each tuple defines flow from one argument to the return value. The first row defines flow from the qualifier of the method call (``u`` in the example) to the return value (``host`` in the example). -The first five values identify the callable (in this case a method) to be modeled as a summary. +The first five values identify the function (in this case a method) to be modeled as a summary. - The first value ``net/url`` is the package name. - The second value ``URL`` is the receiver type. @@ -261,7 +261,7 @@ This example shows how we can model a field read as a source of tainted data. ... } -We need to add a tuple to the ``sourceModel``\(namespace, type, subtypes, name, signature, ext, output, kind, provenance) extensible predicate by updating a data extension file. +We need to add a tuple to the ``sourceModel``\(package, type, subtypes, name, signature, ext, output, kind, provenance) extensible predicate by updating a data extension file. .. code-block:: yaml @@ -294,7 +294,7 @@ Package grouping Since Go uses URLs for package identifiers, it is possible for packages to be imported with different paths. For example, the ``glog`` package can be imported using both the ``github.com/golang/glog`` and ``gopkg.in/glog`` paths. To handle this, the CodeQL Go library uses a mapping from the package path to a group name for the package. This mapping can be specified using the ``packageGrouping`` extensible predicate, and then the models for the APIs in the package -will use the group name in place of the package path. The package field in models will be the prefix ``group:`` followed by the group name. +will use the the prefix ``group:`` followed by the group name in place of the package path. .. code-block:: yaml From 2757b0ba6e62480fcce8fd0eb34a41002c6a1792 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 21 Aug 2024 18:35:19 -0400 Subject: [PATCH 015/470] Change example to net/http Request::FormValue --- .../customizing-library-models-for-go.rst | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index 47e98871c0b..aabe440ade7 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -107,15 +107,15 @@ The remaining values are used to define the ``access path``, the ``kind``, and t - The eighth value ``sql-injection`` is the kind of the sink. The sink kind is used to define the queries where the sink is in scope. In this case - the SQL injection queries. - The ninth value ``manual`` is the provenance of the sink, which is used to identify the origin of the sink. -Example: Taint source from the ``net`` package -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This example shows how the Go query pack models the return value from the ``Listen`` method as a ``remote`` source. -This is the ``Listen`` function which is located in the ``net`` package. +Example: Taint source from the ``net/http`` package +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This example shows how the Go query pack models the return value from the ``FormValue`` method as a ``remote`` source. +This is the ``FormValue`` method of the ``Request`` struct which is located in the ``net/http`` package. .. code-block:: go - func Tainted() { - ln, err := net.Listen("tcp", ":8080") // The return value of this method is a remote source. + func Tainted(r *http.Request) { + name := r.FormValue("name") // The return value of this method is a source of tainted data. ... } @@ -129,16 +129,16 @@ We need to add a tuple to the ``sourceModel``\(package, type, subtypes, name, si pack: codeql/go-all extensible: sourceModel data: - - ["net", "", False, "Listen", "", "", "ReturnValue", "remote", "manual"] + - ["net/http", "Request", True, "FormValue", "", "", "ReturnValue", "remote", "manual"] Since we are adding a new source, we need to add a tuple to the ``sourceModel`` extensible predicate. The first five values identify the function to be modeled as a source. -- The first value ``net`` is the package name. -- The second value ``""`` is left blank, since the function is not a method of a type. -- The third value ``False`` is a flag that indicates whether or not the source also applies to all overrides of the method. -- The fourth value ``Listen`` is the function name. +- The first value ``net/http`` is the package name. +- The second value ``Request`` is the type name, since the function is a method of the ``Request`` type. +- The third value ``True`` is a flag that indicates whether or not the source also applies to all overrides of the method. +- The fourth value ``FormValue`` is the function name. - The fifth value ``""`` is the function input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions or methods may have the same name and they need to be distinguished by the number and types of the arguments. The sixth value should be left empty and is out of scope for this documentation. From 7e98d02d56dd7ebaad0306f3654521939d15cc1f Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Thu, 22 Aug 2024 08:51:30 -0400 Subject: [PATCH 016/470] Wording Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- .../customizing-library-models-for-go.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index aabe440ade7..b55707cbf87 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -110,7 +110,7 @@ The remaining values are used to define the ``access path``, the ``kind``, and t Example: Taint source from the ``net/http`` package ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This example shows how the Go query pack models the return value from the ``FormValue`` method as a ``remote`` source. -This is the ``FormValue`` method of the ``Request`` struct which is located in the ``net/http`` package. +This is the ``FormValue`` method of the ``Request`` type which is located in the ``net/http`` package. .. code-block:: go From 9b43b4994e10025c7694c79b1dc1e949bc3350fe Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Thu, 22 Aug 2024 08:52:02 -0400 Subject: [PATCH 017/470] `fixed-version:` example Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- .../customizing-library-models-for-go.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index b55707cbf87..d79300c522b 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -288,6 +288,24 @@ The remaining values are used to define the ``access path``, the ``kind``, and t - The eighth value ``remote`` is the source kind. This indicates that the source is a remote source of untrusted data. - The ninth value ``manual`` is the provenance of the source, which is used to identify the origin of the source. +Package versions +~~~~~~~~~~~~~~~~ + +When the major version number is greater than 1 it is included in the package import path. It usually looks like ``/v2`` after the module import path. This is called the major version suffix. We normally want our models to apply to all versions of a package. Rather than having to repeat models with the package column changed to include all available versions, we can just use the package name without the major version suffix and this will be matched to any version. So models with ``github.com/couchbase/gocb`` in the package column will match packages imported from ``github.com/couchbase/gocb`` and ``github.com/couchbase/gocb/v2`` (or any other version). + +Note that packages hosted at ``gopkg.in`` use a slightly different syntax: the major version suffix looks like ``.v2``, and it is present even for version 1. This is also supported. So models with ``gopkg.in/yaml`` in the package column will match packages imported from ``gopkg.in/yaml.v1``, ``gopkg.in/yaml.v2`` and ``gopkg.in/yaml.v3``. + +To write models that only apply to ``github.com/couchbase/gocb/v2``, it is sufficient to include the major version suffix (``/v2``) in the package column. To write models that only apply to ``github.com/couchbase/gocb``, you may prefix the package column with ``fixed-version:``. For example, here are two models for a method that has changed name from v1 to v2. + +.. code-block:: yaml + extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["fixed-version:github.com/couchbase/gocb", "Cluster", True, "ExecuteAnalyticsQuery", "", "", "Argument[0]", "nosql-injection", "manual"] + - ["github.com/couchbase/gocb/v2", "Cluster", True, "AnalyticsQuery", "", "", "Argument[0]", "nosql-injection", "manual"] + Package grouping ~~~~~~~~~~~~~~~~ From bf11e2cd0fec58c8f5ae562a39d42f1cf641015a Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Thu, 22 Aug 2024 08:57:54 -0400 Subject: [PATCH 018/470] Fix code block --- .../customizing-library-models-for-go.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index d79300c522b..bf56447fce1 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -298,13 +298,14 @@ Note that packages hosted at ``gopkg.in`` use a slightly different syntax: the m To write models that only apply to ``github.com/couchbase/gocb/v2``, it is sufficient to include the major version suffix (``/v2``) in the package column. To write models that only apply to ``github.com/couchbase/gocb``, you may prefix the package column with ``fixed-version:``. For example, here are two models for a method that has changed name from v1 to v2. .. code-block:: yaml - extensions: - - addsTo: - pack: codeql/go-all - extensible: sinkModel - data: - - ["fixed-version:github.com/couchbase/gocb", "Cluster", True, "ExecuteAnalyticsQuery", "", "", "Argument[0]", "nosql-injection", "manual"] - - ["github.com/couchbase/gocb/v2", "Cluster", True, "AnalyticsQuery", "", "", "Argument[0]", "nosql-injection", "manual"] + + extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["fixed-version:github.com/couchbase/gocb", "Cluster", True, "ExecuteAnalyticsQuery", "", "", "Argument[0]", "nosql-injection", "manual"] + - ["github.com/couchbase/gocb/v2", "Cluster", True, "AnalyticsQuery", "", "", "Argument[0]", "nosql-injection", "manual"] Package grouping ~~~~~~~~~~~~~~~~ From 459d16824e2687fbd1bbec29ce052a19939ee926 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Tue, 29 Oct 2024 21:26:59 -0400 Subject: [PATCH 019/470] Java: weak crypto: do not report weak hash algorithms --- java/ql/lib/semmle/code/java/security/Encryption.qll | 5 +---- .../code/java/security/MaybeBrokenCryptoAlgorithmQuery.qll | 6 +++++- java/ql/src/change-notes/2024-10-29-weak-crypto-hash.md | 4 ++++ .../CWE-327/semmle/tests/BrokenCryptoAlgorithm.expected | 6 ------ 4 files changed, 10 insertions(+), 11 deletions(-) create mode 100644 java/ql/src/change-notes/2024-10-29-weak-crypto-hash.md diff --git a/java/ql/lib/semmle/code/java/security/Encryption.qll b/java/ql/lib/semmle/code/java/security/Encryption.qll index 6fc7f6b7d16..1b28f5cbba6 100644 --- a/java/ql/lib/semmle/code/java/security/Encryption.qll +++ b/java/ql/lib/semmle/code/java/security/Encryption.qll @@ -223,10 +223,7 @@ string getAnInsecureHashAlgorithmName() { } private string rankedInsecureAlgorithm(int i) { - // In this case we know these are being used for encryption, so we want to match - // weak hash algorithms too. - result = - rank[i](string s | s = getAnInsecureAlgorithmName() or s = getAnInsecureHashAlgorithmName()) + result = rank[i](string s | s = getAnInsecureAlgorithmName()) } private string insecureAlgorithmString(int i) { diff --git a/java/ql/lib/semmle/code/java/security/MaybeBrokenCryptoAlgorithmQuery.qll b/java/ql/lib/semmle/code/java/security/MaybeBrokenCryptoAlgorithmQuery.qll index 1533b61dd5e..060a30f87e6 100644 --- a/java/ql/lib/semmle/code/java/security/MaybeBrokenCryptoAlgorithmQuery.qll +++ b/java/ql/lib/semmle/code/java/security/MaybeBrokenCryptoAlgorithmQuery.qll @@ -30,7 +30,11 @@ class InsecureAlgoLiteral extends InsecureAlgorithm, ShortStringLiteral { s.length() > 1 and not s.regexpMatch(getSecureAlgorithmRegex()) and // Exclude results covered by another query. - not s.regexpMatch(getInsecureAlgorithmRegex()) + not s.regexpMatch(getInsecureAlgorithmRegex()) and + // Exclude results covered by `InsecureAlgoProperty`. + // This removes duplicates when a string literal is a default value for the property, + // such as "MD5" in the following: `props.getProperty("hashAlg2", "MD5")`. + not exists(InsecureAlgoProperty insecAlgoProp | this = insecAlgoProp.getAnArgument()) ) } diff --git a/java/ql/src/change-notes/2024-10-29-weak-crypto-hash.md b/java/ql/src/change-notes/2024-10-29-weak-crypto-hash.md new file mode 100644 index 00000000000..b4ac88bcdc6 --- /dev/null +++ b/java/ql/src/change-notes/2024-10-29-weak-crypto-hash.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `java/weak-cryptographic-algorithm` query has been updated to no longer report uses of hash functions such as `MD5` and `SHA1` even if they are known to be weak. These hash algorithms are used very often in non-sensitive contexts, making the query too imprecise in practice. The `java/potentially-weak-cryptographic-algorithm` query has been updated to report these uses instead. diff --git a/java/ql/test/query-tests/security/CWE-327/semmle/tests/BrokenCryptoAlgorithm.expected b/java/ql/test/query-tests/security/CWE-327/semmle/tests/BrokenCryptoAlgorithm.expected index 612e1c73054..94719b47739 100644 --- a/java/ql/test/query-tests/security/CWE-327/semmle/tests/BrokenCryptoAlgorithm.expected +++ b/java/ql/test/query-tests/security/CWE-327/semmle/tests/BrokenCryptoAlgorithm.expected @@ -1,14 +1,8 @@ #select | Test.java:19:20:19:50 | getInstance(...) | Test.java:19:45:19:49 | "DES" | Test.java:19:45:19:49 | "DES" | Cryptographic algorithm $@ is weak and should not be used. | Test.java:19:45:19:49 | "DES" | DES | | Test.java:42:14:42:38 | getInstance(...) | Test.java:42:33:42:37 | "RC2" | Test.java:42:33:42:37 | "RC2" | Cryptographic algorithm $@ is weak and should not be used. | Test.java:42:33:42:37 | "RC2" | RC2 | -| WeakHashing.java:21:30:21:92 | getInstance(...) | WeakHashing.java:21:86:21:90 | "MD5" : String | WeakHashing.java:21:56:21:91 | getProperty(...) | Cryptographic algorithm $@ is weak and should not be used. | WeakHashing.java:21:86:21:90 | "MD5" | MD5 | edges -| WeakHashing.java:21:86:21:90 | "MD5" : String | WeakHashing.java:21:56:21:91 | getProperty(...) | provenance | MaD:1 | -models -| 1 | Summary: java.util; Properties; true; getProperty; (String,String); ; Argument[1]; ReturnValue; value; manual | nodes | Test.java:19:45:19:49 | "DES" | semmle.label | "DES" | | Test.java:42:33:42:37 | "RC2" | semmle.label | "RC2" | -| WeakHashing.java:21:56:21:91 | getProperty(...) | semmle.label | getProperty(...) | -| WeakHashing.java:21:86:21:90 | "MD5" : String | semmle.label | "MD5" : String | subpaths From 7279cc42f86146e1c34978989182ecc05b3c2667 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 8 Nov 2024 09:49:47 +0000 Subject: [PATCH 020/470] Rust: Add resolved macros to rust/summary/summary-stats. --- rust/ql/src/queries/summary/SummaryStats.ql | 4 ++++ rust/ql/test/query-tests/diagnostics/SummaryStats.expected | 2 ++ 2 files changed, 6 insertions(+) diff --git a/rust/ql/src/queries/summary/SummaryStats.ql b/rust/ql/src/queries/summary/SummaryStats.ql index 3f24eb50d19..53856bf7b03 100644 --- a/rust/ql/src/queries/summary/SummaryStats.ql +++ b/rust/ql/src/queries/summary/SummaryStats.ql @@ -37,4 +37,8 @@ where key = "Inconsistencies - CFG" and value = getTotalCfgInconsistencies() or key = "Inconsistencies - data flow" and value = getTotalDataFlowInconsistencies() + or + key = "Macro calls - total" and value = count(MacroCall mc) + or + key = "Macro calls - resolved" and value = count(MacroCall mc | mc.hasExpanded()) select key, value diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index 37ec4eb1425..6508ec059a6 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -10,3 +10,5 @@ | Inconsistencies - data flow | 7 | | Lines of code extracted | 59 | | Lines of user code extracted | 59 | +| Macro calls - resolved | 8 | +| Macro calls - total | 8 | From 7b265b2df3172d4723bc50777bd4e784bb0032f3 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 8 Nov 2024 09:53:32 +0000 Subject: [PATCH 021/470] Rust: Add a deliberately unresolvable macro call to the test. --- .../diagnostics/ExtractionWarnings.expected | 1 + .../query-tests/diagnostics/LinesOfCode.expected | 2 +- .../diagnostics/LinesOfUserCode.expected | 2 +- .../diagnostics/LinesOfUserCodeInFiles.expected | 2 +- .../query-tests/diagnostics/SummaryStats.expected | 14 +++++++------- rust/ql/test/query-tests/diagnostics/my_macro.rs | 5 +++-- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/rust/ql/test/query-tests/diagnostics/ExtractionWarnings.expected b/rust/ql/test/query-tests/diagnostics/ExtractionWarnings.expected index 1ebd7e23221..9db7d1d2383 100644 --- a/rust/ql/test/query-tests/diagnostics/ExtractionWarnings.expected +++ b/rust/ql/test/query-tests/diagnostics/ExtractionWarnings.expected @@ -5,3 +5,4 @@ | does_not_compile.rs:2:26:2:25 | expected SEMICOLON | Extraction warning in does_not_compile.rs with message expected SEMICOLON | 1 | | does_not_compile.rs:2:32:2:31 | expected field name or number | Extraction warning in does_not_compile.rs with message expected field name or number | 1 | | error.rs:2:5:2:17 | An error! | Extraction warning in error.rs with message An error! | 1 | +| my_macro.rs:17:9:17:27 | macro expansion failed: could not resolve macro 'myUndefinedMacro' | Extraction warning in my_macro.rs with message macro expansion failed: could not resolve macro 'myUndefinedMacro' | 1 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected b/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected index 6facd293859..5fa7b20e01b 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected @@ -1 +1 @@ -| 59 | +| 60 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected index 6facd293859..5fa7b20e01b 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected @@ -1 +1 @@ -| 59 | +| 60 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected index fe63f68abd8..d11c7dc615b 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected @@ -1,7 +1,7 @@ | my_struct.rs:0:0:0:0 | my_struct.rs | 20 | | comments.rs:0:0:0:0 | comments.rs | 13 | | main.rs:0:0:0:0 | main.rs | 8 | -| my_macro.rs:0:0:0:0 | my_macro.rs | 7 | +| my_macro.rs:0:0:0:0 | my_macro.rs | 8 | | lib.rs:0:0:0:0 | lib.rs | 5 | | does_not_compile.rs:0:0:0:0 | does_not_compile.rs | 3 | | error.rs:0:0:0:0 | error.rs | 3 | diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index 6508ec059a6..317be07ec7a 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -1,14 +1,14 @@ -| Elements extracted | 376 | +| Elements extracted | 383 | | Elements unextracted | 0 | | Extraction errors | 0 | -| Extraction warnings | 7 | +| Extraction warnings | 8 | | Files extracted - total | 7 | -| Files extracted - with errors | 2 | -| Files extracted - without errors | 5 | +| Files extracted - with errors | 3 | +| Files extracted - without errors | 4 | | Inconsistencies - AST | 0 | | Inconsistencies - CFG | 0 | | Inconsistencies - data flow | 7 | -| Lines of code extracted | 59 | -| Lines of user code extracted | 59 | +| Lines of code extracted | 60 | +| Lines of user code extracted | 60 | | Macro calls - resolved | 8 | -| Macro calls - total | 8 | +| Macro calls - total | 9 | diff --git a/rust/ql/test/query-tests/diagnostics/my_macro.rs b/rust/ql/test/query-tests/diagnostics/my_macro.rs index d8a0cc2812b..3b24857aa6c 100644 --- a/rust/ql/test/query-tests/diagnostics/my_macro.rs +++ b/rust/ql/test/query-tests/diagnostics/my_macro.rs @@ -1,6 +1,6 @@ /** - * total lines in this file: 18 - * of which code: 10 + * total lines in this file: 19 + * of which code: 11 * of which only comments: 6 * of which blank: 2 */ @@ -14,5 +14,6 @@ macro_rules! myMacro { pub fn my_func() { if true { myMacro!(); + myUndefinedMacro!(); } } From 0d1bd8a9cdd359885d86054a9ea6248f4a4dfaa7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 8 Nov 2024 10:19:28 +0000 Subject: [PATCH 022/470] Rust: Add 'order by' to the summary stats query (doesn't seem to affect the test, but affects VSCode runs). --- rust/ql/src/queries/summary/SummaryStats.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/src/queries/summary/SummaryStats.ql b/rust/ql/src/queries/summary/SummaryStats.ql index 53856bf7b03..2ff6fc7be70 100644 --- a/rust/ql/src/queries/summary/SummaryStats.ql +++ b/rust/ql/src/queries/summary/SummaryStats.ql @@ -41,4 +41,4 @@ where key = "Macro calls - total" and value = count(MacroCall mc) or key = "Macro calls - resolved" and value = count(MacroCall mc | mc.hasExpanded()) -select key, value +select key, value order by key From 04926df6ea9fa4f33b66b30501f75c52ed3e6833 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 8 Nov 2024 10:11:21 +0000 Subject: [PATCH 023/470] Rust: Add rust/diagnostics/unresolved-macro-calls diagnostic query. --- .../src/queries/diagnostics/UnresolvedMacroCalls.ql | 11 +++++++++++ .../diagnostics/UnresolvedMacroCalls.expected | 1 + .../diagnostics/UnresolvedMacroCalls.qlref | 1 + 3 files changed, 13 insertions(+) create mode 100644 rust/ql/src/queries/diagnostics/UnresolvedMacroCalls.ql create mode 100644 rust/ql/test/query-tests/diagnostics/UnresolvedMacroCalls.expected create mode 100644 rust/ql/test/query-tests/diagnostics/UnresolvedMacroCalls.qlref diff --git a/rust/ql/src/queries/diagnostics/UnresolvedMacroCalls.ql b/rust/ql/src/queries/diagnostics/UnresolvedMacroCalls.ql new file mode 100644 index 00000000000..49ff698dcb0 --- /dev/null +++ b/rust/ql/src/queries/diagnostics/UnresolvedMacroCalls.ql @@ -0,0 +1,11 @@ +/** + * @name Unresolved Macro Calls + * @description List all macro calls that were not resolved to a target. + * @id rust/diagnostics/unresolved-macro-calls + */ + +import rust + +from MacroCall mc +where not mc.hasExpanded() +select mc, "Macro call was not resolved to a target." diff --git a/rust/ql/test/query-tests/diagnostics/UnresolvedMacroCalls.expected b/rust/ql/test/query-tests/diagnostics/UnresolvedMacroCalls.expected new file mode 100644 index 00000000000..28fb46e8283 --- /dev/null +++ b/rust/ql/test/query-tests/diagnostics/UnresolvedMacroCalls.expected @@ -0,0 +1 @@ +| my_macro.rs:17:9:17:27 | MacroCall | Macro call was not resolved to a target. | diff --git a/rust/ql/test/query-tests/diagnostics/UnresolvedMacroCalls.qlref b/rust/ql/test/query-tests/diagnostics/UnresolvedMacroCalls.qlref new file mode 100644 index 00000000000..77f337e2703 --- /dev/null +++ b/rust/ql/test/query-tests/diagnostics/UnresolvedMacroCalls.qlref @@ -0,0 +1 @@ +queries/diagnostics/UnresolvedMacroCalls.ql From f827ad815709a0887662f820bdd071cddcd9bd81 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 8 Nov 2024 12:33:06 +0000 Subject: [PATCH 024/470] Rust: Add missing @kind diagnostic query metadata. --- rust/ql/src/queries/diagnostics/UnextractedElements.ql | 1 + rust/ql/src/queries/diagnostics/UnresolvedMacroCalls.ql | 1 + 2 files changed, 2 insertions(+) diff --git a/rust/ql/src/queries/diagnostics/UnextractedElements.ql b/rust/ql/src/queries/diagnostics/UnextractedElements.ql index dccf7d2ab09..1a819e3f784 100644 --- a/rust/ql/src/queries/diagnostics/UnextractedElements.ql +++ b/rust/ql/src/queries/diagnostics/UnextractedElements.ql @@ -1,6 +1,7 @@ /** * @name Unextracted Elements * @description List all elements that weren't extracted due to unimplemented features or parse errors. + * @kind diagnostic * @id rust/diagnostics/unextracted-elements */ diff --git a/rust/ql/src/queries/diagnostics/UnresolvedMacroCalls.ql b/rust/ql/src/queries/diagnostics/UnresolvedMacroCalls.ql index 49ff698dcb0..a20c5035b6a 100644 --- a/rust/ql/src/queries/diagnostics/UnresolvedMacroCalls.ql +++ b/rust/ql/src/queries/diagnostics/UnresolvedMacroCalls.ql @@ -1,6 +1,7 @@ /** * @name Unresolved Macro Calls * @description List all macro calls that were not resolved to a target. + * @kind diagnostic * @id rust/diagnostics/unresolved-macro-calls */ From ede72b26809f1bf8d735124bcee1cd5ba52f01d9 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 8 Nov 2024 13:59:05 +0000 Subject: [PATCH 025/470] Rust: Add unresolved macro calls count as well. --- rust/ql/src/queries/summary/SummaryStats.ql | 2 ++ rust/ql/test/query-tests/diagnostics/SummaryStats.expected | 1 + 2 files changed, 3 insertions(+) diff --git a/rust/ql/src/queries/summary/SummaryStats.ql b/rust/ql/src/queries/summary/SummaryStats.ql index 2ff6fc7be70..72a876ba08c 100644 --- a/rust/ql/src/queries/summary/SummaryStats.ql +++ b/rust/ql/src/queries/summary/SummaryStats.ql @@ -41,4 +41,6 @@ where key = "Macro calls - total" and value = count(MacroCall mc) or key = "Macro calls - resolved" and value = count(MacroCall mc | mc.hasExpanded()) + or + key = "Macro calls - unresolved" and value = count(MacroCall mc | not mc.hasExpanded()) select key, value order by key diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index 317be07ec7a..ecc33cd7be2 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -12,3 +12,4 @@ | Lines of user code extracted | 60 | | Macro calls - resolved | 8 | | Macro calls - total | 9 | +| Macro calls - unresolved | 1 | From 82f09f1f8bdd73e3be0d9e3bf36df0f9a92b032a Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 11 Nov 2024 10:19:32 +0100 Subject: [PATCH 026/470] Updated TS version to 5.7.1-release candidate --- javascript/extractor/lib/typescript/package-lock.json | 8 ++++---- javascript/extractor/lib/typescript/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/javascript/extractor/lib/typescript/package-lock.json b/javascript/extractor/lib/typescript/package-lock.json index 50a9e0a66ca..47015f8f6e3 100644 --- a/javascript/extractor/lib/typescript/package-lock.json +++ b/javascript/extractor/lib/typescript/package-lock.json @@ -6,7 +6,7 @@ "": { "name": "typescript-parser-wrapper", "dependencies": { - "typescript": "^5.6.2" + "typescript": "^5.7.1-rc" }, "devDependencies": { "@types/node": "18.15.3" @@ -20,9 +20,9 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "version": "5.7.1-rc", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.1-rc.tgz", + "integrity": "sha512-d6m+HT78uZtyUbXbUyIvuJ6kXCTSJEfy+2pZSUwt9d6JZ0kOMNDwhIILfV5FnaxMwVa48Yfw4sK0ISC4Qyq5tw==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/javascript/extractor/lib/typescript/package.json b/javascript/extractor/lib/typescript/package.json index bf650ec457a..730a3b5f53e 100644 --- a/javascript/extractor/lib/typescript/package.json +++ b/javascript/extractor/lib/typescript/package.json @@ -2,7 +2,7 @@ "name": "typescript-parser-wrapper", "private": true, "dependencies": { - "typescript": "5.6.2" + "typescript": "^5.7.1-rc" }, "scripts": { "build": "tsc --project tsconfig.json", From c2c6b77b11350fc83773d09b21f9a61faaee73b2 Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 12 Nov 2024 11:05:12 +0100 Subject: [PATCH 027/470] Added new test case for TS57 Creating Index Signatures from Non-Literal Method Names in Classes --- .../TypeScript/Types/printAst.expected | 139 ++++++++++++++---- .../TypeScript/Types/tests.expected | 14 ++ .../library-tests/TypeScript/Types/tst.ts | 11 +- 3 files changed, 132 insertions(+), 32 deletions(-) diff --git a/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected b/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected index 3061a6ba1f0..df304b899bb 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected @@ -1877,8 +1877,35 @@ nodes | tst.ts:508:17:508:38 | [MethodCallExpr] obj[key ... rCase() | semmle.label | [MethodCallExpr] obj[key ... rCase() | | tst.ts:508:21:508:23 | [VarRef] key | semmle.label | [VarRef] key | | tst.ts:508:26:508:36 | [Label] toUpperCase | semmle.label | [Label] toUpperCase | +| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | semmle.label | [NamespaceDeclaration] namespa ... type. } | +| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | semmle.order | 92 | +| tst.ts:513:11:513:14 | [VarDecl] TS57 | semmle.label | [VarDecl] TS57 | +| tst.ts:514:3:514:26 | [DeclStmt] const a = ... | semmle.label | [DeclStmt] const a = ... | +| tst.ts:514:17:514:17 | [VarDecl] a | semmle.label | [VarDecl] a | +| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | semmle.label | [VariableDeclarator] a: symbol | +| tst.ts:514:20:514:25 | [KeywordTypeExpr] symbol | semmle.label | [KeywordTypeExpr] symbol | +| tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | semmle.label | [ExportDeclaration] export ... }; } | +| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | semmle.label | [ClassDefinition,TypeDefinition] class A ... }; } | +| tst.ts:515:16:515:16 | [VarDecl] A | semmle.label | [VarDecl] A | +| tst.ts:515:18:515:17 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | +| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} | +| tst.ts:515:18:515:17 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} | +| tst.ts:515:18:515:17 | [Label] constructor | semmle.label | [Label] constructor | +| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | semmle.label | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | +| tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | semmle.label | [FunctionExpr] [a]() { return 1 } | +| tst.ts:516:8:516:8 | [VarRef] a | semmle.label | [VarRef] a | +| tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | semmle.label | [BlockStmt] { return 1 } | +| tst.ts:516:15:516:22 | [ReturnStmt] return 1 | semmle.label | [ReturnStmt] return 1 | +| tst.ts:516:22:516:22 | [Literal] 1 | semmle.label | [Literal] 1 | +| tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | semmle.label | [DeclStmt] const e1 = ... | +| tst.ts:519:17:519:18 | [VarDecl] e1 | semmle.label | [VarDecl] e1 | +| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | semmle.label | [VariableDeclarator] e1: A[typeof a] | +| tst.ts:519:21:519:21 | [LocalTypeAccess] A | semmle.label | [LocalTypeAccess] A | +| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | semmle.label | [IndexedAccessTypeExpr] A[typeof a] | +| tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | semmle.label | [TypeofTypeExpr] typeof a | +| tst.ts:519:30:519:30 | [LocalVarTypeAccess] a | semmle.label | [LocalVarTypeAccess] a | | tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.label | [ExportDeclaration] export ... 'b'; } | -| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 92 | +| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 93 | | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | [FunctionDeclStmt] functio ... 'b'; } | | tstModuleCJS.cts:1:17:1:28 | [VarDecl] tstModuleCJS | semmle.label | [VarDecl] tstModuleCJS | | tstModuleCJS.cts:1:33:1:35 | [LiteralTypeExpr] 'a' | semmle.label | [LiteralTypeExpr] 'a' | @@ -1896,7 +1923,7 @@ nodes | tstModuleCJS.cts:2:34:2:36 | [Literal] 'a' | semmle.label | [Literal] 'a' | | tstModuleCJS.cts:2:40:2:42 | [Literal] 'b' | semmle.label | [Literal] 'b' | | tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.label | [ExportDeclaration] export ... 'b'; } | -| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 93 | +| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 94 | | tstModuleES.mts:1:16:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | [FunctionDeclStmt] functio ... 'b'; } | | tstModuleES.mts:1:25:1:35 | [VarDecl] tstModuleES | semmle.label | [VarDecl] tstModuleES | | tstModuleES.mts:1:40:1:42 | [LiteralTypeExpr] 'a' | semmle.label | [LiteralTypeExpr] 'a' | @@ -1914,7 +1941,7 @@ nodes | tstModuleES.mts:2:34:2:36 | [Literal] 'a' | semmle.label | [Literal] 'a' | | tstModuleES.mts:2:40:2:42 | [Literal] 'b' | semmle.label | [Literal] 'b' | | tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } | -| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 94 | +| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 95 | | tstSuffixA.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } | | tstSuffixA.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile | | tstSuffixA.ts:1:33:1:47 | [LiteralTypeExpr] 'tstSuffixA.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixA.ts' | @@ -1922,7 +1949,7 @@ nodes | tstSuffixA.ts:2:5:2:27 | [ReturnStmt] return ... xA.ts'; | semmle.label | [ReturnStmt] return ... xA.ts'; | | tstSuffixA.ts:2:12:2:26 | [Literal] 'tstSuffixA.ts' | semmle.label | [Literal] 'tstSuffixA.ts' | | tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } | -| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 95 | +| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 96 | | tstSuffixB.ios.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } | | tstSuffixB.ios.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile | | tstSuffixB.ios.ts:1:33:1:51 | [LiteralTypeExpr] 'tstSuffixB.ios.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixB.ios.ts' | @@ -1930,7 +1957,7 @@ nodes | tstSuffixB.ios.ts:2:5:2:31 | [ReturnStmt] return ... os.ts'; | semmle.label | [ReturnStmt] return ... os.ts'; | | tstSuffixB.ios.ts:2:12:2:30 | [Literal] 'tstSuffixB.ios.ts' | semmle.label | [Literal] 'tstSuffixB.ios.ts' | | tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } | -| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 96 | +| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 97 | | tstSuffixB.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } | | tstSuffixB.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile | | tstSuffixB.ts:1:33:1:47 | [LiteralTypeExpr] 'tstSuffixB.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixB.ts' | @@ -1938,16 +1965,16 @@ nodes | tstSuffixB.ts:2:5:2:27 | [ReturnStmt] return ... xB.ts'; | semmle.label | [ReturnStmt] return ... xB.ts'; | | tstSuffixB.ts:2:12:2:26 | [Literal] 'tstSuffixB.ts' | semmle.label | [Literal] 'tstSuffixB.ts' | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | -| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 97 | +| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 98 | | type_alias.ts:1:6:1:6 | [Identifier] B | semmle.label | [Identifier] B | | type_alias.ts:1:10:1:16 | [KeywordTypeExpr] boolean | semmle.label | [KeywordTypeExpr] boolean | | type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.label | [DeclStmt] var b = ... | -| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 98 | +| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 99 | | type_alias.ts:3:5:3:5 | [VarDecl] b | semmle.label | [VarDecl] b | | type_alias.ts:3:5:3:8 | [VariableDeclarator] b: B | semmle.label | [VariableDeclarator] b: B | | type_alias.ts:3:8:3:8 | [LocalTypeAccess] B | semmle.label | [LocalTypeAccess] B | | type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | -| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.order | 99 | +| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.order | 100 | | type_alias.ts:5:6:5:17 | [Identifier] ValueOrArray | semmle.label | [Identifier] ValueOrArray | | type_alias.ts:5:19:5:19 | [Identifier] T | semmle.label | [Identifier] T | | type_alias.ts:5:19:5:19 | [TypeParameter] T | semmle.label | [TypeParameter] T | @@ -1959,14 +1986,14 @@ nodes | type_alias.ts:5:34:5:48 | [GenericTypeExpr] ValueOrArray | semmle.label | [GenericTypeExpr] ValueOrArray | | type_alias.ts:5:47:5:47 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T | | type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.label | [DeclStmt] var c = ... | -| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 100 | +| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 101 | | type_alias.ts:7:5:7:5 | [VarDecl] c | semmle.label | [VarDecl] c | | type_alias.ts:7:5:7:27 | [VariableDeclarator] c: Valu ... number> | semmle.label | [VariableDeclarator] c: Valu ... number> | | type_alias.ts:7:8:7:19 | [LocalTypeAccess] ValueOrArray | semmle.label | [LocalTypeAccess] ValueOrArray | | type_alias.ts:7:8:7:27 | [GenericTypeExpr] ValueOrArray | semmle.label | [GenericTypeExpr] ValueOrArray | | type_alias.ts:7:21:7:26 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | | type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | -| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 101 | +| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 102 | | type_alias.ts:9:6:9:9 | [Identifier] Json | semmle.label | [Identifier] Json | | type_alias.ts:10:5:15:12 | [UnionTypeExpr] \| strin ... Json[] | semmle.label | [UnionTypeExpr] \| strin ... Json[] | | type_alias.ts:10:7:10:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | @@ -1982,12 +2009,12 @@ nodes | type_alias.ts:15:7:15:10 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json | | type_alias.ts:15:7:15:12 | [ArrayTypeExpr] Json[] | semmle.label | [ArrayTypeExpr] Json[] | | type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.label | [DeclStmt] var json = ... | -| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 102 | +| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 103 | | type_alias.ts:17:5:17:8 | [VarDecl] json | semmle.label | [VarDecl] json | | type_alias.ts:17:5:17:14 | [VariableDeclarator] json: Json | semmle.label | [VariableDeclarator] json: Json | | type_alias.ts:17:11:17:14 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json | | type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | -| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 103 | +| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 104 | | type_alias.ts:19:6:19:16 | [Identifier] VirtualNode | semmle.label | [Identifier] VirtualNode | | type_alias.ts:20:5:21:56 | [UnionTypeExpr] \| strin ... Node[]] | semmle.label | [UnionTypeExpr] \| strin ... Node[]] | | type_alias.ts:20:7:20:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | @@ -2003,7 +2030,7 @@ nodes | type_alias.ts:21:43:21:53 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode | | type_alias.ts:21:43:21:55 | [ArrayTypeExpr] VirtualNode[] | semmle.label | [ArrayTypeExpr] VirtualNode[] | | type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.label | [DeclStmt] const myNode = ... | -| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 104 | +| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 105 | | type_alias.ts:23:7:23:12 | [VarDecl] myNode | semmle.label | [VarDecl] myNode | | type_alias.ts:23:7:27:5 | [VariableDeclarator] myNode: ... ] ] | semmle.label | [VariableDeclarator] myNode: ... ] ] | | type_alias.ts:23:15:23:25 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode | @@ -2028,12 +2055,12 @@ nodes | type_alias.ts:26:23:26:36 | [Literal] "second-child" | semmle.label | [Literal] "second-child" | | type_alias.ts:26:41:26:62 | [Literal] "I'm the second child" | semmle.label | [Literal] "I'm the second child" | | type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; | -| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 105 | +| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 106 | | type_definition_objects.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy | | type_definition_objects.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy | | type_definition_objects.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" | | type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.label | [ExportDeclaration] export class C {} | -| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 106 | +| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 107 | | type_definition_objects.ts:3:8:3:17 | [ClassDefinition,TypeDefinition] class C {} | semmle.label | [ClassDefinition,TypeDefinition] class C {} | | type_definition_objects.ts:3:14:3:14 | [VarDecl] C | semmle.label | [VarDecl] C | | type_definition_objects.ts:3:16:3:15 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | @@ -2041,36 +2068,36 @@ nodes | type_definition_objects.ts:3:16:3:15 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} | | type_definition_objects.ts:3:16:3:15 | [Label] constructor | semmle.label | [Label] constructor | | type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.label | [DeclStmt] let classObj = ... | -| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 107 | +| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 108 | | type_definition_objects.ts:4:5:4:12 | [VarDecl] classObj | semmle.label | [VarDecl] classObj | | type_definition_objects.ts:4:5:4:16 | [VariableDeclarator] classObj = C | semmle.label | [VariableDeclarator] classObj = C | | type_definition_objects.ts:4:16:4:16 | [VarRef] C | semmle.label | [VarRef] C | | type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.label | [ExportDeclaration] export enum E {} | -| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 108 | +| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 109 | | type_definition_objects.ts:6:8:6:16 | [EnumDeclaration,TypeDefinition] enum E {} | semmle.label | [EnumDeclaration,TypeDefinition] enum E {} | | type_definition_objects.ts:6:13:6:13 | [VarDecl] E | semmle.label | [VarDecl] E | | type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.label | [DeclStmt] let enumObj = ... | -| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 109 | +| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 110 | | type_definition_objects.ts:7:5:7:11 | [VarDecl] enumObj | semmle.label | [VarDecl] enumObj | | type_definition_objects.ts:7:5:7:15 | [VariableDeclarator] enumObj = E | semmle.label | [VariableDeclarator] enumObj = E | | type_definition_objects.ts:7:15:7:15 | [VarRef] E | semmle.label | [VarRef] E | | type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.label | [ExportDeclaration] export ... e N {;} | -| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 110 | +| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 111 | | type_definition_objects.ts:9:8:9:22 | [NamespaceDeclaration] namespace N {;} | semmle.label | [NamespaceDeclaration] namespace N {;} | | type_definition_objects.ts:9:18:9:18 | [VarDecl] N | semmle.label | [VarDecl] N | | type_definition_objects.ts:9:21:9:21 | [EmptyStmt] ; | semmle.label | [EmptyStmt] ; | | type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.label | [DeclStmt] let namespaceObj = ... | -| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 111 | +| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 112 | | type_definition_objects.ts:10:5:10:16 | [VarDecl] namespaceObj | semmle.label | [VarDecl] namespaceObj | | type_definition_objects.ts:10:5:10:20 | [VariableDeclarator] namespaceObj = N | semmle.label | [VariableDeclarator] namespaceObj = N | | type_definition_objects.ts:10:20:10:20 | [VarRef] N | semmle.label | [VarRef] N | | type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; | -| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 112 | +| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 113 | | type_definitions.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy | | type_definitions.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy | | type_definitions.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" | | type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | -| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 113 | +| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 114 | | type_definitions.ts:3:11:3:11 | [Identifier] I | semmle.label | [Identifier] I | | type_definitions.ts:3:13:3:13 | [Identifier] S | semmle.label | [Identifier] S | | type_definitions.ts:3:13:3:13 | [TypeParameter] S | semmle.label | [TypeParameter] S | @@ -2078,14 +2105,14 @@ nodes | type_definitions.ts:4:3:4:7 | [FieldDeclaration] x: S; | semmle.label | [FieldDeclaration] x: S; | | type_definitions.ts:4:6:4:6 | [LocalTypeAccess] S | semmle.label | [LocalTypeAccess] S | | type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.label | [DeclStmt] let i = ... | -| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 114 | +| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 115 | | type_definitions.ts:6:5:6:5 | [VarDecl] i | semmle.label | [VarDecl] i | | type_definitions.ts:6:5:6:16 | [VariableDeclarator] i: I | semmle.label | [VariableDeclarator] i: I | | type_definitions.ts:6:8:6:8 | [LocalTypeAccess] I | semmle.label | [LocalTypeAccess] I | | type_definitions.ts:6:8:6:16 | [GenericTypeExpr] I | semmle.label | [GenericTypeExpr] I | | type_definitions.ts:6:10:6:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | | type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.label | [ClassDefinition,TypeDefinition] class C ... x: T } | -| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 115 | +| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 116 | | type_definitions.ts:8:7:8:7 | [VarDecl] C | semmle.label | [VarDecl] C | | type_definitions.ts:8:8:8:7 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | | type_definitions.ts:8:8:8:7 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} | @@ -2097,14 +2124,14 @@ nodes | type_definitions.ts:9:3:9:6 | [FieldDeclaration] x: T | semmle.label | [FieldDeclaration] x: T | | type_definitions.ts:9:6:9:6 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T | | type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.label | [DeclStmt] let c = ... | -| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 116 | +| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 117 | | type_definitions.ts:11:5:11:5 | [VarDecl] c | semmle.label | [VarDecl] c | | type_definitions.ts:11:5:11:16 | [VariableDeclarator] c: C | semmle.label | [VariableDeclarator] c: C | | type_definitions.ts:11:8:11:8 | [LocalTypeAccess] C | semmle.label | [LocalTypeAccess] C | | type_definitions.ts:11:8:11:16 | [GenericTypeExpr] C | semmle.label | [GenericTypeExpr] C | | type_definitions.ts:11:10:11:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | | type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.label | [EnumDeclaration,TypeDefinition] enum Co ... blue } | -| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 117 | +| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 118 | | type_definitions.ts:13:6:13:10 | [VarDecl] Color | semmle.label | [VarDecl] Color | | type_definitions.ts:14:3:14:5 | [EnumMember,TypeDefinition] red | semmle.label | [EnumMember,TypeDefinition] red | | type_definitions.ts:14:3:14:5 | [VarDecl] red | semmle.label | [VarDecl] red | @@ -2113,29 +2140,29 @@ nodes | type_definitions.ts:14:15:14:18 | [EnumMember,TypeDefinition] blue | semmle.label | [EnumMember,TypeDefinition] blue | | type_definitions.ts:14:15:14:18 | [VarDecl] blue | semmle.label | [VarDecl] blue | | type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.label | [DeclStmt] let color = ... | -| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 118 | +| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 119 | | type_definitions.ts:16:5:16:9 | [VarDecl] color | semmle.label | [VarDecl] color | | type_definitions.ts:16:5:16:16 | [VariableDeclarator] color: Color | semmle.label | [VariableDeclarator] color: Color | | type_definitions.ts:16:12:16:16 | [LocalTypeAccess] Color | semmle.label | [LocalTypeAccess] Color | | type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.label | [EnumDeclaration,TypeDefinition] enum En ... ember } | -| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 119 | +| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 120 | | type_definitions.ts:18:6:18:22 | [VarDecl] EnumWithOneMember | semmle.label | [VarDecl] EnumWithOneMember | | type_definitions.ts:18:26:18:31 | [EnumMember,TypeDefinition] member | semmle.label | [EnumMember,TypeDefinition] member | | type_definitions.ts:18:26:18:31 | [VarDecl] member | semmle.label | [VarDecl] member | | type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.label | [DeclStmt] let e = ... | -| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 120 | +| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 121 | | type_definitions.ts:19:5:19:5 | [VarDecl] e | semmle.label | [VarDecl] e | | type_definitions.ts:19:5:19:24 | [VariableDeclarator] e: EnumWithOneMember | semmle.label | [VariableDeclarator] e: EnumWithOneMember | | type_definitions.ts:19:8:19:24 | [LocalTypeAccess] EnumWithOneMember | semmle.label | [LocalTypeAccess] EnumWithOneMember | | type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | -| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.order | 121 | +| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.order | 122 | | type_definitions.ts:21:6:21:10 | [Identifier] Alias | semmle.label | [Identifier] Alias | | type_definitions.ts:21:12:21:12 | [Identifier] T | semmle.label | [Identifier] T | | type_definitions.ts:21:12:21:12 | [TypeParameter] T | semmle.label | [TypeParameter] T | | type_definitions.ts:21:17:21:17 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T | | type_definitions.ts:21:17:21:19 | [ArrayTypeExpr] T[] | semmle.label | [ArrayTypeExpr] T[] | | type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.label | [DeclStmt] let aliasForNumberArray = ... | -| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 122 | +| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 123 | | type_definitions.ts:22:5:22:23 | [VarDecl] aliasForNumberArray | semmle.label | [VarDecl] aliasForNumberArray | | type_definitions.ts:22:5:22:38 | [VariableDeclarator] aliasFo ... number> | semmle.label | [VariableDeclarator] aliasFo ... number> | | type_definitions.ts:22:26:22:30 | [LocalTypeAccess] Alias | semmle.label | [LocalTypeAccess] Alias | @@ -5534,6 +5561,56 @@ edges | tst.ts:508:17:508:36 | [DotExpr] obj[key].toUpperCase | tst.ts:508:26:508:36 | [Label] toUpperCase | semmle.order | 2 | | tst.ts:508:17:508:38 | [MethodCallExpr] obj[key ... rCase() | tst.ts:508:17:508:36 | [DotExpr] obj[key].toUpperCase | semmle.label | 0 | | tst.ts:508:17:508:38 | [MethodCallExpr] obj[key ... rCase() | tst.ts:508:17:508:36 | [DotExpr] obj[key].toUpperCase | semmle.order | 0 | +| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:513:11:513:14 | [VarDecl] TS57 | semmle.label | 1 | +| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:513:11:513:14 | [VarDecl] TS57 | semmle.order | 1 | +| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:514:3:514:26 | [DeclStmt] const a = ... | semmle.label | 2 | +| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:514:3:514:26 | [DeclStmt] const a = ... | semmle.order | 2 | +| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | semmle.label | 3 | +| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | semmle.order | 3 | +| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | semmle.label | 4 | +| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | semmle.order | 4 | +| tst.ts:514:3:514:26 | [DeclStmt] const a = ... | tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | semmle.label | 1 | +| tst.ts:514:3:514:26 | [DeclStmt] const a = ... | tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | semmle.order | 1 | +| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | tst.ts:514:17:514:17 | [VarDecl] a | semmle.label | 1 | +| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | tst.ts:514:17:514:17 | [VarDecl] a | semmle.order | 1 | +| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | tst.ts:514:20:514:25 | [KeywordTypeExpr] symbol | semmle.label | 2 | +| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | tst.ts:514:20:514:25 | [KeywordTypeExpr] symbol | semmle.order | 2 | +| tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | semmle.label | 1 | +| tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | semmle.order | 1 | +| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:515:16:515:16 | [VarDecl] A | semmle.label | 1 | +| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:515:16:515:16 | [VarDecl] A | semmle.order | 1 | +| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | 2 | +| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.order | 2 | +| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | semmle.label | 3 | +| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | semmle.order | 3 | +| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:515:18:515:17 | [FunctionExpr] () {} | semmle.label | 2 | +| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:515:18:515:17 | [FunctionExpr] () {} | semmle.order | 2 | +| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:515:18:515:17 | [Label] constructor | semmle.label | 1 | +| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:515:18:515:17 | [Label] constructor | semmle.order | 1 | +| tst.ts:515:18:515:17 | [FunctionExpr] () {} | tst.ts:515:18:515:17 | [BlockStmt] {} | semmle.label | 5 | +| tst.ts:515:18:515:17 | [FunctionExpr] () {} | tst.ts:515:18:515:17 | [BlockStmt] {} | semmle.order | 5 | +| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | semmle.label | 1 | +| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | semmle.order | 1 | +| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | tst.ts:516:8:516:8 | [VarRef] a | semmle.label | 2 | +| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | tst.ts:516:8:516:8 | [VarRef] a | semmle.order | 2 | +| tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | semmle.label | 5 | +| tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | semmle.order | 5 | +| tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | tst.ts:516:15:516:22 | [ReturnStmt] return 1 | semmle.label | 1 | +| tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | tst.ts:516:15:516:22 | [ReturnStmt] return 1 | semmle.order | 1 | +| tst.ts:516:15:516:22 | [ReturnStmt] return 1 | tst.ts:516:22:516:22 | [Literal] 1 | semmle.label | 1 | +| tst.ts:516:15:516:22 | [ReturnStmt] return 1 | tst.ts:516:22:516:22 | [Literal] 1 | semmle.order | 1 | +| tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | semmle.label | 1 | +| tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | semmle.order | 1 | +| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | tst.ts:519:17:519:18 | [VarDecl] e1 | semmle.label | 1 | +| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | tst.ts:519:17:519:18 | [VarDecl] e1 | semmle.order | 1 | +| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | semmle.label | 2 | +| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | semmle.order | 2 | +| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | tst.ts:519:21:519:21 | [LocalTypeAccess] A | semmle.label | 1 | +| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | tst.ts:519:21:519:21 | [LocalTypeAccess] A | semmle.order | 1 | +| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | semmle.label | 2 | +| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | semmle.order | 2 | +| tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | tst.ts:519:30:519:30 | [LocalVarTypeAccess] a | semmle.label | 1 | +| tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | tst.ts:519:30:519:30 | [LocalVarTypeAccess] a | semmle.order | 1 | | tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | 1 | | tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.order | 1 | | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | tstModuleCJS.cts:1:17:1:28 | [VarDecl] tstModuleCJS | semmle.label | 0 | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/tests.expected b/javascript/ql/test/library-tests/TypeScript/Types/tests.expected index b786fae3713..150ce186724 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/tests.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/tests.expected @@ -728,6 +728,13 @@ getExprType | tst.ts:508:17:508:38 | obj[key ... rCase() | string | | tst.ts:508:21:508:23 | key | string | | tst.ts:508:26:508:36 | toUpperCase | () => string | +| tst.ts:513:11:513:14 | TS57 | typeof TS57 in tst.ts | +| tst.ts:514:17:514:17 | a | symbol | +| tst.ts:515:16:515:16 | A | A | +| tst.ts:516:7:516:24 | [a]() { return 1 } | () => number | +| tst.ts:516:8:516:8 | a | symbol | +| tst.ts:516:22:516:22 | 1 | 1 | +| tst.ts:519:17:519:18 | e1 | () => number | | tstModuleCJS.cts:1:17:1:28 | tstModuleCJS | () => "a" \| "b" | | tstModuleCJS.cts:2:12:2:15 | Math | Math | | tstModuleCJS.cts:2:12:2:22 | Math.random | () => number | @@ -843,6 +850,7 @@ getTypeDefinitionType | tst.ts:447:5:458:5 | class P ... }\\n } | Person | | tst.ts:473:5:476:5 | class S ... ;\\n } | SomeClass | | tst.ts:481:5:481:34 | type Pa ... T, T]; | Pair3 | +| tst.ts:515:10:517:3 | class A ... };\\n } | A | | type_alias.ts:1:1:1:17 | type B = boolean; | boolean | | type_alias.ts:5:1:5:50 | type Va ... ay>; | ValueOrArray | | type_alias.ts:9:1:15:13 | type Js ... Json[]; | Json | @@ -1219,6 +1227,11 @@ getTypeExprType | tst.ts:506:27:506:32 | string | string | | tst.ts:506:35:506:41 | unknown | unknown | | tst.ts:506:50:506:55 | string | string | +| tst.ts:514:20:514:25 | symbol | symbol | +| tst.ts:519:21:519:21 | A | A | +| tst.ts:519:21:519:31 | A[typeof a] | () => number | +| tst.ts:519:23:519:30 | typeof a | symbol | +| tst.ts:519:30:519:30 | a | symbol | | tstModuleCJS.cts:1:33:1:35 | 'a' | "a" | | tstModuleCJS.cts:1:33:1:41 | 'a' \| 'b' | "a" \| "b" | | tstModuleCJS.cts:1:39:1:41 | 'b' | "b" | @@ -1290,6 +1303,7 @@ getTypeExprType missingToString referenceDefinition | A | badTypes.ts:5:1:5:29 | interfa ... is.B {} | +| A | tst.ts:515:10:517:3 | class A ... };\\n } | | Action | tst.ts:252:3:254:50 | type Ac ... ring }; | | Alias | type_definitions.ts:21:1:21:20 | type Alias = T[]; | | Alias | type_definitions.ts:21:1:21:20 | type Alias = T[]; | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/tst.ts b/javascript/ql/test/library-tests/TypeScript/Types/tst.ts index 4c29465b564..87f876be9d0 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/tst.ts +++ b/javascript/ql/test/library-tests/TypeScript/Types/tst.ts @@ -508,4 +508,13 @@ module TS55 { var str = obj[key].toUpperCase(); // Now okay, previously was error } } -} \ No newline at end of file +} + +namespace TS57{ + declare const a: symbol; + export class A { + [a]() { return 1 }; + } + + declare const e1: A[typeof a]; // Now okay, previously was compilation error TS2538: Type 'symbol' cannot be used as an index type. +} From 37712d2e219b70ac7edb19b4b1718e5fdf1d93ed Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 13 Nov 2024 08:58:54 +0100 Subject: [PATCH 028/470] Added a new way to simulate CatastrophicError for integration-tests. In the future environmental variable, might be a more sustainable solution. --- .../internal-error/src/my_failure.ts | 3039 ++++++++++++++++- 1 file changed, 3022 insertions(+), 17 deletions(-) diff --git a/javascript/ql/integration-tests/diagnostics/internal-error/src/my_failure.ts b/javascript/ql/integration-tests/diagnostics/internal-error/src/my_failure.ts index 29e78b136e8..f2a1644e18f 100644 --- a/javascript/ql/integration-tests/diagnostics/internal-error/src/my_failure.ts +++ b/javascript/ql/integration-tests/diagnostics/internal-error/src/my_failure.ts @@ -1,17 +1,3022 @@ -type Output = { - (...args: S): any; -}; - -declare function createThing( - type: K, - fn: (...args: S) => any -): Output; - -const one = createThing("one", () => ({})); - -const two = createThing("two", () => ({})); - -const three = createThing("three", (cursor: string) => null); -const four = createThing("four", (error: number) => null); - -type Events = Array; +console.log( + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 +); From c86bbbb063d030f8b97ff1eca768c69528fa8fc6 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 14 Nov 2024 11:48:17 +0100 Subject: [PATCH 029/470] C++: Fix `cpp/guarded-free` FPs when there are other blocks depending on the guard --- cpp/ql/src/experimental/Best Practices/GuardedFree.ql | 3 ++- .../Best Practices/GuardedFree/GuardedFree.expected | 5 ----- .../query-tests/Best Practices/GuardedFree/test.cpp | 4 ++-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql index 2d504d9bc05..f47af783ac9 100644 --- a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql @@ -22,5 +22,6 @@ from GuardCondition gc, FreeCall fc, Variable v, BasicBlock bb where gc.ensuresEq(v.getAnAccess(), 0, bb, false) and fc.getArgument(0) = v.getAnAccess() and - bb = fc.getEnclosingStmt() + bb = fc.getEnclosingStmt() and + strictcount(BasicBlock bb2 | gc.ensuresEq(_, 0, bb2, _) | bb2) = 1 select gc, "unnecessary NULL check before call to $@", fc, "free" diff --git a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected index 209bae407b8..f86ab67b08d 100644 --- a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected +++ b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected @@ -1,10 +1,5 @@ | test.cpp:5:7:5:7 | x | unnecessary NULL check before call to $@ | test.cpp:6:5:6:8 | call to free | free | -| test.cpp:23:7:23:7 | x | unnecessary NULL check before call to $@ | test.cpp:26:5:26:8 | call to free | free | -| test.cpp:31:7:31:8 | ! ... | unnecessary NULL check before call to $@ | test.cpp:35:3:35:6 | call to free | free | | test.cpp:31:7:31:24 | ... \|\| ... | unnecessary NULL check before call to $@ | test.cpp:35:3:35:6 | call to free | free | -| test.cpp:31:8:31:8 | x | unnecessary NULL check before call to $@ | test.cpp:35:3:35:6 | call to free | free | | test.cpp:94:12:94:12 | x | unnecessary NULL check before call to $@ | test.cpp:94:3:94:13 | call to free | free | -| test.cpp:98:7:98:8 | ! ... | unnecessary NULL check before call to $@ | test.cpp:101:3:101:6 | call to free | free | -| test.cpp:98:8:98:8 | x | unnecessary NULL check before call to $@ | test.cpp:101:3:101:6 | call to free | free | | test.cpp:106:7:106:18 | ... != ... | unnecessary NULL check before call to $@ | test.cpp:107:5:107:8 | call to free | free | | test.cpp:113:7:113:18 | ... != ... | unnecessary NULL check before call to $@ | test.cpp:114:17:114:20 | call to free | free | diff --git a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp index 12b1fb2364e..da73ba2ca29 100644 --- a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp @@ -20,7 +20,7 @@ void test2(int *x) { } void test3(int *x, bool b) { - if (x) { // GOOD [FALSE POSITIVE]: x is being accessed in the body of the if + if (x) { // GOOD: x is being accessed in the body of the if if (b) *x = 42; free(x); @@ -95,7 +95,7 @@ void test11(char *x) { } bool test12(char *x) { - if (!x) // GOOD [FALSE POSITIVE]: return value depends on x + if (!x) // GOOD: return value depends on x return false; free(x); From a31e983e9e548888bd6bb3187c71bc499bcd4ff2 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 14 Nov 2024 12:47:29 +0100 Subject: [PATCH 030/470] C++: Also allow single statement blocks in `cpp/guarded-free` --- cpp/ql/src/experimental/Best Practices/GuardedFree.ql | 7 ++++++- .../Best Practices/GuardedFree/GuardedFree.expected | 5 +++++ .../query-tests/Best Practices/GuardedFree/test.cpp | 4 ++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql index f47af783ac9..664352c929b 100644 --- a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql @@ -22,6 +22,11 @@ from GuardCondition gc, FreeCall fc, Variable v, BasicBlock bb where gc.ensuresEq(v.getAnAccess(), 0, bb, false) and fc.getArgument(0) = v.getAnAccess() and - bb = fc.getEnclosingStmt() and + bb = fc.getBasicBlock() and + ( + bb = fc.getEnclosingStmt() + or + strictcount(bb.(BlockStmt).getAStmt()) = 1 + ) and strictcount(BasicBlock bb2 | gc.ensuresEq(_, 0, bb2, _) | bb2) = 1 select gc, "unnecessary NULL check before call to $@", fc, "free" diff --git a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected index f86ab67b08d..d69551bbbc2 100644 --- a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected +++ b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected @@ -1,5 +1,10 @@ | test.cpp:5:7:5:7 | x | unnecessary NULL check before call to $@ | test.cpp:6:5:6:8 | call to free | free | +| test.cpp:10:7:10:7 | x | unnecessary NULL check before call to $@ | test.cpp:11:5:11:8 | call to free | free | | test.cpp:31:7:31:24 | ... \|\| ... | unnecessary NULL check before call to $@ | test.cpp:35:3:35:6 | call to free | free | +| test.cpp:42:7:42:7 | x | unnecessary NULL check before call to $@ | test.cpp:43:5:43:8 | call to free | free | +| test.cpp:49:7:49:7 | x | unnecessary NULL check before call to $@ | test.cpp:50:5:50:8 | call to free | free | +| test.cpp:75:7:75:7 | x | unnecessary NULL check before call to $@ | test.cpp:76:5:76:14 | call to free | free | +| test.cpp:81:7:81:7 | x | unnecessary NULL check before call to $@ | test.cpp:85:5:85:8 | call to free | free | | test.cpp:94:12:94:12 | x | unnecessary NULL check before call to $@ | test.cpp:94:3:94:13 | call to free | free | | test.cpp:106:7:106:18 | ... != ... | unnecessary NULL check before call to $@ | test.cpp:107:5:107:8 | call to free | free | | test.cpp:113:7:113:18 | ... != ... | unnecessary NULL check before call to $@ | test.cpp:114:17:114:20 | call to free | free | diff --git a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp index da73ba2ca29..3f9f458867a 100644 --- a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp @@ -72,13 +72,13 @@ bool test8(char *x) { #endif void test9(char *x) { - if (x) { // GOOD: macro may make free behave unexpectedly when compiled differently + if (x) { // GOOD [FALSE POSITIVE]: macro may make free behave unexpectedly when compiled differently my_free(x); } } void test10(char *x) { - if (x) { // GOOD: #ifdef may make free behave unexpectedly when compiled differently + if (x) { // GOOD [FALSE POSITIVE]: #ifdef may make free behave unexpectedly when compiled differently #ifdef FOO free(x - 1); #else From 176acabd9dbfeef4ea9c3fe8261e77abfd9da8fd Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 14 Nov 2024 12:51:04 +0100 Subject: [PATCH 031/470] C++: Ignore `free` calls that are macro defined or `#if`/`#ifdef` guarded --- .../src/experimental/Best Practices/GuardedFree.ql | 14 +++++++++++++- .../GuardedFree/GuardedFree.expected | 3 --- .../Best Practices/GuardedFree/test.cpp | 6 +++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql index 664352c929b..747181cd32f 100644 --- a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql @@ -18,6 +18,17 @@ class FreeCall extends FunctionCall { FreeCall() { this.getTarget().hasGlobalName("free") } } +predicate isAffectedByMacro(FreeCall fc, BasicBlock bb) { + fc.isInMacroExpansion() + or + exists(PreprocessorBranch ppb, Location bbLoc, Location ppbLoc | + bbLoc = bb.(Stmt).getLocation() and ppbLoc = ppb.getLocation() + | + bbLoc.getStartLine() < ppbLoc.getStartLine() and + ppbLoc.getEndLine() < bbLoc.getEndLine() + ) +} + from GuardCondition gc, FreeCall fc, Variable v, BasicBlock bb where gc.ensuresEq(v.getAnAccess(), 0, bb, false) and @@ -28,5 +39,6 @@ where or strictcount(bb.(BlockStmt).getAStmt()) = 1 ) and - strictcount(BasicBlock bb2 | gc.ensuresEq(_, 0, bb2, _) | bb2) = 1 + strictcount(BasicBlock bb2 | gc.ensuresEq(_, 0, bb2, _) | bb2) = 1 and + not isAffectedByMacro(fc, bb) select gc, "unnecessary NULL check before call to $@", fc, "free" diff --git a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected index d69551bbbc2..3a6fdfe5403 100644 --- a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected +++ b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected @@ -3,8 +3,5 @@ | test.cpp:31:7:31:24 | ... \|\| ... | unnecessary NULL check before call to $@ | test.cpp:35:3:35:6 | call to free | free | | test.cpp:42:7:42:7 | x | unnecessary NULL check before call to $@ | test.cpp:43:5:43:8 | call to free | free | | test.cpp:49:7:49:7 | x | unnecessary NULL check before call to $@ | test.cpp:50:5:50:8 | call to free | free | -| test.cpp:75:7:75:7 | x | unnecessary NULL check before call to $@ | test.cpp:76:5:76:14 | call to free | free | -| test.cpp:81:7:81:7 | x | unnecessary NULL check before call to $@ | test.cpp:85:5:85:8 | call to free | free | -| test.cpp:94:12:94:12 | x | unnecessary NULL check before call to $@ | test.cpp:94:3:94:13 | call to free | free | | test.cpp:106:7:106:18 | ... != ... | unnecessary NULL check before call to $@ | test.cpp:107:5:107:8 | call to free | free | | test.cpp:113:7:113:18 | ... != ... | unnecessary NULL check before call to $@ | test.cpp:114:17:114:20 | call to free | free | diff --git a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp index 3f9f458867a..ee7b8c03150 100644 --- a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp @@ -72,13 +72,13 @@ bool test8(char *x) { #endif void test9(char *x) { - if (x) { // GOOD [FALSE POSITIVE]: macro may make free behave unexpectedly when compiled differently + if (x) { // GOOD: macro may make free behave unexpectedly when compiled differently my_free(x); } } void test10(char *x) { - if (x) { // GOOD [FALSE POSITIVE]: #ifdef may make free behave unexpectedly when compiled differently + if (x) { // GOOD: #ifdef may make free behave unexpectedly when compiled differently #ifdef FOO free(x - 1); #else @@ -91,7 +91,7 @@ void test10(char *x) { if (x) free(x); void test11(char *x) { - TRY_FREE(x) // BAD + TRY_FREE(x) // BAD [NOT DETECTED] } bool test12(char *x) { From b581723a63e29cac3a39da01f069556c7f6e8a80 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 14 Nov 2024 12:53:54 +0100 Subject: [PATCH 032/470] C++: Ignore complex guards and the comma operator --- cpp/ql/src/experimental/Best Practices/GuardedFree.ql | 4 +++- .../Best Practices/GuardedFree/GuardedFree.expected | 2 -- .../query-tests/Best Practices/GuardedFree/test.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql index 747181cd32f..94bec38af9f 100644 --- a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql @@ -40,5 +40,7 @@ where strictcount(bb.(BlockStmt).getAStmt()) = 1 ) and strictcount(BasicBlock bb2 | gc.ensuresEq(_, 0, bb2, _) | bb2) = 1 and - not isAffectedByMacro(fc, bb) + not isAffectedByMacro(fc, bb) and + not (gc instanceof BinaryOperation and not gc instanceof ComparisonOperation) and + not exists(CommaExpr c | c.getAChild*() = fc) select gc, "unnecessary NULL check before call to $@", fc, "free" diff --git a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected index 3a6fdfe5403..a9a189218c6 100644 --- a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected +++ b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected @@ -1,7 +1,5 @@ | test.cpp:5:7:5:7 | x | unnecessary NULL check before call to $@ | test.cpp:6:5:6:8 | call to free | free | | test.cpp:10:7:10:7 | x | unnecessary NULL check before call to $@ | test.cpp:11:5:11:8 | call to free | free | -| test.cpp:31:7:31:24 | ... \|\| ... | unnecessary NULL check before call to $@ | test.cpp:35:3:35:6 | call to free | free | | test.cpp:42:7:42:7 | x | unnecessary NULL check before call to $@ | test.cpp:43:5:43:8 | call to free | free | | test.cpp:49:7:49:7 | x | unnecessary NULL check before call to $@ | test.cpp:50:5:50:8 | call to free | free | | test.cpp:106:7:106:18 | ... != ... | unnecessary NULL check before call to $@ | test.cpp:107:5:107:8 | call to free | free | -| test.cpp:113:7:113:18 | ... != ... | unnecessary NULL check before call to $@ | test.cpp:114:17:114:20 | call to free | free | diff --git a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp index ee7b8c03150..d52bcef72d1 100644 --- a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp @@ -28,7 +28,7 @@ void test3(int *x, bool b) { } bool test4(char *x, char *y) { - if (!x || strcmp(x, y)) { // GOOD [FALSE POSITIVE]: x is being accessed in the guard and return value depends on x + if (!x || strcmp(x, y)) { // GOOD: x is being accessed in the guard and return value depends on x free(x); return true; } @@ -110,6 +110,6 @@ void test13(char *x) { void inspect(char *x); void test14(char *x) { - if (x != nullptr) // GOOD [FALSE POSITIVE]: x might be accessed in the first operand of the comma operator + if (x != nullptr) // GOOD: x might be accessed in the first operand of the comma operator inspect(x), free(x); } From 20685918bdbf54a16b403fa5c0842c5ee4bf8109 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 14 Nov 2024 13:10:20 +0100 Subject: [PATCH 033/470] C++: Silence ql-for-ql warning --- cpp/ql/src/experimental/Best Practices/GuardedFree.ql | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql index 94bec38af9f..94b179ac5eb 100644 --- a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql @@ -18,9 +18,7 @@ class FreeCall extends FunctionCall { FreeCall() { this.getTarget().hasGlobalName("free") } } -predicate isAffectedByMacro(FreeCall fc, BasicBlock bb) { - fc.isInMacroExpansion() - or +predicate blockContainsPreprocessorBranches(BasicBlock bb) { exists(PreprocessorBranch ppb, Location bbLoc, Location ppbLoc | bbLoc = bb.(Stmt).getLocation() and ppbLoc = ppb.getLocation() | @@ -40,7 +38,8 @@ where strictcount(bb.(BlockStmt).getAStmt()) = 1 ) and strictcount(BasicBlock bb2 | gc.ensuresEq(_, 0, bb2, _) | bb2) = 1 and - not isAffectedByMacro(fc, bb) and + not fc.isInMacroExpansion() and + not blockContainsPreprocessorBranches(bb) and not (gc instanceof BinaryOperation and not gc instanceof ComparisonOperation) and not exists(CommaExpr c | c.getAChild*() = fc) select gc, "unnecessary NULL check before call to $@", fc, "free" From 15953bf5698856d6be06217db7f770a8df851bda Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 14 Nov 2024 23:49:52 +0100 Subject: [PATCH 034/470] java: inline range test --- .../dataflow/range-analysis-inline/B.java | 90 +++++++++++++++++++ .../range-analysis-inline/range.expected | 0 .../dataflow/range-analysis-inline/range.ql | 37 ++++++++ 3 files changed, 127 insertions(+) create mode 100644 java/ql/test/library-tests/dataflow/range-analysis-inline/B.java create mode 100644 java/ql/test/library-tests/dataflow/range-analysis-inline/range.expected create mode 100644 java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql diff --git a/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java b/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java new file mode 100644 index 00000000000..f3ff1855811 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java @@ -0,0 +1,90 @@ +public class B { + public int forloop() { + int result = 0; + for (int i = 0; i < 10; i++) {// $ bound="i in [0..10]" bound="i in [0..9]" + result = i; // $ bound="i in [0..9]" + } + return result; // $ bound="result in [0..9]" + } + + public int forloopexit() { + int result = 0; + for (; result < 10;) { // $ bound="result in [0..10]" + result += 1; // $ bound="result in [0..9]" + } + return result; // $ bound="result = 10" + } + + public int forloopexitstep() { + int result = 0; + for (; result < 10;) { // $ bound="result in [0..12]" + result += 3; // $ bound="result in [0..9]" + } + return result; // $ bound="result = 12" + } + + public int forloopexitupd() { + int result = 0; + for (; result < 10; result++) { // $ bound="result in [0..9]" bound="result in [0..10]" + } + return result; // $ bound="result = 10" + } + + public int forloopexitnested() { + int result = 0; + for (; result < 10;) { + int i = 0; + for (; i < 3;) { // $ bound="i in [0..3]" + i += 1; // $ bound="i in [0..2]" + } + result += i; // $ bound="result in [0..9]" bound="i = 3" + } + return result; // $ MISSING:bound="result = 12" + } + + public int emptyforloop() { + int result = 0; + for (int i = 0; i < 0; i++) { // $ bound="i = 0" bound="i in [0..-1]" + result = i; // $ bound="i in [0..-1]" + } + return result; // $ bound="result = 0" + } + + public int noloop() { + int result = 0; + result += 1; // $ bound="result = 0" + return result; // $ bound="result = 1" + } + + public int foreachloop() { + int result = 0; + for (int i : new int[] {1, 2, 3, 4, 5}) { + result = i; + } + return result; + } + + public int emptyforeachloop() { + int result = 0; + for (int i : new int[] {}) { + result = i; + } + return result; + } + + public int whileloop() { + int result = 100; + while (result > 5) { // $ bound="result in [4..100]" + result = result - 2; // $ bound="result in [6..100]" + } + return result; // $ bound="result = 4" + } + + public int oddwhileloop() { + int result = 101; + while (result > 5) { // $ bound="result in [5..101]" + result = result - 2; // $ bound="result in [7..101]" + } + return result; // $ bound="result = 5" + } +} \ No newline at end of file diff --git a/java/ql/test/library-tests/dataflow/range-analysis-inline/range.expected b/java/ql/test/library-tests/dataflow/range-analysis-inline/range.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql b/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql new file mode 100644 index 00000000000..dcfbfbf54c6 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql @@ -0,0 +1,37 @@ +/** + * Inline range analysis tests for Java. + * See `shared/util/codeql/dataflow/test/InlineFlowTest.qll` + */ + +import java +import semmle.code.java.dataflow.RangeAnalysis +private import codeql.util.test.InlineExpectationsTest +private import TestUtilities.internal.InlineExpectationsTestImpl +private import Make as IET + +module RangeTest implements IET::TestSig { + string getARelevantTag() { result = "bound" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "bound" and + exists(Expr e, int lower, int upper | + constrained(e, lower, upper) and + e instanceof VarRead and + e.getCompilationUnit().fromSource() + | + location = e.getLocation() and + element = e.toString() and + if lower = upper + then value = "\"" + e.toString() + " = " + lower.toString() + "\"" + else + value = "\"" + e.toString() + " in [" + lower.toString() + ".." + upper.toString() + "]\"" + ) + } + + private predicate constrained(Expr e, int lower, int upper) { + lower = min(int delta | bounded(e, any(ZeroBound z), delta, false, _)) and + upper = min(int delta | bounded(e, any(ZeroBound z), delta, true, _)) + } +} + +import IET::MakeTest From ea90698fc1d98acfd093677d4ba522fe7407f909 Mon Sep 17 00:00:00 2001 From: Napalys Date: Fri, 15 Nov 2024 13:35:28 +0100 Subject: [PATCH 035/470] JS: Add: Test case taint step for findLast --- javascript/ql/test/library-tests/Arrays/arrays.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/javascript/ql/test/library-tests/Arrays/arrays.js b/javascript/ql/test/library-tests/Arrays/arrays.js index 579741fa3aa..7b57f810330 100644 --- a/javascript/ql/test/library-tests/Arrays/arrays.js +++ b/javascript/ql/test/library-tests/Arrays/arrays.js @@ -107,4 +107,6 @@ var arr8_spread = []; arr8_spread = arr8_spread.toSpliced(0, 0, ...arr); sink(arr8_spread.pop()); // NOT OK + + sink(arr.findLast(someCallback)); // NOT OK -- Should be flagged by the taint tracking rule, but it is not. }); From fcb65534a85cb87b448d93a2b6457f78fe8316ff Mon Sep 17 00:00:00 2001 From: Napalys Date: Fri, 15 Nov 2024 14:09:44 +0100 Subject: [PATCH 036/470] JS: Add: Array.protype.findLast as taint step --- .../ql/lib/semmle/javascript/Arrays.qll | 9 +- .../library-tests/Arrays/DataFlow.expected | 1 + .../library-tests/Arrays/TaintFlow.expected | 1 + .../ql/test/library-tests/Arrays/arrays.js | 2 +- .../library-tests/Arrays/printAst.expected | 284 ++++++++++-------- 5 files changed, 166 insertions(+), 131 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/Arrays.qll b/javascript/ql/lib/semmle/javascript/Arrays.qll index 7ce37130996..f36f8af4c17 100644 --- a/javascript/ql/lib/semmle/javascript/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/Arrays.qll @@ -384,13 +384,16 @@ private module ArrayLibraries { } /** - * Gets a call to `Array.prototype.find` or a polyfill implementing the same functionality. + * Gets a call to `Array.prototype.find` or `Array.prototype.findLast` or a polyfill implementing the same functionality. */ DataFlow::CallNode arrayFindCall(DataFlow::Node array) { - result.(DataFlow::MethodCallNode).getMethodName() = "find" and + result.(DataFlow::MethodCallNode).getMethodName() in ["find", "findLast"] and array = result.getReceiver() or - result = DataFlow::moduleImport(["array.prototype.find", "array-find"]).getACall() and + result = + DataFlow::moduleImport([ + "array.prototype.find", "array-find", "array.prototype.findLast", "array-find-last" + ]).getACall() and array = result.getArgument(0) } diff --git a/javascript/ql/test/library-tests/Arrays/DataFlow.expected b/javascript/ql/test/library-tests/Arrays/DataFlow.expected index 4332f14c45e..38a9316bfaa 100644 --- a/javascript/ql/test/library-tests/Arrays/DataFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/DataFlow.expected @@ -14,6 +14,7 @@ | arrays.js:2:16:2:23 | "source" | arrays.js:90:10:90:10 | x | | arrays.js:2:16:2:23 | "source" | arrays.js:93:8:93:17 | arr.at(-1) | | arrays.js:2:16:2:23 | "source" | arrays.js:109:8:109:24 | arr8_spread.pop() | +| arrays.js:2:16:2:23 | "source" | arrays.js:111:8:111:33 | arr.fin ... llback) | | arrays.js:18:22:18:29 | "source" | arrays.js:18:50:18:50 | e | | arrays.js:22:15:22:22 | "source" | arrays.js:23:8:23:17 | arr2.pop() | | arrays.js:25:15:25:22 | "source" | arrays.js:26:8:26:17 | arr3.pop() | diff --git a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected index a531715bfb6..53fbe4cf0c5 100644 --- a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected @@ -15,6 +15,7 @@ | arrays.js:2:16:2:23 | "source" | arrays.js:90:10:90:10 | x | | arrays.js:2:16:2:23 | "source" | arrays.js:93:8:93:17 | arr.at(-1) | | arrays.js:2:16:2:23 | "source" | arrays.js:109:8:109:24 | arr8_spread.pop() | +| arrays.js:2:16:2:23 | "source" | arrays.js:111:8:111:33 | arr.fin ... llback) | | arrays.js:18:22:18:29 | "source" | arrays.js:18:50:18:50 | e | | arrays.js:22:15:22:22 | "source" | arrays.js:23:8:23:17 | arr2.pop() | | arrays.js:25:15:25:22 | "source" | arrays.js:26:8:26:17 | arr3.pop() | diff --git a/javascript/ql/test/library-tests/Arrays/arrays.js b/javascript/ql/test/library-tests/Arrays/arrays.js index 7b57f810330..3ae7c635019 100644 --- a/javascript/ql/test/library-tests/Arrays/arrays.js +++ b/javascript/ql/test/library-tests/Arrays/arrays.js @@ -108,5 +108,5 @@ arr8_spread = arr8_spread.toSpliced(0, 0, ...arr); sink(arr8_spread.pop()); // NOT OK - sink(arr.findLast(someCallback)); // NOT OK -- Should be flagged by the taint tracking rule, but it is not. + sink(arr.findLast(someCallback)); // NOT OK }); diff --git a/javascript/ql/test/library-tests/Arrays/printAst.expected b/javascript/ql/test/library-tests/Arrays/printAst.expected index a7333b29485..c00f46d8dad 100644 --- a/javascript/ql/test/library-tests/Arrays/printAst.expected +++ b/javascript/ql/test/library-tests/Arrays/printAst.expected @@ -1,9 +1,9 @@ nodes -| arrays.js:1:1:110:2 | [ParExpr] (functi ... T OK }) | semmle.label | [ParExpr] (functi ... T OK }) | -| arrays.js:1:1:110:3 | [ExprStmt] (functi ... OK }); | semmle.label | [ExprStmt] (functi ... OK }); | -| arrays.js:1:1:110:3 | [ExprStmt] (functi ... OK }); | semmle.order | 1 | -| arrays.js:1:2:110:1 | [FunctionExpr] functio ... OT OK } | semmle.label | [FunctionExpr] functio ... OT OK } | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | semmle.label | [BlockStmt] { let ... OT OK } | +| arrays.js:1:1:112:2 | [ParExpr] (functi ... T OK }) | semmle.label | [ParExpr] (functi ... T OK }) | +| arrays.js:1:1:112:3 | [ExprStmt] (functi ... OK }); | semmle.label | [ExprStmt] (functi ... OK }); | +| arrays.js:1:1:112:3 | [ExprStmt] (functi ... OK }); | semmle.order | 1 | +| arrays.js:1:2:112:1 | [FunctionExpr] functio ... OT OK } | semmle.label | [FunctionExpr] functio ... OT OK } | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | semmle.label | [BlockStmt] { let ... OT OK } | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | [DeclStmt] let source = ... | | arrays.js:2:7:2:12 | [VarDecl] source | semmle.label | [VarDecl] source | | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.label | [VariableDeclarator] source = "source" | @@ -487,6 +487,16 @@ nodes | arrays.js:109:8:109:22 | [DotExpr] arr8_spread.pop | semmle.label | [DotExpr] arr8_spread.pop | | arrays.js:109:8:109:24 | [MethodCallExpr] arr8_spread.pop() | semmle.label | [MethodCallExpr] arr8_spread.pop() | | arrays.js:109:20:109:22 | [Label] pop | semmle.label | [Label] pop | +| arrays.js:111:3:111:6 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:111:3:111:34 | [CallExpr] sink(ar ... lback)) | semmle.label | [CallExpr] sink(ar ... lback)) | +| arrays.js:111:3:111:35 | [ExprStmt] sink(ar ... back)); | semmle.label | [ExprStmt] sink(ar ... back)); | +| arrays.js:111:8:111:10 | [VarRef] arr | semmle.label | [VarRef] arr | +| arrays.js:111:8:111:19 | [DotExpr] arr.findLast | semmle.label | [DotExpr] arr.findLast | +| arrays.js:111:8:111:33 | [MethodCallExpr] arr.fin ... llback) | semmle.label | [MethodCallExpr] arr.fin ... llback) | +| arrays.js:111:12:111:19 | [Label] findLast | semmle.label | [Label] findLast | +| arrays.js:111:21:111:32 | [VarRef] someCallback | semmle.label | [VarRef] someCallback | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | @@ -552,128 +562,130 @@ nodes | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | edges -| arrays.js:1:1:110:2 | [ParExpr] (functi ... T OK }) | arrays.js:1:2:110:1 | [FunctionExpr] functio ... OT OK } | semmle.label | 1 | -| arrays.js:1:1:110:2 | [ParExpr] (functi ... T OK }) | arrays.js:1:2:110:1 | [FunctionExpr] functio ... OT OK } | semmle.order | 1 | -| arrays.js:1:1:110:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:110:2 | [ParExpr] (functi ... T OK }) | semmle.label | 1 | -| arrays.js:1:1:110:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:110:2 | [ParExpr] (functi ... T OK }) | semmle.order | 1 | -| arrays.js:1:2:110:1 | [FunctionExpr] functio ... OT OK } | arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | semmle.label | 5 | -| arrays.js:1:2:110:1 | [FunctionExpr] functio ... OT OK } | arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | semmle.order | 5 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | 1 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.order | 1 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.label | 2 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.order | 2 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.label | 3 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.order | 3 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.label | 4 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.order | 4 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.label | 5 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.order | 5 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.label | 6 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.order | 6 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.label | 7 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.order | 7 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.label | 8 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.order | 8 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.label | 9 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.order | 9 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.label | 10 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.order | 10 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.label | 11 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.order | 11 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.label | 12 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.order | 12 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.label | 13 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.order | 13 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.label | 14 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.order | 14 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.label | 15 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.order | 15 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.label | 16 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.order | 16 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.label | 17 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.order | 17 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.label | 18 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.order | 18 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.label | 19 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.order | 19 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.label | 20 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.order | 20 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 21 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 21 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.label | 22 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.order | 22 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.label | 23 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.order | 23 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 24 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 24 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.label | 25 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.order | 25 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.label | 26 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.order | 26 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.label | 27 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.order | 27 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.label | 28 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.order | 28 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.label | 29 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.order | 29 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.label | 30 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.order | 30 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.label | 31 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.order | 31 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.label | 32 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.order | 32 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.label | 33 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.order | 33 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.label | 34 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.order | 34 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.label | 35 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.order | 35 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.label | 36 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.order | 36 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.label | 37 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.order | 37 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.label | 38 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.order | 38 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.label | 39 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.order | 39 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.label | 40 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.order | 40 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.label | 41 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.order | 41 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.label | 42 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.order | 42 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.label | 43 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.order | 43 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.label | 44 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.order | 44 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.label | 45 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.order | 45 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.label | 46 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.order | 46 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.label | 47 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.order | 47 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.label | 48 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.order | 48 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.label | 49 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.order | 49 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.label | 50 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.order | 50 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.label | 51 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.order | 51 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.label | 52 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.order | 52 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.label | 53 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.order | 53 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.label | 54 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.order | 54 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 55 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 55 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.label | 56 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.order | 56 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.label | 57 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.order | 57 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 58 | -| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 58 | +| arrays.js:1:1:112:2 | [ParExpr] (functi ... T OK }) | arrays.js:1:2:112:1 | [FunctionExpr] functio ... OT OK } | semmle.label | 1 | +| arrays.js:1:1:112:2 | [ParExpr] (functi ... T OK }) | arrays.js:1:2:112:1 | [FunctionExpr] functio ... OT OK } | semmle.order | 1 | +| arrays.js:1:1:112:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:112:2 | [ParExpr] (functi ... T OK }) | semmle.label | 1 | +| arrays.js:1:1:112:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:112:2 | [ParExpr] (functi ... T OK }) | semmle.order | 1 | +| arrays.js:1:2:112:1 | [FunctionExpr] functio ... OT OK } | arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | semmle.label | 5 | +| arrays.js:1:2:112:1 | [FunctionExpr] functio ... OT OK } | arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | semmle.order | 5 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | 1 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.order | 1 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.label | 2 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.order | 2 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.label | 3 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.order | 3 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.label | 4 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.order | 4 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.label | 5 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.order | 5 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.label | 6 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.order | 6 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.label | 7 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.order | 7 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.label | 8 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.order | 8 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.label | 9 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.order | 9 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.label | 10 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.order | 10 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.label | 11 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.order | 11 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.label | 12 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.order | 12 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.label | 13 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.order | 13 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.label | 14 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.order | 14 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.label | 15 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.order | 15 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.label | 16 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.order | 16 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.label | 17 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.order | 17 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.label | 18 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.order | 18 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.label | 19 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.order | 19 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.label | 20 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.order | 20 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 21 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 21 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.label | 22 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.order | 22 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.label | 23 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.order | 23 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 24 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 24 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.label | 25 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.order | 25 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.label | 26 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.order | 26 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.label | 27 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.order | 27 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.label | 28 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.order | 28 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.label | 29 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.order | 29 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.label | 30 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.order | 30 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.label | 31 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.order | 31 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.label | 32 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.order | 32 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.label | 33 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.order | 33 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.label | 34 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.order | 34 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.label | 35 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.order | 35 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.label | 36 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.order | 36 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.label | 37 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.order | 37 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.label | 38 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.order | 38 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.label | 39 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.order | 39 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.label | 40 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.order | 40 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.label | 41 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.order | 41 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.label | 42 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.order | 42 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.label | 43 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.order | 43 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.label | 44 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.order | 44 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.label | 45 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.order | 45 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.label | 46 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.order | 46 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.label | 47 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.order | 47 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.label | 48 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.order | 48 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.label | 49 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.order | 49 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.label | 50 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.order | 50 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.label | 51 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.order | 51 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.label | 52 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.order | 52 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.label | 53 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.order | 53 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.label | 54 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.order | 54 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 55 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 55 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.label | 56 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.order | 56 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.label | 57 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.order | 57 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 58 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 58 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:111:3:111:35 | [ExprStmt] sink(ar ... back)); | semmle.label | 59 | +| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:111:3:111:35 | [ExprStmt] sink(ar ... back)); | semmle.order | 59 | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.label | 1 | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.order | 1 | | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | arrays.js:2:7:2:12 | [VarDecl] source | semmle.label | 1 | @@ -1490,6 +1502,20 @@ edges | arrays.js:109:8:109:22 | [DotExpr] arr8_spread.pop | arrays.js:109:20:109:22 | [Label] pop | semmle.order | 2 | | arrays.js:109:8:109:24 | [MethodCallExpr] arr8_spread.pop() | arrays.js:109:8:109:22 | [DotExpr] arr8_spread.pop | semmle.label | 0 | | arrays.js:109:8:109:24 | [MethodCallExpr] arr8_spread.pop() | arrays.js:109:8:109:22 | [DotExpr] arr8_spread.pop | semmle.order | 0 | +| arrays.js:111:3:111:34 | [CallExpr] sink(ar ... lback)) | arrays.js:111:3:111:6 | [VarRef] sink | semmle.label | 0 | +| arrays.js:111:3:111:34 | [CallExpr] sink(ar ... lback)) | arrays.js:111:3:111:6 | [VarRef] sink | semmle.order | 0 | +| arrays.js:111:3:111:34 | [CallExpr] sink(ar ... lback)) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:111:3:111:34 | [CallExpr] sink(ar ... lback)) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:111:3:111:35 | [ExprStmt] sink(ar ... back)); | arrays.js:111:3:111:34 | [CallExpr] sink(ar ... lback)) | semmle.label | 1 | +| arrays.js:111:3:111:35 | [ExprStmt] sink(ar ... back)); | arrays.js:111:3:111:34 | [CallExpr] sink(ar ... lback)) | semmle.order | 1 | +| arrays.js:111:8:111:19 | [DotExpr] arr.findLast | arrays.js:111:8:111:10 | [VarRef] arr | semmle.label | 1 | +| arrays.js:111:8:111:19 | [DotExpr] arr.findLast | arrays.js:111:8:111:10 | [VarRef] arr | semmle.order | 1 | +| arrays.js:111:8:111:19 | [DotExpr] arr.findLast | arrays.js:111:12:111:19 | [Label] findLast | semmle.label | 2 | +| arrays.js:111:8:111:19 | [DotExpr] arr.findLast | arrays.js:111:12:111:19 | [Label] findLast | semmle.order | 2 | +| arrays.js:111:8:111:33 | [MethodCallExpr] arr.fin ... llback) | arrays.js:111:8:111:19 | [DotExpr] arr.findLast | semmle.label | 0 | +| arrays.js:111:8:111:33 | [MethodCallExpr] arr.fin ... llback) | arrays.js:111:8:111:19 | [DotExpr] arr.findLast | semmle.order | 0 | +| arrays.js:111:8:111:33 | [MethodCallExpr] arr.fin ... llback) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:111:8:111:33 | [MethodCallExpr] arr.fin ... llback) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | | file://:0:0:0:0 | (Arguments) | arrays.js:5:8:5:14 | [DotExpr] obj.foo | semmle.label | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:5:8:5:14 | [DotExpr] obj.foo | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:8:12:8:17 | [VarRef] source | semmle.label | 0 | @@ -1634,6 +1660,10 @@ edges | file://:0:0:0:0 | (Arguments) | arrays.js:108:45:108:50 | [SpreadElement] ...arr | semmle.order | 2 | | file://:0:0:0:0 | (Arguments) | arrays.js:109:8:109:24 | [MethodCallExpr] arr8_spread.pop() | semmle.label | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:109:8:109:24 | [MethodCallExpr] arr8_spread.pop() | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:111:8:111:33 | [MethodCallExpr] arr.fin ... llback) | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:111:8:111:33 | [MethodCallExpr] arr.fin ... llback) | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:111:21:111:32 | [VarRef] someCallback | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:111:21:111:32 | [VarRef] someCallback | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:15:16:15:16 | [SimpleParameter] e | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:15:16:15:16 | [SimpleParameter] e | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:16:12:16:12 | [SimpleParameter] e | semmle.label | 0 | From 7250099f6c20090acef04232277b095967f9e14f Mon Sep 17 00:00:00 2001 From: Napalys Date: Fri, 15 Nov 2024 14:42:11 +0100 Subject: [PATCH 037/470] JS: Add: Test cases use of returnless function in findLast and findLastIndex --- .../Statements/UseOfReturnlessFunction/tst.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js b/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js index dbedb3dee3c..2b2b28d4b05 100644 --- a/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js +++ b/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js @@ -107,3 +107,13 @@ class Bar extends Foo { console.log(super()); // OK. } } + +() => { + let equals = (x, y) => { return x === y; }; + + var foo = [1,2,3].findLastIndex(n => { equals(n, 3); }) // NOT OK -- Currently not flagged, but should be. + console.log(foo); + + var foo = [1,2,3].findLast(n => { equals(n, 3); }) // NOT OK -- Currently not flagged, but should be. + console.log(foo); +} From a28fc8e77270614140fc2a0086d52f9f168832f5 Mon Sep 17 00:00:00 2001 From: Napalys Date: Fri, 15 Nov 2024 14:44:25 +0100 Subject: [PATCH 038/470] JS: Add: Use of returnless function support for findLast and findLastIndex --- javascript/ql/src/Statements/UseOfReturnlessFunction.ql | 2 +- .../UseOfReturnlessFunction/UseOfReturnlessFunction.expected | 2 ++ .../query-tests/Statements/UseOfReturnlessFunction/tst.js | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/javascript/ql/src/Statements/UseOfReturnlessFunction.ql b/javascript/ql/src/Statements/UseOfReturnlessFunction.ql index ea5f2fb9755..818f0d922d4 100644 --- a/javascript/ql/src/Statements/UseOfReturnlessFunction.ql +++ b/javascript/ql/src/Statements/UseOfReturnlessFunction.ql @@ -114,7 +114,7 @@ predicate hasNonVoidCallbackMethod(string name) { name = [ "every", "filter", "find", "findIndex", "flatMap", "map", "reduce", "reduceRight", "some", - "sort" + "sort", "findLastIndex", "findLast" ] } diff --git a/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/UseOfReturnlessFunction.expected b/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/UseOfReturnlessFunction.expected index 1cbbd9faa5a..dec3eea044d 100644 --- a/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/UseOfReturnlessFunction.expected +++ b/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/UseOfReturnlessFunction.expected @@ -7,3 +7,5 @@ | tst.js:53:10:53:34 | bothOnl ... fects() | the $@ does not return anything, yet the return value is used. | tst.js:48:2:50:5 | functio ... )\\n } | function onlySideEffects2 | | tst.js:76:12:76:46 | [1,2,3] ... n, 3)}) | the $@ does not return anything, yet the return value from the call to filter is used. | tst.js:76:27:76:45 | n => {equals(n, 3)} | callback function | | tst.js:80:12:80:50 | filter( ... 3) } ) | the $@ does not return anything, yet the return value from the call to filter is used. | tst.js:80:28:80:48 | x => { ... x, 3) } | callback function | +| tst.js:114:12:114:56 | [1,2,3] ... 3); }) | the $@ does not return anything, yet the return value from the call to findLastIndex is used. | tst.js:114:34:114:55 | n => { ... , 3); } | callback function | +| tst.js:117:12:117:51 | [1,2,3] ... 3); }) | the $@ does not return anything, yet the return value from the call to findLast is used. | tst.js:117:29:117:50 | n => { ... , 3); } | callback function | diff --git a/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js b/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js index 2b2b28d4b05..7b9968115f5 100644 --- a/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js +++ b/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js @@ -111,9 +111,9 @@ class Bar extends Foo { () => { let equals = (x, y) => { return x === y; }; - var foo = [1,2,3].findLastIndex(n => { equals(n, 3); }) // NOT OK -- Currently not flagged, but should be. + var foo = [1,2,3].findLastIndex(n => { equals(n, 3); }) // NOT OK console.log(foo); - var foo = [1,2,3].findLast(n => { equals(n, 3); }) // NOT OK -- Currently not flagged, but should be. + var foo = [1,2,3].findLast(n => { equals(n, 3); }) // NOT OK console.log(foo); } From 3786ad4277c7b63a9901a0dd4ae211383dd48f12 Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 18 Nov 2024 12:44:49 +0100 Subject: [PATCH 039/470] JS: Add: test case for Map.groupBy --- javascript/ql/test/library-tests/TaintTracking/tst.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/javascript/ql/test/library-tests/TaintTracking/tst.js b/javascript/ql/test/library-tests/TaintTracking/tst.js index a5142e29685..6ea2e755df4 100644 --- a/javascript/ql/test/library-tests/TaintTracking/tst.js +++ b/javascript/ql/test/library-tests/TaintTracking/tst.js @@ -68,4 +68,7 @@ function test() { sink(x.toReversed()) // NOT OK const xReversed = x.toReversed(); sink(xReversed) // NOT OK + + sink(Map.groupBy(x, z => z)); // NOT OK -- This should be marked via taint step, but it is not. + sink(Custom.groupBy(x, z => z)); // OK } From c02ad65fdc27142b10d21b26915c9425422957ff Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 18 Nov 2024 12:50:06 +0100 Subject: [PATCH 040/470] JS: Add: taint step for Map.groupBy function --- javascript/ql/lib/semmle/javascript/Collections.qll | 13 +++++++++++++ .../TaintTracking/BasicTaintTracking.expected | 1 + .../ql/test/library-tests/TaintTracking/tst.js | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/Collections.qll b/javascript/ql/lib/semmle/javascript/Collections.qll index a0e251554ff..ff64a5568d1 100644 --- a/javascript/ql/lib/semmle/javascript/Collections.qll +++ b/javascript/ql/lib/semmle/javascript/Collections.qll @@ -151,4 +151,17 @@ private module CollectionDataFlow { ) } } + + /** + * A step for a call to `groupBy` on an iterable object. + */ + private class GroupByTaintStep extends TaintTracking::SharedTaintStep { + override predicate heapStep(DataFlow::Node pred, DataFlow::Node succ) { + exists(DataFlow::MethodCallNode call | + call = DataFlow::globalVarRef("Map").getAMemberCall("groupBy") and + pred = call.getArgument(0) and + succ = call + ) + } + } } diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 88465784205..248a35b907f 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -244,6 +244,7 @@ typeInferenceMismatch | tst.js:2:13:2:20 | source() | tst.js:66:10:66:16 | xSorted | | tst.js:2:13:2:20 | source() | tst.js:68:10:68:23 | x.toReversed() | | tst.js:2:13:2:20 | source() | tst.js:70:10:70:18 | xReversed | +| tst.js:2:13:2:20 | source() | tst.js:72:10:72:31 | Map.gro ... z => z) | | xml.js:5:18:5:25 | source() | xml.js:8:14:8:17 | text | | xml.js:12:17:12:24 | source() | xml.js:13:14:13:19 | result | | xml.js:23:18:23:25 | source() | xml.js:20:14:20:17 | attr | diff --git a/javascript/ql/test/library-tests/TaintTracking/tst.js b/javascript/ql/test/library-tests/TaintTracking/tst.js index 6ea2e755df4..c69895625ca 100644 --- a/javascript/ql/test/library-tests/TaintTracking/tst.js +++ b/javascript/ql/test/library-tests/TaintTracking/tst.js @@ -69,6 +69,6 @@ function test() { const xReversed = x.toReversed(); sink(xReversed) // NOT OK - sink(Map.groupBy(x, z => z)); // NOT OK -- This should be marked via taint step, but it is not. + sink(Map.groupBy(x, z => z)); // NOT OK sink(Custom.groupBy(x, z => z)); // OK } From 8ae05d8be474848cf325180e8507aac10ed63ee6 Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 18 Nov 2024 12:52:49 +0100 Subject: [PATCH 041/470] JS: Add: test case for Object.groupBy --- javascript/ql/test/library-tests/TaintTracking/tst.js | 1 + 1 file changed, 1 insertion(+) diff --git a/javascript/ql/test/library-tests/TaintTracking/tst.js b/javascript/ql/test/library-tests/TaintTracking/tst.js index c69895625ca..d268c02e687 100644 --- a/javascript/ql/test/library-tests/TaintTracking/tst.js +++ b/javascript/ql/test/library-tests/TaintTracking/tst.js @@ -71,4 +71,5 @@ function test() { sink(Map.groupBy(x, z => z)); // NOT OK sink(Custom.groupBy(x, z => z)); // OK + sink(Object.groupBy(x, z => z)); // NOT OK -- This should be marked via taint step, but it is not. } From 213ce225e0d3a3a426c20d91f48abfed94328f4b Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 18 Nov 2024 12:58:07 +0100 Subject: [PATCH 042/470] JS: Add: taint step for Object.groupBy function, fixed test cases from 8ae05d8be474848cf325180e8507aac10ed63ee6 --- javascript/ql/lib/semmle/javascript/Collections.qll | 2 +- .../library-tests/TaintTracking/BasicTaintTracking.expected | 1 + javascript/ql/test/library-tests/TaintTracking/tst.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/Collections.qll b/javascript/ql/lib/semmle/javascript/Collections.qll index ff64a5568d1..c7348e603f4 100644 --- a/javascript/ql/lib/semmle/javascript/Collections.qll +++ b/javascript/ql/lib/semmle/javascript/Collections.qll @@ -158,7 +158,7 @@ private module CollectionDataFlow { private class GroupByTaintStep extends TaintTracking::SharedTaintStep { override predicate heapStep(DataFlow::Node pred, DataFlow::Node succ) { exists(DataFlow::MethodCallNode call | - call = DataFlow::globalVarRef("Map").getAMemberCall("groupBy") and + call = DataFlow::globalVarRef(["Map", "Object"]).getAMemberCall("groupBy") and pred = call.getArgument(0) and succ = call ) diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 248a35b907f..79be56cbb7e 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -245,6 +245,7 @@ typeInferenceMismatch | tst.js:2:13:2:20 | source() | tst.js:68:10:68:23 | x.toReversed() | | tst.js:2:13:2:20 | source() | tst.js:70:10:70:18 | xReversed | | tst.js:2:13:2:20 | source() | tst.js:72:10:72:31 | Map.gro ... z => z) | +| tst.js:2:13:2:20 | source() | tst.js:74:10:74:34 | Object. ... z => z) | | xml.js:5:18:5:25 | source() | xml.js:8:14:8:17 | text | | xml.js:12:17:12:24 | source() | xml.js:13:14:13:19 | result | | xml.js:23:18:23:25 | source() | xml.js:20:14:20:17 | attr | diff --git a/javascript/ql/test/library-tests/TaintTracking/tst.js b/javascript/ql/test/library-tests/TaintTracking/tst.js index d268c02e687..0fab561954d 100644 --- a/javascript/ql/test/library-tests/TaintTracking/tst.js +++ b/javascript/ql/test/library-tests/TaintTracking/tst.js @@ -71,5 +71,5 @@ function test() { sink(Map.groupBy(x, z => z)); // NOT OK sink(Custom.groupBy(x, z => z)); // OK - sink(Object.groupBy(x, z => z)); // NOT OK -- This should be marked via taint step, but it is not. + sink(Object.groupBy(x, z => z)); // NOT OK } From 88be4b88ab61570fd984740270543166bc9934fd Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Mon, 18 Nov 2024 14:27:01 +0100 Subject: [PATCH 043/470] C++: Address review comments --- cpp/ql/src/experimental/Best Practices/GuardedFree.ql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql index 94b179ac5eb..66c7a31111b 100644 --- a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql @@ -22,6 +22,7 @@ predicate blockContainsPreprocessorBranches(BasicBlock bb) { exists(PreprocessorBranch ppb, Location bbLoc, Location ppbLoc | bbLoc = bb.(Stmt).getLocation() and ppbLoc = ppb.getLocation() | + bbLoc.getFile() = ppb.getFile() and bbLoc.getStartLine() < ppbLoc.getStartLine() and ppbLoc.getEndLine() < bbLoc.getEndLine() ) @@ -33,8 +34,10 @@ where fc.getArgument(0) = v.getAnAccess() and bb = fc.getBasicBlock() and ( + // No block statement: if (x) free(x); bb = fc.getEnclosingStmt() or + // Block statement with a single nested statement: if (x) { free(x); } strictcount(bb.(BlockStmt).getAStmt()) = 1 ) and strictcount(BasicBlock bb2 | gc.ensuresEq(_, 0, bb2, _) | bb2) = 1 and From de05aee483c204aa6da50fe6213c44c229748348 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Mon, 18 Nov 2024 11:11:25 -0500 Subject: [PATCH 044/470] Adding model transition to using Throwing.qll. --- .../raw/internal/TranslatedCall.qll | 4 +- .../cpp/models/implementations/Memcpy.qll | 4 +- .../cpp/models/implementations/Memset.qll | 4 +- .../implementations/NoexceptFunction.qll | 4 +- .../cpp/models/implementations/Printf.qll | 12 +++- .../cpp/models/implementations/Strcat.qll | 4 +- .../cpp/models/implementations/Strcpy.qll | 4 +- .../StructuredExceptionHandling.qll | 23 ++++++- .../cpp/models/interfaces/NonThrowing.qll | 11 --- .../code/cpp/models/interfaces/Throwing.qll | 69 +++++++++++++++++-- 10 files changed, 112 insertions(+), 27 deletions(-) delete mode 100644 cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index daa6bdaafcf..a4c67886959 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -363,11 +363,11 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { } final override predicate mayThrowException() { - expr.getTarget().(ThrowingFunction).mayThrowException(_) + expr.getTarget().(ThrowingFunction).mayRaiseException() } final override predicate mustThrowException() { - expr.getTarget().(ThrowingFunction).mayThrowException(true) + expr.getTarget().(ThrowingFunction).alwaysRaisesException() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll index 0bf2dd31fe4..8c3ae368da9 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll @@ -9,7 +9,7 @@ import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect import semmle.code.cpp.models.interfaces.Taint -import semmle.code.cpp.models.interfaces.NonThrowing +import semmle.code.cpp.models.interfaces.Throwing /** * The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant @@ -106,6 +106,8 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect not this.hasGlobalName(["bcopy", mempcpy(), "memccpy"]) and index = this.getParamDest() } + + override TCxxException getExceptionType() { any() } } private string mempcpy() { result = ["mempcpy", "wmempcpy"] } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll index ab2e0af99f3..6a4ab8a133f 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll @@ -8,7 +8,7 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.NonThrowing +import semmle.code.cpp.models.interfaces.Throwing private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, AliasFunction, SideEffectFunction, NonThrowingFunction @@ -74,6 +74,8 @@ private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, Alias i = 0 and if this.hasGlobalName(bzero()) then result = 1 else result = 2 } + + override TCxxException getExceptionType() { any() } } private string bzero() { result = ["bzero", "explicit_bzero"] } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll index b0f76ee6538..ee05b2a68a0 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll @@ -1,4 +1,4 @@ -import semmle.code.cpp.models.interfaces.NonThrowing +import semmle.code.cpp.models.interfaces.Throwing /** * A function that is annotated with a `noexcept` specifier (or the equivalent @@ -8,4 +8,6 @@ import semmle.code.cpp.models.interfaces.NonThrowing */ class NoexceptFunction extends NonThrowingFunction { NoexceptFunction() { this.isNoExcept() or this.isNoThrow() } + + override TCxxException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll index 9c3bfb4f35e..7dbd38126bf 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll @@ -8,7 +8,7 @@ import semmle.code.cpp.models.interfaces.FormattingFunction import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.NonThrowing +import semmle.code.cpp.models.interfaces.Throwing /** * The standard functions `printf`, `wprintf` and their glib variants. @@ -32,6 +32,8 @@ private class Printf extends FormattingFunction, AliasFunction, NonThrowingFunct override predicate parameterEscapesOnlyViaReturn(int n) { none() } override predicate parameterIsAlwaysReturned(int n) { none() } + + override TCxxException getExceptionType() { any() } } /** @@ -50,6 +52,8 @@ private class Fprintf extends FormattingFunction, NonThrowingFunction { override int getFormatParameterIndex() { result = 1 } override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = true } + + override TCxxException getExceptionType() { any() } } /** @@ -93,6 +97,8 @@ private class Sprintf extends FormattingFunction, NonThrowingFunction { then result = 4 else result = super.getFirstFormatArgumentIndex() } + + override TCxxException getExceptionType() { any() } } /** @@ -165,6 +171,8 @@ private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, // We don't know how many parameters are passed to the function since it's varargs, but they also have read side effects. i = this.getFormatParameterIndex() and buffer = true } + + override TCxxException getExceptionType() { any() } } /** @@ -215,4 +223,6 @@ private class Syslog extends FormattingFunction, NonThrowingFunction { override int getFormatParameterIndex() { result = 1 } override predicate isOutputGlobal() { any() } + + override TCxxException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll index 9b11ed0af15..df85c56148a 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll @@ -7,7 +7,7 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.NonThrowing +import semmle.code.cpp.models.interfaces.Throwing /** * The standard function `strcat` and its wide, sized, and Microsoft variants. @@ -94,6 +94,8 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid (i = 0 or i = 1) and buffer = true } + + override TCxxException getExceptionType() { any() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll index b7f06f0cebf..b09cbeb8dc6 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll @@ -7,7 +7,7 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.NonThrowing +import semmle.code.cpp.models.interfaces.Throwing /** * The standard function `strcpy` and its wide, sized, and Microsoft variants. @@ -145,4 +145,6 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid i = this.getParamDest() and result = this.getParamSize() } + + override TCxxException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll index af8f3088f25..d5941488d0d 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll @@ -1,9 +1,26 @@ import semmle.code.cpp.models.interfaces.Throwing -class WindowsDriverFunction extends ThrowingFunction { - WindowsDriverFunction() { +/** + * The default behavior for Structured Exception Handling (SEH) is + * any function may (conditionally) raise an exception. + * NOTE: this can be overridden by for any specific function to make in + * unconditional or non-throwing. IR generation will enforce + * the most strict interpretation. + */ +class DefaultSehExceptionBehavior extends ThrowingFunction { + DefaultSehExceptionBehavior() { any() } + + override predicate raisesException(boolean unconditional) { unconditional = false } + + override TSehException getExceptionType() { any() } +} + +class WindowsDriverExceptionAnnotation extends ThrowingFunction { + WindowsDriverExceptionAnnotation() { this.hasGlobalName(["RaiseException", "ExRaiseAccessViolation", "ExRaiseDatatypeMisalignment"]) } - final override predicate mayThrowException(boolean unconditional) { unconditional = true } + override predicate raisesException(boolean unconditional) { unconditional = true } + + override TSehException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll deleted file mode 100644 index 64901d39ad3..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Provides an abstract class for modeling functions that never throw. - */ - -import semmle.code.cpp.Function -import semmle.code.cpp.models.Models - -/** - * A function that is guaranteed to never throw. - */ -abstract class NonThrowingFunction extends Function { } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll index 79b7523f1d9..72db8c9e96c 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll @@ -11,12 +11,71 @@ import semmle.code.cpp.models.Models import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs /** - * A class that models the exceptional behavior of a function. + * Represents a type of exception, + * either Structured Exception Handling (SEH) or C++ exceptions. */ -abstract class ThrowingFunction extends Function { +newtype TException = + /** Structured Exception Handling (SEH) exception */ + TSehException() or + /** C++ exception */ + TCxxException() + +/** + * Functions with information about how an exception is thrown or if one is thrown at all. + * If throwing details conflict for the same function, IR is assumed + * to use the most restricted interpretation, meaning taking options + * that stipulate no exception is raised, before the exception is always raised, + * before conditional exceptions. + * + * Annotations must specify if the exception is from SEH (structured exception handling) + * or ordinary c++ exceptions. + */ +abstract private class ExceptionAnnotation extends Function { /** - * Holds if this function may throw an exception during evaluation. - * If `unconditional` is `true` the function always throws an exception. + * Returns the type of exception this annotation is for, + * either a CPP exception or a STructured Exception Handling (SEH) exception. */ - abstract predicate mayThrowException(boolean unconditional); + abstract TException getExceptionType(); + + /** + * Holds if the exception type of this annotation is for a Structured Exception Handling (SEH) exception. + */ + final predicate isSeh() { this.getExceptionType() = TSehException() } + + /** + * Holds if the exception type of this annotation is for a CPP exception. + */ + final predicate isCxx() { this.getExceptionType() = TCxxException() } +} + +/** + * A Function that is known to not throw an exception. + */ +abstract class NonThrowingFunction extends ExceptionAnnotation { } + +/** + * A function this is known to raise an exception. + */ +abstract class ThrowingFunction extends ExceptionAnnotation { + ThrowingFunction() { any() } + + /** + * Holds if this function may raise an exception during evaluation. + * If `unconditional` is `false` the function may raise, and if `true` the function + * will always raise an exception. + * Do not specify `none()` if no exception is raised, instead use the + * `NonThrowingFunction` class instead. + */ + abstract predicate raisesException(boolean unconditional); + + /** + * Holds if this function will always raise an exception if called + */ + final predicate alwaysRaisesException() { this.raisesException(true) } + + /** + * Holds if this function may raise an exception if called but + * it is not guaranteed to do so. I.e., the function does not always raise an exception. + */ + final predicate mayRaiseException() { this.raisesException(false) } } From 4b83a451bd0547bba0d6bd41750d4739fd7dd5e0 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Mon, 18 Nov 2024 11:14:46 -0500 Subject: [PATCH 045/470] Change log --- cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md diff --git a/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md b/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md new file mode 100644 index 00000000000..f3c33f40b51 --- /dev/null +++ b/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Removed NonThrowing.qll. Throwing meta-data now part of Throwing.qll. Updated models and IR to use the new Throwing library and predicates. \ No newline at end of file From 792231c949154be6b003d86204df40478e23e600 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Mon, 18 Nov 2024 14:43:44 -0500 Subject: [PATCH 046/470] Removing SEH default case for function calls as the logic to handle SEH is not yet part of the IR generation to make this logic work. --- .../StructuredExceptionHandling.qll | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll index d5941488d0d..485dc7137b8 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll @@ -1,20 +1,5 @@ import semmle.code.cpp.models.interfaces.Throwing -/** - * The default behavior for Structured Exception Handling (SEH) is - * any function may (conditionally) raise an exception. - * NOTE: this can be overridden by for any specific function to make in - * unconditional or non-throwing. IR generation will enforce - * the most strict interpretation. - */ -class DefaultSehExceptionBehavior extends ThrowingFunction { - DefaultSehExceptionBehavior() { any() } - - override predicate raisesException(boolean unconditional) { unconditional = false } - - override TSehException getExceptionType() { any() } -} - class WindowsDriverExceptionAnnotation extends ThrowingFunction { WindowsDriverExceptionAnnotation() { this.hasGlobalName(["RaiseException", "ExRaiseAccessViolation", "ExRaiseDatatypeMisalignment"]) From 72a69cfa17e863c5a612ac5024a90913e4f18b63 Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 18 Nov 2024 14:51:23 +0100 Subject: [PATCH 047/470] Added change notes --- .../ql/lib/change-notes/2024-11-18-ES2022-find-functions.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md diff --git a/javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md b/javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md new file mode 100644 index 00000000000..93b7e286cf4 --- /dev/null +++ b/javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added pre call graph step for `Array.prototype.findLast` From 1b0f8aa65767fdd823c6b6a18697cf7d745508fc Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 19 Nov 2024 08:26:03 +0100 Subject: [PATCH 048/470] JS: removed unnecessary findlast module import --- .../ql/lib/change-notes/2024-11-18-ES2022-find-functions.md | 3 ++- javascript/ql/lib/semmle/javascript/Arrays.qll | 5 +---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md b/javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md index 93b7e286cf4..e3fe3b6aef2 100644 --- a/javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md +++ b/javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md @@ -1,4 +1,5 @@ --- category: minorAnalysis --- -* Added pre call graph step for `Array.prototype.findLast` +* Added taint-steps for `Array.prototype.findLast` +* Added taint-steps for `Array.prototype.findLastIndex` diff --git a/javascript/ql/lib/semmle/javascript/Arrays.qll b/javascript/ql/lib/semmle/javascript/Arrays.qll index f36f8af4c17..5cb7d231586 100644 --- a/javascript/ql/lib/semmle/javascript/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/Arrays.qll @@ -390,10 +390,7 @@ private module ArrayLibraries { result.(DataFlow::MethodCallNode).getMethodName() in ["find", "findLast"] and array = result.getReceiver() or - result = - DataFlow::moduleImport([ - "array.prototype.find", "array-find", "array.prototype.findLast", "array-find-last" - ]).getACall() and + result = DataFlow::moduleImport(["array.prototype.find", "array-find"]).getACall() and array = result.getArgument(0) } From b64b837db371291070959b0b271ca72845eaf5bd Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 19 Nov 2024 09:35:43 +0100 Subject: [PATCH 049/470] JS: Add: test cases for find, findLast, findLastIndex with callbacks --- .../library-tests/Arrays/DataFlow.expected | 2 + .../library-tests/Arrays/TaintFlow.expected | 2 + .../ql/test/library-tests/Arrays/arrays.js | 18 + .../library-tests/Arrays/printAst.expected | 492 +++++++++++++----- 4 files changed, 385 insertions(+), 129 deletions(-) diff --git a/javascript/ql/test/library-tests/Arrays/DataFlow.expected b/javascript/ql/test/library-tests/Arrays/DataFlow.expected index 38a9316bfaa..91742699b61 100644 --- a/javascript/ql/test/library-tests/Arrays/DataFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/DataFlow.expected @@ -26,3 +26,5 @@ | arrays.js:53:4:53:11 | "source" | arrays.js:54:10:54:18 | ary.pop() | | arrays.js:99:31:99:38 | "source" | arrays.js:100:8:100:17 | arr8.pop() | | arrays.js:103:55:103:62 | "source" | arrays.js:105:8:105:25 | arr8_variant.pop() | +| arrays.js:114:19:114:26 | "source" | arrays.js:116:10:116:16 | element | +| arrays.js:120:19:120:26 | "source" | arrays.js:122:10:122:16 | element | diff --git a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected index 53fbe4cf0c5..cb3b16479a7 100644 --- a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected @@ -30,3 +30,5 @@ | arrays.js:96:9:96:16 | "source" | arrays.js:96:8:96:36 | ["sourc ... => !!x) | | arrays.js:99:31:99:38 | "source" | arrays.js:100:8:100:17 | arr8.pop() | | arrays.js:103:55:103:62 | "source" | arrays.js:105:8:105:25 | arr8_variant.pop() | +| arrays.js:114:19:114:26 | "source" | arrays.js:116:10:116:16 | element | +| arrays.js:120:19:120:26 | "source" | arrays.js:122:10:122:16 | element | diff --git a/javascript/ql/test/library-tests/Arrays/arrays.js b/javascript/ql/test/library-tests/Arrays/arrays.js index 3ae7c635019..e4124ec16d8 100644 --- a/javascript/ql/test/library-tests/Arrays/arrays.js +++ b/javascript/ql/test/library-tests/Arrays/arrays.js @@ -109,4 +109,22 @@ sink(arr8_spread.pop()); // NOT OK sink(arr.findLast(someCallback)); // NOT OK + + { // Test for findLast function + const list = ["source"]; + const element = list.findLast((item) => sink(item)); // NOT OK -- Not caught, currently missing dataflow tracking. + sink(element); // NOT OK + } + + { // Test for find function + const list = ["source"]; + const element = list.find((item) => sink(item)); // NOT OK -- Not caught, currently missing dataflow tracking. + sink(element); // NOT OK + } + + { // Test for findLastIndex function + const list = ["source"]; + const element = list.findLastIndex((item) => sink(item)); // NOT OK -- Not caught, currently missing dataflow tracking. + sink(element); // OK + } }); diff --git a/javascript/ql/test/library-tests/Arrays/printAst.expected b/javascript/ql/test/library-tests/Arrays/printAst.expected index c00f46d8dad..6a23be2dee6 100644 --- a/javascript/ql/test/library-tests/Arrays/printAst.expected +++ b/javascript/ql/test/library-tests/Arrays/printAst.expected @@ -1,9 +1,9 @@ nodes -| arrays.js:1:1:112:2 | [ParExpr] (functi ... T OK }) | semmle.label | [ParExpr] (functi ... T OK }) | -| arrays.js:1:1:112:3 | [ExprStmt] (functi ... OK }); | semmle.label | [ExprStmt] (functi ... OK }); | -| arrays.js:1:1:112:3 | [ExprStmt] (functi ... OK }); | semmle.order | 1 | -| arrays.js:1:2:112:1 | [FunctionExpr] functio ... OT OK } | semmle.label | [FunctionExpr] functio ... OT OK } | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | semmle.label | [BlockStmt] { let ... OT OK } | +| arrays.js:1:1:130:2 | [ParExpr] (functi ... } }) | semmle.label | [ParExpr] (functi ... } }) | +| arrays.js:1:1:130:3 | [ExprStmt] (functi ... } }); | semmle.label | [ExprStmt] (functi ... } }); | +| arrays.js:1:1:130:3 | [ExprStmt] (functi ... } }); | semmle.order | 1 | +| arrays.js:1:2:130:1 | [FunctionExpr] functio ... K } } | semmle.label | [FunctionExpr] functio ... K } } | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | semmle.label | [BlockStmt] { let ... K } } | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | [DeclStmt] let source = ... | | arrays.js:2:7:2:12 | [VarDecl] source | semmle.label | [VarDecl] source | | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.label | [VariableDeclarator] source = "source" | @@ -495,6 +495,72 @@ nodes | arrays.js:111:8:111:33 | [MethodCallExpr] arr.fin ... llback) | semmle.label | [MethodCallExpr] arr.fin ... llback) | | arrays.js:111:12:111:19 | [Label] findLast | semmle.label | [Label] findLast | | arrays.js:111:21:111:32 | [VarRef] someCallback | semmle.label | [VarRef] someCallback | +| arrays.js:113:3:117:3 | [BlockStmt] { // T ... OK } | semmle.label | [BlockStmt] { // T ... OK } | +| arrays.js:114:5:114:28 | [DeclStmt] const list = ... | semmle.label | [DeclStmt] const list = ... | +| arrays.js:114:11:114:14 | [VarDecl] list | semmle.label | [VarDecl] list | +| arrays.js:114:11:114:27 | [VariableDeclarator] list = ["source"] | semmle.label | [VariableDeclarator] list = ["source"] | +| arrays.js:114:18:114:27 | [ArrayExpr] ["source"] | semmle.label | [ArrayExpr] ["source"] | +| arrays.js:114:19:114:26 | [Literal] "source" | semmle.label | [Literal] "source" | +| arrays.js:115:5:115:56 | [DeclStmt] const element = ... | semmle.label | [DeclStmt] const element = ... | +| arrays.js:115:11:115:17 | [VarDecl] element | semmle.label | [VarDecl] element | +| arrays.js:115:11:115:55 | [VariableDeclarator] element ... (item)) | semmle.label | [VariableDeclarator] element ... (item)) | +| arrays.js:115:21:115:24 | [VarRef] list | semmle.label | [VarRef] list | +| arrays.js:115:21:115:33 | [DotExpr] list.findLast | semmle.label | [DotExpr] list.findLast | +| arrays.js:115:21:115:55 | [MethodCallExpr] list.fi ... (item)) | semmle.label | [MethodCallExpr] list.fi ... (item)) | +| arrays.js:115:26:115:33 | [Label] findLast | semmle.label | [Label] findLast | +| arrays.js:115:35:115:54 | [ArrowFunctionExpr] (item) => sink(item) | semmle.label | [ArrowFunctionExpr] (item) => sink(item) | +| arrays.js:115:36:115:39 | [SimpleParameter] item | semmle.label | [SimpleParameter] item | +| arrays.js:115:45:115:48 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:115:45:115:54 | [CallExpr] sink(item) | semmle.label | [CallExpr] sink(item) | +| arrays.js:115:50:115:53 | [VarRef] item | semmle.label | [VarRef] item | +| arrays.js:116:5:116:8 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:116:5:116:17 | [CallExpr] sink(element) | semmle.label | [CallExpr] sink(element) | +| arrays.js:116:5:116:18 | [ExprStmt] sink(element); | semmle.label | [ExprStmt] sink(element); | +| arrays.js:116:10:116:16 | [VarRef] element | semmle.label | [VarRef] element | +| arrays.js:119:3:123:3 | [BlockStmt] { // T ... OK } | semmle.label | [BlockStmt] { // T ... OK } | +| arrays.js:120:5:120:28 | [DeclStmt] const list = ... | semmle.label | [DeclStmt] const list = ... | +| arrays.js:120:11:120:14 | [VarDecl] list | semmle.label | [VarDecl] list | +| arrays.js:120:11:120:27 | [VariableDeclarator] list = ["source"] | semmle.label | [VariableDeclarator] list = ["source"] | +| arrays.js:120:18:120:27 | [ArrayExpr] ["source"] | semmle.label | [ArrayExpr] ["source"] | +| arrays.js:120:19:120:26 | [Literal] "source" | semmle.label | [Literal] "source" | +| arrays.js:121:5:121:52 | [DeclStmt] const element = ... | semmle.label | [DeclStmt] const element = ... | +| arrays.js:121:11:121:17 | [VarDecl] element | semmle.label | [VarDecl] element | +| arrays.js:121:11:121:51 | [VariableDeclarator] element ... (item)) | semmle.label | [VariableDeclarator] element ... (item)) | +| arrays.js:121:21:121:24 | [VarRef] list | semmle.label | [VarRef] list | +| arrays.js:121:21:121:29 | [DotExpr] list.find | semmle.label | [DotExpr] list.find | +| arrays.js:121:21:121:51 | [MethodCallExpr] list.fi ... (item)) | semmle.label | [MethodCallExpr] list.fi ... (item)) | +| arrays.js:121:26:121:29 | [Label] find | semmle.label | [Label] find | +| arrays.js:121:31:121:50 | [ArrowFunctionExpr] (item) => sink(item) | semmle.label | [ArrowFunctionExpr] (item) => sink(item) | +| arrays.js:121:32:121:35 | [SimpleParameter] item | semmle.label | [SimpleParameter] item | +| arrays.js:121:41:121:44 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:121:41:121:50 | [CallExpr] sink(item) | semmle.label | [CallExpr] sink(item) | +| arrays.js:121:46:121:49 | [VarRef] item | semmle.label | [VarRef] item | +| arrays.js:122:5:122:8 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:122:5:122:17 | [CallExpr] sink(element) | semmle.label | [CallExpr] sink(element) | +| arrays.js:122:5:122:18 | [ExprStmt] sink(element); | semmle.label | [ExprStmt] sink(element); | +| arrays.js:122:10:122:16 | [VarRef] element | semmle.label | [VarRef] element | +| arrays.js:125:3:129:3 | [BlockStmt] { // T ... OK } | semmle.label | [BlockStmt] { // T ... OK } | +| arrays.js:126:5:126:28 | [DeclStmt] const list = ... | semmle.label | [DeclStmt] const list = ... | +| arrays.js:126:11:126:14 | [VarDecl] list | semmle.label | [VarDecl] list | +| arrays.js:126:11:126:27 | [VariableDeclarator] list = ["source"] | semmle.label | [VariableDeclarator] list = ["source"] | +| arrays.js:126:18:126:27 | [ArrayExpr] ["source"] | semmle.label | [ArrayExpr] ["source"] | +| arrays.js:126:19:126:26 | [Literal] "source" | semmle.label | [Literal] "source" | +| arrays.js:127:5:127:61 | [DeclStmt] const element = ... | semmle.label | [DeclStmt] const element = ... | +| arrays.js:127:11:127:17 | [VarDecl] element | semmle.label | [VarDecl] element | +| arrays.js:127:11:127:60 | [VariableDeclarator] element ... (item)) | semmle.label | [VariableDeclarator] element ... (item)) | +| arrays.js:127:21:127:24 | [VarRef] list | semmle.label | [VarRef] list | +| arrays.js:127:21:127:38 | [DotExpr] list.findLastIndex | semmle.label | [DotExpr] list.findLastIndex | +| arrays.js:127:21:127:60 | [MethodCallExpr] list.fi ... (item)) | semmle.label | [MethodCallExpr] list.fi ... (item)) | +| arrays.js:127:26:127:38 | [Label] findLastIndex | semmle.label | [Label] findLastIndex | +| arrays.js:127:40:127:59 | [ArrowFunctionExpr] (item) => sink(item) | semmle.label | [ArrowFunctionExpr] (item) => sink(item) | +| arrays.js:127:41:127:44 | [SimpleParameter] item | semmle.label | [SimpleParameter] item | +| arrays.js:127:50:127:53 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:127:50:127:59 | [CallExpr] sink(item) | semmle.label | [CallExpr] sink(item) | +| arrays.js:127:55:127:58 | [VarRef] item | semmle.label | [VarRef] item | +| arrays.js:128:5:128:8 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:128:5:128:17 | [CallExpr] sink(element) | semmle.label | [CallExpr] sink(element) | +| arrays.js:128:5:128:18 | [ExprStmt] sink(element); | semmle.label | [ExprStmt] sink(element); | +| arrays.js:128:10:128:16 | [VarRef] element | semmle.label | [VarRef] element | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | @@ -554,6 +620,18 @@ nodes | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | @@ -562,130 +640,136 @@ nodes | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | edges -| arrays.js:1:1:112:2 | [ParExpr] (functi ... T OK }) | arrays.js:1:2:112:1 | [FunctionExpr] functio ... OT OK } | semmle.label | 1 | -| arrays.js:1:1:112:2 | [ParExpr] (functi ... T OK }) | arrays.js:1:2:112:1 | [FunctionExpr] functio ... OT OK } | semmle.order | 1 | -| arrays.js:1:1:112:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:112:2 | [ParExpr] (functi ... T OK }) | semmle.label | 1 | -| arrays.js:1:1:112:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:112:2 | [ParExpr] (functi ... T OK }) | semmle.order | 1 | -| arrays.js:1:2:112:1 | [FunctionExpr] functio ... OT OK } | arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | semmle.label | 5 | -| arrays.js:1:2:112:1 | [FunctionExpr] functio ... OT OK } | arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | semmle.order | 5 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | 1 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.order | 1 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.label | 2 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.order | 2 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.label | 3 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.order | 3 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.label | 4 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.order | 4 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.label | 5 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.order | 5 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.label | 6 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.order | 6 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.label | 7 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.order | 7 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.label | 8 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.order | 8 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.label | 9 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.order | 9 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.label | 10 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.order | 10 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.label | 11 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.order | 11 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.label | 12 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.order | 12 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.label | 13 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.order | 13 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.label | 14 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.order | 14 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.label | 15 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.order | 15 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.label | 16 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.order | 16 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.label | 17 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.order | 17 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.label | 18 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.order | 18 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.label | 19 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.order | 19 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.label | 20 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.order | 20 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 21 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 21 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.label | 22 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.order | 22 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.label | 23 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.order | 23 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 24 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 24 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.label | 25 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.order | 25 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.label | 26 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.order | 26 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.label | 27 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.order | 27 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.label | 28 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.order | 28 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.label | 29 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.order | 29 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.label | 30 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.order | 30 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.label | 31 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.order | 31 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.label | 32 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.order | 32 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.label | 33 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.order | 33 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.label | 34 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.order | 34 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.label | 35 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.order | 35 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.label | 36 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.order | 36 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.label | 37 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.order | 37 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.label | 38 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.order | 38 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.label | 39 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.order | 39 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.label | 40 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.order | 40 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.label | 41 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.order | 41 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.label | 42 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.order | 42 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.label | 43 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.order | 43 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.label | 44 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.order | 44 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.label | 45 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.order | 45 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.label | 46 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.order | 46 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.label | 47 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.order | 47 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.label | 48 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.order | 48 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.label | 49 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.order | 49 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.label | 50 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.order | 50 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.label | 51 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.order | 51 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.label | 52 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.order | 52 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.label | 53 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.order | 53 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.label | 54 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.order | 54 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 55 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 55 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.label | 56 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.order | 56 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.label | 57 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.order | 57 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 58 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 58 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:111:3:111:35 | [ExprStmt] sink(ar ... back)); | semmle.label | 59 | -| arrays.js:1:14:112:1 | [BlockStmt] { let ... OT OK } | arrays.js:111:3:111:35 | [ExprStmt] sink(ar ... back)); | semmle.order | 59 | +| arrays.js:1:1:130:2 | [ParExpr] (functi ... } }) | arrays.js:1:2:130:1 | [FunctionExpr] functio ... K } } | semmle.label | 1 | +| arrays.js:1:1:130:2 | [ParExpr] (functi ... } }) | arrays.js:1:2:130:1 | [FunctionExpr] functio ... K } } | semmle.order | 1 | +| arrays.js:1:1:130:3 | [ExprStmt] (functi ... } }); | arrays.js:1:1:130:2 | [ParExpr] (functi ... } }) | semmle.label | 1 | +| arrays.js:1:1:130:3 | [ExprStmt] (functi ... } }); | arrays.js:1:1:130:2 | [ParExpr] (functi ... } }) | semmle.order | 1 | +| arrays.js:1:2:130:1 | [FunctionExpr] functio ... K } } | arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | semmle.label | 5 | +| arrays.js:1:2:130:1 | [FunctionExpr] functio ... K } } | arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | semmle.order | 5 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | 1 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.order | 1 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.label | 2 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.order | 2 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.label | 3 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.order | 3 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.label | 4 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.order | 4 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.label | 5 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.order | 5 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.label | 6 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.order | 6 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.label | 7 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.order | 7 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.label | 8 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.order | 8 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.label | 9 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.order | 9 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.label | 10 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.order | 10 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.label | 11 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.order | 11 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.label | 12 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.order | 12 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.label | 13 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.order | 13 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.label | 14 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.order | 14 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.label | 15 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.order | 15 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.label | 16 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.order | 16 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.label | 17 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.order | 17 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.label | 18 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.order | 18 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.label | 19 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.order | 19 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.label | 20 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.order | 20 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 21 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 21 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.label | 22 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.order | 22 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.label | 23 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.order | 23 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 24 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 24 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.label | 25 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.order | 25 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.label | 26 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.order | 26 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.label | 27 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.order | 27 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.label | 28 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.order | 28 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.label | 29 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.order | 29 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.label | 30 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.order | 30 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.label | 31 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.order | 31 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.label | 32 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.order | 32 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.label | 33 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.order | 33 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.label | 34 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.order | 34 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.label | 35 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.order | 35 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.label | 36 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.order | 36 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.label | 37 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.order | 37 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.label | 38 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.order | 38 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.label | 39 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.order | 39 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.label | 40 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.order | 40 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.label | 41 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.order | 41 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.label | 42 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.order | 42 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.label | 43 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.order | 43 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.label | 44 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.order | 44 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.label | 45 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.order | 45 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.label | 46 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.order | 46 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.label | 47 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.order | 47 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.label | 48 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.order | 48 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.label | 49 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.order | 49 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.label | 50 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.order | 50 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.label | 51 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.order | 51 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.label | 52 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.order | 52 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.label | 53 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.order | 53 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.label | 54 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.order | 54 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 55 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 55 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.label | 56 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.order | 56 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.label | 57 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.order | 57 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 58 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 58 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:111:3:111:35 | [ExprStmt] sink(ar ... back)); | semmle.label | 59 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:111:3:111:35 | [ExprStmt] sink(ar ... back)); | semmle.order | 59 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:113:3:117:3 | [BlockStmt] { // T ... OK } | semmle.label | 60 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:113:3:117:3 | [BlockStmt] { // T ... OK } | semmle.order | 60 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:119:3:123:3 | [BlockStmt] { // T ... OK } | semmle.label | 61 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:119:3:123:3 | [BlockStmt] { // T ... OK } | semmle.order | 61 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:125:3:129:3 | [BlockStmt] { // T ... OK } | semmle.label | 62 | +| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:125:3:129:3 | [BlockStmt] { // T ... OK } | semmle.order | 62 | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.label | 1 | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.order | 1 | | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | arrays.js:2:7:2:12 | [VarDecl] source | semmle.label | 1 | @@ -1516,6 +1600,132 @@ edges | arrays.js:111:8:111:33 | [MethodCallExpr] arr.fin ... llback) | arrays.js:111:8:111:19 | [DotExpr] arr.findLast | semmle.order | 0 | | arrays.js:111:8:111:33 | [MethodCallExpr] arr.fin ... llback) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | | arrays.js:111:8:111:33 | [MethodCallExpr] arr.fin ... llback) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:113:3:117:3 | [BlockStmt] { // T ... OK } | arrays.js:114:5:114:28 | [DeclStmt] const list = ... | semmle.label | 1 | +| arrays.js:113:3:117:3 | [BlockStmt] { // T ... OK } | arrays.js:114:5:114:28 | [DeclStmt] const list = ... | semmle.order | 1 | +| arrays.js:113:3:117:3 | [BlockStmt] { // T ... OK } | arrays.js:115:5:115:56 | [DeclStmt] const element = ... | semmle.label | 2 | +| arrays.js:113:3:117:3 | [BlockStmt] { // T ... OK } | arrays.js:115:5:115:56 | [DeclStmt] const element = ... | semmle.order | 2 | +| arrays.js:113:3:117:3 | [BlockStmt] { // T ... OK } | arrays.js:116:5:116:18 | [ExprStmt] sink(element); | semmle.label | 3 | +| arrays.js:113:3:117:3 | [BlockStmt] { // T ... OK } | arrays.js:116:5:116:18 | [ExprStmt] sink(element); | semmle.order | 3 | +| arrays.js:114:5:114:28 | [DeclStmt] const list = ... | arrays.js:114:11:114:27 | [VariableDeclarator] list = ["source"] | semmle.label | 1 | +| arrays.js:114:5:114:28 | [DeclStmt] const list = ... | arrays.js:114:11:114:27 | [VariableDeclarator] list = ["source"] | semmle.order | 1 | +| arrays.js:114:11:114:27 | [VariableDeclarator] list = ["source"] | arrays.js:114:11:114:14 | [VarDecl] list | semmle.label | 1 | +| arrays.js:114:11:114:27 | [VariableDeclarator] list = ["source"] | arrays.js:114:11:114:14 | [VarDecl] list | semmle.order | 1 | +| arrays.js:114:11:114:27 | [VariableDeclarator] list = ["source"] | arrays.js:114:18:114:27 | [ArrayExpr] ["source"] | semmle.label | 2 | +| arrays.js:114:11:114:27 | [VariableDeclarator] list = ["source"] | arrays.js:114:18:114:27 | [ArrayExpr] ["source"] | semmle.order | 2 | +| arrays.js:114:18:114:27 | [ArrayExpr] ["source"] | arrays.js:114:19:114:26 | [Literal] "source" | semmle.label | 1 | +| arrays.js:114:18:114:27 | [ArrayExpr] ["source"] | arrays.js:114:19:114:26 | [Literal] "source" | semmle.order | 1 | +| arrays.js:115:5:115:56 | [DeclStmt] const element = ... | arrays.js:115:11:115:55 | [VariableDeclarator] element ... (item)) | semmle.label | 1 | +| arrays.js:115:5:115:56 | [DeclStmt] const element = ... | arrays.js:115:11:115:55 | [VariableDeclarator] element ... (item)) | semmle.order | 1 | +| arrays.js:115:11:115:55 | [VariableDeclarator] element ... (item)) | arrays.js:115:11:115:17 | [VarDecl] element | semmle.label | 1 | +| arrays.js:115:11:115:55 | [VariableDeclarator] element ... (item)) | arrays.js:115:11:115:17 | [VarDecl] element | semmle.order | 1 | +| arrays.js:115:11:115:55 | [VariableDeclarator] element ... (item)) | arrays.js:115:21:115:55 | [MethodCallExpr] list.fi ... (item)) | semmle.label | 2 | +| arrays.js:115:11:115:55 | [VariableDeclarator] element ... (item)) | arrays.js:115:21:115:55 | [MethodCallExpr] list.fi ... (item)) | semmle.order | 2 | +| arrays.js:115:21:115:33 | [DotExpr] list.findLast | arrays.js:115:21:115:24 | [VarRef] list | semmle.label | 1 | +| arrays.js:115:21:115:33 | [DotExpr] list.findLast | arrays.js:115:21:115:24 | [VarRef] list | semmle.order | 1 | +| arrays.js:115:21:115:33 | [DotExpr] list.findLast | arrays.js:115:26:115:33 | [Label] findLast | semmle.label | 2 | +| arrays.js:115:21:115:33 | [DotExpr] list.findLast | arrays.js:115:26:115:33 | [Label] findLast | semmle.order | 2 | +| arrays.js:115:21:115:55 | [MethodCallExpr] list.fi ... (item)) | arrays.js:115:21:115:33 | [DotExpr] list.findLast | semmle.label | 0 | +| arrays.js:115:21:115:55 | [MethodCallExpr] list.fi ... (item)) | arrays.js:115:21:115:33 | [DotExpr] list.findLast | semmle.order | 0 | +| arrays.js:115:21:115:55 | [MethodCallExpr] list.fi ... (item)) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:115:21:115:55 | [MethodCallExpr] list.fi ... (item)) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:115:35:115:54 | [ArrowFunctionExpr] (item) => sink(item) | arrays.js:115:45:115:54 | [CallExpr] sink(item) | semmle.label | 5 | +| arrays.js:115:35:115:54 | [ArrowFunctionExpr] (item) => sink(item) | arrays.js:115:45:115:54 | [CallExpr] sink(item) | semmle.order | 5 | +| arrays.js:115:35:115:54 | [ArrowFunctionExpr] (item) => sink(item) | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| arrays.js:115:35:115:54 | [ArrowFunctionExpr] (item) => sink(item) | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| arrays.js:115:45:115:54 | [CallExpr] sink(item) | arrays.js:115:45:115:48 | [VarRef] sink | semmle.label | 0 | +| arrays.js:115:45:115:54 | [CallExpr] sink(item) | arrays.js:115:45:115:48 | [VarRef] sink | semmle.order | 0 | +| arrays.js:115:45:115:54 | [CallExpr] sink(item) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:115:45:115:54 | [CallExpr] sink(item) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:116:5:116:17 | [CallExpr] sink(element) | arrays.js:116:5:116:8 | [VarRef] sink | semmle.label | 0 | +| arrays.js:116:5:116:17 | [CallExpr] sink(element) | arrays.js:116:5:116:8 | [VarRef] sink | semmle.order | 0 | +| arrays.js:116:5:116:17 | [CallExpr] sink(element) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:116:5:116:17 | [CallExpr] sink(element) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:116:5:116:18 | [ExprStmt] sink(element); | arrays.js:116:5:116:17 | [CallExpr] sink(element) | semmle.label | 1 | +| arrays.js:116:5:116:18 | [ExprStmt] sink(element); | arrays.js:116:5:116:17 | [CallExpr] sink(element) | semmle.order | 1 | +| arrays.js:119:3:123:3 | [BlockStmt] { // T ... OK } | arrays.js:120:5:120:28 | [DeclStmt] const list = ... | semmle.label | 1 | +| arrays.js:119:3:123:3 | [BlockStmt] { // T ... OK } | arrays.js:120:5:120:28 | [DeclStmt] const list = ... | semmle.order | 1 | +| arrays.js:119:3:123:3 | [BlockStmt] { // T ... OK } | arrays.js:121:5:121:52 | [DeclStmt] const element = ... | semmle.label | 2 | +| arrays.js:119:3:123:3 | [BlockStmt] { // T ... OK } | arrays.js:121:5:121:52 | [DeclStmt] const element = ... | semmle.order | 2 | +| arrays.js:119:3:123:3 | [BlockStmt] { // T ... OK } | arrays.js:122:5:122:18 | [ExprStmt] sink(element); | semmle.label | 3 | +| arrays.js:119:3:123:3 | [BlockStmt] { // T ... OK } | arrays.js:122:5:122:18 | [ExprStmt] sink(element); | semmle.order | 3 | +| arrays.js:120:5:120:28 | [DeclStmt] const list = ... | arrays.js:120:11:120:27 | [VariableDeclarator] list = ["source"] | semmle.label | 1 | +| arrays.js:120:5:120:28 | [DeclStmt] const list = ... | arrays.js:120:11:120:27 | [VariableDeclarator] list = ["source"] | semmle.order | 1 | +| arrays.js:120:11:120:27 | [VariableDeclarator] list = ["source"] | arrays.js:120:11:120:14 | [VarDecl] list | semmle.label | 1 | +| arrays.js:120:11:120:27 | [VariableDeclarator] list = ["source"] | arrays.js:120:11:120:14 | [VarDecl] list | semmle.order | 1 | +| arrays.js:120:11:120:27 | [VariableDeclarator] list = ["source"] | arrays.js:120:18:120:27 | [ArrayExpr] ["source"] | semmle.label | 2 | +| arrays.js:120:11:120:27 | [VariableDeclarator] list = ["source"] | arrays.js:120:18:120:27 | [ArrayExpr] ["source"] | semmle.order | 2 | +| arrays.js:120:18:120:27 | [ArrayExpr] ["source"] | arrays.js:120:19:120:26 | [Literal] "source" | semmle.label | 1 | +| arrays.js:120:18:120:27 | [ArrayExpr] ["source"] | arrays.js:120:19:120:26 | [Literal] "source" | semmle.order | 1 | +| arrays.js:121:5:121:52 | [DeclStmt] const element = ... | arrays.js:121:11:121:51 | [VariableDeclarator] element ... (item)) | semmle.label | 1 | +| arrays.js:121:5:121:52 | [DeclStmt] const element = ... | arrays.js:121:11:121:51 | [VariableDeclarator] element ... (item)) | semmle.order | 1 | +| arrays.js:121:11:121:51 | [VariableDeclarator] element ... (item)) | arrays.js:121:11:121:17 | [VarDecl] element | semmle.label | 1 | +| arrays.js:121:11:121:51 | [VariableDeclarator] element ... (item)) | arrays.js:121:11:121:17 | [VarDecl] element | semmle.order | 1 | +| arrays.js:121:11:121:51 | [VariableDeclarator] element ... (item)) | arrays.js:121:21:121:51 | [MethodCallExpr] list.fi ... (item)) | semmle.label | 2 | +| arrays.js:121:11:121:51 | [VariableDeclarator] element ... (item)) | arrays.js:121:21:121:51 | [MethodCallExpr] list.fi ... (item)) | semmle.order | 2 | +| arrays.js:121:21:121:29 | [DotExpr] list.find | arrays.js:121:21:121:24 | [VarRef] list | semmle.label | 1 | +| arrays.js:121:21:121:29 | [DotExpr] list.find | arrays.js:121:21:121:24 | [VarRef] list | semmle.order | 1 | +| arrays.js:121:21:121:29 | [DotExpr] list.find | arrays.js:121:26:121:29 | [Label] find | semmle.label | 2 | +| arrays.js:121:21:121:29 | [DotExpr] list.find | arrays.js:121:26:121:29 | [Label] find | semmle.order | 2 | +| arrays.js:121:21:121:51 | [MethodCallExpr] list.fi ... (item)) | arrays.js:121:21:121:29 | [DotExpr] list.find | semmle.label | 0 | +| arrays.js:121:21:121:51 | [MethodCallExpr] list.fi ... (item)) | arrays.js:121:21:121:29 | [DotExpr] list.find | semmle.order | 0 | +| arrays.js:121:21:121:51 | [MethodCallExpr] list.fi ... (item)) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:121:21:121:51 | [MethodCallExpr] list.fi ... (item)) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:121:31:121:50 | [ArrowFunctionExpr] (item) => sink(item) | arrays.js:121:41:121:50 | [CallExpr] sink(item) | semmle.label | 5 | +| arrays.js:121:31:121:50 | [ArrowFunctionExpr] (item) => sink(item) | arrays.js:121:41:121:50 | [CallExpr] sink(item) | semmle.order | 5 | +| arrays.js:121:31:121:50 | [ArrowFunctionExpr] (item) => sink(item) | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| arrays.js:121:31:121:50 | [ArrowFunctionExpr] (item) => sink(item) | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| arrays.js:121:41:121:50 | [CallExpr] sink(item) | arrays.js:121:41:121:44 | [VarRef] sink | semmle.label | 0 | +| arrays.js:121:41:121:50 | [CallExpr] sink(item) | arrays.js:121:41:121:44 | [VarRef] sink | semmle.order | 0 | +| arrays.js:121:41:121:50 | [CallExpr] sink(item) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:121:41:121:50 | [CallExpr] sink(item) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:122:5:122:17 | [CallExpr] sink(element) | arrays.js:122:5:122:8 | [VarRef] sink | semmle.label | 0 | +| arrays.js:122:5:122:17 | [CallExpr] sink(element) | arrays.js:122:5:122:8 | [VarRef] sink | semmle.order | 0 | +| arrays.js:122:5:122:17 | [CallExpr] sink(element) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:122:5:122:17 | [CallExpr] sink(element) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:122:5:122:18 | [ExprStmt] sink(element); | arrays.js:122:5:122:17 | [CallExpr] sink(element) | semmle.label | 1 | +| arrays.js:122:5:122:18 | [ExprStmt] sink(element); | arrays.js:122:5:122:17 | [CallExpr] sink(element) | semmle.order | 1 | +| arrays.js:125:3:129:3 | [BlockStmt] { // T ... OK } | arrays.js:126:5:126:28 | [DeclStmt] const list = ... | semmle.label | 1 | +| arrays.js:125:3:129:3 | [BlockStmt] { // T ... OK } | arrays.js:126:5:126:28 | [DeclStmt] const list = ... | semmle.order | 1 | +| arrays.js:125:3:129:3 | [BlockStmt] { // T ... OK } | arrays.js:127:5:127:61 | [DeclStmt] const element = ... | semmle.label | 2 | +| arrays.js:125:3:129:3 | [BlockStmt] { // T ... OK } | arrays.js:127:5:127:61 | [DeclStmt] const element = ... | semmle.order | 2 | +| arrays.js:125:3:129:3 | [BlockStmt] { // T ... OK } | arrays.js:128:5:128:18 | [ExprStmt] sink(element); | semmle.label | 3 | +| arrays.js:125:3:129:3 | [BlockStmt] { // T ... OK } | arrays.js:128:5:128:18 | [ExprStmt] sink(element); | semmle.order | 3 | +| arrays.js:126:5:126:28 | [DeclStmt] const list = ... | arrays.js:126:11:126:27 | [VariableDeclarator] list = ["source"] | semmle.label | 1 | +| arrays.js:126:5:126:28 | [DeclStmt] const list = ... | arrays.js:126:11:126:27 | [VariableDeclarator] list = ["source"] | semmle.order | 1 | +| arrays.js:126:11:126:27 | [VariableDeclarator] list = ["source"] | arrays.js:126:11:126:14 | [VarDecl] list | semmle.label | 1 | +| arrays.js:126:11:126:27 | [VariableDeclarator] list = ["source"] | arrays.js:126:11:126:14 | [VarDecl] list | semmle.order | 1 | +| arrays.js:126:11:126:27 | [VariableDeclarator] list = ["source"] | arrays.js:126:18:126:27 | [ArrayExpr] ["source"] | semmle.label | 2 | +| arrays.js:126:11:126:27 | [VariableDeclarator] list = ["source"] | arrays.js:126:18:126:27 | [ArrayExpr] ["source"] | semmle.order | 2 | +| arrays.js:126:18:126:27 | [ArrayExpr] ["source"] | arrays.js:126:19:126:26 | [Literal] "source" | semmle.label | 1 | +| arrays.js:126:18:126:27 | [ArrayExpr] ["source"] | arrays.js:126:19:126:26 | [Literal] "source" | semmle.order | 1 | +| arrays.js:127:5:127:61 | [DeclStmt] const element = ... | arrays.js:127:11:127:60 | [VariableDeclarator] element ... (item)) | semmle.label | 1 | +| arrays.js:127:5:127:61 | [DeclStmt] const element = ... | arrays.js:127:11:127:60 | [VariableDeclarator] element ... (item)) | semmle.order | 1 | +| arrays.js:127:11:127:60 | [VariableDeclarator] element ... (item)) | arrays.js:127:11:127:17 | [VarDecl] element | semmle.label | 1 | +| arrays.js:127:11:127:60 | [VariableDeclarator] element ... (item)) | arrays.js:127:11:127:17 | [VarDecl] element | semmle.order | 1 | +| arrays.js:127:11:127:60 | [VariableDeclarator] element ... (item)) | arrays.js:127:21:127:60 | [MethodCallExpr] list.fi ... (item)) | semmle.label | 2 | +| arrays.js:127:11:127:60 | [VariableDeclarator] element ... (item)) | arrays.js:127:21:127:60 | [MethodCallExpr] list.fi ... (item)) | semmle.order | 2 | +| arrays.js:127:21:127:38 | [DotExpr] list.findLastIndex | arrays.js:127:21:127:24 | [VarRef] list | semmle.label | 1 | +| arrays.js:127:21:127:38 | [DotExpr] list.findLastIndex | arrays.js:127:21:127:24 | [VarRef] list | semmle.order | 1 | +| arrays.js:127:21:127:38 | [DotExpr] list.findLastIndex | arrays.js:127:26:127:38 | [Label] findLastIndex | semmle.label | 2 | +| arrays.js:127:21:127:38 | [DotExpr] list.findLastIndex | arrays.js:127:26:127:38 | [Label] findLastIndex | semmle.order | 2 | +| arrays.js:127:21:127:60 | [MethodCallExpr] list.fi ... (item)) | arrays.js:127:21:127:38 | [DotExpr] list.findLastIndex | semmle.label | 0 | +| arrays.js:127:21:127:60 | [MethodCallExpr] list.fi ... (item)) | arrays.js:127:21:127:38 | [DotExpr] list.findLastIndex | semmle.order | 0 | +| arrays.js:127:21:127:60 | [MethodCallExpr] list.fi ... (item)) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:127:21:127:60 | [MethodCallExpr] list.fi ... (item)) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:127:40:127:59 | [ArrowFunctionExpr] (item) => sink(item) | arrays.js:127:50:127:59 | [CallExpr] sink(item) | semmle.label | 5 | +| arrays.js:127:40:127:59 | [ArrowFunctionExpr] (item) => sink(item) | arrays.js:127:50:127:59 | [CallExpr] sink(item) | semmle.order | 5 | +| arrays.js:127:40:127:59 | [ArrowFunctionExpr] (item) => sink(item) | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| arrays.js:127:40:127:59 | [ArrowFunctionExpr] (item) => sink(item) | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| arrays.js:127:50:127:59 | [CallExpr] sink(item) | arrays.js:127:50:127:53 | [VarRef] sink | semmle.label | 0 | +| arrays.js:127:50:127:59 | [CallExpr] sink(item) | arrays.js:127:50:127:53 | [VarRef] sink | semmle.order | 0 | +| arrays.js:127:50:127:59 | [CallExpr] sink(item) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:127:50:127:59 | [CallExpr] sink(item) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:128:5:128:17 | [CallExpr] sink(element) | arrays.js:128:5:128:8 | [VarRef] sink | semmle.label | 0 | +| arrays.js:128:5:128:17 | [CallExpr] sink(element) | arrays.js:128:5:128:8 | [VarRef] sink | semmle.order | 0 | +| arrays.js:128:5:128:17 | [CallExpr] sink(element) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:128:5:128:17 | [CallExpr] sink(element) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:128:5:128:18 | [ExprStmt] sink(element); | arrays.js:128:5:128:17 | [CallExpr] sink(element) | semmle.label | 1 | +| arrays.js:128:5:128:18 | [ExprStmt] sink(element); | arrays.js:128:5:128:17 | [CallExpr] sink(element) | semmle.order | 1 | | file://:0:0:0:0 | (Arguments) | arrays.js:5:8:5:14 | [DotExpr] obj.foo | semmle.label | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:5:8:5:14 | [DotExpr] obj.foo | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:8:12:8:17 | [VarRef] source | semmle.label | 0 | @@ -1664,6 +1874,24 @@ edges | file://:0:0:0:0 | (Arguments) | arrays.js:111:8:111:33 | [MethodCallExpr] arr.fin ... llback) | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:111:21:111:32 | [VarRef] someCallback | semmle.label | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:111:21:111:32 | [VarRef] someCallback | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:115:35:115:54 | [ArrowFunctionExpr] (item) => sink(item) | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:115:35:115:54 | [ArrowFunctionExpr] (item) => sink(item) | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:115:50:115:53 | [VarRef] item | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:115:50:115:53 | [VarRef] item | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:116:10:116:16 | [VarRef] element | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:116:10:116:16 | [VarRef] element | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:121:31:121:50 | [ArrowFunctionExpr] (item) => sink(item) | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:121:31:121:50 | [ArrowFunctionExpr] (item) => sink(item) | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:121:46:121:49 | [VarRef] item | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:121:46:121:49 | [VarRef] item | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:122:10:122:16 | [VarRef] element | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:122:10:122:16 | [VarRef] element | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:127:40:127:59 | [ArrowFunctionExpr] (item) => sink(item) | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:127:40:127:59 | [ArrowFunctionExpr] (item) => sink(item) | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:127:55:127:58 | [VarRef] item | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:127:55:127:58 | [VarRef] item | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:128:10:128:16 | [VarRef] element | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:128:10:128:16 | [VarRef] element | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:15:16:15:16 | [SimpleParameter] e | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:15:16:15:16 | [SimpleParameter] e | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:16:12:16:12 | [SimpleParameter] e | semmle.label | 0 | @@ -1682,5 +1910,11 @@ edges | file://:0:0:0:0 | (Parameters) | arrays.js:95:27:95:27 | [SimpleParameter] x | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:96:27:96:27 | [SimpleParameter] x | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:96:27:96:27 | [SimpleParameter] x | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | arrays.js:115:36:115:39 | [SimpleParameter] item | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | arrays.js:115:36:115:39 | [SimpleParameter] item | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | arrays.js:121:32:121:35 | [SimpleParameter] item | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | arrays.js:121:32:121:35 | [SimpleParameter] item | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | arrays.js:127:41:127:44 | [SimpleParameter] item | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | arrays.js:127:41:127:44 | [SimpleParameter] item | semmle.order | 0 | graphProperties | semmle.graphKind | tree | From c03d69af1eeaeed4ee27d0c72fdf676f5b1bc46f Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 19 Nov 2024 09:42:11 +0100 Subject: [PATCH 050/470] JS: Add: dataflow step for find, findLast, findLastIndex callback functions --- javascript/ql/lib/semmle/javascript/Arrays.qll | 14 ++++++++++++++ .../ql/test/library-tests/Arrays/DataFlow.expected | 3 +++ .../test/library-tests/Arrays/TaintFlow.expected | 3 +++ javascript/ql/test/library-tests/Arrays/arrays.js | 6 +++--- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/Arrays.qll b/javascript/ql/lib/semmle/javascript/Arrays.qll index 5cb7d231586..c132fc9bc2a 100644 --- a/javascript/ql/lib/semmle/javascript/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/Arrays.qll @@ -483,4 +483,18 @@ private module ArrayLibraries { ) } } + + /** + * Defines a data flow step that tracks the flow of data through callback functions in arrays. + */ + private class ArrayCallBackDataFlowStep extends PreCallGraphStep { + override predicate loadStep(DataFlow::Node obj, DataFlow::Node element, string prop) { + exists(DataFlow::MethodCallNode call | + call.getMethodName() = ["findLast", "find", "findLastIndex"] and + prop = arrayLikeElement() and + obj = call.getReceiver() and + element = call.getCallback(0).getParameter(0) + ) + } + } } diff --git a/javascript/ql/test/library-tests/Arrays/DataFlow.expected b/javascript/ql/test/library-tests/Arrays/DataFlow.expected index 91742699b61..07fabfb7270 100644 --- a/javascript/ql/test/library-tests/Arrays/DataFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/DataFlow.expected @@ -26,5 +26,8 @@ | arrays.js:53:4:53:11 | "source" | arrays.js:54:10:54:18 | ary.pop() | | arrays.js:99:31:99:38 | "source" | arrays.js:100:8:100:17 | arr8.pop() | | arrays.js:103:55:103:62 | "source" | arrays.js:105:8:105:25 | arr8_variant.pop() | +| arrays.js:114:19:114:26 | "source" | arrays.js:115:50:115:53 | item | | arrays.js:114:19:114:26 | "source" | arrays.js:116:10:116:16 | element | +| arrays.js:120:19:120:26 | "source" | arrays.js:121:46:121:49 | item | | arrays.js:120:19:120:26 | "source" | arrays.js:122:10:122:16 | element | +| arrays.js:126:19:126:26 | "source" | arrays.js:127:55:127:58 | item | diff --git a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected index cb3b16479a7..06260a21c1c 100644 --- a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected @@ -30,5 +30,8 @@ | arrays.js:96:9:96:16 | "source" | arrays.js:96:8:96:36 | ["sourc ... => !!x) | | arrays.js:99:31:99:38 | "source" | arrays.js:100:8:100:17 | arr8.pop() | | arrays.js:103:55:103:62 | "source" | arrays.js:105:8:105:25 | arr8_variant.pop() | +| arrays.js:114:19:114:26 | "source" | arrays.js:115:50:115:53 | item | | arrays.js:114:19:114:26 | "source" | arrays.js:116:10:116:16 | element | +| arrays.js:120:19:120:26 | "source" | arrays.js:121:46:121:49 | item | | arrays.js:120:19:120:26 | "source" | arrays.js:122:10:122:16 | element | +| arrays.js:126:19:126:26 | "source" | arrays.js:127:55:127:58 | item | diff --git a/javascript/ql/test/library-tests/Arrays/arrays.js b/javascript/ql/test/library-tests/Arrays/arrays.js index e4124ec16d8..00aa0c59e18 100644 --- a/javascript/ql/test/library-tests/Arrays/arrays.js +++ b/javascript/ql/test/library-tests/Arrays/arrays.js @@ -112,19 +112,19 @@ { // Test for findLast function const list = ["source"]; - const element = list.findLast((item) => sink(item)); // NOT OK -- Not caught, currently missing dataflow tracking. + const element = list.findLast((item) => sink(item)); // NOT OK sink(element); // NOT OK } { // Test for find function const list = ["source"]; - const element = list.find((item) => sink(item)); // NOT OK -- Not caught, currently missing dataflow tracking. + const element = list.find((item) => sink(item)); // NOT OK sink(element); // NOT OK } { // Test for findLastIndex function const list = ["source"]; - const element = list.findLastIndex((item) => sink(item)); // NOT OK -- Not caught, currently missing dataflow tracking. + const element = list.findLastIndex((item) => sink(item)); // NOT OK sink(element); // OK } }); From aea7c3fc81fab7af5c485b95e7485cd9541375a1 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Tue, 19 Nov 2024 10:37:35 +0100 Subject: [PATCH 051/470] Java: drop automodel change note --- .../automodel/src/change-notes/2024-11-19-drop-automodel.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/automodel/src/change-notes/2024-11-19-drop-automodel.md diff --git a/java/ql/automodel/src/change-notes/2024-11-19-drop-automodel.md b/java/ql/automodel/src/change-notes/2024-11-19-drop-automodel.md new file mode 100644 index 00000000000..2b554d6de20 --- /dev/null +++ b/java/ql/automodel/src/change-notes/2024-11-19-drop-automodel.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Dropped the Java Automodel queries. From 4208f031e3fdebdaab6c7029fee37df725b17a98 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Tue, 19 Nov 2024 10:40:04 +0100 Subject: [PATCH 052/470] Java: drop automodel queries --- java/ql/automodel/publish.sh | 197 ----- .../automodel/src/AutomodelAlertSinkUtil.qll | 183 ----- java/ql/automodel/src/AutomodelAlertSinks.ql | 16 - .../src/AutomodelAlertSinksPerQuery.ql | 19 - ...utomodelApplicationModeCharacteristics.qll | 677 ------------------ ...tomodelApplicationModeExtractCandidates.ql | 81 --- ...lApplicationModeExtractNegativeExamples.ql | 66 -- ...lApplicationModeExtractPositiveExamples.ql | 37 - .../src/AutomodelCandidateFilter.yml | 5 - .../src/AutomodelCountGeneratedSinks.ql | 19 - .../automodel/src/AutomodelEndpointTypes.qll | 82 --- .../AutomodelFrameworkModeCharacteristics.qll | 507 ------------- ...AutomodelFrameworkModeExtractCandidates.ql | 38 - ...delFrameworkModeExtractNegativeExamples.ql | 36 - ...delFrameworkModeExtractPositiveExamples.ql | 34 - java/ql/automodel/src/AutomodelJavaUtil.qll | 111 --- .../src/AutomodelSharedCharacteristics.qll | 412 ----------- .../src/AutomodelSinkModelMrvaQueries.ql | 62 -- java/ql/automodel/src/codeql-pack.release.yml | 2 - java/ql/automodel/src/qlpack.yml | 10 - ...delApplicationModeExtractionTests.expected | 2 - ...AutomodelApplicationModeExtractionTests.ql | 35 - .../PluginImpl.java | 8 - .../Test.java | 112 --- .../hudson/Plugin.java | 7 - .../test/AutomodelExtractionTests.qll | 77 -- ...modelFrameworkModeExtractionTests.expected | 2 - .../AutomodelFrameworkModeExtractionTests.ql | 35 - .../com/github/codeql/test/MyWriter.java | 15 - .../github/codeql/test/NonPublicClass.java | 10 - .../com/github/codeql/test/PublicClass.java | 27 - .../github/codeql/test/PublicInterface.java | 9 - .../java/io/File.java | 13 - .../java/nio/file/Files.java | 31 - .../test/change-notes/2024-05-23-Version1.md | 4 - java/ql/automodel/test/qlpack.yml | 13 - 36 files changed, 2994 deletions(-) delete mode 100755 java/ql/automodel/publish.sh delete mode 100644 java/ql/automodel/src/AutomodelAlertSinkUtil.qll delete mode 100644 java/ql/automodel/src/AutomodelAlertSinks.ql delete mode 100644 java/ql/automodel/src/AutomodelAlertSinksPerQuery.ql delete mode 100644 java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll delete mode 100644 java/ql/automodel/src/AutomodelApplicationModeExtractCandidates.ql delete mode 100644 java/ql/automodel/src/AutomodelApplicationModeExtractNegativeExamples.ql delete mode 100644 java/ql/automodel/src/AutomodelApplicationModeExtractPositiveExamples.ql delete mode 100644 java/ql/automodel/src/AutomodelCandidateFilter.yml delete mode 100644 java/ql/automodel/src/AutomodelCountGeneratedSinks.ql delete mode 100644 java/ql/automodel/src/AutomodelEndpointTypes.qll delete mode 100644 java/ql/automodel/src/AutomodelFrameworkModeCharacteristics.qll delete mode 100644 java/ql/automodel/src/AutomodelFrameworkModeExtractCandidates.ql delete mode 100644 java/ql/automodel/src/AutomodelFrameworkModeExtractNegativeExamples.ql delete mode 100644 java/ql/automodel/src/AutomodelFrameworkModeExtractPositiveExamples.ql delete mode 100644 java/ql/automodel/src/AutomodelJavaUtil.qll delete mode 100644 java/ql/automodel/src/AutomodelSharedCharacteristics.qll delete mode 100644 java/ql/automodel/src/AutomodelSinkModelMrvaQueries.ql delete mode 100644 java/ql/automodel/src/codeql-pack.release.yml delete mode 100644 java/ql/automodel/src/qlpack.yml delete mode 100644 java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractionTests.expected delete mode 100644 java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractionTests.ql delete mode 100644 java/ql/automodel/test/AutomodelApplicationModeExtraction/PluginImpl.java delete mode 100644 java/ql/automodel/test/AutomodelApplicationModeExtraction/Test.java delete mode 100644 java/ql/automodel/test/AutomodelApplicationModeExtraction/hudson/Plugin.java delete mode 100644 java/ql/automodel/test/AutomodelExtractionTests.qll delete mode 100644 java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractionTests.expected delete mode 100644 java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractionTests.ql delete mode 100644 java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/MyWriter.java delete mode 100644 java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/NonPublicClass.java delete mode 100644 java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java delete mode 100644 java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicInterface.java delete mode 100644 java/ql/automodel/test/AutomodelFrameworkModeExtraction/java/io/File.java delete mode 100644 java/ql/automodel/test/AutomodelFrameworkModeExtraction/java/nio/file/Files.java delete mode 100644 java/ql/automodel/test/change-notes/2024-05-23-Version1.md delete mode 100644 java/ql/automodel/test/qlpack.yml diff --git a/java/ql/automodel/publish.sh b/java/ql/automodel/publish.sh deleted file mode 100755 index 7304f0da180..00000000000 --- a/java/ql/automodel/publish.sh +++ /dev/null @@ -1,197 +0,0 @@ -#!/bin/bash -set -e - -help="Usage: ./publish [--override-release] [--dry-run] -Publish the automodel query pack. - -If no arguments are provided, publish the version of the codeql repo specified by the latest official release of the codeml-automodel repo. -If the --override-release argument is provided, your current local HEAD is used (for unofficial releases or patching). -If the --dry-run argument is provided, the release is not published (for testing purposes)." - -# Echo the help message -if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then - echo "$help" - exit 0 -fi - -# Check the number of arguments are valid -if [ $# -gt 2 ]; then - echo "Error: Invalid arguments provided" - echo "$help" - exit 1 -fi - -OVERRIDE_RELEASE=0 -DRY_RUN=0 -for arg in "$@" -do - case $arg in - --override-release) - OVERRIDE_RELEASE=1 - shift # Remove --override-release from processing - ;; - --dry-run) - DRY_RUN=1 - shift # Remove --dry-run from processing - ;; - *) - echo "Error: Invalid argument provided: $arg" - echo "$help" - exit 1 - ;; - esac -done - -# Describe what we're about to do based on the command-line arguments -if [ $OVERRIDE_RELEASE = 1 ]; then - echo "Publishing the current HEAD of the automodel repo" -else - echo "Publishing the version of the automodel repo specified by the latest official release of the codeml-automodel repo" -fi -if [ $DRY_RUN = 1 ]; then - echo "Dry run: we will step through the process but we won't publish the query pack" -else - echo "Not a dry run! Publishing the query pack" -fi - -# If we're publishing the codeml-automodel release then we will checkout the sha specified in the release. -# So we need to check that there are no uncommitted changes in the local branch. -# And, if we're publishing the current HEAD, it's cleaner to ensure that there are no uncommitted changes. -if ! git diff --quiet; then - echo "Error: Uncommitted changes exist. Please commit or stash your changes before publishing." - exit 1 -fi - -# Check the above environment variables are set -if [ -z "${GITHUB_TOKEN}" ]; then - echo "Error: GITHUB_TOKEN environment variable not set. Please set this to a token with package:write permissions to codeql." - exit 1 -fi -if [ -z "${GH_TOKEN}" ]; then - echo "Error: GH_TOKEN environment variable not set. Please set this to a token with repo permissions to github/codeml-automodel." - exit 1 -fi - -# Get the sha of the previous release, i.e. the last commit to the main branch that updated the query pack version -PREVIOUS_RELEASE_SHA=$(git rev-list -n 1 main -- ./src/qlpack.yml) -if [ -z "$PREVIOUS_RELEASE_SHA" ]; then - echo "Error: Could not get the sha of the previous release of codeml-automodel query pack" - exit 1 -else - echo "Previous query-pack release sha: $PREVIOUS_RELEASE_SHA" -fi - -CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) -CURRENT_SHA=$(git rev-parse HEAD) - -if [ $OVERRIDE_RELEASE = 1 ]; then - # Check that the current HEAD is downstream from PREVIOUS_RELEASE_SHA - if ! git merge-base --is-ancestor "$PREVIOUS_RELEASE_SHA" "$CURRENT_SHA"; then - echo "Error: The current HEAD is not downstream from the previous release" - exit 1 - fi -else - # Get the latest release of codeml-automodel - TAG_NAME=$(gh api -H 'Accept: application/vnd.github+json' -H 'X-GitHub-Api-Version: 2022-11-28' /repos/github/codeml-automodel/releases/latest | jq -r .tag_name) - # Check TAG_NAME is not empty - if [ -z "$TAG_NAME" ]; then - echo "Error: Could not get latest release of codeml-automodel" - exit 1 - fi - echo "Updating to latest automodel release: $TAG_NAME" - # Before downloading, delete any existing release.zip, and ignore failure if not present - rm release.zip || true - gh release download $TAG_NAME -A zip -O release.zip --repo 'https://github.com/github/codeml-automodel' - # Before unzipping, delete any existing release directory, and ignore failure if not present - rm -rf release || true - unzip -o release.zip -d release - REVISION=$(jq -r '.["codeql-sha"]' release/codeml-automodel*/codeml-automodel-release.json) - echo "The latest codeml-automodel release specifies the codeql sha $REVISION" - # Check that REVISION is downstream from PREVIOUS_RELEASE_SHA - if ! git merge-base --is-ancestor "$PREVIOUS_RELEASE_SHA" "$REVISION"; then - echo "Error: The codeql version $REVISION is not downstream of the query-pack version $PREVIOUS_RELEASE_SHA" - exit 1 - fi - # Get the version of the codeql code specified by the codeml-automodel release - git checkout "$REVISION" -fi - -# Get the absolute path of the automodel repo -AUTOMODEL_ROOT="$(readlink -f "$(dirname $0)")" -# Get the absolute path of the workspace root -WORKSPACE_ROOT="$AUTOMODEL_ROOT/../../.." -# Specify the groups of queries to test and publish -GRPS="automodel,-test" - -# Install the codeql gh extension -gh extensions install github/gh-codeql - -pushd "$AUTOMODEL_ROOT" -echo Testing automodel queries -gh codeql test run test -popd - -pushd "$WORKSPACE_ROOT" -echo "Preparing the release" -gh codeql pack release --groups $GRPS -v - -if [ $DRY_RUN = 1 ]; then - echo "Dry run: not publishing the query pack" - gh codeql pack publish --groups $GRPS --dry-run -v -else - echo "Not a dry run! Publishing the query pack" - gh codeql pack publish --groups $GRPS -v -fi - -echo "Bumping versions" -gh codeql pack post-release --groups $GRPS -v -popd - -# The above commands update -# ./src/CHANGELOG.md -# ./src/codeql-pack.release.yml -# ./src/qlpack.yml -# and add a new file -# ./src/change-notes/released/.md - -# Get the filename of the most recently created file in ./src/change-notes/released/*.md -# This will be the file for the new release -NEW_CHANGE_NOTES_FILE=$(ls -t ./src/change-notes/released/*.md | head -n 1) - -# Make a copy of the modified files -mv ./src/CHANGELOG.md ./src/CHANGELOG.md.dry-run -mv ./src/codeql-pack.release.yml ./src/codeql-pack.release.yml.dry-run -mv ./src/qlpack.yml ./src/qlpack.yml.dry-run -mv "$NEW_CHANGE_NOTES_FILE" ./src/change-notes/released.md.dry-run - -if [ $OVERRIDE_RELEASE = 1 ]; then - # Restore the original files - git checkout ./src/CHANGELOG.md - git checkout ./src/codeql-pack.release.yml - git checkout ./src/qlpack.yml -else - # Restore the original files - git checkout "$CURRENT_BRANCH" --force -fi - -if [ $DRY_RUN = 1 ]; then - echo "Inspect the updated dry-run version files:" - ls -l ./src/*.dry-run - ls -l ./src/change-notes/*.dry-run -else - # Add the updated files to the current branch - echo "Adding the version changes" - mv -f ./src/CHANGELOG.md.dry-run ./src/CHANGELOG.md - mv -f ./src/codeql-pack.release.yml.dry-run ./src/codeql-pack.release.yml - mv -f ./src/qlpack.yml.dry-run ./src/qlpack.yml - mv -f ./src/change-notes/released.md.dry-run "$NEW_CHANGE_NOTES_FILE" - git add ./src/CHANGELOG.md - git add ./src/codeql-pack.release.yml - git add ./src/qlpack.yml - git add "$NEW_CHANGE_NOTES_FILE" - echo "Added the following updated version files to the current branch:" - git status -s - echo "To complete the release, please commit these files and merge to the main branch" -fi - -echo "Done" \ No newline at end of file diff --git a/java/ql/automodel/src/AutomodelAlertSinkUtil.qll b/java/ql/automodel/src/AutomodelAlertSinkUtil.qll deleted file mode 100644 index f20c8e57b6c..00000000000 --- a/java/ql/automodel/src/AutomodelAlertSinkUtil.qll +++ /dev/null @@ -1,183 +0,0 @@ -private import java -private import semmle.code.java.dataflow.ExternalFlow as ExternalFlow -private import semmle.code.java.dataflow.TaintTracking -private import semmle.code.java.security.RequestForgeryConfig -private import semmle.code.java.security.CommandLineQuery -private import semmle.code.java.security.SqlConcatenatedQuery -private import semmle.code.java.security.SqlInjectionQuery -private import semmle.code.java.security.UrlRedirectQuery -private import semmle.code.java.security.TaintedPathQuery -private import semmle.code.java.security.SqlInjectionQuery -private import AutomodelJavaUtil - -private newtype TSinkModel = - MkSinkModel( - string package, string type, boolean subtypes, string name, string signature, string ext, - string input, string kind, string provenance - ) { - ExternalFlow::sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance, - _) - } - -class SinkModel extends TSinkModel { - string package; - string type; - boolean subtypes; - string name; - string signature; - string ext; - string input; - string kind; - string provenance; - - SinkModel() { - this = MkSinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) - } - - /** Gets the package for this sink model. */ - string getPackage() { result = package } - - /** Gets the type for this sink model. */ - string getType() { result = type } - - /** Gets whether this sink model considers subtypes. */ - boolean getSubtypes() { result = subtypes } - - /** Gets the name for this sink model. */ - string getName() { result = name } - - /** Gets the signature for this sink model. */ - string getSignature() { result = signature } - - /** Gets the input for this sink model. */ - string getInput() { result = input } - - /** Gets the extension for this sink model. */ - string getExt() { result = ext } - - /** Gets the kind for this sink model. */ - string getKind() { result = kind } - - /** Gets the provenance for this sink model. */ - string getProvenance() { result = provenance } - - /** Gets the number of instances of this sink model. */ - int getInstanceCount() { result = count(PotentialSinkModelExpr p | p.getSinkModel() = this) } - - /** Gets a string representation of this sink model. */ - string toString() { - result = - "SinkModel(" + package + ", " + type + ", " + subtypes + ", " + name + ", " + signature + ", " - + ext + ", " + input + ", " + kind + ", " + provenance + ")" - } - - /** Gets a string representation of this sink model as it would appear in a Models-as-Data file. */ - string getRepr() { - result = - "\"" + package + "\", \"" + type + "\", " + pyBool(subtypes) + ", \"" + name + "\", \"" + - signature + "\", \"" + ext + "\", \"" + input + "\", \"" + kind + "\", \"" + provenance + - "\"" - } -} - -/** An expression that may correspond to a sink model. */ -class PotentialSinkModelExpr extends Expr { - /** - * Holds if this expression has the given signature. The signature should contain enough - * information to determine a corresponding sink model, if one exists. - */ - pragma[nomagic] - predicate hasSignature( - string package, string type, boolean subtypes, string name, string signature, string input - ) { - exists(Call call, Callable callable, int argIdx | - call.getCallee().getSourceDeclaration() = callable and - ( - this = call.getArgument(argIdx) - or - this = call.getQualifier() and argIdx = -1 - ) and - (if argIdx = -1 then input = "Argument[this]" else input = "Argument[" + argIdx + "]") and - package = callable.getDeclaringType().getPackage().getName() and - type = callable.getDeclaringType().getErasure().(RefType).getNestedName() and - subtypes = considerSubtypes(callable) and - name = callable.getName() and - signature = ExternalFlow::paramsString(callable) - ) - } - - /** Gets a sink model that corresponds to this expression. */ - SinkModel getSinkModel() { - this.hasSignature(result.getPackage(), result.getType(), result.getSubtypes(), result.getName(), - result.getSignature(), result.getInput()) - } -} - -private string pyBool(boolean b) { - b = true and result = "True" - or - b = false and result = "False" -} - -/** - * Gets a string representation of the existing sink model at the expression `e`, in the format in - * which it would appear in a Models-as-Data file. Also restricts the provenance of the sink model - * to be `ai-generated`. - */ -string getSinkModelRepr(PotentialSinkModelExpr e) { - result = e.getSinkModel().getRepr() and - e.getSinkModel().getProvenance() = "ai-generated" -} - -/** - * Gets the string representation of a sink model in a format suitable for appending to an alert - * message. - */ -string getSinkModelQueryRepr(PotentialSinkModelExpr e) { - result = "\nsinkModel: " + getSinkModelRepr(e) -} - -/** - * A parameterised module that takes a dataflow config, and exposes a predicate for counting the - * number of AI-generated sink models that appear in alerts for that query. - */ -private module SinkTallier { - module ConfigFlow = TaintTracking::Global; - - predicate getSinkModelCount(int c, SinkModel s) { - s = any(ConfigFlow::PathNode sink).getNode().asExpr().(PotentialSinkModelExpr).getSinkModel() and - c = - strictcount(ConfigFlow::PathNode sink | - ConfigFlow::flowPath(_, sink) and - s = sink.getNode().asExpr().(PotentialSinkModelExpr).getSinkModel() - ) - } -} - -predicate sinkModelTallyPerQuery(string queryName, int alertCount, SinkModel sinkModel) { - queryName = "java/request-forgery" and - SinkTallier::getSinkModelCount(alertCount, sinkModel) - or - queryName = "java/command-line-injection" and - SinkTallier::getSinkModelCount(alertCount, sinkModel) - or - queryName = "java/concatenated-sql-query" and - SinkTallier::getSinkModelCount(alertCount, sinkModel) - or - queryName = "java/ssrf" and - SinkTallier::getSinkModelCount(alertCount, sinkModel) - or - queryName = "java/path-injection" and - SinkTallier::getSinkModelCount(alertCount, sinkModel) - or - queryName = "java/unvalidated-url-redirection" and - SinkTallier::getSinkModelCount(alertCount, sinkModel) - or - queryName = "java/sql-injection" and - SinkTallier::getSinkModelCount(alertCount, sinkModel) -} - -predicate sinkModelTally(int alertCount, SinkModel sinkModel) { - sinkModelTallyPerQuery(_, _, sinkModel) and - alertCount = sum(int c | sinkModelTallyPerQuery(_, c, sinkModel)) -} diff --git a/java/ql/automodel/src/AutomodelAlertSinks.ql b/java/ql/automodel/src/AutomodelAlertSinks.ql deleted file mode 100644 index e9af51b4d63..00000000000 --- a/java/ql/automodel/src/AutomodelAlertSinks.ql +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @name Number of alerts per sink model - * @description Counts the number of alerts using `ai-generated` sink models. - * @kind table - * @id java/ml/metrics-count-alerts-per-sink-model - * @tags internal automodel metrics - */ - -private import java -private import AutomodelAlertSinkUtil - -from int alertCount, SinkModel s -where sinkModelTally(alertCount, s) and s.getProvenance() = "ai-generated" -select alertCount, s.getPackage() as package, s.getType() as type, s.getSubtypes() as subtypes, - s.getName() as name, s.getSignature() as signature, s.getInput() as input, s.getExt() as ext, - s.getKind() as kind, s.getProvenance() as provenance order by alertCount desc diff --git a/java/ql/automodel/src/AutomodelAlertSinksPerQuery.ql b/java/ql/automodel/src/AutomodelAlertSinksPerQuery.ql deleted file mode 100644 index 64a5038d116..00000000000 --- a/java/ql/automodel/src/AutomodelAlertSinksPerQuery.ql +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @name Number of alerts per sink model and query - * @description Counts the number of alerts per query using `ai-generated` sink models. - * @kind table - * @id java/ml/metrics-count-alerts-per-sink-model-and-query - * @tags internal automodel metrics - */ - -private import java -private import AutomodelAlertSinkUtil - -from string queryId, int alertCount, SinkModel s -where - sinkModelTallyPerQuery(queryId, alertCount, s) and - s.getProvenance() = "ai-generated" -select queryId, alertCount, s.getPackage() as package, s.getType() as type, - s.getSubtypes() as subtypes, s.getName() as name, s.getSignature() as signature, - s.getInput() as input, s.getExt() as ext, s.getKind() as kind, s.getProvenance() as provenance - order by queryId, alertCount desc diff --git a/java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll b/java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll deleted file mode 100644 index 750d776891f..00000000000 --- a/java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll +++ /dev/null @@ -1,677 +0,0 @@ -/** - * For internal use only. - */ - -private import java -private import semmle.code.Location as Location -private import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.TaintTracking -private import semmle.code.java.dataflow.ExternalFlow as ExternalFlow -private import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl -private import semmle.code.java.security.ExternalAPIs as ExternalAPIs -private import semmle.code.java.Expr as Expr -private import semmle.code.java.security.QueryInjection -private import semmle.code.java.dataflow.internal.ModelExclusions as ModelExclusions -private import AutomodelJavaUtil as AutomodelJavaUtil -private import semmle.code.java.security.PathSanitizer as PathSanitizer -import AutomodelSharedCharacteristics as SharedCharacteristics -import AutomodelEndpointTypes as AutomodelEndpointTypes - -newtype JavaRelatedLocationType = - CallContext() or - MethodDoc() or - ClassDoc() - -newtype TApplicationModeEndpoint = - TExplicitArgument(Call call, DataFlow::Node arg) { - AutomodelJavaUtil::isFromSource(call) and - exists(Argument argExpr | - arg.asExpr() = argExpr and call = argExpr.getCall() and not argExpr.isVararg() - ) and - not AutomodelJavaUtil::isUnexploitableType(arg.getType()) - } or - TInstanceArgument(Call call, DataFlow::Node arg) { - AutomodelJavaUtil::isFromSource(call) and - arg = DataFlow::getInstanceArgument(call) and - not call instanceof ConstructorCall and - not AutomodelJavaUtil::isUnexploitableType(arg.getType()) - } or - TImplicitVarargsArray(Call call, DataFlow::ImplicitVarargsArray arg, int idx) { - AutomodelJavaUtil::isFromSource(call) and - call = arg.getCall() and - idx = call.getCallee().getVaragsParameterIndex() and - not AutomodelJavaUtil::isUnexploitableType(arg.getType()) - } or - TMethodReturnValue(MethodCall call) { - AutomodelJavaUtil::isFromSource(call) and - not AutomodelJavaUtil::isUnexploitableType(call.getType()) - } or - TOverriddenParameter(Parameter p, Method overriddenMethod) { - AutomodelJavaUtil::isFromSource(p) and - p.getCallable().(Method).overrides(overriddenMethod) - } - -/** - * An endpoint is a node that is a candidate for modeling. - */ -abstract private class ApplicationModeEndpoint extends TApplicationModeEndpoint { - /** - * Gets the callable to be modeled that this endpoint represents. - */ - abstract Callable getCallable(); - - /** - * Gets the input (if any) for this endpoint, eg.: `Argument[0]`. - * - * For endpoints that are source candidates, this will be `none()`. - */ - abstract string getMaDInput(); - - /** - * Gets the output (if any) for this endpoint, eg.: `ReturnValue`. - * - * For endpoints that are sink candidates, this will be `none()`. - */ - abstract string getMaDOutput(); - - abstract Top asTop(); - - /** - * Converts the endpoint to a node that can be used in a data flow graph. - */ - abstract DataFlow::Node asNode(); - - string getExtensibleType() { - if not exists(this.getMaDInput()) and exists(this.getMaDOutput()) - then result = "sourceModel" - else - if exists(this.getMaDInput()) and not exists(this.getMaDOutput()) - then result = "sinkModel" - else none() // if both exist, it would be a summaryModel (not yet supported) - } - - abstract string toString(); -} - -class TCallArgument = TExplicitArgument or TInstanceArgument or TImplicitVarargsArray; - -/** - * An endpoint that represents an "argument" to a call in a broad sense, including - * both explicit arguments and the instance argument. - */ -abstract class CallArgument extends ApplicationModeEndpoint, TCallArgument { - Call call; - DataFlow::Node arg; - - override Callable getCallable() { result = call.getCallee().getSourceDeclaration() } - - override string getMaDOutput() { none() } - - override DataFlow::Node asNode() { result = arg } - - Call getCall() { result = call } - - override string toString() { result = arg.toString() } -} - -/** - * An endpoint that represents an explicit argument to a call. - */ -class ExplicitArgument extends CallArgument, TExplicitArgument { - ExplicitArgument() { this = TExplicitArgument(call, arg) } - - private int getArgIndex() { this.asTop() = call.getArgument(result) } - - override string getMaDInput() { result = "Argument[" + this.getArgIndex() + "]" } - - override Top asTop() { result = arg.asExpr() } -} - -/** - * An endpoint that represents the instance argument to a call. - */ -class InstanceArgument extends CallArgument, TInstanceArgument { - InstanceArgument() { this = TInstanceArgument(call, arg) } - - override string getMaDInput() { result = "Argument[this]" } - - override Top asTop() { if exists(arg.asExpr()) then result = arg.asExpr() else result = call } - - override string toString() { result = arg.toString() } -} - -/** - * An endpoint that represents an implicit varargs array. - * We choose to represent the varargs array as a single endpoint, rather than as multiple endpoints. - * - * This avoids the problem of having to deal with redundant endpoints downstream. - * - * In order to be able to distinguish between varargs endpoints and regular endpoints, we export the `isVarargsArray` - * meta data field in the extraction queries. - */ -class ImplicitVarargsArray extends CallArgument, TImplicitVarargsArray { - int idx; - - ImplicitVarargsArray() { this = TImplicitVarargsArray(call, arg, idx) } - - override string getMaDInput() { result = "Argument[" + idx + "]" } - - override Top asTop() { result = call } -} - -/** - * An endpoint that represents a method call. The `ReturnValue` of a method call - * may be a source. - */ -class MethodReturnValue extends ApplicationModeEndpoint, TMethodReturnValue { - MethodCall call; - - MethodReturnValue() { this = TMethodReturnValue(call) } - - override Callable getCallable() { result = call.getCallee().getSourceDeclaration() } - - override string getMaDInput() { none() } - - override string getMaDOutput() { result = "ReturnValue" } - - override Top asTop() { result = call } - - override DataFlow::Node asNode() { result.asExpr() = call } - - override string toString() { result = call.toString() } -} - -/** - * An endpoint that represents a parameter of an overridden method that may be - * a source. - */ -class OverriddenParameter extends ApplicationModeEndpoint, TOverriddenParameter { - Parameter p; - Method overriddenMethod; - - OverriddenParameter() { this = TOverriddenParameter(p, overriddenMethod) } - - override Callable getCallable() { - // NB: we're returning the overridden callable here. This means that the - // candidate model will be about the overridden method, not the overriding - // method. This is a more general model, that also applies to other - // subclasses of the overridden class. - result = overriddenMethod.getSourceDeclaration() - } - - private int getArgIndex() { p.getCallable().getParameter(result) = p } - - override string getMaDInput() { none() } - - override string getMaDOutput() { result = "Parameter[" + this.getArgIndex() + "]" } - - override Top asTop() { result = p } - - override DataFlow::Node asNode() { result.(DataFlow::ParameterNode).asParameter() = p } - - override string toString() { result = p.toString() } -} - -/** - * A candidates implementation. - * - * Some important notes: - * - This mode is using arguments as endpoints. - * - We use the `CallContext` (the surrounding call expression) as related location. - */ -module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig { - // for documentation of the implementations here, see the QLDoc in the CandidateSig signature module. - class Endpoint = ApplicationModeEndpoint; - - class EndpointType = AutomodelEndpointTypes::EndpointType; - - class SinkType = AutomodelEndpointTypes::SinkType; - - class SourceType = AutomodelEndpointTypes::SourceType; - - class RelatedLocation = Location::Top; - - class RelatedLocationType = JavaRelatedLocationType; - - // Sanitizers are currently not modeled in MaD. TODO: check if this has large negative impact. - predicate isSanitizer(Endpoint e, EndpointType t) { - exists(t) and - AutomodelJavaUtil::isUnexploitableType([ - // for most endpoints, we can get the type from the node - e.asNode().getType(), - // but not for calls to void methods, where we need to go via the AST - e.asTop().(Expr).getType() - ]) - or - t instanceof AutomodelEndpointTypes::PathInjectionSinkType and - e.asNode() instanceof PathSanitizer::PathInjectionSanitizer - } - - RelatedLocation asLocation(Endpoint e) { result = e.asTop() } - - predicate isKnownKind = AutomodelJavaUtil::isKnownKind/2; - - predicate isSink(Endpoint e, string kind, string provenance) { - exists( - string package, string type, boolean subtypes, string name, string signature, string ext, - string input - | - sinkSpec(e, package, type, subtypes, name, signature, ext, input) and - ExternalFlow::sinkModel(package, type, subtypes, name, [signature, ""], ext, input, kind, - provenance, _) - ) - or - isCustomSink(e, kind) and provenance = "custom-sink" - } - - predicate isSource(Endpoint e, string kind, string provenance) { - exists( - string package, string type, boolean subtypes, string name, string signature, string ext, - string output - | - sourceSpec(e, package, type, subtypes, name, signature, ext, output) and - ExternalFlow::sourceModel(package, type, subtypes, name, [signature, ""], ext, output, kind, - provenance, _) - ) - } - - predicate isNeutral(Endpoint e) { - exists(string package, string type, string name, string signature, string endpointType | - sinkSpec(e, package, type, _, name, signature, _, _) and - endpointType = "sink" - or - sourceSpec(e, package, type, _, name, signature, _, _) and - endpointType = "source" - | - ExternalFlow::neutralModel(package, type, name, [signature, ""], endpointType, _) - ) - } - - /** - * Holds if the endpoint concerns a callable with the given package, type, name and signature. - * - * If `subtypes` is `false`, only the exact callable is considered. If `true`, the callable and - * all its overrides are considered. - */ - additional predicate endpointCallable( - Endpoint e, string package, string type, boolean subtypes, string name, string signature - ) { - exists(Callable c | - c = e.getCallable() and subtypes in [true, false] - or - e.getCallable().(Method).getSourceDeclaration().overrides+(c) and subtypes = true - | - c.hasQualifiedName(package, type, name) and - signature = ExternalFlow::paramsString(c) - ) - } - - additional predicate sinkSpec( - Endpoint e, string package, string type, boolean subtypes, string name, string signature, - string ext, string input - ) { - endpointCallable(e, package, type, subtypes, name, signature) and - ext = "" and - input = e.getMaDInput() - } - - additional predicate sourceSpec( - Endpoint e, string package, string type, boolean subtypes, string name, string signature, - string ext, string output - ) { - endpointCallable(e, package, type, subtypes, name, signature) and - ext = "" and - output = e.getMaDOutput() - } - - /** - * Gets the related location for the given endpoint. - * - * The only related location we model is the the call expression surrounding to - * which the endpoint is either argument or qualifier (known as the call context). - */ - RelatedLocation getRelatedLocation(Endpoint e, RelatedLocationType type) { - type = CallContext() and - result = e.(CallArgument).getCall() - or - type = MethodDoc() and - result = e.getCallable().(Documentable).getJavadoc() - or - type = ClassDoc() and - result = e.getCallable().getDeclaringType().(Documentable).getJavadoc() - } -} - -/** - * Contains endpoints that are defined in QL code rather than as a MaD model. Ideally this predicate - * should be empty. - */ -private predicate isCustomSink(Endpoint e, string kind) { - e.asNode() instanceof QueryInjectionSink and kind = "sql" -} - -module CharacteristicsImpl = - SharedCharacteristics::SharedCharacteristics; - -class EndpointCharacteristic = CharacteristicsImpl::EndpointCharacteristic; - -class Endpoint = ApplicationCandidatesImpl::Endpoint; - -/* - * Predicates that are used to surface prompt examples and candidates for classification with an ML model. - */ - -/** - * A MetadataExtractor that extracts metadata for application mode. - */ -class ApplicationModeMetadataExtractor extends string { - ApplicationModeMetadataExtractor() { this = "ApplicationModeMetadataExtractor" } - - predicate hasMetadata( - Endpoint e, string package, string type, string subtypes, string name, string signature, - string input, string output, string isVarargsArray, string alreadyAiModeled, - string extensibleType - ) { - exists(Callable callable | e.getCallable() = callable | - (if exists(e.getMaDInput()) then input = e.getMaDInput() else input = "") and - (if exists(e.getMaDOutput()) then output = e.getMaDOutput() else output = "") and - package = callable.getDeclaringType().getPackage().getName() and - // we're using the erased types because the MaD convention is to not specify type parameters. - // Whether something is or isn't a sink doesn't usually depend on the type parameters. - type = callable.getDeclaringType().getErasure().(RefType).getNestedName() and - subtypes = AutomodelJavaUtil::considerSubtypes(callable).toString() and - name = callable.getName() and - signature = ExternalFlow::paramsString(callable) and - ( - if e instanceof ImplicitVarargsArray - then isVarargsArray = "true" - else isVarargsArray = "false" - ) and - extensibleType = e.getExtensibleType() - ) and - ( - not CharacteristicsImpl::isModeled(e, _, extensibleType, _) and alreadyAiModeled = "" - or - CharacteristicsImpl::isModeled(e, _, extensibleType, alreadyAiModeled) - ) - } -} - -/** - * Holds if the given `endpoint` should be considered a candidate for the `extensibleType`. - * - * The other parameters record various other properties of interest. - */ -predicate isCandidate( - Endpoint endpoint, string package, string type, string subtypes, string name, string signature, - string input, string output, string isVarargs, string extensibleType, string alreadyAiModeled -) { - CharacteristicsImpl::isCandidate(endpoint, _) and - not exists(CharacteristicsImpl::UninterestingToModelCharacteristic u | - u.appliesToEndpoint(endpoint) - ) and - any(ApplicationModeMetadataExtractor meta) - .hasMetadata(endpoint, package, type, subtypes, name, signature, input, output, isVarargs, - alreadyAiModeled, extensibleType) and - // If a node is already modeled in MaD, we don't include it as a candidate. Otherwise, we might include it as a - // candidate for query A, but the model will label it as a sink for one of the sink types of query B, for which it's - // already a known sink. This would result in overlap between our detected sinks and the pre-existing modeling. We - // assume that, if a sink has already been modeled in a MaD model, then it doesn't belong to any additional sink - // types, and we don't need to reexamine it. - alreadyAiModeled.matches(["", "%ai-%"]) and - AutomodelJavaUtil::includeAutomodelCandidate(package, type, name, signature) -} - -/** - * Holds if the given `endpoint` is a negative example for the `extensibleType` - * because of the `characteristic`. - * - * The other parameters record various other properties of interest. - */ -predicate isNegativeExample( - Endpoint endpoint, EndpointCharacteristic characteristic, float confidence, string package, - string type, string subtypes, string name, string signature, string input, string output, - string isVarargsArray, string extensibleType -) { - characteristic.appliesToEndpoint(endpoint) and - // the node is known not to be an endpoint of any appropriate type - forall(AutomodelEndpointTypes::EndpointType tp | - tp = CharacteristicsImpl::getAPotentialType(endpoint) - | - characteristic.hasImplications(tp, false, _) - ) and - // the lowest confidence across all endpoint types should be at least highConfidence - confidence = - min(float c | - characteristic.hasImplications(CharacteristicsImpl::getAPotentialType(endpoint), false, c) - ) and - confidence >= SharedCharacteristics::highConfidence() and - any(ApplicationModeMetadataExtractor meta) - .hasMetadata(endpoint, package, type, subtypes, name, signature, input, output, - isVarargsArray, _, extensibleType) and - // It's valid for a node to be both a potential source/sanitizer and a sink. We don't want to include such nodes - // as negative examples in the prompt, because they're ambiguous and might confuse the model, so we explicitly exclude them here. - not exists(EndpointCharacteristic characteristic2, float confidence2 | - characteristic2 != characteristic - | - characteristic2.appliesToEndpoint(endpoint) and - confidence2 >= SharedCharacteristics::maximalConfidence() and - characteristic2 - .hasImplications(CharacteristicsImpl::getAPotentialType(endpoint), true, confidence2) - ) -} - -/** - * Holds if the given `endpoint` is a positive example for the `endpointType`. - * - * The other parameters record various other properties of interest. - */ -predicate isPositiveExample( - Endpoint endpoint, string endpointType, string package, string type, string subtypes, string name, - string signature, string input, string output, string isVarargsArray, string extensibleType -) { - any(ApplicationModeMetadataExtractor meta) - .hasMetadata(endpoint, package, type, subtypes, name, signature, input, output, - isVarargsArray, _, extensibleType) and - CharacteristicsImpl::isKnownAs(endpoint, endpointType, _) and - exists(CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, CallContext())) -} - -/* - * EndpointCharacteristic classes that are specific to Automodel for Java. - */ - -/** - * A negative characteristic that indicates that parameters of an is-style boolean method should not be considered sinks. - * - * A sink is highly unlikely to be exploitable if its callable's name starts with `is` and the callable has a boolean return - * type (e.g. `isDirectory`). These kinds of calls normally do only checks, and appear before the proper call that does - * the dangerous/interesting thing, so we want the latter to be modeled as the sink. - * - * TODO: this might filter too much, it's possible that methods with more than one parameter contain interesting sinks - */ -private class UnexploitableIsCharacteristic extends CharacteristicsImpl::NotASinkCharacteristic { - UnexploitableIsCharacteristic() { this = "argument of is-style boolean method" } - - override predicate appliesToEndpoint(Endpoint e) { - e.getCallable().getName().matches("is%") and - e.getCallable().getReturnType() instanceof BooleanType and - not ApplicationCandidatesImpl::isSink(e, _, _) - } -} - -/** - * A negative characteristic that indicates that parameters of an existence-checking boolean method should not be - * considered sinks. - * - * A sink is highly unlikely to be exploitable if its callable's name is `exists` or `notExists` and the callable has a - * boolean return type. These kinds of calls normally do only checks, and appear before the proper call that does the - * dangerous/interesting thing, so we want the latter to be modeled as the sink. - */ -private class UnexploitableExistsCharacteristic extends CharacteristicsImpl::NotASinkCharacteristic { - UnexploitableExistsCharacteristic() { this = "argument of existence-checking boolean method" } - - override predicate appliesToEndpoint(Endpoint e) { - exists(Callable callable | callable = e.getCallable() | - callable.getName().toLowerCase() = ["exists", "notexists"] and - callable.getReturnType() instanceof BooleanType - ) - } -} - -/** - * A negative characteristic that indicates that parameters of an exception method or constructor should not be considered sinks, - * and its return value should not be considered a source. - */ -private class ExceptionCharacteristic extends CharacteristicsImpl::NeitherSourceNorSinkCharacteristic -{ - ExceptionCharacteristic() { this = "argument/result of exception-related method" } - - override predicate appliesToEndpoint(Endpoint e) { - e.getCallable().getDeclaringType().getASupertype*() instanceof TypeThrowable and - ( - e.getExtensibleType() = "sinkModel" and - not ApplicationCandidatesImpl::isSink(e, _, _) - or - e.getExtensibleType() = "sourceModel" and - not ApplicationCandidatesImpl::isSource(e, _, _) and - e.getMaDOutput() = "ReturnValue" - ) - } -} - -/** - * A negative characteristic that indicates that an endpoint is a MaD taint step. MaD modeled taint steps are global, - * so they are not sinks for any query. Non-MaD taint steps might be specific to a particular query, so we don't - * filter those out. - */ -private class IsMaDTaintStepCharacteristic extends CharacteristicsImpl::NotASinkCharacteristic { - IsMaDTaintStepCharacteristic() { this = "taint step" } - - override predicate appliesToEndpoint(Endpoint e) { - FlowSummaryImpl::Private::Steps::summaryThroughStepValue(e.asNode(), _, _) - or - FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(e.asNode(), _, _) - or - FlowSummaryImpl::Private::Steps::summaryGetterStep(e.asNode(), _, _, _) - or - FlowSummaryImpl::Private::Steps::summarySetterStep(e.asNode(), _, _, _) - } -} - -/** - * A call to a method that's known locally will not be considered as a candidate to model. - * - * The reason is that we would expect data/taint flow into the method implementation to uncover - * any sinks that are present there. - */ -private class LocalCall extends CharacteristicsImpl::UninterestingToModelCharacteristic { - LocalCall() { this = "local call" } - - override predicate appliesToEndpoint(Endpoint e) { - e.(CallArgument).getCallable().fromSource() - or - e.(MethodReturnValue).getCallable().fromSource() - } -} - -/** - * A characteristic that marks endpoints as uninteresting to model, according to the Java ModelExclusions module. - */ -private class ExcludedFromModeling extends CharacteristicsImpl::UninterestingToModelCharacteristic { - ExcludedFromModeling() { this = "excluded from modeling" } - - override predicate appliesToEndpoint(Endpoint e) { - ModelExclusions::isUninterestingForModels(e.getCallable()) - } -} - -/** - * A negative characteristic that filters out non-public methods. Non-public methods are not interesting to include in - * the standard Java modeling, because they cannot be called from outside the package. - */ -private class NonPublicMethodCharacteristic extends CharacteristicsImpl::UninterestingToModelCharacteristic -{ - NonPublicMethodCharacteristic() { this = "non-public method" } - - override predicate appliesToEndpoint(Endpoint e) { - exists(Callable c | c = e.getCallable() | not c.isPublic()) - } -} - -/** - * A negative characteristic that indicates that an endpoint is a non-sink argument to a method whose sinks have already - * been modeled _manually_. This is restricted to manual sinks only, because only during the manual process do we have - * the expectation that all sinks present in a method have been considered. - * - * WARNING: These endpoints should not be used as negative samples for training, because some sinks may have been missed - * when the method was modeled. Specifically, as we start using ATM to merge in new declarations, we can be less sure - * that a method with one argument modeled as a MaD sink has also had its remaining arguments manually reviewed. The - * ML model might have predicted argument 0 of some method to be a sink but not argument 1, when in fact argument 1 is - * also a sink. - */ -private class OtherArgumentToModeledMethodCharacteristic extends CharacteristicsImpl::LikelyNotASinkCharacteristic -{ - OtherArgumentToModeledMethodCharacteristic() { - this = "other argument to a method that has already been modeled manually" - } - - override predicate appliesToEndpoint(Endpoint e) { - not ApplicationCandidatesImpl::isSink(e, _, _) and - exists(CallArgument otherSink | - ApplicationCandidatesImpl::isSink(otherSink, _, "manual") and - e.(CallArgument).getCall() = otherSink.getCall() and - e != otherSink - ) - } -} - -/** - * Holds if the type of the given expression is annotated with `@FunctionalInterface`. - */ -predicate hasFunctionalInterfaceType(Expr e) { - exists(RefType tp | tp = e.getType().getErasure() | - tp.getAnAssociatedAnnotation().getType().hasQualifiedName("java.lang", "FunctionalInterface") - ) -} - -/** - * A characteristic that marks functional expression as likely not sinks. - * - * These expressions may well _contain_ sinks, but rarely are sinks themselves. - */ -private class FunctionValueCharacteristic extends CharacteristicsImpl::LikelyNotASinkCharacteristic { - FunctionValueCharacteristic() { this = "function value" } - - override predicate appliesToEndpoint(Endpoint e) { - exists(Expr expr | expr = e.asNode().asExpr() | - expr instanceof FunctionalExpr or hasFunctionalInterfaceType(expr) - ) - } -} - -/** - * A negative characteristic that indicates that an endpoint is not a `to` node for any known taint step. Such a node - * cannot be tainted, because taint can't flow into it. - * - * WARNING: These endpoints should not be used as negative samples for training, because they may include sinks for - * which our taint tracking modeling is incomplete. - */ -private class CannotBeTaintedCharacteristic extends CharacteristicsImpl::LikelyNotASinkCharacteristic -{ - CannotBeTaintedCharacteristic() { this = "cannot be tainted" } - - override predicate appliesToEndpoint(Endpoint e) { not this.isKnownOutNodeForStep(e) } - - /** - * Holds if the node `n` is known as the predecessor in a modeled flow step. - */ - private predicate isKnownOutNodeForStep(Endpoint e) { - e.asNode().asExpr() instanceof Call or // we just assume flow in that case - TaintTracking::localTaintStep(_, e.asNode()) or - FlowSummaryImpl::Private::Steps::summaryThroughStepValue(_, e.asNode(), _) or - FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(_, e.asNode(), _) or - FlowSummaryImpl::Private::Steps::summaryGetterStep(_, _, e.asNode(), _) or - FlowSummaryImpl::Private::Steps::summarySetterStep(_, _, e.asNode(), _) - } -} diff --git a/java/ql/automodel/src/AutomodelApplicationModeExtractCandidates.ql b/java/ql/automodel/src/AutomodelApplicationModeExtractCandidates.ql deleted file mode 100644 index a3fa8b9b46f..00000000000 --- a/java/ql/automodel/src/AutomodelApplicationModeExtractCandidates.ql +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Surfaces the endpoints that are not already known to be sinks, and are therefore used as candidates for - * classification with an ML model. - * - * Note: This query does not actually classify the endpoints using the model. - * - * @name Automodel candidates (application mode) - * @description A query to extract automodel candidates in application mode. - * @kind problem - * @problem.severity recommendation - * @id java/ml/extract-automodel-application-candidates - * @tags internal extract automodel application-mode candidates - */ - -import java -private import AutomodelApplicationModeCharacteristics -private import AutomodelJavaUtil - -/** - * Gets a sample of endpoints (of at most `limit` samples) with the given method signature. - * - * The main purpose of this helper predicate is to avoid selecting too many candidates, as this may - * cause the SARIF file to exceed the maximum size limit. - */ -bindingset[limit] -private Endpoint getSampleForSignature( - int limit, string package, string type, string subtypes, string name, string signature, - string input, string output, string isVarargs, string extensibleType, string alreadyAiModeled -) { - exists(int n, int num_endpoints, ApplicationModeMetadataExtractor meta | - num_endpoints = - count(Endpoint e | - meta.hasMetadata(e, package, type, subtypes, name, signature, input, output, isVarargs, - alreadyAiModeled, extensibleType) - ) - | - result = - rank[n](Endpoint e, Location loc | - loc = e.asTop().getLocation() and - meta.hasMetadata(e, package, type, subtypes, name, signature, input, output, isVarargs, - alreadyAiModeled, extensibleType) - | - e - order by - loc.getFile().getAbsolutePath(), loc.getStartLine(), loc.getStartColumn(), - loc.getEndLine(), loc.getEndColumn() - ) and - // To avoid selecting samples that are too close together (as the ranking above goes by file - // path first), we select `limit` evenly spaced samples from the ranked list of endpoints. By - // default this would always include the first sample, so we add a random-chosen prime offset - // to the first sample index, and reduce modulo the number of endpoints. - // Finally, we add 1 to the result, as ranking results in a 1-indexed relation. - n = 1 + (([0 .. limit - 1] * (num_endpoints / limit).floor() + 46337) % num_endpoints) - ) -} - -from - Endpoint endpoint, DollarAtString package, DollarAtString type, DollarAtString subtypes, - DollarAtString name, DollarAtString signature, DollarAtString input, DollarAtString output, - DollarAtString isVarargsArray, DollarAtString alreadyAiModeled, DollarAtString extensibleType -where - isCandidate(endpoint, package, type, subtypes, name, signature, input, output, isVarargsArray, - extensibleType, alreadyAiModeled) and - endpoint = - getSampleForSignature(9, package, type, subtypes, name, signature, input, output, - isVarargsArray, extensibleType, alreadyAiModeled) -select endpoint.asNode(), - "Related locations: $@, $@, $@." + "\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@.", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, CallContext()), "CallContext", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, MethodDoc()), "MethodDoc", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, ClassDoc()), "ClassDoc", // - package, "package", // - type, "type", // - subtypes, "subtypes", // - name, "name", // method name - signature, "signature", // - input, "input", // - output, "output", // - isVarargsArray, "isVarargsArray", // - alreadyAiModeled, "alreadyAiModeled", // - extensibleType, "extensibleType" diff --git a/java/ql/automodel/src/AutomodelApplicationModeExtractNegativeExamples.ql b/java/ql/automodel/src/AutomodelApplicationModeExtractNegativeExamples.ql deleted file mode 100644 index a399c413fa4..00000000000 --- a/java/ql/automodel/src/AutomodelApplicationModeExtractNegativeExamples.ql +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Surfaces endpoints that are non-sinks with high confidence, for use as negative examples in the prompt. - * - * @name Negative examples (application mode) - * @kind problem - * @problem.severity recommendation - * @id java/ml/extract-automodel-application-negative-examples - * @tags internal extract automodel application-mode negative examples - */ - -private import java -private import AutomodelApplicationModeCharacteristics -private import AutomodelEndpointTypes -private import AutomodelJavaUtil - -/** - * Gets a sample of endpoints (of at most `limit` samples) for which the given characteristic applies. - * - * The main purpose of this helper predicate is to avoid selecting too many samples, as this may - * cause the SARIF file to exceed the maximum size limit. - */ -bindingset[limit] -Endpoint getSampleForCharacteristic(EndpointCharacteristic c, int limit) { - exists(int n, int num_endpoints | num_endpoints = count(Endpoint e | c.appliesToEndpoint(e)) | - result = - rank[n](Endpoint e, Location loc | - loc = e.asTop().getLocation() and c.appliesToEndpoint(e) - | - e - order by - loc.getFile().getAbsolutePath(), loc.getStartLine(), loc.getStartColumn(), - loc.getEndLine(), loc.getEndColumn() - ) and - // To avoid selecting samples that are too close together (as the ranking above goes by file - // path first), we select `limit` evenly spaced samples from the ranked list of endpoints. By - // default this would always include the first sample, so we add a random-chosen prime offset - // to the first sample index, and reduce modulo the number of endpoints. - // Finally, we add 1 to the result, as ranking results in a 1-indexed relation. - n = 1 + (([0 .. limit - 1] * (num_endpoints / limit).floor() + 46337) % num_endpoints) - ) -} - -from - Endpoint endpoint, EndpointCharacteristic characteristic, float confidence, string message, - DollarAtString package, DollarAtString type, DollarAtString subtypes, DollarAtString name, - DollarAtString signature, DollarAtString input, DollarAtString output, - DollarAtString isVarargsArray, DollarAtString extensibleType -where - endpoint = getSampleForCharacteristic(characteristic, 100) and - isNegativeExample(endpoint, characteristic, confidence, package, type, subtypes, name, signature, - input, output, isVarargsArray, extensibleType) and - message = characteristic -select endpoint.asNode(), - message + "\nrelated locations: $@, $@, $@." + "\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@.", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, CallContext()), "CallContext", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, MethodDoc()), "MethodDoc", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, ClassDoc()), "ClassDoc", // - package, "package", // - type, "type", // - subtypes, "subtypes", // - name, "name", // - signature, "signature", // - input, "input", // - output, "output", // - isVarargsArray, "isVarargsArray", // - extensibleType, "extensibleType" diff --git a/java/ql/automodel/src/AutomodelApplicationModeExtractPositiveExamples.ql b/java/ql/automodel/src/AutomodelApplicationModeExtractPositiveExamples.ql deleted file mode 100644 index faf49b73fc1..00000000000 --- a/java/ql/automodel/src/AutomodelApplicationModeExtractPositiveExamples.ql +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Surfaces endpoints that are sinks with high confidence, for use as positive examples in the prompt. - * - * @name Positive examples (application mode) - * @kind problem - * @problem.severity recommendation - * @id java/ml/extract-automodel-application-positive-examples - * @tags internal extract automodel application-mode positive examples - */ - -private import AutomodelApplicationModeCharacteristics -private import AutomodelEndpointTypes -private import AutomodelJavaUtil - -from - Endpoint endpoint, EndpointType endpointType, ApplicationModeMetadataExtractor meta, - DollarAtString package, DollarAtString type, DollarAtString subtypes, DollarAtString name, - DollarAtString signature, DollarAtString input, DollarAtString output, - DollarAtString isVarargsArray, DollarAtString extensibleType -where - isPositiveExample(endpoint, endpointType, package, type, subtypes, name, signature, input, output, - isVarargsArray, extensibleType) -select endpoint.asNode(), - endpointType + "\nrelated locations: $@, $@, $@." + - "\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@.", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, CallContext()), "CallContext", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, MethodDoc()), "MethodDoc", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, ClassDoc()), "ClassDoc", // - package, "package", // - type, "type", // - subtypes, "subtypes", // - name, "name", // - signature, "signature", // - input, "input", // - output, "output", // - isVarargsArray, "isVarargsArray", // - extensibleType, "extensibleType" diff --git a/java/ql/automodel/src/AutomodelCandidateFilter.yml b/java/ql/automodel/src/AutomodelCandidateFilter.yml deleted file mode 100644 index c945ae3206f..00000000000 --- a/java/ql/automodel/src/AutomodelCandidateFilter.yml +++ /dev/null @@ -1,5 +0,0 @@ -extensions: - - addsTo: - pack: codeql/java-automodel-queries - extensible: automodelCandidateFilter - data: [] diff --git a/java/ql/automodel/src/AutomodelCountGeneratedSinks.ql b/java/ql/automodel/src/AutomodelCountGeneratedSinks.ql deleted file mode 100644 index 475e3753810..00000000000 --- a/java/ql/automodel/src/AutomodelCountGeneratedSinks.ql +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @name Number of instances of each sink model - * @description Counts the number of instances of `ai-generated` sink models. - * @kind table - * @id java/ml/metrics-count-instances-per-sink-model - * @tags internal automodel metrics - */ - -private import java -private import AutomodelAlertSinkUtil - -from int instanceCount, SinkModel s -where - instanceCount = s.getInstanceCount() and - instanceCount > 0 and - s.getProvenance() = "ai-generated" -select instanceCount, s.getPackage() as package, s.getType() as type, s.getSubtypes() as subtypes, - s.getName() as name, s.getSignature() as signature, s.getInput() as input, s.getExt() as ext, - s.getKind() as kind, s.getProvenance() as provenance order by instanceCount desc diff --git a/java/ql/automodel/src/AutomodelEndpointTypes.qll b/java/ql/automodel/src/AutomodelEndpointTypes.qll deleted file mode 100644 index f4f7bc8eb7b..00000000000 --- a/java/ql/automodel/src/AutomodelEndpointTypes.qll +++ /dev/null @@ -1,82 +0,0 @@ -/** - * For internal use only. - * - * Defines the set of classes that endpoint scoring models can predict. Endpoint scoring models must - * only predict classes defined within this file. This file is the source of truth for the integer - * representation of each of these classes. - */ - -/** A class that can be predicted by a classifier. */ -abstract class EndpointType extends string { - /** - * Holds when the string matches the name of the sink / source type. - */ - bindingset[this] - EndpointType() { any() } - - /** - * Gets the name of the sink/source kind for this endpoint type as used in models-as-data. - * - * See https://github.com/github/codeql/blob/44213f0144fdd54bb679ca48d68b28dcf820f7a8/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll#LL353C11-L357C31 - * for sink types, and https://github.com/github/codeql/blob/44213f0144fdd54bb679ca48d68b28dcf820f7a8/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll#L365 - * for source types. - */ - final string getKind() { result = this } -} - -/** A class for sink types that can be predicted by a classifier. */ -abstract class SinkType extends EndpointType { - bindingset[this] - SinkType() { any() } -} - -/** A sink relevant to the SQL injection query */ -class SqlInjectionSinkType extends SinkType { - SqlInjectionSinkType() { this = "sql-injection" } -} - -/** A sink relevant to the tainted path injection query. */ -class PathInjectionSinkType extends SinkType { - PathInjectionSinkType() { this = "path-injection" } -} - -/** A sink relevant to the SSRF query. */ -class RequestForgerySinkType extends SinkType { - RequestForgerySinkType() { this = "request-forgery" } -} - -/** A sink relevant to the command injection query. */ -class CommandInjectionSinkType extends SinkType { - CommandInjectionSinkType() { this = "command-injection" } -} - -/** A sink relevant to file storage. */ -class FileContentStoreSinkType extends SinkType { - FileContentStoreSinkType() { this = "file-content-store" } -} - -/** A sink relevant to HTML injection. */ -class HtmlInjectionSinkType extends SinkType { - HtmlInjectionSinkType() { this = "html-injection" } -} - -/** A sink relevant to LDAP injection. */ -class LdapInjectionSinkType extends SinkType { - LdapInjectionSinkType() { this = "ldap-injection" } -} - -/** A sink relevant to URL redirection. */ -class UrlRedirectionSinkType extends SinkType { - UrlRedirectionSinkType() { this = "url-redirection" } -} - -/** A class for source types that can be predicted by a classifier. */ -abstract class SourceType extends EndpointType { - bindingset[this] - SourceType() { any() } -} - -/** A source of remote data. */ -class RemoteSourceType extends SourceType { - RemoteSourceType() { this = "remote" } -} diff --git a/java/ql/automodel/src/AutomodelFrameworkModeCharacteristics.qll b/java/ql/automodel/src/AutomodelFrameworkModeCharacteristics.qll deleted file mode 100644 index 7f385a41d1e..00000000000 --- a/java/ql/automodel/src/AutomodelFrameworkModeCharacteristics.qll +++ /dev/null @@ -1,507 +0,0 @@ -/** - * For internal use only. - */ - -private import java -private import semmle.code.Location as Location -private import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.TaintTracking -private import semmle.code.java.dataflow.ExternalFlow as ExternalFlow -private import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl -private import semmle.code.java.security.ExternalAPIs as ExternalAPIs -private import semmle.code.java.Expr as Expr -private import semmle.code.java.security.QueryInjection -private import semmle.code.java.security.RequestForgery -private import semmle.code.java.dataflow.internal.ModelExclusions as ModelExclusions -private import AutomodelJavaUtil as AutomodelJavaUtil -import AutomodelSharedCharacteristics as SharedCharacteristics -import AutomodelEndpointTypes as AutomodelEndpointTypes - -newtype JavaRelatedLocationType = - MethodDoc() or - ClassDoc() - -newtype TFrameworkModeEndpoint = - TExplicitParameter(Parameter p) { - AutomodelJavaUtil::isFromSource(p) and - not AutomodelJavaUtil::isUnexploitableType(p.getType()) - } or - TQualifier(Callable c) { AutomodelJavaUtil::isFromSource(c) and not c instanceof Constructor } or - TReturnValue(Callable c) { - AutomodelJavaUtil::isFromSource(c) and - c instanceof Constructor - or - AutomodelJavaUtil::isFromSource(c) and - c instanceof Method and - not AutomodelJavaUtil::isUnexploitableType(c.getReturnType()) - } or - TOverridableParameter(Method m, Parameter p) { - AutomodelJavaUtil::isFromSource(p) and - not AutomodelJavaUtil::isUnexploitableType(p.getType()) and - p.getCallable() = m and - m instanceof ModelExclusions::ModelApi and - AutomodelJavaUtil::isOverridable(m) - } or - TOverridableQualifier(Method m) { - AutomodelJavaUtil::isFromSource(m) and - m instanceof ModelExclusions::ModelApi and - AutomodelJavaUtil::isOverridable(m) - } - -/** - * A framework mode endpoint. - */ -abstract class FrameworkModeEndpoint extends TFrameworkModeEndpoint { - /** - * Gets the input (if any) for this endpoint, eg.: `Argument[0]`. - * - * For endpoints that are source candidates, this will be `none()`. - */ - abstract string getMaDInput(); - - /** - * Gets the output (if any) for this endpoint, eg.: `ReturnValue`. - * - * For endpoints that are sink candidates, this will be `none()`. - */ - abstract string getMaDOutput(); - - /** - * Returns the name of the parameter of the endpoint. - */ - abstract string getParamName(); - - /** - * Returns the callable that contains the endpoint. - */ - abstract Callable getCallable(); - - abstract Top asTop(); - - abstract string getExtensibleType(); - - string toString() { result = this.asTop().toString() } - - Location getLocation() { result = this.asTop().getLocation() } -} - -class ExplicitParameterEndpoint extends FrameworkModeEndpoint, TExplicitParameter { - Parameter param; - - ExplicitParameterEndpoint() { this = TExplicitParameter(param) and param.fromSource() } - - override string getMaDInput() { result = "Argument[" + param.getPosition() + "]" } - - override string getMaDOutput() { none() } - - override string getParamName() { result = param.getName() } - - override Callable getCallable() { result = param.getCallable() } - - override Top asTop() { result = param } - - override string getExtensibleType() { result = "sinkModel" } -} - -class QualifierEndpoint extends FrameworkModeEndpoint, TQualifier { - Callable callable; - - QualifierEndpoint() { - this = TQualifier(callable) and not callable.isStatic() and callable.fromSource() - } - - override string getMaDInput() { result = "Argument[this]" } - - override string getMaDOutput() { none() } - - override string getParamName() { result = "this" } - - override Callable getCallable() { result = callable } - - override Top asTop() { result = callable } - - override string getExtensibleType() { result = "sinkModel" } -} - -class ReturnValue extends FrameworkModeEndpoint, TReturnValue { - Callable callable; - - ReturnValue() { this = TReturnValue(callable) and callable.fromSource() } - - override string getMaDInput() { none() } - - override string getMaDOutput() { result = "ReturnValue" } - - override string getParamName() { none() } - - override Callable getCallable() { result = callable } - - override Top asTop() { result = callable } - - override string getExtensibleType() { result = "sourceModel" } -} - -class OverridableParameter extends FrameworkModeEndpoint, TOverridableParameter { - Method method; - Parameter param; - - OverridableParameter() { this = TOverridableParameter(method, param) } - - override string getMaDInput() { none() } - - override string getMaDOutput() { result = "Parameter[" + param.getPosition() + "]" } - - override string getParamName() { result = param.getName() } - - override Callable getCallable() { result = method } - - override Top asTop() { result = param } - - override string getExtensibleType() { result = "sourceModel" } -} - -class OverridableQualifier extends FrameworkModeEndpoint, TOverridableQualifier { - Method m; - - OverridableQualifier() { this = TOverridableQualifier(m) } - - override string getMaDInput() { none() } - - override string getMaDOutput() { result = "Parameter[this]" } - - override string getParamName() { result = "this" } - - override Callable getCallable() { result = m } - - override Top asTop() { result = m } - - override string getExtensibleType() { result = "sourceModel" } -} - -/** - * A candidates implementation for framework mode. - * - * Some important notes: - * - This mode is using parameters as endpoints. - * - Sink- and neutral-information is being used from MaD models. - * - When available, we use method- and class-java-docs as related locations. - */ -module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig { - // for documentation of the implementations here, see the QLDoc in the CandidateSig signature module. - class Endpoint = FrameworkModeEndpoint; - - class EndpointType = AutomodelEndpointTypes::EndpointType; - - class SinkType = AutomodelEndpointTypes::SinkType; - - class SourceType = AutomodelEndpointTypes::SourceType; - - class RelatedLocation = Location::Top; - - class RelatedLocationType = JavaRelatedLocationType; - - // Sanitizers are currently not modeled in MaD. TODO: check if this has large negative impact. - predicate isSanitizer(Endpoint e, EndpointType t) { none() } - - RelatedLocation asLocation(Endpoint e) { result = e.asTop() } - - predicate isKnownKind = AutomodelJavaUtil::isKnownKind/2; - - predicate isSink(Endpoint e, string kind, string provenance) { - exists( - string package, string type, boolean subtypes, string name, string signature, string ext, - string input - | - sinkSpec(e, package, type, subtypes, name, signature, ext, input) and - ExternalFlow::sinkModel(package, type, subtypes, name, [signature, ""], ext, input, kind, - provenance, _) - ) - } - - predicate isSource(Endpoint e, string kind, string provenance) { - exists( - string package, string type, boolean subtypes, string name, string signature, string ext, - string output - | - sourceSpec(e, package, type, subtypes, name, signature, ext, output) and - ExternalFlow::sourceModel(package, type, subtypes, name, [signature, ""], ext, output, kind, - provenance, _) - ) - } - - predicate isNeutral(Endpoint e) { - exists(string package, string type, string name, string signature, string endpointType | - sinkSpec(e, package, type, _, name, signature, _, _) and - endpointType = "sink" - or - sourceSpec(e, package, type, _, name, signature, _, _) and - endpointType = "source" - | - ExternalFlow::neutralModel(package, type, name, [signature, ""], endpointType, _) - ) - } - - /** - * Holds if the endpoint concerns a callable with the given package, type, name and signature. - * - * If `subtypes` is `false`, only the exact callable is considered. If `true`, the callable and - * all its overrides are considered. - */ - additional predicate endpointCallable( - Endpoint e, string package, string type, boolean subtypes, string name, string signature - ) { - exists(Callable c | - c = e.getCallable() and subtypes in [true, false] - or - e.getCallable().(Method).getSourceDeclaration().overrides+(c) and subtypes = true - | - c.hasQualifiedName(package, type, name) and - signature = ExternalFlow::paramsString(c) - ) - } - - additional predicate sinkSpec( - Endpoint e, string package, string type, boolean subtypes, string name, string signature, - string ext, string input - ) { - endpointCallable(e, package, type, subtypes, name, signature) and - ext = "" and - input = e.getMaDInput() - } - - additional predicate sourceSpec( - Endpoint e, string package, string type, boolean subtypes, string name, string signature, - string ext, string output - ) { - endpointCallable(e, package, type, subtypes, name, signature) and - ext = "" and - output = e.getMaDOutput() - } - - /** - * Gets the related location for the given endpoint. - * - * Related locations can be JavaDoc comments of the class or the method. - */ - RelatedLocation getRelatedLocation(Endpoint e, RelatedLocationType type) { - type = MethodDoc() and - result = e.getCallable().(Documentable).getJavadoc() - or - type = ClassDoc() and - result = e.getCallable().getDeclaringType().(Documentable).getJavadoc() - } -} - -module CharacteristicsImpl = SharedCharacteristics::SharedCharacteristics; - -class EndpointCharacteristic = CharacteristicsImpl::EndpointCharacteristic; - -class Endpoint = FrameworkCandidatesImpl::Endpoint; - -/* - * Predicates that are used to surface prompt examples and candidates for classification with an ML model. - */ - -/** - * A MetadataExtractor that extracts metadata for framework mode. - */ -class FrameworkModeMetadataExtractor extends string { - FrameworkModeMetadataExtractor() { this = "FrameworkModeMetadataExtractor" } - - predicate hasMetadata( - Endpoint e, string package, string type, string subtypes, string name, string signature, - string input, string output, string parameterName, string alreadyAiModeled, - string extensibleType - ) { - exists(Callable callable | e.getCallable() = callable | - (if exists(e.getMaDInput()) then input = e.getMaDInput() else input = "") and - (if exists(e.getMaDOutput()) then output = e.getMaDOutput() else output = "") and - package = callable.getDeclaringType().getPackage().getName() and - // we're using the erased types because the MaD convention is to not specify type parameters. - // Whether something is or isn't a sink doesn't usually depend on the type parameters. - type = callable.getDeclaringType().getErasure().(RefType).getNestedName() and - subtypes = AutomodelJavaUtil::considerSubtypes(callable).toString() and - name = callable.getName() and - signature = ExternalFlow::paramsString(callable) and - (if exists(e.getParamName()) then parameterName = e.getParamName() else parameterName = "") and - e.getExtensibleType() = extensibleType - ) and - ( - not CharacteristicsImpl::isModeled(e, _, extensibleType, _) and alreadyAiModeled = "" - or - CharacteristicsImpl::isModeled(e, _, extensibleType, alreadyAiModeled) - ) - } -} - -/** - * Holds if the given `endpoint` should be considered a candidate for the `extensibleType`. - * - * The other parameters record various other properties of interest. - */ -predicate isCandidate( - Endpoint endpoint, string package, string type, string subtypes, string name, string signature, - string input, string output, string parameterName, string extensibleType, string alreadyAiModeled -) { - CharacteristicsImpl::isCandidate(endpoint, _) and - not exists(CharacteristicsImpl::UninterestingToModelCharacteristic u | - u.appliesToEndpoint(endpoint) - ) and - any(FrameworkModeMetadataExtractor meta) - .hasMetadata(endpoint, package, type, subtypes, name, signature, input, output, parameterName, - alreadyAiModeled, extensibleType) and - // If a node is already modeled in MaD, we don't include it as a candidate. Otherwise, we might include it as a - // candidate for query A, but the model will label it as a sink for one of the sink types of query B, for which it's - // already a known sink. This would result in overlap between our detected sinks and the pre-existing modeling. We - // assume that, if a sink has already been modeled in a MaD model, then it doesn't belong to any additional sink - // types, and we don't need to reexamine it. - alreadyAiModeled.matches(["", "%ai-%"]) and - AutomodelJavaUtil::includeAutomodelCandidate(package, type, name, signature) -} - -/** - * Holds if the given `endpoint` is a negative example for the `extensibleType` - * because of the `characteristic`. - * - * The other parameters record various other properties of interest. - */ -predicate isNegativeExample( - Endpoint endpoint, EndpointCharacteristic characteristic, float confidence, string package, - string type, string subtypes, string name, string signature, string input, string output, - string parameterName, string extensibleType -) { - characteristic.appliesToEndpoint(endpoint) and - // the node is known not to be an endpoint of any appropriate type - forall(AutomodelEndpointTypes::EndpointType tp | - tp = CharacteristicsImpl::getAPotentialType(endpoint) - | - characteristic.hasImplications(tp, false, _) - ) and - // the lowest confidence across all endpoint types should be at least highConfidence - confidence = - min(float c | - characteristic.hasImplications(CharacteristicsImpl::getAPotentialType(endpoint), false, c) - ) and - confidence >= SharedCharacteristics::highConfidence() and - any(FrameworkModeMetadataExtractor meta) - .hasMetadata(endpoint, package, type, subtypes, name, signature, input, output, parameterName, - _, extensibleType) and - // It's valid for a node to be both a potential source/sanitizer and a sink. We don't want to include such nodes - // as negative examples in the prompt, because they're ambiguous and might confuse the model, so we explicitly exclude them here. - not exists(EndpointCharacteristic characteristic2, float confidence2 | - characteristic2 != characteristic - | - characteristic2.appliesToEndpoint(endpoint) and - confidence2 >= SharedCharacteristics::maximalConfidence() and - characteristic2 - .hasImplications(CharacteristicsImpl::getAPotentialType(endpoint), true, confidence2) - ) -} - -/** - * Holds if the given `endpoint` is a positive example for the `endpointType`. - * - * The other parameters record various other properties of interest. - */ -predicate isPositiveExample( - Endpoint endpoint, string endpointType, string package, string type, string subtypes, string name, - string signature, string input, string output, string parameterName, string extensibleType -) { - any(FrameworkModeMetadataExtractor meta) - .hasMetadata(endpoint, package, type, subtypes, name, signature, input, output, parameterName, - _, extensibleType) and - CharacteristicsImpl::isKnownAs(endpoint, endpointType, _) -} - -/* - * EndpointCharacteristic classes that are specific to Automodel for Java. - */ - -/** - * A negative characteristic that indicates that parameters of an is-style boolean method should not be considered sinks, - * and its return value should not be considered a source. - * - * A sink is highly unlikely to be exploitable if its callable's name starts with `is` and the callable has a boolean return - * type (e.g. `isDirectory`). These kinds of calls normally do only checks, and appear before the proper call that does - * the dangerous/interesting thing, so we want the latter to be modeled as the sink. - * - * TODO: this might filter too much, it's possible that methods with more than one parameter contain interesting sinks - */ -private class UnexploitableIsCharacteristic extends CharacteristicsImpl::NeitherSourceNorSinkCharacteristic -{ - UnexploitableIsCharacteristic() { this = "argument of is-style boolean method" } - - override predicate appliesToEndpoint(Endpoint e) { - e.getCallable().getName().matches("is%") and - e.getCallable().getReturnType() instanceof BooleanType and - ( - e.getExtensibleType() = "sinkModel" and - not FrameworkCandidatesImpl::isSink(e, _, _) - or - e.getExtensibleType() = "sourceModel" and - not FrameworkCandidatesImpl::isSource(e, _, _) and - e.getMaDOutput() = "ReturnValue" - ) - } -} - -/** - * A negative characteristic that indicates that parameters of an existence-checking boolean method should not be - * considered sinks, and its return value should not be considered a source. - * - * A sink is highly unlikely to be exploitable if its callable's name is `exists` or `notExists` and the callable has a - * boolean return type. These kinds of calls normally do only checks, and appear before the proper call that does the - * dangerous/interesting thing, so we want the latter to be modeled as the sink. - */ -private class UnexploitableExistsCharacteristic extends CharacteristicsImpl::NeitherSourceNorSinkCharacteristic -{ - UnexploitableExistsCharacteristic() { this = "argument of existence-checking boolean method" } - - override predicate appliesToEndpoint(Endpoint e) { - exists(Callable callable | - callable = e.getCallable() and - callable.getName().toLowerCase() = ["exists", "notexists"] and - callable.getReturnType() instanceof BooleanType - | - e.getExtensibleType() = "sinkModel" and - not FrameworkCandidatesImpl::isSink(e, _, _) - or - e.getExtensibleType() = "sourceModel" and - not FrameworkCandidatesImpl::isSource(e, _, _) and - e.getMaDOutput() = "ReturnValue" - ) - } -} - -/** - * A negative characteristic that indicates that parameters of an exception method or constructor should not be considered sinks, - * and its return value should not be considered a source. - */ -private class ExceptionCharacteristic extends CharacteristicsImpl::NeitherSourceNorSinkCharacteristic -{ - ExceptionCharacteristic() { this = "argument/result of exception-related method" } - - override predicate appliesToEndpoint(Endpoint e) { - e.getCallable().getDeclaringType().getASupertype*() instanceof TypeThrowable and - ( - e.getExtensibleType() = "sinkModel" and - not FrameworkCandidatesImpl::isSink(e, _, _) - or - e.getExtensibleType() = "sourceModel" and - not FrameworkCandidatesImpl::isSource(e, _, _) and - e.getMaDOutput() = "ReturnValue" - ) - } -} - -/** - * A characteristic that limits candidates to parameters of methods that are recognized as `ModelApi`, iow., APIs that - * are considered worth modeling. - */ -private class NotAModelApi extends CharacteristicsImpl::UninterestingToModelCharacteristic { - NotAModelApi() { this = "not a model API" } - - override predicate appliesToEndpoint(Endpoint e) { - not e.getCallable() instanceof ModelExclusions::ModelApi - } -} diff --git a/java/ql/automodel/src/AutomodelFrameworkModeExtractCandidates.ql b/java/ql/automodel/src/AutomodelFrameworkModeExtractCandidates.ql deleted file mode 100644 index 83683b4e78f..00000000000 --- a/java/ql/automodel/src/AutomodelFrameworkModeExtractCandidates.ql +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Surfaces the endpoints that are not already known to be sinks, and are therefore used as candidates for - * classification with an ML model. - * - * Note: This query does not actually classify the endpoints using the model. - * - * @name Automodel candidates (framework mode) - * @description A query to extract automodel candidates in framework mode. - * @kind problem - * @problem.severity recommendation - * @id java/ml/extract-automodel-framework-candidates - * @tags internal extract automodel framework-mode candidates - */ - -private import AutomodelFrameworkModeCharacteristics -private import AutomodelJavaUtil - -from - Endpoint endpoint, DollarAtString package, DollarAtString type, DollarAtString subtypes, - DollarAtString name, DollarAtString signature, DollarAtString input, DollarAtString output, - DollarAtString parameterName, DollarAtString alreadyAiModeled, DollarAtString extensibleType -where - isCandidate(endpoint, package, type, subtypes, name, signature, input, output, parameterName, - extensibleType, alreadyAiModeled) -select endpoint, - "Related locations: $@, $@." + "\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@.", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, MethodDoc()), "MethodDoc", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, ClassDoc()), "ClassDoc", // - package, "package", // - type, "type", // - subtypes, "subtypes", // - name, "name", // - signature, "signature", // - input, "input", // - output, "output", // - parameterName, "parameterName", // - alreadyAiModeled, "alreadyAiModeled", // - extensibleType, "extensibleType" diff --git a/java/ql/automodel/src/AutomodelFrameworkModeExtractNegativeExamples.ql b/java/ql/automodel/src/AutomodelFrameworkModeExtractNegativeExamples.ql deleted file mode 100644 index 05e5951b061..00000000000 --- a/java/ql/automodel/src/AutomodelFrameworkModeExtractNegativeExamples.ql +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Surfaces endpoints that are non-sinks with high confidence, for use as negative examples in the prompt. - * - * @name Negative examples (framework mode) - * @kind problem - * @problem.severity recommendation - * @id java/ml/extract-automodel-framework-negative-examples - * @tags internal extract automodel framework-mode negative examples - */ - -private import AutomodelFrameworkModeCharacteristics -private import AutomodelEndpointTypes -private import AutomodelJavaUtil - -from - Endpoint endpoint, EndpointCharacteristic characteristic, float confidence, - DollarAtString package, DollarAtString type, DollarAtString subtypes, DollarAtString name, - DollarAtString signature, DollarAtString input, DollarAtString output, - DollarAtString parameterName, DollarAtString extensibleType -where - isNegativeExample(endpoint, characteristic, confidence, package, type, subtypes, name, signature, - input, output, parameterName, extensibleType) -select endpoint, - characteristic + "\nrelated locations: $@, $@." + - "\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@.", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, MethodDoc()), "MethodDoc", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, ClassDoc()), "ClassDoc", // - package, "package", // - type, "type", // - subtypes, "subtypes", // - name, "name", // - signature, "signature", // - input, "input", // - output, "output", // - parameterName, "parameterName", // - extensibleType, "extensibleType" diff --git a/java/ql/automodel/src/AutomodelFrameworkModeExtractPositiveExamples.ql b/java/ql/automodel/src/AutomodelFrameworkModeExtractPositiveExamples.ql deleted file mode 100644 index 7cb023949ed..00000000000 --- a/java/ql/automodel/src/AutomodelFrameworkModeExtractPositiveExamples.ql +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Surfaces endpoints that are sinks with high confidence, for use as positive examples in the prompt. - * - * @name Positive examples (framework mode) - * @kind problem - * @problem.severity recommendation - * @id java/ml/extract-automodel-framework-positive-examples - * @tags internal extract automodel framework-mode positive examples - */ - -private import AutomodelFrameworkModeCharacteristics -private import AutomodelEndpointTypes -private import AutomodelJavaUtil - -from - Endpoint endpoint, EndpointType endpointType, DollarAtString package, DollarAtString type, - DollarAtString subtypes, DollarAtString name, DollarAtString signature, DollarAtString input, - DollarAtString output, DollarAtString parameterName, DollarAtString extensibleType -where - isPositiveExample(endpoint, endpointType, package, type, subtypes, name, signature, input, output, - parameterName, extensibleType) -select endpoint, - endpointType + "\nrelated locations: $@, $@." + "\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@.", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, MethodDoc()), "MethodDoc", // - CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, ClassDoc()), "ClassDoc", // - package, "package", // - type, "type", // - subtypes, "subtypes", // - name, "name", // - signature, "signature", // - input, "input", // - output, "output", // - parameterName, "parameterName", // - extensibleType, "extensibleType" diff --git a/java/ql/automodel/src/AutomodelJavaUtil.qll b/java/ql/automodel/src/AutomodelJavaUtil.qll deleted file mode 100644 index 368fb172483..00000000000 --- a/java/ql/automodel/src/AutomodelJavaUtil.qll +++ /dev/null @@ -1,111 +0,0 @@ -private import java -private import AutomodelEndpointTypes as AutomodelEndpointTypes - -/** - * A helper class to represent a string value that can be returned by a query using $@ notation. - * - * It extends `string`, but adds a mock `hasLocationInfo` method that returns the string itself as the file name. - * - * Use this, when you want to return a string value from a query using $@ notation - the string value - * will be included in the sarif file. - * - * - * Background information on `hasLocationInfo`: - * https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-location-information - */ -class DollarAtString extends string { - bindingset[this] - DollarAtString() { any() } - - bindingset[this] - predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { - path = this and sl = 1 and sc = 1 and el = 1 and ec = 1 - } -} - -/** - * Holds for all combinations of MaD kinds (`kind`) and their human readable - * descriptions. - */ -predicate isKnownKind(string kind, AutomodelEndpointTypes::EndpointType type) { - kind = type.getKind() -} - -/** - * By convention, the subtypes property of the MaD declaration should only be - * true when there _can_ exist any subtypes with a different implementation. - * - * It would technically be ok to always use the value 'true', but this would - * break convention. - */ -pragma[nomagic] -boolean considerSubtypes(Callable callable) { - if - callable.isStatic() or - callable.getDeclaringType().isStatic() or - callable.isFinal() or - callable.getDeclaringType().isFinal() - then result = false - else result = true -} - -/** - * Holds if the given package, type, name and signature is a candidate for automodeling. - * - * This predicate is extensible, so that different endpoints can be selected at runtime. - */ -extensible predicate automodelCandidateFilter( - string package, string type, string name, string signature -); - -/** - * Holds if the given package, type, name and signature is a candidate for automodeling. - * - * This relies on an extensible predicate, and if that is not supplied then - * all endpoints are considered candidates. - */ -bindingset[package, type, name, signature] -predicate includeAutomodelCandidate(string package, string type, string name, string signature) { - not automodelCandidateFilter(_, _, _, _) or - automodelCandidateFilter(package, type, name, signature) -} - -/** - * Holds if the given program element corresponds to a piece of source code, - * that is, it is not compiler-generated. - * - * Note: This is a stricter check than `Element::fromSource`, which simply - * checks whether the element is in a source file as opposed to a JAR file. - * There can be compiler-generated elements in source files (especially for - * Kotlin), which we also want to exclude. - */ -predicate isFromSource(Element e) { - // from a source file (not a JAR) - e.fromSource() and - // not explicitly marked as compiler-generated - not e.isCompilerGenerated() and - // does not have a dummy location - not e.hasLocationInfo(_, 0, 0, 0, 0) -} - -/** - * Holds if taint cannot flow through the given type (because it is a numeric - * type or some other type with a fixed set of values). - */ -predicate isUnexploitableType(Type tp) { - tp instanceof PrimitiveType or - tp instanceof BoxedType or - tp instanceof NumberType or - tp instanceof VoidType -} - -/** - * Holds if the given method can be overridden, that is, it is not final, - * static, or private. - */ -predicate isOverridable(Method m) { - not m.getDeclaringType().isFinal() and - not m.isFinal() and - not m.isStatic() and - not m.isPrivate() -} diff --git a/java/ql/automodel/src/AutomodelSharedCharacteristics.qll b/java/ql/automodel/src/AutomodelSharedCharacteristics.qll deleted file mode 100644 index 273c5d30dec..00000000000 --- a/java/ql/automodel/src/AutomodelSharedCharacteristics.qll +++ /dev/null @@ -1,412 +0,0 @@ -float maximalConfidence() { result = 1.0 } - -float highConfidence() { result = 0.9 } - -float mediumConfidence() { result = 0.6 } - -/** - * A specification of how to instantiate the shared characteristics for a given candidate class. - * - * The `CandidateSig` implementation specifies a type to use for Endpoints (eg., `ParameterNode`), as well as a type - * to label endpoint classes (the `EndpointType`). One of the endpoint classes needs to be a 'negative' class, meaning - * "not any of the other known endpoint types". - */ -signature module CandidateSig { - /** - * An endpoint is a potential candidate for modeling. This will typically be bound to the language's - * DataFlow node class, or a subtype thereof. - */ - class Endpoint { - /** - * Gets the kind of this endpoint, either "sourceModel" or "sinkModel". - */ - string getExtensibleType(); - - /** - * Gets a string representation of this endpoint. - */ - string toString(); - } - - /** - * A related location for an endpoint. This will typically be bound to the supertype of all AST nodes (eg., `Top`). - */ - class RelatedLocation; - - /** - * A label for a related location. - * - * Eg., method-doc, class-doc, etc. - */ - class RelatedLocationType; - - /** - * An endpoint type considered by this specification. - */ - class EndpointType extends string; - - /** - * A sink endpoint type considered by this specification. - */ - class SinkType extends EndpointType; - - /** - * A source endpoint type considered by this specification. - */ - class SourceType extends EndpointType; - - /** - * Gets the endpoint as a location. - * - * This is a utility function to convert an endpoint to its corresponding location. - */ - RelatedLocation asLocation(Endpoint e); - - /** - * Defines what MaD kinds are known, and what endpoint type they correspond to. - */ - predicate isKnownKind(string kind, EndpointType type); - - /** - * Holds if `e` is a flow sanitizer, and has type `t`. - */ - predicate isSanitizer(Endpoint e, EndpointType t); - - /** - * Holds if `e` is a sink with the label `kind`, and provenance `provenance`. - */ - predicate isSink(Endpoint e, string kind, string provenance); - - /** - * Holds if `e` is a source with the label `kind`, and provenance `provenance`. - */ - predicate isSource(Endpoint e, string kind, string provenance); - - /** - * Holds if `e` is not a source or sink of any kind. - */ - predicate isNeutral(Endpoint e); - - /** - * Gets a related location. - * - * A related location is a source code location that may hold extra information about an endpoint that can be useful - * to the machine learning model. - * - * For example, a related location for a method call may be the documentation comment of a method. - */ - RelatedLocation getRelatedLocation(Endpoint e, RelatedLocationType name); -} - -/** - * A set of shared characteristics for a given candidate class. - * - * This module is language-agnostic, although the `CandidateSig` module will be language-specific. - * - * The language specific implementation can also further extend the behavior of this module by adding additional - * implementations of endpoint characteristics exported by this module. - */ -module SharedCharacteristics { - predicate isSink = Candidate::isSink/3; - - predicate isNeutral = Candidate::isNeutral/1; - - predicate isModeled(Candidate::Endpoint e, string kind, string extensibleKind, string provenance) { - Candidate::isSink(e, kind, provenance) and extensibleKind = "sinkModel" - or - Candidate::isSource(e, kind, provenance) and extensibleKind = "sourceModel" - } - - /** - * Holds if `endpoint` is modeled as `endpointType`. - */ - predicate isKnownAs( - Candidate::Endpoint endpoint, Candidate::EndpointType endpointType, - EndpointCharacteristic characteristic - ) { - // If the list of characteristics includes positive indicators with maximal confidence for this class, then it's a - // known sink for the class. - characteristic.appliesToEndpoint(endpoint) and - characteristic.hasImplications(endpointType, true, maximalConfidence()) - } - - /** - * Gets a potential type of this endpoint to make sure that sources are - * associated with source types and sinks with sink types. - */ - Candidate::EndpointType getAPotentialType(Candidate::Endpoint endpoint) { - endpoint.getExtensibleType() = "sourceModel" and - result instanceof Candidate::SourceType - or - endpoint.getExtensibleType() = "sinkModel" and - result instanceof Candidate::SinkType - } - - /** - * Holds if the given `endpoint` should be considered as a candidate for type `endpointType`, - * and classified by the ML model. - * - * A candidate is an endpoint that cannot be excluded from `endpointType` based on its characteristics. - */ - predicate isCandidate(Candidate::Endpoint endpoint, Candidate::EndpointType endpointType) { - endpointType = getAPotentialType(endpoint) and - not exists(getAnExcludingCharacteristic(endpoint, endpointType)) - } - - /** - * Gets the related location of `e` with name `name`, if it exists. - * Otherwise, gets the candidate itself. - */ - Candidate::RelatedLocation getRelatedLocationOrCandidate( - Candidate::Endpoint e, Candidate::RelatedLocationType type - ) { - if exists(Candidate::getRelatedLocation(e, type)) - then result = Candidate::getRelatedLocation(e, type) - else result = Candidate::asLocation(e) - } - - /** - * Gets a characteristics that disbar `endpoint` from being a candidate for `endpointType` - * with at least medium confidence. - */ - EndpointCharacteristic getAnExcludingCharacteristic( - Candidate::Endpoint endpoint, Candidate::EndpointType endpointType - ) { - result.appliesToEndpoint(endpoint) and - exists(float confidence | - confidence >= mediumConfidence() and - result.hasImplications(endpointType, false, confidence) - ) - } - - /** - * A set of characteristics that a particular endpoint might have. This set of characteristics is used to make decisions - * about whether to include the endpoint in the training set and with what kind, as well as whether to score the - * endpoint at inference time. - */ - abstract class EndpointCharacteristic extends string { - /** - * Holds for the string that is the name of the characteristic. This should describe some property of an endpoint - * that is meaningful for determining whether it's a sink, and if so, of which sink type. - */ - bindingset[this] - EndpointCharacteristic() { any() } - - /** - * Holds for endpoints that have this characteristic. - */ - abstract predicate appliesToEndpoint(Candidate::Endpoint n); - - /** - * This predicate describes what the characteristic tells us about an endpoint. - * - * Params: - * endpointType: The sink/source type. - * isPositiveIndicator: If true, this characteristic indicates that this endpoint _is_ a member of the class; if - * false, it indicates that it _isn't_ a member of the class. - * confidence: A float in [0, 1], which tells us how strong an indicator this characteristic is for the endpoint - * belonging / not belonging to the given class. A confidence near zero means this characteristic is a very weak - * indicator of whether or not the endpoint belongs to the class. A confidence of 1 means that all endpoints with - * this characteristic definitively do/don't belong to the class. - */ - abstract predicate hasImplications( - Candidate::EndpointType endpointType, boolean isPositiveIndicator, float confidence - ); - - /** Indicators with confidence at or above this threshold are considered to be high-confidence indicators. */ - final float getHighConfidenceThreshold() { result = 0.8 } - } - - /** - * A high-confidence characteristic that indicates that an endpoint is a sink of a specified type. These endpoints can - * be used as positive samples for training or for a few-shot prompt. - */ - abstract class SinkCharacteristic extends EndpointCharacteristic { - bindingset[this] - SinkCharacteristic() { any() } - - abstract Candidate::EndpointType getSinkType(); - - final override predicate hasImplications( - Candidate::EndpointType endpointType, boolean isPositiveIndicator, float confidence - ) { - endpointType = this.getSinkType() and - isPositiveIndicator = true and - confidence = maximalConfidence() - } - } - - /** - * A high-confidence characteristic that indicates that an endpoint is a source of a specified type. These endpoints can - * be used as positive samples for training or for a few-shot prompt. - */ - abstract class SourceCharacteristic extends EndpointCharacteristic { - bindingset[this] - SourceCharacteristic() { any() } - - abstract Candidate::EndpointType getSourceType(); - - final override predicate hasImplications( - Candidate::EndpointType endpointType, boolean isPositiveIndicator, float confidence - ) { - endpointType = this.getSourceType() and - isPositiveIndicator = true and - confidence = maximalConfidence() - } - } - - /** - * A high-confidence characteristic that indicates that an endpoint is not a sink of any type. These endpoints can be - * used as negative samples for training or for a few-shot prompt. - */ - abstract class NotASinkCharacteristic extends EndpointCharacteristic { - bindingset[this] - NotASinkCharacteristic() { any() } - - override predicate hasImplications( - Candidate::EndpointType endpointType, boolean isPositiveIndicator, float confidence - ) { - endpointType instanceof Candidate::SinkType and - isPositiveIndicator = false and - confidence = highConfidence() - } - } - - /** - * A high-confidence characteristic that indicates that an endpoint is not a source of any type. These endpoints can be - * used as negative samples for training or for a few-shot prompt. - */ - abstract class NotASourceCharacteristic extends EndpointCharacteristic { - bindingset[this] - NotASourceCharacteristic() { any() } - - override predicate hasImplications( - Candidate::EndpointType endpointType, boolean isPositiveIndicator, float confidence - ) { - endpointType instanceof Candidate::SourceType and - isPositiveIndicator = false and - confidence = highConfidence() - } - } - - /** - * A high-confidence characteristic that indicates that an endpoint is neither a source nor a sink of any type. - */ - abstract class NeitherSourceNorSinkCharacteristic extends NotASinkCharacteristic, - NotASourceCharacteristic - { - bindingset[this] - NeitherSourceNorSinkCharacteristic() { any() } - - final override predicate hasImplications( - Candidate::EndpointType endpointType, boolean isPositiveIndicator, float confidence - ) { - NotASinkCharacteristic.super.hasImplications(endpointType, isPositiveIndicator, confidence) or - NotASourceCharacteristic.super.hasImplications(endpointType, isPositiveIndicator, confidence) - } - } - - /** - * A medium-confidence characteristic that indicates that an endpoint is unlikely to be a sink of any type. These - * endpoints can be excluded from scoring at inference time, both to save time and to avoid false positives. They should - * not, however, be used as negative samples for training or for a few-shot prompt, because they may include a small - * number of sinks. - */ - abstract class LikelyNotASinkCharacteristic extends EndpointCharacteristic { - bindingset[this] - LikelyNotASinkCharacteristic() { any() } - - override predicate hasImplications( - Candidate::EndpointType endpointType, boolean isPositiveIndicator, float confidence - ) { - endpointType instanceof Candidate::SinkType and - isPositiveIndicator = false and - confidence = mediumConfidence() - } - } - - /** - * A characteristic that indicates not necessarily that an endpoint is not a sink, but rather that it is not a sink - * that's interesting to model in the standard Java libraries. These filters should be removed when extracting sink - * candidates within a user's codebase for customized modeling. - * - * These endpoints should not be used as negative samples for training or for a few-shot prompt, because they are not - * necessarily non-sinks. - */ - abstract class UninterestingToModelCharacteristic extends EndpointCharacteristic { - bindingset[this] - UninterestingToModelCharacteristic() { any() } - - override predicate hasImplications( - Candidate::EndpointType endpointType, boolean isPositiveIndicator, float confidence - ) { - endpointType instanceof Candidate::SinkType and - isPositiveIndicator = false and - confidence = mediumConfidence() - } - } - - /** - * Contains default implementations that are derived solely from the `CandidateSig` implementation. - */ - private module DefaultCharacteristicImplementations { - /** - * Endpoints identified as sinks by the `CandidateSig` implementation are sinks with maximal confidence. - */ - private class KnownSinkCharacteristic extends SinkCharacteristic { - string madKind; - Candidate::EndpointType endpointType; - string provenance; - - KnownSinkCharacteristic() { - Candidate::isKnownKind(madKind, endpointType) and - // bind "this" to a unique string differing from that of the SinkType classes - this = madKind + "_" + provenance + "_characteristic" and - Candidate::isSink(_, madKind, provenance) - } - - override predicate appliesToEndpoint(Candidate::Endpoint e) { - Candidate::isSink(e, madKind, provenance) - } - - override Candidate::EndpointType getSinkType() { result = endpointType } - } - - private class KnownSourceCharacteristic extends SourceCharacteristic { - string madKind; - Candidate::EndpointType endpointType; - string provenance; - - KnownSourceCharacteristic() { - Candidate::isKnownKind(madKind, endpointType) and - // bind "this" to a unique string differing from that of the SinkType classes - this = madKind + "_" + provenance + "_characteristic" and - Candidate::isSource(_, madKind, provenance) - } - - override predicate appliesToEndpoint(Candidate::Endpoint e) { - Candidate::isSource(e, madKind, provenance) - } - - override Candidate::EndpointType getSourceType() { result = endpointType } - } - - /** - * A negative characteristic that indicates that an endpoint was manually modeled as a neutral model. - */ - private class NeutralModelCharacteristic extends NeitherSourceNorSinkCharacteristic { - NeutralModelCharacteristic() { this = "known non-sink" } - - override predicate appliesToEndpoint(Candidate::Endpoint e) { Candidate::isNeutral(e) } - } - - /** - * A negative characteristic that indicates that an endpoint is a sanitizer, and thus not a source. - */ - private class IsSanitizerCharacteristic extends NotASourceCharacteristic { - IsSanitizerCharacteristic() { this = "known sanitizer" } - - override predicate appliesToEndpoint(Candidate::Endpoint e) { Candidate::isSanitizer(e, _) } - } - } -} diff --git a/java/ql/automodel/src/AutomodelSinkModelMrvaQueries.ql b/java/ql/automodel/src/AutomodelSinkModelMrvaQueries.ql deleted file mode 100644 index ed61ccfbbfd..00000000000 --- a/java/ql/automodel/src/AutomodelSinkModelMrvaQueries.ql +++ /dev/null @@ -1,62 +0,0 @@ -/** - * This file contains query predicates for use when gathering metrics at scale using Multi Repo - * Variant Analysis. - */ - -private import java -private import AutomodelAlertSinkUtil - -/** - * Holds if `alertCount` is the number of alerts for the query with ID `queryId` for which the - * sinks correspond to the given `ai-generated` sink model. - */ -query predicate sinkModelCountPerQuery( - string queryId, int alertCount, string package, string type, boolean subtypes, string name, - string signature, string input, string ext, string kind, string provenance -) { - exists(SinkModel s | - sinkModelTallyPerQuery(queryId, alertCount, s) and - s.getProvenance() = "ai-generated" and - s.getPackage() = package and - s.getType() = type and - s.getSubtypes() = subtypes and - s.getName() = name and - s.getSignature() = signature and - s.getInput() = input and - s.getExt() = ext and - s.getKind() = kind and - s.getProvenance() = provenance - ) -} - -/** - * Holds if `instanceCount` is the number of instances corresponding to the given `ai-generated` - * sink model (as identified by the `package`, `name`, `input`, etc.). - */ -query predicate instanceCount( - int instanceCount, string package, string type, boolean subtypes, string name, string signature, - string input, string ext, string kind, string provenance -) { - exists(SinkModel s | - instanceCount = s.getInstanceCount() and - instanceCount > 0 and - s.getProvenance() = "ai-generated" and - s.getPackage() = package and - s.getType() = type and - s.getSubtypes() = subtypes and - s.getName() = name and - s.getSignature() = signature and - s.getInput() = input and - s.getExt() = ext and - s.getKind() = kind and - s.getProvenance() = provenance - ) -} - -// MRVA requires a select clause, so we repurpose it to tell us which query predicates had results. -from string hadResults -where - sinkModelCountPerQuery(_, _, _, _, _, _, _, _, _, _, _) and hadResults = "sinkModelCountPerQuery" - or - instanceCount(_, _, _, _, _, _, _, _, _, _) and hadResults = "instanceCount" -select hadResults diff --git a/java/ql/automodel/src/codeql-pack.release.yml b/java/ql/automodel/src/codeql-pack.release.yml deleted file mode 100644 index 56a2fb38872..00000000000 --- a/java/ql/automodel/src/codeql-pack.release.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -lastReleaseVersion: 1.0.11 diff --git a/java/ql/automodel/src/qlpack.yml b/java/ql/automodel/src/qlpack.yml deleted file mode 100644 index 4acf2219db3..00000000000 --- a/java/ql/automodel/src/qlpack.yml +++ /dev/null @@ -1,10 +0,0 @@ -name: codeql/java-automodel-queries -version: 1.0.12-dev -groups: - - java - - automodel -dependencies: - codeql/java-all: ${workspace} -dataExtensions: - - AutomodelCandidateFilter.yml -warnOnImplicitThis: true \ No newline at end of file diff --git a/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractionTests.expected b/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractionTests.expected deleted file mode 100644 index 8ec8033d086..00000000000 --- a/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractionTests.expected +++ /dev/null @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractionTests.ql b/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractionTests.ql deleted file mode 100644 index b7e1efc4532..00000000000 --- a/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractionTests.ql +++ /dev/null @@ -1,35 +0,0 @@ -import java -import AutomodelApplicationModeCharacteristics as Characteristics -import AutomodelExtractionTests - -module TestHelper implements TestHelperSig { - Location getEndpointLocation(Characteristics::Endpoint endpoint) { - result = endpoint.asTop().getLocation() - } - - predicate isCandidate( - Characteristics::Endpoint endpoint, string name, string signature, string input, string output, - string extensibleType - ) { - Characteristics::isCandidate(endpoint, _, _, _, name, signature, input, output, _, - extensibleType, _) - } - - predicate isPositiveExample( - Characteristics::Endpoint endpoint, string endpointType, string name, string signature, - string input, string output, string extensibleType - ) { - Characteristics::isPositiveExample(endpoint, endpointType, _, _, _, name, signature, input, - output, _, extensibleType) - } - - predicate isNegativeExample( - Characteristics::Endpoint endpoint, string name, string signature, string input, string output, - string extensibleType - ) { - Characteristics::isNegativeExample(endpoint, _, _, _, _, _, name, signature, input, output, _, - extensibleType) - } -} - -import MakeTest> diff --git a/java/ql/automodel/test/AutomodelApplicationModeExtraction/PluginImpl.java b/java/ql/automodel/test/AutomodelApplicationModeExtraction/PluginImpl.java deleted file mode 100644 index b0f3482a732..00000000000 --- a/java/ql/automodel/test/AutomodelApplicationModeExtraction/PluginImpl.java +++ /dev/null @@ -1,8 +0,0 @@ -import hudson.Plugin; - -public class PluginImpl extends Plugin { - @Override - public void configure(String name, String value) { // $ sourceModelCandidate=configure(String,String):Parameter[0] sourceModelCandidate=configure(String,String):Parameter[1] - // ... - } -} diff --git a/java/ql/automodel/test/AutomodelApplicationModeExtraction/Test.java b/java/ql/automodel/test/AutomodelApplicationModeExtraction/Test.java deleted file mode 100644 index 9691cf86c15..00000000000 --- a/java/ql/automodel/test/AutomodelApplicationModeExtraction/Test.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.github.codeql.test; - -import java.io.InputStream; -import java.io.PrintWriter; -import java.nio.file.CopyOption; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Supplier; -import java.io.File; -import java.io.FileFilter; -import java.nio.file.FileVisitOption; -import java.net.URLConnection; -import java.util.concurrent.FutureTask; - -class Test { - public static void main(String[] args) throws Exception { - AtomicReference reference = new AtomicReference<>(); // uninteresting (parameterless constructor) - reference.set( // $ sinkModelCandidate=set(Object):Argument[this] - args[0] // $ negativeSinkExample=set(Object):Argument[0] // modeled as a flow step - ); // not a source candidate (return type is void) - } - - public static void callSupplier(Supplier supplier) { - supplier.get(); // not a source candidate (lambda flow) - } - - public static void copyFiles(Path source, Path target, CopyOption option) throws Exception { - Files.copy( - source, // $ positiveSinkExample=copy(Path,Path,CopyOption[]):Argument[0](path-injection) - target, // $ positiveSinkExample=copy(Path,Path,CopyOption[]):Argument[1](path-injection) - option // no candidate (not modeled, but source and target are modeled) - ); // $ sourceModelCandidate=copy(Path,Path,CopyOption[]):ReturnValue - } - - public static InputStream getInputStream(Path openPath) throws Exception { - return Files.newInputStream( - openPath // $ sinkModelCandidate=newInputStream(Path,OpenOption[]):Argument[0] positiveSinkExample=newInputStream(Path,OpenOption[]):Argument[0](path-injection) // sink candidate because "only" ai-modeled, and useful as a candidate in regression testing - ); // $ sourceModelCandidate=newInputStream(Path,OpenOption[]):ReturnValue - } - - public static InputStream getInputStream(String openPath, String otherPath) throws Exception { - return Test.getInputStream( // the call is not a source candidate (argument to local call) - Paths.get( - openPath, // $ negativeSinkExample=get(String,String[]):Argument[0] // modeled as a flow step - otherPath - ) // $ sourceModelCandidate=get(String,String[]):ReturnValue negativeSinkExample=get(String,String[]):Argument[1] - ); - } - - public static int compareFiles(File f1, File f2) { - return f1.compareTo( // $ negativeSinkExample=compareTo(File):Argument[this] - f2 // $ negativeSinkExample=compareTo(File):Argument[0] // modeled as not a sink - ); // not a source candidate (return type is int) - } - - public static void FilesWalkExample(Path p, FileVisitOption o) throws Exception { - Files.walk( - p, // $ negativeSinkExample=walk(Path,FileVisitOption[]):Argument[0] // modeled as a flow step - o, // the implicit varargs array is a candidate, annotated on the last line of the call - o // not a candidate (only the first arg corresponding to a varargs array - // is extracted) - ); // $ sourceModelCandidate=walk(Path,FileVisitOption[]):ReturnValue sinkModelCandidate=walk(Path,FileVisitOption[]):Argument[1] - } - - public static void WebSocketExample(URLConnection c) throws Exception { - c.getInputStream(); // $ sinkModelCandidate=getInputStream():Argument[this] positiveSourceExample=getInputStream():ReturnValue(remote) // not a source candidate (manual modeling) - c.connect(); // $ sinkModelCandidate=connect():Argument[this] // not a source candidate (return type is void) - } - - public static void fileFilterExample(File f, FileFilter ff) { - f.listFiles( // $ sinkModelCandidate=listFiles(FileFilter):Argument[this] - ff - ); // $ sourceModelCandidate=listFiles(FileFilter):ReturnValue - } -} - -class OverrideTest extends Exception { - public void printStackTrace(PrintWriter writer) { // $ sourceModelCandidate=printStackTrace(PrintWriter):Parameter[0] - return; - } - -} - -class TaskUtils { - public FutureTask getTask() { - FutureTask ft = new FutureTask(() -> { - // ^-- no sink candidate for the `this` qualifier of a constructor - return 42; - }); - return ft; - } -} - -class MoreTests { - public static void FilesListExample(Path p) throws Exception { - Files.list( - Files.createDirectories( - p // $ positiveSinkExample=createDirectories(Path,FileAttribute[]):Argument[0](path-injection) - ) // $ sourceModelCandidate=createDirectories(Path,FileAttribute[]):ReturnValue negativeSinkExample=list(Path):Argument[0] // modeled as a flow step - ); // $ sourceModelCandidate=list(Path):ReturnValue - - Files.delete( - p // $ sinkModelCandidate=delete(Path):Argument[0] positiveSinkExample=delete(Path):Argument[0](path-injection) - ); // not a source candidate (return type is void) - - Files.deleteIfExists( - p // $ sinkModelCandidate=deleteIfExists(Path):Argument[0] positiveSinkExample=deleteIfExists(Path):Argument[0](path-injection) - ); // not a source candidate (return type is boolean) - } -} \ No newline at end of file diff --git a/java/ql/automodel/test/AutomodelApplicationModeExtraction/hudson/Plugin.java b/java/ql/automodel/test/AutomodelApplicationModeExtraction/hudson/Plugin.java deleted file mode 100644 index 3ad79abb8df..00000000000 --- a/java/ql/automodel/test/AutomodelApplicationModeExtraction/hudson/Plugin.java +++ /dev/null @@ -1,7 +0,0 @@ -package hudson; - -/** Plugin doc */ -public class Plugin { - /** Configure method doc */ - public void configure(String name, String value) {} -} diff --git a/java/ql/automodel/test/AutomodelExtractionTests.qll b/java/ql/automodel/test/AutomodelExtractionTests.qll deleted file mode 100644 index fbc407c67f0..00000000000 --- a/java/ql/automodel/test/AutomodelExtractionTests.qll +++ /dev/null @@ -1,77 +0,0 @@ -import java -import TestUtilities.InlineExpectationsTest -import AutomodelSharedCharacteristics - -signature module TestHelperSig { - Location getEndpointLocation(Candidate::Endpoint e); - - predicate isCandidate( - Candidate::Endpoint e, string name, string signature, string input, string output, - string extensibleType - ); - - predicate isPositiveExample( - Candidate::Endpoint e, string endpointType, string name, string signature, string input, - string output, string extensibleType - ); - - predicate isNegativeExample( - Candidate::Endpoint e, string name, string signature, string input, string output, - string extensibleType - ); -} - -module Extraction TestHelper> implements TestSig { - string getARelevantTag() { - result in [ - "sourceModelCandidate", "sinkModelCandidate", // a candidate source/sink - "positiveSourceExample", "positiveSinkExample", // a known source/sink - "negativeSourceExample", "negativeSinkExample" // a known non-source/non-sink - ] - } - - /** - * If `extensibleType` is `sourceModel` then the result is `ifSource`, if it - * is `sinkModel` then the result is `ifSink`. - */ - bindingset[extensibleType, ifSource, ifSink] - private string ifSource(string extensibleType, string ifSource, string ifSink) { - extensibleType = "sourceModel" and result = ifSource - or - extensibleType = "sinkModel" and result = ifSink - } - - additional predicate selectEndpoint( - Candidate::Endpoint endpoint, string name, string signature, string input, string output, - string extensibleType, string tag, string suffix - ) { - TestHelper::isCandidate(endpoint, name, signature, input, output, extensibleType) and - tag = ifSource(extensibleType, "sourceModelCandidate", "sinkModelCandidate") and - suffix = "" - or - TestHelper::isNegativeExample(endpoint, name, signature, input, output, extensibleType) and - tag = "negative" + ifSource(extensibleType, "Source", "Sink") + "Example" and - suffix = "" - or - exists(string endpointType | - TestHelper::isPositiveExample(endpoint, endpointType, name, signature, input, output, - extensibleType) and - tag = "positive" + ifSource(extensibleType, "Source", "Sink") + "Example" and - suffix = "(" + endpointType + ")" - ) - } - - predicate hasActualResult(Location location, string element, string tag, string value) { - exists( - Candidate::Endpoint endpoint, string name, string signature, string input, string output, - string extensibleType, string suffix - | - selectEndpoint(endpoint, name, signature, input, output, extensibleType, tag, suffix) - | - TestHelper::getEndpointLocation(endpoint) = location and - endpoint.toString() = element and - // for source models only the output is relevant, and vice versa for sink models - value = name + signature + ":" + ifSource(extensibleType, output, input) + suffix - ) - } -} diff --git a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractionTests.expected b/java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractionTests.expected deleted file mode 100644 index 8ec8033d086..00000000000 --- a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractionTests.expected +++ /dev/null @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractionTests.ql b/java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractionTests.ql deleted file mode 100644 index 0d5e8611870..00000000000 --- a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractionTests.ql +++ /dev/null @@ -1,35 +0,0 @@ -import java -import AutomodelFrameworkModeCharacteristics as Characteristics -import AutomodelExtractionTests - -module TestHelper implements TestHelperSig { - Location getEndpointLocation(Characteristics::Endpoint endpoint) { - result = endpoint.asTop().getLocation() - } - - predicate isCandidate( - Characteristics::Endpoint endpoint, string name, string signature, string input, string output, - string extensibleType - ) { - Characteristics::isCandidate(endpoint, _, _, _, name, signature, input, output, _, - extensibleType, _) - } - - predicate isPositiveExample( - Characteristics::Endpoint endpoint, string endpointType, string name, string signature, - string input, string output, string extensibleType - ) { - Characteristics::isPositiveExample(endpoint, endpointType, _, _, _, name, signature, input, - output, _, extensibleType) - } - - predicate isNegativeExample( - Characteristics::Endpoint endpoint, string name, string signature, string input, string output, - string extensibleType - ) { - Characteristics::isNegativeExample(endpoint, _, _, _, _, _, name, signature, input, output, _, - extensibleType) - } -} - -import MakeTest> diff --git a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/MyWriter.java b/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/MyWriter.java deleted file mode 100644 index 62bd773cc2e..00000000000 --- a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/MyWriter.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.github.codeql.test; - -public class MyWriter extends java.io.Writer { - @Override - public void write(char[] cbuf, int off, int len) { // $ sinkModelCandidate=write(char[],int,int):Argument[this] positiveSinkExample=write(char[],int,int):Argument[0](file-content-store) sourceModelCandidate=write(char[],int,int):Parameter[this] sourceModelCandidate=write(char[],int,int):Parameter[0] - } - - @Override - public void close() { // $ sinkModelCandidate=close():Argument[this] sourceModelCandidate=close():Parameter[this] - } - - @Override - public void flush() { // $ sinkModelCandidate=flush():Argument[this] sourceModelCandidate=flush():Parameter[this] - } -} diff --git a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/NonPublicClass.java b/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/NonPublicClass.java deleted file mode 100644 index b106d3da594..00000000000 --- a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/NonPublicClass.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.github.codeql.test; - -/** - * No candidates in this class, as it's not public! - */ -class NonPublicClass { - public void noCandidates(String here) { - System.out.println(here); - } -} diff --git a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java b/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java deleted file mode 100644 index 79fabff0664..00000000000 --- a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.github.codeql.test; - -public class PublicClass { - public void stuff(String arg) { // $ sinkModelCandidate=stuff(String):Argument[this] sourceModelCandidate=stuff(String):Parameter[this] sinkModelCandidate=stuff(String):Argument[0] sourceModelCandidate=stuff(String):Parameter[0] // source candidates because it is an overrideable method - System.out.println(arg); - } - - public static void staticStuff(String arg) { // $ sinkModelCandidate=staticStuff(String):Argument[0] // `arg` is not a source candidate (not overrideabe); `this` is not a candidate (static method) - System.out.println(arg); - } - - protected void nonPublicStuff(String arg) { // $ sinkModelCandidate=nonPublicStuff(String):Argument[this] sourceModelCandidate=nonPublicStuff(String):Parameter[this] sinkModelCandidate=nonPublicStuff(String):Argument[0] sourceModelCandidate=nonPublicStuff(String):Parameter[0] - System.out.println(arg); - } - - void packagePrivateStuff(String arg) { // no candidates because the method is not public - System.out.println(arg); - } - - public PublicClass(Object input) { // $ sourceModelCandidate=PublicClass(Object):ReturnValue sinkModelCandidate=PublicClass(Object):Argument[0] // `this` is not a candidate because it is a constructor - } - - // `input` and `input` are source candidates, but not sink candidates (is-style method) - public Boolean isIgnored(Object input) { // $ negativeSinkExample=isIgnored(Object):Argument[this] sourceModelCandidate=isIgnored(Object):Parameter[this] negativeSinkExample=isIgnored(Object):Argument[0] sourceModelCandidate=isIgnored(Object):Parameter[0] - return false; - } -} diff --git a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicInterface.java b/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicInterface.java deleted file mode 100644 index d4f80b3c698..00000000000 --- a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicInterface.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.github.codeql.test; - -public interface PublicInterface { - public int stuff(String arg); // $ sinkModelCandidate=stuff(String):Argument[this] sourceModelCandidate=stuff(String):Parameter[this] sinkModelCandidate=stuff(String):Argument[0] sourceModelCandidate=stuff(String):Parameter[0] // result is _not_ a source candidate source (primitive return type) - - public static void staticStuff(String arg) { // $ sinkModelCandidate=staticStuff(String):Argument[0] // not a source candidate (static method) - System.out.println(arg); - } -} diff --git a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/java/io/File.java b/java/ql/automodel/test/AutomodelFrameworkModeExtraction/java/io/File.java deleted file mode 100644 index 8bfe83e2339..00000000000 --- a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/java/io/File.java +++ /dev/null @@ -1,13 +0,0 @@ -package java.io; - -public class File { - public int compareTo( // $ negativeSinkExample=compareTo(File):Argument[this] sourceModelCandidate=compareTo(File):Parameter[this] // modeled as neutral for sinks - File pathname // $ negativeSinkExample=compareTo(File):Argument[0] sourceModelCandidate=compareTo(File):Parameter[0] // modeled as neutral for sinks - ) { - return 0; - } - - public boolean setLastModified(long time) { // $ sinkModelCandidate=setLastModified(long):Argument[this] sourceModelCandidate=setLastModified(long):Parameter[this] // time is not a candidate (primitive type) - return false; - } // return value is not a source candidate because it's a primitive -} diff --git a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/java/nio/file/Files.java b/java/ql/automodel/test/AutomodelFrameworkModeExtraction/java/nio/file/Files.java deleted file mode 100644 index a833ba5f6e2..00000000000 --- a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/java/nio/file/Files.java +++ /dev/null @@ -1,31 +0,0 @@ -package java.nio.file; - -import java.io.InputStream; -import java.io.FileInputStream; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.file.OpenOption; - -public class Files { - public static void copy( // method result is not a candidate source (void) - Path source, // $ positiveSinkExample=copy(Path,OutputStream):Argument[0](path-injection) // manual model exists - OutputStream out // $ sinkModelCandidate=copy(Path,OutputStream):Argument[1] - /* NB: may be worthwhile to implement the - same behavior as in application mode where out would not be a - candidate because there already is a model for another parameter of - the same method and we assume that methods are always modeled - completely. - */ - ) throws IOException { - // ... - } - - public static InputStream newInputStream( // $ sourceModelCandidate=newInputStream(Path,OpenOption[]):ReturnValue - Path openPath, // $ positiveSinkExample=newInputStream(Path,OpenOption[]):Argument[0](path-injection) sinkModelCandidate=newInputStream(Path,OpenOption[]):Argument[0] // known sink, but still a candidate (ai-modeled, and useful as a candidate in regression testing) - OpenOption... options // $ sinkModelCandidate=newInputStream(Path,OpenOption[]):Argument[1] - ) throws IOException { - return new FileInputStream(openPath.toFile()); - } -} diff --git a/java/ql/automodel/test/change-notes/2024-05-23-Version1.md b/java/ql/automodel/test/change-notes/2024-05-23-Version1.md deleted file mode 100644 index 5840e51017b..00000000000 --- a/java/ql/automodel/test/change-notes/2024-05-23-Version1.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: breaking ---- -* CodeQL package management is now generally available, and all GitHub-produced CodeQL packages have had their version numbers increased to 1.0.0. diff --git a/java/ql/automodel/test/qlpack.yml b/java/ql/automodel/test/qlpack.yml deleted file mode 100644 index 46138d9435c..00000000000 --- a/java/ql/automodel/test/qlpack.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: codeql/java-automodel-tests -version: 1.0.0-dev -groups: - - java - - automodel - - test -dependencies: - codeql/java-all: ${workspace} - codeql/java-automodel-queries: ${workspace} - codeql/java-tests: ${workspace} -extractor: java -tests: . -warnOnImplicitThis: true \ No newline at end of file From 3673c7c813cec3c382c29733174a6425890dd565 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 30 Oct 2024 17:56:20 +0000 Subject: [PATCH 053/470] Rust: Add SQL injection test cases (complete and functioning). --- .../query-tests/security/CWE-089/.gitignore | 2 + .../query-tests/security/CWE-089/cargo.toml | 15 ++ .../migrations/20241031153051_create.sql | 12 + .../test/query-tests/security/CWE-089/sqlx.rs | 217 ++++++++++++++++++ 4 files changed, 246 insertions(+) create mode 100644 rust/ql/test/query-tests/security/CWE-089/.gitignore create mode 100644 rust/ql/test/query-tests/security/CWE-089/cargo.toml create mode 100644 rust/ql/test/query-tests/security/CWE-089/migrations/20241031153051_create.sql create mode 100644 rust/ql/test/query-tests/security/CWE-089/sqlx.rs diff --git a/rust/ql/test/query-tests/security/CWE-089/.gitignore b/rust/ql/test/query-tests/security/CWE-089/.gitignore new file mode 100644 index 00000000000..bdcfa82b5d5 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-089/.gitignore @@ -0,0 +1,2 @@ +# sqlite database +*.db* diff --git a/rust/ql/test/query-tests/security/CWE-089/cargo.toml b/rust/ql/test/query-tests/security/CWE-089/cargo.toml new file mode 100644 index 00000000000..0f9f0b75510 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-089/cargo.toml @@ -0,0 +1,15 @@ +[workspace] + +[package] +name = "CWE-089-Test" +version = "0.1.0" +edition = "2021" + +[dependencies] +reqwest = { version = "0.12.9", features = ["blocking"] } +sqlx = { version = "0.8", features = ["mysql", "sqlite", "postgres", "runtime-async-std", "tls-native-tls"] } +futures = { version = "0.3" } + +[[bin]] +name = "sqlx" +path = "./sqlx.rs" diff --git a/rust/ql/test/query-tests/security/CWE-089/migrations/20241031153051_create.sql b/rust/ql/test/query-tests/security/CWE-089/migrations/20241031153051_create.sql new file mode 100644 index 00000000000..c7d989a7258 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-089/migrations/20241031153051_create.sql @@ -0,0 +1,12 @@ +CREATE TABLE IF NOT EXISTS people +( + id INTEGER PRIMARY KEY NOT NULL, + firstname TEXT NOT NULL, + lastname TEXT NOT NULL +); + +INSERT INTO people +VALUES (1, "Alice", "Adams"); + +INSERT INTO people +VALUES (2, "Bob", "Becket"); diff --git a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs new file mode 100644 index 00000000000..bf4cd7a96ae --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs @@ -0,0 +1,217 @@ +use sqlx::Connection; +use sqlx::Executor; + +/** + * This test is designed to be "run" in two ways: + * - you can extract and analyze the code here using the CodeQL test runner in the usual way, + * verifying the that various vulnerabilities are detected. + * - you can compile and run the code using `cargo`, verifying that it really is a complete + * program that compiles, runs and executes SQL commands (the sqlite ones, at least). + * + * To do the latter: + * + * Install `sqlx`: + * ``` + * cargo install sqlx-cli + * ``` + * + * Create the database: + * ``` + * export DATABASE_URL="sqlite:sqlite_database.db" + * sqlx db create + * sqlx migrate run + * ``` + * + * Build and run: + * ``` + * cargo run + * ``` + * + * You can also rebuild the sqlx 'query cache' in the `.sqlx` subdirectory + * with: + * ``` + * cargo sqlx prepare + * ``` + * This allows the code (in particular the `prepare!` macro) to be built + * in the test without setting `DATABASE_URL` first. + */ + +async fn test_sqlx_mysql(url: &str, enable_remote: bool) -> Result<(), sqlx::Error> { + // connect through a MySql connection pool + let pool = sqlx::mysql::MySqlPool::connect(url).await?; + let mut conn = pool.acquire().await?; + + // construct queries (with extra variants) + let const_string = String::from("Alice"); + let arg_string = std::env::args().nth(1).unwrap_or(String::from("Alice")); // $ MISSING Source=args1 + let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING Source=remote1 + let remote_number = remote_string.parse::().unwrap_or(0); + let safe_query_1 = String::from("SELECT * FROM people WHERE firstname='Alice'"); + let safe_query_2 = String::from("SELECT * FROM people WHERE firstname='") + &const_string + "'"; + let safe_query_3 = format!("SELECT * FROM people WHERE firstname='{remote_number}'"); + let unsafe_query_1 = &arg_string; + let unsafe_query_2 = &remote_string; + let unsafe_query_3 = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'"; + let unsafe_query_4 = format!("SELECT * FROM people WHERE firstname='{remote_string}'"); + let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe) + + // direct execution + let _ = conn.execute(safe_query_1.as_str()).await?; + let _ = conn.execute(safe_query_2.as_str()).await?; + let _ = conn.execute(safe_query_3.as_str()).await?; + let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ MISSING Alert[sql-injection]=args1 + if enable_remote { + let _ = conn.execute(unsafe_query_2.as_str()).await?; // $ MISSING Alert[sql-injection]=remote1 + let _ = conn.execute(unsafe_query_3.as_str()).await?; // $ MISSING Alert[sql-injection]=remote1 + let _ = conn.execute(unsafe_query_4.as_str()).await?; // $ MISSING Alert[sql-injection]=remote1 + } + + // prepared queries + let _ = sqlx::query(safe_query_1.as_str()).execute(&pool).await?; + let _ = sqlx::query(safe_query_2.as_str()).execute(&pool).await?; + let _ = sqlx::query(safe_query_3.as_str()).execute(&pool).await?; + let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ MISSING Alert[sql-injection]=args1 + if enable_remote { + let _ = sqlx::query(unsafe_query_2.as_str()).execute(&pool).await?; // $ MISSING Alert[sql-injection]=remote1 + let _ = sqlx::query(unsafe_query_3.as_str()).execute(&pool).await?; // $ MISSING Alert[sql-injection]=remote1 + let _ = sqlx::query(unsafe_query_4.as_str()).execute(&pool).await?; // $ MISSING Alert[sql-injection]=remote1 + } + let _ = sqlx::query(prepared_query_1.as_str()).bind(const_string).execute(&pool).await?; + let _ = sqlx::query(prepared_query_1.as_str()).bind(arg_string).execute(&pool).await?; + if enable_remote { + let _ = sqlx::query(prepared_query_1.as_str()).bind(remote_string).execute(&pool).await?; + let _ = sqlx::query(prepared_query_1.as_str()).bind(remote_number).execute(&pool).await?; + } + + Ok(()) +} + +async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Error> { + // connect through Sqlite, no connection pool + let mut conn = sqlx::sqlite::SqliteConnection::connect(url).await?; + + // construct queries + let const_string = String::from("Alice"); + let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING Source=remote2 + let safe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &const_string + "'"; + let unsafe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'"; + let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe) + + // direct execution (with extra variants) + let _ = conn.execute(safe_query_1.as_str()).await?; + if enable_remote { + let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ MISSING Alert[sql-injection]=remote2 + } + // ... + let _ = sqlx::raw_sql(safe_query_1.as_str()).execute(&mut conn).await?; + if enable_remote { + let _ = sqlx::raw_sql(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ MISSING Alert[sql-injection]=remote2 + } + + // prepared queries (with extra variants) + let _ = sqlx::query(safe_query_1.as_str()).execute(&mut conn).await?; + let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).execute(&mut conn).await?; + if enable_remote { + let _ = sqlx::query(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ MISSING Alert[sql-injection]=remote2 + let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).execute(&mut conn).await?; + } + // ... + let _ = sqlx::query(safe_query_1.as_str()).fetch(&mut conn); + let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).fetch(&mut conn); + if enable_remote { + let _ = sqlx::query(unsafe_query_1.as_str()).fetch(&mut conn); // $ MISSING Alert[sql-injection]=remote2 + let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).fetch(&mut conn); + } + // ... + let row1: (i64, String, String) = sqlx::query_as(safe_query_1.as_str()).fetch_one(&mut conn).await?; + println!(" row1 = {:?}", row1); + let row2: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&const_string).fetch_one(&mut conn).await?; + println!(" row2 = {:?}", row2); + if enable_remote { + let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_one(&mut conn).await?; // $ MISSING Alert[sql-injection]=remote2 + let _: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&remote_string).fetch_one(&mut conn).await?; + } + // ... + let row3: (i64, String, String) = sqlx::query_as(safe_query_1.as_str()).fetch_optional(&mut conn).await?.expect("no data"); + println!(" row3 = {:?}", row3); + let row4: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&const_string).fetch_optional(&mut conn).await?.expect("no data"); + println!(" row4 = {:?}", row4); + if enable_remote { + let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_optional(&mut conn).await?.expect("no data"); // $ MISSING Alert[sql-injection]=remote2 + let _: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&remote_string).fetch_optional(&mut conn).await?.expect("no data"); + } + // ... + let _ = sqlx::query(safe_query_1.as_str()).fetch_all(&mut conn).await?; + let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).fetch_all(&mut conn).await?; + let _ = sqlx::query("SELECT * FROM people WHERE firstname=?").bind(&const_string).fetch_all(&mut conn).await?; + if enable_remote { + let _ = sqlx::query(unsafe_query_1.as_str()).fetch_all(&mut conn).await?; // $ MISSING Alert[sql-injection]=remote2 + let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).fetch_all(&mut conn).await?; + let _ = sqlx::query("SELECT * FROM people WHERE firstname=?").bind(&remote_string).fetch_all(&mut conn).await?; + } + // ... + let _ = sqlx::query!("SELECT * FROM people WHERE firstname=$1", const_string).fetch_all(&mut conn).await?; // (only takes string literals, so can't be vulnerable) + if enable_remote { + let _ = sqlx::query!("SELECT * FROM people WHERE firstname=$1", remote_string).fetch_all(&mut conn).await?; + } + + Ok(()) +} + +async fn test_sqlx_postgres(url: &str, enable_remote: bool) -> Result<(), sqlx::Error> { + // connect through a PostGres connection pool + let pool = sqlx::postgres::PgPool::connect(url).await?; + let mut conn = pool.acquire().await?; + + // construct queries + let const_string = String::from("Alice"); + let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING Source=remote3 + let safe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &const_string + "'"; + let unsafe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'"; + let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=$1"); // (prepared arguments are safe) + + // direct execution + let _ = conn.execute(safe_query_1.as_str()).await?; + if enable_remote { + let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ MISSING Alert[sql-injection]=remote3 + } + + // prepared queries + let _ = sqlx::query(safe_query_1.as_str()).execute(&pool).await?; + let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).execute(&pool).await?; + if enable_remote { + let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ MISSING Alert[sql-injection]=remote3 + let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).execute(&pool).await?; + } + + Ok(()) +} + +fn main() { + println!("--- CWE-089 sqlx.rs test ---"); + + // we don't *actually* use data from a remote source unless we're explicitly told to at the + // command line; that's because this test is designed to be runnable, and we don't really + // want to expose the test database to potential SQL injection from http://example.com/ - + // no matter how unlikely, local and compartmentalized that may seem. + let enable_remote = std::env::args().nth(1) == Some(String::from("ENABLE_REMOTE")); + println!("enable_remote = {enable_remote}"); + + println!("test_sqlx_mysql..."); + match futures::executor::block_on(test_sqlx_mysql("", enable_remote)) { + Ok(_) => println!(" successful!"), + Err(e) => println!(" error: {}", e), + } + + println!("test_sqlx_sqlite..."); + match futures::executor::block_on(test_sqlx_sqlite("sqlite:sqlite_database.db", enable_remote)) { + Ok(_) => println!(" successful!"), + Err(e) => println!(" error: {}", e), + } + + println!("test_sqlx_postgres..."); + match futures::executor::block_on(test_sqlx_postgres("", enable_remote)) { + Ok(_) => println!(" successful!"), + Err(e) => println!(" error: {}", e), + } +} From 28d0ad94d503d76bc95cf88de7605b97a372875a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 31 Oct 2024 17:56:17 +0000 Subject: [PATCH 054/470] Rust: Add placeholder SQL injection query, linked in test. --- .../queries/security/CWE-089/SqlInjection.ql | 22 +++++++++++++++++++ .../security/CWE-089/SqlInjection.expected | 0 .../security/CWE-089/SqlInjection.qlref | 2 ++ 3 files changed, 24 insertions(+) create mode 100644 rust/ql/src/queries/security/CWE-089/SqlInjection.ql create mode 100644 rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected create mode 100644 rust/ql/test/query-tests/security/CWE-089/SqlInjection.qlref diff --git a/rust/ql/src/queries/security/CWE-089/SqlInjection.ql b/rust/ql/src/queries/security/CWE-089/SqlInjection.ql new file mode 100644 index 00000000000..7d24d5d1207 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-089/SqlInjection.ql @@ -0,0 +1,22 @@ +/** + * @name Database query built from user-controlled sources + * @description Building a database query from user-controlled sources is vulnerable to insertion of malicious code by the user. + * @kind path-problem + * @problem.severity error + * @security-severity 8.8 + * @precision high + * @id rust/sql-injection + * @tags security + * external/cwe/cwe-089 + */ + +import codeql.rust.dataflow.DataFlow +/*import codeql.rust.security.SqlInjectionQuery +import SqlInjectionFlow::PathGraph + +from SqlInjectionFlow::PathNode sourceNode, SqlInjectionFlow::PathNode sinkNode +where SqlInjectionFlow::flowPath(sourceNode, sinkNode) +select sinkNode.getNode(), sourceNode, sinkNode, "This query depends on a $@.", + sourceNode.getNode(), "user-provided value" +*/ +select 0 diff --git a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.qlref b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.qlref new file mode 100644 index 00000000000..504d27ff30c --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.qlref @@ -0,0 +1,2 @@ +query: queries/security/CWE-089/SqlInjection.ql +postprocess: utils/InlineExpectationsTestQuery.ql From 2df565c84f1a5e8a886797b6cbe9d1ed315c4c3d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:24:33 +0000 Subject: [PATCH 055/470] Rust: Add options.yml and sqlx 'query cache' (result of 'sqlx prepare') so that the query test can function. --- ...b6da5ed65c28f666a68c4d73a1918f0eaa6f6.json | 32 +++++++++++++++++++ .../security/CWE-089/SqlInjection.expected | 1 + .../CWE-089/{cargo.toml => cargo.toml.manual} | 0 .../query-tests/security/CWE-089/options.yml | 5 +++ .../test/query-tests/security/CWE-089/sqlx.rs | 3 +- 5 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 rust/ql/test/query-tests/security/CWE-089/.sqlx/query-c996a36820ff0b98021fa553b09b6da5ed65c28f666a68c4d73a1918f0eaa6f6.json rename rust/ql/test/query-tests/security/CWE-089/{cargo.toml => cargo.toml.manual} (100%) create mode 100644 rust/ql/test/query-tests/security/CWE-089/options.yml diff --git a/rust/ql/test/query-tests/security/CWE-089/.sqlx/query-c996a36820ff0b98021fa553b09b6da5ed65c28f666a68c4d73a1918f0eaa6f6.json b/rust/ql/test/query-tests/security/CWE-089/.sqlx/query-c996a36820ff0b98021fa553b09b6da5ed65c28f666a68c4d73a1918f0eaa6f6.json new file mode 100644 index 00000000000..a4493e90c37 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-089/.sqlx/query-c996a36820ff0b98021fa553b09b6da5ed65c28f666a68c4d73a1918f0eaa6f6.json @@ -0,0 +1,32 @@ +{ + "db_name": "SQLite", + "query": "SELECT * FROM people WHERE firstname=$1", + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Integer" + }, + { + "name": "firstname", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "lastname", + "ordinal": 2, + "type_info": "Text" + } + ], + "parameters": { + "Right": 1 + }, + "nullable": [ + false, + false, + false + ] + }, + "hash": "c996a36820ff0b98021fa553b09b6da5ed65c28f666a68c4d73a1918f0eaa6f6" +} diff --git a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected index e69de29bb2d..f082a67fcf6 100644 --- a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected +++ b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected @@ -0,0 +1 @@ +| 0 | diff --git a/rust/ql/test/query-tests/security/CWE-089/cargo.toml b/rust/ql/test/query-tests/security/CWE-089/cargo.toml.manual similarity index 100% rename from rust/ql/test/query-tests/security/CWE-089/cargo.toml rename to rust/ql/test/query-tests/security/CWE-089/cargo.toml.manual diff --git a/rust/ql/test/query-tests/security/CWE-089/options.yml b/rust/ql/test/query-tests/security/CWE-089/options.yml new file mode 100644 index 00000000000..24744b7dfb4 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-089/options.yml @@ -0,0 +1,5 @@ +qltest_cargo_check: true +qltest_dependencies: + - reqwest = { version = "0.12.9", features = ["blocking"] } + - sqlx = { version = "0.8", features = ["mysql", "sqlite", "postgres", "runtime-async-std", "tls-native-tls"] } + - futures = { version = "0.3" } diff --git a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs index bf4cd7a96ae..b5cc25000f9 100644 --- a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs +++ b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs @@ -22,8 +22,9 @@ use sqlx::Executor; * sqlx migrate run * ``` * - * Build and run: + * Build and run with the provided `cargo.toml.manual`: * ``` + * cp cargo.toml.manual cargo.toml * cargo run * ``` * From 6a7fb060866a702e774951f302b234a9a3aa4db0 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 31 Oct 2024 18:24:05 +0000 Subject: [PATCH 056/470] Rust: Add .qhelp and examples. --- .../security/CWE-089/SqlInjection.qhelp | 39 +++++++++++++++++++ .../security/CWE-089/SqlInjectionBad.rs | 7 ++++ .../security/CWE-089/SqlInjectionGood.rs | 5 +++ 3 files changed, 51 insertions(+) create mode 100644 rust/ql/src/queries/security/CWE-089/SqlInjection.qhelp create mode 100644 rust/ql/src/queries/security/CWE-089/SqlInjectionBad.rs create mode 100644 rust/ql/src/queries/security/CWE-089/SqlInjectionGood.rs diff --git a/rust/ql/src/queries/security/CWE-089/SqlInjection.qhelp b/rust/ql/src/queries/security/CWE-089/SqlInjection.qhelp new file mode 100644 index 00000000000..bcf54fca582 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-089/SqlInjection.qhelp @@ -0,0 +1,39 @@ + + + + +

+If a database query (such as a SQL query) is built from user-provided data without sufficient sanitization, a user may be able to run malicious database queries. An attacker can craft the part of the query they control to change the overall meaning of the query. +

+ +
+ + +

+Most database connector libraries offer a way to safely embed untrusted data into a query using query parameters or prepared statements. You should use these features to build queries, rather than string concatenation or similar methods. You can also escape (sanitize) user-controlled strings so that they can be included directly in an SQL command. A library function should be used for escaping, because this approach is only safe if the escaping function is robust against all possible inputs. +

+ +
+ + +

+In the following examples, an SQL query is prepared using string formatting to directly include a user-controlled value remote_controlled_string. An attacker could craft remote_controlled_string to change the overall meaning of the SQL query. +

+ + + +

A better way to do this is with a prepared statement, binding remote_controlled_string to a parameter of that statement. An attacker who controls remote_controlled_string now cannot change the overall meaning of the query. +

+ + + +
+ + +
  • Wikipedia: SQL injection.
  • +
  • OWASP: SQL Injection Prevention Cheat Sheet.
  • + +
    +
    diff --git a/rust/ql/src/queries/security/CWE-089/SqlInjectionBad.rs b/rust/ql/src/queries/security/CWE-089/SqlInjectionBad.rs new file mode 100644 index 00000000000..cd0086b7eb2 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-089/SqlInjectionBad.rs @@ -0,0 +1,7 @@ +// with SQLx + +let unsafe_query = format!("SELECT * FROM people WHERE firstname='{remote_controlled_string}'"); + +let _ = conn.execute(unsafe_query.as_str()).await?; // BAD (arbitrary SQL injection is possible) + +let _ = sqlx::query(unsafe_query.as_str()).fetch_all(&mut conn).await?; // $ BAD (arbitrary SQL injection is possible) diff --git a/rust/ql/src/queries/security/CWE-089/SqlInjectionGood.rs b/rust/ql/src/queries/security/CWE-089/SqlInjectionGood.rs new file mode 100644 index 00000000000..238665cc273 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-089/SqlInjectionGood.rs @@ -0,0 +1,5 @@ +// with SQLx + +let prepared_query = "SELECT * FROM people WHERE firstname=?"; + +let _ = sqlx::query(prepared_query_1).bind(&remote_controlled_string).fetch_all(&mut conn).await?; // GOOD (prepared statement with bound parameter) From c7c6924fdacb8779a717b1662e3fe0d6108b34e9 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Nov 2024 09:08:00 +0000 Subject: [PATCH 057/470] Rust: Implement query, source/sink/barrier classes and concepts. All of this is framework, nothing is concretely modelled yet. --- rust/ql/lib/codeql/rust/Concepts.qll | 138 ++++++++++++++++++ .../rust/security/SqlInjectionExtensions.qll | 50 +++++++ rust/ql/lib/qlpack.yml | 1 + .../queries/security/CWE-089/SqlInjection.ql | 22 ++- .../security/CWE-089/SqlInjection.expected | 5 +- 5 files changed, 212 insertions(+), 4 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/Concepts.qll create mode 100644 rust/ql/lib/codeql/rust/security/SqlInjectionExtensions.qll diff --git a/rust/ql/lib/codeql/rust/Concepts.qll b/rust/ql/lib/codeql/rust/Concepts.qll new file mode 100644 index 00000000000..f64d2444573 --- /dev/null +++ b/rust/ql/lib/codeql/rust/Concepts.qll @@ -0,0 +1,138 @@ +/** + * Provides abstract classes representing generic concepts such as file system + * access or system command execution, for which individual framework libraries + * provide concrete subclasses. + */ + +private import codeql.rust.dataflow.DataFlow +private import codeql.threatmodels.ThreatModels + +/** + * A data flow source for a specific threat-model. + * + * Extend this class to refine existing API models. If you want to model new APIs, + * extend `ThreatModelSource::Range` instead. + */ +class ThreatModelSource extends DataFlow::Node instanceof ThreatModelSource::Range { + /** + * Gets a string that represents the source kind with respect to threat modeling. + * + * See + * - https://github.com/github/codeql/blob/main/docs/codeql/reusables/threat-model-description.rst + * - https://github.com/github/codeql/blob/main/shared/threat-models/ext/threat-model-grouping.model.yml + */ + string getThreatModel() { result = super.getThreatModel() } + + /** + * Gets a string that describes the type of this threat-model source. + */ + string getSourceType() { result = super.getSourceType() } +} + +/** + * Provides a class for modeling new sources for specific threat-models. + */ +module ThreatModelSource { + /** + * A data flow source, for a specific threat-model. + */ + abstract class Range extends DataFlow::Node { + /** + * Gets a string that represents the source kind with respect to threat modeling. + */ + abstract string getThreatModel(); + + /** + * Gets a string that describes the type of this threat-model source. + */ + abstract string getSourceType(); + } +} + +/** + * A data flow source that is enabled in the current threat model configuration. + */ +class ActiveThreatModelSource extends ThreatModelSource { + ActiveThreatModelSource() { + currentThreatModel(this.getThreatModel()) + } +} + +/** + * A data-flow node that constructs a SQL statement. + * + * Often, it is worthy of an alert if a SQL statement is constructed such that + * executing it would be a security risk. + * + * If it is important that the SQL statement is executed, use `SqlExecution`. + * + * Extend this class to refine existing API models. If you want to model new APIs, + * extend `SqlConstruction::Range` instead. + */ +class SqlConstruction extends DataFlow::Node instanceof SqlConstruction::Range { + /** + * Gets the argument that specifies the SQL statements to be constructed. + */ + DataFlow::Node getSql() { result = super.getSql() } +} + +/** + * Provides a class for modeling new SQL execution APIs. + */ +module SqlConstruction { + /** + * A data-flow node that constructs a SQL statement. + */ + abstract class Range extends DataFlow::Node { + /** + * Gets the argument that specifies the SQL statements to be constructed. + */ + abstract DataFlow::Node getSql(); + } +} + +/** + * A data-flow node that executes SQL statements. + * + * If the context of interest is such that merely constructing a SQL statement + * would be valuable to report, consider using `SqlConstruction`. + * + * Extend this class to refine existing API models. If you want to model new APIs, + * extend `SqlExecution::Range` instead. + */ +class SqlExecution extends DataFlow::Node instanceof SqlExecution::Range { + /** + * Gets the argument that specifies the SQL statements to be executed. + */ + DataFlow::Node getSql() { result = super.getSql() } +} + +/** + * Provides a class for modeling new SQL execution APIs. + */ +module SqlExecution { + /** + * A data-flow node that executes SQL statements. + */ + abstract class Range extends DataFlow::Node { + /** + * Gets the argument that specifies the SQL statements to be executed. + */ + abstract DataFlow::Node getSql(); + } +} + +/** + * A data-flow node that performs SQL sanitization. + */ +class SqlSanitization extends DataFlow::Node instanceof SqlSanitization::Range { } + +/** + * Provides a class for modeling new SQL sanitization APIs. + */ +module SqlSanitization { + /** + * A data-flow node that performs SQL sanitization. + */ + abstract class Range extends DataFlow::Node { } +} diff --git a/rust/ql/lib/codeql/rust/security/SqlInjectionExtensions.qll b/rust/ql/lib/codeql/rust/security/SqlInjectionExtensions.qll new file mode 100644 index 00000000000..db6239d7811 --- /dev/null +++ b/rust/ql/lib/codeql/rust/security/SqlInjectionExtensions.qll @@ -0,0 +1,50 @@ +/** + * Provides classes and predicates for reasoning about database + * queries built from user-controlled sources (that is, SQL injection + * vulnerabilities). + */ + +import rust +private import codeql.rust.dataflow.DataFlow +private import codeql.rust.Concepts +private import codeql.util.Unit + +/** + * Provides default sources, sinks and barriers for detecting SQL injection + * vulnerabilities, as well as extension points for adding your own. + */ +module SqlInjection { + /** + * A data flow source for SQL injection vulnerabilities. + */ + abstract class Source extends DataFlow::Node { } + + /** + * A data flow sink for SQL injection vulnerabilities. + */ + abstract class Sink extends DataFlow::Node { } + + /** + * A barrier for SQL injection vulnerabilities. + */ + abstract class Barrier extends DataFlow::Node { } + + /** + * An active threat-model source, considered as a flow source. + */ + private class ActiveThreatModelSourceAsSource extends Source, ActiveThreatModelSource { } + + /** + * A flow sink that is the statement of an SQL construction. + */ + class SqlConstructionAsSink extends Sink { + SqlConstructionAsSink() { this = any(SqlConstruction c).getSql() } + } + + /** + * A flow sink that is the statement of an SQL execution. + */ + class SqlExecutionAsSink extends Sink { + SqlExecutionAsSink() { this = any(SqlExecution e).getSql() } + } +} diff --git a/rust/ql/lib/qlpack.yml b/rust/ql/lib/qlpack.yml index 649d02c8e3a..53ccf6dfced 100644 --- a/rust/ql/lib/qlpack.yml +++ b/rust/ql/lib/qlpack.yml @@ -8,6 +8,7 @@ dependencies: codeql/controlflow: ${workspace} codeql/dataflow: ${workspace} codeql/regex: ${workspace} + codeql/threat-models: ${workspace} codeql/mad: ${workspace} codeql/ssa: ${workspace} codeql/tutorial: ${workspace} diff --git a/rust/ql/src/queries/security/CWE-089/SqlInjection.ql b/rust/ql/src/queries/security/CWE-089/SqlInjection.ql index 7d24d5d1207..c8db4569e59 100644 --- a/rust/ql/src/queries/security/CWE-089/SqlInjection.ql +++ b/rust/ql/src/queries/security/CWE-089/SqlInjection.ql @@ -10,13 +10,29 @@ * external/cwe/cwe-089 */ +import rust import codeql.rust.dataflow.DataFlow -/*import codeql.rust.security.SqlInjectionQuery +import codeql.rust.dataflow.TaintTracking +import codeql.rust.security.SqlInjectionExtensions import SqlInjectionFlow::PathGraph +/** + * A taint configuration for tainted data that reaches a SQL sink. + */ +module SqlInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node instanceof SqlInjection::Source } + + predicate isSink(DataFlow::Node node) { node instanceof SqlInjection::Sink } + + predicate isBarrier(DataFlow::Node barrier) { barrier instanceof SqlInjection::Barrier } +} + +/** + * Detect taint flow of tainted data that reaches a SQL sink. + */ +module SqlInjectionFlow = TaintTracking::Global; + from SqlInjectionFlow::PathNode sourceNode, SqlInjectionFlow::PathNode sinkNode where SqlInjectionFlow::flowPath(sourceNode, sinkNode) select sinkNode.getNode(), sourceNode, sinkNode, "This query depends on a $@.", sourceNode.getNode(), "user-provided value" -*/ -select 0 diff --git a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected index f082a67fcf6..58f42bec0c8 100644 --- a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected +++ b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected @@ -1 +1,4 @@ -| 0 | +#select +edges +nodes +subpaths From 924467bebe60f37340ae673523a632d63568aa97 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 8 Aug 2024 12:21:32 +0100 Subject: [PATCH 058/470] Convert squirrel sql-injection sinks to MaD (non-existent methods removed) Various non-existent methods were modeled, and I couldn't find any evidence that they used to exist. They aren't in the stubs or tests. I have removed them. --- .../github.com.mastermind.squirrel.model.yml | 51 +++++++++++++++++++ go/ql/lib/semmle/go/frameworks/SQL.qll | 44 +++------------- .../semmle/go/frameworks/SQL/squirrel.go | 18 +++---- 3 files changed, 68 insertions(+), 45 deletions(-) create mode 100644 go/ql/lib/ext/github.com.mastermind.squirrel.model.yml diff --git a/go/ql/lib/ext/github.com.mastermind.squirrel.model.yml b/go/ql/lib/ext/github.com.mastermind.squirrel.model.yml new file mode 100644 index 00000000000..a5f46d7c214 --- /dev/null +++ b/go/ql/lib/ext/github.com.mastermind.squirrel.model.yml @@ -0,0 +1,51 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: packageGrouping + data: + - ["squirrel", "github.com/Masterminds/squirrel"] + - ["squirrel", "gopkg.in/Masterminds/squirrel"] + - ["squirrel", "github.com/lann/squirrel"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["group:squirrel", "", True, "Delete", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "", True, "Expr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "", True, "Insert", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "", True, "Select", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement + - ["group:squirrel", "", True, "Update", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement + + - ["group:squirrel", "DeleteBuilder", True, "From", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "DeleteBuilder", True, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement + - ["group:squirrel", "DeleteBuilder", True, "Prefix", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "DeleteBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "DeleteBuilder", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] + + - ["group:squirrel", "InsertBuilder", True, "Columns", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement + - ["group:squirrel", "InsertBuilder", True, "Into", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "InsertBuilder", True, "Options", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement + - ["group:squirrel", "InsertBuilder", True, "Prefix", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "InsertBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"] + + - ["group:squirrel", "SelectBuilder", True, "CrossJoin", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "SelectBuilder", True, "Column", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "SelectBuilder", True, "Columns", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement + - ["group:squirrel", "SelectBuilder", True, "From", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "SelectBuilder", True, "GroupBy", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "SelectBuilder", True, "InnerJoin", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "SelectBuilder", True, "LeftJoin", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "SelectBuilder", True, "Options", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement + - ["group:squirrel", "SelectBuilder", True, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement + - ["group:squirrel", "SelectBuilder", True, "Prefix", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "SelectBuilder", True, "RightJoin", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "SelectBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "SelectBuilder", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] + + - ["group:squirrel", "UpdateBuilder", True, "From", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "UpdateBuilder", True, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement + - ["group:squirrel", "UpdateBuilder", True, "Prefix", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "UpdateBuilder", True, "Set", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "UpdateBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "UpdateBuilder", True, "Table", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "UpdateBuilder", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] diff --git a/go/ql/lib/semmle/go/frameworks/SQL.qll b/go/ql/lib/semmle/go/frameworks/SQL.qll index 1a6e2280781..73cd5d93947 100644 --- a/go/ql/lib/semmle/go/frameworks/SQL.qll +++ b/go/ql/lib/semmle/go/frameworks/SQL.qll @@ -67,42 +67,14 @@ module SQL { */ abstract class Range extends DataFlow::Node { } - /** - * An argument to an API of the squirrel library that is directly interpreted as SQL without - * taking syntactic structure into account. - */ - private class SquirrelQueryString extends Range { - SquirrelQueryString() { - exists(Function fn | - exists(string sq | - sq = - package([ - "github.com/Masterminds/squirrel", "gopkg.in/Masterminds/squirrel", - "github.com/lann/squirrel" - ], "") - | - fn.hasQualifiedName(sq, ["Delete", "Expr", "Insert", "Select", "Update"]) - or - exists(Method m, string builder | m = fn | - builder = ["DeleteBuilder", "InsertBuilder", "SelectBuilder", "UpdateBuilder"] and - m.hasQualifiedName(sq, builder, - ["Columns", "From", "Options", "OrderBy", "Prefix", "Suffix", "Where"]) - or - builder = "InsertBuilder" and - m.hasQualifiedName(sq, builder, ["Replace", "Into"]) - or - builder = "SelectBuilder" and - m.hasQualifiedName(sq, builder, - ["CrossJoin", "GroupBy", "InnerJoin", "LeftJoin", "RightJoin"]) - or - builder = "UpdateBuilder" and - m.hasQualifiedName(sq, builder, ["Set", "Table"]) - ) - ) and - this = fn.getACall().getArgument(0) - | - this.getType().getUnderlyingType() instanceof StringType or - this.getType().getUnderlyingType().(SliceType).getElementType() instanceof StringType + private class DefaultQueryString extends Range { + DefaultQueryString() { + exists(DataFlow::ArgumentNode arg | sinkNode(arg, "sql-injection") | + not arg instanceof DataFlow::ImplicitVarargsSlice and + this = arg + or + arg instanceof DataFlow::ImplicitVarargsSlice and + this = arg.getCall().getAnImplicitVarargsArgument() ) } } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/squirrel.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/squirrel.go index 15b687c7ad1..3629b8087cb 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/squirrel.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/squirrel.go @@ -10,35 +10,35 @@ func squirrelTest(querypart string) { squirrel.Expr(querypart) // $ querystring=querypart deleteBuilder := squirrel.Delete(querypart) // $ querystring=querypart deleteBuilder.From(querypart) // $ querystring=querypart - deleteBuilder.OrderBy(querypart) // $ querystring=[]type{args} + deleteBuilder.OrderBy(querypart) // $ querystring=querypart deleteBuilder.Prefix(querypart) // $ querystring=querypart deleteBuilder.Suffix(querypart) // $ querystring=querypart deleteBuilder.Where(querypart) // $ querystring=querypart insertBuilder := squirrel.Insert(querypart) // $ querystring=querypart - insertBuilder.Columns(querypart) // $ querystring=[]type{args} - insertBuilder.Options(querypart) // $ querystring=[]type{args} + insertBuilder.Columns(querypart) // $ querystring=querypart + insertBuilder.Options(querypart) // $ querystring=querypart insertBuilder.Prefix(querypart) // $ querystring=querypart insertBuilder.Suffix(querypart) // $ querystring=querypart insertBuilder.Into(querypart) // $ querystring=querypart - selectBuilder := squirrel.Select(querypart) // $ querystring=[]type{args} - selectBuilder.Columns(querypart) // $ querystring=[]type{args} + selectBuilder := squirrel.Select(querypart) // $ querystring=querypart + selectBuilder.Columns(querypart) // $ querystring=querypart selectBuilder.From(querypart) // $ querystring=querypart - selectBuilder.Options(querypart) // $ querystring=[]type{args} - selectBuilder.OrderBy(querypart) // $ querystring=[]type{args} + selectBuilder.Options(querypart) // $ querystring=querypart + selectBuilder.OrderBy(querypart) // $ querystring=querypart selectBuilder.Prefix(querypart) // $ querystring=querypart selectBuilder.Suffix(querypart) // $ querystring=querypart selectBuilder.Where(querypart) // $ querystring=querypart selectBuilder.CrossJoin(querypart) // $ querystring=querypart - selectBuilder.GroupBy(querypart) // $ querystring=[]type{args} + selectBuilder.GroupBy(querypart) // $ querystring=querypart selectBuilder.InnerJoin(querypart) // $ querystring=querypart selectBuilder.LeftJoin(querypart) // $ querystring=querypart selectBuilder.RightJoin(querypart) // $ querystring=querypart updateBuilder := squirrel.Update(querypart) // $ querystring=querypart updateBuilder.From(querypart) // $ querystring=querypart - updateBuilder.OrderBy(querypart) // $ querystring=[]type{args} + updateBuilder.OrderBy(querypart) // $ querystring=querypart updateBuilder.Prefix(querypart) // $ querystring=querypart updateBuilder.Suffix(querypart) // $ querystring=querypart updateBuilder.Where(querypart) // $ querystring=querypart From 1315a1e9aef45a9d823443406755813eccd583c1 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 15 Aug 2024 12:25:24 +0100 Subject: [PATCH 059/470] Upgrade and convert gorqlite sql-injection sinks to MaD --- .../ext/github.com.rqlite.gorqlite.model.yml | 35 ++++++ go/ql/lib/semmle/go/frameworks/SQL.qll | 24 ---- .../SQL/gorqlite/QueryString.expected | 3 + .../go/frameworks/SQL/gorqlite/QueryString.ql | 60 +++++++++ .../semmle/go/frameworks/SQL/gorqlite/go.mod | 2 +- .../frameworks/SQL/gorqlite/gorqlite.expected | 6 - .../go/frameworks/SQL/gorqlite/gorqlite.go | 39 +++++- .../go/frameworks/SQL/gorqlite/gorqlite.ql | 4 - .../vendor/github.com/rqlite/gorqlite/stub.go | 115 +++++++++++++++++- .../SQL/gorqlite/vendor/modules.txt | 2 +- 10 files changed, 245 insertions(+), 45 deletions(-) create mode 100644 go/ql/lib/ext/github.com.rqlite.gorqlite.model.yml create mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/QueryString.expected create mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/QueryString.ql delete mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.expected delete mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.ql diff --git a/go/ql/lib/ext/github.com.rqlite.gorqlite.model.yml b/go/ql/lib/ext/github.com.rqlite.gorqlite.model.yml new file mode 100644 index 00000000000..62e24f2c920 --- /dev/null +++ b/go/ql/lib/ext/github.com.rqlite.gorqlite.model.yml @@ -0,0 +1,35 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: packageGrouping + data: + - ["gorqlite", "github.com/rqlite/gorqlite"] + - ["gorqlite", "github.com/raindog308/gorqlite"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["group:gorqlite", "Connection", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "QueryOne", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "QueryOneContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "QueryOneParameterized", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "QueryOneParameterizedContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "QueryParameterized", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "QueryParameterizedContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "Queue", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "QueueContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "QueueOne", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "QueueOneContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "QueueOneParameterized", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "QueueOneParameterizedContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "QueueParameterized", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "QueueParameterizedContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "Write", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "WriteContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "WriteOne", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "WriteOneContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "WriteOneParameterized", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "WriteOneParameterizedContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "WriteParameterized", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorqlite", "Connection", True, "WriteParameterizedContext", "", "", "Argument[1]", "sql-injection", "manual"] diff --git a/go/ql/lib/semmle/go/frameworks/SQL.qll b/go/ql/lib/semmle/go/frameworks/SQL.qll index 73cd5d93947..e6318df82f2 100644 --- a/go/ql/lib/semmle/go/frameworks/SQL.qll +++ b/go/ql/lib/semmle/go/frameworks/SQL.qll @@ -85,11 +85,6 @@ module SQL { /** A string that might identify package `go-pg/pg/orm` or a specific version of it. */ private string gopgorm() { result = package("github.com/go-pg/pg", "orm") } - /** A string that might identify package `github.com/rqlite/gorqlite` or `github.com/raindog308/gorqlite` or a specific version of it. */ - private string gorqlite() { - result = package(["github.com/rqlite/gorqlite", "github.com/raindog308/gorqlite"], "") - } - /** A string that might identify package `github.com/gogf/gf/database/gdb` or a specific version of it. */ private string gogf() { result = package("github.com/gogf/gf", "database/gdb") } @@ -158,25 +153,6 @@ module SQL { } } - /** - * A string argument to an API of `github.com/rqlite/gorqlite`, or a specific version of it, that is directly interpreted as SQL without - * taking syntactic structure into account. - */ - private class GorqliteQueryString extends Range { - GorqliteQueryString() { - // func (conn *Connection) Query(sqlStatements []string) (results []QueryResult, err error) - // func (conn *Connection) QueryOne(sqlStatement string) (qr QueryResult, err error) - // func (conn *Connection) Queue(sqlStatements []string) (seq int64, err error) - // func (conn *Connection) QueueOne(sqlStatement string) (seq int64, err error) - // func (conn *Connection) Write(sqlStatements []string) (results []WriteResult, err error) - // func (conn *Connection) WriteOne(sqlStatement string) (wr WriteResult, err error) - exists(Method m, string name | m.hasQualifiedName(gorqlite(), "Connection", name) | - name = ["Query", "QueryOne", "Queue", "QueueOne", "Write", "WriteOne"] and - this = m.getACall().getArgument(0) - ) - } - } - /** * A string argument to an API of `github.com/gogf/gf/database/gdb`, or a specific version of it, that is directly interpreted as SQL without * taking syntactic structure into account. diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/QueryString.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/QueryString.expected new file mode 100644 index 00000000000..db33d6d2504 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/QueryString.expected @@ -0,0 +1,3 @@ +testFailures +invalidModelRow +failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/QueryString.ql b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/QueryString.ql new file mode 100644 index 00000000000..eeb43a82fad --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/QueryString.ql @@ -0,0 +1,60 @@ +import go +import semmle.go.dataflow.ExternalFlow +import ModelValidation +import TestUtilities.InlineExpectationsTest + +module SqlTest implements TestSig { + string getARelevantTag() { result = "query" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "query" and + exists(SQL::Query q, SQL::QueryString qs | qs = q.getAQueryString() | + q.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = q.toString() and + value = qs.toString() + ) + } +} + +module QueryString implements TestSig { + string getARelevantTag() { result = "querystring" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "querystring" and + element = "" and + exists(SQL::QueryString qs | not exists(SQL::Query q | qs = q.getAQueryString()) | + qs.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + value = qs.toString() + ) + } +} + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLit } + + predicate isSink(DataFlow::Node n) { + n = any(DataFlow::CallNode cn | cn.getTarget().getName() = "sink").getAnArgument() + } +} + +module Flow = TaintTracking::Global; + +module TaintFlow implements TestSig { + string getARelevantTag() { result = "flowfrom" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "flowfrom" and + element = "" and + exists(DataFlow::Node fromNode, DataFlow::Node toNode | + toNode + .hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + Flow::flow(fromNode, toNode) and + value = fromNode.asExpr().(StringLit).getValue() + ) + } +} + +import MakeTest> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/go.mod b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/go.mod index 1f243775658..826ed0eb1c0 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/go.mod +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/go.mod @@ -2,4 +2,4 @@ module main go 1.18 -require github.com/rqlite/gorqlite v0.0.0-20220528150909-c4e99ae96be6 +require github.com/rqlite/gorqlite v0.0.0-20240808172217-12ae7d03ef19 diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.expected deleted file mode 100644 index cbd8166ea5e..00000000000 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.expected +++ /dev/null @@ -1,6 +0,0 @@ -| gorqlite.go:11:13:11:16 | sqls | -| gorqlite.go:12:13:12:16 | sqls | -| gorqlite.go:13:13:13:16 | sqls | -| gorqlite.go:14:16:14:18 | sql | -| gorqlite.go:15:16:15:18 | sql | -| gorqlite.go:16:16:16:18 | sql | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.go index 9b60c6684e6..ebd6e5fd9f3 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.go @@ -1,20 +1,49 @@ package main -//go:generate depstubber -vendor github.com/rqlite/gorqlite Connection Open +//go:generate depstubber -vendor github.com/rqlite/gorqlite Connection,ParameterizedStatement Open import ( + "context" + "github.com/rqlite/gorqlite" ) -func gorqlitetest(sql string, sqls []string) { +func gorqlitetest(sql string, sqls []string, param_sql gorqlite.ParameterizedStatement, param_sqls []gorqlite.ParameterizedStatement, ctx context.Context) { conn, _ := gorqlite.Open("dbUrl") - conn.Query(sqls) // $ querystring=sqls - conn.Queue(sqls) // $ querystring=sqls - conn.Write(sqls) // $ querystring=sqls + + conn.Query(sqls) // $ querystring=sqls + conn.Queue(sqls) // $ querystring=sqls + conn.Write(sqls) // $ querystring=sqls + conn.QueryOne(sql) // $ querystring=sql conn.QueueOne(sql) // $ querystring=sql conn.WriteOne(sql) // $ querystring=sql + + conn.QueryParameterized(param_sqls) // $ querystring=param_sqls + conn.QueueParameterized(param_sqls) // $ querystring=param_sqls + conn.WriteParameterized(param_sqls) // $ querystring=param_sqls + + conn.QueryOneParameterized(param_sql) // $ querystring=param_sql + conn.QueueOneParameterized(param_sql) // $ querystring=param_sql + conn.WriteOneParameterized(param_sql) // $ querystring=param_sql + + conn.QueryContext(ctx, sqls) // $ querystring=sqls + conn.QueueContext(ctx, sqls) // $ querystring=sqls + conn.WriteContext(ctx, sqls) // $ querystring=sqls + + conn.QueryOneContext(ctx, sql) // $ querystring=sql + conn.QueueOneContext(ctx, sql) // $ querystring=sql + conn.WriteOneContext(ctx, sql) // $ querystring=sql + + conn.QueryParameterizedContext(ctx, param_sqls) // $ querystring=param_sqls + conn.QueueParameterizedContext(ctx, param_sqls) // $ querystring=param_sqls + conn.WriteParameterizedContext(ctx, param_sqls) // $ querystring=param_sqls + + conn.QueryOneParameterizedContext(ctx, param_sql) // $ querystring=param_sql + conn.QueueOneParameterizedContext(ctx, param_sql) // $ querystring=param_sql + conn.WriteOneParameterizedContext(ctx, param_sql) // $ querystring=param_sql } + func main() { return } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.ql b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.ql deleted file mode 100644 index 7b56fd97441..00000000000 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.ql +++ /dev/null @@ -1,4 +0,0 @@ -import go - -from SQL::QueryString qs -select qs diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/vendor/github.com/rqlite/gorqlite/stub.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/vendor/github.com/rqlite/gorqlite/stub.go index f6f4ca18ec1..0572097582e 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/vendor/github.com/rqlite/gorqlite/stub.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/vendor/github.com/rqlite/gorqlite/stub.go @@ -2,11 +2,15 @@ // This is a simple stub for github.com/rqlite/gorqlite, strictly for use in testing. // See the LICENSE file for information about the licensing of the original library. -// Source: github.com/rqlite/gorqlite (exports: Connection; functions: Open) +// Source: github.com/rqlite/gorqlite (exports: Connection,ParameterizedStatement; functions: Open) // Package gorqlite is a stub of github.com/rqlite/gorqlite, generated by depstubber. package gorqlite +import ( + context "context" +) + type Connection struct { ID string } @@ -29,19 +33,83 @@ func (_ *Connection) Query(_ []string) ([]QueryResult, error) { return nil, nil } +func (_ *Connection) QueryContext(_ context.Context, _ []string) ([]QueryResult, error) { + return nil, nil +} + func (_ *Connection) QueryOne(_ string) (QueryResult, error) { return QueryResult{}, nil } +func (_ *Connection) QueryOneContext(_ context.Context, _ string) (QueryResult, error) { + return QueryResult{}, nil +} + +func (_ *Connection) QueryOneParameterized(_ ParameterizedStatement) (QueryResult, error) { + return QueryResult{}, nil +} + +func (_ *Connection) QueryOneParameterizedContext(_ context.Context, _ ParameterizedStatement) (QueryResult, error) { + return QueryResult{}, nil +} + +func (_ *Connection) QueryParameterized(_ []ParameterizedStatement) ([]QueryResult, error) { + return nil, nil +} + +func (_ *Connection) QueryParameterizedContext(_ context.Context, _ []ParameterizedStatement) ([]QueryResult, error) { + return nil, nil +} + func (_ *Connection) Queue(_ []string) (int64, error) { return 0, nil } +func (_ *Connection) QueueContext(_ context.Context, _ []string) (int64, error) { + return 0, nil +} + func (_ *Connection) QueueOne(_ string) (int64, error) { return 0, nil } -func (_ *Connection) SetConsistencyLevel(_ string) error { +func (_ *Connection) QueueOneContext(_ context.Context, _ string) (int64, error) { + return 0, nil +} + +func (_ *Connection) QueueOneParameterized(_ ParameterizedStatement) (int64, error) { + return 0, nil +} + +func (_ *Connection) QueueOneParameterizedContext(_ context.Context, _ ParameterizedStatement) (int64, error) { + return 0, nil +} + +func (_ *Connection) QueueParameterized(_ []ParameterizedStatement) (int64, error) { + return 0, nil +} + +func (_ *Connection) QueueParameterizedContext(_ context.Context, _ []ParameterizedStatement) (int64, error) { + return 0, nil +} + +func (_ *Connection) Request(_ []string) ([]RequestResult, error) { + return nil, nil +} + +func (_ *Connection) RequestContext(_ context.Context, _ []string) ([]RequestResult, error) { + return nil, nil +} + +func (_ *Connection) RequestParameterized(_ []ParameterizedStatement) ([]RequestResult, error) { + return nil, nil +} + +func (_ *Connection) RequestParameterizedContext(_ context.Context, _ []ParameterizedStatement) ([]RequestResult, error) { + return nil, nil +} + +func (_ *Connection) SetConsistencyLevel(_ interface{}) error { return nil } @@ -53,12 +121,41 @@ func (_ *Connection) Write(_ []string) ([]WriteResult, error) { return nil, nil } +func (_ *Connection) WriteContext(_ context.Context, _ []string) ([]WriteResult, error) { + return nil, nil +} + func (_ *Connection) WriteOne(_ string) (WriteResult, error) { return WriteResult{}, nil } -func Open(_ string) (Connection, error) { - return Connection{}, nil +func (_ *Connection) WriteOneContext(_ context.Context, _ string) (WriteResult, error) { + return WriteResult{}, nil +} + +func (_ *Connection) WriteOneParameterized(_ ParameterizedStatement) (WriteResult, error) { + return WriteResult{}, nil +} + +func (_ *Connection) WriteOneParameterizedContext(_ context.Context, _ ParameterizedStatement) (WriteResult, error) { + return WriteResult{}, nil +} + +func (_ *Connection) WriteParameterized(_ []ParameterizedStatement) ([]WriteResult, error) { + return nil, nil +} + +func (_ *Connection) WriteParameterizedContext(_ context.Context, _ []ParameterizedStatement) ([]WriteResult, error) { + return nil, nil +} + +func Open(_ string) (*Connection, error) { + return nil, nil +} + +type ParameterizedStatement struct { + Query string + Arguments []interface{} } type QueryResult struct { @@ -90,10 +187,20 @@ func (_ *QueryResult) Scan(_ ...interface{}) error { return nil } +func (_ *QueryResult) Slice() ([]interface{}, error) { + return nil, nil +} + func (_ *QueryResult) Types() []string { return nil } +type RequestResult struct { + Err error + Query *QueryResult + Write *WriteResult +} + type WriteResult struct { Err error Timing float64 diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/vendor/modules.txt b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/vendor/modules.txt index f5e5b9989ed..dafb7c6d1a9 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/vendor/modules.txt +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/vendor/modules.txt @@ -1,3 +1,3 @@ -# github.com/rqlite/gorqlite v0.0.0-20220528150909-c4e99ae96be6 +# github.com/rqlite/gorqlite v0.0.0-20240808172217-12ae7d03ef19 ## explicit github.com/rqlite/gorqlite From d9d3e74e8c052faef3321366169466c8e0195e5b Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 15 Aug 2024 12:50:27 +0100 Subject: [PATCH 060/470] Convert gogf/gf sql-injection sinks to MaD --- .../github.com.gogf.gf.database.gdb.model.yml | 57 ++++++++++++++++++ go/ql/lib/semmle/go/frameworks/SQL.qll | 43 ------------- .../frameworks/SQL/gogf/QueryString.expected | 3 + .../go/frameworks/SQL/gogf/QueryString.ql | 60 +++++++++++++++++++ .../go/frameworks/SQL/gogf/gogf.expected | 47 --------------- .../semmle/go/frameworks/SQL/gogf/gogf.go | 38 ++++++------ .../semmle/go/frameworks/SQL/gogf/gogf.ql | 4 -- 7 files changed, 140 insertions(+), 112 deletions(-) create mode 100644 go/ql/lib/ext/github.com.gogf.gf.database.gdb.model.yml create mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/QueryString.expected create mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/QueryString.ql delete mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.expected delete mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.ql diff --git a/go/ql/lib/ext/github.com.gogf.gf.database.gdb.model.yml b/go/ql/lib/ext/github.com.gogf.gf.database.gdb.model.yml new file mode 100644 index 00000000000..030656c6eb8 --- /dev/null +++ b/go/ql/lib/ext/github.com.gogf.gf.database.gdb.model.yml @@ -0,0 +1,57 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + # These models are for v1. Some of them hold for v2, but we should model v2 properly. + - ["github.com/gogf/gf/database/gdb", "Core", True, "DoCommit", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "DoExec", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "DoGetAll", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "DoQuery", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "DoPrepare", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "GetAll", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "GetArray", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "GetCount", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "GetOne", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "GetScan", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "GetStruct", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "GetStructs", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "GetValue", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Core", True, "Raw", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "DoCommit", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "DoExec", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "DoGetAll", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "DoQuery", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "DoPrepare", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "GetAll", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "GetArray", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "GetCount", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "GetOne", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "GetScan", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "GetStruct", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "GetStructs", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "GetValue", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "DB", True, "Raw", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "DoCommit", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "DoExec", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "DoGetAll", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "DoQuery", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "DoPrepare", "", "", "Argument[2]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "GetAll", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "GetArray", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "GetCount", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "GetOne", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "GetScan", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "GetStruct", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "GetStructs", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "GetValue", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/gogf/gf/database/gdb", "Tx", True, "Raw", "", "", "Argument[0]", "sql-injection", "manual"] diff --git a/go/ql/lib/semmle/go/frameworks/SQL.qll b/go/ql/lib/semmle/go/frameworks/SQL.qll index e6318df82f2..f960c214d84 100644 --- a/go/ql/lib/semmle/go/frameworks/SQL.qll +++ b/go/ql/lib/semmle/go/frameworks/SQL.qll @@ -85,9 +85,6 @@ module SQL { /** A string that might identify package `go-pg/pg/orm` or a specific version of it. */ private string gopgorm() { result = package("github.com/go-pg/pg", "orm") } - /** A string that might identify package `github.com/gogf/gf/database/gdb` or a specific version of it. */ - private string gogf() { result = package("github.com/gogf/gf", "database/gdb") } - /** * A string argument to an API of `go-pg/pg` that is directly interpreted as SQL without * taking syntactic structure into account. @@ -152,46 +149,6 @@ module SQL { ) } } - - /** - * A string argument to an API of `github.com/gogf/gf/database/gdb`, or a specific version of it, that is directly interpreted as SQL without - * taking syntactic structure into account. - */ - private class GogfQueryString extends Range { - GogfQueryString() { - exists(Method m, string name | m.implements(gogf(), ["DB", "Core", "TX"], name) | - // func (c *Core) Exec(sql string, args ...interface{}) (result sql.Result, err error) - // func (c *Core) GetAll(sql string, args ...interface{}) (Result, error) - // func (c *Core) GetArray(sql string, args ...interface{}) ([]Value, error) - // func (c *Core) GetCount(sql string, args ...interface{}) (int, error) - // func (c *Core) GetOne(sql string, args ...interface{}) (Record, error) - // func (c *Core) GetValue(sql string, args ...interface{}) (Value, error) - // func (c *Core) Prepare(sql string, execOnMaster ...bool) (*Stmt, error) - // func (c *Core) Query(sql string, args ...interface{}) (rows *sql.Rows, err error) - // func (c *Core) Raw(rawSql string, args ...interface{}) *Model - name = - [ - "Query", "Exec", "Prepare", "GetAll", "GetOne", "GetValue", "GetArray", "GetCount", - "Raw" - ] and - this = m.getACall().getArgument(0) - or - // func (c *Core) GetScan(pointer interface{}, sql string, args ...interface{}) error - // func (c *Core) GetStruct(pointer interface{}, sql string, args ...interface{}) error - // func (c *Core) GetStructs(pointer interface{}, sql string, args ...interface{}) error - name = ["GetScan", "GetStruct", "GetStructs"] and - this = m.getACall().getArgument(1) - or - // func (c *Core) DoCommit(ctx context.Context, link Link, sql string, args []interface{}) (newSql string, newArgs []interface{}, err error) - // func (c *Core) DoExec(ctx context.Context, link Link, sql string, args ...interface{}) (result sql.Result, err error) - // func (c *Core) DoGetAll(ctx context.Context, link Link, sql string, args ...interface{}) (result Result, err error) - // func (c *Core) DoPrepare(ctx context.Context, link Link, sql string) (*Stmt, error) - // func (c *Core) DoQuery(ctx context.Context, link Link, sql string, args ...interface{}) (rows *sql.Rows, err error) - name = ["DoGetAll", "DoQuery", "DoExec", "DoCommit", "DoPrepare"] and - this = m.getACall().getArgument(2) - ) - } - } } /** A model for sinks of GORM. */ diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/QueryString.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/QueryString.expected new file mode 100644 index 00000000000..db33d6d2504 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/QueryString.expected @@ -0,0 +1,3 @@ +testFailures +invalidModelRow +failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/QueryString.ql b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/QueryString.ql new file mode 100644 index 00000000000..eeb43a82fad --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/QueryString.ql @@ -0,0 +1,60 @@ +import go +import semmle.go.dataflow.ExternalFlow +import ModelValidation +import TestUtilities.InlineExpectationsTest + +module SqlTest implements TestSig { + string getARelevantTag() { result = "query" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "query" and + exists(SQL::Query q, SQL::QueryString qs | qs = q.getAQueryString() | + q.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = q.toString() and + value = qs.toString() + ) + } +} + +module QueryString implements TestSig { + string getARelevantTag() { result = "querystring" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "querystring" and + element = "" and + exists(SQL::QueryString qs | not exists(SQL::Query q | qs = q.getAQueryString()) | + qs.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + value = qs.toString() + ) + } +} + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLit } + + predicate isSink(DataFlow::Node n) { + n = any(DataFlow::CallNode cn | cn.getTarget().getName() = "sink").getAnArgument() + } +} + +module Flow = TaintTracking::Global; + +module TaintFlow implements TestSig { + string getARelevantTag() { result = "flowfrom" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "flowfrom" and + element = "" and + exists(DataFlow::Node fromNode, DataFlow::Node toNode | + toNode + .hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + Flow::flow(fromNode, toNode) and + value = fromNode.asExpr().(StringLit).getValue() + ) + } +} + +import MakeTest> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.expected deleted file mode 100644 index f4e3e4f15b0..00000000000 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.expected +++ /dev/null @@ -1,47 +0,0 @@ -| gogf.go:12:9:12:11 | sql | -| gogf.go:13:11:13:13 | sql | -| gogf.go:14:13:14:15 | sql | -| gogf.go:15:13:15:15 | sql | -| gogf.go:16:11:16:13 | sql | -| gogf.go:17:13:17:15 | sql | -| gogf.go:18:12:18:14 | sql | -| gogf.go:19:10:19:12 | sql | -| gogf.go:20:8:20:10 | sql | -| gogf.go:21:17:21:19 | sql | -| gogf.go:22:19:22:21 | sql | -| gogf.go:23:20:23:22 | sql | -| gogf.go:24:23:24:25 | sql | -| gogf.go:25:21:25:23 | sql | -| gogf.go:26:23:26:25 | sql | -| gogf.go:27:22:27:24 | sql | -| gogf.go:28:24:28:26 | sql | -| gogf.go:32:9:32:11 | sql | -| gogf.go:33:11:33:13 | sql | -| gogf.go:34:13:34:15 | sql | -| gogf.go:35:13:35:15 | sql | -| gogf.go:36:11:36:13 | sql | -| gogf.go:37:13:37:15 | sql | -| gogf.go:38:12:38:14 | sql | -| gogf.go:39:10:39:12 | sql | -| gogf.go:40:8:40:10 | sql | -| gogf.go:41:17:41:19 | sql | -| gogf.go:42:23:42:25 | sql | -| gogf.go:43:21:43:23 | sql | -| gogf.go:44:23:44:25 | sql | -| gogf.go:45:22:45:24 | sql | -| gogf.go:46:24:46:26 | sql | -| gogf.go:51:9:51:11 | sql | -| gogf.go:52:11:52:13 | sql | -| gogf.go:53:13:53:15 | sql | -| gogf.go:54:13:54:15 | sql | -| gogf.go:55:11:55:13 | sql | -| gogf.go:56:13:56:15 | sql | -| gogf.go:57:12:57:14 | sql | -| gogf.go:58:10:58:12 | sql | -| gogf.go:59:8:59:10 | sql | -| gogf.go:60:17:60:19 | sql | -| gogf.go:61:23:61:25 | sql | -| gogf.go:62:21:62:23 | sql | -| gogf.go:63:23:63:25 | sql | -| gogf.go:64:22:64:24 | sql | -| gogf.go:65:24:65:26 | sql | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.go index d0eceaf862c..e2db8016cf0 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.go @@ -4,11 +4,13 @@ package main //go:generate depstubber -vendor github.com/gogf/gf/database/gdb DB,Core,TX "" import ( + "context" + "github.com/gogf/gf/database/gdb" "github.com/gogf/gf/frame/g" ) -func gogfCoreTest(sql string, c *gdb.Core) { +func gogfCoreTest(sql string, c *gdb.Core, ctx context.Context) { c.Exec(sql, nil) // $ querystring=sql c.GetAll(sql, nil) // $ querystring=sql c.GetArray(sql, nil) // $ querystring=sql @@ -21,14 +23,14 @@ func gogfCoreTest(sql string, c *gdb.Core) { c.GetScan(nil, sql, nil) // $ querystring=sql c.GetStruct(nil, sql, nil) // $ querystring=sql c.GetStructs(nil, sql, nil) // $ querystring=sql - c.DoCommit(nil, nil, sql, nil) // $ querystring=sql - c.DoExec(nil, nil, sql, nil) // $ querystring=sql - c.DoGetAll(nil, nil, sql, nil) // $ querystring=sql - c.DoQuery(nil, nil, sql, nil) // $ querystring=sql - c.DoPrepare(nil, nil, sql) // $ querystring=sql + c.DoCommit(ctx, nil, sql, nil) // $ querystring=sql + c.DoExec(ctx, nil, sql, nil) // $ querystring=sql + c.DoGetAll(ctx, nil, sql, nil) // $ querystring=sql + c.DoQuery(ctx, nil, sql, nil) // $ querystring=sql + c.DoPrepare(ctx, nil, sql) // $ querystring=sql } -func gogfDbtest(sql string, c gdb.DB) { +func gogfDbtest(sql string, c gdb.DB, ctx context.Context) { c.Exec(sql, nil) // $ querystring=sql c.GetAll(sql, nil) // $ querystring=sql c.GetArray(sql, nil) // $ querystring=sql @@ -39,14 +41,14 @@ func gogfDbtest(sql string, c gdb.DB) { c.Query(sql, nil) // $ querystring=sql c.Raw(sql, nil) // $ querystring=sql c.GetScan(nil, sql, nil) // $ querystring=sql - c.DoCommit(nil, nil, sql, nil) // $ querystring=sql - c.DoExec(nil, nil, sql, nil) // $ querystring=sql - c.DoGetAll(nil, nil, sql, nil) // $ querystring=sql - c.DoQuery(nil, nil, sql, nil) // $ querystring=sql - c.DoPrepare(nil, nil, sql) // $ querystring=sql + c.DoCommit(ctx, nil, sql, nil) // $ querystring=sql + c.DoExec(ctx, nil, sql, nil) // $ querystring=sql + c.DoGetAll(ctx, nil, sql, nil) // $ querystring=sql + c.DoQuery(ctx, nil, sql, nil) // $ querystring=sql + c.DoPrepare(ctx, nil, sql) // $ querystring=sql } -func gogfGTest(sql string) { +func gogfGTest(sql string, ctx context.Context) { c := g.DB("ad") c.Exec(sql, nil) // $ querystring=sql c.GetAll(sql, nil) // $ querystring=sql @@ -58,11 +60,11 @@ func gogfGTest(sql string) { c.Query(sql, nil) // $ querystring=sql c.Raw(sql, nil) // $ querystring=sql c.GetScan(nil, sql, nil) // $ querystring=sql - c.DoCommit(nil, nil, sql, nil) // $ querystring=sql - c.DoExec(nil, nil, sql, nil) // $ querystring=sql - c.DoGetAll(nil, nil, sql, nil) // $ querystring=sql - c.DoQuery(nil, nil, sql, nil) // $ querystring=sql - c.DoPrepare(nil, nil, sql) // $ querystring=sql + c.DoCommit(ctx, nil, sql, nil) // $ querystring=sql + c.DoExec(ctx, nil, sql, nil) // $ querystring=sql + c.DoGetAll(ctx, nil, sql, nil) // $ querystring=sql + c.DoQuery(ctx, nil, sql, nil) // $ querystring=sql + c.DoPrepare(ctx, nil, sql) // $ querystring=sql } func main() { diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.ql b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.ql deleted file mode 100644 index 7b56fd97441..00000000000 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.ql +++ /dev/null @@ -1,4 +0,0 @@ -import go - -from SQL::QueryString qs -select qs From fb050e8b431569094b1e872b9e1359b0dde2284d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 15 Aug 2024 12:57:42 +0100 Subject: [PATCH 061/470] Convert sqlx sql-injection sinks to MaD --- .../lib/ext/github.com.jmoiron.sqlx.model.yml | 17 ++++++ go/ql/lib/semmle/go/frameworks/SQL.qll | 14 ----- .../frameworks/SQL/Sqlx/QueryString.expected | 3 + .../go/frameworks/SQL/Sqlx/QueryString.ql | 60 +++++++++++++++++++ .../go/frameworks/SQL/Sqlx/sqlx.expected | 12 ---- .../semmle/go/frameworks/SQL/Sqlx/sqlx.go | 24 ++++---- .../semmle/go/frameworks/SQL/Sqlx/sqlx.ql | 4 -- 7 files changed, 92 insertions(+), 42 deletions(-) create mode 100644 go/ql/lib/ext/github.com.jmoiron.sqlx.model.yml create mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/QueryString.expected create mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/QueryString.ql delete mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/sqlx.expected delete mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/sqlx.ql diff --git a/go/ql/lib/ext/github.com.jmoiron.sqlx.model.yml b/go/ql/lib/ext/github.com.jmoiron.sqlx.model.yml new file mode 100644 index 00000000000..8c9d19b4b85 --- /dev/null +++ b/go/ql/lib/ext/github.com.jmoiron.sqlx.model.yml @@ -0,0 +1,17 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["github.com/jmoiron/sqlx", "DB", True, "Get", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/jmoiron/sqlx", "DB", True, "MustExec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/jmoiron/sqlx", "DB", True, "NamedExec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/jmoiron/sqlx", "DB", True, "NamedQuery", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/jmoiron/sqlx", "DB", True, "Queryx", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/jmoiron/sqlx", "DB", True, "Select", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/jmoiron/sqlx", "Tx", True, "Get", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/jmoiron/sqlx", "Tx", True, "MustExec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/jmoiron/sqlx", "Tx", True, "NamedExec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/jmoiron/sqlx", "Tx", True, "NamedQuery", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/jmoiron/sqlx", "Tx", True, "Queryx", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/jmoiron/sqlx", "Tx", True, "Select", "", "", "Argument[1]", "sql-injection", "manual"] diff --git a/go/ql/lib/semmle/go/frameworks/SQL.qll b/go/ql/lib/semmle/go/frameworks/SQL.qll index f960c214d84..304c7f82d87 100644 --- a/go/ql/lib/semmle/go/frameworks/SQL.qll +++ b/go/ql/lib/semmle/go/frameworks/SQL.qll @@ -165,20 +165,6 @@ module SQL { ) } } - - /** A model for sinks of github.com/jmoiron/sqlx. */ - private class SqlxSink extends SQL::QueryString::Range { - SqlxSink() { - exists(Method meth, string name, int n | - meth.hasQualifiedName(package("github.com/jmoiron/sqlx", ""), ["DB", "Tx"], name) and - this = meth.getACall().getArgument(n) - | - name = ["Select", "Get"] and n = 1 - or - name = ["MustExec", "Queryx", "NamedExec", "NamedQuery"] and n = 0 - ) - } - } } /** diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/QueryString.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/QueryString.expected new file mode 100644 index 00000000000..db33d6d2504 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/QueryString.expected @@ -0,0 +1,3 @@ +testFailures +invalidModelRow +failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/QueryString.ql b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/QueryString.ql new file mode 100644 index 00000000000..eeb43a82fad --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/QueryString.ql @@ -0,0 +1,60 @@ +import go +import semmle.go.dataflow.ExternalFlow +import ModelValidation +import TestUtilities.InlineExpectationsTest + +module SqlTest implements TestSig { + string getARelevantTag() { result = "query" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "query" and + exists(SQL::Query q, SQL::QueryString qs | qs = q.getAQueryString() | + q.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = q.toString() and + value = qs.toString() + ) + } +} + +module QueryString implements TestSig { + string getARelevantTag() { result = "querystring" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "querystring" and + element = "" and + exists(SQL::QueryString qs | not exists(SQL::Query q | qs = q.getAQueryString()) | + qs.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + value = qs.toString() + ) + } +} + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLit } + + predicate isSink(DataFlow::Node n) { + n = any(DataFlow::CallNode cn | cn.getTarget().getName() = "sink").getAnArgument() + } +} + +module Flow = TaintTracking::Global; + +module TaintFlow implements TestSig { + string getARelevantTag() { result = "flowfrom" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "flowfrom" and + element = "" and + exists(DataFlow::Node fromNode, DataFlow::Node toNode | + toNode + .hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + Flow::flow(fromNode, toNode) and + value = fromNode.asExpr().(StringLit).getValue() + ) + } +} + +import MakeTest> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/sqlx.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/sqlx.expected deleted file mode 100644 index 0540a78fb34..00000000000 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/sqlx.expected +++ /dev/null @@ -1,12 +0,0 @@ -| sqlx.go:15:17:15:25 | untrusted | -| sqlx.go:16:14:16:22 | untrusted | -| sqlx.go:17:14:17:22 | untrusted | -| sqlx.go:18:12:18:20 | untrusted | -| sqlx.go:19:15:19:23 | untrusted | -| sqlx.go:20:16:20:24 | untrusted | -| sqlx.go:23:17:23:25 | untrusted | -| sqlx.go:24:14:24:22 | untrusted | -| sqlx.go:25:14:25:22 | untrusted | -| sqlx.go:26:12:26:20 | untrusted | -| sqlx.go:27:15:27:23 | untrusted | -| sqlx.go:28:16:28:24 | untrusted | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/sqlx.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/sqlx.go index edc29c4d4ee..e4e8d43395b 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/sqlx.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/sqlx.go @@ -12,19 +12,19 @@ func main() { db := sqlx.DB{} untrusted := getUntrustedString() - db.Select(nil, untrusted) - db.Get(nil, untrusted) - db.MustExec(untrusted) - db.Queryx(untrusted) - db.NamedExec(untrusted, nil) - db.NamedQuery(untrusted, nil) + db.Select(nil, untrusted) // $ querystring=untrusted + db.Get(nil, untrusted) // $ querystring=untrusted + db.MustExec(untrusted) // $ querystring=untrusted + db.Queryx(untrusted) // $ querystring=untrusted + db.NamedExec(untrusted, nil) // $ querystring=untrusted + db.NamedQuery(untrusted, nil) // $ querystring=untrusted tx := sqlx.Tx{} - tx.Select(nil, untrusted) - tx.Get(nil, untrusted) - tx.MustExec(untrusted) - tx.Queryx(untrusted) - tx.NamedExec(untrusted, nil) - tx.NamedQuery(untrusted, nil) + tx.Select(nil, untrusted) // $ querystring=untrusted + tx.Get(nil, untrusted) // $ querystring=untrusted + tx.MustExec(untrusted) // $ querystring=untrusted + tx.Queryx(untrusted) // $ querystring=untrusted + tx.NamedExec(untrusted, nil) // $ querystring=untrusted + tx.NamedQuery(untrusted, nil) // $ querystring=untrusted } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/sqlx.ql b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/sqlx.ql deleted file mode 100644 index 7b56fd97441..00000000000 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/sqlx.ql +++ /dev/null @@ -1,4 +0,0 @@ -import go - -from SQL::QueryString qs -select qs From 1ab50fc62cc0c748f0ccb2630c2247ec3c725cfb Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 15 Aug 2024 15:24:56 +0100 Subject: [PATCH 062/470] Convert Gorm sql-injection sinks to MaD --- go/ql/lib/ext/gorm.io.gorm.model.yml | 25 ++++++++ go/ql/lib/semmle/go/frameworks/SQL.qll | 15 ----- .../frameworks/SQL/Gorm/QueryString.expected | 3 + .../go/frameworks/SQL/Gorm/QueryString.ql | 60 +++++++++++++++++++ .../go/frameworks/SQL/Gorm/gorm.expected | 25 -------- .../semmle/go/frameworks/SQL/Gorm/gorm.go | 51 ++++++++-------- .../semmle/go/frameworks/SQL/Gorm/gorm.ql | 5 -- 7 files changed, 113 insertions(+), 71 deletions(-) create mode 100644 go/ql/lib/ext/gorm.io.gorm.model.yml create mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/QueryString.expected create mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/QueryString.ql delete mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.expected delete mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.ql diff --git a/go/ql/lib/ext/gorm.io.gorm.model.yml b/go/ql/lib/ext/gorm.io.gorm.model.yml new file mode 100644 index 00000000000..bfcf1fa66a7 --- /dev/null +++ b/go/ql/lib/ext/gorm.io.gorm.model.yml @@ -0,0 +1,25 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: packageGrouping + data: + - ["gorm", "gorm.io/gorm"] + - ["gorm", "github.com/jinzhu/gorm"] + - ["gorm", "github.com/go-gorm/gorm"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["group:gorm", "DB", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorm", "DB", True, "Raw", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorm", "DB", True, "Order", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorm", "DB", True, "Not", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorm", "DB", True, "Or", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorm", "DB", True, "Select", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorm", "DB", True, "Table", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorm", "DB", True, "Group", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorm", "DB", True, "Having", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorm", "DB", True, "Joins", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorm", "DB", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorm", "DB", True, "Distinct", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:gorm", "DB", True, "Pluck", "", "", "Argument[0]", "sql-injection", "manual"] diff --git a/go/ql/lib/semmle/go/frameworks/SQL.qll b/go/ql/lib/semmle/go/frameworks/SQL.qll index 304c7f82d87..72003985d77 100644 --- a/go/ql/lib/semmle/go/frameworks/SQL.qll +++ b/go/ql/lib/semmle/go/frameworks/SQL.qll @@ -150,21 +150,6 @@ module SQL { } } } - - /** A model for sinks of GORM. */ - private class GormSink extends SQL::QueryString::Range { - GormSink() { - exists(Method meth, string package, string name | - meth.hasQualifiedName(package, "DB", name) and - this = meth.getACall().getSyntacticArgument(0) and - package = Gorm::packagePath() and - name in [ - "Where", "Raw", "Order", "Not", "Or", "Select", "Table", "Group", "Having", "Joins", - "Exec", "Distinct", "Pluck" - ] - ) - } - } } /** diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/QueryString.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/QueryString.expected new file mode 100644 index 00000000000..db33d6d2504 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/QueryString.expected @@ -0,0 +1,3 @@ +testFailures +invalidModelRow +failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/QueryString.ql b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/QueryString.ql new file mode 100644 index 00000000000..eeb43a82fad --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/QueryString.ql @@ -0,0 +1,60 @@ +import go +import semmle.go.dataflow.ExternalFlow +import ModelValidation +import TestUtilities.InlineExpectationsTest + +module SqlTest implements TestSig { + string getARelevantTag() { result = "query" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "query" and + exists(SQL::Query q, SQL::QueryString qs | qs = q.getAQueryString() | + q.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = q.toString() and + value = qs.toString() + ) + } +} + +module QueryString implements TestSig { + string getARelevantTag() { result = "querystring" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "querystring" and + element = "" and + exists(SQL::QueryString qs | not exists(SQL::Query q | qs = q.getAQueryString()) | + qs.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + value = qs.toString() + ) + } +} + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLit } + + predicate isSink(DataFlow::Node n) { + n = any(DataFlow::CallNode cn | cn.getTarget().getName() = "sink").getAnArgument() + } +} + +module Flow = TaintTracking::Global; + +module TaintFlow implements TestSig { + string getARelevantTag() { result = "flowfrom" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "flowfrom" and + element = "" and + exists(DataFlow::Node fromNode, DataFlow::Node toNode | + toNode + .hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + Flow::flow(fromNode, toNode) and + value = fromNode.asExpr().(StringLit).getValue() + ) + } +} + +import MakeTest> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.expected deleted file mode 100644 index ca70ed07c33..00000000000 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.expected +++ /dev/null @@ -1,25 +0,0 @@ -| gorm.go:20:12:20:20 | untrusted | github.com/jinzhu/gorm | DB | Where | -| gorm.go:21:10:21:18 | untrusted | github.com/jinzhu/gorm | DB | Raw | -| gorm.go:22:10:22:18 | untrusted | github.com/jinzhu/gorm | DB | Not | -| gorm.go:23:12:23:20 | untrusted | github.com/jinzhu/gorm | DB | Order | -| gorm.go:24:9:24:17 | untrusted | github.com/jinzhu/gorm | DB | Or | -| gorm.go:25:13:25:21 | untrusted | github.com/jinzhu/gorm | DB | Select | -| gorm.go:26:12:26:20 | untrusted | github.com/jinzhu/gorm | DB | Table | -| gorm.go:27:12:27:20 | untrusted | github.com/jinzhu/gorm | DB | Group | -| gorm.go:28:13:28:21 | untrusted | github.com/jinzhu/gorm | DB | Having | -| gorm.go:29:12:29:20 | untrusted | github.com/jinzhu/gorm | DB | Joins | -| gorm.go:30:11:30:19 | untrusted | github.com/jinzhu/gorm | DB | Exec | -| gorm.go:31:12:31:20 | untrusted | github.com/jinzhu/gorm | DB | Pluck | -| gorm.go:34:12:34:20 | untrusted | gorm.io/gorm | DB | Where | -| gorm.go:35:10:35:18 | untrusted | gorm.io/gorm | DB | Raw | -| gorm.go:36:10:36:18 | untrusted | gorm.io/gorm | DB | Not | -| gorm.go:37:12:37:20 | untrusted | gorm.io/gorm | DB | Order | -| gorm.go:38:9:38:17 | untrusted | gorm.io/gorm | DB | Or | -| gorm.go:39:13:39:21 | untrusted | gorm.io/gorm | DB | Select | -| gorm.go:40:12:40:20 | untrusted | gorm.io/gorm | DB | Table | -| gorm.go:41:12:41:20 | untrusted | gorm.io/gorm | DB | Group | -| gorm.go:42:13:42:21 | untrusted | gorm.io/gorm | DB | Having | -| gorm.go:43:12:43:20 | untrusted | gorm.io/gorm | DB | Joins | -| gorm.go:44:11:44:19 | untrusted | gorm.io/gorm | DB | Exec | -| gorm.go:45:15:45:23 | untrusted | gorm.io/gorm | DB | Distinct | -| gorm.go:46:12:46:20 | untrusted | gorm.io/gorm | DB | Pluck | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.go index bee8edbf7af..2d736e2407c 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.go @@ -13,36 +13,35 @@ func getUntrustedString() string { } func main() { - untrusted := getUntrustedString() db1 := gorm1.DB{} - db1.Where(untrusted) - db1.Raw(untrusted) - db1.Not(untrusted) - db1.Order(untrusted) - db1.Or(untrusted) - db1.Select(untrusted) - db1.Table(untrusted) - db1.Group(untrusted) - db1.Having(untrusted) - db1.Joins(untrusted) - db1.Exec(untrusted) - db1.Pluck(untrusted, nil) + db1.Where(untrusted) // $ querystring=untrusted + db1.Raw(untrusted) // $ querystring=untrusted + db1.Not(untrusted) // $ querystring=untrusted + db1.Order(untrusted) // $ querystring=untrusted + db1.Or(untrusted) // $ querystring=untrusted + db1.Select(untrusted) // $ querystring=untrusted + db1.Table(untrusted) // $ querystring=untrusted + db1.Group(untrusted) // $ querystring=untrusted + db1.Having(untrusted) // $ querystring=untrusted + db1.Joins(untrusted) // $ querystring=untrusted + db1.Exec(untrusted) // $ querystring=untrusted + db1.Pluck(untrusted, nil) // $ querystring=untrusted db2 := gorm2.DB{} - db2.Where(untrusted) - db2.Raw(untrusted) - db2.Not(untrusted) - db2.Order(untrusted) - db2.Or(untrusted) - db2.Select(untrusted) - db2.Table(untrusted) - db2.Group(untrusted) - db2.Having(untrusted) - db2.Joins(untrusted) - db2.Exec(untrusted) - db2.Distinct(untrusted) - db2.Pluck(untrusted, nil) + db2.Where(untrusted) // $ querystring=untrusted + db2.Raw(untrusted) // $ querystring=untrusted + db2.Not(untrusted) // $ querystring=untrusted + db2.Order(untrusted) // $ querystring=untrusted + db2.Or(untrusted) // $ querystring=untrusted + db2.Select(untrusted) // $ querystring=untrusted + db2.Table(untrusted) // $ querystring=untrusted + db2.Group(untrusted) // $ querystring=untrusted + db2.Having(untrusted) // $ querystring=untrusted + db2.Joins(untrusted) // $ querystring=untrusted + db2.Exec(untrusted) // $ querystring=untrusted + db2.Distinct(untrusted) // $ querystring=untrusted + db2.Pluck(untrusted, nil) // $ querystring=untrusted } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.ql b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.ql deleted file mode 100644 index e08b506deaf..00000000000 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.ql +++ /dev/null @@ -1,5 +0,0 @@ -import go - -from SQL::QueryString qs, Method meth, string a, string b, string c -where meth.hasQualifiedName(a, b, c) and qs = meth.getACall().getSyntacticArgument(0) -select qs, a, b, c From 1c305aa8f3f1c2690cf21ecfe15afd7c83fc3b33 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 15 Aug 2024 15:38:07 +0100 Subject: [PATCH 063/470] Convert Xorm sql-injection sinks to MaD --- go/ql/lib/ext/xorm.io.xorm.model.yml | 53 ++++++++++++++++++++++++++ go/ql/lib/semmle/go/frameworks/SQL.qll | 22 ----------- 2 files changed, 53 insertions(+), 22 deletions(-) create mode 100644 go/ql/lib/ext/xorm.io.xorm.model.yml diff --git a/go/ql/lib/ext/xorm.io.xorm.model.yml b/go/ql/lib/ext/xorm.io.xorm.model.yml new file mode 100644 index 00000000000..fd73b7c9a66 --- /dev/null +++ b/go/ql/lib/ext/xorm.io.xorm.model.yml @@ -0,0 +1,53 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: packageGrouping + data: + - ["xorm", "xorm.io/xorm"] + - ["xorm", "github.com/go-xorm/xorm"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["group:xorm", "Engine", True, "Alias", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "And", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "GroupBy", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "Having", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "In", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "Join", "", "", "Argument[0..2]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "NotIn", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "Or", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "QueryString", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "QueryInterface", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "Select", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "SetExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "SQL", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "Sum", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "Sums", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "SumInt", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "SumsInt", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:xorm", "Engine", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "Alias", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "And", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "GroupBy", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "Having", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "In", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "Join", "", "", "Argument[0..2]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "NotIn", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "Or", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "QueryString", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "QueryInterface", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "Select", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "SetExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "SQL", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "Sum", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "Sums", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "SumInt", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "SumsInt", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:xorm", "Session", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] diff --git a/go/ql/lib/semmle/go/frameworks/SQL.qll b/go/ql/lib/semmle/go/frameworks/SQL.qll index 72003985d77..f4367da7854 100644 --- a/go/ql/lib/semmle/go/frameworks/SQL.qll +++ b/go/ql/lib/semmle/go/frameworks/SQL.qll @@ -168,28 +168,6 @@ module Gorm { module Xorm { /** Gets the package name for Xorm. */ string packagePath() { result = package(["xorm.io/xorm", "github.com/go-xorm/xorm"], "") } - - /** A model for sinks of XORM. */ - private class XormSink extends SQL::QueryString::Range { - XormSink() { - exists(Method meth, string type, string name, int n | - meth.hasQualifiedName(Xorm::packagePath(), type, name) and - this = meth.getACall().getSyntacticArgument(n) and - type = ["Engine", "Session"] - | - name = - [ - "Query", "Exec", "QueryString", "QueryInterface", "SQL", "Where", "And", "Or", "Alias", - "NotIn", "In", "Select", "SetExpr", "OrderBy", "Having", "GroupBy" - ] and - n = 0 - or - name = ["SumInt", "Sum", "Sums", "SumsInt"] and n = 1 - or - name = "Join" and n = [0, 1, 2] - ) - } - } } /** From 2282a8184b8435cf2e0232a867eb87526107ceda Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 15 Aug 2024 16:10:11 +0100 Subject: [PATCH 064/470] Convert Bun sql-injection sinks to MaD --- .../lib/ext/github.com.uptrace.bun.model.yml | 68 +++++++++++++++++++ go/ql/lib/semmle/go/frameworks/SQL.qll | 43 +----------- .../frameworks/SQL/bun/QueryString.expected | 3 + .../go/frameworks/SQL/bun/QueryString.ql | 60 ++++++++++++++++ .../semmle/go/frameworks/SQL/bun/bun.go | 42 ++++++------ 5 files changed, 155 insertions(+), 61 deletions(-) create mode 100644 go/ql/lib/ext/github.com.uptrace.bun.model.yml create mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/QueryString.expected create mode 100644 go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/QueryString.ql diff --git a/go/ql/lib/ext/github.com.uptrace.bun.model.yml b/go/ql/lib/ext/github.com.uptrace.bun.model.yml new file mode 100644 index 00000000000..eb060b4f9cc --- /dev/null +++ b/go/ql/lib/ext/github.com.uptrace.bun.model.yml @@ -0,0 +1,68 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["github.com/uptrace/bun", "", True, "NewRawQuery", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "AddColumnQuery", True, "ColumnExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "AddColumnQuery", True, "ModelTableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "AddColumnQuery", True, "TableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "Conn", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "Conn", True, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "Conn", True, "NewRaw", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "Conn", True, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "Conn", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "Conn", True, "QueryRow", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "Conn", True, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "Conn", True, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "Conn", True, "QueryRowContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "Conn", True, "Raw", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "CreateIndexQuery", True, "ColumnExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "CreateIndexQuery", True, "ModelTableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "CreateIndexQuery", True, "TableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "CreateIndexQuery", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "CreateIndexQuery", True, "WhereOr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "CreateTableQuery", True, "ColumnExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "CreateTableQuery", True, "ModelTableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "CreateTableQuery", True, "TableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DB", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DB", True, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DB", True, "NewRaw", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DB", True, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DB", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DB", True, "QueryRow", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DB", True, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DB", True, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DB", True, "QueryRowContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DB", True, "Raw", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DeleteQuery", True, "TableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DeleteQuery", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DeleteQuery", True, "WhereOr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DropColumnQuery", True, "ColumnExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DropColumnQuery", True, "ModelTableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DropColumnQuery", True, "TableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DropTableQuery", True, "ModelTableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "DropTableQuery", True, "TableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "InsertQuery", True, "ColumnExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "InsertQuery", True, "ModelTableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "InsertQuery", True, "TableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "InsertQuery", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "InsertQuery", True, "WhereOr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "MergeQuery", True, "ModelTableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "MergeQuery", True, "TableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "RawQuery", True, "NewRaw", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "SelectQuery", True, "ColumnExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "SelectQuery", True, "DistinctOn", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "SelectQuery", True, "For", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "SelectQuery", True, "GroupExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "SelectQuery", True, "Having", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "SelectQuery", True, "ModelTableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "SelectQuery", True, "OrderExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "SelectQuery", True, "TableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "SelectQuery", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "SelectQuery", True, "WhereOr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "TruncateTableQuery", True, "TableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "UpdateQuery", True, "ModelTableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "UpdateQuery", True, "TableExpr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "UpdateQuery", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "UpdateQuery", True, "WhereOr", "", "", "Argument[0]", "sql-injection", "manual"] diff --git a/go/ql/lib/semmle/go/frameworks/SQL.qll b/go/ql/lib/semmle/go/frameworks/SQL.qll index f4367da7854..c2a550602e1 100644 --- a/go/ql/lib/semmle/go/frameworks/SQL.qll +++ b/go/ql/lib/semmle/go/frameworks/SQL.qll @@ -171,45 +171,8 @@ module Xorm { } /** + * DEPRECATED + * * Provides classes for working with the [Bun](https://bun.uptrace.dev/) package. */ -module Bun { - /** Gets the package name for Bun package. */ - private string packagePath() { result = package("github.com/uptrace/bun", "") } - - /** A model for sinks of Bun. */ - private class BunSink extends SQL::QueryString::Range { - BunSink() { - exists(Function f, string m, int arg | this = f.getACall().getArgument(arg) | - f.hasQualifiedName(packagePath(), m) and - m = "NewRawQuery" and - arg = 1 - ) - or - exists(Method f, string tp, string m, int arg | this = f.getACall().getArgument(arg) | - f.hasQualifiedName(packagePath(), tp, m) and - ( - tp = ["DB", "Conn"] and - m = ["ExecContext", "PrepareContext", "QueryContext", "QueryRowContext"] and - arg = 1 - or - tp = ["DB", "Conn"] and - m = ["Exec", "NewRaw", "Prepare", "Query", "QueryRow", "Raw"] and - arg = 0 - or - tp.matches("%Query") and - m = - [ - "ColumnExpr", "DistinctOn", "For", "GroupExpr", "Having", "ModelTableExpr", - "OrderExpr", "TableExpr", "Where", "WhereOr" - ] and - arg = 0 - or - tp = "RawQuery" and - m = "NewRaw" and - arg = 0 - ) - ) - } - } -} +deprecated module Bun { } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/QueryString.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/QueryString.expected new file mode 100644 index 00000000000..105b7026d0c --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/QueryString.expected @@ -0,0 +1,3 @@ +failures +invalidModelRow +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/QueryString.ql b/go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/QueryString.ql new file mode 100644 index 00000000000..eeb43a82fad --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/QueryString.ql @@ -0,0 +1,60 @@ +import go +import semmle.go.dataflow.ExternalFlow +import ModelValidation +import TestUtilities.InlineExpectationsTest + +module SqlTest implements TestSig { + string getARelevantTag() { result = "query" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "query" and + exists(SQL::Query q, SQL::QueryString qs | qs = q.getAQueryString() | + q.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = q.toString() and + value = qs.toString() + ) + } +} + +module QueryString implements TestSig { + string getARelevantTag() { result = "querystring" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "querystring" and + element = "" and + exists(SQL::QueryString qs | not exists(SQL::Query q | qs = q.getAQueryString()) | + qs.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + value = qs.toString() + ) + } +} + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLit } + + predicate isSink(DataFlow::Node n) { + n = any(DataFlow::CallNode cn | cn.getTarget().getName() = "sink").getAnArgument() + } +} + +module Flow = TaintTracking::Global; + +module TaintFlow implements TestSig { + string getARelevantTag() { result = "flowfrom" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "flowfrom" and + element = "" and + exists(DataFlow::Node fromNode, DataFlow::Node toNode | + toNode + .hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + Flow::flow(fromNode, toNode) and + value = fromNode.asExpr().(StringLit).getValue() + ) + } +} + +import MakeTest> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/bun.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/bun.go index 8ce4e5b0826..44a2e2c2fce 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/bun.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/bun.go @@ -22,28 +22,28 @@ func main() { panic(err) } db := bun.NewDB(sqlite, sqlitedialect.New()) - bun.NewRawQuery(db, untrusted) + bun.NewRawQuery(db, untrusted) // $ querystring=untrusted - db.ExecContext(ctx, untrusted) - db.PrepareContext(ctx, untrusted) - db.QueryContext(ctx, untrusted) - db.QueryRowContext(ctx, untrusted) + db.ExecContext(ctx, untrusted) // $ querystring=untrusted + db.PrepareContext(ctx, untrusted) // $ querystring=untrusted + db.QueryContext(ctx, untrusted) // $ querystring=untrusted + db.QueryRowContext(ctx, untrusted) // $ querystring=untrusted - db.Exec(untrusted) - db.NewRaw(untrusted) - db.Prepare(untrusted) - db.Query(untrusted) - db.QueryRow(untrusted) - db.Raw(untrusted) + db.Exec(untrusted) // $ querystring=untrusted + db.NewRaw(untrusted) // $ querystring=untrusted + db.Prepare(untrusted) // $ querystring=untrusted + db.Query(untrusted) // $ querystring=untrusted + db.QueryRow(untrusted) // $ querystring=untrusted + db.Raw(untrusted) // $ querystring=untrusted - db.NewSelect().ColumnExpr(untrusted) - db.NewSelect().DistinctOn(untrusted) - db.NewSelect().For(untrusted) - db.NewSelect().GroupExpr(untrusted) - db.NewSelect().Having(untrusted) - db.NewSelect().ModelTableExpr(untrusted) - db.NewSelect().OrderExpr(untrusted) - db.NewSelect().TableExpr(untrusted) - db.NewSelect().Where(untrusted) - db.NewSelect().WhereOr(untrusted) + db.NewSelect().ColumnExpr(untrusted) // $ querystring=untrusted + db.NewSelect().DistinctOn(untrusted) // $ querystring=untrusted + db.NewSelect().For(untrusted) // $ querystring=untrusted + db.NewSelect().GroupExpr(untrusted) // $ querystring=untrusted + db.NewSelect().Having(untrusted) // $ querystring=untrusted + db.NewSelect().ModelTableExpr(untrusted) // $ querystring=untrusted + db.NewSelect().OrderExpr(untrusted) // $ querystring=untrusted + db.NewSelect().TableExpr(untrusted) // $ querystring=untrusted + db.NewSelect().Where(untrusted) // $ querystring=untrusted + db.NewSelect().WhereOr(untrusted) // $ querystring=untrusted } From 4cca6cff59fbc2bd13799d4e294d9d66883fbe6d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 15 Aug 2024 16:46:02 +0100 Subject: [PATCH 065/470] Convert Beego orm sql-injection sinks to MaD --- ...ithub.com.beego.beego.client.orm.model.yml | 42 +++++++++ go/ql/lib/semmle/go/frameworks/BeegoOrm.qll | 51 ----------- .../frameworks/BeegoOrm/SqlInjection.expected | 87 ++++++++++++------- 3 files changed, 96 insertions(+), 84 deletions(-) create mode 100644 go/ql/lib/ext/github.com.beego.beego.client.orm.model.yml diff --git a/go/ql/lib/ext/github.com.beego.beego.client.orm.model.yml b/go/ql/lib/ext/github.com.beego.beego.client.orm.model.yml new file mode 100644 index 00000000000..9e8849423eb --- /dev/null +++ b/go/ql/lib/ext/github.com.beego.beego.client.orm.model.yml @@ -0,0 +1,42 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: packageGrouping + data: + - ["beego-orm", "github.com/beego/beego/client/orm"] + - ["beego-orm", "github.com/astaxie/beego/orm"] + - ["beego-orm", "github.com/beego/beego/orm"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["group:beego-orm", "Condition", False, "Raw", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", False, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", False, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", False, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", False, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", False, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", False, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", False, "QueryRow", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", False, "QueryRowContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:beego-orm", "Ormer", False, "Raw", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "And", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "Delete", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "From", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "GroupBy", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "Having", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "In", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "InnerJoin", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "InsertInto", "", "", "Argument[0..1]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "LeftJoin", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "On", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "Or", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "RightJoin", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "Select", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "Set", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "Subquery", "", "", "Argument[0..1]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "Update", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "Values", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", False, "Where", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QuerySeter", False, "FilterRaw", "", "", "Argument[1]", "sql-injection", "manual"] diff --git a/go/ql/lib/semmle/go/frameworks/BeegoOrm.qll b/go/ql/lib/semmle/go/frameworks/BeegoOrm.qll index c1de0cf4244..925b0f19fa3 100644 --- a/go/ql/lib/semmle/go/frameworks/BeegoOrm.qll +++ b/go/ql/lib/semmle/go/frameworks/BeegoOrm.qll @@ -14,57 +14,6 @@ module BeegoOrm { /** Gets the package name `github.com/astaxie/beego/orm`. */ string packagePath() { result = package("github.com/astaxie/beego", "orm") } - private class DbSink extends SQL::QueryString::Range { - DbSink() { - exists(Method m, string methodName, int argNum | - m.hasQualifiedName(packagePath(), "DB", methodName) and - ( - methodName = ["Exec", "Prepare", "Query", "QueryRow"] and - argNum = 0 - or - methodName = ["ExecContext", "PrepareContext", "QueryContext", "QueryRowContext"] and - argNum = 1 - ) - | - this = m.getACall().getArgument(argNum) - ) - } - } - - private class QueryBuilderSink extends SQL::QueryString::Range { - // Note this class doesn't do any escaping, unlike the true ORM part of the package - QueryBuilderSink() { - exists(Method impl | impl.implements(packagePath(), "QueryBuilder", _) | - this = impl.getACall().getASyntacticArgument() - ) and - this.getType().getUnderlyingType() instanceof StringType - } - } - - private class OrmerRawSink extends SQL::QueryString::Range { - OrmerRawSink() { - exists(Method impl | impl.implements(packagePath(), "Ormer", "Raw") | - this = impl.getACall().getArgument(0) - ) - } - } - - private class QuerySeterFilterRawSink extends SQL::QueryString::Range { - QuerySeterFilterRawSink() { - exists(Method impl | impl.implements(packagePath(), "QuerySeter", "FilterRaw") | - this = impl.getACall().getArgument(1) - ) - } - } - - private class ConditionRawSink extends SQL::QueryString::Range { - ConditionRawSink() { - exists(Method impl | impl.implements(packagePath(), "Condition", "Raw") | - this = impl.getACall().getArgument(1) - ) - } - } - private class OrmerSource extends StoredXss::Source { OrmerSource() { exists(Method impl | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.expected b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.expected index 6cc1e09486b..992c1387103 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.expected @@ -32,40 +32,61 @@ | test.go:59:31:59:39 | untrusted | test.go:57:15:57:41 | call to UserAgent | test.go:59:31:59:39 | untrusted | This query depends on a $@. | test.go:57:15:57:41 | call to UserAgent | user-provided value | | test.go:65:19:65:27 | untrusted | test.go:63:15:63:41 | call to UserAgent | test.go:65:19:65:27 | untrusted | This query depends on a $@. | test.go:63:15:63:41 | call to UserAgent | user-provided value | edges -| test.go:11:15:11:41 | call to UserAgent | test.go:13:11:13:19 | untrusted | provenance | Src:MaD:1 | -| test.go:11:15:11:41 | call to UserAgent | test.go:14:23:14:31 | untrusted | provenance | Src:MaD:1 | -| test.go:11:15:11:41 | call to UserAgent | test.go:15:14:15:22 | untrusted | provenance | Src:MaD:1 | -| test.go:11:15:11:41 | call to UserAgent | test.go:16:26:16:34 | untrusted | provenance | Src:MaD:1 | -| test.go:11:15:11:41 | call to UserAgent | test.go:17:12:17:20 | untrusted | provenance | Src:MaD:1 | -| test.go:11:15:11:41 | call to UserAgent | test.go:18:24:18:32 | untrusted | provenance | Src:MaD:1 | -| test.go:11:15:11:41 | call to UserAgent | test.go:19:15:19:23 | untrusted | provenance | Src:MaD:1 | -| test.go:11:15:11:41 | call to UserAgent | test.go:20:27:20:35 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:28:12:28:20 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:29:10:29:18 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:30:15:30:23 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:31:14:31:22 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:32:15:32:23 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:33:8:33:16 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:34:11:34:19 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:35:9:35:17 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:36:8:36:16 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:37:8:37:16 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:38:13:38:21 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:39:13:39:21 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:40:12:40:20 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:41:12:41:20 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:42:9:42:17 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:43:12:43:20 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:44:16:44:24 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:45:12:45:20 | untrusted | provenance | Src:MaD:1 | -| test.go:25:15:25:41 | call to UserAgent | test.go:46:14:46:22 | untrusted | provenance | Src:MaD:1 | -| test.go:26:16:26:42 | call to UserAgent | test.go:44:27:44:36 | untrusted2 | provenance | Src:MaD:1 | -| test.go:26:16:26:42 | call to UserAgent | test.go:46:25:46:34 | untrusted2 | provenance | Src:MaD:1 | -| test.go:50:15:50:41 | call to UserAgent | test.go:52:12:52:20 | untrusted | provenance | Src:MaD:1 | -| test.go:57:15:57:41 | call to UserAgent | test.go:59:31:59:39 | untrusted | provenance | Src:MaD:1 | -| test.go:63:15:63:41 | call to UserAgent | test.go:65:19:65:27 | untrusted | provenance | Src:MaD:1 | +| test.go:11:15:11:41 | call to UserAgent | test.go:13:11:13:19 | untrusted | provenance | Src:MaD:22 Sink:MaD:2 | +| test.go:11:15:11:41 | call to UserAgent | test.go:14:23:14:31 | untrusted | provenance | Src:MaD:22 Sink:MaD:3 | +| test.go:11:15:11:41 | call to UserAgent | test.go:15:14:15:22 | untrusted | provenance | Src:MaD:22 Sink:MaD:4 | +| test.go:11:15:11:41 | call to UserAgent | test.go:16:26:16:34 | untrusted | provenance | Src:MaD:22 Sink:MaD:5 | +| test.go:11:15:11:41 | call to UserAgent | test.go:17:12:17:20 | untrusted | provenance | Src:MaD:22 Sink:MaD:6 | +| test.go:11:15:11:41 | call to UserAgent | test.go:18:24:18:32 | untrusted | provenance | Src:MaD:22 Sink:MaD:7 | +| test.go:11:15:11:41 | call to UserAgent | test.go:19:15:19:23 | untrusted | provenance | Src:MaD:22 Sink:MaD:8 | +| test.go:11:15:11:41 | call to UserAgent | test.go:20:27:20:35 | untrusted | provenance | Src:MaD:22 Sink:MaD:9 | +| test.go:25:15:25:41 | call to UserAgent | test.go:28:12:28:20 | untrusted | provenance | Src:MaD:22 | +| test.go:25:15:25:41 | call to UserAgent | test.go:29:10:29:18 | untrusted | provenance | Src:MaD:22 | +| test.go:25:15:25:41 | call to UserAgent | test.go:30:15:30:23 | untrusted | provenance | Src:MaD:22 Sink:MaD:13 | +| test.go:25:15:25:41 | call to UserAgent | test.go:31:14:31:22 | untrusted | provenance | Src:MaD:22 Sink:MaD:15 | +| test.go:25:15:25:41 | call to UserAgent | test.go:32:15:32:23 | untrusted | provenance | Src:MaD:22 Sink:MaD:18 | +| test.go:25:15:25:41 | call to UserAgent | test.go:33:8:33:16 | untrusted | provenance | Src:MaD:22 Sink:MaD:16 | +| test.go:25:15:25:41 | call to UserAgent | test.go:34:11:34:19 | untrusted | provenance | Src:MaD:22 Sink:MaD:20 | +| test.go:25:15:25:41 | call to UserAgent | test.go:35:9:35:17 | untrusted | provenance | Src:MaD:22 Sink:MaD:11 | +| test.go:25:15:25:41 | call to UserAgent | test.go:36:8:36:16 | untrusted | provenance | Src:MaD:22 Sink:MaD:17 | +| test.go:25:15:25:41 | call to UserAgent | test.go:37:8:37:16 | untrusted | provenance | Src:MaD:22 | +| test.go:25:15:25:41 | call to UserAgent | test.go:38:13:38:21 | untrusted | provenance | Src:MaD:22 | +| test.go:25:15:25:41 | call to UserAgent | test.go:39:13:39:21 | untrusted | provenance | Src:MaD:22 | +| test.go:25:15:25:41 | call to UserAgent | test.go:40:12:40:20 | untrusted | provenance | Src:MaD:22 Sink:MaD:12 | +| test.go:25:15:25:41 | call to UserAgent | test.go:41:12:41:20 | untrusted | provenance | Src:MaD:22 | +| test.go:25:15:25:41 | call to UserAgent | test.go:42:9:42:17 | untrusted | provenance | Src:MaD:22 | +| test.go:25:15:25:41 | call to UserAgent | test.go:43:12:43:20 | untrusted | provenance | Src:MaD:22 | +| test.go:25:15:25:41 | call to UserAgent | test.go:44:16:44:24 | untrusted | provenance | Src:MaD:22 Sink:MaD:14 | +| test.go:25:15:25:41 | call to UserAgent | test.go:45:12:45:20 | untrusted | provenance | Src:MaD:22 | +| test.go:25:15:25:41 | call to UserAgent | test.go:46:14:46:22 | untrusted | provenance | Src:MaD:22 Sink:MaD:19 | +| test.go:26:16:26:42 | call to UserAgent | test.go:44:27:44:36 | untrusted2 | provenance | Src:MaD:22 | +| test.go:26:16:26:42 | call to UserAgent | test.go:46:25:46:34 | untrusted2 | provenance | Src:MaD:22 Sink:MaD:19 | +| test.go:50:15:50:41 | call to UserAgent | test.go:52:12:52:20 | untrusted | provenance | Src:MaD:22 Sink:MaD:10 | +| test.go:57:15:57:41 | call to UserAgent | test.go:59:31:59:39 | untrusted | provenance | Src:MaD:22 Sink:MaD:21 | +| test.go:63:15:63:41 | call to UserAgent | test.go:65:19:65:27 | untrusted | provenance | Src:MaD:22 Sink:MaD:1 | models -| 1 | Source: net/http; Request; true; UserAgent; ; ; ReturnValue; remote; manual | +| 1 | Sink: group:beego-orm; Condition; false; Raw; ; ; Argument[1]; sql-injection; manual | +| 2 | Sink: group:beego-orm; DB; false; Exec; ; ; Argument[0]; sql-injection; manual | +| 3 | Sink: group:beego-orm; DB; false; ExecContext; ; ; Argument[1]; sql-injection; manual | +| 4 | Sink: group:beego-orm; DB; false; Prepare; ; ; Argument[0]; sql-injection; manual | +| 5 | Sink: group:beego-orm; DB; false; PrepareContext; ; ; Argument[1]; sql-injection; manual | +| 6 | Sink: group:beego-orm; DB; false; Query; ; ; Argument[0]; sql-injection; manual | +| 7 | Sink: group:beego-orm; DB; false; QueryContext; ; ; Argument[1]; sql-injection; manual | +| 8 | Sink: group:beego-orm; DB; false; QueryRow; ; ; Argument[0]; sql-injection; manual | +| 9 | Sink: group:beego-orm; DB; false; QueryRowContext; ; ; Argument[1]; sql-injection; manual | +| 10 | Sink: group:beego-orm; Ormer; false; Raw; ; ; Argument[0]; sql-injection; manual | +| 11 | Sink: group:beego-orm; QueryBuilder; false; And; ; ; Argument[0]; sql-injection; manual | +| 12 | Sink: group:beego-orm; QueryBuilder; false; Having; ; ; Argument[0]; sql-injection; manual | +| 13 | Sink: group:beego-orm; QueryBuilder; false; InnerJoin; ; ; Argument[0]; sql-injection; manual | +| 14 | Sink: group:beego-orm; QueryBuilder; false; InsertInto; ; ; Argument[0..1]; sql-injection; manual | +| 15 | Sink: group:beego-orm; QueryBuilder; false; LeftJoin; ; ; Argument[0]; sql-injection; manual | +| 16 | Sink: group:beego-orm; QueryBuilder; false; On; ; ; Argument[0]; sql-injection; manual | +| 17 | Sink: group:beego-orm; QueryBuilder; false; Or; ; ; Argument[0]; sql-injection; manual | +| 18 | Sink: group:beego-orm; QueryBuilder; false; RightJoin; ; ; Argument[0]; sql-injection; manual | +| 19 | Sink: group:beego-orm; QueryBuilder; false; Subquery; ; ; Argument[0..1]; sql-injection; manual | +| 20 | Sink: group:beego-orm; QueryBuilder; false; Where; ; ; Argument[0]; sql-injection; manual | +| 21 | Sink: group:beego-orm; QuerySeter; false; FilterRaw; ; ; Argument[1]; sql-injection; manual | +| 22 | Source: net/http; Request; true; UserAgent; ; ; ReturnValue; remote; manual | nodes | test.go:11:15:11:41 | call to UserAgent | semmle.label | call to UserAgent | | test.go:13:11:13:19 | untrusted | semmle.label | untrusted | From e4eef6791a3cebac86eaa81cb0893d838c91af69 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 15 Aug 2024 16:57:26 +0100 Subject: [PATCH 066/470] Convert database/sql sql-injection sinks to MaD --- go/ql/lib/ext/database.sql.model.yml | 28 +++++++++++++++++++ .../go/frameworks/stdlib/DatabaseSql.qll | 20 +------------ .../frameworks/XNetHtml/SqlInjection.expected | 9 +++--- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/go/ql/lib/ext/database.sql.model.yml b/go/ql/lib/ext/database.sql.model.yml index e1083f6e49a..b8fb85bb893 100644 --- a/go/ql/lib/ext/database.sql.model.yml +++ b/go/ql/lib/ext/database.sql.model.yml @@ -1,4 +1,32 @@ extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["database/sql", "Conn", False, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Conn", False, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Conn", False, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Conn", False, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Conn", False, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Conn", False, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Conn", False, "QueryRow", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Conn", False, "QueryRowContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "DB", False, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "DB", False, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "DB", False, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "DB", False, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "DB", False, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "DB", False, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "DB", False, "QueryRow", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "DB", False, "QueryRowContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Tx", False, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Tx", False, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Tx", False, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Tx", False, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Tx", False, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Tx", False, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Tx", False, "QueryRow", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Tx", False, "QueryRowContext", "", "", "Argument[1]", "sql-injection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/DatabaseSql.qll b/go/ql/lib/semmle/go/frameworks/stdlib/DatabaseSql.qll index 845225af5bd..5f53ea2de8c 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/DatabaseSql.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/DatabaseSql.qll @@ -26,7 +26,7 @@ module DatabaseSql { override DataFlow::Node getAResult() { result = this.getResult(0) } override SQL::QueryString getAQueryString() { - result = this.getAnArgument() + result = this.getASyntacticArgument() or // attempt to resolve a `QueryString` for `Stmt`s using local data flow. t = "Stmt" and @@ -34,24 +34,6 @@ module DatabaseSql { } } - /** A query string used in an API function of the `database/sql` package. */ - private class QueryString extends SQL::QueryString::Range { - QueryString() { - exists(Method meth, string base, string t, string m, int n | - t = ["DB", "Tx", "Conn"] and - meth.hasQualifiedName("database/sql", t, m) and - this = meth.getACall().getArgument(n) - | - base = ["Exec", "Prepare", "Query", "QueryRow"] and - ( - m = base and n = 0 - or - m = base + "Context" and n = 1 - ) - ) - } - } - /** A query in the standard `database/sql/driver` package. */ private class DriverQuery extends SQL::Query::Range, DataFlow::MethodCallNode { DriverQuery() { diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected index c28b1058e7c..d0b5c378c92 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected @@ -1,11 +1,12 @@ #select | test.go:57:11:57:41 | call to EscapeString | test.go:56:2:56:42 | ... := ...[0] | test.go:57:11:57:41 | call to EscapeString | This query depends on a $@. | test.go:56:2:56:42 | ... := ...[0] | user-provided value | edges -| test.go:56:2:56:42 | ... := ...[0] | test.go:57:29:57:40 | selection of Value | provenance | Src:MaD:1 | -| test.go:57:29:57:40 | selection of Value | test.go:57:11:57:41 | call to EscapeString | provenance | MaD:2 | +| test.go:56:2:56:42 | ... := ...[0] | test.go:57:29:57:40 | selection of Value | provenance | Src:MaD:2 | +| test.go:57:29:57:40 | selection of Value | test.go:57:11:57:41 | call to EscapeString | provenance | MaD:3 Sink:MaD:1 | models -| 1 | Source: net/http; Request; true; Cookie; ; ; ReturnValue[0]; remote; manual | -| 2 | Summary: golang.org/x/net/html; ; false; EscapeString; ; ; Argument[0]; ReturnValue; taint; manual | +| 1 | Sink: database/sql; DB; false; Query; ; ; Argument[0]; sql-injection; manual | +| 2 | Source: net/http; Request; true; Cookie; ; ; ReturnValue[0]; remote; manual | +| 3 | Summary: golang.org/x/net/html; ; false; EscapeString; ; ; Argument[0]; ReturnValue; taint; manual | nodes | test.go:56:2:56:42 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:57:11:57:41 | call to EscapeString | semmle.label | call to EscapeString | From b4c84be3bebf63c69b158bc18044a7d0fab7cc31 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 15 Aug 2024 21:35:07 +0100 Subject: [PATCH 067/470] Convert database/sql/driver sql-injection sinks to MaD --- go/ql/lib/ext/database.sql.driver.model.yml | 10 ++++++++ .../go/frameworks/stdlib/DatabaseSql.qll | 25 +------------------ 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/go/ql/lib/ext/database.sql.driver.model.yml b/go/ql/lib/ext/database.sql.driver.model.yml index c2d780bb7c8..50b699e4371 100644 --- a/go/ql/lib/ext/database.sql.driver.model.yml +++ b/go/ql/lib/ext/database.sql.driver.model.yml @@ -1,4 +1,14 @@ extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["database/sql/driver", "Execer", False, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql/driver", "ExecerContext", False, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql/driver", "Conn", False, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql/driver", "ConnPrepareContext", False, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql/driver", "Queryer", False, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql/driver", "QueryerContext", False, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/DatabaseSql.qll b/go/ql/lib/semmle/go/frameworks/stdlib/DatabaseSql.qll index 5f53ea2de8c..f4132688796 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/DatabaseSql.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/DatabaseSql.qll @@ -60,36 +60,13 @@ module DatabaseSql { override DataFlow::Node getAResult() { result = this.getResult(0) } override SQL::QueryString getAQueryString() { - result = this.getAnArgument() + result = this.getASyntacticArgument() or this.getTarget().hasQualifiedName("database/sql/driver", "Stmt") and result = this.getReceiver().getAPredecessor*().(DataFlow::MethodCallNode).getAnArgument() } } - /** A query string used in an API function of the standard `database/sql/driver` package. */ - private class DriverQueryString extends SQL::QueryString::Range { - DriverQueryString() { - exists(Method meth, int n | - ( - meth.hasQualifiedName("database/sql/driver", "Execer", "Exec") and n = 0 - or - meth.hasQualifiedName("database/sql/driver", "ExecerContext", "ExecContext") and n = 1 - or - meth.hasQualifiedName("database/sql/driver", "Conn", "Prepare") and n = 0 - or - meth.hasQualifiedName("database/sql/driver", "ConnPrepareContext", "PrepareContext") and - n = 1 - or - meth.hasQualifiedName("database/sql/driver", "Queryer", "Query") and n = 0 - or - meth.hasQualifiedName("database/sql/driver", "QueryerContext", "QueryContext") and n = 1 - ) and - this = meth.getACall().getArgument(n) - ) - } - } - // These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. private class SqlMethodModels extends TaintTracking::FunctionModel, Method { FunctionInput inp; From fbaad09179856695c3546ec6e506e051e05fc64a Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 16 Aug 2024 07:58:37 +0100 Subject: [PATCH 068/470] Convert mongodb nosql-injection sinks to MaD --- ...o.mongodb.org.mongo-driver.mongo.model.yml | 19 +++ go/ql/lib/semmle/go/frameworks/NoSQL.qll | 154 +++++++++--------- .../Security/CWE-089/SqlInjection.expected | 134 ++++++++------- 3 files changed, 170 insertions(+), 137 deletions(-) create mode 100644 go/ql/lib/ext/go.mongodb.org.mongo-driver.mongo.model.yml diff --git a/go/ql/lib/ext/go.mongodb.org.mongo-driver.mongo.model.yml b/go/ql/lib/ext/go.mongodb.org.mongo-driver.mongo.model.yml new file mode 100644 index 00000000000..ae07bd3a213 --- /dev/null +++ b/go/ql/lib/ext/go.mongodb.org.mongo-driver.mongo.model.yml @@ -0,0 +1,19 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "CountDocuments", "", "", "Argument[1]", "nosql-injection", "manual"] + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "DeleteMany", "", "", "Argument[1]", "nosql-injection", "manual"] + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "DeleteOne", "", "", "Argument[1]", "nosql-injection", "manual"] + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "Distinct", "", "", "Argument[2]", "nosql-injection", "manual"] + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "Find", "", "", "Argument[1]", "nosql-injection", "manual"] + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "FindOne", "", "", "Argument[1]", "nosql-injection", "manual"] + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "FindOneAndDelete", "", "", "Argument[1]", "nosql-injection", "manual"] + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "FindOneAndReplace", "", "", "Argument[1]", "nosql-injection", "manual"] + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "FindOneAndUpdate", "", "", "Argument[1]", "nosql-injection", "manual"] + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "ReplaceOne", "", "", "Argument[1]", "nosql-injection", "manual"] + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "UpdateMany", "", "", "Argument[1]", "nosql-injection", "manual"] + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "UpdateOne", "", "", "Argument[1]", "nosql-injection", "manual"] + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "Watch", "", "", "Argument[1]", "nosql-injection", "manual"] + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "Aggregate", "", "", "Argument[1]", "nosql-injection", "manual"] diff --git a/go/ql/lib/semmle/go/frameworks/NoSQL.qll b/go/ql/lib/semmle/go/frameworks/NoSQL.qll index c2469fc02ac..873b8230f1b 100644 --- a/go/ql/lib/semmle/go/frameworks/NoSQL.qll +++ b/go/ql/lib/semmle/go/frameworks/NoSQL.qll @@ -31,84 +31,82 @@ module NoSql { ) } } - - /** - * Holds if method `name` of struct `Collection` from package - * [go.mongodb.org/mongo-driver/mongo](https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo) - * interprets parameter `n` as a query. - */ - private predicate mongoDbCollectionMethod(string name, int n) { - // func (coll *Collection) CountDocuments(ctx context.Context, filter interface{}, - // opts ...*options.CountOptions) (int64, error) - name = "CountDocuments" and n = 1 - or - // func (coll *Collection) DeleteMany(ctx context.Context, filter interface{}, - // opts ...*options.DeleteOptions) (*DeleteResult, error) - name = "DeleteMany" and n = 1 - or - // func (coll *Collection) DeleteOne(ctx context.Context, filter interface{}, - // opts ...*options.DeleteOptions) (*DeleteResult, error) - name = "DeleteOne" and n = 1 - or - // func (coll *Collection) Distinct(ctx context.Context, fieldName string, filter interface{}, - // ...) ([]interface{}, error) - name = "Distinct" and n = 2 - or - // func (coll *Collection) Find(ctx context.Context, filter interface{}, - // opts ...*options.FindOptions) (*Cursor, error) - name = "Find" and n = 1 - or - // func (coll *Collection) FindOne(ctx context.Context, filter interface{}, - // opts ...*options.FindOneOptions) *SingleResult - name = "FindOne" and n = 1 - or - // func (coll *Collection) FindOneAndDelete(ctx context.Context, filter interface{}, ...) - // *SingleResult - name = "FindOneAndDelete" and n = 1 - or - // func (coll *Collection) FindOneAndReplace(ctx context.Context, filter interface{}, - // replacement interface{}, ...) *SingleResult - name = "FindOneAndReplace" and n = 1 - or - // func (coll *Collection) FindOneAndUpdate(ctx context.Context, filter interface{}, - // update interface{}, ...) *SingleResult - name = "FindOneAndUpdate" and n = 1 - or - // func (coll *Collection) ReplaceOne(ctx context.Context, filter interface{}, - // replacement interface{}, ...) (*UpdateResult, error) - name = "ReplaceOne" and n = 1 - or - // func (coll *Collection) UpdateMany(ctx context.Context, filter interface{}, - // update interface{}, ...) (*UpdateResult, error) - name = "UpdateMany" and n = 1 - or - // func (coll *Collection) UpdateOne(ctx context.Context, filter interface{}, - // update interface{}, ...) (*UpdateResult, error) - name = "UpdateOne" and n = 1 - or - // func (coll *Collection) Watch(ctx context.Context, pipeline interface{}, ...) - // (*ChangeStream, error) - name = "Watch" and n = 1 - or - // func (coll *Collection) Aggregate(ctx context.Context, pipeline interface{}, - // opts ...*options.AggregateOptions) (*Cursor, error) - name = "Aggregate" and n = 1 - } - - /** - * A query used in an API function acting on a `Collection` struct of package - * [go.mongodb.org/mongo-driver/mongo](https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo). - */ - private class MongoDbCollectionQuery extends Range { - MongoDbCollectionQuery() { - exists(Method meth, string methodName, int n | - mongoDbCollectionMethod(methodName, n) and - meth.hasQualifiedName(package("go.mongodb.org/mongo-driver", "mongo"), "Collection", - methodName) and - this = meth.getACall().getArgument(n) - ) - } - } + // /** + // * Holds if method `name` of struct `Collection` from package + // * [go.mongodb.org/mongo-driver/mongo](https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo) + // * interprets parameter `n` as a query. + // */ + // private predicate mongoDbCollectionMethod(string name, int n) { + // // func (coll *Collection) CountDocuments(ctx context.Context, filter interface{}, + // // opts ...*options.CountOptions) (int64, error) + // name = "CountDocuments" and n = 1 + // or + // // func (coll *Collection) DeleteMany(ctx context.Context, filter interface{}, + // // opts ...*options.DeleteOptions) (*DeleteResult, error) + // name = "DeleteMany" and n = 1 + // or + // // func (coll *Collection) DeleteOne(ctx context.Context, filter interface{}, + // // opts ...*options.DeleteOptions) (*DeleteResult, error) + // name = "DeleteOne" and n = 1 + // or + // // func (coll *Collection) Distinct(ctx context.Context, fieldName string, filter interface{}, + // // ...) ([]interface{}, error) + // name = "Distinct" and n = 2 + // or + // // func (coll *Collection) Find(ctx context.Context, filter interface{}, + // // opts ...*options.FindOptions) (*Cursor, error) + // name = "Find" and n = 1 + // or + // // func (coll *Collection) FindOne(ctx context.Context, filter interface{}, + // // opts ...*options.FindOneOptions) *SingleResult + // name = "FindOne" and n = 1 + // or + // // func (coll *Collection) FindOneAndDelete(ctx context.Context, filter interface{}, ...) + // // *SingleResult + // name = "FindOneAndDelete" and n = 1 + // or + // // func (coll *Collection) FindOneAndReplace(ctx context.Context, filter interface{}, + // // replacement interface{}, ...) *SingleResult + // name = "FindOneAndReplace" and n = 1 + // or + // // func (coll *Collection) FindOneAndUpdate(ctx context.Context, filter interface{}, + // // update interface{}, ...) *SingleResult + // name = "FindOneAndUpdate" and n = 1 + // or + // // func (coll *Collection) ReplaceOne(ctx context.Context, filter interface{}, + // // replacement interface{}, ...) (*UpdateResult, error) + // name = "ReplaceOne" and n = 1 + // or + // // func (coll *Collection) UpdateMany(ctx context.Context, filter interface{}, + // // update interface{}, ...) (*UpdateResult, error) + // name = "UpdateMany" and n = 1 + // or + // // func (coll *Collection) UpdateOne(ctx context.Context, filter interface{}, + // // update interface{}, ...) (*UpdateResult, error) + // name = "UpdateOne" and n = 1 + // or + // // func (coll *Collection) Watch(ctx context.Context, pipeline interface{}, ...) + // // (*ChangeStream, error) + // name = "Watch" and n = 1 + // or + // // func (coll *Collection) Aggregate(ctx context.Context, pipeline interface{}, + // // opts ...*options.AggregateOptions) (*Cursor, error) + // name = "Aggregate" and n = 1 + // } + // /** + // * A query used in an API function acting on a `Collection` struct of package + // * [go.mongodb.org/mongo-driver/mongo](https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo). + // */ + // private class MongoDbCollectionQuery extends Range { + // MongoDbCollectionQuery() { + // exists(Method meth, string methodName, int n | + // mongoDbCollectionMethod(methodName, n) and + // meth.hasQualifiedName(package("go.mongodb.org/mongo-driver", "mongo"), "Collection", + // methodName) and + // this = meth.getACall().getArgument(n) + // ) + // } + // } } /** diff --git a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 79d8809e19f..18fc2e554e6 100644 --- a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -25,53 +25,53 @@ | mongoDB.go:80:22:80:27 | filter | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:80:22:80:27 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | | mongoDB.go:81:18:81:25 | pipeline | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:81:18:81:25 | pipeline | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | edges -| SqlInjection.go:10:7:11:30 | []type{args} [array] | SqlInjection.go:10:7:11:30 | call to Sprintf | provenance | MaD:7 | -| SqlInjection.go:10:7:11:30 | call to Sprintf | SqlInjection.go:12:11:12:11 | q | provenance | | -| SqlInjection.go:11:3:11:9 | selection of URL | SqlInjection.go:11:3:11:17 | call to Query | provenance | Src:MaD:5 MaD:10 | +| SqlInjection.go:10:7:11:30 | []type{args} [array] | SqlInjection.go:10:7:11:30 | call to Sprintf | provenance | MaD:23 | +| SqlInjection.go:10:7:11:30 | call to Sprintf | SqlInjection.go:12:11:12:11 | q | provenance | Sink:MaD:1 | +| SqlInjection.go:11:3:11:9 | selection of URL | SqlInjection.go:11:3:11:17 | call to Query | provenance | Src:MaD:21 MaD:26 | | SqlInjection.go:11:3:11:17 | call to Query | SqlInjection.go:11:3:11:29 | index expression | provenance | | | SqlInjection.go:11:3:11:29 | index expression | SqlInjection.go:10:7:11:30 | []type{args} [array] | provenance | | | SqlInjection.go:11:3:11:29 | index expression | SqlInjection.go:10:7:11:30 | call to Sprintf | provenance | FunctionModel | | issue48.go:17:2:17:33 | ... := ...[0] | issue48.go:18:17:18:17 | b | provenance | | -| issue48.go:17:25:17:32 | selection of Body | issue48.go:17:2:17:33 | ... := ...[0] | provenance | Src:MaD:1 MaD:8 | -| issue48.go:18:17:18:17 | b | issue48.go:18:20:18:39 | &... | provenance | MaD:6 | +| issue48.go:17:25:17:32 | selection of Body | issue48.go:17:2:17:33 | ... := ...[0] | provenance | Src:MaD:17 MaD:24 | +| issue48.go:18:17:18:17 | b | issue48.go:18:20:18:39 | &... | provenance | MaD:22 | | issue48.go:18:20:18:39 | &... | issue48.go:21:3:21:33 | index expression | provenance | | -| issue48.go:20:8:21:34 | []type{args} [array] | issue48.go:20:8:21:34 | call to Sprintf | provenance | MaD:7 | -| issue48.go:20:8:21:34 | call to Sprintf | issue48.go:22:11:22:12 | q3 | provenance | | +| issue48.go:20:8:21:34 | []type{args} [array] | issue48.go:20:8:21:34 | call to Sprintf | provenance | MaD:23 | +| issue48.go:20:8:21:34 | call to Sprintf | issue48.go:22:11:22:12 | q3 | provenance | Sink:MaD:1 | | issue48.go:21:3:21:33 | index expression | issue48.go:20:8:21:34 | []type{args} [array] | provenance | | | issue48.go:21:3:21:33 | index expression | issue48.go:20:8:21:34 | call to Sprintf | provenance | FunctionModel | | issue48.go:27:2:27:34 | ... := ...[0] | issue48.go:28:17:28:18 | b2 | provenance | | -| issue48.go:27:26:27:33 | selection of Body | issue48.go:27:2:27:34 | ... := ...[0] | provenance | Src:MaD:1 MaD:8 | -| issue48.go:28:17:28:18 | b2 | issue48.go:28:21:28:41 | &... | provenance | MaD:6 | +| issue48.go:27:26:27:33 | selection of Body | issue48.go:27:2:27:34 | ... := ...[0] | provenance | Src:MaD:17 MaD:24 | +| issue48.go:28:17:28:18 | b2 | issue48.go:28:21:28:41 | &... | provenance | MaD:22 | | issue48.go:28:21:28:41 | &... | issue48.go:31:3:31:31 | selection of Category | provenance | | -| issue48.go:30:8:31:32 | []type{args} [array] | issue48.go:30:8:31:32 | call to Sprintf | provenance | MaD:7 | -| issue48.go:30:8:31:32 | call to Sprintf | issue48.go:32:11:32:12 | q4 | provenance | | +| issue48.go:30:8:31:32 | []type{args} [array] | issue48.go:30:8:31:32 | call to Sprintf | provenance | MaD:23 | +| issue48.go:30:8:31:32 | call to Sprintf | issue48.go:32:11:32:12 | q4 | provenance | Sink:MaD:1 | | issue48.go:31:3:31:31 | selection of Category | issue48.go:30:8:31:32 | []type{args} [array] | provenance | | | issue48.go:31:3:31:31 | selection of Category | issue48.go:30:8:31:32 | call to Sprintf | provenance | FunctionModel | -| issue48.go:37:17:37:50 | type conversion | issue48.go:37:53:37:73 | &... | provenance | MaD:6 | -| issue48.go:37:24:37:30 | selection of URL | issue48.go:37:24:37:38 | call to Query | provenance | Src:MaD:5 MaD:10 | +| issue48.go:37:17:37:50 | type conversion | issue48.go:37:53:37:73 | &... | provenance | MaD:22 | +| issue48.go:37:24:37:30 | selection of URL | issue48.go:37:24:37:38 | call to Query | provenance | Src:MaD:21 MaD:26 | | issue48.go:37:24:37:38 | call to Query | issue48.go:37:17:37:50 | type conversion | provenance | | | issue48.go:37:53:37:73 | &... | issue48.go:40:3:40:31 | selection of Category | provenance | | -| issue48.go:39:8:40:32 | []type{args} [array] | issue48.go:39:8:40:32 | call to Sprintf | provenance | MaD:7 | -| issue48.go:39:8:40:32 | call to Sprintf | issue48.go:41:11:41:12 | q5 | provenance | | +| issue48.go:39:8:40:32 | []type{args} [array] | issue48.go:39:8:40:32 | call to Sprintf | provenance | MaD:23 | +| issue48.go:39:8:40:32 | call to Sprintf | issue48.go:41:11:41:12 | q5 | provenance | Sink:MaD:1 | | issue48.go:40:3:40:31 | selection of Category | issue48.go:39:8:40:32 | []type{args} [array] | provenance | | | issue48.go:40:3:40:31 | selection of Category | issue48.go:39:8:40:32 | call to Sprintf | provenance | FunctionModel | -| main.go:11:11:11:16 | selection of Form | main.go:11:11:11:28 | index expression | provenance | Src:MaD:2 | -| main.go:15:11:15:84 | []type{args} [array] | main.go:15:11:15:84 | call to Sprintf | provenance | MaD:7 | -| main.go:15:63:15:67 | selection of URL | main.go:15:63:15:75 | call to Query | provenance | Src:MaD:5 MaD:10 | +| main.go:11:11:11:16 | selection of Form | main.go:11:11:11:28 | index expression | provenance | Src:MaD:18 Sink:MaD:1 | +| main.go:15:11:15:84 | []type{args} [array] | main.go:15:11:15:84 | call to Sprintf | provenance | MaD:23 Sink:MaD:2 | +| main.go:15:63:15:67 | selection of URL | main.go:15:63:15:75 | call to Query | provenance | Src:MaD:21 MaD:26 | | main.go:15:63:15:75 | call to Query | main.go:15:63:15:83 | index expression | provenance | | | main.go:15:63:15:83 | index expression | main.go:15:11:15:84 | []type{args} [array] | provenance | | -| main.go:15:63:15:83 | index expression | main.go:15:11:15:84 | call to Sprintf | provenance | FunctionModel | -| main.go:16:11:16:85 | []type{args} [array] | main.go:16:11:16:85 | call to Sprintf | provenance | MaD:7 | -| main.go:16:63:16:70 | selection of Header | main.go:16:63:16:84 | call to Get | provenance | Src:MaD:3 MaD:9 | +| main.go:15:63:15:83 | index expression | main.go:15:11:15:84 | call to Sprintf | provenance | FunctionModel Sink:MaD:2 | +| main.go:16:11:16:85 | []type{args} [array] | main.go:16:11:16:85 | call to Sprintf | provenance | MaD:23 Sink:MaD:2 | +| main.go:16:63:16:70 | selection of Header | main.go:16:63:16:84 | call to Get | provenance | Src:MaD:19 MaD:25 | | main.go:16:63:16:84 | call to Get | main.go:16:11:16:85 | []type{args} [array] | provenance | | -| main.go:16:63:16:84 | call to Get | main.go:16:11:16:85 | call to Sprintf | provenance | FunctionModel | +| main.go:16:63:16:84 | call to Get | main.go:16:11:16:85 | call to Sprintf | provenance | FunctionModel Sink:MaD:2 | | main.go:28:17:31:2 | &... [pointer, Category] | main.go:34:3:34:13 | RequestData [pointer, Category] | provenance | | | main.go:28:18:31:2 | struct literal [Category] | main.go:28:17:31:2 | &... [pointer, Category] | provenance | | -| main.go:30:13:30:19 | selection of URL | main.go:30:13:30:27 | call to Query | provenance | Src:MaD:5 MaD:10 | +| main.go:30:13:30:19 | selection of URL | main.go:30:13:30:27 | call to Query | provenance | Src:MaD:21 MaD:26 | | main.go:30:13:30:27 | call to Query | main.go:30:13:30:39 | index expression | provenance | | | main.go:30:13:30:39 | index expression | main.go:28:18:31:2 | struct literal [Category] | provenance | | -| main.go:33:7:34:23 | []type{args} [array] | main.go:33:7:34:23 | call to Sprintf | provenance | MaD:7 | -| main.go:33:7:34:23 | call to Sprintf | main.go:35:11:35:11 | q | provenance | | +| main.go:33:7:34:23 | []type{args} [array] | main.go:33:7:34:23 | call to Sprintf | provenance | MaD:23 | +| main.go:33:7:34:23 | call to Sprintf | main.go:35:11:35:11 | q | provenance | Sink:MaD:1 | | main.go:34:3:34:13 | RequestData [pointer, Category] | main.go:34:3:34:13 | implicit dereference [Category] | provenance | | | main.go:34:3:34:13 | implicit dereference [Category] | main.go:34:3:34:22 | selection of Category | provenance | | | main.go:34:3:34:22 | selection of Category | main.go:33:7:34:23 | []type{args} [array] | provenance | | @@ -80,11 +80,11 @@ edges | main.go:39:2:39:12 | definition of RequestData [pointer, Category] | main.go:43:3:43:13 | RequestData [pointer, Category] | provenance | | | main.go:40:2:40:12 | RequestData [pointer, Category] | main.go:40:2:40:12 | implicit dereference [Category] | provenance | | | main.go:40:2:40:12 | implicit dereference [Category] | main.go:39:2:39:12 | definition of RequestData [pointer, Category] | provenance | | -| main.go:40:25:40:31 | selection of URL | main.go:40:25:40:39 | call to Query | provenance | Src:MaD:5 MaD:10 | +| main.go:40:25:40:31 | selection of URL | main.go:40:25:40:39 | call to Query | provenance | Src:MaD:21 MaD:26 | | main.go:40:25:40:39 | call to Query | main.go:40:25:40:51 | index expression | provenance | | | main.go:40:25:40:51 | index expression | main.go:40:2:40:12 | implicit dereference [Category] | provenance | | -| main.go:42:7:43:23 | []type{args} [array] | main.go:42:7:43:23 | call to Sprintf | provenance | MaD:7 | -| main.go:42:7:43:23 | call to Sprintf | main.go:44:11:44:11 | q | provenance | | +| main.go:42:7:43:23 | []type{args} [array] | main.go:42:7:43:23 | call to Sprintf | provenance | MaD:23 | +| main.go:42:7:43:23 | call to Sprintf | main.go:44:11:44:11 | q | provenance | Sink:MaD:1 | | main.go:43:3:43:13 | RequestData [pointer, Category] | main.go:43:3:43:13 | implicit dereference [Category] | provenance | | | main.go:43:3:43:13 | implicit dereference [Category] | main.go:43:3:43:22 | selection of Category | provenance | | | main.go:43:3:43:22 | selection of Category | main.go:42:7:43:23 | []type{args} [array] | provenance | | @@ -93,11 +93,11 @@ edges | main.go:48:2:48:12 | definition of RequestData [pointer, Category] | main.go:52:3:52:13 | RequestData [pointer, Category] | provenance | | | main.go:49:3:49:14 | star expression [Category] | main.go:48:2:48:12 | definition of RequestData [pointer, Category] | provenance | | | main.go:49:4:49:14 | RequestData [pointer, Category] | main.go:49:3:49:14 | star expression [Category] | provenance | | -| main.go:49:28:49:34 | selection of URL | main.go:49:28:49:42 | call to Query | provenance | Src:MaD:5 MaD:10 | +| main.go:49:28:49:34 | selection of URL | main.go:49:28:49:42 | call to Query | provenance | Src:MaD:21 MaD:26 | | main.go:49:28:49:42 | call to Query | main.go:49:28:49:54 | index expression | provenance | | | main.go:49:28:49:54 | index expression | main.go:49:3:49:14 | star expression [Category] | provenance | | -| main.go:51:7:52:23 | []type{args} [array] | main.go:51:7:52:23 | call to Sprintf | provenance | MaD:7 | -| main.go:51:7:52:23 | call to Sprintf | main.go:53:11:53:11 | q | provenance | | +| main.go:51:7:52:23 | []type{args} [array] | main.go:51:7:52:23 | call to Sprintf | provenance | MaD:23 | +| main.go:51:7:52:23 | call to Sprintf | main.go:53:11:53:11 | q | provenance | Sink:MaD:1 | | main.go:52:3:52:13 | RequestData [pointer, Category] | main.go:52:3:52:13 | implicit dereference [Category] | provenance | | | main.go:52:3:52:13 | implicit dereference [Category] | main.go:52:3:52:22 | selection of Category | provenance | | | main.go:52:3:52:22 | selection of Category | main.go:51:7:52:23 | []type{args} [array] | provenance | | @@ -106,44 +106,60 @@ edges | main.go:57:2:57:12 | definition of RequestData [pointer, Category] | main.go:61:5:61:15 | RequestData [pointer, Category] | provenance | | | main.go:58:3:58:14 | star expression [Category] | main.go:57:2:57:12 | definition of RequestData [pointer, Category] | provenance | | | main.go:58:4:58:14 | RequestData [pointer, Category] | main.go:58:3:58:14 | star expression [Category] | provenance | | -| main.go:58:28:58:34 | selection of URL | main.go:58:28:58:42 | call to Query | provenance | Src:MaD:5 MaD:10 | +| main.go:58:28:58:34 | selection of URL | main.go:58:28:58:42 | call to Query | provenance | Src:MaD:21 MaD:26 | | main.go:58:28:58:42 | call to Query | main.go:58:28:58:54 | index expression | provenance | | | main.go:58:28:58:54 | index expression | main.go:58:3:58:14 | star expression [Category] | provenance | | -| main.go:60:7:61:26 | []type{args} [array] | main.go:60:7:61:26 | call to Sprintf | provenance | MaD:7 | -| main.go:60:7:61:26 | call to Sprintf | main.go:62:11:62:11 | q | provenance | | +| main.go:60:7:61:26 | []type{args} [array] | main.go:60:7:61:26 | call to Sprintf | provenance | MaD:23 | +| main.go:60:7:61:26 | call to Sprintf | main.go:62:11:62:11 | q | provenance | Sink:MaD:1 | | main.go:61:3:61:25 | selection of Category | main.go:60:7:61:26 | []type{args} [array] | provenance | | | main.go:61:3:61:25 | selection of Category | main.go:60:7:61:26 | call to Sprintf | provenance | FunctionModel | | main.go:61:4:61:15 | star expression [Category] | main.go:61:3:61:25 | selection of Category | provenance | | | main.go:61:5:61:15 | RequestData [pointer, Category] | main.go:61:4:61:15 | star expression [Category] | provenance | | -| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:42:28:42:41 | untrustedInput | provenance | Src:MaD:4 | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:42:28:42:41 | untrustedInput | provenance | Src:MaD:20 | | mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:50:34:50:39 | filter | provenance | | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:61:27:61:32 | filter | provenance | | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:63:23:63:28 | filter | provenance | | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:64:22:64:27 | filter | provenance | | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:66:32:66:37 | filter | provenance | | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:69:17:69:22 | filter | provenance | | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:70:20:70:25 | filter | provenance | | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:71:29:71:34 | filter | provenance | | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:72:30:72:35 | filter | provenance | | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:73:29:73:34 | filter | provenance | | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:78:23:78:28 | filter | provenance | | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:79:23:79:28 | filter | provenance | | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:80:22:80:27 | filter | provenance | | +| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:61:27:61:32 | filter | provenance | Sink:MaD:4 | +| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:63:23:63:28 | filter | provenance | Sink:MaD:5 | +| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:64:22:64:27 | filter | provenance | Sink:MaD:6 | +| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:66:32:66:37 | filter | provenance | Sink:MaD:7 | +| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:69:17:69:22 | filter | provenance | Sink:MaD:8 | +| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:70:20:70:25 | filter | provenance | Sink:MaD:9 | +| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:71:29:71:34 | filter | provenance | Sink:MaD:10 | +| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:72:30:72:35 | filter | provenance | Sink:MaD:11 | +| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:73:29:73:34 | filter | provenance | Sink:MaD:12 | +| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:78:23:78:28 | filter | provenance | Sink:MaD:13 | +| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:79:23:79:28 | filter | provenance | Sink:MaD:14 | +| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:80:22:80:27 | filter | provenance | Sink:MaD:15 | | mongoDB.go:42:28:42:41 | untrustedInput | mongoDB.go:42:19:42:42 | struct literal | provenance | Config | -| mongoDB.go:50:23:50:40 | struct literal | mongoDB.go:57:22:57:29 | pipeline | provenance | | -| mongoDB.go:50:23:50:40 | struct literal | mongoDB.go:81:18:81:25 | pipeline | provenance | | +| mongoDB.go:50:23:50:40 | struct literal | mongoDB.go:57:22:57:29 | pipeline | provenance | Sink:MaD:3 | +| mongoDB.go:50:23:50:40 | struct literal | mongoDB.go:81:18:81:25 | pipeline | provenance | Sink:MaD:16 | | mongoDB.go:50:34:50:39 | filter | mongoDB.go:50:23:50:40 | struct literal | provenance | Config | models -| 1 | Source: net/http; Request; true; Body; ; ; ; remote; manual | -| 2 | Source: net/http; Request; true; Form; ; ; ; remote; manual | -| 3 | Source: net/http; Request; true; Header; ; ; ; remote; manual | -| 4 | Source: net/http; Request; true; Referer; ; ; ReturnValue; remote; manual | -| 5 | Source: net/http; Request; true; URL; ; ; ; remote; manual | -| 6 | Summary: encoding/json; ; false; Unmarshal; ; ; Argument[0]; Argument[1]; taint; manual | -| 7 | Summary: fmt; ; false; Sprintf; ; ; Argument[1].ArrayElement; ReturnValue; taint; manual | -| 8 | Summary: io/ioutil; ; false; ReadAll; ; ; Argument[0]; ReturnValue[0]; taint; manual | -| 9 | Summary: net/http; Header; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual | -| 10 | Summary: net/url; URL; true; Query; ; ; Argument[receiver]; ReturnValue; taint; manual | +| 1 | Sink: database/sql; DB; false; Query; ; ; Argument[0]; sql-injection; manual | +| 2 | Sink: database/sql; Tx; false; Query; ; ; Argument[0]; sql-injection; manual | +| 3 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; Aggregate; ; ; Argument[1]; nosql-injection; manual | +| 4 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; CountDocuments; ; ; Argument[1]; nosql-injection; manual | +| 5 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; DeleteMany; ; ; Argument[1]; nosql-injection; manual | +| 6 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; DeleteOne; ; ; Argument[1]; nosql-injection; manual | +| 7 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; Distinct; ; ; Argument[2]; nosql-injection; manual | +| 8 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; Find; ; ; Argument[1]; nosql-injection; manual | +| 9 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; FindOne; ; ; Argument[1]; nosql-injection; manual | +| 10 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; FindOneAndDelete; ; ; Argument[1]; nosql-injection; manual | +| 11 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; FindOneAndReplace; ; ; Argument[1]; nosql-injection; manual | +| 12 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; FindOneAndUpdate; ; ; Argument[1]; nosql-injection; manual | +| 13 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; ReplaceOne; ; ; Argument[1]; nosql-injection; manual | +| 14 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; UpdateMany; ; ; Argument[1]; nosql-injection; manual | +| 15 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; UpdateOne; ; ; Argument[1]; nosql-injection; manual | +| 16 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; Watch; ; ; Argument[1]; nosql-injection; manual | +| 17 | Source: net/http; Request; true; Body; ; ; ; remote; manual | +| 18 | Source: net/http; Request; true; Form; ; ; ; remote; manual | +| 19 | Source: net/http; Request; true; Header; ; ; ; remote; manual | +| 20 | Source: net/http; Request; true; Referer; ; ; ReturnValue; remote; manual | +| 21 | Source: net/http; Request; true; URL; ; ; ; remote; manual | +| 22 | Summary: encoding/json; ; false; Unmarshal; ; ; Argument[0]; Argument[1]; taint; manual | +| 23 | Summary: fmt; ; false; Sprintf; ; ; Argument[1].ArrayElement; ReturnValue; taint; manual | +| 24 | Summary: io/ioutil; ; false; ReadAll; ; ; Argument[0]; ReturnValue[0]; taint; manual | +| 25 | Summary: net/http; Header; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual | +| 26 | Summary: net/url; URL; true; Query; ; ; Argument[receiver]; ReturnValue; taint; manual | nodes | SqlInjection.go:10:7:11:30 | []type{args} [array] | semmle.label | []type{args} [array] | | SqlInjection.go:10:7:11:30 | call to Sprintf | semmle.label | call to Sprintf | From 85c7e8c2212523d26c9c56e99e8dabb76b1274be Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 16 Aug 2024 07:59:04 +0100 Subject: [PATCH 069/470] Convert gocb nosql-injection sinks to MaD --- .../ext/github.com.couchbase.gocb.model.yml | 57 +++++++++----- ...o.mongodb.org.mongo-driver.mongo.model.yml | 2 +- go/ql/lib/semmle/go/frameworks/Couchbase.qll | 46 ++--------- go/ql/lib/semmle/go/frameworks/NoSQL.qll | 76 ------------------- 4 files changed, 43 insertions(+), 138 deletions(-) diff --git a/go/ql/lib/ext/github.com.couchbase.gocb.model.yml b/go/ql/lib/ext/github.com.couchbase.gocb.model.yml index ff0a4c22c8d..d17b53dd6da 100644 --- a/go/ql/lib/ext/github.com.couchbase.gocb.model.yml +++ b/go/ql/lib/ext/github.com.couchbase.gocb.model.yml @@ -3,28 +3,43 @@ extensions: pack: codeql/go-all extensible: packageGrouping data: - - ["gocb", "github.com/couchbase/gocb"] - - ["gocb", "gopkg.in/couchbase/gocb"] - - ["gocb", "github.com/couchbaselabs/gocb"] + - ["gocb1", "fixed-version:github.com/couchbase/gocb"] + - ["gocb1", "fixed-version:gopkg.in/couchbase/gocb.v1"] + - ["gocb1", "fixed-version:github.com/couchbaselabs/gocb"] + - ["gocb2", "github.com/couchbase/gocb/v2"] + - ["gocb2", "gopkg.in/couchbase/gocb.v2"] + - ["gocb2", "github.com/couchbaselabs/gocb/v2"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["group:gocb1", "Bucket", True, "ExecuteN1qlQuery", "", "", "Argument[0]", "nosql-injection", "manual"] + - ["group:gocb1", "Bucket", True, "ExecuteAnalyticsQuery", "", "", "Argument[0]", "nosql-injection", "manual"] + - ["group:gocb1", "Cluster", True, "ExecuteN1qlQuery", "", "", "Argument[0]", "nosql-injection", "manual"] + - ["group:gocb1", "Cluster", True, "ExecuteAnalyticsQuery", "", "", "Argument[0]", "nosql-injection", "manual"] + - ["group:gocb2", "Cluster", True, "AnalyticsQuery", "", "", "Argument[0]", "nosql-injection", "manual"] + - ["group:gocb2", "Cluster", True, "Query", "", "", "Argument[0]", "nosql-injection", "manual"] + - ["group:gocb2", "Scope", True, "AnalyticsQuery", "", "", "Argument[0]", "nosql-injection", "manual"] + - ["group:gocb2", "Scope", True, "Query", "", "", "Argument[0]", "nosql-injection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel data: - - ["group:gocb", "", False, "NewAnalyticsQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "", False, "NewN1qlQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "AnalyticsQuery", True, "ContextId", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "AnalyticsQuery", True, "Deferred", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "AnalyticsQuery", True, "Pretty", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "AnalyticsQuery", True, "Priority", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "AnalyticsQuery", True, "RawParam", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "AnalyticsQuery", True, "ServerSideTimeout", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "N1qlQuery", True, "AdHoc", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "N1qlQuery", True, "Consistency", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "N1qlQuery", True, "ConsistentWith", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "N1qlQuery", True, "Custom", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "N1qlQuery", True, "PipelineBatch", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "N1qlQuery", True, "PipelineCap", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "N1qlQuery", True, "Profile", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "N1qlQuery", True, "ReadOnly", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "N1qlQuery", True, "ScanCap", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] - - ["group:gocb", "N1qlQuery", True, "Timeout", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "", False, "NewAnalyticsQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "", False, "NewN1qlQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "AnalyticsQuery", True, "ContextId", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "AnalyticsQuery", True, "Deferred", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "AnalyticsQuery", True, "Pretty", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "AnalyticsQuery", True, "Priority", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "AnalyticsQuery", True, "RawParam", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "AnalyticsQuery", True, "ServerSideTimeout", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "N1qlQuery", True, "AdHoc", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "N1qlQuery", True, "Consistency", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "N1qlQuery", True, "ConsistentWith", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "N1qlQuery", True, "Custom", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "N1qlQuery", True, "PipelineBatch", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "N1qlQuery", True, "PipelineCap", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "N1qlQuery", True, "Profile", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "N1qlQuery", True, "ReadOnly", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "N1qlQuery", True, "ScanCap", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["group:gocb1", "N1qlQuery", True, "Timeout", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/go.mongodb.org.mongo-driver.mongo.model.yml b/go/ql/lib/ext/go.mongodb.org.mongo-driver.mongo.model.yml index ae07bd3a213..6c2d4afdeae 100644 --- a/go/ql/lib/ext/go.mongodb.org.mongo-driver.mongo.model.yml +++ b/go/ql/lib/ext/go.mongodb.org.mongo-driver.mongo.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/go-all extensible: sinkModel data: + - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "Aggregate", "", "", "Argument[1]", "nosql-injection", "manual"] - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "CountDocuments", "", "", "Argument[1]", "nosql-injection", "manual"] - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "DeleteMany", "", "", "Argument[1]", "nosql-injection", "manual"] - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "DeleteOne", "", "", "Argument[1]", "nosql-injection", "manual"] @@ -16,4 +17,3 @@ extensions: - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "UpdateMany", "", "", "Argument[1]", "nosql-injection", "manual"] - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "UpdateOne", "", "", "Argument[1]", "nosql-injection", "manual"] - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "Watch", "", "", "Argument[1]", "nosql-injection", "manual"] - - ["go.mongodb.org/mongo-driver/mongo", "Collection", True, "Aggregate", "", "", "Argument[1]", "nosql-injection", "manual"] diff --git a/go/ql/lib/semmle/go/frameworks/Couchbase.qll b/go/ql/lib/semmle/go/frameworks/Couchbase.qll index 5eaa4d20c3a..b5bfbcb22a2 100644 --- a/go/ql/lib/semmle/go/frameworks/Couchbase.qll +++ b/go/ql/lib/semmle/go/frameworks/Couchbase.qll @@ -5,57 +5,23 @@ import go /** + * DEPRECATED + * * Provides models of commonly used functions in the official Couchbase Go SDK library. */ -module Couchbase { +deprecated module Couchbase { /** + * DEPRECATED + * * Gets a package path for the official Couchbase Go SDK library. * * Note that v1 and v2 have different APIs, but the names are disjoint so there is no need to * distinguish between them. */ - string packagePath() { + deprecated string packagePath() { result = package([ "gopkg.in/couchbase/gocb", "github.com/couchbase/gocb", "github.com/couchbaselabs/gocb" ], "") } - - /** - * A query used in an API function acting on a `Bucket` or `Cluster` struct of v1 of - * the official Couchbase Go library, gocb. - */ - private class CouchbaseV1Query extends NoSql::Query::Range { - CouchbaseV1Query() { - // func (b *Bucket) ExecuteAnalyticsQuery(q *AnalyticsQuery, params interface{}) (AnalyticsResults, error) - // func (b *Bucket) ExecuteN1qlQuery(q *N1qlQuery, params interface{}) (QueryResults, error) - // func (c *Cluster) ExecuteAnalyticsQuery(q *AnalyticsQuery, params interface{}) (AnalyticsResults, error) - // func (c *Cluster) ExecuteN1qlQuery(q *N1qlQuery, params interface{}) (QueryResults, error) - exists(Method meth, string structName, string methodName | - structName in ["Bucket", "Cluster"] and - methodName in ["ExecuteN1qlQuery", "ExecuteAnalyticsQuery"] and - meth.hasQualifiedName(packagePath(), structName, methodName) and - this = meth.getACall().getArgument(0) - ) - } - } - - /** - * A query used in an API function acting on a `Bucket` or `Cluster` struct of v1 of - * the official Couchbase Go library, gocb. - */ - private class CouchbaseV2Query extends NoSql::Query::Range { - CouchbaseV2Query() { - // func (c *Cluster) AnalyticsQuery(statement string, opts *AnalyticsOptions) (*AnalyticsResult, error) - // func (c *Cluster) Query(statement string, opts *QueryOptions) (*QueryResult, error) - // func (s *Scope) AnalyticsQuery(statement string, opts *AnalyticsOptions) (*AnalyticsResult, error) - // func (s *Scope) Query(statement string, opts *QueryOptions) (*QueryResult, error) - exists(Method meth, string structName, string methodName | - structName in ["Cluster", "Scope"] and - methodName in ["AnalyticsQuery", "Query"] and - meth.hasQualifiedName(packagePath(), structName, methodName) and - this = meth.getACall().getArgument(0) - ) - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/NoSQL.qll b/go/ql/lib/semmle/go/frameworks/NoSQL.qll index 873b8230f1b..36932149628 100644 --- a/go/ql/lib/semmle/go/frameworks/NoSQL.qll +++ b/go/ql/lib/semmle/go/frameworks/NoSQL.qll @@ -31,82 +31,6 @@ module NoSql { ) } } - // /** - // * Holds if method `name` of struct `Collection` from package - // * [go.mongodb.org/mongo-driver/mongo](https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo) - // * interprets parameter `n` as a query. - // */ - // private predicate mongoDbCollectionMethod(string name, int n) { - // // func (coll *Collection) CountDocuments(ctx context.Context, filter interface{}, - // // opts ...*options.CountOptions) (int64, error) - // name = "CountDocuments" and n = 1 - // or - // // func (coll *Collection) DeleteMany(ctx context.Context, filter interface{}, - // // opts ...*options.DeleteOptions) (*DeleteResult, error) - // name = "DeleteMany" and n = 1 - // or - // // func (coll *Collection) DeleteOne(ctx context.Context, filter interface{}, - // // opts ...*options.DeleteOptions) (*DeleteResult, error) - // name = "DeleteOne" and n = 1 - // or - // // func (coll *Collection) Distinct(ctx context.Context, fieldName string, filter interface{}, - // // ...) ([]interface{}, error) - // name = "Distinct" and n = 2 - // or - // // func (coll *Collection) Find(ctx context.Context, filter interface{}, - // // opts ...*options.FindOptions) (*Cursor, error) - // name = "Find" and n = 1 - // or - // // func (coll *Collection) FindOne(ctx context.Context, filter interface{}, - // // opts ...*options.FindOneOptions) *SingleResult - // name = "FindOne" and n = 1 - // or - // // func (coll *Collection) FindOneAndDelete(ctx context.Context, filter interface{}, ...) - // // *SingleResult - // name = "FindOneAndDelete" and n = 1 - // or - // // func (coll *Collection) FindOneAndReplace(ctx context.Context, filter interface{}, - // // replacement interface{}, ...) *SingleResult - // name = "FindOneAndReplace" and n = 1 - // or - // // func (coll *Collection) FindOneAndUpdate(ctx context.Context, filter interface{}, - // // update interface{}, ...) *SingleResult - // name = "FindOneAndUpdate" and n = 1 - // or - // // func (coll *Collection) ReplaceOne(ctx context.Context, filter interface{}, - // // replacement interface{}, ...) (*UpdateResult, error) - // name = "ReplaceOne" and n = 1 - // or - // // func (coll *Collection) UpdateMany(ctx context.Context, filter interface{}, - // // update interface{}, ...) (*UpdateResult, error) - // name = "UpdateMany" and n = 1 - // or - // // func (coll *Collection) UpdateOne(ctx context.Context, filter interface{}, - // // update interface{}, ...) (*UpdateResult, error) - // name = "UpdateOne" and n = 1 - // or - // // func (coll *Collection) Watch(ctx context.Context, pipeline interface{}, ...) - // // (*ChangeStream, error) - // name = "Watch" and n = 1 - // or - // // func (coll *Collection) Aggregate(ctx context.Context, pipeline interface{}, - // // opts ...*options.AggregateOptions) (*Cursor, error) - // name = "Aggregate" and n = 1 - // } - // /** - // * A query used in an API function acting on a `Collection` struct of package - // * [go.mongodb.org/mongo-driver/mongo](https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo). - // */ - // private class MongoDbCollectionQuery extends Range { - // MongoDbCollectionQuery() { - // exists(Method meth, string methodName, int n | - // mongoDbCollectionMethod(methodName, n) and - // meth.hasQualifiedName(package("go.mongodb.org/mongo-driver", "mongo"), "Collection", - // methodName) and - // this = meth.getACall().getArgument(n) - // ) - // } - // } } /** From 35cbc162b0ce14ad67b8d6ac0ca1d3a436becf6a Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 25 Jul 2024 16:41:36 +0100 Subject: [PATCH 070/470] Convert logging sinks to use MaD --- go/ql/lib/ext/fmt.model.yml | 7 + ...github.com.beego.beego.core.logs.model.yml | 34 +++++ ...ithub.com.beego.beego.core.utils.model.yml | 5 + ...ithub.com.beego.beego.server.web.model.yml | 12 ++ .../github.com.davecgh.go-spew.spew.model.yml | 14 ++ .../ext/github.com.elazarl.goproxy.model.yml | 6 + .../lib/ext/github.com.golang.glog.model.yml | 102 ++++++++++++++ .../ext/github.com.sirupsen.logrus.model.yml | 131 ++++++++++++++++++ go/ql/lib/ext/go.uber.org.zap.model.yml | 37 +++++ go/ql/lib/ext/log.model.yml | 24 ++++ go/ql/lib/semmle/go/Concepts.qll | 17 +++ go/ql/lib/semmle/go/frameworks/Beego.qll | 37 ----- .../semmle/go/frameworks/ElazarlGoproxy.qll | 6 - go/ql/lib/semmle/go/frameworks/Glog.qll | 10 -- go/ql/lib/semmle/go/frameworks/Logrus.qll | 6 - go/ql/lib/semmle/go/frameworks/Spew.qll | 10 -- go/ql/lib/semmle/go/frameworks/Zap.qll | 12 -- go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll | 7 - go/ql/lib/semmle/go/frameworks/stdlib/Log.qll | 10 -- 19 files changed, 389 insertions(+), 98 deletions(-) create mode 100644 go/ql/lib/ext/github.com.beego.beego.core.logs.model.yml create mode 100644 go/ql/lib/ext/github.com.davecgh.go-spew.spew.model.yml create mode 100644 go/ql/lib/ext/github.com.golang.glog.model.yml create mode 100644 go/ql/lib/ext/github.com.sirupsen.logrus.model.yml diff --git a/go/ql/lib/ext/fmt.model.yml b/go/ql/lib/ext/fmt.model.yml index cad64ce0fdf..2baac68da3a 100644 --- a/go/ql/lib/ext/fmt.model.yml +++ b/go/ql/lib/ext/fmt.model.yml @@ -1,4 +1,11 @@ extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["fmt", "", False, "Print", "", "", "Argument[0]", "log-injection", "manual"] + - ["fmt", "", False, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["fmt", "", False, "Println", "", "", "Argument[0]", "log-injection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/ext/github.com.beego.beego.core.logs.model.yml b/go/ql/lib/ext/github.com.beego.beego.core.logs.model.yml new file mode 100644 index 00000000000..3dfbbe89719 --- /dev/null +++ b/go/ql/lib/ext/github.com.beego.beego.core.logs.model.yml @@ -0,0 +1,34 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: packageGrouping + data: + - ["beego-logs", "github.com/astaxie/beego/logs"] + - ["beego-logs", "github.com/beego/beego/logs"] + - ["beego-logs", "github.com/beego/beego/core/logs"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["group:beego-logs", "", False, "Alert", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "", False, "Critical", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "", False, "Debug", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "", False, "Emergency", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "", False, "Error", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "", False, "Info", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "", False, "Informational", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "", False, "Notice", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "", False, "Trace", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "", False, "Warn", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "", False, "Warning", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", False, "Alert", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", False, "Critical", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", False, "Debug", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", False, "Emergency", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", False, "Error", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", False, "Info", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", False, "Informational", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", False, "Notice", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", False, "Trace", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", False, "Warn", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", False, "Warning", "", "", "Argument[0..1]", "log-injection", "manual"] diff --git a/go/ql/lib/ext/github.com.beego.beego.core.utils.model.yml b/go/ql/lib/ext/github.com.beego.beego.core.utils.model.yml index 4eb0688e37e..63c05b92040 100644 --- a/go/ql/lib/ext/github.com.beego.beego.core.utils.model.yml +++ b/go/ql/lib/ext/github.com.beego.beego.core.utils.model.yml @@ -6,6 +6,11 @@ extensions: - ["beego-utils", "github.com/astaxie/beego/utils"] - ["beego-utils", "github.com/beego/beego/utils"] - ["beego-utils", "github.com/beego/beego/core/utils"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["group:beego-utils", "", False, "Display", "", "", "Argument[0]", "log-injection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/ext/github.com.beego.beego.server.web.model.yml b/go/ql/lib/ext/github.com.beego.beego.server.web.model.yml index 963000fffcc..0c539522c5a 100644 --- a/go/ql/lib/ext/github.com.beego.beego.server.web.model.yml +++ b/go/ql/lib/ext/github.com.beego.beego.server.web.model.yml @@ -10,6 +10,18 @@ extensions: pack: codeql/go-all extensible: sinkModel data: + # log-injection + - ["group:beego", "", False, "Alert", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego", "", False, "Critical", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego", "", False, "Debug", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego", "", False, "Emergency", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego", "", False, "Error", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego", "", False, "Info", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego", "", False, "Informational", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego", "", False, "Notice", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego", "", False, "Trace", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego", "", False, "Warn", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego", "", False, "Warning", "", "", "Argument[0..1]", "log-injection", "manual"] # path-injection - ["group:beego", "", False, "Walk", "", "", "Argument[1]", "path-injection", "manual"] - ["group:beego", "Controller", True, "SaveToFile", "", "", "Argument[1]", "path-injection", "manual"] diff --git a/go/ql/lib/ext/github.com.davecgh.go-spew.spew.model.yml b/go/ql/lib/ext/github.com.davecgh.go-spew.spew.model.yml new file mode 100644 index 00000000000..4b4996926e3 --- /dev/null +++ b/go/ql/lib/ext/github.com.davecgh.go-spew.spew.model.yml @@ -0,0 +1,14 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["github.com/davecgh/go-spew/spew", "", False, "Dump", "", "", "Argument[0]", "log-injection", "manual"] + - ["github.com/davecgh/go-spew/spew", "", False, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["github.com/davecgh/go-spew/spew", "", False, "Fdump", "", "", "Argument[1]", "log-injection", "manual"] + - ["github.com/davecgh/go-spew/spew", "", False, "Fprint", "", "", "Argument[1]", "log-injection", "manual"] + - ["github.com/davecgh/go-spew/spew", "", False, "Fprintf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["github.com/davecgh/go-spew/spew", "", False, "Fprintln", "", "", "Argument[1]", "log-injection", "manual"] + - ["github.com/davecgh/go-spew/spew", "", False, "Print", "", "", "Argument[0]", "log-injection", "manual"] + - ["github.com/davecgh/go-spew/spew", "", False, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["github.com/davecgh/go-spew/spew", "", False, "Println", "", "", "Argument[0]", "log-injection", "manual"] diff --git a/go/ql/lib/ext/github.com.elazarl.goproxy.model.yml b/go/ql/lib/ext/github.com.elazarl.goproxy.model.yml index 20e4a26f1cd..01a61d2c3ac 100644 --- a/go/ql/lib/ext/github.com.elazarl.goproxy.model.yml +++ b/go/ql/lib/ext/github.com.elazarl.goproxy.model.yml @@ -1,4 +1,10 @@ extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["github.com/elazarl/goproxy", "ProxyCtx", False, "Logf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["github.com/elazarl/goproxy", "ProxyCtx", False, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/ext/github.com.golang.glog.model.yml b/go/ql/lib/ext/github.com.golang.glog.model.yml new file mode 100644 index 00000000000..dd36e6a7d8f --- /dev/null +++ b/go/ql/lib/ext/github.com.golang.glog.model.yml @@ -0,0 +1,102 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: packageGrouping + data: + - ["glog", "github.com/golang/glog"] + - ["glog", "gopkg.in/glog"] + - ["glog", "k8s.io/klog"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["group:glog", "", False, "Error", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "", False, "ErrorContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "", False, "ErrorContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "", False, "ErrorContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "", False, "ErrorContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "", False, "ErrorDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "", False, "ErrorDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "", False, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "", False, "Errorln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "", False, "Exit", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "", False, "ExitContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "", False, "ExitContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "", False, "ExitContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "", False, "ExitContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "", False, "ExitDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "", False, "ExitDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "", False, "Exitf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "", False, "Exitln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "", False, "FatalContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "", False, "FatalContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "", False, "FatalContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "", False, "FatalContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "", False, "FatalDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "", False, "FatalDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "", False, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "", False, "Info", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "", False, "InfoContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "", False, "InfoContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "", False, "InfoContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "", False, "InfoContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "", False, "InfoDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "", False, "InfoDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "", False, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "", False, "Infoln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "", False, "Warning", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "", False, "WarningContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "", False, "WarningContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "", False, "WarningContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "", False, "WarningContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "", False, "WarningDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "", False, "WarningDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "", False, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "", False, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Error", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "ErrorContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "ErrorContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "ErrorContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "ErrorContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "ErrorDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "ErrorDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Errorln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Exit", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "ExitContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "ExitContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "ExitContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "ExitContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "ExitDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "ExitDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Exitf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Exitln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "FatalContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "FatalContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "FatalContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "FatalContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "FatalDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "FatalDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Info", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "InfoContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "InfoContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "InfoContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "InfoContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "InfoDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "InfoDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Infoln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Warning", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "WarningContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "WarningContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "WarningContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "WarningContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "WarningDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "WarningDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "Verbose", False, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] diff --git a/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml b/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml new file mode 100644 index 00000000000..5779b5fa639 --- /dev/null +++ b/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml @@ -0,0 +1,131 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: packageGrouping + data: + - ["logrus", "github.com/sirupsen/logrus"] + - ["logrus", "ggithub.com/Sirupsen/logrus"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["group:logrus", "", False, "Debug", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "DebugFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Debugf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "", False, "Debugln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Error", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "ErrorFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "", False, "Errorln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "FatalFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "", False, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Info", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "InfoFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "", False, "Infoln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Panic", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "PanicFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "", False, "Panicln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Print", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "PrintFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "", False, "Println", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Trace", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "TraceFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Tracef", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "", False, "Traceln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Warn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "WarnFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "", False, "Warnln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Warning", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "WarningFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "", False, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "WithError", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "WithField", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "", False, "WithFields", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "", False, "WithTime", "", "", "Argument[0]", "log-injection", "manual"] + + - ["group:logrus", "Entry", False, "Debug", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Debugf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Debugln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Error", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Errorln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Info", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Infoln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Log", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Logf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Logln", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Panic", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Panicln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Print", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Println", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Trace", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Tracef", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Traceln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Warn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Warnln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Warning", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "WithError", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "WithField", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "WithFields", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", False, "WithTime", "", "", "Argument[0]", "log-injection", "manual"] + + - ["group:logrus", "Logger", False, "Debug", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "DebugFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Debugf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Debugln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Error", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "ErrorFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Errorln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "FatalFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Info", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "InfoFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Infoln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Log", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "LogFn", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Logf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Logln", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Panic", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "PanicFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Panicln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Print", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "PrintFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Println", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Trace", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "TraceFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Tracef", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Traceln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Warn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "WarnFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Warnln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Warning", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "WarningFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "WithError", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "WithField", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "WithFields", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "WithTime", "", "", "Argument[0]", "log-injection", "manual"] diff --git a/go/ql/lib/ext/go.uber.org.zap.model.yml b/go/ql/lib/ext/go.uber.org.zap.model.yml index 2ca7f7e8a80..c4e43356f26 100644 --- a/go/ql/lib/ext/go.uber.org.zap.model.yml +++ b/go/ql/lib/ext/go.uber.org.zap.model.yml @@ -1,4 +1,41 @@ extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["go.uber.org/zap", "Logger", False, "DPanic", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", False, "Debug", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", False, "Error", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", False, "Fatal", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", False, "Info", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", False, "Named", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", False, "Panic", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", False, "Warn", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", False, "With", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", False, "WithOptions", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "DPanic", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "DPanicf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "DPanicw", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Debug", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Debugf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Debugw", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Error", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Errorw", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Fatalw", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Info", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Infow", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Named", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Panic", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Panicw", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Warn", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "Warnw", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", False, "With", "", "", "Argument[0]", "log-injection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/ext/log.model.yml b/go/ql/lib/ext/log.model.yml index 7f52a173307..1ebce079a52 100644 --- a/go/ql/lib/ext/log.model.yml +++ b/go/ql/lib/ext/log.model.yml @@ -1,4 +1,28 @@ extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["log", "", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["log", "", False, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "", False, "Output", "", "", "Argument[1]", "log-injection", "manual"] + - ["log", "", False, "Panic", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "", False, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["log", "", False, "Panicln", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "", False, "Print", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "", False, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["log", "", False, "Println", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "Logger", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "Logger", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["log", "Logger", False, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "Logger", False, "Output", "", "", "Argument[1]", "log-injection", "manual"] + - ["log", "Logger", False, "Panic", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "Logger", False, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["log", "Logger", False, "Panicln", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "Logger", False, "Print", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "Logger", False, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["log", "Logger", False, "Println", "", "", "Argument[0]", "log-injection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/semmle/go/Concepts.qll b/go/ql/lib/semmle/go/Concepts.qll index c15d3683b40..edb8e6c88fd 100644 --- a/go/ql/lib/semmle/go/Concepts.qll +++ b/go/ql/lib/semmle/go/Concepts.qll @@ -373,6 +373,23 @@ module LoggerCall { } } +private class DefaultLoggerCall extends LoggerCall::Range, DataFlow::CallNode { + DataFlow::ArgumentNode messageComponent; + + DefaultLoggerCall() { + sinkNode(messageComponent, "log-injection") and + this = messageComponent.getCall() + } + + override DataFlow::Node getAMessageComponent() { + not messageComponent instanceof DataFlow::ImplicitVarargsSlice and + result = messageComponent + or + messageComponent instanceof DataFlow::ImplicitVarargsSlice and + result = this.getAnImplicitVarargsArgument() + } +} + /** * A function that encodes data into a binary or textual format. * diff --git a/go/ql/lib/semmle/go/frameworks/Beego.qll b/go/ql/lib/semmle/go/frameworks/Beego.qll index 9f6ee598003..a9e296a1f97 100644 --- a/go/ql/lib/semmle/go/frameworks/Beego.qll +++ b/go/ql/lib/semmle/go/frameworks/Beego.qll @@ -33,13 +33,6 @@ module Beego { result = package(v2modulePath(), "server/web/context") } - /** Gets the path for the logs package of beego. */ - string logsPackagePath() { - result = package(v1modulePath(), "logs") - or - result = package(v2modulePath(), "core/logs") - } - /** Gets the path for the utils package of beego. */ string utilsPackagePath() { result = package(v1modulePath(), "utils") @@ -172,36 +165,6 @@ module Beego { override string getAContentType() { none() } } - private string getALogFunctionName() { - result = - [ - "Alert", "Critical", "Debug", "Emergency", "Error", "Info", "Informational", "Notice", - "Trace", "Warn", "Warning" - ] - } - - private class ToplevelBeegoLoggers extends LoggerCall::Range, DataFlow::CallNode { - ToplevelBeegoLoggers() { - this.getTarget().hasQualifiedName([packagePath(), logsPackagePath()], getALogFunctionName()) - } - - override DataFlow::Node getAMessageComponent() { result = this.getASyntacticArgument() } - } - - private class BeegoLoggerMethods extends LoggerCall::Range, DataFlow::MethodCallNode { - BeegoLoggerMethods() { - this.getTarget().hasQualifiedName(logsPackagePath(), "BeeLogger", getALogFunctionName()) - } - - override DataFlow::Node getAMessageComponent() { result = this.getASyntacticArgument() } - } - - private class UtilLoggers extends LoggerCall::Range, DataFlow::CallNode { - UtilLoggers() { this.getTarget().hasQualifiedName(utilsPackagePath(), "Display") } - - override DataFlow::Node getAMessageComponent() { result = this.getASyntacticArgument() } - } - private class HtmlQuoteSanitizer extends SharedXss::Sanitizer { HtmlQuoteSanitizer() { exists(DataFlow::CallNode c | c.getTarget().hasQualifiedName(packagePath(), "Htmlquote") | diff --git a/go/ql/lib/semmle/go/frameworks/ElazarlGoproxy.qll b/go/ql/lib/semmle/go/frameworks/ElazarlGoproxy.qll index 4d10c8af312..b1bf4571216 100644 --- a/go/ql/lib/semmle/go/frameworks/ElazarlGoproxy.qll +++ b/go/ql/lib/semmle/go/frameworks/ElazarlGoproxy.qll @@ -100,10 +100,4 @@ module ElazarlGoproxy { override int getFormatStringIndex() { result = 0 } } - - private class ProxyLog extends LoggerCall::Range, DataFlow::MethodCallNode { - ProxyLog() { this.getTarget() instanceof ProxyLogFunction } - - override DataFlow::Node getAMessageComponent() { result = this.getASyntacticArgument() } - } } diff --git a/go/ql/lib/semmle/go/frameworks/Glog.qll b/go/ql/lib/semmle/go/frameworks/Glog.qll index f9f5c9e3f11..146b8a4f814 100644 --- a/go/ql/lib/semmle/go/frameworks/Glog.qll +++ b/go/ql/lib/semmle/go/frameworks/Glog.qll @@ -40,14 +40,4 @@ module Glog { override int getFormatStringIndex() { result = super.getFirstPrintedArg() } } - - private class GlogCall extends LoggerCall::Range, DataFlow::CallNode { - GlogFunction callee; - - GlogCall() { this = callee.getACall() } - - override DataFlow::Node getAMessageComponent() { - result = this.getSyntacticArgument(any(int i | i >= callee.getFirstPrintedArg())) - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/Logrus.qll b/go/ql/lib/semmle/go/frameworks/Logrus.qll index f7de9a75dae..83278a4cd9e 100644 --- a/go/ql/lib/semmle/go/frameworks/Logrus.qll +++ b/go/ql/lib/semmle/go/frameworks/Logrus.qll @@ -28,12 +28,6 @@ module Logrus { } } - private class LogCall extends LoggerCall::Range, DataFlow::CallNode { - LogCall() { this = any(LogFunction f).getACall() } - - override DataFlow::Node getAMessageComponent() { result = this.getASyntacticArgument() } - } - private class StringFormatters extends StringOps::Formatting::Range instanceof LogFunction { int argOffset; diff --git a/go/ql/lib/semmle/go/frameworks/Spew.qll b/go/ql/lib/semmle/go/frameworks/Spew.qll index b12bd0fed81..f49a4aa4d89 100644 --- a/go/ql/lib/semmle/go/frameworks/Spew.qll +++ b/go/ql/lib/semmle/go/frameworks/Spew.qll @@ -33,16 +33,6 @@ module Spew { override int getFormatStringIndex() { result = super.getFirstPrintedArg() } } - private class SpewCall extends LoggerCall::Range, DataFlow::CallNode { - SpewFunction target; - - SpewCall() { this = target.getACall() } - - override DataFlow::Node getAMessageComponent() { - result = this.getSyntacticArgument(any(int i | i >= target.getFirstPrintedArg())) - } - } - // These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. /** The `Sprint` function or one of its variants. */ class Sprinter extends TaintTracking::FunctionModel { diff --git a/go/ql/lib/semmle/go/frameworks/Zap.qll b/go/ql/lib/semmle/go/frameworks/Zap.qll index 359f9aba410..0928d2b0595 100644 --- a/go/ql/lib/semmle/go/frameworks/Zap.qll +++ b/go/ql/lib/semmle/go/frameworks/Zap.qll @@ -34,18 +34,6 @@ module Zap { override int getFormatStringIndex() { result = 0 } } - /** - * A call to a logger function in Zap. - * - * Functions which add data to be included the next time a direct logging - * function is called are included. - */ - private class ZapCall extends LoggerCall::Range, DataFlow::MethodCallNode { - ZapCall() { this = any(ZapFunction f).getACall() } - - override DataFlow::Node getAMessageComponent() { result = this.getASyntacticArgument() } - } - // These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. /** The function `Fields` that creates an `Option` that can be added to the logger out of `Field`s. */ class FieldsFunction extends TaintTracking::FunctionModel { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll index 54794ea21c9..6adbd542e9b 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll @@ -41,13 +41,6 @@ module Fmt { Printer() { this.hasQualifiedName("fmt", ["Print", "Printf", "Println"]) } } - /** A call to `Print` or similar. */ - private class PrintCall extends LoggerCall::Range, DataFlow::CallNode { - PrintCall() { this.getTarget() instanceof Printer } - - override DataFlow::Node getAMessageComponent() { result = this.getASyntacticArgument() } - } - /** The `Fprint` function or one of its variants. */ private class Fprinter extends TaintTracking::FunctionModel { Fprinter() { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll index 5b402fca1b7..ca74160bf0d 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll @@ -32,16 +32,6 @@ module Log { override int getFormatStringIndex() { result = 0 } } - private class LogCall extends LoggerCall::Range, DataFlow::CallNode { - LogFunction target; - - LogCall() { this = target.getACall() } - - override DataFlow::Node getAMessageComponent() { - result = this.getSyntacticArgument(any(int i | i >= target.getFirstPrintedArg())) - } - } - /** A fatal log function, which calls `os.Exit`. */ private class FatalLogFunction extends Function { FatalLogFunction() { this.hasQualifiedName("log", ["Fatal", "Fatalf", "Fatalln"]) } From a0729fc7606ad1c10e0bedbc9ebc81b738dc28b7 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> Date: Fri, 9 Aug 2024 14:27:58 +0100 Subject: [PATCH 071/470] Fix typo in package path Co-authored-by: Edward Minnix III --- go/ql/lib/ext/github.com.sirupsen.logrus.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml b/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml index 5779b5fa639..54f802e0241 100644 --- a/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml +++ b/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml @@ -4,7 +4,7 @@ extensions: extensible: packageGrouping data: - ["logrus", "github.com/sirupsen/logrus"] - - ["logrus", "ggithub.com/Sirupsen/logrus"] + - ["logrus", "github.com/Sirupsen/logrus"] - addsTo: pack: codeql/go-all extensible: sinkModel From 25cd4d4585a13ab614028b7d83b28fdd43d679be Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 12 Sep 2024 14:27:38 +0100 Subject: [PATCH 072/470] Model some squirrel methods in QL We need to put a restriction on the type of the argument. --- .../github.com.mastermind.squirrel.model.yml | 6 +++--- go/ql/lib/semmle/go/frameworks/SQL.qll | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/go/ql/lib/ext/github.com.mastermind.squirrel.model.yml b/go/ql/lib/ext/github.com.mastermind.squirrel.model.yml index a5f46d7c214..dc476abd057 100644 --- a/go/ql/lib/ext/github.com.mastermind.squirrel.model.yml +++ b/go/ql/lib/ext/github.com.mastermind.squirrel.model.yml @@ -20,7 +20,7 @@ extensions: - ["group:squirrel", "DeleteBuilder", True, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement - ["group:squirrel", "DeleteBuilder", True, "Prefix", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:squirrel", "DeleteBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:squirrel", "DeleteBuilder", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] + # DeleteBuilder.Where has to be modeled in QL to avoid FPs when a non-string argument is used - ["group:squirrel", "InsertBuilder", True, "Columns", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement - ["group:squirrel", "InsertBuilder", True, "Into", "", "", "Argument[0]", "sql-injection", "manual"] @@ -40,7 +40,7 @@ extensions: - ["group:squirrel", "SelectBuilder", True, "Prefix", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:squirrel", "SelectBuilder", True, "RightJoin", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:squirrel", "SelectBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:squirrel", "SelectBuilder", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] + # SelectBuilder.Where has to be modeled in QL to avoid FPs when a non-string argument is used - ["group:squirrel", "UpdateBuilder", True, "From", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:squirrel", "UpdateBuilder", True, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement @@ -48,4 +48,4 @@ extensions: - ["group:squirrel", "UpdateBuilder", True, "Set", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:squirrel", "UpdateBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:squirrel", "UpdateBuilder", True, "Table", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:squirrel", "UpdateBuilder", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] + # UpdateBuilder.Where has to be modeled in QL to avoid FPs when a non-string argument is used diff --git a/go/ql/lib/semmle/go/frameworks/SQL.qll b/go/ql/lib/semmle/go/frameworks/SQL.qll index c2a550602e1..e555e22d3b9 100644 --- a/go/ql/lib/semmle/go/frameworks/SQL.qll +++ b/go/ql/lib/semmle/go/frameworks/SQL.qll @@ -79,6 +79,27 @@ module SQL { } } + /** + * An argument to an API of the squirrel library that is directly interpreted as SQL without + * taking syntactic structure into account. + */ + private class SquirrelQueryString extends Range { + SquirrelQueryString() { + exists(string sq, Method m, string builder | + FlowExtensions::packageGrouping("squirrel", sq) and + builder = ["DeleteBuilder", "SelectBuilder", "UpdateBuilder"] + | + m.hasQualifiedName(sq, builder, "Where") and + this = m.getACall().getArgument(0) + ) and + ( + this.getType().getUnderlyingType() instanceof StringType + or + this.getType().getUnderlyingType().(SliceType).getElementType() instanceof StringType + ) + } + } + /** A string that might identify package `go-pg/pg` or a specific version of it. */ private string gopg() { result = package("github.com/go-pg/pg", "") } From d37c816bd990f7839d040d6963b47c86b0ffe2e7 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 12 Sep 2024 15:23:12 +0100 Subject: [PATCH 073/470] Model some Xorm methods in QL --- go/ql/lib/ext/xorm.io.xorm.model.yml | 12 ++++-------- go/ql/lib/semmle/go/frameworks/SQL.qll | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/go/ql/lib/ext/xorm.io.xorm.model.yml b/go/ql/lib/ext/xorm.io.xorm.model.yml index fd73b7c9a66..5cf1ac4f5d7 100644 --- a/go/ql/lib/ext/xorm.io.xorm.model.yml +++ b/go/ql/lib/ext/xorm.io.xorm.model.yml @@ -11,7 +11,7 @@ extensions: data: - ["group:xorm", "Engine", True, "Alias", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Engine", True, "And", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:xorm", "Engine", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + # Engine.Exec has to be modeled in QL to select only the first syntactic argument - ["group:xorm", "Engine", True, "GroupBy", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Engine", True, "Having", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Engine", True, "In", "", "", "Argument[0]", "sql-injection", "manual"] @@ -19,9 +19,7 @@ extensions: - ["group:xorm", "Engine", True, "NotIn", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Engine", True, "Or", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Engine", True, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:xorm", "Engine", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:xorm", "Engine", True, "QueryString", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:xorm", "Engine", True, "QueryInterface", "", "", "Argument[0]", "sql-injection", "manual"] + # Engine.Query, Engine.QueryInterface and Engine.QueryString have to be modeled in QL to select only the first syntactic argument - ["group:xorm", "Engine", True, "Select", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Engine", True, "SetExpr", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Engine", True, "SQL", "", "", "Argument[0]", "sql-injection", "manual"] @@ -32,7 +30,7 @@ extensions: - ["group:xorm", "Engine", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Session", True, "Alias", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Session", True, "And", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:xorm", "Session", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + # Session.Exec has to be modeled in QL to select only the first syntactic argument - ["group:xorm", "Session", True, "GroupBy", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Session", True, "Having", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Session", True, "In", "", "", "Argument[0]", "sql-injection", "manual"] @@ -40,9 +38,7 @@ extensions: - ["group:xorm", "Session", True, "NotIn", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Session", True, "Or", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Session", True, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:xorm", "Session", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:xorm", "Session", True, "QueryString", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:xorm", "Session", True, "QueryInterface", "", "", "Argument[0]", "sql-injection", "manual"] + # Session.Query, Session.QueryInterface and Session.QueryString have to be modeled in QL to select only the first syntactic argument - ["group:xorm", "Session", True, "Select", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Session", True, "SetExpr", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:xorm", "Session", True, "SQL", "", "", "Argument[0]", "sql-injection", "manual"] diff --git a/go/ql/lib/semmle/go/frameworks/SQL.qll b/go/ql/lib/semmle/go/frameworks/SQL.qll index e555e22d3b9..a0e80fde1c9 100644 --- a/go/ql/lib/semmle/go/frameworks/SQL.qll +++ b/go/ql/lib/semmle/go/frameworks/SQL.qll @@ -188,7 +188,20 @@ module Gorm { */ module Xorm { /** Gets the package name for Xorm. */ - string packagePath() { result = package(["xorm.io/xorm", "github.com/go-xorm/xorm"], "") } + string packagePath() { FlowExtensions::packageGrouping("xorm", result) } + + /** A model for sinks of XORM. */ + private class XormSink extends SQL::QueryString::Range { + XormSink() { + exists(Method meth, string type, string name | + meth.hasQualifiedName(Xorm::packagePath(), type, name) and + type = ["Engine", "Session"] and + name = ["Exec", "Query", "QueryInterface", "QueryString"] + | + this = meth.getACall().getSyntacticArgument(0) + ) + } + } } /** From 8cbab0c66ebc842de5e75e0bfd775f32acc369be Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 17 Sep 2024 10:36:03 +0100 Subject: [PATCH 074/470] Model `logrus.FieldLogger` using models-as-data --- .../ext/github.com.sirupsen.logrus.model.yml | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml b/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml index 54f802e0241..b3ef5ea1d10 100644 --- a/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml +++ b/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml @@ -85,6 +85,34 @@ extensions: - ["group:logrus", "Entry", False, "WithFields", "", "", "Argument[0]", "log-injection", "manual"] - ["group:logrus", "Entry", False, "WithTime", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Debug", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Debugf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Debugln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Error", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Errorln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Info", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Infoln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Panic", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Panicln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Print", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Println", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Warn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Warnln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Warning", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "WithError", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "WithField", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", False, "WithFields", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", False, "Debug", "", "", "Argument[0]", "log-injection", "manual"] - ["group:logrus", "Logger", False, "DebugFn", "", "", "Argument[0]", "log-injection", "manual"] - ["group:logrus", "Logger", False, "Debugf", "", "", "Argument[0..1]", "log-injection", "manual"] From 5a0cd2e7d674819e0073d483ba5c41576687a2a3 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 12 Sep 2024 11:27:32 +0100 Subject: [PATCH 075/470] Add tests for squirrel.Eq --- .../library-tests/semmle/go/frameworks/SQL/squirrel.go | 8 +++++++- .../SQL/vendor/github.com/Masterminds/squirrel/stub.go | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/squirrel.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/squirrel.go index 3629b8087cb..d0350643bb0 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/squirrel.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/squirrel.go @@ -1,6 +1,6 @@ package main -//go:generate depstubber -vendor github.com/Masterminds/squirrel DeleteBuilder,InsertBuilder,SelectBuilder,UpdateBuilder Delete,Expr,Insert,Select,Update +//go:generate depstubber -vendor github.com/Masterminds/squirrel DeleteBuilder,Eq,InsertBuilder,SelectBuilder,UpdateBuilder Delete,Expr,Insert,Select,Update import ( "github.com/Masterminds/squirrel" @@ -44,4 +44,10 @@ func squirrelTest(querypart string) { updateBuilder.Where(querypart) // $ querystring=querypart updateBuilder.Set(querypart, "") // $ querystring=querypart updateBuilder.Table(querypart) // $ querystring=querypart + + // safe + wrapped := squirrel.Eq{"id": querypart} + deleteBuilder.Where(wrapped) + selectBuilder.Where(wrapped) + updateBuilder.Where(wrapped) } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/vendor/github.com/Masterminds/squirrel/stub.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/vendor/github.com/Masterminds/squirrel/stub.go index 96a30e49d4e..1a9e5ca0e9b 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/vendor/github.com/Masterminds/squirrel/stub.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/vendor/github.com/Masterminds/squirrel/stub.go @@ -2,7 +2,7 @@ // This is a simple stub for github.com/Masterminds/squirrel, strictly for use in testing. // See the LICENSE file for information about the licensing of the original library. -// Source: github.com/Masterminds/squirrel (exports: DeleteBuilder,InsertBuilder,SelectBuilder,UpdateBuilder; functions: Delete,Expr,Insert,Select,Update) +// Source: github.com/Masterminds/squirrel (exports: DeleteBuilder,Eq,InsertBuilder,SelectBuilder,UpdateBuilder; functions: Delete,Expr,Insert,Select,Update) // Package squirrel is a stub of github.com/Masterminds/squirrel, generated by depstubber. package squirrel @@ -99,6 +99,12 @@ func (_ DeleteBuilder) Where(_ interface{}, _ ...interface{}) DeleteBuilder { return DeleteBuilder{} } +type Eq map[string]interface{} + +func (_ Eq) ToSql() (string, []interface{}, error) { + return "", nil, nil +} + func Expr(_ string, _ ...interface{}) Sqlizer { return nil } From cc62db796c57cdb1623c5a87a4d762ac2286c549 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 12 Sep 2024 11:28:02 +0100 Subject: [PATCH 076/470] Add tests for Xorm first argument of varargs slice --- .../semmle/go/frameworks/SQL/xorm.go | 117 +++++++++--------- 1 file changed, 61 insertions(+), 56 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/xorm.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/xorm.go index 6b4dbb116ee..f63b33a0e09 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/xorm.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/xorm.go @@ -10,68 +10,73 @@ import ( func xormtest() { query := "UntrustedString" + arg := "arg" engine1 := xorm1.Engine{} - engine1.Query(query) // $ querystring=query - engine1.QueryString(query) // $ querystring=query - engine1.QueryInterface(query) // $ querystring=query - engine1.SQL(query) // $ querystring=query - engine1.Where(query) // $ querystring=query - engine1.Alias(query) // $ querystring=query - engine1.NotIn(query) // $ querystring=query - engine1.In(query) // $ querystring=query - engine1.Select(query) // $ querystring=query - engine1.SetExpr(query, nil) // $ querystring=query - engine1.OrderBy(query) // $ querystring=query - engine1.Having(query) // $ querystring=query - engine1.GroupBy(query) // $ querystring=query + engine1.Query(query, arg) // $ querystring=query + engine1.Exec(query, arg) // $ querystring=query + engine1.QueryString(query, arg) // $ querystring=query + engine1.QueryInterface(query, arg) // $ querystring=query + engine1.SQL(query) // $ querystring=query + engine1.Where(query) // $ querystring=query + engine1.Alias(query) // $ querystring=query + engine1.NotIn(query) // $ querystring=query + engine1.In(query) // $ querystring=query + engine1.Select(query) // $ querystring=query + engine1.SetExpr(query, nil) // $ querystring=query + engine1.OrderBy(query) // $ querystring=query + engine1.Having(query) // $ querystring=query + engine1.GroupBy(query) // $ querystring=query engine2 := xorm2.Engine{} - engine2.Query(query) // $ querystring=query - engine2.QueryString(query) // $ querystring=query - engine2.QueryInterface(query) // $ querystring=query - engine2.SQL(query) // $ querystring=query - engine2.Where(query) // $ querystring=query - engine2.Alias(query) // $ querystring=query - engine2.NotIn(query) // $ querystring=query - engine2.In(query) // $ querystring=query - engine2.Select(query) // $ querystring=query - engine2.SetExpr(query, nil) // $ querystring=query - engine2.OrderBy(query) // $ querystring=query - engine2.Having(query) // $ querystring=query - engine2.GroupBy(query) // $ querystring=query + engine2.Query(query, arg) // $ querystring=query + engine2.Exec(query, arg) // $ querystring=query + engine2.QueryString(query, arg) // $ querystring=query + engine2.QueryInterface(query, arg) // $ querystring=query + engine2.SQL(query) // $ querystring=query + engine2.Where(query) // $ querystring=query + engine2.Alias(query) // $ querystring=query + engine2.NotIn(query) // $ querystring=query + engine2.In(query) // $ querystring=query + engine2.Select(query) // $ querystring=query + engine2.SetExpr(query, nil) // $ querystring=query + engine2.OrderBy(query) // $ querystring=query + engine2.Having(query) // $ querystring=query + engine2.GroupBy(query) // $ querystring=query session1 := xorm1.Session{} - session1.Query(query) // $ querystring=query - session1.QueryString(query) // $ querystring=query - session1.QueryInterface(query) // $ querystring=query - session1.SQL(query) // $ querystring=query - session1.Where(query) // $ querystring=query - session1.Alias(query) // $ querystring=query - session1.NotIn(query) // $ querystring=query - session1.In(query) // $ querystring=query - session1.Select(query) // $ querystring=query - session1.SetExpr(query, nil) // $ querystring=query - session1.OrderBy(query) // $ querystring=query - session1.Having(query) // $ querystring=query - session1.GroupBy(query) // $ querystring=query - session1.And(query) // $ querystring=query - session1.Or(query) // $ querystring=query + session1.Query(query, arg) // $ querystring=query + session1.Exec(query, arg) // $ querystring=query + session1.QueryString(query, arg) // $ querystring=query + session1.QueryInterface(query, arg) // $ querystring=query + session1.SQL(query) // $ querystring=query + session1.Where(query) // $ querystring=query + session1.Alias(query) // $ querystring=query + session1.NotIn(query) // $ querystring=query + session1.In(query) // $ querystring=query + session1.Select(query) // $ querystring=query + session1.SetExpr(query, nil) // $ querystring=query + session1.OrderBy(query) // $ querystring=query + session1.Having(query) // $ querystring=query + session1.GroupBy(query) // $ querystring=query + session1.And(query) // $ querystring=query + session1.Or(query) // $ querystring=query session2 := xorm2.Session{} - session2.Query(query) // $ querystring=query - session2.QueryString(query) // $ querystring=query - session2.QueryInterface(query) // $ querystring=query - session2.SQL(query) // $ querystring=query - session2.Where(query) // $ querystring=query - session2.Alias(query) // $ querystring=query - session2.NotIn(query) // $ querystring=query - session2.In(query) // $ querystring=query - session2.Select(query) // $ querystring=query - session2.SetExpr(query, nil) // $ querystring=query - session2.OrderBy(query) // $ querystring=query - session2.Having(query) // $ querystring=query - session2.GroupBy(query) // $ querystring=query - session2.And(query) // $ querystring=query - session2.Or(query) // $ querystring=query + session2.Query(query, arg) // $ querystring=query + session2.Exec(query, arg) // $ querystring=query + session2.QueryString(query, arg) // $ querystring=query + session2.QueryInterface(query, arg) // $ querystring=query + session2.SQL(query) // $ querystring=query + session2.Where(query) // $ querystring=query + session2.Alias(query) // $ querystring=query + session2.NotIn(query) // $ querystring=query + session2.In(query) // $ querystring=query + session2.Select(query) // $ querystring=query + session2.SetExpr(query, nil) // $ querystring=query + session2.OrderBy(query) // $ querystring=query + session2.Having(query) // $ querystring=query + session2.GroupBy(query) // $ querystring=query + session2.And(query) // $ querystring=query + session2.Or(query) // $ querystring=query } From 791313fbdffc3dd31d99df32404e9a1ffc6230e1 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 12 Sep 2024 11:29:01 +0100 Subject: [PATCH 077/470] Add tests for logrus.FieldLogger --- .../Security/CWE-117/LogInjection.go | 36 ++++++++++++++++++- .../vendor/github.com/sirupsen/logrus/stub.go | 32 ++++++++++++++++- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/go/ql/test/query-tests/Security/CWE-117/LogInjection.go b/go/ql/test/query-tests/Security/CWE-117/LogInjection.go index 4f02cc9aef8..81568be3db8 100644 --- a/go/ql/test/query-tests/Security/CWE-117/LogInjection.go +++ b/go/ql/test/query-tests/Security/CWE-117/LogInjection.go @@ -7,7 +7,7 @@ package main //go:generate depstubber -vendor github.com/davecgh/go-spew/spew "" Dump,Errorf,Print,Printf,Println,Fdump,Fprint,Fprintf,Fprintln //go:generate depstubber -vendor github.com/elazarl/goproxy ProxyCtx "" //go:generate depstubber -vendor github.com/golang/glog Level,Verbose Info,InfoDepth,Infof,Infoln,Error,ErrorDepth,Errorf,Errorln,Fatal,FatalDepth,Fatalf,Fatalln,Exit,ExitDepth,Exitf,Exitln,V -//go:generate depstubber -vendor github.com/sirupsen/logrus Fields,Entry,Logger,Level Debug,Debugf,Debugln,Error,Errorf,Errorln,Fatal,Fatalf,Fatalln,Info,Infof,Infoln,Panic,Panicf,Panicln,Print,Printf,Println,Trace,Tracef,Traceln,Warn,Warnf,Warnln,Warning,Warningf,Warningln,WithFields,WithField +//go:generate depstubber -vendor github.com/sirupsen/logrus FieldLogger,Fields,Entry,Logger,Level Debug,Debugf,Debugln,Error,Errorf,Errorln,Fatal,Fatalf,Fatalln,Info,Infof,Infoln,Panic,Panicf,Panicln,Print,Printf,Println,Trace,Tracef,Traceln,Warn,Warnf,Warnln,Warning,Warningf,Warningln,WithFields,WithField //go:generate depstubber -vendor go.uber.org/zap Logger,SugaredLogger NewProduction import ( @@ -293,6 +293,40 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) { logger.Warningf(username, "") // $ hasTaintFlow="username" logger.Warningf("", username) // $ hasTaintFlow="username" logger.Warningln(username) // $ hasTaintFlow="username" + + var fieldlogger logrus.FieldLogger = entry + fieldlogger.Debug(username) // $ hasTaintFlow="username" + fieldlogger.Debugf(username, "") // $ hasTaintFlow="username" + fieldlogger.Debugf("", username) // $ hasTaintFlow="username" + fieldlogger.Debugln(username) // $ hasTaintFlow="username" + fieldlogger.Error(username) // $ hasTaintFlow="username" + fieldlogger.Errorf(username, "") // $ hasTaintFlow="username" + fieldlogger.Errorf("", username) // $ hasTaintFlow="username" + fieldlogger.Errorln(username) // $ hasTaintFlow="username" + fieldlogger.Fatal(username) // $ hasTaintFlow="username" + fieldlogger.Fatalf(username, "") // $ hasTaintFlow="username" + fieldlogger.Fatalf("", username) // $ hasTaintFlow="username" + fieldlogger.Fatalln(username) // $ hasTaintFlow="username" + fieldlogger.Info(username) // $ hasTaintFlow="username" + fieldlogger.Infof(username, "") // $ hasTaintFlow="username" + fieldlogger.Infof("", username) // $ hasTaintFlow="username" + fieldlogger.Infoln(username) // $ hasTaintFlow="username" + fieldlogger.Panic(username) // $ hasTaintFlow="username" + fieldlogger.Panicf(username, "") // $ hasTaintFlow="username" + fieldlogger.Panicf("", username) // $ hasTaintFlow="username" + fieldlogger.Panicln(username) // $ hasTaintFlow="username" + fieldlogger.Print(username) // $ hasTaintFlow="username" + fieldlogger.Printf(username, "") // $ hasTaintFlow="username" + fieldlogger.Printf("", username) // $ hasTaintFlow="username" + fieldlogger.Println(username) // $ hasTaintFlow="username" + fieldlogger.Warn(username) // $ hasTaintFlow="username" + fieldlogger.Warnf(username, "") // $ hasTaintFlow="username" + fieldlogger.Warnf("", username) // $ hasTaintFlow="username" + fieldlogger.Warnln(username) // $ hasTaintFlow="username" + fieldlogger.Warning(username) // $ hasTaintFlow="username" + fieldlogger.Warningf(username, "") // $ hasTaintFlow="username" + fieldlogger.Warningf("", username) // $ hasTaintFlow="username" + fieldlogger.Warningln(username) // $ hasTaintFlow="username" } // davecgh/go-spew/spew { diff --git a/go/ql/test/query-tests/Security/CWE-117/vendor/github.com/sirupsen/logrus/stub.go b/go/ql/test/query-tests/Security/CWE-117/vendor/github.com/sirupsen/logrus/stub.go index e8f7bccc446..61294748ea4 100644 --- a/go/ql/test/query-tests/Security/CWE-117/vendor/github.com/sirupsen/logrus/stub.go +++ b/go/ql/test/query-tests/Security/CWE-117/vendor/github.com/sirupsen/logrus/stub.go @@ -2,7 +2,7 @@ // This is a simple stub for github.com/sirupsen/logrus, strictly for use in testing. // See the LICENSE file for information about the licensing of the original library. -// Source: github.com/sirupsen/logrus (exports: Fields,Entry,Logger,Level; functions: Debug,Debugf,Debugln,Error,Errorf,Errorln,Fatal,Fatalf,Fatalln,Info,Infof,Infoln,Panic,Panicf,Panicln,Print,Printf,Println,Trace,Tracef,Traceln,Warn,Warnf,Warnln,Warning,Warningf,Warningln,WithFields,WithField) +// Source: github.com/sirupsen/logrus (exports: FieldLogger,Fields,Entry,Logger,Level; functions: Debug,Debugf,Debugln,Error,Errorf,Errorln,Fatal,Fatalf,Fatalln,Info,Infof,Infoln,Panic,Panicf,Panicln,Print,Printf,Println,Trace,Tracef,Traceln,Warn,Warnf,Warnln,Warning,Warningf,Warningln,WithFields,WithField) // Package logrus is a stub of github.com/sirupsen/logrus, generated by depstubber. package logrus @@ -148,6 +148,36 @@ func Fatalf(_ string, _ ...interface{}) {} func Fatalln(_ ...interface{}) {} +type FieldLogger interface { + Debug(_ ...interface{}) + Debugf(_ string, _ ...interface{}) + Debugln(_ ...interface{}) + Error(_ ...interface{}) + Errorf(_ string, _ ...interface{}) + Errorln(_ ...interface{}) + Fatal(_ ...interface{}) + Fatalf(_ string, _ ...interface{}) + Fatalln(_ ...interface{}) + Info(_ ...interface{}) + Infof(_ string, _ ...interface{}) + Infoln(_ ...interface{}) + Panic(_ ...interface{}) + Panicf(_ string, _ ...interface{}) + Panicln(_ ...interface{}) + Print(_ ...interface{}) + Printf(_ string, _ ...interface{}) + Println(_ ...interface{}) + Warn(_ ...interface{}) + Warnf(_ string, _ ...interface{}) + Warning(_ ...interface{}) + Warningf(_ string, _ ...interface{}) + Warningln(_ ...interface{}) + Warnln(_ ...interface{}) + WithError(_ error) *Entry + WithField(_ string, _ interface{}) *Entry + WithFields(_ Fields) *Entry +} + type Fields map[string]interface{} type Formatter interface { From bc784268fdeeb823dbbd4636828a43a20b1244d0 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 17 Sep 2024 11:04:23 +0100 Subject: [PATCH 078/470] Make Logrus log injection tests more comprehensive --- .../Security/CWE-117/LogInjection.go | 323 +++++++++--------- .../vendor/github.com/sirupsen/logrus/stub.go | 14 +- 2 files changed, 183 insertions(+), 154 deletions(-) diff --git a/go/ql/test/query-tests/Security/CWE-117/LogInjection.go b/go/ql/test/query-tests/Security/CWE-117/LogInjection.go index 81568be3db8..5cc9c81d449 100644 --- a/go/ql/test/query-tests/Security/CWE-117/LogInjection.go +++ b/go/ql/test/query-tests/Security/CWE-117/LogInjection.go @@ -7,7 +7,7 @@ package main //go:generate depstubber -vendor github.com/davecgh/go-spew/spew "" Dump,Errorf,Print,Printf,Println,Fdump,Fprint,Fprintf,Fprintln //go:generate depstubber -vendor github.com/elazarl/goproxy ProxyCtx "" //go:generate depstubber -vendor github.com/golang/glog Level,Verbose Info,InfoDepth,Infof,Infoln,Error,ErrorDepth,Errorf,Errorln,Fatal,FatalDepth,Fatalf,Fatalln,Exit,ExitDepth,Exitf,Exitln,V -//go:generate depstubber -vendor github.com/sirupsen/logrus FieldLogger,Fields,Entry,Logger,Level Debug,Debugf,Debugln,Error,Errorf,Errorln,Fatal,Fatalf,Fatalln,Info,Infof,Infoln,Panic,Panicf,Panicln,Print,Printf,Println,Trace,Tracef,Traceln,Warn,Warnf,Warnln,Warning,Warningf,Warningln,WithFields,WithField +//go:generate depstubber -vendor github.com/sirupsen/logrus FieldLogger,Fields,Entry,Logger,Level Debug,Debugf,Debugln,Error,Errorf,Errorln,Fatal,Fatalf,Fatalln,Info,Infof,Infoln,New,NewEntry,Panic,Panicf,Panicln,Print,Printf,Println,Trace,Tracef,Traceln,Warn,Warnf,Warnln,Warning,Warningf,Warningln,WithError,WithFields,WithField //go:generate depstubber -vendor go.uber.org/zap Logger,SugaredLogger NewProduction import ( @@ -170,163 +170,180 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) { } // sirupsen/logrus { - logrus.Debug(username) // $ hasTaintFlow="username" - logrus.Debugf(username, "") // $ hasTaintFlow="username" - logrus.Debugf("", username) // $ hasTaintFlow="username" - logrus.Debugln(username) // $ hasTaintFlow="username" - logrus.Error(username) // $ hasTaintFlow="username" - logrus.Errorf(username, "") // $ hasTaintFlow="username" - logrus.Errorf("", username) // $ hasTaintFlow="username" - logrus.Errorln(username) // $ hasTaintFlow="username" - logrus.Fatal(username) // $ hasTaintFlow="username" - logrus.Fatalf(username, "") // $ hasTaintFlow="username" - logrus.Fatalf("", username) // $ hasTaintFlow="username" - logrus.Fatalln(username) // $ hasTaintFlow="username" - logrus.Info(username) // $ hasTaintFlow="username" - logrus.Infof(username, "") // $ hasTaintFlow="username" - logrus.Infof("", username) // $ hasTaintFlow="username" - logrus.Infoln(username) // $ hasTaintFlow="username" - logrus.Panic(username) // $ hasTaintFlow="username" - logrus.Panicf(username, "") // $ hasTaintFlow="username" - logrus.Panicf("", username) // $ hasTaintFlow="username" - logrus.Panicln(username) // $ hasTaintFlow="username" - logrus.Print(username) // $ hasTaintFlow="username" - logrus.Printf(username, "") // $ hasTaintFlow="username" - logrus.Printf("", username) // $ hasTaintFlow="username" - logrus.Println(username) // $ hasTaintFlow="username" - logrus.Trace(username) // $ hasTaintFlow="username" - logrus.Tracef(username, "") // $ hasTaintFlow="username" - logrus.Tracef("", username) // $ hasTaintFlow="username" - logrus.Traceln(username) // $ hasTaintFlow="username" - logrus.Warn(username) // $ hasTaintFlow="username" - logrus.Warnf(username, "") // $ hasTaintFlow="username" - logrus.Warnf("", username) // $ hasTaintFlow="username" - logrus.Warnln(username) // $ hasTaintFlow="username" - logrus.Warning(username) // $ hasTaintFlow="username" - logrus.Warningf(username, "") // $ hasTaintFlow="username" - logrus.Warningf("", username) // $ hasTaintFlow="username" - logrus.Warningln(username) // $ hasTaintFlow="username" - + err := fmt.Errorf("error: %s", username) fields := make(logrus.Fields) fields["username"] = username - entry := logrus.WithFields(fields) // $ hasTaintFlow="fields" - entry = logrus.WithField("username", username) // $ hasTaintFlow="username" - entry.Debug(username) // $ hasTaintFlow="username" - entry.Debugf(username, "") // $ hasTaintFlow="username" - entry.Debugf("", username) // $ hasTaintFlow="username" - entry.Debugln(username) // $ hasTaintFlow="username" - entry.Error(username) // $ hasTaintFlow="username" - entry.Errorf(username, "") // $ hasTaintFlow="username" - entry.Errorf("", username) // $ hasTaintFlow="username" - entry.Errorln(username) // $ hasTaintFlow="username" - entry.Fatal(username) // $ hasTaintFlow="username" - entry.Fatalf(username, "") // $ hasTaintFlow="username" - entry.Fatalf("", username) // $ hasTaintFlow="username" - entry.Fatalln(username) // $ hasTaintFlow="username" - entry.Info(username) // $ hasTaintFlow="username" - entry.Infof(username, "") // $ hasTaintFlow="username" - entry.Infof("", username) // $ hasTaintFlow="username" - entry.Infoln(username) // $ hasTaintFlow="username" - entry.Log(0, username) // $ hasTaintFlow="username" - entry.Logf(0, username, "") // $ hasTaintFlow="username" - entry.Logf(0, "", username) // $ hasTaintFlow="username" - entry.Logln(0, username) // $ hasTaintFlow="username" - entry.Panic(username) // $ hasTaintFlow="username" - entry.Panicf(username, "") // $ hasTaintFlow="username" - entry.Panicf("", username) // $ hasTaintFlow="username" - entry.Panicln(username) // $ hasTaintFlow="username" - entry.Print(username) // $ hasTaintFlow="username" - entry.Printf(username, "") // $ hasTaintFlow="username" - entry.Printf("", username) // $ hasTaintFlow="username" - entry.Println(username) // $ hasTaintFlow="username" - entry.Trace(username) // $ hasTaintFlow="username" - entry.Tracef(username, "") // $ hasTaintFlow="username" - entry.Tracef("", username) // $ hasTaintFlow="username" - entry.Traceln(username) // $ hasTaintFlow="username" - entry.Warn(username) // $ hasTaintFlow="username" - entry.Warnf(username, "") // $ hasTaintFlow="username" - entry.Warnf("", username) // $ hasTaintFlow="username" - entry.Warnln(username) // $ hasTaintFlow="username" - entry.Warning(username) // $ hasTaintFlow="username" - entry.Warningf(username, "") // $ hasTaintFlow="username" - entry.Warningf("", username) // $ hasTaintFlow="username" - entry.Warningln(username) // $ hasTaintFlow="username" + logger := logrus.New() + entry := logrus.NewEntry(logger) - logger := entry.Logger - logger.Debug(username) // $ hasTaintFlow="username" - logger.Debugf(username, "") // $ hasTaintFlow="username" - logger.Debugf("", username) // $ hasTaintFlow="username" - logger.Debugln(username) // $ hasTaintFlow="username" - logger.Error(username) // $ hasTaintFlow="username" - logger.Errorf(username, "") // $ hasTaintFlow="username" - logger.Errorf("", username) // $ hasTaintFlow="username" - logger.Errorln(username) // $ hasTaintFlow="username" - logger.Fatal(username) // $ hasTaintFlow="username" - logger.Fatalf(username, "") // $ hasTaintFlow="username" - logger.Fatalf("", username) // $ hasTaintFlow="username" - logger.Fatalln(username) // $ hasTaintFlow="username" - logger.Info(username) // $ hasTaintFlow="username" - logger.Infof(username, "") // $ hasTaintFlow="username" - logger.Infof("", username) // $ hasTaintFlow="username" - logger.Infoln(username) // $ hasTaintFlow="username" - logger.Log(0, username) // $ hasTaintFlow="username" - logger.Logf(0, username, "") // $ hasTaintFlow="username" - logger.Logf(0, "", username) // $ hasTaintFlow="username" - logger.Logln(0, username) // $ hasTaintFlow="username" - logger.Panic(username) // $ hasTaintFlow="username" - logger.Panicf(username, "") // $ hasTaintFlow="username" - logger.Panicf("", username) // $ hasTaintFlow="username" - logger.Panicln(username) // $ hasTaintFlow="username" - logger.Print(username) // $ hasTaintFlow="username" - logger.Printf(username, "") // $ hasTaintFlow="username" - logger.Printf("", username) // $ hasTaintFlow="username" - logger.Println(username) // $ hasTaintFlow="username" - logger.Trace(username) // $ hasTaintFlow="username" - logger.Tracef(username, "") // $ hasTaintFlow="username" - logger.Tracef("", username) // $ hasTaintFlow="username" - logger.Traceln(username) // $ hasTaintFlow="username" - logger.Warn(username) // $ hasTaintFlow="username" - logger.Warnf(username, "") // $ hasTaintFlow="username" - logger.Warnf("", username) // $ hasTaintFlow="username" - logger.Warnln(username) // $ hasTaintFlow="username" - logger.Warning(username) // $ hasTaintFlow="username" - logger.Warningf(username, "") // $ hasTaintFlow="username" - logger.Warningf("", username) // $ hasTaintFlow="username" - logger.Warningln(username) // $ hasTaintFlow="username" + logrus.Debug(username) // $ hasTaintFlow="username" + logrus.Debugf(username, "") // $ hasTaintFlow="username" + logrus.Debugf("", username) // $ hasTaintFlow="username" + logrus.Debugln(username) // $ hasTaintFlow="username" + logrus.Error(username) // $ hasTaintFlow="username" + logrus.Errorf(username, "") // $ hasTaintFlow="username" + logrus.Errorf("", username) // $ hasTaintFlow="username" + logrus.Errorln(username) // $ hasTaintFlow="username" + logrus.Fatal(username) // $ hasTaintFlow="username" + logrus.Fatalf(username, "") // $ hasTaintFlow="username" + logrus.Fatalf("", username) // $ hasTaintFlow="username" + logrus.Fatalln(username) // $ hasTaintFlow="username" + logrus.Info(username) // $ hasTaintFlow="username" + logrus.Infof(username, "") // $ hasTaintFlow="username" + logrus.Infof("", username) // $ hasTaintFlow="username" + logrus.Infoln(username) // $ hasTaintFlow="username" + logrus.Panic(username) // $ hasTaintFlow="username" + logrus.Panicf(username, "") // $ hasTaintFlow="username" + logrus.Panicf("", username) // $ hasTaintFlow="username" + logrus.Panicln(username) // $ hasTaintFlow="username" + logrus.Print(username) // $ hasTaintFlow="username" + logrus.Printf(username, "") // $ hasTaintFlow="username" + logrus.Printf("", username) // $ hasTaintFlow="username" + logrus.Println(username) // $ hasTaintFlow="username" + logrus.Trace(username) // $ hasTaintFlow="username" + logrus.Tracef(username, "") // $ hasTaintFlow="username" + logrus.Tracef("", username) // $ hasTaintFlow="username" + logrus.Traceln(username) // $ hasTaintFlow="username" + logrus.Warn(username) // $ hasTaintFlow="username" + logrus.Warnf(username, "") // $ hasTaintFlow="username" + logrus.Warnf("", username) // $ hasTaintFlow="username" + logrus.Warnln(username) // $ hasTaintFlow="username" + logrus.Warning(username) // $ hasTaintFlow="username" + logrus.Warningf(username, "") // $ hasTaintFlow="username" + logrus.Warningf("", username) // $ hasTaintFlow="username" + logrus.Warningln(username) // $ hasTaintFlow="username" + logrus.WithError(err) // $ hasTaintFlow="err" + logrus.WithField(username, "") // $ hasTaintFlow="username" + logrus.WithField("", username) // $ hasTaintFlow="username" + logrus.WithFields(fields) // $ hasTaintFlow="fields" + + entry.Debug(username) // $ hasTaintFlow="username" + entry.Debugf(username, "") // $ hasTaintFlow="username" + entry.Debugf("", username) // $ hasTaintFlow="username" + entry.Debugln(username) // $ hasTaintFlow="username" + entry.Error(username) // $ hasTaintFlow="username" + entry.Errorf(username, "") // $ hasTaintFlow="username" + entry.Errorf("", username) // $ hasTaintFlow="username" + entry.Errorln(username) // $ hasTaintFlow="username" + entry.Fatal(username) // $ hasTaintFlow="username" + entry.Fatalf(username, "") // $ hasTaintFlow="username" + entry.Fatalf("", username) // $ hasTaintFlow="username" + entry.Fatalln(username) // $ hasTaintFlow="username" + entry.Info(username) // $ hasTaintFlow="username" + entry.Infof(username, "") // $ hasTaintFlow="username" + entry.Infof("", username) // $ hasTaintFlow="username" + entry.Infoln(username) // $ hasTaintFlow="username" + entry.Log(0, username) // $ hasTaintFlow="username" + entry.Logf(0, username, "") // $ hasTaintFlow="username" + entry.Logf(0, "", username) // $ hasTaintFlow="username" + entry.Logln(0, username) // $ hasTaintFlow="username" + entry.Panic(username) // $ hasTaintFlow="username" + entry.Panicf(username, "") // $ hasTaintFlow="username" + entry.Panicf("", username) // $ hasTaintFlow="username" + entry.Panicln(username) // $ hasTaintFlow="username" + entry.Print(username) // $ hasTaintFlow="username" + entry.Printf(username, "") // $ hasTaintFlow="username" + entry.Printf("", username) // $ hasTaintFlow="username" + entry.Println(username) // $ hasTaintFlow="username" + entry.Trace(username) // $ hasTaintFlow="username" + entry.Tracef(username, "") // $ hasTaintFlow="username" + entry.Tracef("", username) // $ hasTaintFlow="username" + entry.Traceln(username) // $ hasTaintFlow="username" + entry.Warn(username) // $ hasTaintFlow="username" + entry.Warnf(username, "") // $ hasTaintFlow="username" + entry.Warnf("", username) // $ hasTaintFlow="username" + entry.Warnln(username) // $ hasTaintFlow="username" + entry.Warning(username) // $ hasTaintFlow="username" + entry.Warningf(username, "") // $ hasTaintFlow="username" + entry.Warningf("", username) // $ hasTaintFlow="username" + entry.Warningln(username) // $ hasTaintFlow="username" + entry.WithError(err) // $ hasTaintFlow="err" + entry.WithField(username, "") // $ hasTaintFlow="username" + entry.WithField("", username) // $ hasTaintFlow="username" + entry.WithFields(fields) // $ hasTaintFlow="fields" + + logger.Debug(username) // $ hasTaintFlow="username" + logger.Debugf(username, "") // $ hasTaintFlow="username" + logger.Debugf("", username) // $ hasTaintFlow="username" + logger.Debugln(username) // $ hasTaintFlow="username" + logger.Error(username) // $ hasTaintFlow="username" + logger.Errorf(username, "") // $ hasTaintFlow="username" + logger.Errorf("", username) // $ hasTaintFlow="username" + logger.Errorln(username) // $ hasTaintFlow="username" + logger.Fatal(username) // $ hasTaintFlow="username" + logger.Fatalf(username, "") // $ hasTaintFlow="username" + logger.Fatalf("", username) // $ hasTaintFlow="username" + logger.Fatalln(username) // $ hasTaintFlow="username" + logger.Info(username) // $ hasTaintFlow="username" + logger.Infof(username, "") // $ hasTaintFlow="username" + logger.Infof("", username) // $ hasTaintFlow="username" + logger.Infoln(username) // $ hasTaintFlow="username" + logger.Log(0, username) // $ hasTaintFlow="username" + logger.Logf(0, username, "") // $ hasTaintFlow="username" + logger.Logf(0, "", username) // $ hasTaintFlow="username" + logger.Logln(0, username) // $ hasTaintFlow="username" + logger.Panic(username) // $ hasTaintFlow="username" + logger.Panicf(username, "") // $ hasTaintFlow="username" + logger.Panicf("", username) // $ hasTaintFlow="username" + logger.Panicln(username) // $ hasTaintFlow="username" + logger.Print(username) // $ hasTaintFlow="username" + logger.Printf(username, "") // $ hasTaintFlow="username" + logger.Printf("", username) // $ hasTaintFlow="username" + logger.Println(username) // $ hasTaintFlow="username" + logger.Trace(username) // $ hasTaintFlow="username" + logger.Tracef(username, "") // $ hasTaintFlow="username" + logger.Tracef("", username) // $ hasTaintFlow="username" + logger.Traceln(username) // $ hasTaintFlow="username" + logger.Warn(username) // $ hasTaintFlow="username" + logger.Warnf(username, "") // $ hasTaintFlow="username" + logger.Warnf("", username) // $ hasTaintFlow="username" + logger.Warnln(username) // $ hasTaintFlow="username" + logger.Warning(username) // $ hasTaintFlow="username" + logger.Warningf(username, "") // $ hasTaintFlow="username" + logger.Warningf("", username) // $ hasTaintFlow="username" + logger.Warningln(username) // $ hasTaintFlow="username" + logger.WithError(err) // $ hasTaintFlow="err" + logger.WithField(username, "") // $ hasTaintFlow="username" + logger.WithField("", username) // $ hasTaintFlow="username" + logger.WithFields(fields) // $ hasTaintFlow="fields" var fieldlogger logrus.FieldLogger = entry - fieldlogger.Debug(username) // $ hasTaintFlow="username" - fieldlogger.Debugf(username, "") // $ hasTaintFlow="username" - fieldlogger.Debugf("", username) // $ hasTaintFlow="username" - fieldlogger.Debugln(username) // $ hasTaintFlow="username" - fieldlogger.Error(username) // $ hasTaintFlow="username" - fieldlogger.Errorf(username, "") // $ hasTaintFlow="username" - fieldlogger.Errorf("", username) // $ hasTaintFlow="username" - fieldlogger.Errorln(username) // $ hasTaintFlow="username" - fieldlogger.Fatal(username) // $ hasTaintFlow="username" - fieldlogger.Fatalf(username, "") // $ hasTaintFlow="username" - fieldlogger.Fatalf("", username) // $ hasTaintFlow="username" - fieldlogger.Fatalln(username) // $ hasTaintFlow="username" - fieldlogger.Info(username) // $ hasTaintFlow="username" - fieldlogger.Infof(username, "") // $ hasTaintFlow="username" - fieldlogger.Infof("", username) // $ hasTaintFlow="username" - fieldlogger.Infoln(username) // $ hasTaintFlow="username" - fieldlogger.Panic(username) // $ hasTaintFlow="username" - fieldlogger.Panicf(username, "") // $ hasTaintFlow="username" - fieldlogger.Panicf("", username) // $ hasTaintFlow="username" - fieldlogger.Panicln(username) // $ hasTaintFlow="username" - fieldlogger.Print(username) // $ hasTaintFlow="username" - fieldlogger.Printf(username, "") // $ hasTaintFlow="username" - fieldlogger.Printf("", username) // $ hasTaintFlow="username" - fieldlogger.Println(username) // $ hasTaintFlow="username" - fieldlogger.Warn(username) // $ hasTaintFlow="username" - fieldlogger.Warnf(username, "") // $ hasTaintFlow="username" - fieldlogger.Warnf("", username) // $ hasTaintFlow="username" - fieldlogger.Warnln(username) // $ hasTaintFlow="username" - fieldlogger.Warning(username) // $ hasTaintFlow="username" - fieldlogger.Warningf(username, "") // $ hasTaintFlow="username" - fieldlogger.Warningf("", username) // $ hasTaintFlow="username" - fieldlogger.Warningln(username) // $ hasTaintFlow="username" + fieldlogger.Debug(username) // $ hasTaintFlow="username" + fieldlogger.Debugf(username, "") // $ hasTaintFlow="username" + fieldlogger.Debugf("", username) // $ hasTaintFlow="username" + fieldlogger.Debugln(username) // $ hasTaintFlow="username" + fieldlogger.Error(username) // $ hasTaintFlow="username" + fieldlogger.Errorf(username, "") // $ hasTaintFlow="username" + fieldlogger.Errorf("", username) // $ hasTaintFlow="username" + fieldlogger.Errorln(username) // $ hasTaintFlow="username" + fieldlogger.Fatal(username) // $ hasTaintFlow="username" + fieldlogger.Fatalf(username, "") // $ hasTaintFlow="username" + fieldlogger.Fatalf("", username) // $ hasTaintFlow="username" + fieldlogger.Fatalln(username) // $ hasTaintFlow="username" + fieldlogger.Info(username) // $ hasTaintFlow="username" + fieldlogger.Infof(username, "") // $ hasTaintFlow="username" + fieldlogger.Infof("", username) // $ hasTaintFlow="username" + fieldlogger.Infoln(username) // $ hasTaintFlow="username" + fieldlogger.Panic(username) // $ hasTaintFlow="username" + fieldlogger.Panicf(username, "") // $ hasTaintFlow="username" + fieldlogger.Panicf("", username) // $ hasTaintFlow="username" + fieldlogger.Panicln(username) // $ hasTaintFlow="username" + fieldlogger.Print(username) // $ hasTaintFlow="username" + fieldlogger.Printf(username, "") // $ hasTaintFlow="username" + fieldlogger.Printf("", username) // $ hasTaintFlow="username" + fieldlogger.Println(username) // $ hasTaintFlow="username" + fieldlogger.Warn(username) // $ hasTaintFlow="username" + fieldlogger.Warnf(username, "") // $ hasTaintFlow="username" + fieldlogger.Warnf("", username) // $ hasTaintFlow="username" + fieldlogger.Warnln(username) // $ hasTaintFlow="username" + fieldlogger.Warning(username) // $ hasTaintFlow="username" + fieldlogger.Warningf(username, "") // $ hasTaintFlow="username" + fieldlogger.Warningf("", username) // $ hasTaintFlow="username" + fieldlogger.Warningln(username) // $ hasTaintFlow="username" + fieldlogger.WithError(err) // $ hasTaintFlow="err" + fieldlogger.WithField(username, "") // $ hasTaintFlow="username" + fieldlogger.WithField("", username) // $ hasTaintFlow="username" + fieldlogger.WithFields(fields) // $ hasTaintFlow="fields" } // davecgh/go-spew/spew { diff --git a/go/ql/test/query-tests/Security/CWE-117/vendor/github.com/sirupsen/logrus/stub.go b/go/ql/test/query-tests/Security/CWE-117/vendor/github.com/sirupsen/logrus/stub.go index 61294748ea4..497d85559bb 100644 --- a/go/ql/test/query-tests/Security/CWE-117/vendor/github.com/sirupsen/logrus/stub.go +++ b/go/ql/test/query-tests/Security/CWE-117/vendor/github.com/sirupsen/logrus/stub.go @@ -2,7 +2,7 @@ // This is a simple stub for github.com/sirupsen/logrus, strictly for use in testing. // See the LICENSE file for information about the licensing of the original library. -// Source: github.com/sirupsen/logrus (exports: FieldLogger,Fields,Entry,Logger,Level; functions: Debug,Debugf,Debugln,Error,Errorf,Errorln,Fatal,Fatalf,Fatalln,Info,Infof,Infoln,Panic,Panicf,Panicln,Print,Printf,Println,Trace,Tracef,Traceln,Warn,Warnf,Warnln,Warning,Warningf,Warningln,WithFields,WithField) +// Source: github.com/sirupsen/logrus (exports: FieldLogger,Fields,Entry,Logger,Level; functions: Debug,Debugf,Debugln,Error,Errorf,Errorln,Fatal,Fatalf,Fatalln,Info,Infof,Infoln,New,NewEntry,Panic,Panicf,Panicln,Print,Printf,Println,Trace,Tracef,Traceln,Warn,Warnf,Warnln,Warning,Warningf,Warningln,WithError,WithFields,WithField) // Package logrus is a stub of github.com/sirupsen/logrus, generated by depstubber. package logrus @@ -362,6 +362,14 @@ func (_ *Logger) WriterLevel(_ Level) *io.PipeWriter { return nil } +func New() *Logger { + return nil +} + +func NewEntry(_ *Logger) *Entry { + return nil +} + func Panic(_ ...interface{}) {} func Panicf(_ string, _ ...interface{}) {} @@ -392,6 +400,10 @@ func Warningln(_ ...interface{}) {} func Warnln(_ ...interface{}) {} +func WithError(_ error) *Entry { + return nil +} + func WithField(_ string, _ interface{}) *Entry { return nil } From 81907bc743581165bb29ec175fc9468714add8db Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 18 Sep 2024 12:07:18 +0100 Subject: [PATCH 079/470] Set Subtypes column correctly We set it to False when it has no meaning and True otherwise. --- go/ql/lib/ext/database.sql.driver.model.yml | 12 +- go/ql/lib/ext/database.sql.model.yml | 48 ++-- ...ithub.com.beego.beego.client.orm.model.yml | 60 ++--- ...github.com.beego.beego.core.logs.model.yml | 22 +- .../ext/github.com.elazarl.goproxy.model.yml | 4 +- .../lib/ext/github.com.golang.glog.model.yml | 90 ++++---- .../github.com.mastermind.squirrel.model.yml | 10 +- .../ext/github.com.sirupsen.logrus.model.yml | 210 +++++++++--------- .../lib/ext/github.com.uptrace.bun.model.yml | 2 +- go/ql/lib/ext/go.uber.org.zap.model.yml | 66 +++--- go/ql/lib/ext/log.model.yml | 20 +- 11 files changed, 272 insertions(+), 272 deletions(-) diff --git a/go/ql/lib/ext/database.sql.driver.model.yml b/go/ql/lib/ext/database.sql.driver.model.yml index 50b699e4371..10cfba9388a 100644 --- a/go/ql/lib/ext/database.sql.driver.model.yml +++ b/go/ql/lib/ext/database.sql.driver.model.yml @@ -3,12 +3,12 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["database/sql/driver", "Execer", False, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql/driver", "ExecerContext", False, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["database/sql/driver", "Conn", False, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql/driver", "ConnPrepareContext", False, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["database/sql/driver", "Queryer", False, "Query", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql/driver", "QueryerContext", False, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql/driver", "Execer", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql/driver", "ExecerContext", True, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql/driver", "Conn", True, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql/driver", "ConnPrepareContext", True, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql/driver", "Queryer", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql/driver", "QueryerContext", True, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/ext/database.sql.model.yml b/go/ql/lib/ext/database.sql.model.yml index b8fb85bb893..5854ced527d 100644 --- a/go/ql/lib/ext/database.sql.model.yml +++ b/go/ql/lib/ext/database.sql.model.yml @@ -3,30 +3,30 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["database/sql", "Conn", False, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql", "Conn", False, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["database/sql", "Conn", False, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql", "Conn", False, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["database/sql", "Conn", False, "Query", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql", "Conn", False, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["database/sql", "Conn", False, "QueryRow", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql", "Conn", False, "QueryRowContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["database/sql", "DB", False, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql", "DB", False, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["database/sql", "DB", False, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql", "DB", False, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["database/sql", "DB", False, "Query", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql", "DB", False, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["database/sql", "DB", False, "QueryRow", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql", "DB", False, "QueryRowContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["database/sql", "Tx", False, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql", "Tx", False, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["database/sql", "Tx", False, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql", "Tx", False, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["database/sql", "Tx", False, "Query", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql", "Tx", False, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["database/sql", "Tx", False, "QueryRow", "", "", "Argument[0]", "sql-injection", "manual"] - - ["database/sql", "Tx", False, "QueryRowContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Conn", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Conn", True, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Conn", True, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Conn", True, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Conn", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Conn", True, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Conn", True, "QueryRow", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Conn", True, "QueryRowContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "DB", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "DB", True, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "DB", True, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "DB", True, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "DB", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "DB", True, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "DB", True, "QueryRow", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "DB", True, "QueryRowContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Tx", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Tx", True, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Tx", True, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Tx", True, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Tx", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Tx", True, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["database/sql", "Tx", True, "QueryRow", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "Tx", True, "QueryRowContext", "", "", "Argument[1]", "sql-injection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/ext/github.com.beego.beego.client.orm.model.yml b/go/ql/lib/ext/github.com.beego.beego.client.orm.model.yml index 9e8849423eb..08c0572b894 100644 --- a/go/ql/lib/ext/github.com.beego.beego.client.orm.model.yml +++ b/go/ql/lib/ext/github.com.beego.beego.client.orm.model.yml @@ -10,33 +10,33 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["group:beego-orm", "Condition", False, "Raw", "", "", "Argument[1]", "sql-injection", "manual"] - - ["group:beego-orm", "DB", False, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "DB", False, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["group:beego-orm", "DB", False, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "DB", False, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["group:beego-orm", "DB", False, "Query", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "DB", False, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["group:beego-orm", "DB", False, "QueryRow", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "DB", False, "QueryRowContext", "", "", "Argument[1]", "sql-injection", "manual"] - - ["group:beego-orm", "Ormer", False, "Raw", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "And", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "Delete", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "From", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "GroupBy", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "Having", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "In", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "InnerJoin", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "InsertInto", "", "", "Argument[0..1]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "LeftJoin", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "On", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "Or", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "RightJoin", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "Select", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "Set", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "Subquery", "", "", "Argument[0..1]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "Update", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "Values", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QueryBuilder", False, "Where", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:beego-orm", "QuerySeter", False, "FilterRaw", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:beego-orm", "Condition", True, "Raw", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", True, "ExecContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", True, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", True, "PrepareContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", True, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", True, "QueryRow", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "DB", True, "QueryRowContext", "", "", "Argument[1]", "sql-injection", "manual"] + - ["group:beego-orm", "Ormer", True, "Raw", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "And", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "Delete", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "From", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "GroupBy", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "Having", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "In", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "InnerJoin", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "InsertInto", "", "", "Argument[0..1]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "LeftJoin", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "On", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "Or", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "RightJoin", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "Select", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "Set", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "Subquery", "", "", "Argument[0..1]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "Update", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "Values", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QueryBuilder", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:beego-orm", "QuerySeter", True, "FilterRaw", "", "", "Argument[1]", "sql-injection", "manual"] diff --git a/go/ql/lib/ext/github.com.beego.beego.core.logs.model.yml b/go/ql/lib/ext/github.com.beego.beego.core.logs.model.yml index 3dfbbe89719..b55c3be507d 100644 --- a/go/ql/lib/ext/github.com.beego.beego.core.logs.model.yml +++ b/go/ql/lib/ext/github.com.beego.beego.core.logs.model.yml @@ -21,14 +21,14 @@ extensions: - ["group:beego-logs", "", False, "Trace", "", "", "Argument[0..1]", "log-injection", "manual"] - ["group:beego-logs", "", False, "Warn", "", "", "Argument[0..1]", "log-injection", "manual"] - ["group:beego-logs", "", False, "Warning", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:beego-logs", "BeeLogger", False, "Alert", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:beego-logs", "BeeLogger", False, "Critical", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:beego-logs", "BeeLogger", False, "Debug", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:beego-logs", "BeeLogger", False, "Emergency", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:beego-logs", "BeeLogger", False, "Error", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:beego-logs", "BeeLogger", False, "Info", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:beego-logs", "BeeLogger", False, "Informational", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:beego-logs", "BeeLogger", False, "Notice", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:beego-logs", "BeeLogger", False, "Trace", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:beego-logs", "BeeLogger", False, "Warn", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:beego-logs", "BeeLogger", False, "Warning", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", True, "Alert", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", True, "Critical", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", True, "Debug", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", True, "Emergency", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", True, "Error", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", True, "Info", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", True, "Informational", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", True, "Notice", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", True, "Trace", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", True, "Warn", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:beego-logs", "BeeLogger", True, "Warning", "", "", "Argument[0..1]", "log-injection", "manual"] diff --git a/go/ql/lib/ext/github.com.elazarl.goproxy.model.yml b/go/ql/lib/ext/github.com.elazarl.goproxy.model.yml index 01a61d2c3ac..9dc8284ea58 100644 --- a/go/ql/lib/ext/github.com.elazarl.goproxy.model.yml +++ b/go/ql/lib/ext/github.com.elazarl.goproxy.model.yml @@ -3,8 +3,8 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/elazarl/goproxy", "ProxyCtx", False, "Logf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["github.com/elazarl/goproxy", "ProxyCtx", False, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["github.com/elazarl/goproxy", "ProxyCtx", True, "Logf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["github.com/elazarl/goproxy", "ProxyCtx", True, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/ext/github.com.golang.glog.model.yml b/go/ql/lib/ext/github.com.golang.glog.model.yml index dd36e6a7d8f..275450f2c44 100644 --- a/go/ql/lib/ext/github.com.golang.glog.model.yml +++ b/go/ql/lib/ext/github.com.golang.glog.model.yml @@ -55,48 +55,48 @@ extensions: - ["group:glog", "", False, "WarningDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] - ["group:glog", "", False, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] - ["group:glog", "", False, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Error", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "ErrorContext", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "ErrorContextDepth", "", "", "Argument[2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "ErrorContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "ErrorContextf", "", "", "Argument[1..2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "ErrorDepth", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "ErrorDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Errorln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Exit", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "ExitContext", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "ExitContextDepth", "", "", "Argument[2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "ExitContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "ExitContextf", "", "", "Argument[1..2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "ExitDepth", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "ExitDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Exitf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Exitln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "FatalContext", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "FatalContextDepth", "", "", "Argument[2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "FatalContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "FatalContextf", "", "", "Argument[1..2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "FatalDepth", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "FatalDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Info", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "InfoContext", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "InfoContextDepth", "", "", "Argument[2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "InfoContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "InfoContextf", "", "", "Argument[1..2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "InfoDepth", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "InfoDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Infoln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Warning", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "WarningContext", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "WarningContextDepth", "", "", "Argument[2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "WarningContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "WarningContextf", "", "", "Argument[1..2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "WarningDepth", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "WarningDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:glog", "Verbose", False, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Error", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "ErrorContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "ErrorContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "ErrorContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "ErrorContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "ErrorDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "ErrorDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Errorln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Exit", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "ExitContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "ExitContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "ExitContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "ExitContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "ExitDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "ExitDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Exitf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Exitln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "FatalContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "FatalContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "FatalContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "FatalContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "FatalDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "FatalDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Info", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "InfoContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "InfoContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "InfoContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "InfoContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "InfoDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "InfoDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Infoln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Warning", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "WarningContext", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "WarningContextDepth", "", "", "Argument[2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "WarningContextDepthf", "", "", "Argument[2..3]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "WarningContextf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "WarningDepth", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "WarningDepthf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:glog", "Verbose", True, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] diff --git a/go/ql/lib/ext/github.com.mastermind.squirrel.model.yml b/go/ql/lib/ext/github.com.mastermind.squirrel.model.yml index dc476abd057..6f3c5830e45 100644 --- a/go/ql/lib/ext/github.com.mastermind.squirrel.model.yml +++ b/go/ql/lib/ext/github.com.mastermind.squirrel.model.yml @@ -10,11 +10,11 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["group:squirrel", "", True, "Delete", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:squirrel", "", True, "Expr", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:squirrel", "", True, "Insert", "", "", "Argument[0]", "sql-injection", "manual"] - - ["group:squirrel", "", True, "Select", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement - - ["group:squirrel", "", True, "Update", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement + - ["group:squirrel", "", False, "Delete", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "", False, "Expr", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "", False, "Insert", "", "", "Argument[0]", "sql-injection", "manual"] + - ["group:squirrel", "", False, "Select", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement + - ["group:squirrel", "", False, "Update", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement - ["group:squirrel", "DeleteBuilder", True, "From", "", "", "Argument[0]", "sql-injection", "manual"] - ["group:squirrel", "DeleteBuilder", True, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement diff --git a/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml b/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml index b3ef5ea1d10..06f9a54622b 100644 --- a/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml +++ b/go/ql/lib/ext/github.com.sirupsen.logrus.model.yml @@ -50,110 +50,110 @@ extensions: - ["group:logrus", "", False, "WithFields", "", "", "Argument[0]", "log-injection", "manual"] - ["group:logrus", "", False, "WithTime", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Debug", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Debugf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Debugln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Error", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Errorln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Info", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Infoln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Log", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Logf", "", "", "Argument[1..2]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Logln", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Panic", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Panicln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Print", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Println", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Trace", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Tracef", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Traceln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Warn", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Warnln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Warning", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "WithError", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "WithField", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "WithFields", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Entry", False, "WithTime", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Debug", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Debugf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Debugln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Error", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Errorln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Info", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Infoln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Log", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Logf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Logln", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Panic", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Panicln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Print", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Println", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Trace", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Tracef", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Traceln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Warn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Warnln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Warning", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "WithError", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "WithField", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "WithFields", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Entry", True, "WithTime", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Debug", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Debugf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Debugln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Error", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Errorln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Info", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Infoln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Panic", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Panicln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Print", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Println", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Warn", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Warnln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Warning", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "WithError", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "WithField", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "FieldLogger", False, "WithFields", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Debug", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Debugf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Debugln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Error", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Errorln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Info", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Infoln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Panic", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Panicln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Print", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Println", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Warn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Warnln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Warning", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "WithError", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "WithField", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "FieldLogger", True, "WithFields", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Debug", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "DebugFn", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Debugf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Debugln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Error", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "ErrorFn", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Errorln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "FatalFn", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Info", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "InfoFn", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Infoln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Log", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "LogFn", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Logf", "", "", "Argument[1..2]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Logln", "", "", "Argument[1]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Panic", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "PanicFn", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Panicln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Print", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "PrintFn", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Println", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Trace", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "TraceFn", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Tracef", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Traceln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Warn", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "WarnFn", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Warnln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Warning", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "WarningFn", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "WithError", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "WithField", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "WithFields", "", "", "Argument[0]", "log-injection", "manual"] - - ["group:logrus", "Logger", False, "WithTime", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Debug", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "DebugFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Debugf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Debugln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Error", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "ErrorFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Errorln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "FatalFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Info", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "InfoFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Infoln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Log", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "LogFn", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Logf", "", "", "Argument[1..2]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Logln", "", "", "Argument[1]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Panic", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "PanicFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Panicln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Print", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "PrintFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Println", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Trace", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "TraceFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Tracef", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Traceln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Warn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "WarnFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Warnln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Warning", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "WarningFn", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Warningf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "Warningln", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "WithError", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "WithField", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "WithFields", "", "", "Argument[0]", "log-injection", "manual"] + - ["group:logrus", "Logger", True, "WithTime", "", "", "Argument[0]", "log-injection", "manual"] diff --git a/go/ql/lib/ext/github.com.uptrace.bun.model.yml b/go/ql/lib/ext/github.com.uptrace.bun.model.yml index eb060b4f9cc..a08adb07973 100644 --- a/go/ql/lib/ext/github.com.uptrace.bun.model.yml +++ b/go/ql/lib/ext/github.com.uptrace.bun.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/uptrace/bun", "", True, "NewRawQuery", "", "", "Argument[1]", "sql-injection", "manual"] + - ["github.com/uptrace/bun", "", False, "NewRawQuery", "", "", "Argument[1]", "sql-injection", "manual"] - ["github.com/uptrace/bun", "AddColumnQuery", True, "ColumnExpr", "", "", "Argument[0]", "sql-injection", "manual"] - ["github.com/uptrace/bun", "AddColumnQuery", True, "ModelTableExpr", "", "", "Argument[0]", "sql-injection", "manual"] - ["github.com/uptrace/bun", "AddColumnQuery", True, "TableExpr", "", "", "Argument[0]", "sql-injection", "manual"] diff --git a/go/ql/lib/ext/go.uber.org.zap.model.yml b/go/ql/lib/ext/go.uber.org.zap.model.yml index c4e43356f26..e9fc971e5fa 100644 --- a/go/ql/lib/ext/go.uber.org.zap.model.yml +++ b/go/ql/lib/ext/go.uber.org.zap.model.yml @@ -3,39 +3,39 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["go.uber.org/zap", "Logger", False, "DPanic", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "Logger", False, "Debug", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "Logger", False, "Error", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "Logger", False, "Fatal", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "Logger", False, "Info", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "Logger", False, "Named", "", "", "Argument[0]", "log-injection", "manual"] - - ["go.uber.org/zap", "Logger", False, "Panic", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "Logger", False, "Warn", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "Logger", False, "With", "", "", "Argument[0]", "log-injection", "manual"] - - ["go.uber.org/zap", "Logger", False, "WithOptions", "", "", "Argument[0]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "DPanic", "", "", "Argument[0]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "DPanicf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "DPanicw", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Debug", "", "", "Argument[0]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Debugf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Debugw", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Error", "", "", "Argument[0]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Errorw", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Fatalw", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Info", "", "", "Argument[0]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Infow", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Named", "", "", "Argument[0]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Panic", "", "", "Argument[0]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Panicw", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Warn", "", "", "Argument[0]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "Warnw", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["go.uber.org/zap", "SugaredLogger", False, "With", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", True, "DPanic", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", True, "Debug", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", True, "Error", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", True, "Fatal", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", True, "Info", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", True, "Named", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", True, "Panic", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", True, "Warn", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", True, "With", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "Logger", True, "WithOptions", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "DPanic", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "DPanicf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "DPanicw", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Debug", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Debugf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Debugw", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Error", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Errorf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Errorw", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Fatalw", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Info", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Infof", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Infow", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Named", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Panic", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Panicw", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Warn", "", "", "Argument[0]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Warnf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "Warnw", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["go.uber.org/zap", "SugaredLogger", True, "With", "", "", "Argument[0]", "log-injection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/ext/log.model.yml b/go/ql/lib/ext/log.model.yml index 1ebce079a52..4d1df7cf082 100644 --- a/go/ql/lib/ext/log.model.yml +++ b/go/ql/lib/ext/log.model.yml @@ -13,16 +13,16 @@ extensions: - ["log", "", False, "Print", "", "", "Argument[0]", "log-injection", "manual"] - ["log", "", False, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] - ["log", "", False, "Println", "", "", "Argument[0]", "log-injection", "manual"] - - ["log", "Logger", False, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] - - ["log", "Logger", False, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["log", "Logger", False, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] - - ["log", "Logger", False, "Output", "", "", "Argument[1]", "log-injection", "manual"] - - ["log", "Logger", False, "Panic", "", "", "Argument[0]", "log-injection", "manual"] - - ["log", "Logger", False, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["log", "Logger", False, "Panicln", "", "", "Argument[0]", "log-injection", "manual"] - - ["log", "Logger", False, "Print", "", "", "Argument[0]", "log-injection", "manual"] - - ["log", "Logger", False, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] - - ["log", "Logger", False, "Println", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "Logger", True, "Fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "Logger", True, "Fatalf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["log", "Logger", True, "Fatalln", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "Logger", True, "Output", "", "", "Argument[1]", "log-injection", "manual"] + - ["log", "Logger", True, "Panic", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "Logger", True, "Panicf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["log", "Logger", True, "Panicln", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "Logger", True, "Print", "", "", "Argument[0]", "log-injection", "manual"] + - ["log", "Logger", True, "Printf", "", "", "Argument[0..1]", "log-injection", "manual"] + - ["log", "Logger", True, "Println", "", "", "Argument[0]", "log-injection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel From 874dc83f3fdf6b8f48141a96cbb00635f481679e Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 19 Sep 2024 10:34:33 +0100 Subject: [PATCH 080/470] Update test expectations --- .../frameworks/BeegoOrm/SqlInjection.expected | 86 +++++++++---------- .../frameworks/XNetHtml/SqlInjection.expected | 2 +- .../Security/CWE-089/SqlInjection.expected | 4 +- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.expected b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.expected index 992c1387103..1198f8d41a9 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.expected @@ -32,60 +32,60 @@ | test.go:59:31:59:39 | untrusted | test.go:57:15:57:41 | call to UserAgent | test.go:59:31:59:39 | untrusted | This query depends on a $@. | test.go:57:15:57:41 | call to UserAgent | user-provided value | | test.go:65:19:65:27 | untrusted | test.go:63:15:63:41 | call to UserAgent | test.go:65:19:65:27 | untrusted | This query depends on a $@. | test.go:63:15:63:41 | call to UserAgent | user-provided value | edges -| test.go:11:15:11:41 | call to UserAgent | test.go:13:11:13:19 | untrusted | provenance | Src:MaD:22 Sink:MaD:2 | -| test.go:11:15:11:41 | call to UserAgent | test.go:14:23:14:31 | untrusted | provenance | Src:MaD:22 Sink:MaD:3 | -| test.go:11:15:11:41 | call to UserAgent | test.go:15:14:15:22 | untrusted | provenance | Src:MaD:22 Sink:MaD:4 | -| test.go:11:15:11:41 | call to UserAgent | test.go:16:26:16:34 | untrusted | provenance | Src:MaD:22 Sink:MaD:5 | -| test.go:11:15:11:41 | call to UserAgent | test.go:17:12:17:20 | untrusted | provenance | Src:MaD:22 Sink:MaD:6 | -| test.go:11:15:11:41 | call to UserAgent | test.go:18:24:18:32 | untrusted | provenance | Src:MaD:22 Sink:MaD:7 | -| test.go:11:15:11:41 | call to UserAgent | test.go:19:15:19:23 | untrusted | provenance | Src:MaD:22 Sink:MaD:8 | -| test.go:11:15:11:41 | call to UserAgent | test.go:20:27:20:35 | untrusted | provenance | Src:MaD:22 Sink:MaD:9 | +| test.go:11:15:11:41 | call to UserAgent | test.go:13:11:13:19 | untrusted | provenance | Src:MaD:22 Sink:MaD:2 | +| test.go:11:15:11:41 | call to UserAgent | test.go:14:23:14:31 | untrusted | provenance | Src:MaD:22 Sink:MaD:3 | +| test.go:11:15:11:41 | call to UserAgent | test.go:15:14:15:22 | untrusted | provenance | Src:MaD:22 Sink:MaD:4 | +| test.go:11:15:11:41 | call to UserAgent | test.go:16:26:16:34 | untrusted | provenance | Src:MaD:22 Sink:MaD:5 | +| test.go:11:15:11:41 | call to UserAgent | test.go:17:12:17:20 | untrusted | provenance | Src:MaD:22 Sink:MaD:6 | +| test.go:11:15:11:41 | call to UserAgent | test.go:18:24:18:32 | untrusted | provenance | Src:MaD:22 Sink:MaD:7 | +| test.go:11:15:11:41 | call to UserAgent | test.go:19:15:19:23 | untrusted | provenance | Src:MaD:22 Sink:MaD:8 | +| test.go:11:15:11:41 | call to UserAgent | test.go:20:27:20:35 | untrusted | provenance | Src:MaD:22 Sink:MaD:9 | | test.go:25:15:25:41 | call to UserAgent | test.go:28:12:28:20 | untrusted | provenance | Src:MaD:22 | | test.go:25:15:25:41 | call to UserAgent | test.go:29:10:29:18 | untrusted | provenance | Src:MaD:22 | -| test.go:25:15:25:41 | call to UserAgent | test.go:30:15:30:23 | untrusted | provenance | Src:MaD:22 Sink:MaD:13 | -| test.go:25:15:25:41 | call to UserAgent | test.go:31:14:31:22 | untrusted | provenance | Src:MaD:22 Sink:MaD:15 | -| test.go:25:15:25:41 | call to UserAgent | test.go:32:15:32:23 | untrusted | provenance | Src:MaD:22 Sink:MaD:18 | -| test.go:25:15:25:41 | call to UserAgent | test.go:33:8:33:16 | untrusted | provenance | Src:MaD:22 Sink:MaD:16 | -| test.go:25:15:25:41 | call to UserAgent | test.go:34:11:34:19 | untrusted | provenance | Src:MaD:22 Sink:MaD:20 | -| test.go:25:15:25:41 | call to UserAgent | test.go:35:9:35:17 | untrusted | provenance | Src:MaD:22 Sink:MaD:11 | -| test.go:25:15:25:41 | call to UserAgent | test.go:36:8:36:16 | untrusted | provenance | Src:MaD:22 Sink:MaD:17 | +| test.go:25:15:25:41 | call to UserAgent | test.go:30:15:30:23 | untrusted | provenance | Src:MaD:22 Sink:MaD:13 | +| test.go:25:15:25:41 | call to UserAgent | test.go:31:14:31:22 | untrusted | provenance | Src:MaD:22 Sink:MaD:15 | +| test.go:25:15:25:41 | call to UserAgent | test.go:32:15:32:23 | untrusted | provenance | Src:MaD:22 Sink:MaD:18 | +| test.go:25:15:25:41 | call to UserAgent | test.go:33:8:33:16 | untrusted | provenance | Src:MaD:22 Sink:MaD:16 | +| test.go:25:15:25:41 | call to UserAgent | test.go:34:11:34:19 | untrusted | provenance | Src:MaD:22 Sink:MaD:20 | +| test.go:25:15:25:41 | call to UserAgent | test.go:35:9:35:17 | untrusted | provenance | Src:MaD:22 Sink:MaD:11 | +| test.go:25:15:25:41 | call to UserAgent | test.go:36:8:36:16 | untrusted | provenance | Src:MaD:22 Sink:MaD:17 | | test.go:25:15:25:41 | call to UserAgent | test.go:37:8:37:16 | untrusted | provenance | Src:MaD:22 | | test.go:25:15:25:41 | call to UserAgent | test.go:38:13:38:21 | untrusted | provenance | Src:MaD:22 | | test.go:25:15:25:41 | call to UserAgent | test.go:39:13:39:21 | untrusted | provenance | Src:MaD:22 | -| test.go:25:15:25:41 | call to UserAgent | test.go:40:12:40:20 | untrusted | provenance | Src:MaD:22 Sink:MaD:12 | +| test.go:25:15:25:41 | call to UserAgent | test.go:40:12:40:20 | untrusted | provenance | Src:MaD:22 Sink:MaD:12 | | test.go:25:15:25:41 | call to UserAgent | test.go:41:12:41:20 | untrusted | provenance | Src:MaD:22 | | test.go:25:15:25:41 | call to UserAgent | test.go:42:9:42:17 | untrusted | provenance | Src:MaD:22 | | test.go:25:15:25:41 | call to UserAgent | test.go:43:12:43:20 | untrusted | provenance | Src:MaD:22 | -| test.go:25:15:25:41 | call to UserAgent | test.go:44:16:44:24 | untrusted | provenance | Src:MaD:22 Sink:MaD:14 | +| test.go:25:15:25:41 | call to UserAgent | test.go:44:16:44:24 | untrusted | provenance | Src:MaD:22 Sink:MaD:14 | | test.go:25:15:25:41 | call to UserAgent | test.go:45:12:45:20 | untrusted | provenance | Src:MaD:22 | -| test.go:25:15:25:41 | call to UserAgent | test.go:46:14:46:22 | untrusted | provenance | Src:MaD:22 Sink:MaD:19 | +| test.go:25:15:25:41 | call to UserAgent | test.go:46:14:46:22 | untrusted | provenance | Src:MaD:22 Sink:MaD:19 | | test.go:26:16:26:42 | call to UserAgent | test.go:44:27:44:36 | untrusted2 | provenance | Src:MaD:22 | -| test.go:26:16:26:42 | call to UserAgent | test.go:46:25:46:34 | untrusted2 | provenance | Src:MaD:22 Sink:MaD:19 | -| test.go:50:15:50:41 | call to UserAgent | test.go:52:12:52:20 | untrusted | provenance | Src:MaD:22 Sink:MaD:10 | -| test.go:57:15:57:41 | call to UserAgent | test.go:59:31:59:39 | untrusted | provenance | Src:MaD:22 Sink:MaD:21 | -| test.go:63:15:63:41 | call to UserAgent | test.go:65:19:65:27 | untrusted | provenance | Src:MaD:22 Sink:MaD:1 | +| test.go:26:16:26:42 | call to UserAgent | test.go:46:25:46:34 | untrusted2 | provenance | Src:MaD:22 Sink:MaD:19 | +| test.go:50:15:50:41 | call to UserAgent | test.go:52:12:52:20 | untrusted | provenance | Src:MaD:22 Sink:MaD:10 | +| test.go:57:15:57:41 | call to UserAgent | test.go:59:31:59:39 | untrusted | provenance | Src:MaD:22 Sink:MaD:21 | +| test.go:63:15:63:41 | call to UserAgent | test.go:65:19:65:27 | untrusted | provenance | Src:MaD:22 Sink:MaD:1 | models -| 1 | Sink: group:beego-orm; Condition; false; Raw; ; ; Argument[1]; sql-injection; manual | -| 2 | Sink: group:beego-orm; DB; false; Exec; ; ; Argument[0]; sql-injection; manual | -| 3 | Sink: group:beego-orm; DB; false; ExecContext; ; ; Argument[1]; sql-injection; manual | -| 4 | Sink: group:beego-orm; DB; false; Prepare; ; ; Argument[0]; sql-injection; manual | -| 5 | Sink: group:beego-orm; DB; false; PrepareContext; ; ; Argument[1]; sql-injection; manual | -| 6 | Sink: group:beego-orm; DB; false; Query; ; ; Argument[0]; sql-injection; manual | -| 7 | Sink: group:beego-orm; DB; false; QueryContext; ; ; Argument[1]; sql-injection; manual | -| 8 | Sink: group:beego-orm; DB; false; QueryRow; ; ; Argument[0]; sql-injection; manual | -| 9 | Sink: group:beego-orm; DB; false; QueryRowContext; ; ; Argument[1]; sql-injection; manual | -| 10 | Sink: group:beego-orm; Ormer; false; Raw; ; ; Argument[0]; sql-injection; manual | -| 11 | Sink: group:beego-orm; QueryBuilder; false; And; ; ; Argument[0]; sql-injection; manual | -| 12 | Sink: group:beego-orm; QueryBuilder; false; Having; ; ; Argument[0]; sql-injection; manual | -| 13 | Sink: group:beego-orm; QueryBuilder; false; InnerJoin; ; ; Argument[0]; sql-injection; manual | -| 14 | Sink: group:beego-orm; QueryBuilder; false; InsertInto; ; ; Argument[0..1]; sql-injection; manual | -| 15 | Sink: group:beego-orm; QueryBuilder; false; LeftJoin; ; ; Argument[0]; sql-injection; manual | -| 16 | Sink: group:beego-orm; QueryBuilder; false; On; ; ; Argument[0]; sql-injection; manual | -| 17 | Sink: group:beego-orm; QueryBuilder; false; Or; ; ; Argument[0]; sql-injection; manual | -| 18 | Sink: group:beego-orm; QueryBuilder; false; RightJoin; ; ; Argument[0]; sql-injection; manual | -| 19 | Sink: group:beego-orm; QueryBuilder; false; Subquery; ; ; Argument[0..1]; sql-injection; manual | -| 20 | Sink: group:beego-orm; QueryBuilder; false; Where; ; ; Argument[0]; sql-injection; manual | -| 21 | Sink: group:beego-orm; QuerySeter; false; FilterRaw; ; ; Argument[1]; sql-injection; manual | +| 1 | Sink: group:beego-orm; Condition; true; Raw; ; ; Argument[1]; sql-injection; manual | +| 2 | Sink: group:beego-orm; DB; true; Exec; ; ; Argument[0]; sql-injection; manual | +| 3 | Sink: group:beego-orm; DB; true; ExecContext; ; ; Argument[1]; sql-injection; manual | +| 4 | Sink: group:beego-orm; DB; true; Prepare; ; ; Argument[0]; sql-injection; manual | +| 5 | Sink: group:beego-orm; DB; true; PrepareContext; ; ; Argument[1]; sql-injection; manual | +| 6 | Sink: group:beego-orm; DB; true; Query; ; ; Argument[0]; sql-injection; manual | +| 7 | Sink: group:beego-orm; DB; true; QueryContext; ; ; Argument[1]; sql-injection; manual | +| 8 | Sink: group:beego-orm; DB; true; QueryRow; ; ; Argument[0]; sql-injection; manual | +| 9 | Sink: group:beego-orm; DB; true; QueryRowContext; ; ; Argument[1]; sql-injection; manual | +| 10 | Sink: group:beego-orm; Ormer; true; Raw; ; ; Argument[0]; sql-injection; manual | +| 11 | Sink: group:beego-orm; QueryBuilder; true; And; ; ; Argument[0]; sql-injection; manual | +| 12 | Sink: group:beego-orm; QueryBuilder; true; Having; ; ; Argument[0]; sql-injection; manual | +| 13 | Sink: group:beego-orm; QueryBuilder; true; InnerJoin; ; ; Argument[0]; sql-injection; manual | +| 14 | Sink: group:beego-orm; QueryBuilder; true; InsertInto; ; ; Argument[0..1]; sql-injection; manual | +| 15 | Sink: group:beego-orm; QueryBuilder; true; LeftJoin; ; ; Argument[0]; sql-injection; manual | +| 16 | Sink: group:beego-orm; QueryBuilder; true; On; ; ; Argument[0]; sql-injection; manual | +| 17 | Sink: group:beego-orm; QueryBuilder; true; Or; ; ; Argument[0]; sql-injection; manual | +| 18 | Sink: group:beego-orm; QueryBuilder; true; RightJoin; ; ; Argument[0]; sql-injection; manual | +| 19 | Sink: group:beego-orm; QueryBuilder; true; Subquery; ; ; Argument[0..1]; sql-injection; manual | +| 20 | Sink: group:beego-orm; QueryBuilder; true; Where; ; ; Argument[0]; sql-injection; manual | +| 21 | Sink: group:beego-orm; QuerySeter; true; FilterRaw; ; ; Argument[1]; sql-injection; manual | | 22 | Source: net/http; Request; true; UserAgent; ; ; ReturnValue; remote; manual | nodes | test.go:11:15:11:41 | call to UserAgent | semmle.label | call to UserAgent | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected index d0b5c378c92..8b2f05c297f 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected @@ -4,7 +4,7 @@ edges | test.go:56:2:56:42 | ... := ...[0] | test.go:57:29:57:40 | selection of Value | provenance | Src:MaD:2 | | test.go:57:29:57:40 | selection of Value | test.go:57:11:57:41 | call to EscapeString | provenance | MaD:3 Sink:MaD:1 | models -| 1 | Sink: database/sql; DB; false; Query; ; ; Argument[0]; sql-injection; manual | +| 1 | Sink: database/sql; DB; true; Query; ; ; Argument[0]; sql-injection; manual | | 2 | Source: net/http; Request; true; Cookie; ; ; ReturnValue[0]; remote; manual | | 3 | Summary: golang.org/x/net/html; ; false; EscapeString; ; ; Argument[0]; ReturnValue; taint; manual | nodes diff --git a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 18fc2e554e6..1ce8c3d1dcf 100644 --- a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -134,8 +134,8 @@ edges | mongoDB.go:50:23:50:40 | struct literal | mongoDB.go:81:18:81:25 | pipeline | provenance | Sink:MaD:16 | | mongoDB.go:50:34:50:39 | filter | mongoDB.go:50:23:50:40 | struct literal | provenance | Config | models -| 1 | Sink: database/sql; DB; false; Query; ; ; Argument[0]; sql-injection; manual | -| 2 | Sink: database/sql; Tx; false; Query; ; ; Argument[0]; sql-injection; manual | +| 1 | Sink: database/sql; DB; true; Query; ; ; Argument[0]; sql-injection; manual | +| 2 | Sink: database/sql; Tx; true; Query; ; ; Argument[0]; sql-injection; manual | | 3 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; Aggregate; ; ; Argument[1]; nosql-injection; manual | | 4 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; CountDocuments; ; ; Argument[1]; nosql-injection; manual | | 5 | Sink: go.mongodb.org/mongo-driver/mongo; Collection; true; DeleteMany; ; ; Argument[1]; nosql-injection; manual | From 9fc0dc569085f15f8825c31f715f4fa870b6131a Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 18 Sep 2024 14:43:55 +0100 Subject: [PATCH 081/470] Fix typo in unrelated QLDoc --- go/ql/lib/semmle/go/Scopes.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/ql/lib/semmle/go/Scopes.qll b/go/ql/lib/semmle/go/Scopes.qll index f9b9e3a26b9..c3671c74b5c 100644 --- a/go/ql/lib/semmle/go/Scopes.qll +++ b/go/ql/lib/semmle/go/Scopes.qll @@ -472,7 +472,7 @@ class Function extends ValueEntity, @functionobject { /** Gets a parameter of this function. */ Parameter getAParameter() { result = this.getParameter(_) } - /** Gets the `i`th reslt variable of this function. */ + /** Gets the `i`th result variable of this function. */ ResultVariable getResult(int i) { result.isResultOf(this.getFuncDecl(), i) } /** Gets a result variable of this function. */ From e57d8983f5e9602070032efde858042e492f4851 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 18 Sep 2024 13:51:13 +0100 Subject: [PATCH 082/470] Add heuristic logger calls --- go/ql/lib/semmle/go/Concepts.qll | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/go/ql/lib/semmle/go/Concepts.qll b/go/ql/lib/semmle/go/Concepts.qll index edb8e6c88fd..16b32466f3d 100644 --- a/go/ql/lib/semmle/go/Concepts.qll +++ b/go/ql/lib/semmle/go/Concepts.qll @@ -390,6 +390,28 @@ private class DefaultLoggerCall extends LoggerCall::Range, DataFlow::CallNode { } } +/** + * A call to an interface that looks like a logger. It is common to use a + * locally-defined interface for logging to make it easy to changing logging + * library. + */ +private class HeuristicLoggerCall extends LoggerCall::Range, DataFlow::CallNode { + HeuristicLoggerCall() { + exists(Method m, string tp, string logLevel, string name | + m = this.getTarget() and + m.hasQualifiedName(_, tp, name) and + m.getReceiverBaseType().getUnderlyingType() instanceof InterfaceType + | + tp.regexpMatch(".*[lL]ogger") and + logLevel = + ["Debug", "Error", "Fatal", "Info", "Log", "Output", "Panic", "Print", "Trace", "Warn"] and + name.matches(logLevel + "%") + ) + } + + override DataFlow::Node getAMessageComponent() { result = this.getASyntacticArgument() } +} + /** * A function that encodes data into a binary or textual format. * From 307fdc0864a353a6dd241b0f701ea8c33d646832 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 18 Sep 2024 16:50:37 +0100 Subject: [PATCH 083/470] Add tests for heuristic logger calls --- .../Security/CWE-117/LogInjection.go | 28 +++- .../test/query-tests/Security/CWE-117/go.mod | 27 +++- .../Security/CWE-117/vendor/modules.txt | 126 ++++++++++++++++-- 3 files changed, 168 insertions(+), 13 deletions(-) diff --git a/go/ql/test/query-tests/Security/CWE-117/LogInjection.go b/go/ql/test/query-tests/Security/CWE-117/LogInjection.go index 5cc9c81d449..6fb628c4cc3 100644 --- a/go/ql/test/query-tests/Security/CWE-117/LogInjection.go +++ b/go/ql/test/query-tests/Security/CWE-117/LogInjection.go @@ -30,6 +30,7 @@ import ( func handler(req *http.Request, ctx *goproxy.ProxyCtx) { username := req.URL.Query()["username"][0] + slice := []any{"username", username} testFlag := req.URL.Query()["testFlag"][0] { @@ -412,8 +413,34 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) { sLogger.Named(username) // $ hasTaintFlow="username" sLogger.With(username) // $ hasTaintFlow="username" } + // heuristic logger interface + { + logger.Printf(username) // $ hasTaintFlow="username" + logger.Printf("%s", username) // $ hasTaintFlow="username" + simpleLogger.Tracew(username) // $ hasTaintFlow="username" + simpleLogger.Tracew("%s", username) // $ hasTaintFlow="username" + simpleLogger.Debugw("%s %s", slice...) // $ hasTaintFlow="slice" + } + } +type Logger interface { + Printf(string, ...interface{}) +} + +type SimpleLogger interface { + Debugw(msg string, keysAndValues ...any) + Infow(msg string, keysAndValues ...any) + Warnw(msg string, keysAndValues ...any) + Errorw(msg string, keysAndValues ...any) + Tracew(msg string, keysAndValues ...any) +} + +var ( + logger Logger + simpleLogger SimpleLogger +) + // GOOD: The user-provided value is escaped before being written to the log. func handlerGood(req *http.Request) { username := req.URL.Query()["username"][0] @@ -649,5 +676,4 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) { } sLogger.Warnf("user %#q logged in.\n", username) // $ hasTaintFlow="username" } - } diff --git a/go/ql/test/query-tests/Security/CWE-117/go.mod b/go/ql/test/query-tests/Security/CWE-117/go.mod index 57b2077a4ed..906d90f31b6 100644 --- a/go/ql/test/query-tests/Security/CWE-117/go.mod +++ b/go/ql/test/query-tests/Security/CWE-117/go.mod @@ -1,14 +1,33 @@ module main -go 1.14 +go 1.23 require ( github.com/astaxie/beego v1.12.3 + github.com/davecgh/go-spew v1.1.1 github.com/elazarl/goproxy v0.0.0-20211114080932-d06c3be7c11b github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b - github.com/kr/text v0.2.0 // indirect github.com/sirupsen/logrus v1.8.1 - github.com/stretchr/testify v1.6.0 // indirect - golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect + go.uber.org/zap v1.27.0 k8s.io/klog v1.0.0 ) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/golang/protobuf v1.4.2 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/prometheus/client_golang v1.7.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.10.0 // indirect + github.com/prometheus/procfs v0.1.3 // indirect + github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect + go.uber.org/multierr v1.10.0 // indirect + golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect + golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect + golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect + golang.org/x/text v0.3.0 // indirect + google.golang.org/protobuf v1.23.0 // indirect + gopkg.in/yaml.v2 v2.2.8 // indirect +) diff --git a/go/ql/test/query-tests/Security/CWE-117/vendor/modules.txt b/go/ql/test/query-tests/Security/CWE-117/vendor/modules.txt index a6227c09a93..fa7cb0a9a82 100644 --- a/go/ql/test/query-tests/Security/CWE-117/vendor/modules.txt +++ b/go/ql/test/query-tests/Security/CWE-117/vendor/modules.txt @@ -1,24 +1,134 @@ # github.com/astaxie/beego v1.12.3 -## explicit +## explicit; go 1.13 github.com/astaxie/beego +github.com/astaxie/beego/config +github.com/astaxie/beego/context +github.com/astaxie/beego/context/param +github.com/astaxie/beego/grace +github.com/astaxie/beego/logs +github.com/astaxie/beego/session +github.com/astaxie/beego/toolbox +github.com/astaxie/beego/utils +# github.com/beorn7/perks v1.0.1 +## explicit; go 1.11 +github.com/beorn7/perks/quantile +# github.com/cespare/xxhash/v2 v2.1.1 +## explicit; go 1.11 +github.com/cespare/xxhash/v2 +# github.com/davecgh/go-spew v1.1.1 +## explicit +github.com/davecgh/go-spew/spew # github.com/elazarl/goproxy v0.0.0-20211114080932-d06c3be7c11b ## explicit github.com/elazarl/goproxy # github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b ## explicit github.com/golang/glog -# github.com/kr/text v0.2.0 +# github.com/golang/protobuf v1.4.2 +## explicit; go 1.9 +github.com/golang/protobuf/proto +github.com/golang/protobuf/ptypes +github.com/golang/protobuf/ptypes/any +github.com/golang/protobuf/ptypes/duration +github.com/golang/protobuf/ptypes/timestamp +# github.com/hashicorp/golang-lru v0.5.4 +## explicit; go 1.12 +github.com/hashicorp/golang-lru +github.com/hashicorp/golang-lru/simplelru +# github.com/matttproud/golang_protobuf_extensions v1.0.1 ## explicit -github.com/kr/text +github.com/matttproud/golang_protobuf_extensions/pbutil +# github.com/prometheus/client_golang v1.7.0 +## explicit; go 1.11 +github.com/prometheus/client_golang/prometheus +github.com/prometheus/client_golang/prometheus/internal +github.com/prometheus/client_golang/prometheus/promhttp +# github.com/prometheus/client_model v0.2.0 +## explicit; go 1.9 +github.com/prometheus/client_model/go +# github.com/prometheus/common v0.10.0 +## explicit; go 1.11 +github.com/prometheus/common/expfmt +github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg +github.com/prometheus/common/model +# github.com/prometheus/procfs v0.1.3 +## explicit; go 1.12 +github.com/prometheus/procfs +github.com/prometheus/procfs/internal/fs +github.com/prometheus/procfs/internal/util +# github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 +## explicit +github.com/shiena/ansicolor # github.com/sirupsen/logrus v1.8.1 -## explicit +## explicit; go 1.13 github.com/sirupsen/logrus -# github.com/stretchr/testify v1.6.0 +# go.uber.org/multierr v1.10.0 +## explicit; go 1.19 +go.uber.org/multierr +# go.uber.org/zap v1.27.0 +## explicit; go 1.19 +go.uber.org/zap +go.uber.org/zap/buffer +go.uber.org/zap/internal +go.uber.org/zap/internal/bufferpool +go.uber.org/zap/internal/color +go.uber.org/zap/internal/exit +go.uber.org/zap/internal/pool +go.uber.org/zap/internal/stacktrace +go.uber.org/zap/zapcore +# golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 ## explicit -github.com/stretchr/testify +golang.org/x/crypto/acme +golang.org/x/crypto/acme/autocert +# golang.org/x/net v0.0.0-20190620200207-3b0461eec859 +## explicit; go 1.11 +golang.org/x/net/idna # golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f +## explicit; go 1.12 +golang.org/x/sys/internal/unsafeheader +golang.org/x/sys/unix +golang.org/x/sys/windows +# golang.org/x/text v0.3.0 ## explicit -golang.org/x/sys +golang.org/x/text/secure/bidirule +golang.org/x/text/transform +golang.org/x/text/unicode/bidi +golang.org/x/text/unicode/norm +# google.golang.org/protobuf v1.23.0 +## explicit; go 1.9 +google.golang.org/protobuf/encoding/prototext +google.golang.org/protobuf/encoding/protowire +google.golang.org/protobuf/internal/descfmt +google.golang.org/protobuf/internal/descopts +google.golang.org/protobuf/internal/detrand +google.golang.org/protobuf/internal/encoding/defval +google.golang.org/protobuf/internal/encoding/messageset +google.golang.org/protobuf/internal/encoding/tag +google.golang.org/protobuf/internal/encoding/text +google.golang.org/protobuf/internal/errors +google.golang.org/protobuf/internal/fieldnum +google.golang.org/protobuf/internal/fieldsort +google.golang.org/protobuf/internal/filedesc +google.golang.org/protobuf/internal/filetype +google.golang.org/protobuf/internal/flags +google.golang.org/protobuf/internal/genname +google.golang.org/protobuf/internal/impl +google.golang.org/protobuf/internal/mapsort +google.golang.org/protobuf/internal/pragma +google.golang.org/protobuf/internal/set +google.golang.org/protobuf/internal/strs +google.golang.org/protobuf/internal/version +google.golang.org/protobuf/proto +google.golang.org/protobuf/reflect/protoreflect +google.golang.org/protobuf/reflect/protoregistry +google.golang.org/protobuf/runtime/protoiface +google.golang.org/protobuf/runtime/protoimpl +google.golang.org/protobuf/types/known/anypb +google.golang.org/protobuf/types/known/durationpb +google.golang.org/protobuf/types/known/timestamppb +# gopkg.in/yaml.v2 v2.2.8 +## explicit +gopkg.in/yaml.v2 # k8s.io/klog v1.0.0 -## explicit +## explicit; go 1.12 k8s.io/klog From 49eefccde1a73cc3e9d2bce670556652f2beac72 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Nov 2024 11:49:02 +0000 Subject: [PATCH 084/470] Rust: Autoformat. --- rust/ql/lib/codeql/rust/Concepts.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/rust/ql/lib/codeql/rust/Concepts.qll b/rust/ql/lib/codeql/rust/Concepts.qll index f64d2444573..62cd24467d1 100644 --- a/rust/ql/lib/codeql/rust/Concepts.qll +++ b/rust/ql/lib/codeql/rust/Concepts.qll @@ -53,9 +53,7 @@ module ThreatModelSource { * A data flow source that is enabled in the current threat model configuration. */ class ActiveThreatModelSource extends ThreatModelSource { - ActiveThreatModelSource() { - currentThreatModel(this.getThreatModel()) - } + ActiveThreatModelSource() { currentThreatModel(this.getThreatModel()) } } /** From 758092b1d63dcdcd58f8dcdc642c50f23ede2c77 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Nov 2024 12:04:15 +0000 Subject: [PATCH 085/470] Rust: Add consistency check failures. --- .../security/CWE-089/CONSISTENCY/DataFlowConsistency.expected | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected diff --git a/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected new file mode 100644 index 00000000000..d9a60435a6f --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected @@ -0,0 +1,3 @@ +uniqueNodeToString +| sqlx.rs:154:13:154:81 | (no string representation) | Node should have one toString but has 0. | +| sqlx.rs:156:17:156:86 | (no string representation) | Node should have one toString but has 0. | From 6ed895064ffc9d09e898167b4cac85453f279ffb Mon Sep 17 00:00:00 2001 From: yoff Date: Tue, 19 Nov 2024 13:37:53 +0100 Subject: [PATCH 086/470] Apply suggestions from code review Co-authored-by: Anders Schack-Mulligen --- .../library-tests/dataflow/range-analysis-inline/B.java | 4 +++- .../library-tests/dataflow/range-analysis-inline/range.ql | 8 +++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java b/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java index f3ff1855811..7cc30479537 100644 --- a/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java +++ b/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java @@ -1,7 +1,9 @@ public class B { public int forloop() { int result = 0; - for (int i = 0; i < 10; i++) {// $ bound="i in [0..10]" bound="i in [0..9]" + for (int i = 0; + i < 10; // $ bound="i in [0..10]" + i++) { // $ bound="i in [0..9]" result = i; // $ bound="i in [0..9]" } return result; // $ bound="result in [0..9]" diff --git a/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql b/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql index dcfbfbf54c6..0e0fa68b07b 100644 --- a/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql +++ b/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql @@ -5,9 +5,7 @@ import java import semmle.code.java.dataflow.RangeAnalysis -private import codeql.util.test.InlineExpectationsTest -private import TestUtilities.internal.InlineExpectationsTestImpl -private import Make as IET +private import TestUtilities.InlineExpectationsTest as IET module RangeTest implements IET::TestSig { string getARelevantTag() { result = "bound" } @@ -29,8 +27,8 @@ module RangeTest implements IET::TestSig { } private predicate constrained(Expr e, int lower, int upper) { - lower = min(int delta | bounded(e, any(ZeroBound z), delta, false, _)) and - upper = min(int delta | bounded(e, any(ZeroBound z), delta, true, _)) + bounded(e, any(ZeroBound z), lower, false, _) and + bounded(e, any(ZeroBound z), upper, true, _) } } From f1e95a8a1dee4d68038779011bf3414564080f4f Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 19 Nov 2024 14:09:58 +0100 Subject: [PATCH 087/470] JS: Add: taint step test cases for findLastIndex, findLast, find --- .../ql/test/library-tests/Arrays/DataFlow.ql | 5 +- .../library-tests/Arrays/TaintFlow.expected | 2 + .../ql/test/library-tests/Arrays/TaintFlow.ql | 5 +- .../ql/test/library-tests/Arrays/arrays.js | 17 + .../library-tests/Arrays/printAst.expected | 504 +++++++++++++----- 5 files changed, 396 insertions(+), 137 deletions(-) diff --git a/javascript/ql/test/library-tests/Arrays/DataFlow.ql b/javascript/ql/test/library-tests/Arrays/DataFlow.ql index 80c9f068a10..5c5f4a0d10e 100644 --- a/javascript/ql/test/library-tests/Arrays/DataFlow.ql +++ b/javascript/ql/test/library-tests/Arrays/DataFlow.ql @@ -3,7 +3,10 @@ import javascript class ArrayFlowConfig extends DataFlow::Configuration { ArrayFlowConfig() { this = "ArrayFlowConfig" } - override predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" } + override predicate isSource(DataFlow::Node source) { + source.asExpr().getStringValue() = "source" or + source.(DataFlow::CallNode).getCalleeName() = "source" + } override predicate isSink(DataFlow::Node sink) { sink = any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument() diff --git a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected index 06260a21c1c..e17fe726d16 100644 --- a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected @@ -35,3 +35,5 @@ | arrays.js:120:19:120:26 | "source" | arrays.js:121:46:121:49 | item | | arrays.js:120:19:120:26 | "source" | arrays.js:122:10:122:16 | element | | arrays.js:126:19:126:26 | "source" | arrays.js:127:55:127:58 | item | +| arrays.js:131:17:131:24 | source() | arrays.js:133:10:133:17 | element1 | +| arrays.js:137:17:137:24 | source() | arrays.js:139:10:139:17 | element1 | diff --git a/javascript/ql/test/library-tests/Arrays/TaintFlow.ql b/javascript/ql/test/library-tests/Arrays/TaintFlow.ql index cee2f294a34..d8f18759162 100644 --- a/javascript/ql/test/library-tests/Arrays/TaintFlow.ql +++ b/javascript/ql/test/library-tests/Arrays/TaintFlow.ql @@ -3,7 +3,10 @@ import javascript class ArrayTaintFlowConfig extends TaintTracking::Configuration { ArrayTaintFlowConfig() { this = "ArrayTaintFlowConfig" } - override predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" } + override predicate isSource(DataFlow::Node source) { + source.asExpr().getStringValue() = "source" or + source.(DataFlow::CallNode).getCalleeName() = "source" + } override predicate isSink(DataFlow::Node sink) { sink = any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument() diff --git a/javascript/ql/test/library-tests/Arrays/arrays.js b/javascript/ql/test/library-tests/Arrays/arrays.js index 00aa0c59e18..862dae77967 100644 --- a/javascript/ql/test/library-tests/Arrays/arrays.js +++ b/javascript/ql/test/library-tests/Arrays/arrays.js @@ -127,4 +127,21 @@ const element = list.findLastIndex((item) => sink(item)); // NOT OK sink(element); // OK } + { + const arr = source(); + const element1 = arr.find((item) => sink(item)); // NOT OK - only found with taint-tracking. + sink(element1); // NOT OK + } + + { + const arr = source(); + const element1 = arr.findLast((item) => sink(item)); // NOT OK - only found with taint-tracking. + sink(element1); // NOT OK + } + + { + const arr = source(); + const element1 = arr.findLastIndex((item) => sink(item)); // NOT OK - only found with taint-tracking. + sink(element1); // OK + } }); diff --git a/javascript/ql/test/library-tests/Arrays/printAst.expected b/javascript/ql/test/library-tests/Arrays/printAst.expected index 6a23be2dee6..a825b12f3fb 100644 --- a/javascript/ql/test/library-tests/Arrays/printAst.expected +++ b/javascript/ql/test/library-tests/Arrays/printAst.expected @@ -1,9 +1,9 @@ nodes -| arrays.js:1:1:130:2 | [ParExpr] (functi ... } }) | semmle.label | [ParExpr] (functi ... } }) | -| arrays.js:1:1:130:3 | [ExprStmt] (functi ... } }); | semmle.label | [ExprStmt] (functi ... } }); | -| arrays.js:1:1:130:3 | [ExprStmt] (functi ... } }); | semmle.order | 1 | -| arrays.js:1:2:130:1 | [FunctionExpr] functio ... K } } | semmle.label | [FunctionExpr] functio ... K } } | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | semmle.label | [BlockStmt] { let ... K } } | +| arrays.js:1:1:147:2 | [ParExpr] (functi ... } }) | semmle.label | [ParExpr] (functi ... } }) | +| arrays.js:1:1:147:3 | [ExprStmt] (functi ... } }); | semmle.label | [ExprStmt] (functi ... } }); | +| arrays.js:1:1:147:3 | [ExprStmt] (functi ... } }); | semmle.order | 1 | +| arrays.js:1:2:147:1 | [FunctionExpr] functio ... K } } | semmle.label | [FunctionExpr] functio ... K } } | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | semmle.label | [BlockStmt] { let ... K } } | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | [DeclStmt] let source = ... | | arrays.js:2:7:2:12 | [VarDecl] source | semmle.label | [VarDecl] source | | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.label | [VariableDeclarator] source = "source" | @@ -561,6 +561,72 @@ nodes | arrays.js:128:5:128:17 | [CallExpr] sink(element) | semmle.label | [CallExpr] sink(element) | | arrays.js:128:5:128:18 | [ExprStmt] sink(element); | semmle.label | [ExprStmt] sink(element); | | arrays.js:128:10:128:16 | [VarRef] element | semmle.label | [VarRef] element | +| arrays.js:130:3:134:3 | [BlockStmt] { c ... OK } | semmle.label | [BlockStmt] { c ... OK } | +| arrays.js:131:5:131:25 | [DeclStmt] const arr = ... | semmle.label | [DeclStmt] const arr = ... | +| arrays.js:131:11:131:13 | [VarDecl] arr | semmle.label | [VarDecl] arr | +| arrays.js:131:11:131:24 | [VariableDeclarator] arr = source() | semmle.label | [VariableDeclarator] arr = source() | +| arrays.js:131:17:131:22 | [VarRef] source | semmle.label | [VarRef] source | +| arrays.js:131:17:131:24 | [CallExpr] source() | semmle.label | [CallExpr] source() | +| arrays.js:132:5:132:52 | [DeclStmt] const element1 = ... | semmle.label | [DeclStmt] const element1 = ... | +| arrays.js:132:11:132:18 | [VarDecl] element1 | semmle.label | [VarDecl] element1 | +| arrays.js:132:11:132:51 | [VariableDeclarator] element ... (item)) | semmle.label | [VariableDeclarator] element ... (item)) | +| arrays.js:132:22:132:24 | [VarRef] arr | semmle.label | [VarRef] arr | +| arrays.js:132:22:132:29 | [DotExpr] arr.find | semmle.label | [DotExpr] arr.find | +| arrays.js:132:22:132:51 | [MethodCallExpr] arr.fin ... (item)) | semmle.label | [MethodCallExpr] arr.fin ... (item)) | +| arrays.js:132:26:132:29 | [Label] find | semmle.label | [Label] find | +| arrays.js:132:31:132:50 | [ArrowFunctionExpr] (item) => sink(item) | semmle.label | [ArrowFunctionExpr] (item) => sink(item) | +| arrays.js:132:32:132:35 | [SimpleParameter] item | semmle.label | [SimpleParameter] item | +| arrays.js:132:41:132:44 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:132:41:132:50 | [CallExpr] sink(item) | semmle.label | [CallExpr] sink(item) | +| arrays.js:132:46:132:49 | [VarRef] item | semmle.label | [VarRef] item | +| arrays.js:133:5:133:8 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:133:5:133:18 | [CallExpr] sink(element1) | semmle.label | [CallExpr] sink(element1) | +| arrays.js:133:5:133:19 | [ExprStmt] sink(element1); | semmle.label | [ExprStmt] sink(element1); | +| arrays.js:133:10:133:17 | [VarRef] element1 | semmle.label | [VarRef] element1 | +| arrays.js:136:3:140:3 | [BlockStmt] { c ... OK } | semmle.label | [BlockStmt] { c ... OK } | +| arrays.js:137:5:137:25 | [DeclStmt] const arr = ... | semmle.label | [DeclStmt] const arr = ... | +| arrays.js:137:11:137:13 | [VarDecl] arr | semmle.label | [VarDecl] arr | +| arrays.js:137:11:137:24 | [VariableDeclarator] arr = source() | semmle.label | [VariableDeclarator] arr = source() | +| arrays.js:137:17:137:22 | [VarRef] source | semmle.label | [VarRef] source | +| arrays.js:137:17:137:24 | [CallExpr] source() | semmle.label | [CallExpr] source() | +| arrays.js:138:5:138:56 | [DeclStmt] const element1 = ... | semmle.label | [DeclStmt] const element1 = ... | +| arrays.js:138:11:138:18 | [VarDecl] element1 | semmle.label | [VarDecl] element1 | +| arrays.js:138:11:138:55 | [VariableDeclarator] element ... (item)) | semmle.label | [VariableDeclarator] element ... (item)) | +| arrays.js:138:22:138:24 | [VarRef] arr | semmle.label | [VarRef] arr | +| arrays.js:138:22:138:33 | [DotExpr] arr.findLast | semmle.label | [DotExpr] arr.findLast | +| arrays.js:138:22:138:55 | [MethodCallExpr] arr.fin ... (item)) | semmle.label | [MethodCallExpr] arr.fin ... (item)) | +| arrays.js:138:26:138:33 | [Label] findLast | semmle.label | [Label] findLast | +| arrays.js:138:35:138:54 | [ArrowFunctionExpr] (item) => sink(item) | semmle.label | [ArrowFunctionExpr] (item) => sink(item) | +| arrays.js:138:36:138:39 | [SimpleParameter] item | semmle.label | [SimpleParameter] item | +| arrays.js:138:45:138:48 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:138:45:138:54 | [CallExpr] sink(item) | semmle.label | [CallExpr] sink(item) | +| arrays.js:138:50:138:53 | [VarRef] item | semmle.label | [VarRef] item | +| arrays.js:139:5:139:8 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:139:5:139:18 | [CallExpr] sink(element1) | semmle.label | [CallExpr] sink(element1) | +| arrays.js:139:5:139:19 | [ExprStmt] sink(element1); | semmle.label | [ExprStmt] sink(element1); | +| arrays.js:139:10:139:17 | [VarRef] element1 | semmle.label | [VarRef] element1 | +| arrays.js:142:3:146:3 | [BlockStmt] { c ... OK } | semmle.label | [BlockStmt] { c ... OK } | +| arrays.js:143:5:143:25 | [DeclStmt] const arr = ... | semmle.label | [DeclStmt] const arr = ... | +| arrays.js:143:11:143:13 | [VarDecl] arr | semmle.label | [VarDecl] arr | +| arrays.js:143:11:143:24 | [VariableDeclarator] arr = source() | semmle.label | [VariableDeclarator] arr = source() | +| arrays.js:143:17:143:22 | [VarRef] source | semmle.label | [VarRef] source | +| arrays.js:143:17:143:24 | [CallExpr] source() | semmle.label | [CallExpr] source() | +| arrays.js:144:5:144:61 | [DeclStmt] const element1 = ... | semmle.label | [DeclStmt] const element1 = ... | +| arrays.js:144:11:144:18 | [VarDecl] element1 | semmle.label | [VarDecl] element1 | +| arrays.js:144:11:144:60 | [VariableDeclarator] element ... (item)) | semmle.label | [VariableDeclarator] element ... (item)) | +| arrays.js:144:22:144:24 | [VarRef] arr | semmle.label | [VarRef] arr | +| arrays.js:144:22:144:38 | [DotExpr] arr.findLastIndex | semmle.label | [DotExpr] arr.findLastIndex | +| arrays.js:144:22:144:60 | [MethodCallExpr] arr.fin ... (item)) | semmle.label | [MethodCallExpr] arr.fin ... (item)) | +| arrays.js:144:26:144:38 | [Label] findLastIndex | semmle.label | [Label] findLastIndex | +| arrays.js:144:40:144:59 | [ArrowFunctionExpr] (item) => sink(item) | semmle.label | [ArrowFunctionExpr] (item) => sink(item) | +| arrays.js:144:41:144:44 | [SimpleParameter] item | semmle.label | [SimpleParameter] item | +| arrays.js:144:50:144:53 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:144:50:144:59 | [CallExpr] sink(item) | semmle.label | [CallExpr] sink(item) | +| arrays.js:144:55:144:58 | [VarRef] item | semmle.label | [VarRef] item | +| arrays.js:145:5:145:8 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:145:5:145:18 | [CallExpr] sink(element1) | semmle.label | [CallExpr] sink(element1) | +| arrays.js:145:5:145:19 | [ExprStmt] sink(element1); | semmle.label | [ExprStmt] sink(element1); | +| arrays.js:145:10:145:17 | [VarRef] element1 | semmle.label | [VarRef] element1 | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | @@ -629,6 +695,18 @@ nodes | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | @@ -640,136 +718,142 @@ nodes | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | edges -| arrays.js:1:1:130:2 | [ParExpr] (functi ... } }) | arrays.js:1:2:130:1 | [FunctionExpr] functio ... K } } | semmle.label | 1 | -| arrays.js:1:1:130:2 | [ParExpr] (functi ... } }) | arrays.js:1:2:130:1 | [FunctionExpr] functio ... K } } | semmle.order | 1 | -| arrays.js:1:1:130:3 | [ExprStmt] (functi ... } }); | arrays.js:1:1:130:2 | [ParExpr] (functi ... } }) | semmle.label | 1 | -| arrays.js:1:1:130:3 | [ExprStmt] (functi ... } }); | arrays.js:1:1:130:2 | [ParExpr] (functi ... } }) | semmle.order | 1 | -| arrays.js:1:2:130:1 | [FunctionExpr] functio ... K } } | arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | semmle.label | 5 | -| arrays.js:1:2:130:1 | [FunctionExpr] functio ... K } } | arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | semmle.order | 5 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | 1 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.order | 1 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.label | 2 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.order | 2 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.label | 3 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.order | 3 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.label | 4 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.order | 4 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.label | 5 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.order | 5 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.label | 6 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.order | 6 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.label | 7 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.order | 7 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.label | 8 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.order | 8 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.label | 9 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.order | 9 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.label | 10 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.order | 10 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.label | 11 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.order | 11 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.label | 12 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.order | 12 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.label | 13 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.order | 13 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.label | 14 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.order | 14 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.label | 15 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.order | 15 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.label | 16 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.order | 16 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.label | 17 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.order | 17 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.label | 18 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.order | 18 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.label | 19 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.order | 19 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.label | 20 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.order | 20 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 21 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 21 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.label | 22 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.order | 22 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.label | 23 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.order | 23 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 24 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 24 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.label | 25 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.order | 25 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.label | 26 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.order | 26 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.label | 27 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.order | 27 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.label | 28 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.order | 28 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.label | 29 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.order | 29 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.label | 30 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.order | 30 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.label | 31 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.order | 31 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.label | 32 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.order | 32 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.label | 33 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.order | 33 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.label | 34 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.order | 34 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.label | 35 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.order | 35 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.label | 36 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.order | 36 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.label | 37 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.order | 37 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.label | 38 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.order | 38 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.label | 39 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.order | 39 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.label | 40 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.order | 40 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.label | 41 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.order | 41 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.label | 42 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.order | 42 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.label | 43 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.order | 43 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.label | 44 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.order | 44 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.label | 45 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.order | 45 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.label | 46 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.order | 46 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.label | 47 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.order | 47 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.label | 48 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.order | 48 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.label | 49 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.order | 49 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.label | 50 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.order | 50 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.label | 51 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.order | 51 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.label | 52 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.order | 52 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.label | 53 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.order | 53 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.label | 54 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.order | 54 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 55 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 55 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.label | 56 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.order | 56 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.label | 57 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.order | 57 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 58 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 58 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:111:3:111:35 | [ExprStmt] sink(ar ... back)); | semmle.label | 59 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:111:3:111:35 | [ExprStmt] sink(ar ... back)); | semmle.order | 59 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:113:3:117:3 | [BlockStmt] { // T ... OK } | semmle.label | 60 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:113:3:117:3 | [BlockStmt] { // T ... OK } | semmle.order | 60 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:119:3:123:3 | [BlockStmt] { // T ... OK } | semmle.label | 61 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:119:3:123:3 | [BlockStmt] { // T ... OK } | semmle.order | 61 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:125:3:129:3 | [BlockStmt] { // T ... OK } | semmle.label | 62 | -| arrays.js:1:14:130:1 | [BlockStmt] { let ... K } } | arrays.js:125:3:129:3 | [BlockStmt] { // T ... OK } | semmle.order | 62 | +| arrays.js:1:1:147:2 | [ParExpr] (functi ... } }) | arrays.js:1:2:147:1 | [FunctionExpr] functio ... K } } | semmle.label | 1 | +| arrays.js:1:1:147:2 | [ParExpr] (functi ... } }) | arrays.js:1:2:147:1 | [FunctionExpr] functio ... K } } | semmle.order | 1 | +| arrays.js:1:1:147:3 | [ExprStmt] (functi ... } }); | arrays.js:1:1:147:2 | [ParExpr] (functi ... } }) | semmle.label | 1 | +| arrays.js:1:1:147:3 | [ExprStmt] (functi ... } }); | arrays.js:1:1:147:2 | [ParExpr] (functi ... } }) | semmle.order | 1 | +| arrays.js:1:2:147:1 | [FunctionExpr] functio ... K } } | arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | semmle.label | 5 | +| arrays.js:1:2:147:1 | [FunctionExpr] functio ... K } } | arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | semmle.order | 5 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | 1 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.order | 1 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.label | 2 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.order | 2 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.label | 3 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.order | 3 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.label | 4 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.order | 4 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.label | 5 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.order | 5 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.label | 6 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.order | 6 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.label | 7 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.order | 7 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.label | 8 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.order | 8 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.label | 9 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.order | 9 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.label | 10 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.order | 10 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.label | 11 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.order | 11 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.label | 12 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.order | 12 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.label | 13 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.order | 13 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.label | 14 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.order | 14 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.label | 15 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.order | 15 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.label | 16 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.order | 16 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.label | 17 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.order | 17 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.label | 18 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.order | 18 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.label | 19 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.order | 19 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.label | 20 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.order | 20 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 21 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 21 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.label | 22 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.order | 22 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.label | 23 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.order | 23 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 24 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 24 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.label | 25 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.order | 25 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.label | 26 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.order | 26 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.label | 27 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.order | 27 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.label | 28 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.order | 28 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.label | 29 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.order | 29 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.label | 30 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.order | 30 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.label | 31 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.order | 31 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.label | 32 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.order | 32 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.label | 33 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.order | 33 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.label | 34 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.order | 34 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.label | 35 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.order | 35 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.label | 36 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.order | 36 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.label | 37 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.order | 37 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.label | 38 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.order | 38 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.label | 39 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.order | 39 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.label | 40 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.order | 40 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.label | 41 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.order | 41 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.label | 42 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.order | 42 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.label | 43 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.order | 43 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.label | 44 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.order | 44 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.label | 45 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.order | 45 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.label | 46 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.order | 46 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.label | 47 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.order | 47 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.label | 48 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.order | 48 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.label | 49 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.order | 49 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.label | 50 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.order | 50 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.label | 51 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.order | 51 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.label | 52 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.order | 52 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.label | 53 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.order | 53 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.label | 54 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.order | 54 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 55 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 55 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.label | 56 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.order | 56 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.label | 57 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.order | 57 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 58 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 58 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:111:3:111:35 | [ExprStmt] sink(ar ... back)); | semmle.label | 59 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:111:3:111:35 | [ExprStmt] sink(ar ... back)); | semmle.order | 59 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:113:3:117:3 | [BlockStmt] { // T ... OK } | semmle.label | 60 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:113:3:117:3 | [BlockStmt] { // T ... OK } | semmle.order | 60 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:119:3:123:3 | [BlockStmt] { // T ... OK } | semmle.label | 61 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:119:3:123:3 | [BlockStmt] { // T ... OK } | semmle.order | 61 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:125:3:129:3 | [BlockStmt] { // T ... OK } | semmle.label | 62 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:125:3:129:3 | [BlockStmt] { // T ... OK } | semmle.order | 62 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:130:3:134:3 | [BlockStmt] { c ... OK } | semmle.label | 63 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:130:3:134:3 | [BlockStmt] { c ... OK } | semmle.order | 63 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:136:3:140:3 | [BlockStmt] { c ... OK } | semmle.label | 64 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:136:3:140:3 | [BlockStmt] { c ... OK } | semmle.order | 64 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:142:3:146:3 | [BlockStmt] { c ... OK } | semmle.label | 65 | +| arrays.js:1:14:147:1 | [BlockStmt] { let ... K } } | arrays.js:142:3:146:3 | [BlockStmt] { c ... OK } | semmle.order | 65 | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.label | 1 | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.order | 1 | | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | arrays.js:2:7:2:12 | [VarDecl] source | semmle.label | 1 | @@ -1726,6 +1810,132 @@ edges | arrays.js:128:5:128:17 | [CallExpr] sink(element) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | | arrays.js:128:5:128:18 | [ExprStmt] sink(element); | arrays.js:128:5:128:17 | [CallExpr] sink(element) | semmle.label | 1 | | arrays.js:128:5:128:18 | [ExprStmt] sink(element); | arrays.js:128:5:128:17 | [CallExpr] sink(element) | semmle.order | 1 | +| arrays.js:130:3:134:3 | [BlockStmt] { c ... OK } | arrays.js:131:5:131:25 | [DeclStmt] const arr = ... | semmle.label | 1 | +| arrays.js:130:3:134:3 | [BlockStmt] { c ... OK } | arrays.js:131:5:131:25 | [DeclStmt] const arr = ... | semmle.order | 1 | +| arrays.js:130:3:134:3 | [BlockStmt] { c ... OK } | arrays.js:132:5:132:52 | [DeclStmt] const element1 = ... | semmle.label | 2 | +| arrays.js:130:3:134:3 | [BlockStmt] { c ... OK } | arrays.js:132:5:132:52 | [DeclStmt] const element1 = ... | semmle.order | 2 | +| arrays.js:130:3:134:3 | [BlockStmt] { c ... OK } | arrays.js:133:5:133:19 | [ExprStmt] sink(element1); | semmle.label | 3 | +| arrays.js:130:3:134:3 | [BlockStmt] { c ... OK } | arrays.js:133:5:133:19 | [ExprStmt] sink(element1); | semmle.order | 3 | +| arrays.js:131:5:131:25 | [DeclStmt] const arr = ... | arrays.js:131:11:131:24 | [VariableDeclarator] arr = source() | semmle.label | 1 | +| arrays.js:131:5:131:25 | [DeclStmt] const arr = ... | arrays.js:131:11:131:24 | [VariableDeclarator] arr = source() | semmle.order | 1 | +| arrays.js:131:11:131:24 | [VariableDeclarator] arr = source() | arrays.js:131:11:131:13 | [VarDecl] arr | semmle.label | 1 | +| arrays.js:131:11:131:24 | [VariableDeclarator] arr = source() | arrays.js:131:11:131:13 | [VarDecl] arr | semmle.order | 1 | +| arrays.js:131:11:131:24 | [VariableDeclarator] arr = source() | arrays.js:131:17:131:24 | [CallExpr] source() | semmle.label | 2 | +| arrays.js:131:11:131:24 | [VariableDeclarator] arr = source() | arrays.js:131:17:131:24 | [CallExpr] source() | semmle.order | 2 | +| arrays.js:131:17:131:24 | [CallExpr] source() | arrays.js:131:17:131:22 | [VarRef] source | semmle.label | 0 | +| arrays.js:131:17:131:24 | [CallExpr] source() | arrays.js:131:17:131:22 | [VarRef] source | semmle.order | 0 | +| arrays.js:132:5:132:52 | [DeclStmt] const element1 = ... | arrays.js:132:11:132:51 | [VariableDeclarator] element ... (item)) | semmle.label | 1 | +| arrays.js:132:5:132:52 | [DeclStmt] const element1 = ... | arrays.js:132:11:132:51 | [VariableDeclarator] element ... (item)) | semmle.order | 1 | +| arrays.js:132:11:132:51 | [VariableDeclarator] element ... (item)) | arrays.js:132:11:132:18 | [VarDecl] element1 | semmle.label | 1 | +| arrays.js:132:11:132:51 | [VariableDeclarator] element ... (item)) | arrays.js:132:11:132:18 | [VarDecl] element1 | semmle.order | 1 | +| arrays.js:132:11:132:51 | [VariableDeclarator] element ... (item)) | arrays.js:132:22:132:51 | [MethodCallExpr] arr.fin ... (item)) | semmle.label | 2 | +| arrays.js:132:11:132:51 | [VariableDeclarator] element ... (item)) | arrays.js:132:22:132:51 | [MethodCallExpr] arr.fin ... (item)) | semmle.order | 2 | +| arrays.js:132:22:132:29 | [DotExpr] arr.find | arrays.js:132:22:132:24 | [VarRef] arr | semmle.label | 1 | +| arrays.js:132:22:132:29 | [DotExpr] arr.find | arrays.js:132:22:132:24 | [VarRef] arr | semmle.order | 1 | +| arrays.js:132:22:132:29 | [DotExpr] arr.find | arrays.js:132:26:132:29 | [Label] find | semmle.label | 2 | +| arrays.js:132:22:132:29 | [DotExpr] arr.find | arrays.js:132:26:132:29 | [Label] find | semmle.order | 2 | +| arrays.js:132:22:132:51 | [MethodCallExpr] arr.fin ... (item)) | arrays.js:132:22:132:29 | [DotExpr] arr.find | semmle.label | 0 | +| arrays.js:132:22:132:51 | [MethodCallExpr] arr.fin ... (item)) | arrays.js:132:22:132:29 | [DotExpr] arr.find | semmle.order | 0 | +| arrays.js:132:22:132:51 | [MethodCallExpr] arr.fin ... (item)) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:132:22:132:51 | [MethodCallExpr] arr.fin ... (item)) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:132:31:132:50 | [ArrowFunctionExpr] (item) => sink(item) | arrays.js:132:41:132:50 | [CallExpr] sink(item) | semmle.label | 5 | +| arrays.js:132:31:132:50 | [ArrowFunctionExpr] (item) => sink(item) | arrays.js:132:41:132:50 | [CallExpr] sink(item) | semmle.order | 5 | +| arrays.js:132:31:132:50 | [ArrowFunctionExpr] (item) => sink(item) | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| arrays.js:132:31:132:50 | [ArrowFunctionExpr] (item) => sink(item) | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| arrays.js:132:41:132:50 | [CallExpr] sink(item) | arrays.js:132:41:132:44 | [VarRef] sink | semmle.label | 0 | +| arrays.js:132:41:132:50 | [CallExpr] sink(item) | arrays.js:132:41:132:44 | [VarRef] sink | semmle.order | 0 | +| arrays.js:132:41:132:50 | [CallExpr] sink(item) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:132:41:132:50 | [CallExpr] sink(item) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:133:5:133:18 | [CallExpr] sink(element1) | arrays.js:133:5:133:8 | [VarRef] sink | semmle.label | 0 | +| arrays.js:133:5:133:18 | [CallExpr] sink(element1) | arrays.js:133:5:133:8 | [VarRef] sink | semmle.order | 0 | +| arrays.js:133:5:133:18 | [CallExpr] sink(element1) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:133:5:133:18 | [CallExpr] sink(element1) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:133:5:133:19 | [ExprStmt] sink(element1); | arrays.js:133:5:133:18 | [CallExpr] sink(element1) | semmle.label | 1 | +| arrays.js:133:5:133:19 | [ExprStmt] sink(element1); | arrays.js:133:5:133:18 | [CallExpr] sink(element1) | semmle.order | 1 | +| arrays.js:136:3:140:3 | [BlockStmt] { c ... OK } | arrays.js:137:5:137:25 | [DeclStmt] const arr = ... | semmle.label | 1 | +| arrays.js:136:3:140:3 | [BlockStmt] { c ... OK } | arrays.js:137:5:137:25 | [DeclStmt] const arr = ... | semmle.order | 1 | +| arrays.js:136:3:140:3 | [BlockStmt] { c ... OK } | arrays.js:138:5:138:56 | [DeclStmt] const element1 = ... | semmle.label | 2 | +| arrays.js:136:3:140:3 | [BlockStmt] { c ... OK } | arrays.js:138:5:138:56 | [DeclStmt] const element1 = ... | semmle.order | 2 | +| arrays.js:136:3:140:3 | [BlockStmt] { c ... OK } | arrays.js:139:5:139:19 | [ExprStmt] sink(element1); | semmle.label | 3 | +| arrays.js:136:3:140:3 | [BlockStmt] { c ... OK } | arrays.js:139:5:139:19 | [ExprStmt] sink(element1); | semmle.order | 3 | +| arrays.js:137:5:137:25 | [DeclStmt] const arr = ... | arrays.js:137:11:137:24 | [VariableDeclarator] arr = source() | semmle.label | 1 | +| arrays.js:137:5:137:25 | [DeclStmt] const arr = ... | arrays.js:137:11:137:24 | [VariableDeclarator] arr = source() | semmle.order | 1 | +| arrays.js:137:11:137:24 | [VariableDeclarator] arr = source() | arrays.js:137:11:137:13 | [VarDecl] arr | semmle.label | 1 | +| arrays.js:137:11:137:24 | [VariableDeclarator] arr = source() | arrays.js:137:11:137:13 | [VarDecl] arr | semmle.order | 1 | +| arrays.js:137:11:137:24 | [VariableDeclarator] arr = source() | arrays.js:137:17:137:24 | [CallExpr] source() | semmle.label | 2 | +| arrays.js:137:11:137:24 | [VariableDeclarator] arr = source() | arrays.js:137:17:137:24 | [CallExpr] source() | semmle.order | 2 | +| arrays.js:137:17:137:24 | [CallExpr] source() | arrays.js:137:17:137:22 | [VarRef] source | semmle.label | 0 | +| arrays.js:137:17:137:24 | [CallExpr] source() | arrays.js:137:17:137:22 | [VarRef] source | semmle.order | 0 | +| arrays.js:138:5:138:56 | [DeclStmt] const element1 = ... | arrays.js:138:11:138:55 | [VariableDeclarator] element ... (item)) | semmle.label | 1 | +| arrays.js:138:5:138:56 | [DeclStmt] const element1 = ... | arrays.js:138:11:138:55 | [VariableDeclarator] element ... (item)) | semmle.order | 1 | +| arrays.js:138:11:138:55 | [VariableDeclarator] element ... (item)) | arrays.js:138:11:138:18 | [VarDecl] element1 | semmle.label | 1 | +| arrays.js:138:11:138:55 | [VariableDeclarator] element ... (item)) | arrays.js:138:11:138:18 | [VarDecl] element1 | semmle.order | 1 | +| arrays.js:138:11:138:55 | [VariableDeclarator] element ... (item)) | arrays.js:138:22:138:55 | [MethodCallExpr] arr.fin ... (item)) | semmle.label | 2 | +| arrays.js:138:11:138:55 | [VariableDeclarator] element ... (item)) | arrays.js:138:22:138:55 | [MethodCallExpr] arr.fin ... (item)) | semmle.order | 2 | +| arrays.js:138:22:138:33 | [DotExpr] arr.findLast | arrays.js:138:22:138:24 | [VarRef] arr | semmle.label | 1 | +| arrays.js:138:22:138:33 | [DotExpr] arr.findLast | arrays.js:138:22:138:24 | [VarRef] arr | semmle.order | 1 | +| arrays.js:138:22:138:33 | [DotExpr] arr.findLast | arrays.js:138:26:138:33 | [Label] findLast | semmle.label | 2 | +| arrays.js:138:22:138:33 | [DotExpr] arr.findLast | arrays.js:138:26:138:33 | [Label] findLast | semmle.order | 2 | +| arrays.js:138:22:138:55 | [MethodCallExpr] arr.fin ... (item)) | arrays.js:138:22:138:33 | [DotExpr] arr.findLast | semmle.label | 0 | +| arrays.js:138:22:138:55 | [MethodCallExpr] arr.fin ... (item)) | arrays.js:138:22:138:33 | [DotExpr] arr.findLast | semmle.order | 0 | +| arrays.js:138:22:138:55 | [MethodCallExpr] arr.fin ... (item)) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:138:22:138:55 | [MethodCallExpr] arr.fin ... (item)) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:138:35:138:54 | [ArrowFunctionExpr] (item) => sink(item) | arrays.js:138:45:138:54 | [CallExpr] sink(item) | semmle.label | 5 | +| arrays.js:138:35:138:54 | [ArrowFunctionExpr] (item) => sink(item) | arrays.js:138:45:138:54 | [CallExpr] sink(item) | semmle.order | 5 | +| arrays.js:138:35:138:54 | [ArrowFunctionExpr] (item) => sink(item) | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| arrays.js:138:35:138:54 | [ArrowFunctionExpr] (item) => sink(item) | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| arrays.js:138:45:138:54 | [CallExpr] sink(item) | arrays.js:138:45:138:48 | [VarRef] sink | semmle.label | 0 | +| arrays.js:138:45:138:54 | [CallExpr] sink(item) | arrays.js:138:45:138:48 | [VarRef] sink | semmle.order | 0 | +| arrays.js:138:45:138:54 | [CallExpr] sink(item) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:138:45:138:54 | [CallExpr] sink(item) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:139:5:139:18 | [CallExpr] sink(element1) | arrays.js:139:5:139:8 | [VarRef] sink | semmle.label | 0 | +| arrays.js:139:5:139:18 | [CallExpr] sink(element1) | arrays.js:139:5:139:8 | [VarRef] sink | semmle.order | 0 | +| arrays.js:139:5:139:18 | [CallExpr] sink(element1) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:139:5:139:18 | [CallExpr] sink(element1) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:139:5:139:19 | [ExprStmt] sink(element1); | arrays.js:139:5:139:18 | [CallExpr] sink(element1) | semmle.label | 1 | +| arrays.js:139:5:139:19 | [ExprStmt] sink(element1); | arrays.js:139:5:139:18 | [CallExpr] sink(element1) | semmle.order | 1 | +| arrays.js:142:3:146:3 | [BlockStmt] { c ... OK } | arrays.js:143:5:143:25 | [DeclStmt] const arr = ... | semmle.label | 1 | +| arrays.js:142:3:146:3 | [BlockStmt] { c ... OK } | arrays.js:143:5:143:25 | [DeclStmt] const arr = ... | semmle.order | 1 | +| arrays.js:142:3:146:3 | [BlockStmt] { c ... OK } | arrays.js:144:5:144:61 | [DeclStmt] const element1 = ... | semmle.label | 2 | +| arrays.js:142:3:146:3 | [BlockStmt] { c ... OK } | arrays.js:144:5:144:61 | [DeclStmt] const element1 = ... | semmle.order | 2 | +| arrays.js:142:3:146:3 | [BlockStmt] { c ... OK } | arrays.js:145:5:145:19 | [ExprStmt] sink(element1); | semmle.label | 3 | +| arrays.js:142:3:146:3 | [BlockStmt] { c ... OK } | arrays.js:145:5:145:19 | [ExprStmt] sink(element1); | semmle.order | 3 | +| arrays.js:143:5:143:25 | [DeclStmt] const arr = ... | arrays.js:143:11:143:24 | [VariableDeclarator] arr = source() | semmle.label | 1 | +| arrays.js:143:5:143:25 | [DeclStmt] const arr = ... | arrays.js:143:11:143:24 | [VariableDeclarator] arr = source() | semmle.order | 1 | +| arrays.js:143:11:143:24 | [VariableDeclarator] arr = source() | arrays.js:143:11:143:13 | [VarDecl] arr | semmle.label | 1 | +| arrays.js:143:11:143:24 | [VariableDeclarator] arr = source() | arrays.js:143:11:143:13 | [VarDecl] arr | semmle.order | 1 | +| arrays.js:143:11:143:24 | [VariableDeclarator] arr = source() | arrays.js:143:17:143:24 | [CallExpr] source() | semmle.label | 2 | +| arrays.js:143:11:143:24 | [VariableDeclarator] arr = source() | arrays.js:143:17:143:24 | [CallExpr] source() | semmle.order | 2 | +| arrays.js:143:17:143:24 | [CallExpr] source() | arrays.js:143:17:143:22 | [VarRef] source | semmle.label | 0 | +| arrays.js:143:17:143:24 | [CallExpr] source() | arrays.js:143:17:143:22 | [VarRef] source | semmle.order | 0 | +| arrays.js:144:5:144:61 | [DeclStmt] const element1 = ... | arrays.js:144:11:144:60 | [VariableDeclarator] element ... (item)) | semmle.label | 1 | +| arrays.js:144:5:144:61 | [DeclStmt] const element1 = ... | arrays.js:144:11:144:60 | [VariableDeclarator] element ... (item)) | semmle.order | 1 | +| arrays.js:144:11:144:60 | [VariableDeclarator] element ... (item)) | arrays.js:144:11:144:18 | [VarDecl] element1 | semmle.label | 1 | +| arrays.js:144:11:144:60 | [VariableDeclarator] element ... (item)) | arrays.js:144:11:144:18 | [VarDecl] element1 | semmle.order | 1 | +| arrays.js:144:11:144:60 | [VariableDeclarator] element ... (item)) | arrays.js:144:22:144:60 | [MethodCallExpr] arr.fin ... (item)) | semmle.label | 2 | +| arrays.js:144:11:144:60 | [VariableDeclarator] element ... (item)) | arrays.js:144:22:144:60 | [MethodCallExpr] arr.fin ... (item)) | semmle.order | 2 | +| arrays.js:144:22:144:38 | [DotExpr] arr.findLastIndex | arrays.js:144:22:144:24 | [VarRef] arr | semmle.label | 1 | +| arrays.js:144:22:144:38 | [DotExpr] arr.findLastIndex | arrays.js:144:22:144:24 | [VarRef] arr | semmle.order | 1 | +| arrays.js:144:22:144:38 | [DotExpr] arr.findLastIndex | arrays.js:144:26:144:38 | [Label] findLastIndex | semmle.label | 2 | +| arrays.js:144:22:144:38 | [DotExpr] arr.findLastIndex | arrays.js:144:26:144:38 | [Label] findLastIndex | semmle.order | 2 | +| arrays.js:144:22:144:60 | [MethodCallExpr] arr.fin ... (item)) | arrays.js:144:22:144:38 | [DotExpr] arr.findLastIndex | semmle.label | 0 | +| arrays.js:144:22:144:60 | [MethodCallExpr] arr.fin ... (item)) | arrays.js:144:22:144:38 | [DotExpr] arr.findLastIndex | semmle.order | 0 | +| arrays.js:144:22:144:60 | [MethodCallExpr] arr.fin ... (item)) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:144:22:144:60 | [MethodCallExpr] arr.fin ... (item)) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:144:40:144:59 | [ArrowFunctionExpr] (item) => sink(item) | arrays.js:144:50:144:59 | [CallExpr] sink(item) | semmle.label | 5 | +| arrays.js:144:40:144:59 | [ArrowFunctionExpr] (item) => sink(item) | arrays.js:144:50:144:59 | [CallExpr] sink(item) | semmle.order | 5 | +| arrays.js:144:40:144:59 | [ArrowFunctionExpr] (item) => sink(item) | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| arrays.js:144:40:144:59 | [ArrowFunctionExpr] (item) => sink(item) | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| arrays.js:144:50:144:59 | [CallExpr] sink(item) | arrays.js:144:50:144:53 | [VarRef] sink | semmle.label | 0 | +| arrays.js:144:50:144:59 | [CallExpr] sink(item) | arrays.js:144:50:144:53 | [VarRef] sink | semmle.order | 0 | +| arrays.js:144:50:144:59 | [CallExpr] sink(item) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:144:50:144:59 | [CallExpr] sink(item) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:145:5:145:18 | [CallExpr] sink(element1) | arrays.js:145:5:145:8 | [VarRef] sink | semmle.label | 0 | +| arrays.js:145:5:145:18 | [CallExpr] sink(element1) | arrays.js:145:5:145:8 | [VarRef] sink | semmle.order | 0 | +| arrays.js:145:5:145:18 | [CallExpr] sink(element1) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:145:5:145:18 | [CallExpr] sink(element1) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:145:5:145:19 | [ExprStmt] sink(element1); | arrays.js:145:5:145:18 | [CallExpr] sink(element1) | semmle.label | 1 | +| arrays.js:145:5:145:19 | [ExprStmt] sink(element1); | arrays.js:145:5:145:18 | [CallExpr] sink(element1) | semmle.order | 1 | | file://:0:0:0:0 | (Arguments) | arrays.js:5:8:5:14 | [DotExpr] obj.foo | semmle.label | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:5:8:5:14 | [DotExpr] obj.foo | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:8:12:8:17 | [VarRef] source | semmle.label | 0 | @@ -1892,6 +2102,24 @@ edges | file://:0:0:0:0 | (Arguments) | arrays.js:127:55:127:58 | [VarRef] item | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:128:10:128:16 | [VarRef] element | semmle.label | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:128:10:128:16 | [VarRef] element | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:132:31:132:50 | [ArrowFunctionExpr] (item) => sink(item) | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:132:31:132:50 | [ArrowFunctionExpr] (item) => sink(item) | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:132:46:132:49 | [VarRef] item | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:132:46:132:49 | [VarRef] item | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:133:10:133:17 | [VarRef] element1 | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:133:10:133:17 | [VarRef] element1 | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:138:35:138:54 | [ArrowFunctionExpr] (item) => sink(item) | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:138:35:138:54 | [ArrowFunctionExpr] (item) => sink(item) | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:138:50:138:53 | [VarRef] item | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:138:50:138:53 | [VarRef] item | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:139:10:139:17 | [VarRef] element1 | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:139:10:139:17 | [VarRef] element1 | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:144:40:144:59 | [ArrowFunctionExpr] (item) => sink(item) | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:144:40:144:59 | [ArrowFunctionExpr] (item) => sink(item) | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:144:55:144:58 | [VarRef] item | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:144:55:144:58 | [VarRef] item | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:145:10:145:17 | [VarRef] element1 | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:145:10:145:17 | [VarRef] element1 | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:15:16:15:16 | [SimpleParameter] e | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:15:16:15:16 | [SimpleParameter] e | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:16:12:16:12 | [SimpleParameter] e | semmle.label | 0 | @@ -1916,5 +2144,11 @@ edges | file://:0:0:0:0 | (Parameters) | arrays.js:121:32:121:35 | [SimpleParameter] item | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:127:41:127:44 | [SimpleParameter] item | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:127:41:127:44 | [SimpleParameter] item | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | arrays.js:132:32:132:35 | [SimpleParameter] item | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | arrays.js:132:32:132:35 | [SimpleParameter] item | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | arrays.js:138:36:138:39 | [SimpleParameter] item | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | arrays.js:138:36:138:39 | [SimpleParameter] item | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | arrays.js:144:41:144:44 | [SimpleParameter] item | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | arrays.js:144:41:144:44 | [SimpleParameter] item | semmle.order | 0 | graphProperties | semmle.graphKind | tree | From 28ead4011abb59919d210f0faf1242ba7bf44946 Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 19 Nov 2024 14:15:15 +0100 Subject: [PATCH 088/470] JS: Add: taint step to handle propagation of data flow from the array to callback --- javascript/ql/lib/semmle/javascript/Arrays.qll | 15 ++++++++++++++- .../test/library-tests/Arrays/TaintFlow.expected | 3 +++ javascript/ql/test/library-tests/Arrays/arrays.js | 6 +++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/Arrays.qll b/javascript/ql/lib/semmle/javascript/Arrays.qll index c132fc9bc2a..95301820dc1 100644 --- a/javascript/ql/lib/semmle/javascript/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/Arrays.qll @@ -492,7 +492,20 @@ private module ArrayLibraries { exists(DataFlow::MethodCallNode call | call.getMethodName() = ["findLast", "find", "findLastIndex"] and prop = arrayLikeElement() and - obj = call.getReceiver() and + obj = call.getReceiver().getALocalSource() and + element = call.getCallback(0).getParameter(0) + ) + } + } + + /** + * This step models the propagation of data from the array to the callback function's parameter. + */ + private class ArrayCallBackDataTaintStep extends TaintTracking::SharedTaintStep { + override predicate step(DataFlow::Node obj, DataFlow::Node element) { + exists(DataFlow::MethodCallNode call | + call.getMethodName() = ["findLast", "find", "findLastIndex"] and + obj = call.getReceiver().getALocalSource() and element = call.getCallback(0).getParameter(0) ) } diff --git a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected index e17fe726d16..246a52e803b 100644 --- a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected @@ -35,5 +35,8 @@ | arrays.js:120:19:120:26 | "source" | arrays.js:121:46:121:49 | item | | arrays.js:120:19:120:26 | "source" | arrays.js:122:10:122:16 | element | | arrays.js:126:19:126:26 | "source" | arrays.js:127:55:127:58 | item | +| arrays.js:131:17:131:24 | source() | arrays.js:132:46:132:49 | item | | arrays.js:131:17:131:24 | source() | arrays.js:133:10:133:17 | element1 | +| arrays.js:137:17:137:24 | source() | arrays.js:138:50:138:53 | item | | arrays.js:137:17:137:24 | source() | arrays.js:139:10:139:17 | element1 | +| arrays.js:143:17:143:24 | source() | arrays.js:144:55:144:58 | item | diff --git a/javascript/ql/test/library-tests/Arrays/arrays.js b/javascript/ql/test/library-tests/Arrays/arrays.js index 862dae77967..deedf29f6f6 100644 --- a/javascript/ql/test/library-tests/Arrays/arrays.js +++ b/javascript/ql/test/library-tests/Arrays/arrays.js @@ -129,19 +129,19 @@ } { const arr = source(); - const element1 = arr.find((item) => sink(item)); // NOT OK - only found with taint-tracking. + const element1 = arr.find((item) => sink(item)); // NOT OK sink(element1); // NOT OK } { const arr = source(); - const element1 = arr.findLast((item) => sink(item)); // NOT OK - only found with taint-tracking. + const element1 = arr.findLast((item) => sink(item)); // NOT OK sink(element1); // NOT OK } { const arr = source(); - const element1 = arr.findLastIndex((item) => sink(item)); // NOT OK - only found with taint-tracking. + const element1 = arr.findLastIndex((item) => sink(item)); // NOT OK sink(element1); // OK } }); From a4ccda5fe3eecbb35ae2769494b7415e83547e11 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 19 Nov 2024 13:45:47 +0000 Subject: [PATCH 089/470] Python: Fix pruning of literals in `match` pattern Co-authored-by: yoff --- .../extractor/semmle/python/passes/pruner.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/python/extractor/semmle/python/passes/pruner.py b/python/extractor/semmle/python/passes/pruner.py index d6363e529f1..fe3b03d453c 100644 --- a/python/extractor/semmle/python/passes/pruner.py +++ b/python/extractor/semmle/python/passes/pruner.py @@ -196,6 +196,25 @@ class SkippedVisitor(ASTVisitor): if isinstance(node.value, ast.Name): self.nodes.add(node.value) +class NotBooleanTestVisitor(ASTVisitor): + """Visitor that checks if a test is not a boolean test.""" + + def __init__(self): + self.nodes = set() + + def visit_MatchLiteralPattern(self, node): + # MatchLiteralPatterns _look_ like boolean tests, but are not. + # Thus, without this check, we would interpret + # + # match x: + # case False: + # pass + # + # (and similarly for True) as if it was a boolean test. This would cause the true edge + # (leading to pass) to be pruned later on. + if isinstance(node.literal, ast.Name) and node.literal.id in ('True', 'False'): + self.nodes.add(node.literal) + class NonlocalVisitor(ASTVisitor): def __init__(self): self.names = set() @@ -306,6 +325,8 @@ def effective_constants_definitions(bool_const_defns, graph, branching_edges): def do_pruning(tree, graph): v = BoolConstVisitor() v.visit(tree) + not_boolean_test = NotBooleanTestVisitor() + not_boolean_test.visit(tree) nonlocals = NonlocalVisitor() nonlocals.visit(tree) global_vars = GlobalVisitor() @@ -353,6 +374,8 @@ def do_pruning(tree, graph): b = const_value(pred.node) if b is None: continue + if pred.node in not_boolean_test.nodes: + continue if b.contradicts(val): to_be_removed.add((pred, succ)) if not to_be_removed: From 358098230ce09bcbbd04146d4a6443e600c119d1 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 19 Nov 2024 14:58:21 +0100 Subject: [PATCH 090/470] C#: Address review comment from previous PR. --- csharp/ql/integration-tests/all-platforms/dotnet_build/test.py | 1 - 1 file changed, 1 deletion(-) diff --git a/csharp/ql/integration-tests/all-platforms/dotnet_build/test.py b/csharp/ql/integration-tests/all-platforms/dotnet_build/test.py index c32d966acb4..75ba09477fa 100644 --- a/csharp/ql/integration-tests/all-platforms/dotnet_build/test.py +++ b/csharp/ql/integration-tests/all-platforms/dotnet_build/test.py @@ -1,7 +1,6 @@ import os def check_build_out(msg, s): - lines = s.splitlines() lines = s.splitlines() assert ( any (("[build-stdout]" in line) and (msg in line) for line in lines) From e2530cf14fcf3a2cad2bce06017c4dbeeba49a96 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 19 Nov 2024 14:10:50 +0000 Subject: [PATCH 091/470] Python: Update expected test output Co-authored-by: yoff --- .../query-tests/Statements/unreachable/UnreachableCode.expected | 2 -- 1 file changed, 2 deletions(-) diff --git a/python/ql/test/query-tests/Statements/unreachable/UnreachableCode.expected b/python/ql/test/query-tests/Statements/unreachable/UnreachableCode.expected index 013d7a0fe68..2417041f472 100644 --- a/python/ql/test/query-tests/Statements/unreachable/UnreachableCode.expected +++ b/python/ql/test/query-tests/Statements/unreachable/UnreachableCode.expected @@ -4,5 +4,3 @@ | test.py:21:5:21:38 | For | This statement is unreachable. | | test.py:28:9:28:21 | ExprStmt | This statement is unreachable. | | test.py:84:5:84:21 | ExceptStmt | This statement is unreachable. | -| test.py:144:13:144:16 | Pass | This statement is unreachable. | -| test.py:147:9:148:16 | Case | This statement is unreachable. | From 1c874d32217994a6faae1d2a24d07d19a3a52af2 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 19 Nov 2024 10:04:11 -0500 Subject: [PATCH 092/470] Fixed usage raisesException --- .../cpp/ir/implementation/raw/internal/TranslatedCall.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index a4c67886959..5f1b2fbe3b4 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -363,11 +363,11 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { } final override predicate mayThrowException() { - expr.getTarget().(ThrowingFunction).mayRaiseException() + expr.getTarget().(ThrowingFunction).raisesException(_) } final override predicate mustThrowException() { - expr.getTarget().(ThrowingFunction).alwaysRaisesException() + expr.getTarget().(ThrowingFunction).raisesException(true) } } From 54e7db229474bab6df51094222e74b6960b218af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Thu, 14 Nov 2024 14:54:44 +0100 Subject: [PATCH 093/470] BigInt GA: s/arbitrary-precision/arbitrary-range/g in .rst docs --- docs/codeql/ql-language-reference/modules.rst | 2 +- docs/codeql/ql-language-reference/ql-language-specification.rst | 2 +- docs/codeql/ql-language-reference/types.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/codeql/ql-language-reference/modules.rst b/docs/codeql/ql-language-reference/modules.rst index 75b61667246..b7a353b8ccb 100644 --- a/docs/codeql/ql-language-reference/modules.rst +++ b/docs/codeql/ql-language-reference/modules.rst @@ -431,7 +431,7 @@ The above query therefore evalutes to: BigInt ====== -The built-in ``QlBuiltins`` module provides an **experimental** type ``BigInt`` of arbitrary-precision integers. +The built-in ``QlBuiltins`` module provides an **experimental** type ``BigInt`` of arbitrary-range integers. This type is not available in the CodeQL CLI by default, but you can enable it by passing the ``--allow-experimental=bigint`` option to the CodeQL CLI. Consequently, BigInts are currently disallowed in query results and dbscheme columns. diff --git a/docs/codeql/ql-language-reference/ql-language-specification.rst b/docs/codeql/ql-language-reference/ql-language-specification.rst index 60e5ece7330..4c8fd30076a 100644 --- a/docs/codeql/ql-language-reference/ql-language-specification.rst +++ b/docs/codeql/ql-language-reference/ql-language-specification.rst @@ -445,7 +445,7 @@ An integer value is of type ``int``. Each value is a 32-bit two's complement int A string is a finite sequence of 16-bit characters. The characters are interpreted as Unicode code points. -A :ref:`big integer ` value is of type ``QlBuiltins::BigInt``. Each value is a signed arbitrary-precision integer. +A :ref:`big integer ` value is of type ``QlBuiltins::BigInt``. Each value is a signed arbitrary-range integer. The database includes a number of opaque entity values. Each such value has a type that is one of the database types, and an identifying integer. An entity value is written as the name of its database type followed by its identifying integer in parentheses. For example, ``@tree(12)``, ``@person(16)``, and ``@location(38132)`` are entity values. The identifying integers are left opaque to programmers in this specification, so an implementation of QL is free to use some other set of countable labels to identify its entities. diff --git a/docs/codeql/ql-language-reference/types.rst b/docs/codeql/ql-language-reference/types.rst index e14f542dcf8..caafc039622 100644 --- a/docs/codeql/ql-language-reference/types.rst +++ b/docs/codeql/ql-language-reference/types.rst @@ -52,7 +52,7 @@ independent of the database that you are querying. QL has a range of built-in operations defined on primitive types. These are available by using dispatch on expressions of the appropriate type. For example, ``1.toString()`` is the string representation of the integer constant ``1``. For a full list of built-in operations available in QL, see the section on `built-ins `__ in the QL language specification. -Additionally, there is an experimental arbitrary-precision integer primitive type at :ref:`QlBuiltins::BigInt `. This type is not available in the CodeQL CLI by default, but you can enable it by passing the ``--allow-experimental=bigint`` option to the CodeQL CLI. +Additionally, there is an experimental arbitrary-range integer primitive type at :ref:`QlBuiltins::BigInt `. This type is not available in the CodeQL CLI by default, but you can enable it by passing the ``--allow-experimental=bigint`` option to the CodeQL CLI. .. index:: class .. _classes: From 2da1d6aaa8aa2fa67e640e7e7627c33aee4f70ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Thu, 14 Nov 2024 15:16:13 +0100 Subject: [PATCH 094/470] BigInt GA: remove mention of experimental status from .rst docs --- docs/codeql/ql-language-reference/modules.rst | 7 +++---- docs/codeql/ql-language-reference/types.rst | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/codeql/ql-language-reference/modules.rst b/docs/codeql/ql-language-reference/modules.rst index b7a353b8ccb..d0cbdd39e36 100644 --- a/docs/codeql/ql-language-reference/modules.rst +++ b/docs/codeql/ql-language-reference/modules.rst @@ -431,10 +431,7 @@ The above query therefore evalutes to: BigInt ====== -The built-in ``QlBuiltins`` module provides an **experimental** type ``BigInt`` of arbitrary-range integers. - -This type is not available in the CodeQL CLI by default, but you can enable it by passing the ``--allow-experimental=bigint`` -option to the CodeQL CLI. Consequently, BigInts are currently disallowed in query results and dbscheme columns. +The built-in ``QlBuiltins`` module provides a type ``BigInt`` of arbitrary-range integers. Unlike ``int`` and ``float``, there is no automatic conversion between ``BigInt`` and other numeric types. Instead, big integers can be constructed using the ``.toBigInt()`` methods of ``int`` and ``string``. @@ -451,3 +448,5 @@ The other built-in operations are: ``rank``, ``unique``, ``any``. * other: ``.pow(int)``, ``.abs()``, ``.gcd(BigInt)``, ``.minimum(BigInt)``, ``.maximum(BigInt)``. + +Note: big integers are currently disallowed in query results and dbscheme columns. diff --git a/docs/codeql/ql-language-reference/types.rst b/docs/codeql/ql-language-reference/types.rst index caafc039622..d2d79fe8409 100644 --- a/docs/codeql/ql-language-reference/types.rst +++ b/docs/codeql/ql-language-reference/types.rst @@ -52,7 +52,7 @@ independent of the database that you are querying. QL has a range of built-in operations defined on primitive types. These are available by using dispatch on expressions of the appropriate type. For example, ``1.toString()`` is the string representation of the integer constant ``1``. For a full list of built-in operations available in QL, see the section on `built-ins `__ in the QL language specification. -Additionally, there is an experimental arbitrary-range integer primitive type at :ref:`QlBuiltins::BigInt `. This type is not available in the CodeQL CLI by default, but you can enable it by passing the ``--allow-experimental=bigint`` option to the CodeQL CLI. +Additionally, there is an arbitrary-range integer primitive type at :ref:`QlBuiltins::BigInt `. .. index:: class .. _classes: From 0fc46f58558fe269affd73f1ad8973a55cbbcf04 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 19 Nov 2024 16:30:48 +0100 Subject: [PATCH 095/470] C#: Fix compiler warnings related to errors in XML comments. --- .../Semmle.Autobuild.CSharp/AutoBuildRule.cs | 8 ++--- .../Semmle.Autobuild.Shared/Autobuilder.cs | 4 +-- .../Semmle.Autobuild.Shared/MarkdownUtil.cs | 4 +-- .../Assets.cs | 30 +++++++++---------- .../DotNetVersion.cs | 2 +- .../FileContent.cs | 4 +-- .../IDotNetCliInvoker.cs | 6 ++-- .../SymbolExtensions.cs | 15 ++++------ .../Entities/Base/CachedEntity.cs | 2 +- .../Entities/Base/IEntity.cs | 8 ++--- .../Entities/Expression.cs | 5 +--- .../Entities/Expression`1.cs | 2 +- .../Entities/Types/NamedType.cs | 5 ++-- .../Entities/Types/Nullability.cs | 4 +-- .../Entities/UserOperator.cs | 2 +- .../Extractor/Context.cs | 3 +- .../Extractor/TrapWriter.cs | 2 +- .../Trap/EscapingTextWriter.cs | 2 +- .../Trap/TrapExtensions.cs | 4 +-- .../Semmle.Util/CanonicalPathCache.cs | 3 +- .../extractor/Semmle.Util/CommandBuilder.cs | 1 - 21 files changed, 52 insertions(+), 64 deletions(-) diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/AutoBuildRule.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/AutoBuildRule.cs index e58c8ddccd9..b3efe64b7e9 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/AutoBuildRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/AutoBuildRule.cs @@ -49,11 +49,9 @@ namespace Semmle.Autobuild.CSharp tryCleanExtractorArgsLogs & BuildScript.DeleteFile(Extractor.GetCSharpLogPath()); - /// - /// Execute script `s` and check that the C# extractor has been executed. - /// If either fails, attempt to cleanup any artifacts produced by the extractor, - /// and exit with code 1, in order to proceed to the next attempt. - /// + // Execute script `s` and check that the C# extractor has been executed. + // If either fails, attempt to cleanup any artifacts produced by the extractor, + // and exit with code 1, in order to proceed to the next attempt. BuildScript IntermediateAttempt(BuildScript s) => (s & this.autobuilder.CheckExtractorRun(false)) | (attemptExtractorCleanup & BuildScript.Failure); diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs index 371352cf5e2..919e3821750 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs @@ -195,7 +195,7 @@ namespace Semmle.Autobuild.Shared } /// - /// Retrieves the value of an environment variable named or throws + /// Retrieves the value of an environment variable named or throws /// an exception if no such environment variable has been set. /// /// The name of the environment variable. @@ -228,7 +228,7 @@ namespace Semmle.Autobuild.Shared private readonly IDiagnosticsWriter diagnostics; /// - /// Makes relative to the root source directory. + /// Makes relative to the root source directory. /// /// The path which to make relative. /// The relative path. diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/MarkdownUtil.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/MarkdownUtil.cs index 13a3533eb31..f5721910a96 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/MarkdownUtil.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/MarkdownUtil.cs @@ -22,7 +22,7 @@ namespace Semmle.Autobuild.Shared public static string ToMarkdownLink(this string link, string title) => $"[{title}]({link})"; /// - /// Renders as a markdown list of the project paths. + /// Renders as a markdown list of the project paths. /// /// /// The list of projects whose paths should be rendered as a markdown list. @@ -35,7 +35,7 @@ namespace Semmle.Autobuild.Shared } /// - /// Renders as a markdown list. + /// Renders as a markdown list. /// /// The item type. /// The list that should be formatted as a markdown list. diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs index 4a6b401038e..13235ba1988 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs @@ -127,21 +127,21 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// /// Example: /// "project": { - // "version": "1.0.0", - // "frameworks": { - // "net7.0": { - // "frameworkReferences": { - // "Microsoft.AspNetCore.App": { - // "privateAssets": "none" - // }, - // "Microsoft.NETCore.App": { - // "privateAssets": "all" - // } - // } - // } - // } - // } - // + /// "version": "1.0.0", + /// "frameworks": { + /// "net7.0": { + /// "frameworkReferences": { + /// "Microsoft.AspNetCore.App": { + /// "privateAssets": "none" + /// }, + /// "Microsoft.NETCore.App": { + /// "privateAssets": "all" + /// } + /// } + /// } + /// } + /// } + /// /// Adds the following dependencies /// Paths: { /// "microsoft.aspnetcore.app.ref", diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetVersion.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetVersion.cs index f62c279d240..b4273d02b77 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetVersion.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetVersion.cs @@ -27,7 +27,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching * This is the same as FullPath, except that we assume that the * reference assemblies are in a directory called "packs" and * the reference assemblies themselves are in a directory called - * ".Ref/ref". + * "[Framework].Ref/ref". * Example: * FullPath: /usr/share/dotnet/shared/Microsoft.NETCore.App/7.0.2 * FullPathReferenceAssemblies: /usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/7.0.2/ref diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileContent.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileContent.cs index f33329046cf..f5199de1c13 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileContent.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileContent.cs @@ -38,8 +38,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// True if any file in the source directory indicates that ASP.NET Core is used. /// The following heuristic is used to decide, if ASP.NET Core is used: /// If any file in the source directory contains something like (this will most like be a .csproj file) - /// - /// + /// <Project Sdk="Microsoft.NET.Sdk.Web"> + /// <FrameworkReference Include="Microsoft.AspNetCore.App"/> /// public bool UseAspNetCoreDlls { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs index bfc8b44ee56..89631ffa861 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs @@ -10,20 +10,20 @@ namespace Semmle.Extraction.CSharp.DependencyFetching string Exec { get; } /// - /// Execute `dotnet ` and return true if the command succeeded, otherwise false. + /// Execute `dotnet ` and return true if the command succeeded, otherwise false. /// If `silent` is true the output of the command is logged as `debug` otherwise as `info`. /// bool RunCommand(string args, bool silent = true); /// - /// Execute `dotnet ` and return true if the command succeeded, otherwise false. + /// Execute `dotnet ` and return true if the command succeeded, otherwise false. /// The output of the command is returned in `output`. /// If `silent` is true the output of the command is logged as `debug` otherwise as `info`. /// bool RunCommand(string args, out IList output, bool silent = true); /// - /// Execute `dotnet ` in `` and return true if the command succeeded, otherwise false. + /// Execute `dotnet ` in `` and return true if the command succeeded, otherwise false. /// The output of the command is returned in `output`. /// If `silent` is true the output of the command is logged as `debug` otherwise as `info`. /// diff --git a/csharp/extractor/Semmle.Extraction.CSharp/CodeAnalysisExtensions/SymbolExtensions.cs b/csharp/extractor/Semmle.Extraction.CSharp/CodeAnalysisExtensions/SymbolExtensions.cs index 2ffdd9dbcd6..72c45b797d8 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/CodeAnalysisExtensions/SymbolExtensions.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/CodeAnalysisExtensions/SymbolExtensions.cs @@ -133,9 +133,6 @@ namespace Semmle.Extraction.CSharp /// /// Constructs a unique string for this type symbol. - /// - /// The supplied action is applied to the - /// syntactic sub terms of this type (if any). /// /// The extraction context. /// The trap builder used to store the result. @@ -495,31 +492,31 @@ namespace Semmle.Extraction.CSharp /// /// Holds if this type is of the form int? or - /// System.Nullable. + /// System.Nullable<int>. /// public static bool IsBoundNullable(this ITypeSymbol type) => type.SpecialType == SpecialType.None && type.OriginalDefinition.IsUnboundNullable(); /// - /// Holds if this type is System.Nullable. + /// Holds if this type is System.Nullable<T>. /// public static bool IsUnboundNullable(this ITypeSymbol type) => type.SpecialType == SpecialType.System_Nullable_T; /// - /// Holds if this type is System.Span. + /// Holds if this type is System.Span<T>. /// public static bool IsUnboundSpan(this ITypeSymbol type) => type.ToString() == "System.Span"; /// - /// Holds if this type is of the form System.Span. + /// Holds if this type is of the form System.Span<byte>. /// public static bool IsBoundSpan(this ITypeSymbol type) => type.SpecialType == SpecialType.None && type.OriginalDefinition.IsUnboundSpan(); /// - /// Holds if this type is System.ReadOnlySpan. + /// Holds if this type is System.ReadOnlySpan<T>. /// public static bool IsUnboundReadOnlySpan(this ITypeSymbol type) => type.ToString() == "System.ReadOnlySpan"; @@ -536,7 +533,7 @@ namespace Semmle.Extraction.CSharp } /// - /// Holds if this type is of the form System.ReadOnlySpan. + /// Holds if this type is of the form System.ReadOnlySpan<byte>. /// public static bool IsBoundReadOnlySpan(this ITypeSymbol type) => type.SpecialType == SpecialType.None && type.OriginalDefinition.IsUnboundReadOnlySpan(); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Base/CachedEntity.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Base/CachedEntity.cs index ed0a21bc083..96bef973211 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Base/CachedEntity.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Base/CachedEntity.cs @@ -7,7 +7,7 @@ namespace Semmle.Extraction.CSharp.Entities /// /// A cached entity. /// - /// The property is used as label in caching. + /// The property is used as label in caching. /// public abstract class CachedEntity : LabelledEntity { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Base/IEntity.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Base/IEntity.cs index d8d3c538e42..f6f60ff9146 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Base/IEntity.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Base/IEntity.cs @@ -9,12 +9,12 @@ namespace Semmle.Extraction.CSharp /// Entities are divided into two types: normal entities and cached /// entities. /// - /// Normal entities implement directly, and they + /// Normal entities implement directly, and they /// (may) emit contents to the trap file during object construction. /// - /// Cached entities implement , and they - /// emit contents to the trap file when - /// is called. Caching prevents + /// Cached entities implement , and they + /// emit contents to the trap file when + /// is called. Caching prevents /// from being called on entities that have already been emitted. /// public interface IEntity diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs index f5021d38eeb..9241528eb75 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs @@ -77,7 +77,7 @@ namespace Semmle.Extraction.CSharp.Entities /// /// Gets a string representation of a constant value. /// - /// The value. + /// The value. /// The string representation. public static string ValueAsString(object? value) { @@ -98,7 +98,6 @@ namespace Semmle.Extraction.CSharp.Entities /// The node to extract. /// The parent entity. /// The child index. - /// A type hint. /// The new expression. public static Expression Create(Context cx, ExpressionSyntax node, IExpressionParentEntity parent, int child, Boolean isCompilerGenerated = false) { @@ -120,7 +119,6 @@ namespace Semmle.Extraction.CSharp.Entities /// The node to extract. /// The parent entity. /// The child index. - /// A type hint. public static void CreateDeferred(Context cx, ExpressionSyntax node, IExpressionParentEntity parent, int child) { if (ContainsPattern(node)) @@ -244,7 +242,6 @@ namespace Semmle.Extraction.CSharp.Entities /// to show the target of the call. Also note the dynamic method /// name if available. /// - /// Context /// The expression. public void OperatorCall(TextWriter trapFile, ExpressionSyntax node) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression`1.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression`1.cs index 6386e43a9b4..4c2670369e0 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression`1.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression`1.cs @@ -20,7 +20,7 @@ namespace Semmle.Extraction.CSharp.Entities /// expressions and expr_location are populated by the constructor /// (should not fail), so even if expression-type specific population fails (e.g., in /// standalone extraction), the expression created via - /// will + /// will /// still be valid. /// protected abstract void PopulateExpression(TextWriter trapFile); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NamedType.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NamedType.cs index 189a07f6f47..b2106febaff 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NamedType.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NamedType.cs @@ -21,10 +21,9 @@ namespace Semmle.Extraction.CSharp.Entities NamedTypeFactory.Instance.CreateEntityFromSymbol(cx, type); /// - /// Creates a named type entity from a tuple type. Unlike `Create`, this + /// Creates a named type entity from a tuple type. Unlike , this /// will create an entity for the underlying `System.ValueTuple` struct. - /// For example, `(int, string)` will result in an entity for - /// `System.ValueTuple`. + /// For example, `(int, string)` will result in an entity for `System.ValueTuple<int, string>`. /// public static NamedType CreateNamedTypeFromTupleType(Context cx, INamedTypeSymbol type) => UnderlyingTupleTypeFactory.Instance.CreateEntity(cx, (new SymbolEqualityWrapper(type), typeof(TupleType)), type); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Nullability.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Nullability.cs index 9791f386a19..add36226f16 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Nullability.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Nullability.cs @@ -209,8 +209,8 @@ namespace Semmle.Extraction.CSharp.Entities /// This is so that we can avoid populating nullability in most cases. /// For example, /// - /// IEnumerable<string?> // false - /// IEnumerable<string?>? // true + /// IEnumerable<string?> // false + /// IEnumerable<string?>? // true /// string? // true /// string[] // true /// string?[] // false diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs index f2fc4b85d7f..141bded87ac 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs @@ -86,7 +86,7 @@ namespace Semmle.Extraction.CSharp.Entities /// Logs an error if the name is not found. /// /// Extractor context. - /// The method name. + /// The method symbol. /// The converted name. private static string OperatorSymbol(Context cx, IMethodSymbol method) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Context.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Context.cs index 8d819d715f9..67bb2808ae6 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Context.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Context.cs @@ -152,7 +152,7 @@ namespace Semmle.Extraction.CSharp /// /// Enqueue the given action to be performed later. /// - /// The action to run. + /// The action to run. public void PopulateLater(Action a, bool preserveDuplicationKey = true) { var key = preserveDuplicationKey ? GetCurrentTagStackKey() : null; @@ -598,7 +598,6 @@ namespace Semmle.Extraction.CSharp /// /// Register a program entity which can be bound to comments. /// - /// Extractor context. /// Program entity. /// Location of the entity. public void BindComments(Entity entity, Microsoft.CodeAnalysis.Location? l) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TrapWriter.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TrapWriter.cs index 4830c3209c2..42e933c8eaf 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TrapWriter.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TrapWriter.cs @@ -171,7 +171,7 @@ namespace Semmle.Extraction.CSharp /// /// Close the trap file, and move it to the right place in the trap directory. /// If the file exists already, rename it to allow the new file (ending .trap.gz) - /// to sit alongside the old file (except if is true, + /// to sit alongside the old file (except if is true, /// in which case only the existing file is kept). /// public void Dispose() diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Trap/EscapingTextWriter.cs b/csharp/extractor/Semmle.Extraction.CSharp/Trap/EscapingTextWriter.cs index 63f5e81c358..28e1d0bf146 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Trap/EscapingTextWriter.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Trap/EscapingTextWriter.cs @@ -8,7 +8,7 @@ namespace Semmle.Extraction.CSharp { /// /// A `TextWriter` object that wraps another `TextWriter` object, and which - /// HTML escapes the characters `&`, `{`, `}`, `"`, `@`, and `#`, before + /// HTML escapes the characters &, {, }, ", @, and #, before /// writing to the underlying object. /// public sealed class EscapingTextWriter : TextWriter diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Trap/TrapExtensions.cs b/csharp/extractor/Semmle.Extraction.CSharp/Trap/TrapExtensions.cs index 787ba62e3e8..22e38bac51c 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Trap/TrapExtensions.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Trap/TrapExtensions.cs @@ -226,7 +226,7 @@ namespace Semmle.Extraction.CSharp /// /// Builds a trap builder using a separator and an action for each item in the list. /// - /// The type of the items. + /// The type of the items. /// The trap builder to append to. /// The separator string (e.g. ",") /// The list of items. @@ -251,7 +251,7 @@ namespace Semmle.Extraction.CSharp /// /// Builds a trap builder using a separator and an action for each item in the list. /// - /// The type of the items. + /// The type of the items. /// The trap builder to append to. /// The separator string (e.g. ",") /// The list of items. diff --git a/csharp/extractor/Semmle.Util/CanonicalPathCache.cs b/csharp/extractor/Semmle.Util/CanonicalPathCache.cs index a79854333ac..d3cbf41fa10 100644 --- a/csharp/extractor/Semmle.Util/CanonicalPathCache.cs +++ b/csharp/extractor/Semmle.Util/CanonicalPathCache.cs @@ -208,7 +208,7 @@ namespace Semmle.Util /// Create cache with a given capacity. /// /// The algorithm for determining the canonical path. - /// The size of the cache. + /// The size of the cache. public CanonicalPathCache(int maxCapacity, PathStrategy pathStrategy) { if (maxCapacity <= 0) @@ -230,7 +230,6 @@ namespace Semmle.Util /// /// /// Size of the cache. - /// Policy for following symlinks. /// A new CanonicalPathCache. public static CanonicalPathCache Create(ILogger logger, int maxCapacity) { diff --git a/csharp/extractor/Semmle.Util/CommandBuilder.cs b/csharp/extractor/Semmle.Util/CommandBuilder.cs index 3d8f907f866..1b6cd3176c4 100644 --- a/csharp/extractor/Semmle.Util/CommandBuilder.cs +++ b/csharp/extractor/Semmle.Util/CommandBuilder.cs @@ -62,7 +62,6 @@ namespace Semmle.Util /// /// The argument to append. /// Whether to always quote the argument. - /// Whether to escape for cmd.exe /// /// /// This implementation is copied from From 3b01efaf5da256749779599b2d19eac4f3c8ee69 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 19 Nov 2024 17:08:08 +0100 Subject: [PATCH 096/470] C#: Update launch.json. --- csharp/.vscode/launch.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/csharp/.vscode/launch.json b/csharp/.vscode/launch.json index 46858861047..1f598f5e44f 100644 --- a/csharp/.vscode/launch.json +++ b/csharp/.vscode/launch.json @@ -6,7 +6,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "dotnet: build", - "program": "${workspaceFolder}/extractor/Semmle.Extraction.CSharp.Standalone/bin/Debug/net8.0/Semmle.Extraction.CSharp.Standalone.dll", + "program": "${workspaceFolder}/extractor/Semmle.Extraction.CSharp.Standalone/bin/Debug/net9.0/Semmle.Extraction.CSharp.Standalone.dll", "args": [], // Set the path to the folder that should be extracted: "cwd": "${workspaceFolder}/ql/test/library-tests/standalone/standalonemode", @@ -35,7 +35,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "dotnet: build", - "program": "${workspaceFolder}/autobuilder/Semmle.Autobuild.CSharp/bin/Debug/net8.0/Semmle.Autobuild.CSharp.dll", + "program": "${workspaceFolder}/autobuilder/Semmle.Autobuild.CSharp/bin/Debug/net9.0/Semmle.Autobuild.CSharp.dll", // Set the path to the folder that should be extracted: "cwd": "${workspaceFolder}/ql/integration-tests/all-platforms/autobuild", "stopAtEntry": true, @@ -53,7 +53,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "dotnet: build", - "program": "${workspaceFolder}/extractor/Semmle.Extraction.CSharp.Driver/bin/Debug/net8.0/Semmle.Extraction.CSharp.Driver.dll", + "program": "${workspaceFolder}/extractor/Semmle.Extraction.CSharp.Driver/bin/Debug/net9.0/Semmle.Extraction.CSharp.Driver.dll", "stopAtEntry": true, "args": [ "--binlog", From a709fc6a54a4c2f0348d9a3c0a7740472a8ad84b Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 19 Nov 2024 17:20:25 +0100 Subject: [PATCH 097/470] Rust: add some `toString` implementations --- rust/ql/.generated.list | 42 ------------------- rust/ql/.gitattributes | 42 ------------------- .../rust/elements/internal/ArrayExprImpl.qll | 6 ++- .../rust/elements/internal/AwaitExprImpl.qll | 6 ++- .../rust/elements/internal/BecomeExprImpl.qll | 6 ++- .../rust/elements/internal/BlockExprImpl.qll | 6 ++- .../rust/elements/internal/BoxPatImpl.qll | 6 ++- .../rust/elements/internal/BreakExprImpl.qll | 12 ++++++ .../rust/elements/internal/CallExprImpl.qll | 6 ++- .../rust/elements/internal/CastExprImpl.qll | 6 ++- .../elements/internal/ClosureExprImpl.qll | 6 ++- .../rust/elements/internal/CommentImpl.qll | 9 ++++ .../elements/internal/ContinueExprImpl.qll | 11 +++++ .../rust/elements/internal/EnumImpl.qll | 6 ++- .../rust/elements/internal/FieldExprImpl.qll | 6 ++- .../rust/elements/internal/FunctionImpl.qll | 2 +- .../rust/elements/internal/IfExprImpl.qll | 11 ++++- .../rust/elements/internal/ImplImpl.qll | 15 ++++++- .../rust/elements/internal/IndexExprImpl.qll | 6 ++- .../rust/elements/internal/LabelImpl.qll | 6 ++- .../rust/elements/internal/LetElseImpl.qll | 6 ++- .../rust/elements/internal/LetExprImpl.qll | 11 ++++- .../rust/elements/internal/LetStmtImpl.qll | 12 +++++- .../rust/elements/internal/LifetimeImpl.qll | 6 ++- .../rust/elements/internal/LiteralPatImpl.qll | 6 ++- .../rust/elements/internal/LoopExprImpl.qll | 6 ++- .../rust/elements/internal/MacroCallImpl.qll | 6 ++- .../rust/elements/internal/MatchArmImpl.qll | 11 ++++- .../rust/elements/internal/MatchExprImpl.qll | 2 + .../rust/elements/internal/ModuleImpl.qll | 6 ++- .../rust/elements/internal/NeverTypeImpl.qll | 6 ++- .../rust/elements/internal/OrPatImpl.qll | 2 + .../rust/elements/internal/ParamImpl.qll | 8 +++- .../rust/elements/internal/ParenExprImpl.qll | 6 ++- .../rust/elements/internal/ParenPatImpl.qll | 6 ++- .../rust/elements/internal/ParenTypeImpl.qll | 6 ++- .../rust/elements/internal/PathPatImpl.qll | 6 ++- .../rust/elements/internal/PathTypeImpl.qll | 6 ++- .../rust/elements/internal/RangeExprImpl.qll | 6 ++- .../elements/internal/RecordExprFieldImpl.qll | 11 ++++- .../rust/elements/internal/RecordExprImpl.qll | 6 ++- .../rust/elements/internal/RecordPatImpl.qll | 6 ++- .../rust/elements/internal/RefExprImpl.qll | 13 +++++- .../rust/elements/internal/RefPatImpl.qll | 11 ++++- .../rust/elements/internal/RestPatImpl.qll | 6 ++- .../rust/elements/internal/ReturnExprImpl.qll | 8 +++- .../rust/elements/internal/TraitImpl.qll | 6 ++- .../elements/internal/UnderscoreExprImpl.qll | 6 ++- .../rust/elements/internal/WhileExprImpl.qll | 6 ++- .../elements/internal/WildcardPatImpl.qll | 6 ++- 50 files changed, 256 insertions(+), 169 deletions(-) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index ca25e0533fc..a26f1d4155e 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -169,7 +169,6 @@ lib/codeql/rust/elements/internal/AbiImpl.qll 01439712ecadc9dc8da6f74d2e19cee13c lib/codeql/rust/elements/internal/ArgListConstructor.qll a73685c8792ae23a2d628e7357658efb3f6e34006ff6e9661863ef116ec0b015 0bee572a046e8dfc031b1216d729843991519d94ae66280f5e795d20aea07a22 lib/codeql/rust/elements/internal/ArgListImpl.qll 19664651c06b46530f0ae5745ccb3233afc97b9152e053761d641de6e9c62d38 40af167e571f5c255f264b3be7cc7f5ff42ec109661ca03dcee94e92f8facfc6 lib/codeql/rust/elements/internal/ArrayExprConstructor.qll f4ac4efefe5fe4fe1e666f35b1ee92d2243d977b3f3308151c89f61582203c09 4167ae58ec869f7dbd8467093c4a53afd7c1efcf1cc865efa62b4eb484bd7ff8 -lib/codeql/rust/elements/internal/ArrayExprImpl.qll 205db9816ec56409db1a0c3987e3a64b8e88b9942055d4bcf84a5fd5943efded 094c954c2861fa7dea69247c9c16ddc6c8699dcd3201a993c72229450bed1490 lib/codeql/rust/elements/internal/ArrayTypeConstructor.qll 9e92e6c40df992b4d71ae0e80392e81499604c7586a671b89d31d2d98060380e 76a1915a88f50ffa60bf129237bae2d66cf26d2a9018aca8ccb343929e847531 lib/codeql/rust/elements/internal/ArrayTypeImpl.qll e22d4f4eb21ba1ea44dd53e0c80aa60ec3a42818c1fc2d512c92dc496a6e2cb3 1b4a7347dbb9310ace1e9e3d08c3ba53c1dc441539cebcb4a78f64a58097bc0a lib/codeql/rust/elements/internal/AsmExprConstructor.qll 36c68023b58beec30af9f05d9d902a4c49faa0206b5528d6aad494a91da07941 4d91b7d30def03e634b92c0d7b99b47c3aadd75f4499f425b80355bc775ea5b6 @@ -182,25 +181,18 @@ lib/codeql/rust/elements/internal/AssocTypeArgImpl.qll 429f12a1a53c81634fc35331b lib/codeql/rust/elements/internal/AttrConstructor.qll de1dd30692635810277430291ba3889a456344dbd25938d9f8289ab22506d5cd 57b62b2b07dee4a9daeed241e0b4514ba36fd5ec0abb089869a4d5b2c79d6e72 lib/codeql/rust/elements/internal/AttrImpl.qll 486d307f74a48e6475fe014b07d5e0e13bbdf493ea80823e77e39747edf470d7 0847aa78d0e075aedbe46c10935969046bde4a7ab842da9d184739eb99a777c2 lib/codeql/rust/elements/internal/AwaitExprConstructor.qll 44ff1653e73d5b9f6885c0a200b45175bb8f2ceb8942c0816520976c74f1fc77 11e6f4a1e1462a59e2652925c8bd6663e0346c311c0b60ebe80daa3b55b268b0 -lib/codeql/rust/elements/internal/AwaitExprImpl.qll 97eb9abc0f30ead9385f31c87b461e6f1bbfbeaac17810838bb94543bfca181f 66357ffc8c106aae565524d7110e9f50f2b3f573b1508c1d1b02db02af4cc52e lib/codeql/rust/elements/internal/BecomeExprConstructor.qll ba073aaa256cb8827a0307c3128d50f62b11aac0b1f324e48c95f30351a9b942 3a787ded505c3158fa4f4923f66e8ecdcb7b5f86f27f64c5412dc32dca031f18 -lib/codeql/rust/elements/internal/BecomeExprImpl.qll 8522410257ca9ff09e5314c3a39fba02f6ba18e1d4349b91f8823586317f3e47 073a877a6d72c5b762aac64cdd843fd2872aaefb9e264fb90eac8c25753a6e07 lib/codeql/rust/elements/internal/BinaryExprConstructor.qll 7f9b17757f78b9fb7c46e21d2040a77fa50083bef4911c8464991c3d1ad91d87 a59390cd8e896c0bfbdc9ba0674e06d980ffcefa710fbc9886be52ed427e9717 lib/codeql/rust/elements/internal/BlockExprConstructor.qll 438337c807645e98a01440f3f4610d68b0567ba15c8f51dc43bf5a30c9af3696 48ce7a546910c884619762349b8ada9836284f8008298fdb0070a38f7ddf25a0 -lib/codeql/rust/elements/internal/BlockExprImpl.qll 36ac09e4a6eeeec22919b62b1d004bdb5bb2527e67932c308aec383a770768d6 3b4b2a2014f6fe075c63a2d633b297566b548ef2e4343cadf067a9edbcadc876 lib/codeql/rust/elements/internal/BoxPatConstructor.qll 153f110ba25fd6c889092bfd16f73bb610fa60d6e0c8965d5f44d2446fcd48a2 9324cf0d8aa29945551bf8ab64801d598f57aab8cd4e19bcd4e9ef8a4a4e06eb -lib/codeql/rust/elements/internal/BoxPatImpl.qll d62a3cc1d5bab6bd258f702ec731ec57f0e5ef2672ab9de4b6f3b558078629eb 26b4fabb676adbbdb0d7f81449e493ee49380ea04d131f779714ac2434bb323a lib/codeql/rust/elements/internal/BreakExprConstructor.qll 356be043c28e0b34fdf925a119c945632ee883c6f5ebb9a27003c6a8d250afd9 bb77e66b04bb9489340e7506931559b94285c6904b6f9d2f83b214cba4f3cfd5 lib/codeql/rust/elements/internal/CallExprBaseImpl.qll d2749cc1a9d7ee8bf7f34b6c3e0238a576a68e439a8c10a503c164ff45ffcbeb ffc7b0a8841945fe6736b0e1aed7d9ed69185db03dee2b16da121325b39397c7 lib/codeql/rust/elements/internal/CallExprConstructor.qll 742b38e862e2cf82fd1ecc4d4fc5b4782a9c7c07f031452b2bae7aa59d5aa13a cad6e0a8be21d91b20ac2ec16cab9c30eae810b452c0f1992ed87d5c7f4144dc -lib/codeql/rust/elements/internal/CallExprImpl.qll 7e48610680ba6f2876a1a005ab0743496dd2364b9c44aca441bd33e11317e2d7 bb12c3c28156b40796fe3ba112760f87bb5abb323aab3c5b7bb3e0facaef8d35 lib/codeql/rust/elements/internal/CallableImpl.qll 917a7d298583e15246428f32fba4cde6fc57a1790262731be27a96baddd8cf5e c5c0848024e0fe3fbb775e7750cf1a2c2dfa454a5aef0df55fec3d0a6fe99190 lib/codeql/rust/elements/internal/CastExprConstructor.qll f3d6e10c4731f38a384675aeab3fba47d17b9e15648293787092bb3247ed808d d738a7751dbadb70aa1dcffcf8af7fa61d4cf8029798369a7e8620013afff4ed -lib/codeql/rust/elements/internal/CastExprImpl.qll 3c57b75f01efc70013ba3f05bd79fe2747fe1d1de47b84ff73b06ad38b4f1093 da813adc3390d23ec0643e37226a58e8afdb78e889380ad265d7531a344b841c lib/codeql/rust/elements/internal/ClosureBinderConstructor.qll 6e376ab9d40308e95bcdaf1cc892472c92099d477720192cd382d2c4e0d9c8a1 60a0efe50203ad5bb97bdfc06d602182edcc48ac9670f2d27a9675bd9fd8e19f lib/codeql/rust/elements/internal/ClosureBinderImpl.qll 58c6b17d34d678802ce3484f556482f3f6e3c3ff9a4be0e845bc2077818ab6fb 467261e12cba46f324364f5366bdb0034bf3c922b08307d39441ea5181e3f5f8 lib/codeql/rust/elements/internal/ClosureExprConstructor.qll a348229d2b25c7ebd43b58461830b7915e92d31ae83436ec831e0c4873f6218a 70a1d2ac33db3ac4da5826b0e8628f2f29a8f9cdfd8e4fd0e488d90ce0031a38 -lib/codeql/rust/elements/internal/ClosureExprImpl.qll 5ae3d211273b3effc3bff9f06bcef480f8264084e0509e69b8ff29bc29f47b05 ff562bc8d15ecb76ada3111c7c74dd990a0e80f41a32477f5f2f7db9e8f71102 lib/codeql/rust/elements/internal/CommentConstructor.qll 0b4a6a976d667bf7595500dfb91b9cfc87460a501837ba5382d9a8d8321d7736 7d02d8c94a319dc48e7978d5270e33fc5c308d443768ff96b618236d250123f1 lib/codeql/rust/elements/internal/ConstArgConstructor.qll f63021dc1ca2276786da3a981d06c18d7a360b5e75c08bca5d1afece4f7c4a83 487a870cbf5ed6554d671a8e159edd9261d853eba2d28ce2bd459759f47f11f2 lib/codeql/rust/elements/internal/ConstArgImpl.qll 234fe6533c208a1731cdb423aa3a28909bd7e042dbc28bbedfd4f62e42b6f21e c576a49006f7a10483041fc07f2f0d089710ac61840be61a2e71140db709f9c6 @@ -214,7 +206,6 @@ lib/codeql/rust/elements/internal/ContinueExprConstructor.qll cd93f1b35ccdb031d7 lib/codeql/rust/elements/internal/DynTraitTypeConstructor.qll 2bfd81fdf116b76f4a62b47bed5f0a730c04ce79747ecd1d3b683b8de22ff4aa 375c57350c432351396b92f28fded1e95a8002e3a1b31f3b66039f9b3d9bdea9 lib/codeql/rust/elements/internal/DynTraitTypeImpl.qll 8ccf27db0b898f518874ae094e5c97206384ad2fd3f82f81a5ecaad953278f71 e28ab56b8814a804e23afa790ca0f9a2665195b0b316d6cc52936e76ce5c0011 lib/codeql/rust/elements/internal/EnumConstructor.qll eca1a13937faacb1db50e4cf69d175f992f2204a5aaed9144bb6f3cb63814ac5 1bafba78b2729fdb052a25a1ba3f4f70871564aa4df632b4a1d467858a437924 -lib/codeql/rust/elements/internal/EnumImpl.qll c4dfa97b0c656957390417ab09c81b29b67fbff1b7b14976d65625ebea6b2c11 940303d4d4cec130f1981d309f8eaea6803c14a41174bbe9a87dd12ce4975945 lib/codeql/rust/elements/internal/ExprImpl.qll ab20ee174e2e786f34af6e5dedf3ec071bb89fc266b3e91df6377f72aa38d3f2 f68192700f449bf1c229cfbaabd5353c7c559941c915d5a0c88752cf9844194b lib/codeql/rust/elements/internal/ExprStmtConstructor.qll dd6bb06a7d48c12f630aafd611621cc50ce0f3e7d9abba5484a695f90879264b dc8b6ec8acc314e041ae71868803630c5d4cab488c72c1ea929bb756e1847c52 lib/codeql/rust/elements/internal/ExprStmtImpl.qll 420221c64245b490dab85f4e50d6b408cf488349869eb87312c166e185ad8145 2c2a4c71eea8c1ad8823e8e22780fadebb38ae502b3a7b9b062923a188fef692 @@ -226,7 +217,6 @@ lib/codeql/rust/elements/internal/ExternItemImpl.qll 577c8ac387c47746e3b45f94337 lib/codeql/rust/elements/internal/ExternItemListConstructor.qll 9e4f6a036707c848c0553119272fd2b11c1740dd9910a626a9a0cf68a55b249b efde86b18bd419154fb5b6d28790a14ea989b317d84b5c1ddbdfb29c6924fd86 lib/codeql/rust/elements/internal/ExternItemListImpl.qll e89d0cf938f6e137ba1ce7907a923b1ab2be7be2fdd642c3b7a722f11b9199f8 85906d3ce89e5abc301cc96ea5104d53e90af3f5f22f8d54ec437687096e39d8 lib/codeql/rust/elements/internal/FieldExprConstructor.qll b3be2c4ccaf2c8a1283f3d5349d7f4f49f87b35e310ef33491023c5ab6f3abc5 645d0d4073b032f6b7284fc36a10a6ec85596fb95c68f30c09504f2c5a6f789f -lib/codeql/rust/elements/internal/FieldExprImpl.qll bae3828bdee6fa3b36219e831cecc2a09fd3c40c4a945f8a19fb5d8765c6f302 be4b89e39013a380bc172ac46e496f14ebdebb1d93e1b7ffb3bab98e08db3f6f lib/codeql/rust/elements/internal/FieldListImpl.qll 02a09d1d146030c68cead4614f4eef75854f19e55ed1eda60b34c4858a8d4a88 9b9f5e77546434c771d2f785119577ec46569a18473daa4169fb84a097369493 lib/codeql/rust/elements/internal/FnPtrTypeConstructor.qll 494c53ee599039c02145f91394d8dfe7635b32d03f9fcde5efcc99ced437fec8 992462b1b6b9e64b6201f3c6c232ca524f126efcb562c9f0c176677bb559f33c lib/codeql/rust/elements/internal/FnPtrTypeImpl.qll 5d70f71e08341dfa851fc53a47cf362786b57f44244a636e2fbbad3d1c41371e 51d6a1b1132204129bb8ee9d2b72c6d13ce4b3ec8b185d3732d2e64d3f80e807 @@ -246,39 +236,28 @@ lib/codeql/rust/elements/internal/GenericParamListConstructor.qll 7221146d1724e0 lib/codeql/rust/elements/internal/GenericParamListImpl.qll 524aa0949df6d4d2cb9bee6226650f63a6f181d7644933fa265673b281074885 27b0210e5eaa2040bc8a093e35e1394befb6994b25369544738d0447ef269a9c lib/codeql/rust/elements/internal/IdentPatConstructor.qll 09792f5a070996b65f095dc6b1b9e0fb096a56648eed26c0643c59f82377cab0 0bb1a9fcdc62b5197aef3dd6e0ea4d679dde10d5be54b57b5209727ba66e078b lib/codeql/rust/elements/internal/IfExprConstructor.qll 03088b54c8fa623f93a5b5a7eb896f680e8b0e9025488157a02c48aaebc6ad56 906f916c3690d0721a31dd31b302dcdcec4233bb507683007d82cf10793a648f -lib/codeql/rust/elements/internal/IfExprImpl.qll 96dc5be0a650a74f96e0c2214eb58f1af5278ad1695ad790b660fdecb6738c14 06a292fcc459297ef3a0ef5c75c887f993ccd6350eb3fb0d2493e5b7c7199b6b lib/codeql/rust/elements/internal/ImplConstructor.qll 24edccca59f70d812d1458b412a45310ddc096d095332f6e3258903c54c1bb44 7eb673b3ab33a0873ee5ce189105425066b376821cce0fc9eb8ace22995f0bc7 -lib/codeql/rust/elements/internal/ImplImpl.qll 33a57be871fe3ab08467a65f2e2e9fb7df9f096c98e9f86d8a755eaf6da6e446 f01d0e9bfccf3926ae9720d3d660ba97e1c094f318bfb252449b2d387176f6a9 lib/codeql/rust/elements/internal/ImplTraitTypeConstructor.qll b47501280b026a4e9c21ace21d9ae59f4d126a3a1e03a6088ca38cd676cc4f6d 3b0b325ab0139b290a81355559227050ba3096a58f9ff01c4c0f5c5fb5beb6ee lib/codeql/rust/elements/internal/ImplTraitTypeImpl.qll 9826a676525c98c30019f62f3c5943b4f62f278ed738dcc023d15f82f36a9d32 da369a61b95685c29fce3c07082d2a58ab633d526d094fa9eaefa82f564609f6 lib/codeql/rust/elements/internal/IndexExprConstructor.qll 99bdc3d793c4dbd993860da60abe2b7c604345d645e86916462bc55a6939a5d1 3fe9d7da725956903707806aadbecac8d5b3874e8bed63c9bab54fff630e75dd -lib/codeql/rust/elements/internal/IndexExprImpl.qll 7914bace26dadf2c1752b65afad2ed226165507e20f3dba7949696103f3d586e 708a9f7eff1cbfcf93841ee009dc01354f4ea3d2e1e00608924e670070410e20 lib/codeql/rust/elements/internal/InferTypeConstructor.qll fb8f2aec6cd1e681cd84a7bd574459e19b9b2a152009290e2eac550f012a06b7 e2b1694f00a4e6a82b13d08d7bb95c98a73792370c1155263d696e60d39b2c3b lib/codeql/rust/elements/internal/InferTypeImpl.qll 9d0bf471a7e0c2671aae52cebadc763ed13e6a62451bf22da3061d7781d8f0bf 4e9e218862e48700523d882eb64d24135289216653cf92195f74eb8a35f50d7c lib/codeql/rust/elements/internal/ItemImpl.qll 3eaa97dcbdb8870acaebc1e11a37a5cfdfa200751461e54d3a52ca48b90ba9bd 41fbd1110b0e24f4d5a3deee0a51c02d206178111a361a1e94501ca1ab70d7f7 lib/codeql/rust/elements/internal/ItemListConstructor.qll 08af3bd12536941c3dd4a43c81cc861be24325e242e2593c087a3ce632674291 2fa166159c409d2aaffa73a30babb40829a6de580bd40894d909ee6152801082 lib/codeql/rust/elements/internal/ItemListImpl.qll fb27417bb3ee17a739ae966dd7c6f382bc2a1de3e7efdfe1586d76a257c0b573 dee7ded650df8ef46b2ac9d472718536fd76dffee86bc208b5a6144060221886 lib/codeql/rust/elements/internal/LabelConstructor.qll 1f814c94251e664bfa1b1a606aef995382e40e78d4f953350ec951ee0bc8bd34 3157fb8c7c6bd365a739f217ad73ba1e0b65ccd59b922e5ab034e3449915b36c -lib/codeql/rust/elements/internal/LabelImpl.qll e1934c3f01e6c9a2517001285bc8e36166757a50ff63be09f9000171c04130f7 4f93e722af890b5241bf55674b29ac5cb134cfefb47eba983503dbd4212abb20 lib/codeql/rust/elements/internal/LetElseConstructor.qll b2b5d68e5701379a0870aa6278078e09f06aa18ddd14045fc6ae62e90827ece7 7359e70bea8a78bcaf6e6ecc8cc37c5135ae31415b74645594456cc8daa82118 -lib/codeql/rust/elements/internal/LetElseImpl.qll 1c801275993b809e80a847736f080a9b650710ef8862797504495d62904a3a71 b79d4760d8e333893e984e45f21eb463dce7f2a49ebd0708321c8653aa8c20cb lib/codeql/rust/elements/internal/LetExprConstructor.qll 66f27cbdafb2b72b31d99645ec5ed72f4b762a7d6f5d292d7639dd8b86272972 7da048f4d7f677919c41d5c87ead301eacc12ece634d30b30a8ae1fab580ff30 -lib/codeql/rust/elements/internal/LetExprImpl.qll d9e2f8a2f4c7cf3b80178012b5f38b029064a52e705301b99c7477ec1d9fe479 1a059d383a5988b32ade329d2ac809f3a830eb9c54020e3271861aa9ef136ab8 lib/codeql/rust/elements/internal/LetStmtConstructor.qll 7ee0d67bebd6d3b9c7560137c165675d17b231318c084952ba4a2226d61e501f 84199ba755bb6c00579eee245b2bca41da478ca813b202b05abaa1246dcf13d8 -lib/codeql/rust/elements/internal/LetStmtImpl.qll 2f3f387a78d1751652bd22dc0ea6cb39f0e186847b6f0dafd74d0f89e2db495a 2ab5a17f588e385f614c8a104a17a91859389227635bd239694a799643727ffc lib/codeql/rust/elements/internal/LifetimeArgConstructor.qll 270f7de475814d42e242e5bfe45d7365a675e62c10257110286e6a16ce026454 643d644b60bfe9943507a77011e5360231ac520fbc2f48e4064b80454b96c19b lib/codeql/rust/elements/internal/LifetimeArgImpl.qll 2d31b328c07b8922e2c448137d577af429150245170d26fe4a9220cba1a26bfe 18c5f5747ff4be87820c78cadd899d57e1d52c5cd6ae3f4e56ee2f5d3164bd41 lib/codeql/rust/elements/internal/LifetimeConstructor.qll 2babe40165547ac53f69296bb966201e8634d6d46bc413a174f52575e874d8cd ef419ae0e1b334d8b03cdb96bc1696787b8e76de5d1a08716e2ff5bd7d6dc60d -lib/codeql/rust/elements/internal/LifetimeImpl.qll 14ec1a4fa0c84fa9e75ea0babebae9c666909239806ed21325c32e47e11c8806 891168f29d4e06a927ec01ef8fd21ff6e0a0a3deadcf1481c99c74bf2ef20536 lib/codeql/rust/elements/internal/LifetimeParamConstructor.qll 530c59a701d814ebc5e12dc35e3bfb84ed6ee9b5be7a0956ea7ada65f75ff100 ff6507e5d82690e0eec675956813afabbbcfb89626b2dbfffe3da34baeff278c lib/codeql/rust/elements/internal/LifetimeParamImpl.qll 8909288801bff8d3e87096dff4b45f434a4c064a9d69d8943a0b30970e011ef9 6d8f80eca24112b5eb659fe5d5fca4fd91c3df20ecab1085dfee9176091237b8 lib/codeql/rust/elements/internal/LiteralExprConstructor.qll 8ea3569bd50704ce7d57be790d2dfd38f4c40cb0b12e0dd60d6830e8145a686f 88d07ad3298003f314f74bd8e3d64a3094de32080ad42a7e6741c416c3856095 lib/codeql/rust/elements/internal/LiteralPatConstructor.qll b660cb428a0cba0b713fc7b07d5d2921de4a2f65a805535fb6387684c40620de 2dbc9fbc56e9de53d24265d6b13738ef5b9ced33cc3c4c1c270e04dc2fc1330f -lib/codeql/rust/elements/internal/LiteralPatImpl.qll af74456649e3949bf27e91f2127389e5c9f2ee99241958afeaa5b55276170994 b8b744b1d0c1b85ec86c535a35fc75d6289636a0e1988500debf236faf24a2cd lib/codeql/rust/elements/internal/LoopExprConstructor.qll 45f3f8f7441fcab6adc58831421679ee07bac68ac0417f3cbc90c97426cc805b f7ab3361b4a11e898126378ea277d76949466946762cd6cb5e9e9b4bb9860420 -lib/codeql/rust/elements/internal/LoopExprImpl.qll 068b98978296b22ae59bf9e941e7e2683f4fee0f6c1affbda1fa42c93f015114 e40e384aeff61099d102a681e5dca1aabc6dd6694731f8570d6358e0197368b0 lib/codeql/rust/elements/internal/MacroCallConstructor.qll 707fee4fba1fd632cd00128f493e8919eaaea552ad653af4c1b7a138e362907d b49e7e36bf9306199f2326af042740ff858871b5c79f6aeddf3d5037044dbf1f -lib/codeql/rust/elements/internal/MacroCallImpl.qll 7732221a0d8677f32695be3e6263f6e5f8857225cf98cc31eb91592e175df260 7c4e15e092abbf3a6070141669f2614909eb0accaaee0da6f70495de6087337b lib/codeql/rust/elements/internal/MacroDefConstructor.qll 382a3bdf46905d112ee491620cc94f87d584d72f49e01eb1483f749e4709c055 eb61b90d8d8d655c2b00ff576ae20c8da9709eeef754212bc64d8e1558ad05ce lib/codeql/rust/elements/internal/MacroDefImpl.qll f26e787ffd43e8cb079db01eba04412dbf32c338938acf1bc09a2f094bbdfdfe 044f43bc94fe4b6df22afae32e9f039d1d0d9e85ad9f24b6388be71211c37ce5 lib/codeql/rust/elements/internal/MacroExprConstructor.qll b12edb21ea189a1b28d96309c69c3d08e08837621af22edd67ff9416c097d2df d35bc98e7b7b5451930214c0d93dce33a2c7b5b74f36bf99f113f53db1f19c14 @@ -294,7 +273,6 @@ lib/codeql/rust/elements/internal/MacroStmtsImpl.qll 27faff9da93ad7f22a6236c73eb lib/codeql/rust/elements/internal/MacroTypeConstructor.qll 0a23573a6f69b38f3d7470050b16197601d67bdd5a4b1a43a155b0b99ccdf6b5 19b623962e8e1f73e55e3ed9712d2a3fe84b9510b99062173902feb2458ec12a lib/codeql/rust/elements/internal/MacroTypeImpl.qll b8711279f09f521b05bb67568c089271b7913f863ee64dfdeec2c502de2cbdc8 51bd9d3a2fb2065bce7b193b485e225ca5c8ba2029e60cab427d43a90baf0880 lib/codeql/rust/elements/internal/MatchArmConstructor.qll b41c1d5822d54127ce376ef62c6a5fa60e11697319fc7d9c9c54fd313d784a93 96cca80e5684e5893c0e9c0dff365ef8ad9e15ff648c9969ba42d91f95abea05 -lib/codeql/rust/elements/internal/MatchArmImpl.qll 065dff16fc70b51924eb4db57be121283f4b5651105320901558bc93bfdf2641 37f4f6ecd23c5170ee5cb0041625c19a8d3245d56f6f1587a2e588eb86baecf9 lib/codeql/rust/elements/internal/MatchArmListConstructor.qll 8bc5ac978fe1158ef70d0ac06bdad9e02aadd657decb64abcc4ea03f6715a87a 4604ab0e524d0de6e19c16711b713f2090c95a8708909816a2b046f1bd83fe24 lib/codeql/rust/elements/internal/MatchArmListImpl.qll 896c6f1650e7ceb60d0b3d90e2b95fe7f8dc529203ddfec58edb063fa9b2871f a668fed1eb68806abfb021913786168d124de47b25da470e7b57f56bf8556891 lib/codeql/rust/elements/internal/MatchExprConstructor.qll 0355ca543a0f9ad56697bc2e1e2511fa3f233bc1f6344d9e1c2369106901c696 78622807a1c4bff61b751c715639510146c7a713e0c4f63246e9a2cf302f4875 @@ -306,46 +284,35 @@ lib/codeql/rust/elements/internal/MethodCallExprConstructor.qll a1b3c4587f0ae60d lib/codeql/rust/elements/internal/MissingConstructor.qll aab0b7f2846f14a5914661a18c7c9eae71b9bde2162a3c5e5e8a8ecafa20e854 8f30b00b5b7918a7500786cc749b61695158b5b3cc8e9f2277b6b6bf0f7850a0 lib/codeql/rust/elements/internal/MissingImpl.qll e81caa383797dfe837cf101fb78d23ab150b32fef7b47ffcc5489bfcd942ac3e 9f3212d45d77e5888e435e7babd55c1e6b42c3c16f5b1f71170ac41f93ee8d0b lib/codeql/rust/elements/internal/ModuleConstructor.qll 31cc83c9d8f25ac07375d19e568f05c068e1f5aa205ff3d9ac31c2510e6f8468 8a70f3f1c18ff87f17e6baf2f05ccaed55c70469288192fc39ef0bb5531b8c0e -lib/codeql/rust/elements/internal/ModuleImpl.qll bbff32cadbad54bdb613df8c1ac6da8cd2a80d0576361b843f1529e6c63b1938 7342473026561b8e4923625a083ba52c31d3b6797f9061accd1a712598244410 lib/codeql/rust/elements/internal/NameConstructor.qll a760134c6d4fc785746e1a5dc042a6bf25b8adaa3947a6897c31e50fd91dd5fd 1359f903d57112bcc1f62a609febb288301bfa810e569aa12e1045fd48b5b5c9 lib/codeql/rust/elements/internal/NameRefConstructor.qll 5ff6eacc614fd41f98b54cbb4960a07a1471cf4ea291758d33e54a48fd5d1bc4 c538d65414a24dfdbeb49cfd997588227559ba038f0b55d14bb5d89ed1a016f2 lib/codeql/rust/elements/internal/NeverTypeConstructor.qll 6a86bff9d885eddf39a159698710def40d693ccfd0888aefd090a283cb59ae95 9c51d6569f267dde5597067a8470d19d7714304399de4f730e7b85ca21feee20 -lib/codeql/rust/elements/internal/NeverTypeImpl.qll 8c7464cb76f9d081dab318d743817d87ecd69672f382d27323ade94c82e8e0f6 55351661214854bbf7faed6c7d17d598459d4e88eaba130a9b3a9f43f6665c37 lib/codeql/rust/elements/internal/OffsetOfExprConstructor.qll 616e146562adb3ac0fba4d6f55dd6ce60518ed377c0856f1f09ba49593e7bfab 80518ce90fc6d08011d6f5fc2a543958067739e1b0a6a5f2ed90fc9b1db078f0 lib/codeql/rust/elements/internal/OffsetOfExprImpl.qll e52d4596068cc54719438121f7d5afcaab04e0c70168ac5e4df1a3a0969817a6 6ab37e659d79e02fb2685d6802ae124157bf14b6f790b31688f437c87f40f52c lib/codeql/rust/elements/internal/OrPatConstructor.qll 4ef583e07298487c0c4c6d7c76ffcc04b1e5fe58aba0c1da3e2c8446a9e0c92b 980a6bd176ae5e5b11c134569910c5468ba91f480982d846e222d031a6a05f1a lib/codeql/rust/elements/internal/ParamConstructor.qll b98a2d8969f289fdcc8c0fb11cbd19a3b0c71be038c4a74f5988295a2bae52f0 77d81b31064167945b79b19d9697b57ca24462c3a7cc19e462c4693ce87db532 -lib/codeql/rust/elements/internal/ParamImpl.qll 8a5101559f5d636b60ab80237057944b537823ce054d760c3dbd58b2acf05a46 e7a08cefeb6a290a975899045b7b19a9624f5a2b0946cba0866b1854cc0c0fb0 lib/codeql/rust/elements/internal/ParamListConstructor.qll 3123142ab3cab46fb53d7f3eff6ba2d3ff7a45b78839a53dc1979a9c6a54920e 165f3d777ea257cfcf142cc4ba9a0ebcd1902eb99842b8a6657c87087f3df6fe lib/codeql/rust/elements/internal/ParamListImpl.qll 0ed6e9affe1dc0144641502292c2ddd51958fe3d503419caf15198176e3a4174 92d053cc5fdf40a2d98acb665083b5da15403d7da205779a97a4ee66fac0add4 lib/codeql/rust/elements/internal/ParenExprConstructor.qll 104b67dc3fd53ab52e2a42ffde37f3a3a50647aa7bf35df9ba9528e9670da210 d1f5937756e87a477710c61698d141cdad0ccce8b07ecb51bab00330a1ca9835 -lib/codeql/rust/elements/internal/ParenExprImpl.qll 185e7c0f8f377f62a7ccf1c0d168caf500afd0654b82d47569bfcb97e368a26d 25a41998ce0ff3490d677676bf02fea1861d6c01db99a02fc940cc37ae580db6 lib/codeql/rust/elements/internal/ParenPatConstructor.qll 9aea3c3b677755177d85c63e20234c234f530a16db20ab699de05ca3f1b59787 29f24aed0d880629a53b30550467ade09a0a778dbf88891769c1e11b0b239f98 -lib/codeql/rust/elements/internal/ParenPatImpl.qll 39c45b3736c4d0329af7a1eec28a8470c3f244efd58a6ba62af482a0e9b4a842 d8aa9e6f8987666cd51cb65f81700d3b4584d3dc7d070836e52a9bc64e572d9e lib/codeql/rust/elements/internal/ParenTypeConstructor.qll d62e656a4a3c8ffd4eb87d49585a7a3bfb5dbe3826fbcbd11cb87b46f34c19ae febf6535965afa0f6eac4d2b08730f5a07bbb36a7434abe0a7663d7264961a3f -lib/codeql/rust/elements/internal/ParenTypeImpl.qll 6f7b4fade4ac0af69bf9766ee7d73da3da1742ba8a7c12d2a067b71c7f96d849 f065ea466111a5abca33d97b9878ef2fcc221f286fc65bec87f3a9c2fd5d57fc lib/codeql/rust/elements/internal/PatImpl.qll 37c9b1da7aa625117644e2cd74ec0b174f69a38cf66926add01786a05d5ad2ad 143685a0b4873fa0b73b204285dca956e59b32d527bfac6cc336326d244994b7 lib/codeql/rust/elements/internal/PathConstructor.qll 5c6354c28faf9f28f3efee8e19bdb82773adcf4b0c1a38788b06af25bcb6bc4a 3e2aeef7b6b9cda7f7f45a6c8119c98803aa644cf6a492cf0fce318eba40fe8f lib/codeql/rust/elements/internal/PathExprBaseImpl.qll e8b09447ee41b4123f7d94c6b366b2602d8022c9644f1088c670c7794307ab2e 96b9b328771aaf19ba18d0591e85fcc915c0f930b2479b433de3bfdd2ea25249 lib/codeql/rust/elements/internal/PathExprConstructor.qll cf6e0a338a8ed2d1042bdee4c2c49be5827e8c572d8c56e828db265d39e59ae3 36a3d1b7c5cc2cf527616be787b32071b9e2a6613a4f6b3f82e2a3b0e02a516f lib/codeql/rust/elements/internal/PathPatConstructor.qll 966c4ea22218ef71e000d7ce8dd5b570c39ad96b9239a3aa8a38292e2a9f36d2 8a1f348e9257ffc6e6bedcd70389b8e7ec2a3ed6e7b3733744ddfab284826e57 -lib/codeql/rust/elements/internal/PathPatImpl.qll 6ab5b5959cfd94e74f60422cbdbd764a5f51ff541db428938c36ba3a512d1d6b 47585157460e8384047de307b0b05deaab758d0f07fd0183d874f7bb9d8bda4b lib/codeql/rust/elements/internal/PathSegmentConstructor.qll 2d9639e42035dc7e73b7d6ddb8a977beadc6b4492dee4292b2f85b4409344441 c337fc3b9ef56366428772563e3f25f711474d16e860d3e89c1395a95d9e83e7 lib/codeql/rust/elements/internal/PathTypeConstructor.qll 8949742c7ab7fcfa3a3f6469e87355a6888931ab9ac7a6a07d2bd51e3fdf8283 fb1a402e94e9a1f33b7757338d7e95b107933339615a4fe86de33e41206dd94a -lib/codeql/rust/elements/internal/PathTypeImpl.qll 0e3b85df054d1194505796e457ee31a8dac2a2a77284c077cbf1a3bfc179294e c198d4fdf8d1d55f1cf57685a9ad2adf88cc2d6d4f84bafa1e9f039192761399 lib/codeql/rust/elements/internal/PrefixExprConstructor.qll 90c50b0df2d4b4cbf5e2b7d67a9d243a1af9bfff660b7a70d8b9c7859c28bca7 1a1b5ea1f06ed8d41a658c872e8e1915c241a7c799c691df81b9a7b55d8f2f1e lib/codeql/rust/elements/internal/PtrTypeConstructor.qll ee3c4326ea3f198d2537a914dd6eb51d0cf247310f037e13e87632fbd6cfb50a 3814218b5271f3c6c45b52082cca2a3250a2573abced43fe53e1b4145374afe3 lib/codeql/rust/elements/internal/PtrTypeImpl.qll ff4283ffab39b4a3c0e55e7d655dfdb846171cde0907bf1f893c86b35d2c1135 e54d3a6fb0b5a1484f00fd5a4631455902bab80642c3bb076e538ddcc29a85a4 lib/codeql/rust/elements/internal/RangeExprConstructor.qll a0aa90a1c38c5deea56475399016afae2a00a858b961fbbab8ddeb3bc6a08103 0ddf1bcf28aafc56d7334e6138fb268f9b36a429e4cbdd982cd8384e0644076b -lib/codeql/rust/elements/internal/RangeExprImpl.qll a6ff92a27e44c2184f5c2d8483de1d0d4a77eb7a5154ff93a8f3a9fc8b63e561 d53d44bc1c1ae426f208595002adcddb88643e1027bbee7445095ca09e433331 lib/codeql/rust/elements/internal/RangePatConstructor.qll fe4345cb41d970ab64196ca37eccb26e5b9cf85fab4253cacfd2b31de03bd070 1d09d5ec8203d76aed2dfb7e7f14c0c07d6559c8f589e11860fff8a2c682c1a6 lib/codeql/rust/elements/internal/RangePatImpl.qll ef11ab2c002896036553231741a7cf896fafa09e22e920e15661b9cbe4393cae 24ac2dcce3055a77f3a5e0b38cf13aebefd2eeaefa53674ff144a6225634ac0d lib/codeql/rust/elements/internal/RecordExprConstructor.qll 742198bd8223902b5625b4a574a9e3539a8b6cf8e48eecc57cc2de4e980fba6e 0a99e454e234e8b7b59dc11b167172a5fcd31b8a5282349956d6fd861ec735df lib/codeql/rust/elements/internal/RecordExprFieldConstructor.qll 11620bc4e2dc7b3903be764cd9510a8e002892722b502876cf3467994aa7a63c e42e50747dd9453a44705b2d6a05e7a4a8c6debed988a0335a774a547d8f7157 -lib/codeql/rust/elements/internal/RecordExprFieldImpl.qll 8af196cbaeeb7997e933fde9ddba50ec099df51f66e03501f00157f238505fe7 29ae10546577a354b0439876ce5deb5ab13455028f02c01fe3903b11eaee35e2 lib/codeql/rust/elements/internal/RecordExprFieldListConstructor.qll 3a0d6ec872792c400d3a0a5ed1c5051b248a597a4b17ada1a078ea5d972b6721 52bae8222e7aa5bc89b73bec3fd1c3c1de0fe11bf30ccf5668454f63fbfc9b83 lib/codeql/rust/elements/internal/RecordExprFieldListImpl.qll 1210c23c0495f5d1a72409afc8c559f8da2b8c71340ff2944af9d1f684d0a856 fea96b053cad4135ab09b1c070a4c9f26507dd890a62c30772cf3e2358686640 -lib/codeql/rust/elements/internal/RecordExprImpl.qll 233b3f7ee8dbd1e5431bea5436c6b7ee38e631c041111dcf53e45c6c4c08a6cf 9537497edb739c535d75ce80122f597ad93241bff5399b1dae17a7bfff1c15cd lib/codeql/rust/elements/internal/RecordFieldConstructor.qll 9fc05f5101e48a45a028c479b35ec3d2f1a3cc33f0938667fcb813c5a4ab9526 98791dcf7f3209524f6132f9c26980e499cbcf94c1559e95c67544732245f05b lib/codeql/rust/elements/internal/RecordFieldImpl.qll 2612dae3c95c9064420a3494872213f7fd7a3e1133243f4adea8a30808a209ae 143b75bb539a1bfea16e1c764a1f549522ef9c8d6d5de3fef377bbf67ba42075 lib/codeql/rust/elements/internal/RecordFieldListConstructor.qll 9f1d916f3784092dcbff7224451c8f4f0daf6f8293a466b0a30ec9b92cd41358 8aafe377714a134287362c4b96439c1c6baa5a31c2c36a544bd5f73e9213477a @@ -355,22 +322,17 @@ lib/codeql/rust/elements/internal/RecordPatFieldConstructor.qll 6e1880ed05401b39 lib/codeql/rust/elements/internal/RecordPatFieldImpl.qll 04bc31b857c8250096d9d1bf3fad1e556a28d83bb3f3b48a3f049048d1e6785f 5853105e55650d05a4b196f17b89baf12b898df0a010e4f88289ce01d16a0379 lib/codeql/rust/elements/internal/RecordPatFieldListConstructor.qll b8f0ef9b75ffe6be6ce7e601d528f0a1b871123c63e39cead3fd13b8bd4f54b7 166f07c708ab8b3de6bfaf193bac93081b2aacad046aa86de7441085dd20a8c5 lib/codeql/rust/elements/internal/RecordPatFieldListImpl.qll 2d1dd9910480eb65c59fcef2e1576ce639be85c35d90e4bce721ce22ec742ba3 1e788a2d7d00e9f96dbf7e93d3a18d5bfb4d7749194ff8e9810e9053fa88a94b -lib/codeql/rust/elements/internal/RecordPatImpl.qll 3c7086be84e336c069f4c7b538c7ad32a7728e7fbf42e4dc7f04c4c99d393c0d 8020215f38639965398c62ddb36c3560579d63928e71e0d773b254e121a68cc3 lib/codeql/rust/elements/internal/RefExprConstructor.qll 9ad08c0f3d980a56a2af8857cb84db589941d20ab3ae5c8ece004ccaccaaf950 4cac3ace31b7ed77a72e989fce9cdbae2247f03c28a3f0c50d67385d02c7f193 -lib/codeql/rust/elements/internal/RefExprImpl.qll 56ed831a3b30ed375e7369b0a60b9b7635a1b00f058364a6b15078031a85af5f ca7e772b409514363e49d56a174ae9bd2e076755cbd09c4e7e5b732d09acdb25 lib/codeql/rust/elements/internal/RefPatConstructor.qll d8b88c2c468b08072f6f853306eb61eb88ee1e6c5cfb63958f115a64a9715bb3 0c1d6a8af6a66912698acce47e89d4e3239e67f89c228a36a141f9c685c36394 -lib/codeql/rust/elements/internal/RefPatImpl.qll 3e06e8130d412b47267497097cffc9f4b930b9e54bc90465ab5ac620fbe52048 b8ac844ec99f30605ce476f89ced4fb1159d2df0df43c631f60b3c868e0e1fd7 lib/codeql/rust/elements/internal/RefTypeConstructor.qll e1952aa69586b440f878400a52d09b2d12d5a29dbe9651360344631cb9493cd4 e4ae45e89472dfd4547d647c75e1635cf065a7d221ed60ed34554f265c0c5405 lib/codeql/rust/elements/internal/RefTypeImpl.qll f72b760a8a26be21170435da2cb2981638513617fd82742f45f38bc437d9f2c4 f32df49f0b6df85ca5fc4393ccd341ac4304b4947a282ccea48468a26837ef3d lib/codeql/rust/elements/internal/RenameConstructor.qll 65fa2e938978d154701e6cac05b56320b176ee014ef5c20a7b66f3e94fd5c4a7 dfc0ff4606b8e1c14003cc93a0811f4d62ec993b07ff3c1aa0776746577ed103 lib/codeql/rust/elements/internal/RenameImpl.qll 4f5943fbda4ec772203e651ed4b7dd1fb072219ddc0cb208c0a0951af5e72bd6 b9854cdcf02e70ee372330a4e0bfdb03012bc81af79dd12af2a567fd7fc4672b lib/codeql/rust/elements/internal/ResolvableImpl.qll 7599625454fe81c3490a122943363a2a2522a7877b78a80649e93155a418fedd 442072c3d70bdaababd7de8bc6c9382f4a50bab41d13759dcd1a5bee9ea32e49 lib/codeql/rust/elements/internal/RestPatConstructor.qll 45430925ddf08fba70ede44c7f413ddb41b3113c149b7efc276e0c2bf72507b4 25c678898d72446e7a975bb8b7f2fde51e55b59dbd42f2cca997c833b1a995f1 -lib/codeql/rust/elements/internal/RestPatImpl.qll 1b83464367e5fdc28b0b3946ae74c67c64d30b286c39268b4118337539250e51 83a03308cba4cb3344d48f0a0730b1d3e41a73f16f729d39dc2bae6d3f57f232 lib/codeql/rust/elements/internal/RetTypeConstructor.qll a96d803c6e4b40be49cfed0853a3e04ae917c47351e5c880fcab06eddf1af9cc d06a0a191cb14c270c0441ffc3d289263808170dcbe05e01847a35ac9d61dfb3 lib/codeql/rust/elements/internal/RetTypeImpl.qll 0e96f1075ccade28ce5664ab0f5c2e98984ae1d0ed708bc02e40e882672d9e2f 350725d16bcb1e8911bfdd87d9dd21be73ec66d23c2a35827c8c8525c48dc885 lib/codeql/rust/elements/internal/ReturnExprConstructor.qll 57be5afbe20aa8db6e63c1f2871914c19c186730ad7dccaa424038c6305730d5 4d3c4f2e9b38a4b54ff26a0032455cdcca3d35fec201b6c932072a9e31fbb4fe -lib/codeql/rust/elements/internal/ReturnExprImpl.qll eef4960a8c27eaa0540d048fe88893cfe9a6ac377a770cc23d72ebe05d5782f1 b7f35650d80f2f8b4893f0091fea74646341af406b6248f75c477112aca96dea lib/codeql/rust/elements/internal/ReturnTypeSyntaxConstructor.qll 8994672e504d1674e5773157d0ad8a0dc3aad3d64ef295e7722e647e78e36c11 abe7df754721f4ff7f3e3bb22d275976b2e9a1ef51436a461fe52ebd2d29cff1 lib/codeql/rust/elements/internal/ReturnTypeSyntaxImpl.qll d47a3dcfcc2b02a6a9eaeefe9a7a4be2074ecd2019da129dda0f218bc3fbd94b 87198db7c0620ed49369da160f09287015e0cd1718784e1ba28ec3ec5a0bb4a8 lib/codeql/rust/elements/internal/SelfParamConstructor.qll a63af1d1ccde6013c09e0397f1247f5ab3efd97f3410dd1b6c15e1fb6cd96e54 0d8977653c074d5010c78144327f8b6c4da07f09d21e5cc3342082cd50107a81 @@ -394,7 +356,6 @@ lib/codeql/rust/elements/internal/TokenTreeImpl.qll c61574f2b551db24640258117e0c lib/codeql/rust/elements/internal/TraitAliasConstructor.qll d2f159cac53b9d65ec8176b8c8ccb944541cd35c64f0d1ceabb32cd975c000bf 6564981793de762af2775cc729e25054ea788648509d151cbfdbdf99fc9ed364 lib/codeql/rust/elements/internal/TraitAliasImpl.qll f338dba5388973ec0c5928d4c60664737f75a93d0c7db5fb34053bc41c107641 f2e437469e4ba1d8dd321bc670978e7eed76508e728d1e08e52ddcf52a461d3a lib/codeql/rust/elements/internal/TraitConstructor.qll 1f790e63c32f1a22ae1b039ca585b5fe6ffef6339c1e2bf8bca108febb433035 535cebd676001bfbbb724d8006fa2da94e585951b8fd54c7dc092732214615b5 -lib/codeql/rust/elements/internal/TraitImpl.qll 776a0c10c944146b89d616e3bf1311502de9e1e84f0c9d5d7de5aecfc97b87e3 3795d920e98620b30f7e2c218cfb57ae91b37956f9165325b5da6705df8beffa lib/codeql/rust/elements/internal/TryExprConstructor.qll 98e3077ebc4d76f687488b344f532b698512af215b66f0a74b5cea8ed180836c b95603c10c262911eeffdf4ccba14849e8443916b360e287963d5f2582d8e434 lib/codeql/rust/elements/internal/TryExprImpl.qll 00635685db339557cfb89fad0bfc134e53efc6d88c68cce400b72c2dd428ef9f 43559b46e45c009f985b58896b542881b81a3e6b82a6f51b784e8a712ae3da2b lib/codeql/rust/elements/internal/TupleExprConstructor.qll 71c38786723225d3d90399b8a085b2b2664c62256654db9e1288fadd56745b9d 639ad70b49ebadc027127fbdc9de14e5180169a4285908233bc38ccac6f14110 @@ -421,7 +382,6 @@ lib/codeql/rust/elements/internal/TypeParamConstructor.qll a6e57cccd6b54fa68742d lib/codeql/rust/elements/internal/TypeParamImpl.qll 9e7169e8254e2d9d13b11a17cbe04e874f72fb67a75c3585e70eddec71ba5c7f b8c862b2cd53bc211caea23261d9832613418aae51f63ef08922d300c2d1f4f2 lib/codeql/rust/elements/internal/TypeRefImpl.qll cfc08bdcc8e7e588f533c7e64c0c08d317d63cdb50f4cba4b4b3e589b37b0fea b46ee7de9b5e9894807004e1bedf39e7d25912ed79de6ac5adfb37a43aa4804b lib/codeql/rust/elements/internal/UnderscoreExprConstructor.qll 8dc27831adb49c1a47b9f8997d6065e82b4e48e41e3c35bd8d35255cea459905 6c5a5272d37f83f1c1b17475f8adb7d867e95025d201320e20a32dab1f69f7bf -lib/codeql/rust/elements/internal/UnderscoreExprImpl.qll 4277b23a09a4ba5e53ca2cfbb20eba6a5f66039b6268da79410e0be30332fedd b9ed79468157a7e751f78aa7597165672cbc38191d5f85ecc15cfdaff388a26a lib/codeql/rust/elements/internal/UnextractedImpl.qll 5c23df7e448184d76ccab2c22757ace24663b8be2592a3fa2a44bef43159ebd3 77b0c9fe75a307adc08c422cc88423c5349756878793cf9e79c006c83b4c403b lib/codeql/rust/elements/internal/UnimplementedConstructor.qll 70b0489fdc75fed389de8203947ed9c8eabb91373a1264eb2c8018ddbb2d9baa 0f2592c1697a2f2f913014ecd73b0e3ff1ec5b038ba1c3a22e7939bf8759e664 lib/codeql/rust/elements/internal/UnimplementedImpl.qll 06771abc088e0a8fc24032c9d2633618e8e40343ef8757a68cc0a70f1617165a 5738f626f1f4f573fdf7dcd5bd57a0948d290ed89342b9160e95ef3c84044f9a @@ -444,9 +404,7 @@ lib/codeql/rust/elements/internal/WhereClauseImpl.qll 59d33533e641ce3851e493de30 lib/codeql/rust/elements/internal/WherePredConstructor.qll f331c37085792a01159e8c218e9ef827e80e99b7c3d5978b6489808f05bd11f8 179cad3e4c5aaaf27755891694ef3569322fcf34c5290e6af49e5b5e3f8aa732 lib/codeql/rust/elements/internal/WherePredImpl.qll aad95f448ca051d5dcd462429fa1ca95dcec6df2e70b6f64a480bd6839307581 411a66a5d866aa8cb4911c5106849adb103a063e1b90a9ecc5d16db3022bb1f8 lib/codeql/rust/elements/internal/WhileExprConstructor.qll 01eb17d834584b3cba0098d367324d137aacfc60860752d9053ec414180897e7 e5e0999fb48a48ba9b3e09f87d8f44f43cc3d8a276059d9f67e7714a1852b8a5 -lib/codeql/rust/elements/internal/WhileExprImpl.qll 5e716498402be3a1a8ed3594e13a03938bb793ac80f2a648bc93c0d746028d8b efcee38fe5e984a690c33f8bfdc78c677c2b0cdc5902525e2196a68fdabb6823 lib/codeql/rust/elements/internal/WildcardPatConstructor.qll 5980c4e5724f88a8cb91365fc2b65a72a47183d01a37f3ff11dcd2021e612dd9 c015e94953e02dc405f8cdc1f24f7cae6b7c1134d69878e99c6858143fc7ab34 -lib/codeql/rust/elements/internal/WildcardPatImpl.qll 01e5fac111cce3bb139fc290dbdb2a80e7369a90952178228efeb025915d40b7 875e91fb1354ab8d94d5fa426b63714c70904f53d7bab15158fcbc290c62a0f1 lib/codeql/rust/elements/internal/YeetExprConstructor.qll 7763e1717d3672156587250a093dd21680ad88c8224a815b472e1c9bba18f976 70dd1fd50824902362554c8c6075468060d0abbe3b3335957be335057512a417 lib/codeql/rust/elements/internal/YeetExprImpl.qll e8924147c3ebe0c32d04c5b33edfd82ae965c32479acfd4429eeab525cf42efb b2debcfa42df901f254c58705a5009825ec153464c9ab4b323aa439e5924e59e lib/codeql/rust/elements/internal/YieldExprConstructor.qll 8cbfa6405acb151ee31ccc7c89336948a597d783e8890e5c3e53853850871712 966f685eb6b9063bc359213323d3ff760b536158ecd17608e7618a3e9adf475f diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index a532f142ec9..8e644be8e46 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -171,7 +171,6 @@ /lib/codeql/rust/elements/internal/ArgListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ArgListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ArrayExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/ArrayExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ArrayTypeConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ArrayTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/AsmExprConstructor.qll linguist-generated @@ -184,25 +183,18 @@ /lib/codeql/rust/elements/internal/AttrConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/AttrImpl.qll linguist-generated /lib/codeql/rust/elements/internal/AwaitExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/AwaitExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/BecomeExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/BecomeExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/BinaryExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/BlockExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/BlockExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/BoxPatConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/BoxPatImpl.qll linguist-generated /lib/codeql/rust/elements/internal/BreakExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/CallExprBaseImpl.qll linguist-generated /lib/codeql/rust/elements/internal/CallExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/CallExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/CallableImpl.qll linguist-generated /lib/codeql/rust/elements/internal/CastExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/CastExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ClosureBinderConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ClosureBinderImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ClosureExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/ClosureExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/CommentConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ConstArgConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ConstArgImpl.qll linguist-generated @@ -216,7 +208,6 @@ /lib/codeql/rust/elements/internal/DynTraitTypeConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/DynTraitTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/EnumConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/EnumImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ExprStmtConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ExprStmtImpl.qll linguist-generated @@ -228,7 +219,6 @@ /lib/codeql/rust/elements/internal/ExternItemListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ExternItemListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/FieldExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/FieldExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/FieldListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/FnPtrTypeConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/FnPtrTypeImpl.qll linguist-generated @@ -248,39 +238,28 @@ /lib/codeql/rust/elements/internal/GenericParamListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/IdentPatConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/IfExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/IfExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ImplConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/ImplImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ImplTraitTypeConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ImplTraitTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/IndexExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/IndexExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/InferTypeConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/InferTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ItemImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ItemListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ItemListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/LabelConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/LabelImpl.qll linguist-generated /lib/codeql/rust/elements/internal/LetElseConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/LetElseImpl.qll linguist-generated /lib/codeql/rust/elements/internal/LetExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/LetExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/LetStmtConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/LetStmtImpl.qll linguist-generated /lib/codeql/rust/elements/internal/LifetimeArgConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/LifetimeArgImpl.qll linguist-generated /lib/codeql/rust/elements/internal/LifetimeConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/LifetimeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/LifetimeParamConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/LifetimeParamImpl.qll linguist-generated /lib/codeql/rust/elements/internal/LiteralExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/LiteralPatConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/LiteralPatImpl.qll linguist-generated /lib/codeql/rust/elements/internal/LoopExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/LoopExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/MacroCallConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/MacroCallImpl.qll linguist-generated /lib/codeql/rust/elements/internal/MacroDefConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/MacroDefImpl.qll linguist-generated /lib/codeql/rust/elements/internal/MacroExprConstructor.qll linguist-generated @@ -296,7 +275,6 @@ /lib/codeql/rust/elements/internal/MacroTypeConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/MacroTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/MatchArmConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/MatchArmImpl.qll linguist-generated /lib/codeql/rust/elements/internal/MatchArmListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/MatchArmListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/MatchExprConstructor.qll linguist-generated @@ -308,46 +286,35 @@ /lib/codeql/rust/elements/internal/MissingConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/MissingImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ModuleConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/ModuleImpl.qll linguist-generated /lib/codeql/rust/elements/internal/NameConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/NameRefConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/NeverTypeConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/NeverTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/OffsetOfExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/OffsetOfExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/OrPatConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ParamConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/ParamImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ParamListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ParamListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ParenExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/ParenExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ParenPatConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/ParenPatImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ParenTypeConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/ParenTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/PatImpl.qll linguist-generated /lib/codeql/rust/elements/internal/PathConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/PathExprBaseImpl.qll linguist-generated /lib/codeql/rust/elements/internal/PathExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/PathPatConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/PathPatImpl.qll linguist-generated /lib/codeql/rust/elements/internal/PathSegmentConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/PathTypeConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/PathTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/PrefixExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/PtrTypeConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/PtrTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RangeExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/RangeExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RangePatConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/RangePatImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RecordExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/RecordExprFieldConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/RecordExprFieldImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RecordExprFieldListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/RecordExprFieldListImpl.qll linguist-generated -/lib/codeql/rust/elements/internal/RecordExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RecordFieldConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/RecordFieldImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RecordFieldListConstructor.qll linguist-generated @@ -357,22 +324,17 @@ /lib/codeql/rust/elements/internal/RecordPatFieldImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RecordPatFieldListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/RecordPatFieldListImpl.qll linguist-generated -/lib/codeql/rust/elements/internal/RecordPatImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RefExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/RefExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RefPatConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/RefPatImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RefTypeConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/RefTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RenameConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/RenameImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ResolvableImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RestPatConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/RestPatImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RetTypeConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/RetTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ReturnExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/ReturnExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ReturnTypeSyntaxConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ReturnTypeSyntaxImpl.qll linguist-generated /lib/codeql/rust/elements/internal/SelfParamConstructor.qll linguist-generated @@ -396,7 +358,6 @@ /lib/codeql/rust/elements/internal/TraitAliasConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/TraitAliasImpl.qll linguist-generated /lib/codeql/rust/elements/internal/TraitConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/TraitImpl.qll linguist-generated /lib/codeql/rust/elements/internal/TryExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/TryExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/TupleExprConstructor.qll linguist-generated @@ -423,7 +384,6 @@ /lib/codeql/rust/elements/internal/TypeParamImpl.qll linguist-generated /lib/codeql/rust/elements/internal/TypeRefImpl.qll linguist-generated /lib/codeql/rust/elements/internal/UnderscoreExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/UnderscoreExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/UnextractedImpl.qll linguist-generated /lib/codeql/rust/elements/internal/UnimplementedConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/UnimplementedImpl.qll linguist-generated @@ -446,9 +406,7 @@ /lib/codeql/rust/elements/internal/WherePredConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/WherePredImpl.qll linguist-generated /lib/codeql/rust/elements/internal/WhileExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/WhileExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/WildcardPatConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/WildcardPatImpl.qll linguist-generated /lib/codeql/rust/elements/internal/YeetExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/YeetExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/YieldExprConstructor.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/elements/internal/ArrayExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ArrayExprImpl.qll index ff4ce224820..8bda9a2d46e 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ArrayExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ArrayExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `ArrayExpr`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.ArrayExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * An array expression. For example: * ```rust @@ -19,5 +19,7 @@ module Impl { * [1; 10]; * ``` */ - class ArrayExpr extends Generated::ArrayExpr { } + class ArrayExpr extends Generated::ArrayExpr { + override string toString() { result = "[...]" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/AwaitExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/AwaitExprImpl.qll index 39bbe3017df..17abcfdaaba 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/AwaitExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/AwaitExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `AwaitExpr`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.AwaitExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * An `await` expression. For example: * ```rust @@ -21,5 +21,7 @@ module Impl { * } * ``` */ - class AwaitExpr extends Generated::AwaitExpr { } + class AwaitExpr extends Generated::AwaitExpr { + override string toString() { result = "await ..." } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/BecomeExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/BecomeExprImpl.qll index 748659cfdd3..806e1d7506d 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/BecomeExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/BecomeExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `BecomeExpr`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.BecomeExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A `become` expression. For example: * ```rust @@ -24,5 +24,7 @@ module Impl { * } * ``` */ - class BecomeExpr extends Generated::BecomeExpr { } + class BecomeExpr extends Generated::BecomeExpr { + override string toString() { result = "become ..." } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/BlockExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/BlockExprImpl.qll index 9011109b194..bdfc8a56d7d 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/BlockExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/BlockExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `BlockExpr`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.BlockExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A block expression. For example: * ```rust @@ -26,5 +26,7 @@ module Impl { * } * ``` */ - class BlockExpr extends Generated::BlockExpr { } + class BlockExpr extends Generated::BlockExpr { + override string toString() { result = "{ ... }" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/BoxPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/BoxPatImpl.qll index 06fb2c0fbfa..5c6ffe229eb 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/BoxPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/BoxPatImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `BoxPat`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.BoxPat * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A box pattern. For example: * ```rust @@ -21,5 +21,7 @@ module Impl { * }; * ``` */ - class BoxPat extends Generated::BoxPat { } + class BoxPat extends Generated::BoxPat { + override string toString() { result = "box ..." } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll index 4b302674a44..49bca4b25a2 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll @@ -102,5 +102,17 @@ module Impl { isLabelled(result, label) ) } + + override string toString() { + exists(string label, string expr | + ( + result = " " + this.getLifetime().toString() + or + not this.hasLifetime() and result = "" + ) and + (if this.hasExpr() then expr = " ..." else expr = "") and + result = "break" + label + expr + ) + } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll index c03a7b9ac13..8b0ae58e2d9 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `CallExpr`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.CallExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A function call expression. For example: * ```rust @@ -21,5 +21,7 @@ module Impl { * foo(1) = 4; * ``` */ - class CallExpr extends Generated::CallExpr { } + class CallExpr extends Generated::CallExpr { + override string toString() { result = "... (...)" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/CastExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CastExprImpl.qll index 308c321dfbd..3d021e4955d 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CastExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CastExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `CastExpr`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.CastExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A cast expression. For example: * ```rust * value as u64; * ``` */ - class CastExpr extends Generated::CastExpr { } + class CastExpr extends Generated::CastExpr { + override string toString() { result = "... as " + this.getTy().toString() } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ClosureExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ClosureExprImpl.qll index b1c6574b17f..861a258ec8e 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ClosureExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ClosureExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `ClosureExpr`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.ClosureExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A closure expression. For example: * ```rust @@ -24,5 +24,7 @@ module Impl { * static |x| yield x; * ``` */ - class ClosureExpr extends Generated::ClosureExpr { } + class ClosureExpr extends Generated::ClosureExpr { + override string toString() { result = "|...| ..." } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.qll index 32a4f415ab7..2e7beca481d 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.qll @@ -20,11 +20,20 @@ module Impl { * ``` */ class Comment extends Generated::Comment { + override string getText() { result = this.getCommentMarker() + " ..." } + /** * Gets the text of this comment, excluding the comment marker. */ string getCommentText() { exists(string s | s = this.getText() | result = s.regexpCapture("///?\\s*(.*)", 1)) } + + /** + * Gets the marker of this comment, that is `//` or `///`. + */ + string getCommentMarker() { + exists(string s | s = this.getText() | result = s.regexpCapture("(///?).*", 1)) + } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll index 4328fdfc9f9..8c67382498c 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll @@ -49,6 +49,17 @@ module Impl { * ``` */ class ContinueExpr extends Generated::ContinueExpr { + override string toString() { + exists(string label | + ( + label = " " + this.getLifetime().getText() + or + not this.hasLifetime() and label = "" + ) and + result = "continue" + label + ) + } + /** * Gets the target of this `continue` expression. * diff --git a/rust/ql/lib/codeql/rust/elements/internal/EnumImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/EnumImpl.qll index bef9d3da903..532fa3ed0b3 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/EnumImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/EnumImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `Enum`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.Enum * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A Enum. For example: * ```rust * todo!() * ``` */ - class Enum extends Generated::Enum { } + class Enum extends Generated::Enum { + override string toString() { result = "enum " + this.getName().toString() } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/FieldExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/FieldExprImpl.qll index 003d2789e68..ccfcc4fd7b7 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/FieldExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/FieldExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `FieldExpr`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.FieldExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A field access expression. For example: * ```rust * x.foo * ``` */ - class FieldExpr extends Generated::FieldExpr { } + class FieldExpr extends Generated::FieldExpr { + override string toString() { result = "... ." + this.getNameRef().toString() } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/FunctionImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/FunctionImpl.qll index bff68da5620..791cf4f9d7f 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/FunctionImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/FunctionImpl.qll @@ -25,6 +25,6 @@ module Impl { * ``` */ class Function extends Generated::Function { - override string toString() { result = this.getName().getText() } + override string toString() { result = "fn " + this.getName().getText() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/IfExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/IfExprImpl.qll index f9aec6faed3..59c0638c42e 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/IfExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/IfExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `IfExpr`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.IfExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * An `if` expression. For example: * ```rust @@ -27,5 +27,12 @@ module Impl { * }; * ``` */ - class IfExpr extends Generated::IfExpr { } + class IfExpr extends Generated::IfExpr { + override string toString() { + exists(string elseString | + (if this.hasElse() then elseString = " else { ... }" else elseString = "") and + result = "if ... { ... }" + elseString + ) + } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll index b1918d16e56..d8ec0ca9d37 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `Impl`. * @@ -12,11 +11,23 @@ private import codeql.rust.elements.internal.generated.Impl * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A Impl. For example: * ```rust * todo!() * ``` */ - class Impl extends Generated::Impl { } + class Impl extends Generated::Impl { + override string toString() { + exists(string trait | + ( + trait = this.getTrait().toString() + " for " + or + not this.hasTrait() and trait = "" + ) and + result = "impl " + trait + this.getSelfTy().toString() + " { ... }" + ) + } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll index 94ff116cf1d..28db84aa873 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `IndexExpr`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.IndexExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * An index expression. For example: * ```rust @@ -19,5 +19,7 @@ module Impl { * list[42] = 1; * ``` */ - class IndexExpr extends Generated::IndexExpr { } + class IndexExpr extends Generated::IndexExpr { + override string toString() { result = "...[...]" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LabelImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LabelImpl.qll index 6740bb23ea8..e1b3eb4e4d7 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LabelImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LabelImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `Label`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.Label * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A label. For example: * ```rust @@ -21,5 +21,7 @@ module Impl { * }; * ``` */ - class Label extends Generated::Label { } + class Label extends Generated::Label { + override string toString() { result = this.getLifetime().toString() } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LetElseImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LetElseImpl.qll index 2399964cf1a..7924d8d8453 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LetElseImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LetElseImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `LetElse`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.LetElse * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A LetElse. For example: * ```rust * todo!() * ``` */ - class LetElse extends Generated::LetElse { } + class LetElse extends Generated::LetElse { + override string toString() { result = "else { ... }" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LetExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LetExprImpl.qll index 4a99a43ba0f..8a54a005cf5 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LetExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LetExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `LetExpr`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.LetExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A `let` expression. For example: * ```rust @@ -20,5 +20,12 @@ module Impl { * } * ``` */ - class LetExpr extends Generated::LetExpr { } + class LetExpr extends Generated::LetExpr { + override string toString() { + exists(string expr | + (if this.hasExpr() then expr = " = ..." else expr = "") and + result = "let " + this.getPat().toString() + expr + ) + } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LetStmtImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LetStmtImpl.qll index 2bcaa6d7905..fce6aa3de44 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LetStmtImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LetStmtImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `LetStmt`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.LetStmt * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A let statement. For example: * ```rust @@ -25,5 +25,13 @@ module Impl { * }; * ``` */ - class LetStmt extends Generated::LetStmt { } + class LetStmt extends Generated::LetStmt { + override string toString() { + exists(string expr, string elseStr | + (if this.hasInitializer() then expr = " = ..." else expr = "") and + (if this.hasLetElse() then elseStr = " else { ... }" else elseStr = "") and + result = "let " + this.getPat().toString() + expr + elseStr + ) + } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LifetimeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LifetimeImpl.qll index 3eb13ac87e5..a51bf3c6b12 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LifetimeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LifetimeImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `Lifetime`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.Lifetime * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A Lifetime. For example: * ```rust * todo!() * ``` */ - class Lifetime extends Generated::Lifetime { } + class Lifetime extends Generated::Lifetime { + override string toString() { result = "'" + this.getText() } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LiteralPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LiteralPatImpl.qll index a71d9b1bf84..5bf0c13576a 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LiteralPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LiteralPatImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `LiteralPat`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.LiteralPat * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A literal pattern. For example: * ```rust @@ -21,5 +21,7 @@ module Impl { * } * ``` */ - class LiteralPat extends Generated::LiteralPat { } + class LiteralPat extends Generated::LiteralPat { + override string toString() { result = this.getLiteral().toString() } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LoopExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LoopExprImpl.qll index c56ea8770d4..f91a14489c5 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LoopExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LoopExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `LoopExpr`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.LoopExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A loop expression. For example: * ```rust @@ -36,5 +36,7 @@ module Impl { * }; * ``` */ - class LoopExpr extends Generated::LoopExpr { } + class LoopExpr extends Generated::LoopExpr { + override string toString() { result = "loop {...}" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/MacroCallImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/MacroCallImpl.qll index 76fcd7645a6..eed9a65d432 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/MacroCallImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/MacroCallImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `MacroCall`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.MacroCall * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A MacroCall. For example: * ```rust * todo!() * ``` */ - class MacroCall extends Generated::MacroCall { } + class MacroCall extends Generated::MacroCall { + override string toString() { result = this.getPath().toString() + "!..." } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/MatchArmImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/MatchArmImpl.qll index 117e6eb3498..280eb4ea7c8 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/MatchArmImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/MatchArmImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `MatchArm`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.MatchArm * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A match arm. For example: * ```rust @@ -27,5 +27,12 @@ module Impl { * }; * ``` */ - class MatchArm extends Generated::MatchArm { } + class MatchArm extends Generated::MatchArm { + override string toString() { + exists(string guard | + (if this.hasGuard() then guard = "if ... " else guard = "") and + result = this.getPat().toString() + guard + " => ..." + ) + } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll index c8cb535b526..530e9cc50a7 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll @@ -28,6 +28,8 @@ module Impl { * ``` */ class MatchExpr extends Generated::MatchExpr { + override string toString() { result = "match ... { ... }" } + /** * Gets the `index`th arm of this match expression. */ diff --git a/rust/ql/lib/codeql/rust/elements/internal/ModuleImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ModuleImpl.qll index 2e94fad609c..505495862b7 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ModuleImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ModuleImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `Module`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.Module * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A module declaration. For example: * ```rust @@ -23,5 +23,7 @@ module Impl { * } * ``` */ - class Module extends Generated::Module { } + class Module extends Generated::Module { + override string toString() { result = "mod " + this.getName() } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/NeverTypeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/NeverTypeImpl.qll index 9c04237f38c..985ec81cdeb 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/NeverTypeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/NeverTypeImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `NeverType`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.NeverType * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A NeverType. For example: * ```rust * todo!() * ``` */ - class NeverType extends Generated::NeverType { } + class NeverType extends Generated::NeverType { + override string toString() { result = "!" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/OrPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/OrPatImpl.qll index f29e3d1865f..ffc3fb3d5b8 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/OrPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/OrPatImpl.qll @@ -21,6 +21,8 @@ module Impl { * ``` */ class OrPat extends Generated::OrPat { + override string toString() { result = "... | ..." } + /** Gets the last pattern in this or pattern. */ pragma[nomagic] Pat getLastPat() { result = this.getPat(this.getNumberOfPats() - 1) } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll index 7015d097e9f..5a961383094 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `Param`. * @@ -12,11 +11,16 @@ private import codeql.rust.elements.internal.generated.Param * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A Param. For example: * ```rust * todo!() * ``` */ - class Param extends Generated::Param { } + class Param extends Generated::Param { + override string toString() { + result = this.getPat().toString() + ": " + this.getTy().toString() + } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ParenExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ParenExprImpl.qll index 98c3cab9267..5dce4634340 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ParenExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ParenExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `ParenExpr`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.ParenExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A ParenExpr. For example: * ```rust * todo!() * ``` */ - class ParenExpr extends Generated::ParenExpr { } + class ParenExpr extends Generated::ParenExpr { + override string toString() { result = "(...)" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ParenPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ParenPatImpl.qll index cdba455451c..5eb8a486030 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ParenPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ParenPatImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `ParenPat`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.ParenPat * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A ParenPat. For example: * ```rust * todo!() * ``` */ - class ParenPat extends Generated::ParenPat { } + class ParenPat extends Generated::ParenPat { + override string toString() { result = "(...)" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ParenTypeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ParenTypeImpl.qll index ab49c9c4fcf..95c022d651a 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ParenTypeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ParenTypeImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `ParenType`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.ParenType * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A ParenType. For example: * ```rust * todo!() * ``` */ - class ParenType extends Generated::ParenType { } + class ParenType extends Generated::ParenType { + override string toString() { result = "(...)" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/PathPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/PathPatImpl.qll index 0acf7a588ba..2c6d94cbcce 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/PathPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/PathPatImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `PathPat`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.PathPat * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A path pattern. For example: * ```rust @@ -21,5 +21,7 @@ module Impl { * } * ``` */ - class PathPat extends Generated::PathPat { } + class PathPat extends Generated::PathPat { + override string toString() { result = this.getPath().toString() } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll index 74fa536e08b..9c2f4e50052 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `PathType`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.PathType * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A PathType. For example: * ```rust * todo!() * ``` */ - class PathType extends Generated::PathType { } + class PathType extends Generated::PathType { + override string toString() { result = this.getPath().toString() } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/RangeExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RangeExprImpl.qll index c015171253f..53dccb24fbd 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RangeExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RangeExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `RangeExpr`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.RangeExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A range expression. For example: * ```rust @@ -23,5 +23,7 @@ module Impl { * let x = ..; * ``` */ - class RangeExpr extends Generated::RangeExpr { } + class RangeExpr extends Generated::RangeExpr { + override string toString() { result = "... " + this.getOperatorName().toString() + " ..." } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/RecordExprFieldImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RecordExprFieldImpl.qll index 12b86bb1e4a..f5462ab29c3 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RecordExprFieldImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RecordExprFieldImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `RecordExprField`. * @@ -12,11 +11,19 @@ private import codeql.rust.elements.internal.generated.RecordExprField * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A field in a record expression. For example `a: 1` in: * ```rust * Foo { a: 1, b: 2 }; * ``` */ - class RecordExprField extends Generated::RecordExprField { } + class RecordExprField extends Generated::RecordExprField { + override string toString() { + exists(string init | + (if this.hasExpr() then init = ": ..." else init = "") and + result = this.getNameRef().toString() + init + ) + } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/RecordExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RecordExprImpl.qll index befc9b26ebb..a59d3bc22e2 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RecordExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RecordExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `RecordExpr`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.RecordExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A record expression. For example: * ```rust @@ -21,5 +21,7 @@ module Impl { * Foo { .. } = second; * ``` */ - class RecordExpr extends Generated::RecordExpr { } + class RecordExpr extends Generated::RecordExpr { + override string toString() { result = this.getPath().toString() + " {...}" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/RecordPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RecordPatImpl.qll index 6378e3220e0..39ccad02065 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RecordPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RecordPatImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `RecordPat`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.RecordPat * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A record pattern. For example: * ```rust @@ -21,5 +21,7 @@ module Impl { * } * ``` */ - class RecordPat extends Generated::RecordPat { } + class RecordPat extends Generated::RecordPat { + override string toString() { result = this.getPath().toString() + " {...}" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/RefExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RefExprImpl.qll index abc45e0d5c2..cf3ade0ad14 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RefExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RefExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `RefExpr`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.RefExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A reference expression. For example: * ```rust @@ -21,5 +21,14 @@ module Impl { * let raw_mut: &mut i32 = &raw mut foo; * ``` */ - class RefExpr extends Generated::RefExpr { } + class RefExpr extends Generated::RefExpr { + override string toString() { + exists(string raw, string const, string mut | + (if this.isRaw() then raw = "raw " else raw = "") and + (if this.isConst() then const = "const " else const = "") and + (if this.isMut() then mut = "mut " else mut = "") and + result = "&" + raw + const + mut + "..." + ) + } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/RefPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RefPatImpl.qll index 03b1abf5a4f..a28574c1c07 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RefPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RefPatImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `RefPat`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.RefPat * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A reference pattern. For example: * ```rust @@ -21,5 +21,12 @@ module Impl { * }; * ``` */ - class RefPat extends Generated::RefPat { } + class RefPat extends Generated::RefPat { + override string toString() { + exists(string mut | + (if this.isMut() then mut = "mut " else mut = "") and + result = "&" + mut + "..." + ) + } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/RestPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RestPatImpl.qll index bd483e4ba9a..a4ae812b72b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RestPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RestPatImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `RestPat`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.RestPat * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A RestPat. For example: * ```rust * todo!() * ``` */ - class RestPat extends Generated::RestPat { } + class RestPat extends Generated::RestPat { + override string toString() { result = ".." } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ReturnExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ReturnExprImpl.qll index fd185c01b1d..245f7e873ac 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ReturnExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ReturnExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `ReturnExpr`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.ReturnExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A return expression. For example: * ```rust @@ -25,5 +25,9 @@ module Impl { * } * ``` */ - class ReturnExpr extends Generated::ReturnExpr { } + class ReturnExpr extends Generated::ReturnExpr { + override string toString() { + if this.hasExpr() then result = "return ..." else result = "return" + } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/TraitImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/TraitImpl.qll index a6fa19517f4..59d685a18e8 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/TraitImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/TraitImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `Trait`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.Trait * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A Trait. For example: * ``` @@ -24,5 +24,7 @@ module Impl { * pub trait Foo where T::Frobinator: Eq {} * ``` */ - class Trait extends Generated::Trait { } + class Trait extends Generated::Trait { + override string toString() { result = "trait " + this.getName() } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/UnderscoreExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/UnderscoreExprImpl.qll index 03709c54b54..26487fbfe4f 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/UnderscoreExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/UnderscoreExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `UnderscoreExpr`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.UnderscoreExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * An underscore expression. For example: * ```rust * _ = 42; * ``` */ - class UnderscoreExpr extends Generated::UnderscoreExpr { } + class UnderscoreExpr extends Generated::UnderscoreExpr { + override string toString() { result = "_" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/WhileExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/WhileExprImpl.qll index 647864d4659..43f9510be1b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/WhileExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/WhileExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `WhileExpr`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.WhileExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A WhileExpr. For example: * ```rust * todo!() * ``` */ - class WhileExpr extends Generated::WhileExpr { } + class WhileExpr extends Generated::WhileExpr { + override string toString() { result = "while ... { ... }" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/WildcardPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/WildcardPatImpl.qll index d12e49e1daa..d7973866d91 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/WildcardPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/WildcardPatImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `WildcardPat`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.WildcardPat * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A wildcard pattern. For example: * ```rust * let _ = 42; * ``` */ - class WildcardPat extends Generated::WildcardPat { } + class WildcardPat extends Generated::WildcardPat { + override string toString() { result = "_" } + } } From a398f707fe50aa119dc200f1aa991dd5dca1a0da Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 19 Nov 2024 16:34:59 +0000 Subject: [PATCH 098/470] Add some test cases for flow involving global variables and captured variables --- .../global-or-captured-vars/test.expected | 4 + .../dataflow/global-or-captured-vars/test.py | 88 +++++++++++++++++++ .../dataflow/global-or-captured-vars/test.ql | 3 + 3 files changed, 95 insertions(+) create mode 100644 python/ql/test/library-tests/dataflow/global-or-captured-vars/test.expected create mode 100644 python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py create mode 100644 python/ql/test/library-tests/dataflow/global-or-captured-vars/test.ql diff --git a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.expected b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.expected new file mode 100644 index 00000000000..366de37b867 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.expected @@ -0,0 +1,4 @@ +argumentToEnsureNotTaintedNotMarkedAsSpurious +untaintedArgumentToEnsureTaintedNotMarkedAsMissing +testFailures +failures diff --git a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py new file mode 100644 index 00000000000..3874d67e4a4 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py @@ -0,0 +1,88 @@ +import threading +import time + +# Test 1 +# TP - Flow is tracked through a global variable +foo1 = None + +def bar1(): + time.sleep(1) + ensure_tainted(foo1) # $tainted + +# The intent of these tests is to test how dataflow is handled through shared state accessed by different threads; +# but the presense or absense of the actual call to start a thread does not affect the results (there is no special modelling for Thread) +# threading.Thread(target=bar).start() + +foo1 = TAINTED_STRING + +# Test 2 +# FN - Flow is *not* tracked through an access path on a global variable +foo2 = [] + +def bar2(): + time.sleep(1) + ensure_tainted(foo2[0]) # $MISSING:tainted + +threading.Thread(target=bar2).start() + +foo2.append(TAINTED_STRING) + +# Test 3 +# FN - Flow is not found even when there is a direct call +foo3 = [] + +def bar3(): + time.sleep(1) + ensure_tainted(foo2[0]) # $MISSING:tainted + +foo3.append(TAINTED_STRING) +bar3() + +# Tast 4 +# TP - Sanity check: Flow is found through a ListElement directly without a call +foo4 = [] +foo4.append(TAINTED_STRING) +ensure_tainted(foo4[0]) # $tainted + +# Test 5 +# FN - Flow is *not* tracked through a shared captured but non-global variable +def test5(): + foo5 = None + + def bar5(): + time.sleep(1) + ensure_tainted(foo5) # $MISSING:tainted + + threading.Thread(target=bar5).start() # Only the presense of this thread call makes this an FN rather than a TN + + foo5 = TAINTED_STRING + + # Test 6 + # TP - Flow is tracked through a shared captured but non-global variable with a direct call +def test6(): + foo6 = [] + + def bar6(): + time.sleep(1) + ensure_tainted(foo[0]) # $tainted + + foo6.append(TAINTED_STRING) + bar6() + + +# Test 7 +# FN - Flow is *not* found through an access path on a global variable that's also used as a parameter +# We'd like to cover this case in order to be able to cover this CVE: https://github.com/github/codeql-python-CVE-coverage/issues/3176 + +foo7 = [] + +def bar7(): + time.sleep(1) + ensure_tainted(foo7[0]) # $MISSING: tainted + +def baz7(loc_foo): + loc_foo.append(TAINTED_STRING) + +threading.Thread(target=bar7).start() + +baz7(foo7) \ No newline at end of file diff --git a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.ql b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.ql new file mode 100644 index 00000000000..dd01b5d3e34 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.ql @@ -0,0 +1,3 @@ +import python +import experimental.meta.InlineTaintTest +import MakeInlineTaintTest From fce13aeb352035acb7b193cd8bc367a3e17000ea Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 19 Nov 2024 17:50:14 +0100 Subject: [PATCH 099/470] Rust: accept test changes --- .../canonical_path/canonical_paths.expected | 54 ++++++++-------- .../generated/ArrayExpr/ArrayExpr.expected | 4 +- .../ArrayExpr/ArrayExpr_getExpr.expected | 10 +-- .../AsmExpr/AsmExpr_getExpr.expected | 2 +- .../generated/AwaitExpr/AwaitExpr.expected | 2 +- .../AwaitExpr/AwaitExpr_getExpr.expected | 2 +- .../generated/BecomeExpr/BecomeExpr.expected | 2 +- .../BecomeExpr/BecomeExpr_getExpr.expected | 2 +- .../generated/BlockExpr/BlockExpr.expected | 6 +- .../BlockExpr/BlockExpr_getLabel.expected | 2 +- .../BlockExpr/BlockExpr_getStmtList.expected | 6 +- .../generated/BoxPat/BoxPat.expected | 4 +- .../generated/BoxPat/BoxPat_getPat.expected | 4 +- .../generated/BreakExpr/BreakExpr.expected | 6 +- .../BreakExpr/BreakExpr_getExpr.expected | 4 +- .../BreakExpr/BreakExpr_getLifetime.expected | 4 +- .../generated/CallExpr/CallExpr.expected | 8 +-- .../CallExpr/CallExpr_getArgList.expected | 8 +-- .../CallExpr/CallExpr_getExpr.expected | 8 +-- .../generated/CastExpr/CastExpr.expected | 2 +- .../CastExpr/CastExpr_getExpr.expected | 2 +- .../CastExpr/CastExpr_getTy.expected | 2 +- .../ClosureExpr/ClosureExpr.expected | 10 +-- .../ClosureExpr/ClosureExpr_getAttr.expected | 4 +- .../ClosureExpr/ClosureExpr_getBody.expected | 10 +-- .../ClosureExpr_getParamList.expected | 10 +-- .../ClosureExpr_getRetType.expected | 2 +- .../ConstBlockPat_getBlockExpr.expected | 2 +- .../ContinueExpr/ContinueExpr.expected | 4 +- .../ContinueExpr_getLifetime.expected | 2 +- .../ExprStmt/ExprStmt_getExpr.expected | 4 +- .../generated/FieldExpr/FieldExpr.expected | 2 +- .../FieldExpr/FieldExpr_getExpr.expected | 2 +- .../FieldExpr/FieldExpr_getNameRef.expected | 2 +- .../generated/Function/Function.expected | 4 +- .../Function/Function_getBody.expected | 2 +- .../Function/Function_getCrateOrigin.expected | 4 +- ...Function_getExtendedCanonicalPath.expected | 4 +- .../Function/Function_getName.expected | 4 +- .../Function/Function_getParamList.expected | 4 +- .../Function/Function_getRetType.expected | 2 +- .../generated/IfExpr/IfExpr.expected | 4 +- .../IfExpr/IfExpr_getCondition.expected | 4 +- .../generated/IfExpr/IfExpr_getElse.expected | 2 +- .../generated/IfExpr/IfExpr_getThen.expected | 4 +- .../generated/IndexExpr/IndexExpr.expected | 4 +- .../IndexExpr/IndexExpr_getBase.expected | 4 +- .../IndexExpr/IndexExpr_getIndex.expected | 4 +- .../generated/Label/Label.expected | 2 +- .../Label/Label_getLifetime.expected | 2 +- .../generated/LetExpr/LetExpr.expected | 2 +- .../LetExpr/LetExpr_getExpr.expected | 2 +- .../generated/LetExpr/LetExpr_getPat.expected | 2 +- .../generated/LetStmt/LetStmt.expected | 12 ++-- .../LetStmt/LetStmt_getInitializer.expected | 8 +-- .../LetStmt/LetStmt_getLetElse.expected | 2 +- .../generated/LetStmt/LetStmt_getPat.expected | 12 ++-- .../generated/LetStmt/LetStmt_getTy.expected | 4 +- .../generated/LiteralPat/LiteralPat.expected | 2 +- .../LiteralPat/LiteralPat_getLiteral.expected | 2 +- .../generated/LoopExpr/LoopExpr.expected | 6 +- .../LoopExpr/LoopExpr_getLabel.expected | 2 +- .../LoopExpr/LoopExpr_getLoopBody.expected | 6 +- .../generated/MacroCall/MacroCall.expected | 2 +- .../MacroCall/MacroCall_getExpanded.expected | 2 +- .../MacroCall/MacroCall_getPath.expected | 2 +- .../MacroCall/MacroCall_getTokenTree.expected | 2 +- .../MacroExpr/MacroExpr_getMacroCall.expected | 2 +- .../CONSISTENCY/DataFlowConsistency.expected | 4 +- .../MacroItems/MacroItems_getItem.expected | 2 +- .../MacroStmts/MacroStmts_getExpr.expected | 2 +- .../generated/MatchArm/MatchArm.expected | 8 +-- .../MatchArm/MatchArm_getGuard.expected | 2 +- .../MatchArm/MatchArm_getPat.expected | 8 +-- .../generated/MatchExpr/MatchExpr.expected | 4 +- .../MatchExpr/MatchExpr_getExpr.expected | 4 +- .../MatchExpr_getMatchArmList.expected | 4 +- .../generated/Module/Module.expected | 6 +- .../Module/Module_getCrateOrigin.expected | 6 +- .../Module_getExtendedCanonicalPath.expected | 6 +- .../Module/Module_getItemList.expected | 2 +- .../generated/Module/Module_getName.expected | 6 +- .../OffsetOfExpr/OffsetOfExpr_getTy.expected | 2 +- .../generated/OrPat/OrPat.expected | 2 +- .../generated/OrPat/OrPat_getPat.expected | 4 +- .../generated/PathPat/PathPat.expected | 2 +- .../PathPat/PathPat_getPath.expected | 2 +- .../generated/RangeExpr/RangeExpr.expected | 12 ++-- .../RangeExpr/RangeExpr_getEnd.expected | 8 +-- .../RangeExpr_getOperatorName.expected | 12 ++-- .../RangeExpr/RangeExpr_getStart.expected | 6 +- .../RangePat/RangePat_getEnd.expected | 4 +- .../RangePat/RangePat_getStart.expected | 4 +- .../generated/RecordExpr/RecordExpr.expected | 8 +-- .../RecordExpr/RecordExpr_getPath.expected | 8 +-- ...RecordExpr_getRecordExprFieldList.expected | 8 +-- .../RecordExprField/RecordExprField.expected | 4 +- .../RecordExprField_getExpr.expected | 4 +- .../RecordExprField_getNameRef.expected | 4 +- .../generated/RecordPat/RecordPat.expected | 4 +- .../RecordPat/RecordPat_getPath.expected | 4 +- .../RecordPat_getRecordPatFieldList.expected | 4 +- .../RecordPatField_getPat.expected | 4 +- .../generated/RefExpr/RefExpr.expected | 8 +-- .../RefExpr/RefExpr_getExpr.expected | 8 +-- .../generated/RefPat/RefPat.expected | 4 +- .../generated/RefPat/RefPat_getPat.expected | 4 +- .../generated/ReturnExpr/ReturnExpr.expected | 4 +- .../ReturnExpr/ReturnExpr_getExpr.expected | 2 +- .../SlicePat/SlicePat_getPat.expected | 20 +++--- .../SourceFile/SourceFile_getItem.expected | 4 +- .../Trait/AssocItemList_getAssocItem.expected | 2 +- .../generated/Trait/Trait.expected | 4 +- .../Trait/Trait_getAssocItemList.expected | 4 +- .../Trait/Trait_getCrateOrigin.expected | 4 +- .../Trait_getExtendedCanonicalPath.expected | 4 +- .../Trait/Trait_getGenericParamList.expected | 2 +- .../generated/Trait/Trait_getName.expected | 4 +- .../Trait/Trait_getVisibility.expected | 2 +- .../Trait/Trait_getWhereClause.expected | 2 +- .../TuplePat/TuplePat_getField.expected | 2 +- .../TupleStructPat_getField.expected | 14 ++-- .../UnderscoreExpr/UnderscoreExpr.expected | 2 +- .../WildcardPat/WildcardPat.expected | 2 +- .../ql/test/extractor-tests/utf8/ast.expected | 16 ++--- .../controlflow-unstable/Cfg.expected | 64 +++++++++---------- .../dataflow/global/viableCallable.expected | 48 +++++++------- .../dataflow/local/DataFlowStep.expected | 58 ++++++++--------- .../test/library-tests/variables/Ssa.expected | 16 ++--- .../DataFlowConsistencyCounts.expected | 2 +- .../diagnostics/SummaryStats.expected | 2 +- .../CONSISTENCY/DataFlowConsistency.expected | 14 ++++ 132 files changed, 417 insertions(+), 403 deletions(-) diff --git a/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected b/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected index 622652e091f..d9919af198c 100644 --- a/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected +++ b/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected @@ -1,36 +1,36 @@ canonicalPaths -| canonical_paths.rs:1:1:34:1 | Module | repo::test | crate::canonical_paths::a | +| canonical_paths.rs:1:1:34:1 | mod a | repo::test | crate::canonical_paths::a | | canonical_paths.rs:2:5:3:22 | Struct | repo::test | crate::canonical_paths::a::Struct | -| canonical_paths.rs:5:5:7:5 | Trait | repo::test | crate::canonical_paths::a::Trait | -| canonical_paths.rs:6:9:6:20 | f | repo::test | crate::canonical_paths::a::Trait::f | -| canonical_paths.rs:9:5:11:5 | Impl | None | None | -| canonical_paths.rs:10:9:10:22 | f | repo::test | ::f | -| canonical_paths.rs:13:5:15:5 | Impl | None | None | -| canonical_paths.rs:14:9:14:22 | g | repo::test | ::g | -| canonical_paths.rs:17:5:19:5 | Trait | repo::test | crate::canonical_paths::a::TraitWithBlanketImpl | -| canonical_paths.rs:18:9:18:20 | h | repo::test | crate::canonical_paths::a::TraitWithBlanketImpl::h | -| canonical_paths.rs:21:5:23:5 | Impl | None | None | -| canonical_paths.rs:22:9:22:22 | h | repo::test | <_ as crate::canonical_paths::a::TraitWithBlanketImpl>::h | -| canonical_paths.rs:25:5:25:16 | free | repo::test | crate::canonical_paths::a::free | -| canonical_paths.rs:27:5:33:5 | usage | repo::test | crate::canonical_paths::a::usage | -| canonical_paths.rs:36:1:73:1 | Module | repo::test | crate::canonical_paths::without | +| canonical_paths.rs:5:5:7:5 | trait Trait | repo::test | crate::canonical_paths::a::Trait | +| canonical_paths.rs:6:9:6:20 | fn f | repo::test | crate::canonical_paths::a::Trait::f | +| canonical_paths.rs:9:5:11:5 | impl Trait for Struct { ... } | None | None | +| canonical_paths.rs:10:9:10:22 | fn f | repo::test | ::f | +| canonical_paths.rs:13:5:15:5 | impl Struct { ... } | None | None | +| canonical_paths.rs:14:9:14:22 | fn g | repo::test | ::g | +| canonical_paths.rs:17:5:19:5 | trait TraitWithBlanketImpl | repo::test | crate::canonical_paths::a::TraitWithBlanketImpl | +| canonical_paths.rs:18:9:18:20 | fn h | repo::test | crate::canonical_paths::a::TraitWithBlanketImpl::h | +| canonical_paths.rs:21:5:23:5 | impl TraitWithBlanketImpl for T { ... } | None | None | +| canonical_paths.rs:22:9:22:22 | fn h | repo::test | <_ as crate::canonical_paths::a::TraitWithBlanketImpl>::h | +| canonical_paths.rs:25:5:25:16 | fn free | repo::test | crate::canonical_paths::a::free | +| canonical_paths.rs:27:5:33:5 | fn usage | repo::test | crate::canonical_paths::a::usage | +| canonical_paths.rs:36:1:73:1 | mod without | repo::test | crate::canonical_paths::without | | canonical_paths.rs:37:5:37:24 | Use | None | None | -| canonical_paths.rs:39:5:68:5 | canonicals | repo::test | crate::canonical_paths::without::canonicals | +| canonical_paths.rs:39:5:68:5 | fn canonicals | repo::test | crate::canonical_paths::without::canonicals | | canonical_paths.rs:40:9:40:27 | Struct | repo::test | {34}::OtherStruct | -| canonical_paths.rs:42:9:44:9 | Trait | repo::test | {34}::OtherTrait | -| canonical_paths.rs:43:13:43:24 | g | repo::test | {34}::OtherTrait::g | -| canonical_paths.rs:46:9:48:9 | Impl | None | None | -| canonical_paths.rs:47:13:47:26 | g | repo::test | <{34}::OtherStruct as {34}::OtherTrait>::g | -| canonical_paths.rs:50:9:52:9 | Impl | None | None | -| canonical_paths.rs:51:13:51:26 | g | repo::test | ::g | -| canonical_paths.rs:54:9:56:9 | Impl | None | None | -| canonical_paths.rs:55:13:55:26 | f | repo::test | <{34}::OtherStruct as crate::canonical_paths::a::Trait>::f | -| canonical_paths.rs:58:9:60:9 | nested | repo::test | {34}::nested | +| canonical_paths.rs:42:9:44:9 | trait OtherTrait | repo::test | {34}::OtherTrait | +| canonical_paths.rs:43:13:43:24 | fn g | repo::test | {34}::OtherTrait::g | +| canonical_paths.rs:46:9:48:9 | impl OtherTrait for OtherStruct { ... } | None | None | +| canonical_paths.rs:47:13:47:26 | fn g | repo::test | <{34}::OtherStruct as {34}::OtherTrait>::g | +| canonical_paths.rs:50:9:52:9 | impl OtherTrait for crate::canonical_paths::a::Struct { ... } | None | None | +| canonical_paths.rs:51:13:51:26 | fn g | repo::test | ::g | +| canonical_paths.rs:54:9:56:9 | impl crate::canonical_paths::a::Trait for OtherStruct { ... } | None | None | +| canonical_paths.rs:55:13:55:26 | fn f | repo::test | <{34}::OtherStruct as crate::canonical_paths::a::Trait>::f | +| canonical_paths.rs:58:9:60:9 | fn nested | repo::test | {34}::nested | | canonical_paths.rs:59:13:59:31 | Struct | repo::test | {35}::OtherStruct | -| canonical_paths.rs:62:9:67:9 | usage | repo::test | {34}::usage | -| canonical_paths.rs:70:5:72:5 | other | repo::test | crate::canonical_paths::without::other | +| canonical_paths.rs:62:9:67:9 | fn usage | repo::test | {34}::usage | +| canonical_paths.rs:70:5:72:5 | fn other | repo::test | crate::canonical_paths::without::other | | canonical_paths.rs:71:9:71:27 | Struct | repo::test | {36}::OtherStruct | -| lib.rs:1:1:1:20 | Module | repo::test | crate::canonical_paths | +| lib.rs:1:1:1:20 | mod canonical_paths | repo::test | crate::canonical_paths | resolvedPaths | canonical_paths.rs:2:7:2:12 | derive | None | None | | canonical_paths.rs:9:10:9:14 | Trait | repo::test | crate::canonical_paths::a::Trait | diff --git a/rust/ql/test/extractor-tests/generated/ArrayExpr/ArrayExpr.expected b/rust/ql/test/extractor-tests/generated/ArrayExpr/ArrayExpr.expected index 549f43fc989..e1ab176fe51 100644 --- a/rust/ql/test/extractor-tests/generated/ArrayExpr/ArrayExpr.expected +++ b/rust/ql/test/extractor-tests/generated/ArrayExpr/ArrayExpr.expected @@ -1,2 +1,2 @@ -| gen_array_expr.rs:5:5:5:13 | ArrayExpr | getNumberOfAttrs: | 0 | getNumberOfExprs: | 3 | -| gen_array_expr.rs:6:5:6:11 | ArrayExpr | getNumberOfAttrs: | 0 | getNumberOfExprs: | 2 | +| gen_array_expr.rs:5:5:5:13 | [...] | getNumberOfAttrs: | 0 | getNumberOfExprs: | 3 | +| gen_array_expr.rs:6:5:6:11 | [...] | getNumberOfAttrs: | 0 | getNumberOfExprs: | 2 | diff --git a/rust/ql/test/extractor-tests/generated/ArrayExpr/ArrayExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/ArrayExpr/ArrayExpr_getExpr.expected index 97da5ba1c2a..393fb28f2bf 100644 --- a/rust/ql/test/extractor-tests/generated/ArrayExpr/ArrayExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/ArrayExpr/ArrayExpr_getExpr.expected @@ -1,5 +1,5 @@ -| gen_array_expr.rs:5:5:5:13 | ArrayExpr | 0 | gen_array_expr.rs:5:6:5:6 | 1 | -| gen_array_expr.rs:5:5:5:13 | ArrayExpr | 1 | gen_array_expr.rs:5:9:5:9 | 2 | -| gen_array_expr.rs:5:5:5:13 | ArrayExpr | 2 | gen_array_expr.rs:5:12:5:12 | 3 | -| gen_array_expr.rs:6:5:6:11 | ArrayExpr | 0 | gen_array_expr.rs:6:6:6:6 | 1 | -| gen_array_expr.rs:6:5:6:11 | ArrayExpr | 1 | gen_array_expr.rs:6:9:6:10 | 10 | +| gen_array_expr.rs:5:5:5:13 | [...] | 0 | gen_array_expr.rs:5:6:5:6 | 1 | +| gen_array_expr.rs:5:5:5:13 | [...] | 1 | gen_array_expr.rs:5:9:5:9 | 2 | +| gen_array_expr.rs:5:5:5:13 | [...] | 2 | gen_array_expr.rs:5:12:5:12 | 3 | +| gen_array_expr.rs:6:5:6:11 | [...] | 0 | gen_array_expr.rs:6:6:6:6 | 1 | +| gen_array_expr.rs:6:5:6:11 | [...] | 1 | gen_array_expr.rs:6:9:6:10 | 10 | diff --git a/rust/ql/test/extractor-tests/generated/AsmExpr/AsmExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/AsmExpr/AsmExpr_getExpr.expected index 7a4af543f31..07aec8f5fe0 100644 --- a/rust/ql/test/extractor-tests/generated/AsmExpr/AsmExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/AsmExpr/AsmExpr_getExpr.expected @@ -1 +1 @@ -| gen_asm_expr.rs:6:9:6:24 | AsmExpr | gen_asm_expr.rs:6:23:6:23 | UnderscoreExpr | +| gen_asm_expr.rs:6:9:6:24 | AsmExpr | gen_asm_expr.rs:6:23:6:23 | _ | diff --git a/rust/ql/test/extractor-tests/generated/AwaitExpr/AwaitExpr.expected b/rust/ql/test/extractor-tests/generated/AwaitExpr/AwaitExpr.expected index 2ed01b9058e..9104ba77e5f 100644 --- a/rust/ql/test/extractor-tests/generated/AwaitExpr/AwaitExpr.expected +++ b/rust/ql/test/extractor-tests/generated/AwaitExpr/AwaitExpr.expected @@ -1 +1 @@ -| gen_await_expr.rs:6:17:6:27 | AwaitExpr | getNumberOfAttrs: | 0 | hasExpr: | yes | +| gen_await_expr.rs:6:17:6:27 | await ... | getNumberOfAttrs: | 0 | hasExpr: | yes | diff --git a/rust/ql/test/extractor-tests/generated/AwaitExpr/AwaitExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/AwaitExpr/AwaitExpr_getExpr.expected index c34a6012f4c..528d6f097a0 100644 --- a/rust/ql/test/extractor-tests/generated/AwaitExpr/AwaitExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/AwaitExpr/AwaitExpr_getExpr.expected @@ -1 +1 @@ -| gen_await_expr.rs:6:17:6:27 | AwaitExpr | gen_await_expr.rs:6:17:6:21 | CallExpr | +| gen_await_expr.rs:6:17:6:27 | await ... | gen_await_expr.rs:6:17:6:21 | ... (...) | diff --git a/rust/ql/test/extractor-tests/generated/BecomeExpr/BecomeExpr.expected b/rust/ql/test/extractor-tests/generated/BecomeExpr/BecomeExpr.expected index 75840ec81fe..ce3e6a09690 100644 --- a/rust/ql/test/extractor-tests/generated/BecomeExpr/BecomeExpr.expected +++ b/rust/ql/test/extractor-tests/generated/BecomeExpr/BecomeExpr.expected @@ -1 +1 @@ -| gen_become_expr.rs:8:10:8:36 | BecomeExpr | getNumberOfAttrs: | 0 | hasExpr: | yes | +| gen_become_expr.rs:8:10:8:36 | become ... | getNumberOfAttrs: | 0 | hasExpr: | yes | diff --git a/rust/ql/test/extractor-tests/generated/BecomeExpr/BecomeExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/BecomeExpr/BecomeExpr_getExpr.expected index 8992c4868ca..4fbba61bc8c 100644 --- a/rust/ql/test/extractor-tests/generated/BecomeExpr/BecomeExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/BecomeExpr/BecomeExpr_getExpr.expected @@ -1 +1 @@ -| gen_become_expr.rs:8:10:8:36 | BecomeExpr | gen_become_expr.rs:8:17:8:36 | CallExpr | +| gen_become_expr.rs:8:10:8:36 | become ... | gen_become_expr.rs:8:17:8:36 | ... (...) | diff --git a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.expected b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.expected index 39ec1d6a7e1..3efd724a013 100644 --- a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.expected +++ b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.expected @@ -1,3 +1,3 @@ -| gen_block_expr.rs:3:28:12:1 | BlockExpr | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasLabel: | no | hasStmtList: | yes | -| gen_block_expr.rs:5:5:7:5 | BlockExpr | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasLabel: | no | hasStmtList: | yes | -| gen_block_expr.rs:8:5:11:5 | BlockExpr | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasLabel: | yes | hasStmtList: | yes | +| gen_block_expr.rs:3:28:12:1 | { ... } | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasLabel: | no | hasStmtList: | yes | +| gen_block_expr.rs:5:5:7:5 | { ... } | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasLabel: | no | hasStmtList: | yes | +| gen_block_expr.rs:8:5:11:5 | { ... } | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasLabel: | yes | hasStmtList: | yes | diff --git a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getLabel.expected b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getLabel.expected index 3a935228e05..354199e9a07 100644 --- a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getLabel.expected +++ b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getLabel.expected @@ -1 +1 @@ -| gen_block_expr.rs:8:5:11:5 | BlockExpr | gen_block_expr.rs:8:5:8:11 | Label | +| gen_block_expr.rs:8:5:11:5 | { ... } | gen_block_expr.rs:8:5:8:11 | ''label | diff --git a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getStmtList.expected b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getStmtList.expected index 21eb195289a..226f5770392 100644 --- a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getStmtList.expected +++ b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getStmtList.expected @@ -1,3 +1,3 @@ -| gen_block_expr.rs:3:28:12:1 | BlockExpr | gen_block_expr.rs:3:28:12:1 | StmtList | -| gen_block_expr.rs:5:5:7:5 | BlockExpr | gen_block_expr.rs:5:5:7:5 | StmtList | -| gen_block_expr.rs:8:5:11:5 | BlockExpr | gen_block_expr.rs:8:13:11:5 | StmtList | +| gen_block_expr.rs:3:28:12:1 | { ... } | gen_block_expr.rs:3:28:12:1 | StmtList | +| gen_block_expr.rs:5:5:7:5 | { ... } | gen_block_expr.rs:5:5:7:5 | StmtList | +| gen_block_expr.rs:8:5:11:5 | { ... } | gen_block_expr.rs:8:13:11:5 | StmtList | diff --git a/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat.expected b/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat.expected index 95c8bdebd47..20bc2bf7cc1 100644 --- a/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat.expected +++ b/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat.expected @@ -1,2 +1,2 @@ -| gen_box_pat.rs:6:9:6:27 | BoxPat | hasPat: | yes | -| gen_box_pat.rs:7:9:7:24 | BoxPat | hasPat: | yes | +| gen_box_pat.rs:6:9:6:27 | box ... | hasPat: | yes | +| gen_box_pat.rs:7:9:7:24 | box ... | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat_getPat.expected b/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat_getPat.expected index cac8ee05d3c..d98d750d3a8 100644 --- a/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat_getPat.expected @@ -1,2 +1,2 @@ -| gen_box_pat.rs:6:9:6:27 | BoxPat | gen_box_pat.rs:6:13:6:27 | TupleStructPat | -| gen_box_pat.rs:7:9:7:24 | BoxPat | gen_box_pat.rs:7:13:7:24 | PathPat | +| gen_box_pat.rs:6:9:6:27 | box ... | gen_box_pat.rs:6:13:6:27 | TupleStructPat | +| gen_box_pat.rs:7:9:7:24 | box ... | gen_box_pat.rs:7:13:7:24 | Option::None | diff --git a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected index 763fae60866..f4c8df0a100 100644 --- a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected +++ b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected @@ -1,3 +1,3 @@ -| gen_break_expr.rs:7:13:7:17 | BreakExpr | getNumberOfAttrs: | 0 | hasExpr: | no | hasLifetime: | no | -| gen_break_expr.rs:12:13:12:27 | BreakExpr | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | -| gen_break_expr.rs:17:13:17:27 | BreakExpr | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | +| gen_break_expr.rs:7:13:7:17 | (no string representation) | getNumberOfAttrs: | 0 | hasExpr: | no | hasLifetime: | no | +| gen_break_expr.rs:12:13:12:27 | (no string representation) | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | +| gen_break_expr.rs:17:13:17:27 | (no string representation) | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | diff --git a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected index 0bd373a4bbc..f99723114fb 100644 --- a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected @@ -1,2 +1,2 @@ -| gen_break_expr.rs:12:13:12:27 | BreakExpr | gen_break_expr.rs:12:26:12:27 | 42 | -| gen_break_expr.rs:17:13:17:27 | BreakExpr | gen_break_expr.rs:17:26:17:27 | 42 | +| gen_break_expr.rs:12:13:12:27 | (no string representation) | gen_break_expr.rs:12:26:12:27 | 42 | +| gen_break_expr.rs:17:13:17:27 | (no string representation) | gen_break_expr.rs:17:26:17:27 | 42 | diff --git a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected index b993a2eebf5..a1a828c744a 100644 --- a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected +++ b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected @@ -1,2 +1,2 @@ -| gen_break_expr.rs:12:13:12:27 | BreakExpr | gen_break_expr.rs:12:19:12:24 | Lifetime | -| gen_break_expr.rs:17:13:17:27 | BreakExpr | gen_break_expr.rs:17:19:17:24 | Lifetime | +| gen_break_expr.rs:12:13:12:27 | (no string representation) | gen_break_expr.rs:12:19:12:24 | ''label | +| gen_break_expr.rs:17:13:17:27 | (no string representation) | gen_break_expr.rs:17:19:17:24 | ''label | diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected index 5414108064c..9e01b6bdc63 100644 --- a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected @@ -1,4 +1,4 @@ -| gen_call_expr.rs:5:5:5:11 | CallExpr | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | -| gen_call_expr.rs:6:5:6:23 | CallExpr | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | -| gen_call_expr.rs:7:5:7:14 | CallExpr | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | -| gen_call_expr.rs:8:5:8:10 | CallExpr | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | +| gen_call_expr.rs:5:5:5:11 | ... (...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | +| gen_call_expr.rs:6:5:6:23 | ... (...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | +| gen_call_expr.rs:7:5:7:14 | ... (...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | +| gen_call_expr.rs:8:5:8:10 | ... (...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getArgList.expected b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getArgList.expected index a42cc13bf39..1876a5b58d8 100644 --- a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getArgList.expected +++ b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getArgList.expected @@ -1,4 +1,4 @@ -| gen_call_expr.rs:5:5:5:11 | CallExpr | gen_call_expr.rs:5:8:5:11 | ArgList | -| gen_call_expr.rs:6:5:6:23 | CallExpr | gen_call_expr.rs:6:20:6:23 | ArgList | -| gen_call_expr.rs:7:5:7:14 | CallExpr | gen_call_expr.rs:7:11:7:14 | ArgList | -| gen_call_expr.rs:8:5:8:10 | CallExpr | gen_call_expr.rs:8:8:8:10 | ArgList | +| gen_call_expr.rs:5:5:5:11 | ... (...) | gen_call_expr.rs:5:8:5:11 | ArgList | +| gen_call_expr.rs:6:5:6:23 | ... (...) | gen_call_expr.rs:6:20:6:23 | ArgList | +| gen_call_expr.rs:7:5:7:14 | ... (...) | gen_call_expr.rs:7:11:7:14 | ArgList | +| gen_call_expr.rs:8:5:8:10 | ... (...) | gen_call_expr.rs:8:8:8:10 | ArgList | diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.expected index 544937866b7..017a4656ffd 100644 --- a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.expected @@ -1,4 +1,4 @@ -| gen_call_expr.rs:5:5:5:11 | CallExpr | gen_call_expr.rs:5:5:5:7 | foo | -| gen_call_expr.rs:6:5:6:23 | CallExpr | gen_call_expr.rs:6:5:6:19 | foo::<...> | -| gen_call_expr.rs:7:5:7:14 | CallExpr | gen_call_expr.rs:7:5:7:10 | IndexExpr | -| gen_call_expr.rs:8:5:8:10 | CallExpr | gen_call_expr.rs:8:5:8:7 | foo | +| gen_call_expr.rs:5:5:5:11 | ... (...) | gen_call_expr.rs:5:5:5:7 | foo | +| gen_call_expr.rs:6:5:6:23 | ... (...) | gen_call_expr.rs:6:5:6:19 | foo::<...> | +| gen_call_expr.rs:7:5:7:14 | ... (...) | gen_call_expr.rs:7:5:7:10 | ...[...] | +| gen_call_expr.rs:8:5:8:10 | ... (...) | gen_call_expr.rs:8:5:8:7 | foo | diff --git a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected index 6050eb02259..157e06c3f2b 100644 --- a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected @@ -1 +1 @@ -| gen_cast_expr.rs:5:5:5:16 | CastExpr | getNumberOfAttrs: | 0 | hasExpr: | yes | hasTy: | yes | +| gen_cast_expr.rs:5:5:5:16 | ... as u64 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasTy: | yes | diff --git a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected index f3e1d4c7ec9..fda7db77d90 100644 --- a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected @@ -1 +1 @@ -| gen_cast_expr.rs:5:5:5:16 | CastExpr | gen_cast_expr.rs:5:5:5:9 | value | +| gen_cast_expr.rs:5:5:5:16 | ... as u64 | gen_cast_expr.rs:5:5:5:9 | value | diff --git a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected index 29cc49cc3b9..90fa37e4f97 100644 --- a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected +++ b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected @@ -1 +1 @@ -| gen_cast_expr.rs:5:5:5:16 | CastExpr | gen_cast_expr.rs:5:14:5:16 | PathType | +| gen_cast_expr.rs:5:5:5:16 | ... as u64 | gen_cast_expr.rs:5:14:5:16 | u64 | diff --git a/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr.expected b/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr.expected index fb665ca8f60..3ea9f463a00 100644 --- a/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr.expected +++ b/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr.expected @@ -1,5 +1,5 @@ -| gen_closure_expr.rs:5:5:5:13 | ClosureExpr | hasParamList: | yes | getNumberOfAttrs: | 0 | hasBody: | yes | hasClosureBinder: | no | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isStatic: | no | hasRetType: | no | -| gen_closure_expr.rs:6:5:6:34 | ClosureExpr | hasParamList: | yes | getNumberOfAttrs: | 0 | hasBody: | yes | hasClosureBinder: | no | isAsync: | no | isConst: | no | isGen: | no | isMove: | yes | isStatic: | no | hasRetType: | yes | -| gen_closure_expr.rs:7:5:7:27 | ClosureExpr | hasParamList: | yes | getNumberOfAttrs: | 0 | hasBody: | yes | hasClosureBinder: | no | isAsync: | yes | isConst: | no | isGen: | no | isMove: | no | isStatic: | no | hasRetType: | no | -| gen_closure_expr.rs:8:6:9:15 | ClosureExpr | hasParamList: | yes | getNumberOfAttrs: | 1 | hasBody: | yes | hasClosureBinder: | no | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isStatic: | no | hasRetType: | no | -| gen_closure_expr.rs:10:6:11:23 | ClosureExpr | hasParamList: | yes | getNumberOfAttrs: | 1 | hasBody: | yes | hasClosureBinder: | no | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isStatic: | yes | hasRetType: | no | +| gen_closure_expr.rs:5:5:5:13 | \|...\| ... | hasParamList: | yes | getNumberOfAttrs: | 0 | hasBody: | yes | hasClosureBinder: | no | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isStatic: | no | hasRetType: | no | +| gen_closure_expr.rs:6:5:6:34 | \|...\| ... | hasParamList: | yes | getNumberOfAttrs: | 0 | hasBody: | yes | hasClosureBinder: | no | isAsync: | no | isConst: | no | isGen: | no | isMove: | yes | isStatic: | no | hasRetType: | yes | +| gen_closure_expr.rs:7:5:7:27 | \|...\| ... | hasParamList: | yes | getNumberOfAttrs: | 0 | hasBody: | yes | hasClosureBinder: | no | isAsync: | yes | isConst: | no | isGen: | no | isMove: | no | isStatic: | no | hasRetType: | no | +| gen_closure_expr.rs:8:6:9:15 | \|...\| ... | hasParamList: | yes | getNumberOfAttrs: | 1 | hasBody: | yes | hasClosureBinder: | no | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isStatic: | no | hasRetType: | no | +| gen_closure_expr.rs:10:6:11:23 | \|...\| ... | hasParamList: | yes | getNumberOfAttrs: | 1 | hasBody: | yes | hasClosureBinder: | no | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isStatic: | yes | hasRetType: | no | diff --git a/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getAttr.expected b/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getAttr.expected index f1859d594d1..4de6e17d785 100644 --- a/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getAttr.expected +++ b/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getAttr.expected @@ -1,2 +1,2 @@ -| gen_closure_expr.rs:8:6:9:15 | ClosureExpr | 0 | gen_closure_expr.rs:8:6:8:17 | Attr | -| gen_closure_expr.rs:10:6:11:23 | ClosureExpr | 0 | gen_closure_expr.rs:10:6:10:17 | Attr | +| gen_closure_expr.rs:8:6:9:15 | \|...\| ... | 0 | gen_closure_expr.rs:8:6:8:17 | Attr | +| gen_closure_expr.rs:10:6:11:23 | \|...\| ... | 0 | gen_closure_expr.rs:10:6:10:17 | Attr | diff --git a/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getBody.expected b/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getBody.expected index 71bc3cccda3..d7b6180e63b 100644 --- a/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getBody.expected +++ b/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getBody.expected @@ -1,5 +1,5 @@ -| gen_closure_expr.rs:5:5:5:13 | ClosureExpr | gen_closure_expr.rs:5:9:5:13 | ... + ... | -| gen_closure_expr.rs:6:5:6:34 | ClosureExpr | gen_closure_expr.rs:6:26:6:34 | BlockExpr | -| gen_closure_expr.rs:7:5:7:27 | ClosureExpr | gen_closure_expr.rs:7:23:7:27 | ... + ... | -| gen_closure_expr.rs:8:6:9:15 | ClosureExpr | gen_closure_expr.rs:9:9:9:15 | YieldExpr | -| gen_closure_expr.rs:10:6:11:23 | ClosureExpr | gen_closure_expr.rs:11:17:11:23 | YieldExpr | +| gen_closure_expr.rs:5:5:5:13 | \|...\| ... | gen_closure_expr.rs:5:9:5:13 | ... + ... | +| gen_closure_expr.rs:6:5:6:34 | \|...\| ... | gen_closure_expr.rs:6:26:6:34 | { ... } | +| gen_closure_expr.rs:7:5:7:27 | \|...\| ... | gen_closure_expr.rs:7:23:7:27 | ... + ... | +| gen_closure_expr.rs:8:6:9:15 | \|...\| ... | gen_closure_expr.rs:9:9:9:15 | YieldExpr | +| gen_closure_expr.rs:10:6:11:23 | \|...\| ... | gen_closure_expr.rs:11:17:11:23 | YieldExpr | diff --git a/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getParamList.expected b/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getParamList.expected index d0e6aaeac06..5945738433b 100644 --- a/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getParamList.expected +++ b/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getParamList.expected @@ -1,5 +1,5 @@ -| gen_closure_expr.rs:5:5:5:13 | ClosureExpr | gen_closure_expr.rs:5:5:5:7 | ParamList | -| gen_closure_expr.rs:6:5:6:34 | ClosureExpr | gen_closure_expr.rs:6:10:6:17 | ParamList | -| gen_closure_expr.rs:7:5:7:27 | ClosureExpr | gen_closure_expr.rs:7:11:7:21 | ParamList | -| gen_closure_expr.rs:8:6:9:15 | ClosureExpr | gen_closure_expr.rs:9:5:9:7 | ParamList | -| gen_closure_expr.rs:10:6:11:23 | ClosureExpr | gen_closure_expr.rs:11:13:11:15 | ParamList | +| gen_closure_expr.rs:5:5:5:13 | \|...\| ... | gen_closure_expr.rs:5:5:5:7 | ParamList | +| gen_closure_expr.rs:6:5:6:34 | \|...\| ... | gen_closure_expr.rs:6:10:6:17 | ParamList | +| gen_closure_expr.rs:7:5:7:27 | \|...\| ... | gen_closure_expr.rs:7:11:7:21 | ParamList | +| gen_closure_expr.rs:8:6:9:15 | \|...\| ... | gen_closure_expr.rs:9:5:9:7 | ParamList | +| gen_closure_expr.rs:10:6:11:23 | \|...\| ... | gen_closure_expr.rs:11:13:11:15 | ParamList | diff --git a/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getRetType.expected b/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getRetType.expected index e018209cb53..d7ec1024953 100644 --- a/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getRetType.expected +++ b/rust/ql/test/extractor-tests/generated/ClosureExpr/ClosureExpr_getRetType.expected @@ -1 +1 @@ -| gen_closure_expr.rs:6:5:6:34 | ClosureExpr | gen_closure_expr.rs:6:19:6:24 | RetType | +| gen_closure_expr.rs:6:5:6:34 | \|...\| ... | gen_closure_expr.rs:6:19:6:24 | RetType | diff --git a/rust/ql/test/extractor-tests/generated/ConstBlockPat/ConstBlockPat_getBlockExpr.expected b/rust/ql/test/extractor-tests/generated/ConstBlockPat/ConstBlockPat_getBlockExpr.expected index 58a885a4857..42cdb5ef4c3 100644 --- a/rust/ql/test/extractor-tests/generated/ConstBlockPat/ConstBlockPat_getBlockExpr.expected +++ b/rust/ql/test/extractor-tests/generated/ConstBlockPat/ConstBlockPat_getBlockExpr.expected @@ -1 +1 @@ -| gen_const_block_pat.rs:6:9:6:27 | ConstBlockPat | gen_const_block_pat.rs:6:15:6:27 | BlockExpr | +| gen_const_block_pat.rs:6:9:6:27 | ConstBlockPat | gen_const_block_pat.rs:6:15:6:27 | { ... } | diff --git a/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr.expected b/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr.expected index ab921873d62..a09556b9a3f 100644 --- a/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr.expected +++ b/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr.expected @@ -1,2 +1,2 @@ -| gen_continue_expr.rs:7:13:7:20 | ContinueExpr | getNumberOfAttrs: | 0 | hasLifetime: | no | -| gen_continue_expr.rs:12:13:12:27 | ContinueExpr | getNumberOfAttrs: | 0 | hasLifetime: | yes | +| gen_continue_expr.rs:7:13:7:20 | continue | getNumberOfAttrs: | 0 | hasLifetime: | no | +| gen_continue_expr.rs:12:13:12:27 | continue 'label | getNumberOfAttrs: | 0 | hasLifetime: | yes | diff --git a/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected b/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected index 525d2bb55a8..d81d276ce0a 100644 --- a/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected +++ b/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected @@ -1 +1 @@ -| gen_continue_expr.rs:12:13:12:27 | ContinueExpr | gen_continue_expr.rs:12:22:12:27 | Lifetime | +| gen_continue_expr.rs:12:13:12:27 | continue 'label | gen_continue_expr.rs:12:22:12:27 | ''label | diff --git a/rust/ql/test/extractor-tests/generated/ExprStmt/ExprStmt_getExpr.expected b/rust/ql/test/extractor-tests/generated/ExprStmt/ExprStmt_getExpr.expected index f29a7f83d7d..08343b7e1e9 100644 --- a/rust/ql/test/extractor-tests/generated/ExprStmt/ExprStmt_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/ExprStmt/ExprStmt_getExpr.expected @@ -1,2 +1,2 @@ -| gen_expr_stmt.rs:5:5:5:12 | ExprStmt | gen_expr_stmt.rs:5:5:5:11 | CallExpr | -| gen_expr_stmt.rs:6:5:6:13 | ExprStmt | gen_expr_stmt.rs:6:5:6:12 | CallExpr | +| gen_expr_stmt.rs:5:5:5:12 | ExprStmt | gen_expr_stmt.rs:5:5:5:11 | ... (...) | +| gen_expr_stmt.rs:6:5:6:13 | ExprStmt | gen_expr_stmt.rs:6:5:6:12 | ... (...) | diff --git a/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr.expected b/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr.expected index 22dcb3c92e1..912f65f43e3 100644 --- a/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr.expected +++ b/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr.expected @@ -1 +1 @@ -| gen_field_expr.rs:5:5:5:9 | FieldExpr | getNumberOfAttrs: | 0 | hasExpr: | yes | hasNameRef: | yes | +| gen_field_expr.rs:5:5:5:9 | ... .foo | getNumberOfAttrs: | 0 | hasExpr: | yes | hasNameRef: | yes | diff --git a/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getExpr.expected index 32b13c1cb2b..ac80547d5ca 100644 --- a/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getExpr.expected @@ -1 +1 @@ -| gen_field_expr.rs:5:5:5:9 | FieldExpr | gen_field_expr.rs:5:5:5:5 | x | +| gen_field_expr.rs:5:5:5:9 | ... .foo | gen_field_expr.rs:5:5:5:5 | x | diff --git a/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getNameRef.expected b/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getNameRef.expected index 667f3130968..743f58b5741 100644 --- a/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getNameRef.expected +++ b/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getNameRef.expected @@ -1 +1 @@ -| gen_field_expr.rs:5:5:5:9 | FieldExpr | gen_field_expr.rs:5:7:5:9 | foo | +| gen_field_expr.rs:5:5:5:9 | ... .foo | gen_field_expr.rs:5:7:5:9 | foo | diff --git a/rust/ql/test/extractor-tests/generated/Function/Function.expected b/rust/ql/test/extractor-tests/generated/Function/Function.expected index f93eb58b2ae..b96996beef9 100644 --- a/rust/ql/test/extractor-tests/generated/Function/Function.expected +++ b/rust/ql/test/extractor-tests/generated/Function/Function.expected @@ -1,2 +1,2 @@ -| gen_function.rs:3:1:4:38 | foo | hasParamList: | yes | getNumberOfAttrs: | 0 | hasExtendedCanonicalPath: | yes | hasCrateOrigin: | yes | hasAbi: | no | hasBody: | yes | hasGenericParamList: | no | isAsync: | no | isConst: | no | isDefault: | no | isGen: | no | isUnsafe: | no | hasName: | yes | hasRetType: | yes | hasVisibility: | no | hasWhereClause: | no | -| gen_function.rs:7:5:7:13 | bar | hasParamList: | yes | getNumberOfAttrs: | 0 | hasExtendedCanonicalPath: | yes | hasCrateOrigin: | yes | hasAbi: | no | hasBody: | no | hasGenericParamList: | no | isAsync: | no | isConst: | no | isDefault: | no | isGen: | no | isUnsafe: | no | hasName: | yes | hasRetType: | no | hasVisibility: | no | hasWhereClause: | no | +| gen_function.rs:3:1:4:38 | fn foo | hasParamList: | yes | getNumberOfAttrs: | 0 | hasExtendedCanonicalPath: | yes | hasCrateOrigin: | yes | hasAbi: | no | hasBody: | yes | hasGenericParamList: | no | isAsync: | no | isConst: | no | isDefault: | no | isGen: | no | isUnsafe: | no | hasName: | yes | hasRetType: | yes | hasVisibility: | no | hasWhereClause: | no | +| gen_function.rs:7:5:7:13 | fn bar | hasParamList: | yes | getNumberOfAttrs: | 0 | hasExtendedCanonicalPath: | yes | hasCrateOrigin: | yes | hasAbi: | no | hasBody: | no | hasGenericParamList: | no | isAsync: | no | isConst: | no | isDefault: | no | isGen: | no | isUnsafe: | no | hasName: | yes | hasRetType: | no | hasVisibility: | no | hasWhereClause: | no | diff --git a/rust/ql/test/extractor-tests/generated/Function/Function_getBody.expected b/rust/ql/test/extractor-tests/generated/Function/Function_getBody.expected index 996e8c1a27c..894900b3eaa 100644 --- a/rust/ql/test/extractor-tests/generated/Function/Function_getBody.expected +++ b/rust/ql/test/extractor-tests/generated/Function/Function_getBody.expected @@ -1 +1 @@ -| gen_function.rs:3:1:4:38 | foo | gen_function.rs:4:23:4:38 | BlockExpr | +| gen_function.rs:3:1:4:38 | fn foo | gen_function.rs:4:23:4:38 | { ... } | diff --git a/rust/ql/test/extractor-tests/generated/Function/Function_getCrateOrigin.expected b/rust/ql/test/extractor-tests/generated/Function/Function_getCrateOrigin.expected index 7c376ffaf1e..eabc941bd5b 100644 --- a/rust/ql/test/extractor-tests/generated/Function/Function_getCrateOrigin.expected +++ b/rust/ql/test/extractor-tests/generated/Function/Function_getCrateOrigin.expected @@ -1,2 +1,2 @@ -| gen_function.rs:3:1:4:38 | foo | repo::test | -| gen_function.rs:7:5:7:13 | bar | repo::test | +| gen_function.rs:3:1:4:38 | fn foo | repo::test | +| gen_function.rs:7:5:7:13 | fn bar | repo::test | diff --git a/rust/ql/test/extractor-tests/generated/Function/Function_getExtendedCanonicalPath.expected b/rust/ql/test/extractor-tests/generated/Function/Function_getExtendedCanonicalPath.expected index d9b6255918f..2c0059ebc2a 100644 --- a/rust/ql/test/extractor-tests/generated/Function/Function_getExtendedCanonicalPath.expected +++ b/rust/ql/test/extractor-tests/generated/Function/Function_getExtendedCanonicalPath.expected @@ -1,2 +1,2 @@ -| gen_function.rs:3:1:4:38 | foo | crate::gen_function::foo | -| gen_function.rs:7:5:7:13 | bar | crate::gen_function::Trait::bar | +| gen_function.rs:3:1:4:38 | fn foo | crate::gen_function::foo | +| gen_function.rs:7:5:7:13 | fn bar | crate::gen_function::Trait::bar | diff --git a/rust/ql/test/extractor-tests/generated/Function/Function_getName.expected b/rust/ql/test/extractor-tests/generated/Function/Function_getName.expected index 62676019818..7e889e82d28 100644 --- a/rust/ql/test/extractor-tests/generated/Function/Function_getName.expected +++ b/rust/ql/test/extractor-tests/generated/Function/Function_getName.expected @@ -1,2 +1,2 @@ -| gen_function.rs:3:1:4:38 | foo | gen_function.rs:4:4:4:6 | foo | -| gen_function.rs:7:5:7:13 | bar | gen_function.rs:7:8:7:10 | bar | +| gen_function.rs:3:1:4:38 | fn foo | gen_function.rs:4:4:4:6 | foo | +| gen_function.rs:7:5:7:13 | fn bar | gen_function.rs:7:8:7:10 | bar | diff --git a/rust/ql/test/extractor-tests/generated/Function/Function_getParamList.expected b/rust/ql/test/extractor-tests/generated/Function/Function_getParamList.expected index baa2734e86a..df581061919 100644 --- a/rust/ql/test/extractor-tests/generated/Function/Function_getParamList.expected +++ b/rust/ql/test/extractor-tests/generated/Function/Function_getParamList.expected @@ -1,2 +1,2 @@ -| gen_function.rs:3:1:4:38 | foo | gen_function.rs:4:7:4:14 | ParamList | -| gen_function.rs:7:5:7:13 | bar | gen_function.rs:7:11:7:12 | ParamList | +| gen_function.rs:3:1:4:38 | fn foo | gen_function.rs:4:7:4:14 | ParamList | +| gen_function.rs:7:5:7:13 | fn bar | gen_function.rs:7:11:7:12 | ParamList | diff --git a/rust/ql/test/extractor-tests/generated/Function/Function_getRetType.expected b/rust/ql/test/extractor-tests/generated/Function/Function_getRetType.expected index 7a533870560..bd225b268e8 100644 --- a/rust/ql/test/extractor-tests/generated/Function/Function_getRetType.expected +++ b/rust/ql/test/extractor-tests/generated/Function/Function_getRetType.expected @@ -1 +1 @@ -| gen_function.rs:3:1:4:38 | foo | gen_function.rs:4:16:4:21 | RetType | +| gen_function.rs:3:1:4:38 | fn foo | gen_function.rs:4:16:4:21 | RetType | diff --git a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr.expected b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr.expected index a0e0ea15594..6c40caaae5c 100644 --- a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr.expected +++ b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr.expected @@ -1,2 +1,2 @@ -| gen_if_expr.rs:5:5:7:5 | IfExpr | getNumberOfAttrs: | 0 | hasCondition: | yes | hasElse: | no | hasThen: | yes | -| gen_if_expr.rs:8:13:12:5 | IfExpr | getNumberOfAttrs: | 0 | hasCondition: | yes | hasElse: | yes | hasThen: | yes | +| gen_if_expr.rs:5:5:7:5 | if ... { ... } | getNumberOfAttrs: | 0 | hasCondition: | yes | hasElse: | no | hasThen: | yes | +| gen_if_expr.rs:8:13:12:5 | if ... { ... } else { ... } | getNumberOfAttrs: | 0 | hasCondition: | yes | hasElse: | yes | hasThen: | yes | diff --git a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getCondition.expected b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getCondition.expected index 7bdb262dd32..9dc91afd773 100644 --- a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getCondition.expected +++ b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getCondition.expected @@ -1,2 +1,2 @@ -| gen_if_expr.rs:5:5:7:5 | IfExpr | gen_if_expr.rs:5:8:5:14 | ... == ... | -| gen_if_expr.rs:8:13:12:5 | IfExpr | gen_if_expr.rs:8:16:8:20 | ... > ... | +| gen_if_expr.rs:5:5:7:5 | if ... { ... } | gen_if_expr.rs:5:8:5:14 | ... == ... | +| gen_if_expr.rs:8:13:12:5 | if ... { ... } else { ... } | gen_if_expr.rs:8:16:8:20 | ... > ... | diff --git a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getElse.expected b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getElse.expected index a857dbe2099..4f8d79008e6 100644 --- a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getElse.expected +++ b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getElse.expected @@ -1 +1 @@ -| gen_if_expr.rs:8:13:12:5 | IfExpr | gen_if_expr.rs:10:12:12:5 | BlockExpr | +| gen_if_expr.rs:8:13:12:5 | if ... { ... } else { ... } | gen_if_expr.rs:10:12:12:5 | { ... } | diff --git a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getThen.expected b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getThen.expected index 0916c3f3391..961cb118409 100644 --- a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getThen.expected +++ b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getThen.expected @@ -1,2 +1,2 @@ -| gen_if_expr.rs:5:5:7:5 | IfExpr | gen_if_expr.rs:5:16:7:5 | BlockExpr | -| gen_if_expr.rs:8:13:12:5 | IfExpr | gen_if_expr.rs:8:22:10:5 | BlockExpr | +| gen_if_expr.rs:5:5:7:5 | if ... { ... } | gen_if_expr.rs:5:16:7:5 | { ... } | +| gen_if_expr.rs:8:13:12:5 | if ... { ... } else { ... } | gen_if_expr.rs:8:22:10:5 | { ... } | diff --git a/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr.expected b/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr.expected index c113934115d..e737827e89f 100644 --- a/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr.expected +++ b/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr.expected @@ -1,2 +1,2 @@ -| gen_index_expr.rs:5:5:5:12 | IndexExpr | getNumberOfAttrs: | 0 | hasBase: | yes | hasIndex: | yes | -| gen_index_expr.rs:6:5:6:12 | IndexExpr | getNumberOfAttrs: | 0 | hasBase: | yes | hasIndex: | yes | +| gen_index_expr.rs:5:5:5:12 | ...[...] | getNumberOfAttrs: | 0 | hasBase: | yes | hasIndex: | yes | +| gen_index_expr.rs:6:5:6:12 | ...[...] | getNumberOfAttrs: | 0 | hasBase: | yes | hasIndex: | yes | diff --git a/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getBase.expected b/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getBase.expected index c149597172b..fc1e9720fab 100644 --- a/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getBase.expected +++ b/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getBase.expected @@ -1,2 +1,2 @@ -| gen_index_expr.rs:5:5:5:12 | IndexExpr | gen_index_expr.rs:5:5:5:8 | list | -| gen_index_expr.rs:6:5:6:12 | IndexExpr | gen_index_expr.rs:6:5:6:8 | list | +| gen_index_expr.rs:5:5:5:12 | ...[...] | gen_index_expr.rs:5:5:5:8 | list | +| gen_index_expr.rs:6:5:6:12 | ...[...] | gen_index_expr.rs:6:5:6:8 | list | diff --git a/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getIndex.expected b/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getIndex.expected index 433afd85eb9..21c6228d5b9 100644 --- a/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getIndex.expected +++ b/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getIndex.expected @@ -1,2 +1,2 @@ -| gen_index_expr.rs:5:5:5:12 | IndexExpr | gen_index_expr.rs:5:10:5:11 | 42 | -| gen_index_expr.rs:6:5:6:12 | IndexExpr | gen_index_expr.rs:6:10:6:11 | 42 | +| gen_index_expr.rs:5:5:5:12 | ...[...] | gen_index_expr.rs:5:10:5:11 | 42 | +| gen_index_expr.rs:6:5:6:12 | ...[...] | gen_index_expr.rs:6:10:6:11 | 42 | diff --git a/rust/ql/test/extractor-tests/generated/Label/Label.expected b/rust/ql/test/extractor-tests/generated/Label/Label.expected index 5cea4ef7222..ad594afe55b 100644 --- a/rust/ql/test/extractor-tests/generated/Label/Label.expected +++ b/rust/ql/test/extractor-tests/generated/Label/Label.expected @@ -1 +1 @@ -| gen_label.rs:5:5:5:11 | Label | hasLifetime: | yes | +| gen_label.rs:5:5:5:11 | ''label | hasLifetime: | yes | diff --git a/rust/ql/test/extractor-tests/generated/Label/Label_getLifetime.expected b/rust/ql/test/extractor-tests/generated/Label/Label_getLifetime.expected index 9c78f23307d..d3ea9171b8c 100644 --- a/rust/ql/test/extractor-tests/generated/Label/Label_getLifetime.expected +++ b/rust/ql/test/extractor-tests/generated/Label/Label_getLifetime.expected @@ -1 +1 @@ -| gen_label.rs:5:5:5:11 | Label | gen_label.rs:5:5:5:10 | Lifetime | +| gen_label.rs:5:5:5:11 | ''label | gen_label.rs:5:5:5:10 | ''label | diff --git a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.expected b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.expected index 26a968ef35b..6c6343e24d3 100644 --- a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.expected +++ b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.expected @@ -1 +1 @@ -| gen_let_expr.rs:5:8:5:31 | LetExpr | getNumberOfAttrs: | 0 | hasExpr: | yes | hasPat: | yes | +| gen_let_expr.rs:5:8:5:31 | let TupleStructPat = ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.expected index f90fa586229..9293ae80e1d 100644 --- a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.expected @@ -1 +1 @@ -| gen_let_expr.rs:5:8:5:31 | LetExpr | gen_let_expr.rs:5:22:5:31 | maybe_some | +| gen_let_expr.rs:5:8:5:31 | let TupleStructPat = ... | gen_let_expr.rs:5:22:5:31 | maybe_some | diff --git a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getPat.expected b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getPat.expected index 287200e610f..527a9fcc3a9 100644 --- a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getPat.expected @@ -1 +1 @@ -| gen_let_expr.rs:5:8:5:31 | LetExpr | gen_let_expr.rs:5:12:5:18 | TupleStructPat | +| gen_let_expr.rs:5:8:5:31 | let TupleStructPat = ... | gen_let_expr.rs:5:12:5:18 | TupleStructPat | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt.expected index 7c05e07e2f3..e433b420d4e 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt.expected @@ -1,6 +1,6 @@ -| gen_let_stmt.rs:5:5:5:15 | LetStmt | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | no | hasPat: | yes | hasTy: | no | -| gen_let_stmt.rs:6:5:6:20 | LetStmt | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | no | hasPat: | yes | hasTy: | yes | -| gen_let_stmt.rs:7:5:7:15 | LetStmt | getNumberOfAttrs: | 0 | hasInitializer: | no | hasLetElse: | no | hasPat: | yes | hasTy: | yes | -| gen_let_stmt.rs:8:5:8:10 | LetStmt | getNumberOfAttrs: | 0 | hasInitializer: | no | hasLetElse: | no | hasPat: | yes | hasTy: | no | -| gen_let_stmt.rs:9:5:9:24 | LetStmt | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | no | hasPat: | yes | hasTy: | no | -| gen_let_stmt.rs:10:5:12:6 | LetStmt | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | yes | hasPat: | yes | hasTy: | no | +| gen_let_stmt.rs:5:5:5:15 | let x = ... | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | no | hasPat: | yes | hasTy: | no | +| gen_let_stmt.rs:6:5:6:20 | let x = ... | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | no | hasPat: | yes | hasTy: | yes | +| gen_let_stmt.rs:7:5:7:15 | let x | getNumberOfAttrs: | 0 | hasInitializer: | no | hasLetElse: | no | hasPat: | yes | hasTy: | yes | +| gen_let_stmt.rs:8:5:8:10 | let x | getNumberOfAttrs: | 0 | hasInitializer: | no | hasLetElse: | no | hasPat: | yes | hasTy: | no | +| gen_let_stmt.rs:9:5:9:24 | let TuplePat = ... | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | no | hasPat: | yes | hasTy: | no | +| gen_let_stmt.rs:10:5:12:6 | let TupleStructPat = ... else { ... } | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | yes | hasPat: | yes | hasTy: | no | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected index 5e79b98f827..07b474609f7 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected @@ -1,4 +1,4 @@ -| gen_let_stmt.rs:5:5:5:15 | LetStmt | gen_let_stmt.rs:5:13:5:14 | 42 | -| gen_let_stmt.rs:6:5:6:20 | LetStmt | gen_let_stmt.rs:6:18:6:19 | 42 | -| gen_let_stmt.rs:9:5:9:24 | LetStmt | gen_let_stmt.rs:9:18:9:23 | TupleExpr | -| gen_let_stmt.rs:10:5:12:6 | LetStmt | gen_let_stmt.rs:10:19:10:38 | CallExpr | +| gen_let_stmt.rs:5:5:5:15 | let x = ... | gen_let_stmt.rs:5:13:5:14 | 42 | +| gen_let_stmt.rs:6:5:6:20 | let x = ... | gen_let_stmt.rs:6:18:6:19 | 42 | +| gen_let_stmt.rs:9:5:9:24 | let TuplePat = ... | gen_let_stmt.rs:9:18:9:23 | TupleExpr | +| gen_let_stmt.rs:10:5:12:6 | let TupleStructPat = ... else { ... } | gen_let_stmt.rs:10:19:10:38 | ... (...) | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getLetElse.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getLetElse.expected index 8078ec66966..a0531cdba9e 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getLetElse.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getLetElse.expected @@ -1 +1 @@ -| gen_let_stmt.rs:10:5:12:6 | LetStmt | gen_let_stmt.rs:10:40:12:5 | LetElse | +| gen_let_stmt.rs:10:5:12:6 | let TupleStructPat = ... else { ... } | gen_let_stmt.rs:10:40:12:5 | else { ... } | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected index 93810df10e3..09a185a51bd 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected @@ -1,6 +1,6 @@ -| gen_let_stmt.rs:5:5:5:15 | LetStmt | gen_let_stmt.rs:5:9:5:9 | x | -| gen_let_stmt.rs:6:5:6:20 | LetStmt | gen_let_stmt.rs:6:9:6:9 | x | -| gen_let_stmt.rs:7:5:7:15 | LetStmt | gen_let_stmt.rs:7:9:7:9 | x | -| gen_let_stmt.rs:8:5:8:10 | LetStmt | gen_let_stmt.rs:8:9:8:9 | x | -| gen_let_stmt.rs:9:5:9:24 | LetStmt | gen_let_stmt.rs:9:9:9:14 | TuplePat | -| gen_let_stmt.rs:10:5:12:6 | LetStmt | gen_let_stmt.rs:10:9:10:15 | TupleStructPat | +| gen_let_stmt.rs:5:5:5:15 | let x = ... | gen_let_stmt.rs:5:9:5:9 | x | +| gen_let_stmt.rs:6:5:6:20 | let x = ... | gen_let_stmt.rs:6:9:6:9 | x | +| gen_let_stmt.rs:7:5:7:15 | let x | gen_let_stmt.rs:7:9:7:9 | x | +| gen_let_stmt.rs:8:5:8:10 | let x | gen_let_stmt.rs:8:9:8:9 | x | +| gen_let_stmt.rs:9:5:9:24 | let TuplePat = ... | gen_let_stmt.rs:9:9:9:14 | TuplePat | +| gen_let_stmt.rs:10:5:12:6 | let TupleStructPat = ... else { ... } | gen_let_stmt.rs:10:9:10:15 | TupleStructPat | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected index 1cf6d1d2a51..f00814567d3 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected @@ -1,2 +1,2 @@ -| gen_let_stmt.rs:6:5:6:20 | LetStmt | gen_let_stmt.rs:6:12:6:14 | PathType | -| gen_let_stmt.rs:7:5:7:15 | LetStmt | gen_let_stmt.rs:7:12:7:14 | PathType | +| gen_let_stmt.rs:6:5:6:20 | let x = ... | gen_let_stmt.rs:6:12:6:14 | i32 | +| gen_let_stmt.rs:7:5:7:15 | let x | gen_let_stmt.rs:7:12:7:14 | i32 | diff --git a/rust/ql/test/extractor-tests/generated/LiteralPat/LiteralPat.expected b/rust/ql/test/extractor-tests/generated/LiteralPat/LiteralPat.expected index b7ac2ced75f..d4734ef3dac 100644 --- a/rust/ql/test/extractor-tests/generated/LiteralPat/LiteralPat.expected +++ b/rust/ql/test/extractor-tests/generated/LiteralPat/LiteralPat.expected @@ -1 +1 @@ -| gen_literal_pat.rs:6:9:6:10 | LiteralPat | hasLiteral: | yes | +| gen_literal_pat.rs:6:9:6:10 | 42 | hasLiteral: | yes | diff --git a/rust/ql/test/extractor-tests/generated/LiteralPat/LiteralPat_getLiteral.expected b/rust/ql/test/extractor-tests/generated/LiteralPat/LiteralPat_getLiteral.expected index ce74da0fb3a..487f239737b 100644 --- a/rust/ql/test/extractor-tests/generated/LiteralPat/LiteralPat_getLiteral.expected +++ b/rust/ql/test/extractor-tests/generated/LiteralPat/LiteralPat_getLiteral.expected @@ -1 +1 @@ -| gen_literal_pat.rs:6:9:6:10 | LiteralPat | gen_literal_pat.rs:6:9:6:10 | 42 | +| gen_literal_pat.rs:6:9:6:10 | 42 | gen_literal_pat.rs:6:9:6:10 | 42 | diff --git a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.expected b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.expected index aae22652d64..9cb3238c825 100644 --- a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.expected +++ b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.expected @@ -1,3 +1,3 @@ -| gen_loop_expr.rs:5:5:7:5 | LoopExpr | getNumberOfAttrs: | 0 | hasLabel: | no | hasLoopBody: | yes | -| gen_loop_expr.rs:8:5:11:5 | LoopExpr | getNumberOfAttrs: | 0 | hasLabel: | yes | hasLoopBody: | yes | -| gen_loop_expr.rs:13:5:19:5 | LoopExpr | getNumberOfAttrs: | 0 | hasLabel: | no | hasLoopBody: | yes | +| gen_loop_expr.rs:5:5:7:5 | loop {...} | getNumberOfAttrs: | 0 | hasLabel: | no | hasLoopBody: | yes | +| gen_loop_expr.rs:8:5:11:5 | loop {...} | getNumberOfAttrs: | 0 | hasLabel: | yes | hasLoopBody: | yes | +| gen_loop_expr.rs:13:5:19:5 | loop {...} | getNumberOfAttrs: | 0 | hasLabel: | no | hasLoopBody: | yes | diff --git a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLabel.expected b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLabel.expected index 98a657f0983..6a71a241413 100644 --- a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLabel.expected +++ b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLabel.expected @@ -1 +1 @@ -| gen_loop_expr.rs:8:5:11:5 | LoopExpr | gen_loop_expr.rs:8:5:8:11 | Label | +| gen_loop_expr.rs:8:5:11:5 | loop {...} | gen_loop_expr.rs:8:5:8:11 | ''label | diff --git a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.expected b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.expected index 358fd7625b5..18a1091d89a 100644 --- a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.expected +++ b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.expected @@ -1,3 +1,3 @@ -| gen_loop_expr.rs:5:5:7:5 | LoopExpr | gen_loop_expr.rs:5:10:7:5 | BlockExpr | -| gen_loop_expr.rs:8:5:11:5 | LoopExpr | gen_loop_expr.rs:8:18:11:5 | BlockExpr | -| gen_loop_expr.rs:13:5:19:5 | LoopExpr | gen_loop_expr.rs:13:10:19:5 | BlockExpr | +| gen_loop_expr.rs:5:5:7:5 | loop {...} | gen_loop_expr.rs:5:10:7:5 | { ... } | +| gen_loop_expr.rs:8:5:11:5 | loop {...} | gen_loop_expr.rs:8:18:11:5 | { ... } | +| gen_loop_expr.rs:13:5:19:5 | loop {...} | gen_loop_expr.rs:13:10:19:5 | { ... } | diff --git a/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall.expected b/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall.expected index 03bcc247a9d..db69c4e068a 100644 --- a/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall.expected +++ b/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall.expected @@ -1 +1 @@ -| gen_macro_call.rs:5:5:5:11 | MacroCall | hasExtendedCanonicalPath: | no | hasCrateOrigin: | no | getNumberOfAttrs: | 0 | hasPath: | yes | hasTokenTree: | yes | hasExpanded: | yes | +| gen_macro_call.rs:5:5:5:11 | todo!... | hasExtendedCanonicalPath: | no | hasCrateOrigin: | no | getNumberOfAttrs: | 0 | hasPath: | yes | hasTokenTree: | yes | hasExpanded: | yes | diff --git a/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall_getExpanded.expected b/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall_getExpanded.expected index 7bdb564985f..1b60df41f79 100644 --- a/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall_getExpanded.expected +++ b/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall_getExpanded.expected @@ -1 +1 @@ -| gen_macro_call.rs:5:5:5:11 | MacroCall | gen_macro_call.rs:5:5:5:11 | MacroStmts | +| gen_macro_call.rs:5:5:5:11 | todo!... | gen_macro_call.rs:5:5:5:11 | MacroStmts | diff --git a/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall_getPath.expected b/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall_getPath.expected index 33685ad0aad..23762715c9a 100644 --- a/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall_getPath.expected +++ b/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall_getPath.expected @@ -1 +1 @@ -| gen_macro_call.rs:5:5:5:11 | MacroCall | gen_macro_call.rs:5:5:5:8 | todo | +| gen_macro_call.rs:5:5:5:11 | todo!... | gen_macro_call.rs:5:5:5:8 | todo | diff --git a/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall_getTokenTree.expected b/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall_getTokenTree.expected index 5f92a68536c..d2ed004ecc4 100644 --- a/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall_getTokenTree.expected +++ b/rust/ql/test/extractor-tests/generated/MacroCall/MacroCall_getTokenTree.expected @@ -1 +1 @@ -| gen_macro_call.rs:5:5:5:11 | MacroCall | gen_macro_call.rs:5:10:5:11 | TokenTree | +| gen_macro_call.rs:5:5:5:11 | todo!... | gen_macro_call.rs:5:10:5:11 | TokenTree | diff --git a/rust/ql/test/extractor-tests/generated/MacroExpr/MacroExpr_getMacroCall.expected b/rust/ql/test/extractor-tests/generated/MacroExpr/MacroExpr_getMacroCall.expected index 5a635cabcbe..c1815adac09 100644 --- a/rust/ql/test/extractor-tests/generated/MacroExpr/MacroExpr_getMacroCall.expected +++ b/rust/ql/test/extractor-tests/generated/MacroExpr/MacroExpr_getMacroCall.expected @@ -1 +1 @@ -| gen_macro_expr.rs:5:5:5:11 | MacroExpr | gen_macro_expr.rs:5:5:5:11 | MacroCall | +| gen_macro_expr.rs:5:5:5:11 | MacroExpr | gen_macro_expr.rs:5:5:5:11 | todo!... | diff --git a/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected index 02210855a69..b7a9f37a672 100644 --- a/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected +++ b/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected @@ -1,9 +1,9 @@ uniqueNodeLocation | file://:0:0:0:0 | ... .parent(...) | Node should have one location but has 0. | | file://:0:0:0:0 | ... .unwrap(...) | Node should have one location but has 0. | -| file://:0:0:0:0 | BlockExpr | Node should have one location but has 0. | -| file://:0:0:0:0 | Param | Node should have one location but has 0. | | file://:0:0:0:0 | path | Node should have one location but has 0. | | file://:0:0:0:0 | path | Node should have one location but has 0. | +| file://:0:0:0:0 | path: RefType | Node should have one location but has 0. | +| file://:0:0:0:0 | { ... } | Node should have one location but has 0. | missingLocation | Nodes without location: 6 | diff --git a/rust/ql/test/extractor-tests/generated/MacroItems/MacroItems_getItem.expected b/rust/ql/test/extractor-tests/generated/MacroItems/MacroItems_getItem.expected index a66e6bcca5e..5940fb61696 100644 --- a/rust/ql/test/extractor-tests/generated/MacroItems/MacroItems_getItem.expected +++ b/rust/ql/test/extractor-tests/generated/MacroItems/MacroItems_getItem.expected @@ -1,2 +1,2 @@ | file://:0:0:0:0 | MacroItems | 0 | file://:0:0:0:0 | Use | -| file://:0:0:0:0 | MacroItems | 1 | file://:0:0:0:0 | get_parent | +| file://:0:0:0:0 | MacroItems | 1 | file://:0:0:0:0 | fn get_parent | diff --git a/rust/ql/test/extractor-tests/generated/MacroStmts/MacroStmts_getExpr.expected b/rust/ql/test/extractor-tests/generated/MacroStmts/MacroStmts_getExpr.expected index 7d30926c152..d1390595304 100644 --- a/rust/ql/test/extractor-tests/generated/MacroStmts/MacroStmts_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/MacroStmts/MacroStmts_getExpr.expected @@ -1 +1 @@ -| gen_macro_stmts.rs:5:14:5:28 | MacroStmts | gen_macro_stmts.rs:5:14:5:28 | BlockExpr | +| gen_macro_stmts.rs:5:14:5:28 | MacroStmts | gen_macro_stmts.rs:5:14:5:28 | { ... } | diff --git a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm.expected b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm.expected index b685f882362..34033eeee08 100644 --- a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm.expected +++ b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm.expected @@ -1,4 +1,4 @@ -| gen_match_arm.rs:6:9:6:29 | MatchArm | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | -| gen_match_arm.rs:7:9:7:26 | MatchArm | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | -| gen_match_arm.rs:10:9:10:35 | MatchArm | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | yes | hasPat: | yes | -| gen_match_arm.rs:11:9:11:15 | MatchArm | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | +| gen_match_arm.rs:6:9:6:29 | TupleStructPat => ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | +| gen_match_arm.rs:7:9:7:26 | Option::None => ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | +| gen_match_arm.rs:10:9:10:35 | TupleStructPatif ... => ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | yes | hasPat: | yes | +| gen_match_arm.rs:11:9:11:15 | _ => ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getGuard.expected b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getGuard.expected index 4e5da987474..ad59397e84a 100644 --- a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getGuard.expected +++ b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getGuard.expected @@ -1 +1 @@ -| gen_match_arm.rs:10:9:10:35 | MatchArm | gen_match_arm.rs:10:17:10:25 | MatchGuard | +| gen_match_arm.rs:10:9:10:35 | TupleStructPatif ... => ... | gen_match_arm.rs:10:17:10:25 | MatchGuard | diff --git a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getPat.expected b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getPat.expected index 41f79ed16c9..2d8cf38991d 100644 --- a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getPat.expected @@ -1,4 +1,4 @@ -| gen_match_arm.rs:6:9:6:29 | MatchArm | gen_match_arm.rs:6:9:6:23 | TupleStructPat | -| gen_match_arm.rs:7:9:7:26 | MatchArm | gen_match_arm.rs:7:9:7:20 | PathPat | -| gen_match_arm.rs:10:9:10:35 | MatchArm | gen_match_arm.rs:10:9:10:15 | TupleStructPat | -| gen_match_arm.rs:11:9:11:15 | MatchArm | gen_match_arm.rs:11:9:11:9 | WildcardPat | +| gen_match_arm.rs:6:9:6:29 | TupleStructPat => ... | gen_match_arm.rs:6:9:6:23 | TupleStructPat | +| gen_match_arm.rs:7:9:7:26 | Option::None => ... | gen_match_arm.rs:7:9:7:20 | Option::None | +| gen_match_arm.rs:10:9:10:35 | TupleStructPatif ... => ... | gen_match_arm.rs:10:9:10:15 | TupleStructPat | +| gen_match_arm.rs:11:9:11:15 | _ => ... | gen_match_arm.rs:11:9:11:9 | _ | diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected index 4591d8a57c3..ae8f3edb665 100644 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected @@ -1,2 +1,2 @@ -| gen_match_expr.rs:5:5:8:5 | MatchExpr | getNumberOfAttrs: | 0 | hasExpr: | yes | hasMatchArmList: | yes | -| gen_match_expr.rs:9:5:12:5 | MatchExpr | getNumberOfAttrs: | 0 | hasExpr: | yes | hasMatchArmList: | yes | +| gen_match_expr.rs:5:5:8:5 | match ... { ... } | getNumberOfAttrs: | 0 | hasExpr: | yes | hasMatchArmList: | yes | +| gen_match_expr.rs:9:5:12:5 | match ... { ... } | getNumberOfAttrs: | 0 | hasExpr: | yes | hasMatchArmList: | yes | diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.expected index 924eb3f807f..ac1ec296029 100644 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.expected @@ -1,2 +1,2 @@ -| gen_match_expr.rs:5:5:8:5 | MatchExpr | gen_match_expr.rs:5:11:5:11 | x | -| gen_match_expr.rs:9:5:12:5 | MatchExpr | gen_match_expr.rs:9:11:9:11 | x | +| gen_match_expr.rs:5:5:8:5 | match ... { ... } | gen_match_expr.rs:5:11:5:11 | x | +| gen_match_expr.rs:9:5:12:5 | match ... { ... } | gen_match_expr.rs:9:11:9:11 | x | diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchArmList.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchArmList.expected index db83ecb1c53..468fe9d14cf 100644 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchArmList.expected +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchArmList.expected @@ -1,2 +1,2 @@ -| gen_match_expr.rs:5:5:8:5 | MatchExpr | gen_match_expr.rs:5:13:8:5 | MatchArmList | -| gen_match_expr.rs:9:5:12:5 | MatchExpr | gen_match_expr.rs:9:13:12:5 | MatchArmList | +| gen_match_expr.rs:5:5:8:5 | match ... { ... } | gen_match_expr.rs:5:13:8:5 | MatchArmList | +| gen_match_expr.rs:9:5:12:5 | match ... { ... } | gen_match_expr.rs:9:13:12:5 | MatchArmList | diff --git a/rust/ql/test/extractor-tests/generated/Module/Module.expected b/rust/ql/test/extractor-tests/generated/Module/Module.expected index d7c04f7c118..11b6d9e1e9b 100644 --- a/rust/ql/test/extractor-tests/generated/Module/Module.expected +++ b/rust/ql/test/extractor-tests/generated/Module/Module.expected @@ -1,3 +1,3 @@ -| gen_module.rs:3:1:4:8 | Module | hasExtendedCanonicalPath: | yes | hasCrateOrigin: | yes | getNumberOfAttrs: | 0 | hasItemList: | no | hasName: | yes | hasVisibility: | no | -| gen_module.rs:5:1:7:1 | Module | hasExtendedCanonicalPath: | yes | hasCrateOrigin: | yes | getNumberOfAttrs: | 0 | hasItemList: | yes | hasName: | yes | hasVisibility: | no | -| lib.rs:1:1:1:15 | Module | hasExtendedCanonicalPath: | yes | hasCrateOrigin: | yes | getNumberOfAttrs: | 0 | hasItemList: | no | hasName: | yes | hasVisibility: | no | +| gen_module.rs:3:1:4:8 | mod foo | hasExtendedCanonicalPath: | yes | hasCrateOrigin: | yes | getNumberOfAttrs: | 0 | hasItemList: | no | hasName: | yes | hasVisibility: | no | +| gen_module.rs:5:1:7:1 | mod bar | hasExtendedCanonicalPath: | yes | hasCrateOrigin: | yes | getNumberOfAttrs: | 0 | hasItemList: | yes | hasName: | yes | hasVisibility: | no | +| lib.rs:1:1:1:15 | mod gen_module | hasExtendedCanonicalPath: | yes | hasCrateOrigin: | yes | getNumberOfAttrs: | 0 | hasItemList: | no | hasName: | yes | hasVisibility: | no | diff --git a/rust/ql/test/extractor-tests/generated/Module/Module_getCrateOrigin.expected b/rust/ql/test/extractor-tests/generated/Module/Module_getCrateOrigin.expected index e2e58c030ef..0164fbb8e29 100644 --- a/rust/ql/test/extractor-tests/generated/Module/Module_getCrateOrigin.expected +++ b/rust/ql/test/extractor-tests/generated/Module/Module_getCrateOrigin.expected @@ -1,3 +1,3 @@ -| gen_module.rs:3:1:4:8 | Module | repo::test | -| gen_module.rs:5:1:7:1 | Module | repo::test | -| lib.rs:1:1:1:15 | Module | repo::test | +| gen_module.rs:3:1:4:8 | mod foo | repo::test | +| gen_module.rs:5:1:7:1 | mod bar | repo::test | +| lib.rs:1:1:1:15 | mod gen_module | repo::test | diff --git a/rust/ql/test/extractor-tests/generated/Module/Module_getExtendedCanonicalPath.expected b/rust/ql/test/extractor-tests/generated/Module/Module_getExtendedCanonicalPath.expected index 19eadfdafd5..c573ef164eb 100644 --- a/rust/ql/test/extractor-tests/generated/Module/Module_getExtendedCanonicalPath.expected +++ b/rust/ql/test/extractor-tests/generated/Module/Module_getExtendedCanonicalPath.expected @@ -1,3 +1,3 @@ -| gen_module.rs:3:1:4:8 | Module | crate::gen_module::foo | -| gen_module.rs:5:1:7:1 | Module | crate::gen_module::bar | -| lib.rs:1:1:1:15 | Module | crate::gen_module | +| gen_module.rs:3:1:4:8 | mod foo | crate::gen_module::foo | +| gen_module.rs:5:1:7:1 | mod bar | crate::gen_module::bar | +| lib.rs:1:1:1:15 | mod gen_module | crate::gen_module | diff --git a/rust/ql/test/extractor-tests/generated/Module/Module_getItemList.expected b/rust/ql/test/extractor-tests/generated/Module/Module_getItemList.expected index 04fd8d4a81a..8edc36efa73 100644 --- a/rust/ql/test/extractor-tests/generated/Module/Module_getItemList.expected +++ b/rust/ql/test/extractor-tests/generated/Module/Module_getItemList.expected @@ -1 +1 @@ -| gen_module.rs:5:1:7:1 | Module | gen_module.rs:5:9:7:1 | ItemList | +| gen_module.rs:5:1:7:1 | mod bar | gen_module.rs:5:9:7:1 | ItemList | diff --git a/rust/ql/test/extractor-tests/generated/Module/Module_getName.expected b/rust/ql/test/extractor-tests/generated/Module/Module_getName.expected index cc295b1da89..1874862befe 100644 --- a/rust/ql/test/extractor-tests/generated/Module/Module_getName.expected +++ b/rust/ql/test/extractor-tests/generated/Module/Module_getName.expected @@ -1,3 +1,3 @@ -| gen_module.rs:3:1:4:8 | Module | gen_module.rs:4:5:4:7 | foo | -| gen_module.rs:5:1:7:1 | Module | gen_module.rs:5:5:5:7 | bar | -| lib.rs:1:1:1:15 | Module | lib.rs:1:5:1:14 | gen_module | +| gen_module.rs:3:1:4:8 | mod foo | gen_module.rs:4:5:4:7 | foo | +| gen_module.rs:5:1:7:1 | mod bar | gen_module.rs:5:5:5:7 | bar | +| lib.rs:1:1:1:15 | mod gen_module | lib.rs:1:5:1:14 | gen_module | diff --git a/rust/ql/test/extractor-tests/generated/OffsetOfExpr/OffsetOfExpr_getTy.expected b/rust/ql/test/extractor-tests/generated/OffsetOfExpr/OffsetOfExpr_getTy.expected index c7d0f2ee6af..e2e11abb6a0 100644 --- a/rust/ql/test/extractor-tests/generated/OffsetOfExpr/OffsetOfExpr_getTy.expected +++ b/rust/ql/test/extractor-tests/generated/OffsetOfExpr/OffsetOfExpr_getTy.expected @@ -1 +1 @@ -| gen_offset_of_expr.rs:5:5:5:38 | OffsetOfExpr | gen_offset_of_expr.rs:5:25:5:30 | PathType | +| gen_offset_of_expr.rs:5:5:5:38 | OffsetOfExpr | gen_offset_of_expr.rs:5:25:5:30 | Struct | diff --git a/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected b/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected index 786a0018093..3574d6c1828 100644 --- a/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected +++ b/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected @@ -1 +1 @@ -| gen_or_pat.rs:6:9:6:38 | OrPat | getNumberOfPats: | 2 | +| gen_or_pat.rs:6:9:6:38 | ... \| ... | getNumberOfPats: | 2 | diff --git a/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected b/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected index a701548b234..ca76590a626 100644 --- a/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected @@ -1,2 +1,2 @@ -| gen_or_pat.rs:6:9:6:38 | OrPat | 0 | gen_or_pat.rs:6:9:6:23 | TupleStructPat | -| gen_or_pat.rs:6:9:6:38 | OrPat | 1 | gen_or_pat.rs:6:27:6:38 | PathPat | +| gen_or_pat.rs:6:9:6:38 | ... \| ... | 0 | gen_or_pat.rs:6:9:6:23 | TupleStructPat | +| gen_or_pat.rs:6:9:6:38 | ... \| ... | 1 | gen_or_pat.rs:6:27:6:38 | Option::None | diff --git a/rust/ql/test/extractor-tests/generated/PathPat/PathPat.expected b/rust/ql/test/extractor-tests/generated/PathPat/PathPat.expected index 54845a7565c..f7cee5c5586 100644 --- a/rust/ql/test/extractor-tests/generated/PathPat/PathPat.expected +++ b/rust/ql/test/extractor-tests/generated/PathPat/PathPat.expected @@ -1 +1 @@ -| gen_path_pat.rs:6:9:6:16 | PathPat | hasPath: | yes | +| gen_path_pat.rs:6:9:6:16 | Foo::Bar | hasPath: | yes | diff --git a/rust/ql/test/extractor-tests/generated/PathPat/PathPat_getPath.expected b/rust/ql/test/extractor-tests/generated/PathPat/PathPat_getPath.expected index d48ba6549db..1f450c24938 100644 --- a/rust/ql/test/extractor-tests/generated/PathPat/PathPat_getPath.expected +++ b/rust/ql/test/extractor-tests/generated/PathPat/PathPat_getPath.expected @@ -1 +1 @@ -| gen_path_pat.rs:6:9:6:16 | PathPat | gen_path_pat.rs:6:9:6:16 | Foo::Bar | +| gen_path_pat.rs:6:9:6:16 | Foo::Bar | gen_path_pat.rs:6:9:6:16 | Foo::Bar | diff --git a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr.expected b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr.expected index 6f222c18f03..de7e26d5197 100644 --- a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr.expected +++ b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr.expected @@ -1,6 +1,6 @@ -| gen_range_expr.rs:5:13:5:18 | RangeExpr | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | yes | -| gen_range_expr.rs:6:13:6:17 | RangeExpr | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | yes | -| gen_range_expr.rs:7:13:7:16 | RangeExpr | getNumberOfAttrs: | 0 | hasEnd: | no | hasOperatorName: | yes | hasStart: | yes | -| gen_range_expr.rs:8:13:8:16 | RangeExpr | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | no | -| gen_range_expr.rs:9:13:9:17 | RangeExpr | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | no | -| gen_range_expr.rs:10:13:10:14 | RangeExpr | getNumberOfAttrs: | 0 | hasEnd: | no | hasOperatorName: | yes | hasStart: | no | +| gen_range_expr.rs:5:13:5:18 | ... ..= ... | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | yes | +| gen_range_expr.rs:6:13:6:17 | ... .. ... | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | yes | +| gen_range_expr.rs:7:13:7:16 | ... .. ... | getNumberOfAttrs: | 0 | hasEnd: | no | hasOperatorName: | yes | hasStart: | yes | +| gen_range_expr.rs:8:13:8:16 | ... .. ... | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | no | +| gen_range_expr.rs:9:13:9:17 | ... ..= ... | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | no | +| gen_range_expr.rs:10:13:10:14 | ... .. ... | getNumberOfAttrs: | 0 | hasEnd: | no | hasOperatorName: | yes | hasStart: | no | diff --git a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getEnd.expected b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getEnd.expected index 101ae46138a..85582cfd97f 100644 --- a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getEnd.expected +++ b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getEnd.expected @@ -1,4 +1,4 @@ -| gen_range_expr.rs:5:13:5:18 | RangeExpr | gen_range_expr.rs:5:17:5:18 | 10 | -| gen_range_expr.rs:6:13:6:17 | RangeExpr | gen_range_expr.rs:6:16:6:17 | 10 | -| gen_range_expr.rs:8:13:8:16 | RangeExpr | gen_range_expr.rs:8:15:8:16 | 10 | -| gen_range_expr.rs:9:13:9:17 | RangeExpr | gen_range_expr.rs:9:16:9:17 | 10 | +| gen_range_expr.rs:5:13:5:18 | ... ..= ... | gen_range_expr.rs:5:17:5:18 | 10 | +| gen_range_expr.rs:6:13:6:17 | ... .. ... | gen_range_expr.rs:6:16:6:17 | 10 | +| gen_range_expr.rs:8:13:8:16 | ... .. ... | gen_range_expr.rs:8:15:8:16 | 10 | +| gen_range_expr.rs:9:13:9:17 | ... ..= ... | gen_range_expr.rs:9:16:9:17 | 10 | diff --git a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getOperatorName.expected b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getOperatorName.expected index b0d778eb7bb..ff6f77424c7 100644 --- a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getOperatorName.expected +++ b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getOperatorName.expected @@ -1,6 +1,6 @@ -| gen_range_expr.rs:5:13:5:18 | RangeExpr | ..= | -| gen_range_expr.rs:6:13:6:17 | RangeExpr | .. | -| gen_range_expr.rs:7:13:7:16 | RangeExpr | .. | -| gen_range_expr.rs:8:13:8:16 | RangeExpr | .. | -| gen_range_expr.rs:9:13:9:17 | RangeExpr | ..= | -| gen_range_expr.rs:10:13:10:14 | RangeExpr | .. | +| gen_range_expr.rs:5:13:5:18 | ... ..= ... | ..= | +| gen_range_expr.rs:6:13:6:17 | ... .. ... | .. | +| gen_range_expr.rs:7:13:7:16 | ... .. ... | .. | +| gen_range_expr.rs:8:13:8:16 | ... .. ... | .. | +| gen_range_expr.rs:9:13:9:17 | ... ..= ... | ..= | +| gen_range_expr.rs:10:13:10:14 | ... .. ... | .. | diff --git a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getStart.expected b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getStart.expected index 79b34397efe..0a012e5ecd5 100644 --- a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getStart.expected +++ b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getStart.expected @@ -1,3 +1,3 @@ -| gen_range_expr.rs:5:13:5:18 | RangeExpr | gen_range_expr.rs:5:13:5:13 | 1 | -| gen_range_expr.rs:6:13:6:17 | RangeExpr | gen_range_expr.rs:6:13:6:13 | 1 | -| gen_range_expr.rs:7:13:7:16 | RangeExpr | gen_range_expr.rs:7:13:7:14 | 10 | +| gen_range_expr.rs:5:13:5:18 | ... ..= ... | gen_range_expr.rs:5:13:5:13 | 1 | +| gen_range_expr.rs:6:13:6:17 | ... .. ... | gen_range_expr.rs:6:13:6:13 | 1 | +| gen_range_expr.rs:7:13:7:16 | ... .. ... | gen_range_expr.rs:7:13:7:14 | 10 | diff --git a/rust/ql/test/extractor-tests/generated/RangePat/RangePat_getEnd.expected b/rust/ql/test/extractor-tests/generated/RangePat/RangePat_getEnd.expected index 591b8d9093e..38ded3fb940 100644 --- a/rust/ql/test/extractor-tests/generated/RangePat/RangePat_getEnd.expected +++ b/rust/ql/test/extractor-tests/generated/RangePat/RangePat_getEnd.expected @@ -1,2 +1,2 @@ -| gen_range_pat.rs:6:9:6:12 | RangePat | gen_range_pat.rs:6:11:6:12 | LiteralPat | -| gen_range_pat.rs:7:9:7:15 | RangePat | gen_range_pat.rs:7:14:7:15 | LiteralPat | +| gen_range_pat.rs:6:9:6:12 | RangePat | gen_range_pat.rs:6:11:6:12 | 15 | +| gen_range_pat.rs:7:9:7:15 | RangePat | gen_range_pat.rs:7:14:7:15 | 25 | diff --git a/rust/ql/test/extractor-tests/generated/RangePat/RangePat_getStart.expected b/rust/ql/test/extractor-tests/generated/RangePat/RangePat_getStart.expected index ef6a8ea2121..ac6eadaf08c 100644 --- a/rust/ql/test/extractor-tests/generated/RangePat/RangePat_getStart.expected +++ b/rust/ql/test/extractor-tests/generated/RangePat/RangePat_getStart.expected @@ -1,2 +1,2 @@ -| gen_range_pat.rs:7:9:7:15 | RangePat | gen_range_pat.rs:7:9:7:10 | LiteralPat | -| gen_range_pat.rs:8:9:8:12 | RangePat | gen_range_pat.rs:8:9:8:10 | LiteralPat | +| gen_range_pat.rs:7:9:7:15 | RangePat | gen_range_pat.rs:7:9:7:10 | 16 | +| gen_range_pat.rs:8:9:8:12 | RangePat | gen_range_pat.rs:8:9:8:10 | 26 | diff --git a/rust/ql/test/extractor-tests/generated/RecordExpr/RecordExpr.expected b/rust/ql/test/extractor-tests/generated/RecordExpr/RecordExpr.expected index d30c4ef70e5..445b906bf88 100644 --- a/rust/ql/test/extractor-tests/generated/RecordExpr/RecordExpr.expected +++ b/rust/ql/test/extractor-tests/generated/RecordExpr/RecordExpr.expected @@ -1,4 +1,4 @@ -| gen_record_expr.rs:5:17:5:34 | RecordExpr | hasPath: | yes | hasRecordExprFieldList: | yes | -| gen_record_expr.rs:6:18:6:38 | RecordExpr | hasPath: | yes | hasRecordExprFieldList: | yes | -| gen_record_expr.rs:7:5:7:22 | RecordExpr | hasPath: | yes | hasRecordExprFieldList: | yes | -| gen_record_expr.rs:8:5:8:14 | RecordExpr | hasPath: | yes | hasRecordExprFieldList: | yes | +| gen_record_expr.rs:5:17:5:34 | Foo {...} | hasPath: | yes | hasRecordExprFieldList: | yes | +| gen_record_expr.rs:6:18:6:38 | Foo {...} | hasPath: | yes | hasRecordExprFieldList: | yes | +| gen_record_expr.rs:7:5:7:22 | Foo {...} | hasPath: | yes | hasRecordExprFieldList: | yes | +| gen_record_expr.rs:8:5:8:14 | Foo {...} | hasPath: | yes | hasRecordExprFieldList: | yes | diff --git a/rust/ql/test/extractor-tests/generated/RecordExpr/RecordExpr_getPath.expected b/rust/ql/test/extractor-tests/generated/RecordExpr/RecordExpr_getPath.expected index 91d4f5cb0b5..5aad8aad60c 100644 --- a/rust/ql/test/extractor-tests/generated/RecordExpr/RecordExpr_getPath.expected +++ b/rust/ql/test/extractor-tests/generated/RecordExpr/RecordExpr_getPath.expected @@ -1,4 +1,4 @@ -| gen_record_expr.rs:5:17:5:34 | RecordExpr | gen_record_expr.rs:5:17:5:19 | Foo | -| gen_record_expr.rs:6:18:6:38 | RecordExpr | gen_record_expr.rs:6:18:6:20 | Foo | -| gen_record_expr.rs:7:5:7:22 | RecordExpr | gen_record_expr.rs:7:5:7:7 | Foo | -| gen_record_expr.rs:8:5:8:14 | RecordExpr | gen_record_expr.rs:8:5:8:7 | Foo | +| gen_record_expr.rs:5:17:5:34 | Foo {...} | gen_record_expr.rs:5:17:5:19 | Foo | +| gen_record_expr.rs:6:18:6:38 | Foo {...} | gen_record_expr.rs:6:18:6:20 | Foo | +| gen_record_expr.rs:7:5:7:22 | Foo {...} | gen_record_expr.rs:7:5:7:7 | Foo | +| gen_record_expr.rs:8:5:8:14 | Foo {...} | gen_record_expr.rs:8:5:8:7 | Foo | diff --git a/rust/ql/test/extractor-tests/generated/RecordExpr/RecordExpr_getRecordExprFieldList.expected b/rust/ql/test/extractor-tests/generated/RecordExpr/RecordExpr_getRecordExprFieldList.expected index d00bf3935d3..79d18cac3b0 100644 --- a/rust/ql/test/extractor-tests/generated/RecordExpr/RecordExpr_getRecordExprFieldList.expected +++ b/rust/ql/test/extractor-tests/generated/RecordExpr/RecordExpr_getRecordExprFieldList.expected @@ -1,4 +1,4 @@ -| gen_record_expr.rs:5:17:5:34 | RecordExpr | gen_record_expr.rs:5:21:5:34 | RecordExprFieldList | -| gen_record_expr.rs:6:18:6:38 | RecordExpr | gen_record_expr.rs:6:22:6:38 | RecordExprFieldList | -| gen_record_expr.rs:7:5:7:22 | RecordExpr | gen_record_expr.rs:7:9:7:22 | RecordExprFieldList | -| gen_record_expr.rs:8:5:8:14 | RecordExpr | gen_record_expr.rs:8:9:8:14 | RecordExprFieldList | +| gen_record_expr.rs:5:17:5:34 | Foo {...} | gen_record_expr.rs:5:21:5:34 | RecordExprFieldList | +| gen_record_expr.rs:6:18:6:38 | Foo {...} | gen_record_expr.rs:6:22:6:38 | RecordExprFieldList | +| gen_record_expr.rs:7:5:7:22 | Foo {...} | gen_record_expr.rs:7:9:7:22 | RecordExprFieldList | +| gen_record_expr.rs:8:5:8:14 | Foo {...} | gen_record_expr.rs:8:9:8:14 | RecordExprFieldList | diff --git a/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField.expected b/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField.expected index 79ed3875918..7f3dd059b0a 100644 --- a/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField.expected +++ b/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField.expected @@ -1,2 +1,2 @@ -| gen_record_expr_field.rs:5:11:5:14 | RecordExprField | getNumberOfAttrs: | 0 | hasExpr: | yes | hasNameRef: | yes | -| gen_record_expr_field.rs:5:17:5:20 | RecordExprField | getNumberOfAttrs: | 0 | hasExpr: | yes | hasNameRef: | yes | +| gen_record_expr_field.rs:5:11:5:14 | a: ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasNameRef: | yes | +| gen_record_expr_field.rs:5:17:5:20 | b: ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasNameRef: | yes | diff --git a/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getExpr.expected b/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getExpr.expected index ec096d00a31..2af437f842b 100644 --- a/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getExpr.expected @@ -1,2 +1,2 @@ -| gen_record_expr_field.rs:5:11:5:14 | RecordExprField | gen_record_expr_field.rs:5:14:5:14 | 1 | -| gen_record_expr_field.rs:5:17:5:20 | RecordExprField | gen_record_expr_field.rs:5:20:5:20 | 2 | +| gen_record_expr_field.rs:5:11:5:14 | a: ... | gen_record_expr_field.rs:5:14:5:14 | 1 | +| gen_record_expr_field.rs:5:17:5:20 | b: ... | gen_record_expr_field.rs:5:20:5:20 | 2 | diff --git a/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getNameRef.expected b/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getNameRef.expected index 081e3ccac56..d0fcb3d0d44 100644 --- a/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getNameRef.expected +++ b/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getNameRef.expected @@ -1,2 +1,2 @@ -| gen_record_expr_field.rs:5:11:5:14 | RecordExprField | gen_record_expr_field.rs:5:11:5:11 | a | -| gen_record_expr_field.rs:5:17:5:20 | RecordExprField | gen_record_expr_field.rs:5:17:5:17 | b | +| gen_record_expr_field.rs:5:11:5:14 | a: ... | gen_record_expr_field.rs:5:11:5:11 | a | +| gen_record_expr_field.rs:5:17:5:20 | b: ... | gen_record_expr_field.rs:5:17:5:17 | b | diff --git a/rust/ql/test/extractor-tests/generated/RecordPat/RecordPat.expected b/rust/ql/test/extractor-tests/generated/RecordPat/RecordPat.expected index 62cd3eb3c37..8d7f96229ad 100644 --- a/rust/ql/test/extractor-tests/generated/RecordPat/RecordPat.expected +++ b/rust/ql/test/extractor-tests/generated/RecordPat/RecordPat.expected @@ -1,2 +1,2 @@ -| gen_record_pat.rs:6:9:6:26 | RecordPat | hasPath: | yes | hasRecordPatFieldList: | yes | -| gen_record_pat.rs:7:9:7:18 | RecordPat | hasPath: | yes | hasRecordPatFieldList: | yes | +| gen_record_pat.rs:6:9:6:26 | Foo {...} | hasPath: | yes | hasRecordPatFieldList: | yes | +| gen_record_pat.rs:7:9:7:18 | Foo {...} | hasPath: | yes | hasRecordPatFieldList: | yes | diff --git a/rust/ql/test/extractor-tests/generated/RecordPat/RecordPat_getPath.expected b/rust/ql/test/extractor-tests/generated/RecordPat/RecordPat_getPath.expected index a9e0be01d5b..7cd2f51d9eb 100644 --- a/rust/ql/test/extractor-tests/generated/RecordPat/RecordPat_getPath.expected +++ b/rust/ql/test/extractor-tests/generated/RecordPat/RecordPat_getPath.expected @@ -1,2 +1,2 @@ -| gen_record_pat.rs:6:9:6:26 | RecordPat | gen_record_pat.rs:6:9:6:11 | Foo | -| gen_record_pat.rs:7:9:7:18 | RecordPat | gen_record_pat.rs:7:9:7:11 | Foo | +| gen_record_pat.rs:6:9:6:26 | Foo {...} | gen_record_pat.rs:6:9:6:11 | Foo | +| gen_record_pat.rs:7:9:7:18 | Foo {...} | gen_record_pat.rs:7:9:7:11 | Foo | diff --git a/rust/ql/test/extractor-tests/generated/RecordPat/RecordPat_getRecordPatFieldList.expected b/rust/ql/test/extractor-tests/generated/RecordPat/RecordPat_getRecordPatFieldList.expected index 86ba10ed9a3..bad0003c07b 100644 --- a/rust/ql/test/extractor-tests/generated/RecordPat/RecordPat_getRecordPatFieldList.expected +++ b/rust/ql/test/extractor-tests/generated/RecordPat/RecordPat_getRecordPatFieldList.expected @@ -1,2 +1,2 @@ -| gen_record_pat.rs:6:9:6:26 | RecordPat | gen_record_pat.rs:6:13:6:26 | RecordPatFieldList | -| gen_record_pat.rs:7:9:7:18 | RecordPat | gen_record_pat.rs:7:13:7:18 | RecordPatFieldList | +| gen_record_pat.rs:6:9:6:26 | Foo {...} | gen_record_pat.rs:6:13:6:26 | RecordPatFieldList | +| gen_record_pat.rs:7:9:7:18 | Foo {...} | gen_record_pat.rs:7:13:7:18 | RecordPatFieldList | diff --git a/rust/ql/test/extractor-tests/generated/RecordPatField/RecordPatField_getPat.expected b/rust/ql/test/extractor-tests/generated/RecordPatField/RecordPatField_getPat.expected index a3ac24ec52b..1fa8a0f8bb7 100644 --- a/rust/ql/test/extractor-tests/generated/RecordPatField/RecordPatField_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/RecordPatField/RecordPatField_getPat.expected @@ -1,2 +1,2 @@ -| gen_record_pat_field.rs:5:15:5:18 | RecordPatField | gen_record_pat_field.rs:5:18:5:18 | LiteralPat | -| gen_record_pat_field.rs:5:21:5:24 | RecordPatField | gen_record_pat_field.rs:5:24:5:24 | LiteralPat | +| gen_record_pat_field.rs:5:15:5:18 | RecordPatField | gen_record_pat_field.rs:5:18:5:18 | 1 | +| gen_record_pat_field.rs:5:21:5:24 | RecordPatField | gen_record_pat_field.rs:5:24:5:24 | 2 | diff --git a/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr.expected b/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr.expected index d4c75d9a79a..df32a2465db 100644 --- a/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr.expected +++ b/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr.expected @@ -1,4 +1,4 @@ -| gen_ref_expr.rs:5:25:5:28 | RefExpr | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | no | isMut: | no | isRaw: | no | -| gen_ref_expr.rs:6:23:6:30 | RefExpr | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | no | isMut: | yes | isRaw: | no | -| gen_ref_expr.rs:7:35:7:48 | RefExpr | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | yes | isMut: | no | isRaw: | yes | -| gen_ref_expr.rs:8:33:8:44 | RefExpr | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | no | isMut: | yes | isRaw: | yes | +| gen_ref_expr.rs:5:25:5:28 | &... | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | no | isMut: | no | isRaw: | no | +| gen_ref_expr.rs:6:23:6:30 | &mut ... | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | no | isMut: | yes | isRaw: | no | +| gen_ref_expr.rs:7:35:7:48 | &raw const ... | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | yes | isMut: | no | isRaw: | yes | +| gen_ref_expr.rs:8:33:8:44 | &raw mut ... | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | no | isMut: | yes | isRaw: | yes | diff --git a/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr_getExpr.expected index 571986ecf10..b350b30b6a1 100644 --- a/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr_getExpr.expected @@ -1,4 +1,4 @@ -| gen_ref_expr.rs:5:25:5:28 | RefExpr | gen_ref_expr.rs:5:26:5:28 | foo | -| gen_ref_expr.rs:6:23:6:30 | RefExpr | gen_ref_expr.rs:6:28:6:30 | foo | -| gen_ref_expr.rs:7:35:7:48 | RefExpr | gen_ref_expr.rs:7:46:7:48 | foo | -| gen_ref_expr.rs:8:33:8:44 | RefExpr | gen_ref_expr.rs:8:42:8:44 | foo | +| gen_ref_expr.rs:5:25:5:28 | &... | gen_ref_expr.rs:5:26:5:28 | foo | +| gen_ref_expr.rs:6:23:6:30 | &mut ... | gen_ref_expr.rs:6:28:6:30 | foo | +| gen_ref_expr.rs:7:35:7:48 | &raw const ... | gen_ref_expr.rs:7:46:7:48 | foo | +| gen_ref_expr.rs:8:33:8:44 | &raw mut ... | gen_ref_expr.rs:8:42:8:44 | foo | diff --git a/rust/ql/test/extractor-tests/generated/RefPat/RefPat.expected b/rust/ql/test/extractor-tests/generated/RefPat/RefPat.expected index c2fc3416297..b851902ff56 100644 --- a/rust/ql/test/extractor-tests/generated/RefPat/RefPat.expected +++ b/rust/ql/test/extractor-tests/generated/RefPat/RefPat.expected @@ -1,2 +1,2 @@ -| gen_ref_pat.rs:6:9:6:28 | RefPat | isMut: | yes | hasPat: | yes | -| gen_ref_pat.rs:7:9:7:21 | RefPat | isMut: | no | hasPat: | yes | +| gen_ref_pat.rs:6:9:6:28 | &mut ... | isMut: | yes | hasPat: | yes | +| gen_ref_pat.rs:7:9:7:21 | &... | isMut: | no | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/RefPat/RefPat_getPat.expected b/rust/ql/test/extractor-tests/generated/RefPat/RefPat_getPat.expected index 891c3c8216e..6078837ceea 100644 --- a/rust/ql/test/extractor-tests/generated/RefPat/RefPat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/RefPat/RefPat_getPat.expected @@ -1,2 +1,2 @@ -| gen_ref_pat.rs:6:9:6:28 | RefPat | gen_ref_pat.rs:6:14:6:28 | TupleStructPat | -| gen_ref_pat.rs:7:9:7:21 | RefPat | gen_ref_pat.rs:7:10:7:21 | PathPat | +| gen_ref_pat.rs:6:9:6:28 | &mut ... | gen_ref_pat.rs:6:14:6:28 | TupleStructPat | +| gen_ref_pat.rs:7:9:7:21 | &... | gen_ref_pat.rs:7:10:7:21 | Option::None | diff --git a/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr.expected b/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr.expected index dbf54e0f49b..c1d4bfbb626 100644 --- a/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr.expected +++ b/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr.expected @@ -1,2 +1,2 @@ -| gen_return_expr.rs:5:5:5:13 | ReturnExpr | getNumberOfAttrs: | 0 | hasExpr: | yes | -| gen_return_expr.rs:8:5:8:10 | ReturnExpr | getNumberOfAttrs: | 0 | hasExpr: | no | +| gen_return_expr.rs:5:5:5:13 | return ... | getNumberOfAttrs: | 0 | hasExpr: | yes | +| gen_return_expr.rs:8:5:8:10 | return | getNumberOfAttrs: | 0 | hasExpr: | no | diff --git a/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr_getExpr.expected index 2e1a4a8f8ce..eb4b7a5f1aa 100644 --- a/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr_getExpr.expected @@ -1 +1 @@ -| gen_return_expr.rs:5:5:5:13 | ReturnExpr | gen_return_expr.rs:5:12:5:13 | 42 | +| gen_return_expr.rs:5:5:5:13 | return ... | gen_return_expr.rs:5:12:5:13 | 42 | diff --git a/rust/ql/test/extractor-tests/generated/SlicePat/SlicePat_getPat.expected b/rust/ql/test/extractor-tests/generated/SlicePat/SlicePat_getPat.expected index e874d3a22ee..0725988f37f 100644 --- a/rust/ql/test/extractor-tests/generated/SlicePat/SlicePat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/SlicePat/SlicePat_getPat.expected @@ -1,13 +1,13 @@ -| gen_slice_pat.rs:6:9:6:23 | SlicePat | 0 | gen_slice_pat.rs:6:10:6:10 | LiteralPat | -| gen_slice_pat.rs:6:9:6:23 | SlicePat | 1 | gen_slice_pat.rs:6:13:6:13 | LiteralPat | -| gen_slice_pat.rs:6:9:6:23 | SlicePat | 2 | gen_slice_pat.rs:6:16:6:16 | LiteralPat | -| gen_slice_pat.rs:6:9:6:23 | SlicePat | 3 | gen_slice_pat.rs:6:19:6:19 | LiteralPat | -| gen_slice_pat.rs:6:9:6:23 | SlicePat | 4 | gen_slice_pat.rs:6:22:6:22 | LiteralPat | -| gen_slice_pat.rs:7:9:7:18 | SlicePat | 0 | gen_slice_pat.rs:7:10:7:10 | LiteralPat | -| gen_slice_pat.rs:7:9:7:18 | SlicePat | 1 | gen_slice_pat.rs:7:13:7:13 | LiteralPat | -| gen_slice_pat.rs:7:9:7:18 | SlicePat | 2 | gen_slice_pat.rs:7:16:7:17 | RestPat | +| gen_slice_pat.rs:6:9:6:23 | SlicePat | 0 | gen_slice_pat.rs:6:10:6:10 | 1 | +| gen_slice_pat.rs:6:9:6:23 | SlicePat | 1 | gen_slice_pat.rs:6:13:6:13 | 2 | +| gen_slice_pat.rs:6:9:6:23 | SlicePat | 2 | gen_slice_pat.rs:6:16:6:16 | 3 | +| gen_slice_pat.rs:6:9:6:23 | SlicePat | 3 | gen_slice_pat.rs:6:19:6:19 | 4 | +| gen_slice_pat.rs:6:9:6:23 | SlicePat | 4 | gen_slice_pat.rs:6:22:6:22 | 5 | +| gen_slice_pat.rs:7:9:7:18 | SlicePat | 0 | gen_slice_pat.rs:7:10:7:10 | 1 | +| gen_slice_pat.rs:7:9:7:18 | SlicePat | 1 | gen_slice_pat.rs:7:13:7:13 | 2 | +| gen_slice_pat.rs:7:9:7:18 | SlicePat | 2 | gen_slice_pat.rs:7:16:7:17 | .. | | gen_slice_pat.rs:8:9:8:24 | SlicePat | 0 | gen_slice_pat.rs:8:10:8:10 | x | | gen_slice_pat.rs:8:9:8:24 | SlicePat | 1 | gen_slice_pat.rs:8:13:8:13 | y | -| gen_slice_pat.rs:8:9:8:24 | SlicePat | 2 | gen_slice_pat.rs:8:16:8:17 | RestPat | +| gen_slice_pat.rs:8:9:8:24 | SlicePat | 2 | gen_slice_pat.rs:8:16:8:17 | .. | | gen_slice_pat.rs:8:9:8:24 | SlicePat | 3 | gen_slice_pat.rs:8:20:8:20 | z | -| gen_slice_pat.rs:8:9:8:24 | SlicePat | 4 | gen_slice_pat.rs:8:23:8:23 | LiteralPat | +| gen_slice_pat.rs:8:9:8:24 | SlicePat | 4 | gen_slice_pat.rs:8:23:8:23 | 7 | diff --git a/rust/ql/test/extractor-tests/generated/SourceFile/SourceFile_getItem.expected b/rust/ql/test/extractor-tests/generated/SourceFile/SourceFile_getItem.expected index a256c2b84b2..981f445201e 100644 --- a/rust/ql/test/extractor-tests/generated/SourceFile/SourceFile_getItem.expected +++ b/rust/ql/test/extractor-tests/generated/SourceFile/SourceFile_getItem.expected @@ -1,2 +1,2 @@ -| gen_source_file.rs:1:1:6:2 | SourceFile | 0 | gen_source_file.rs:3:1:6:1 | test_source_file | -| lib.rs:1:1:1:20 | SourceFile | 0 | lib.rs:1:1:1:20 | Module | +| gen_source_file.rs:1:1:6:2 | SourceFile | 0 | gen_source_file.rs:3:1:6:1 | fn test_source_file | +| lib.rs:1:1:1:20 | SourceFile | 0 | lib.rs:1:1:1:20 | mod gen_source_file | diff --git a/rust/ql/test/extractor-tests/generated/Trait/AssocItemList_getAssocItem.expected b/rust/ql/test/extractor-tests/generated/Trait/AssocItemList_getAssocItem.expected index 0f70039583a..c7337ca090a 100644 --- a/rust/ql/test/extractor-tests/generated/Trait/AssocItemList_getAssocItem.expected +++ b/rust/ql/test/extractor-tests/generated/Trait/AssocItemList_getAssocItem.expected @@ -1,3 +1,3 @@ | gen_trait.rs:4:20:8:1 | AssocItemList | 0 | gen_trait.rs:5:3:5:18 | TypeAlias | | gen_trait.rs:4:20:8:1 | AssocItemList | 1 | gen_trait.rs:6:3:6:20 | TypeAlias | -| gen_trait.rs:4:20:8:1 | AssocItemList | 2 | gen_trait.rs:7:3:7:72 | frobinize_with | +| gen_trait.rs:4:20:8:1 | AssocItemList | 2 | gen_trait.rs:7:3:7:72 | fn frobinize_with | diff --git a/rust/ql/test/extractor-tests/generated/Trait/Trait.expected b/rust/ql/test/extractor-tests/generated/Trait/Trait.expected index ba06219a2d4..451422d330a 100644 --- a/rust/ql/test/extractor-tests/generated/Trait/Trait.expected +++ b/rust/ql/test/extractor-tests/generated/Trait/Trait.expected @@ -1,2 +1,2 @@ -| gen_trait.rs:3:1:8:1 | Trait | hasExtendedCanonicalPath: | yes | hasCrateOrigin: | yes | hasAssocItemList: | yes | getNumberOfAttrs: | 0 | hasGenericParamList: | no | isAuto: | no | isUnsafe: | no | hasName: | yes | hasTypeBoundList: | no | hasVisibility: | no | hasWhereClause: | no | -| gen_trait.rs:10:1:10:57 | Trait | hasExtendedCanonicalPath: | yes | hasCrateOrigin: | yes | hasAssocItemList: | yes | getNumberOfAttrs: | 0 | hasGenericParamList: | yes | isAuto: | no | isUnsafe: | no | hasName: | yes | hasTypeBoundList: | no | hasVisibility: | yes | hasWhereClause: | yes | +| gen_trait.rs:3:1:8:1 | trait Frobinizable | hasExtendedCanonicalPath: | yes | hasCrateOrigin: | yes | hasAssocItemList: | yes | getNumberOfAttrs: | 0 | hasGenericParamList: | no | isAuto: | no | isUnsafe: | no | hasName: | yes | hasTypeBoundList: | no | hasVisibility: | no | hasWhereClause: | no | +| gen_trait.rs:10:1:10:57 | trait Foo | hasExtendedCanonicalPath: | yes | hasCrateOrigin: | yes | hasAssocItemList: | yes | getNumberOfAttrs: | 0 | hasGenericParamList: | yes | isAuto: | no | isUnsafe: | no | hasName: | yes | hasTypeBoundList: | no | hasVisibility: | yes | hasWhereClause: | yes | diff --git a/rust/ql/test/extractor-tests/generated/Trait/Trait_getAssocItemList.expected b/rust/ql/test/extractor-tests/generated/Trait/Trait_getAssocItemList.expected index fc16a774800..b60c89c8d3f 100644 --- a/rust/ql/test/extractor-tests/generated/Trait/Trait_getAssocItemList.expected +++ b/rust/ql/test/extractor-tests/generated/Trait/Trait_getAssocItemList.expected @@ -1,2 +1,2 @@ -| gen_trait.rs:3:1:8:1 | Trait | gen_trait.rs:4:20:8:1 | AssocItemList | -| gen_trait.rs:10:1:10:57 | Trait | gen_trait.rs:10:56:10:57 | AssocItemList | +| gen_trait.rs:3:1:8:1 | trait Frobinizable | gen_trait.rs:4:20:8:1 | AssocItemList | +| gen_trait.rs:10:1:10:57 | trait Foo | gen_trait.rs:10:56:10:57 | AssocItemList | diff --git a/rust/ql/test/extractor-tests/generated/Trait/Trait_getCrateOrigin.expected b/rust/ql/test/extractor-tests/generated/Trait/Trait_getCrateOrigin.expected index 36106a58ae0..1e42bb43731 100644 --- a/rust/ql/test/extractor-tests/generated/Trait/Trait_getCrateOrigin.expected +++ b/rust/ql/test/extractor-tests/generated/Trait/Trait_getCrateOrigin.expected @@ -1,2 +1,2 @@ -| gen_trait.rs:3:1:8:1 | Trait | repo::test | -| gen_trait.rs:10:1:10:57 | Trait | repo::test | +| gen_trait.rs:3:1:8:1 | trait Frobinizable | repo::test | +| gen_trait.rs:10:1:10:57 | trait Foo | repo::test | diff --git a/rust/ql/test/extractor-tests/generated/Trait/Trait_getExtendedCanonicalPath.expected b/rust/ql/test/extractor-tests/generated/Trait/Trait_getExtendedCanonicalPath.expected index d89c9f23757..6a5e8203673 100644 --- a/rust/ql/test/extractor-tests/generated/Trait/Trait_getExtendedCanonicalPath.expected +++ b/rust/ql/test/extractor-tests/generated/Trait/Trait_getExtendedCanonicalPath.expected @@ -1,2 +1,2 @@ -| gen_trait.rs:3:1:8:1 | Trait | crate::gen_trait::Frobinizable | -| gen_trait.rs:10:1:10:57 | Trait | crate::gen_trait::Foo | +| gen_trait.rs:3:1:8:1 | trait Frobinizable | crate::gen_trait::Frobinizable | +| gen_trait.rs:10:1:10:57 | trait Foo | crate::gen_trait::Foo | diff --git a/rust/ql/test/extractor-tests/generated/Trait/Trait_getGenericParamList.expected b/rust/ql/test/extractor-tests/generated/Trait/Trait_getGenericParamList.expected index 85a848355f1..1ea7592a597 100644 --- a/rust/ql/test/extractor-tests/generated/Trait/Trait_getGenericParamList.expected +++ b/rust/ql/test/extractor-tests/generated/Trait/Trait_getGenericParamList.expected @@ -1 +1 @@ -| gen_trait.rs:10:1:10:57 | Trait | gen_trait.rs:10:14:10:30 | GenericParamList | +| gen_trait.rs:10:1:10:57 | trait Foo | gen_trait.rs:10:14:10:30 | GenericParamList | diff --git a/rust/ql/test/extractor-tests/generated/Trait/Trait_getName.expected b/rust/ql/test/extractor-tests/generated/Trait/Trait_getName.expected index cc60a2ab938..1c087cdea89 100644 --- a/rust/ql/test/extractor-tests/generated/Trait/Trait_getName.expected +++ b/rust/ql/test/extractor-tests/generated/Trait/Trait_getName.expected @@ -1,2 +1,2 @@ -| gen_trait.rs:3:1:8:1 | Trait | gen_trait.rs:4:7:4:18 | Frobinizable | -| gen_trait.rs:10:1:10:57 | Trait | gen_trait.rs:10:11:10:13 | Foo | +| gen_trait.rs:3:1:8:1 | trait Frobinizable | gen_trait.rs:4:7:4:18 | Frobinizable | +| gen_trait.rs:10:1:10:57 | trait Foo | gen_trait.rs:10:11:10:13 | Foo | diff --git a/rust/ql/test/extractor-tests/generated/Trait/Trait_getVisibility.expected b/rust/ql/test/extractor-tests/generated/Trait/Trait_getVisibility.expected index 67d505acda7..56576624e47 100644 --- a/rust/ql/test/extractor-tests/generated/Trait/Trait_getVisibility.expected +++ b/rust/ql/test/extractor-tests/generated/Trait/Trait_getVisibility.expected @@ -1 +1 @@ -| gen_trait.rs:10:1:10:57 | Trait | gen_trait.rs:10:1:10:3 | Visibility | +| gen_trait.rs:10:1:10:57 | trait Foo | gen_trait.rs:10:1:10:3 | Visibility | diff --git a/rust/ql/test/extractor-tests/generated/Trait/Trait_getWhereClause.expected b/rust/ql/test/extractor-tests/generated/Trait/Trait_getWhereClause.expected index a1ae3161e79..d46ac2d04cd 100644 --- a/rust/ql/test/extractor-tests/generated/Trait/Trait_getWhereClause.expected +++ b/rust/ql/test/extractor-tests/generated/Trait/Trait_getWhereClause.expected @@ -1 +1 @@ -| gen_trait.rs:10:1:10:57 | Trait | gen_trait.rs:10:32:10:54 | WhereClause | +| gen_trait.rs:10:1:10:57 | trait Foo | gen_trait.rs:10:32:10:54 | WhereClause | diff --git a/rust/ql/test/extractor-tests/generated/TuplePat/TuplePat_getField.expected b/rust/ql/test/extractor-tests/generated/TuplePat/TuplePat_getField.expected index 59d028b43ca..78e00f39c92 100644 --- a/rust/ql/test/extractor-tests/generated/TuplePat/TuplePat_getField.expected +++ b/rust/ql/test/extractor-tests/generated/TuplePat/TuplePat_getField.expected @@ -2,5 +2,5 @@ | gen_tuple_pat.rs:5:9:5:14 | TuplePat | 1 | gen_tuple_pat.rs:5:13:5:13 | y | | gen_tuple_pat.rs:6:9:6:22 | TuplePat | 0 | gen_tuple_pat.rs:6:10:6:10 | a | | gen_tuple_pat.rs:6:9:6:22 | TuplePat | 1 | gen_tuple_pat.rs:6:13:6:13 | b | -| gen_tuple_pat.rs:6:9:6:22 | TuplePat | 2 | gen_tuple_pat.rs:6:16:6:17 | RestPat | +| gen_tuple_pat.rs:6:9:6:22 | TuplePat | 2 | gen_tuple_pat.rs:6:16:6:17 | .. | | gen_tuple_pat.rs:6:9:6:22 | TuplePat | 3 | gen_tuple_pat.rs:6:21:6:21 | z | diff --git a/rust/ql/test/extractor-tests/generated/TupleStructPat/TupleStructPat_getField.expected b/rust/ql/test/extractor-tests/generated/TupleStructPat/TupleStructPat_getField.expected index 7a009a0818b..5885cbcea3e 100644 --- a/rust/ql/test/extractor-tests/generated/TupleStructPat/TupleStructPat_getField.expected +++ b/rust/ql/test/extractor-tests/generated/TupleStructPat/TupleStructPat_getField.expected @@ -1,7 +1,7 @@ -| gen_tuple_struct_pat.rs:6:9:6:27 | TupleStructPat | 0 | gen_tuple_struct_pat.rs:6:15:6:17 | LiteralPat | -| gen_tuple_struct_pat.rs:6:9:6:27 | TupleStructPat | 1 | gen_tuple_struct_pat.rs:6:20:6:20 | LiteralPat | -| gen_tuple_struct_pat.rs:6:9:6:27 | TupleStructPat | 2 | gen_tuple_struct_pat.rs:6:23:6:23 | LiteralPat | -| gen_tuple_struct_pat.rs:6:9:6:27 | TupleStructPat | 3 | gen_tuple_struct_pat.rs:6:26:6:26 | LiteralPat | -| gen_tuple_struct_pat.rs:7:9:7:20 | TupleStructPat | 0 | gen_tuple_struct_pat.rs:7:15:7:16 | RestPat | -| gen_tuple_struct_pat.rs:7:9:7:20 | TupleStructPat | 1 | gen_tuple_struct_pat.rs:7:19:7:19 | LiteralPat | -| gen_tuple_struct_pat.rs:8:9:8:17 | TupleStructPat | 0 | gen_tuple_struct_pat.rs:8:15:8:16 | RestPat | +| gen_tuple_struct_pat.rs:6:9:6:27 | TupleStructPat | 0 | gen_tuple_struct_pat.rs:6:15:6:17 | "a" | +| gen_tuple_struct_pat.rs:6:9:6:27 | TupleStructPat | 1 | gen_tuple_struct_pat.rs:6:20:6:20 | 1 | +| gen_tuple_struct_pat.rs:6:9:6:27 | TupleStructPat | 2 | gen_tuple_struct_pat.rs:6:23:6:23 | 2 | +| gen_tuple_struct_pat.rs:6:9:6:27 | TupleStructPat | 3 | gen_tuple_struct_pat.rs:6:26:6:26 | 3 | +| gen_tuple_struct_pat.rs:7:9:7:20 | TupleStructPat | 0 | gen_tuple_struct_pat.rs:7:15:7:16 | .. | +| gen_tuple_struct_pat.rs:7:9:7:20 | TupleStructPat | 1 | gen_tuple_struct_pat.rs:7:19:7:19 | 3 | +| gen_tuple_struct_pat.rs:8:9:8:17 | TupleStructPat | 0 | gen_tuple_struct_pat.rs:8:15:8:16 | .. | diff --git a/rust/ql/test/extractor-tests/generated/UnderscoreExpr/UnderscoreExpr.expected b/rust/ql/test/extractor-tests/generated/UnderscoreExpr/UnderscoreExpr.expected index 3b2effb788e..ea89e8b29b4 100644 --- a/rust/ql/test/extractor-tests/generated/UnderscoreExpr/UnderscoreExpr.expected +++ b/rust/ql/test/extractor-tests/generated/UnderscoreExpr/UnderscoreExpr.expected @@ -1 +1 @@ -| gen_underscore_expr.rs:5:5:5:5 | UnderscoreExpr | getNumberOfAttrs: | 0 | +| gen_underscore_expr.rs:5:5:5:5 | _ | getNumberOfAttrs: | 0 | diff --git a/rust/ql/test/extractor-tests/generated/WildcardPat/WildcardPat.expected b/rust/ql/test/extractor-tests/generated/WildcardPat/WildcardPat.expected index ceb155671b7..b8ac989ee1c 100644 --- a/rust/ql/test/extractor-tests/generated/WildcardPat/WildcardPat.expected +++ b/rust/ql/test/extractor-tests/generated/WildcardPat/WildcardPat.expected @@ -1 +1 @@ -| gen_wildcard_pat.rs:5:9:5:9 | WildcardPat | +| gen_wildcard_pat.rs:5:9:5:9 | _ | diff --git a/rust/ql/test/extractor-tests/utf8/ast.expected b/rust/ql/test/extractor-tests/utf8/ast.expected index dfc20f5ab58..17457550f79 100644 --- a/rust/ql/test/extractor-tests/utf8/ast.expected +++ b/rust/ql/test/extractor-tests/utf8/ast.expected @@ -1,33 +1,33 @@ -| lib.rs:1:1:1:21 | Module | | lib.rs:1:1:1:21 | SourceFile | +| lib.rs:1:1:1:21 | mod utf8_identifiers | | lib.rs:1:5:1:20 | utf8_identifiers | -| utf8_identifiers.rs:1:1:4:6 | foo | +| utf8_identifiers.rs:1:1:4:6 | fn foo | | utf8_identifiers.rs:1:1:12:2 | SourceFile | | utf8_identifiers.rs:1:4:1:6 | foo | | utf8_identifiers.rs:1:7:4:1 | GenericParamList | -| utf8_identifiers.rs:2:5:2:6 | Lifetime | +| utf8_identifiers.rs:2:5:2:6 | ''\u03b2 | | utf8_identifiers.rs:2:5:2:6 | LifetimeParam | | utf8_identifiers.rs:3:5:3:5 | TypeParam | | utf8_identifiers.rs:3:5:3:5 | \u03b3 | | utf8_identifiers.rs:4:2:4:3 | ParamList | -| utf8_identifiers.rs:4:5:4:6 | BlockExpr | | utf8_identifiers.rs:4:5:4:6 | StmtList | +| utf8_identifiers.rs:4:5:4:6 | { ... } | | utf8_identifiers.rs:6:1:8:1 | Struct | | utf8_identifiers.rs:6:8:6:8 | X | | utf8_identifiers.rs:6:10:8:1 | RecordFieldList | | utf8_identifiers.rs:7:5:7:5 | \u03b4 | | utf8_identifiers.rs:7:5:7:13 | RecordField | -| utf8_identifiers.rs:7:9:7:13 | PathType | +| utf8_identifiers.rs:7:9:7:13 | usize | | utf8_identifiers.rs:7:9:7:13 | usize | | utf8_identifiers.rs:7:9:7:13 | usize | | utf8_identifiers.rs:7:9:7:13 | usize | | utf8_identifiers.rs:10:1:10:3 | Visibility | -| utf8_identifiers.rs:10:1:12:1 | main | +| utf8_identifiers.rs:10:1:12:1 | fn main | | utf8_identifiers.rs:10:8:10:11 | main | | utf8_identifiers.rs:10:12:10:13 | ParamList | -| utf8_identifiers.rs:10:15:12:1 | BlockExpr | | utf8_identifiers.rs:10:15:12:1 | StmtList | -| utf8_identifiers.rs:11:5:11:24 | LetStmt | +| utf8_identifiers.rs:10:15:12:1 | { ... } | +| utf8_identifiers.rs:11:5:11:24 | let \u03b1 = ... | | utf8_identifiers.rs:11:9:11:9 | \u03b1 | | utf8_identifiers.rs:11:9:11:9 | \u03b1 | | utf8_identifiers.rs:11:14:11:23 | 0.00001f64 | diff --git a/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected b/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected index 05851289a35..28a436b1cce 100644 --- a/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected @@ -1,53 +1,53 @@ edges -| test.rs:5:5:11:5 | enter test_and_if_let | test.rs:5:24:5:24 | a | | -| test.rs:5:5:11:5 | exit test_and_if_let (normal) | test.rs:5:5:11:5 | exit test_and_if_let | | -| test.rs:5:24:5:24 | a | test.rs:5:24:5:30 | Param | match | -| test.rs:5:24:5:30 | Param | test.rs:5:33:5:33 | b | | -| test.rs:5:33:5:33 | b | test.rs:5:33:5:47 | Param | match | -| test.rs:5:33:5:47 | Param | test.rs:5:50:5:50 | c | | -| test.rs:5:50:5:50 | c | test.rs:5:50:5:56 | Param | match | -| test.rs:5:50:5:56 | Param | test.rs:6:12:6:12 | a | | -| test.rs:5:67:11:5 | BlockExpr | test.rs:5:5:11:5 | exit test_and_if_let (normal) | | -| test.rs:6:9:10:9 | IfExpr | test.rs:5:67:11:5 | BlockExpr | | +| test.rs:5:5:11:5 | enter fn test_and_if_let | test.rs:5:24:5:24 | a | | +| test.rs:5:5:11:5 | exit fn test_and_if_let (normal) | test.rs:5:5:11:5 | exit fn test_and_if_let | | +| test.rs:5:24:5:24 | a | test.rs:5:24:5:30 | a: bool | match | +| test.rs:5:24:5:30 | a: bool | test.rs:5:33:5:33 | b | | +| test.rs:5:33:5:33 | b | test.rs:5:33:5:47 | b: Option::<...> | match | +| test.rs:5:33:5:47 | b: Option::<...> | test.rs:5:50:5:50 | c | | +| test.rs:5:50:5:50 | c | test.rs:5:50:5:56 | c: bool | match | +| test.rs:5:50:5:56 | c: bool | test.rs:6:12:6:12 | a | | +| test.rs:5:67:11:5 | { ... } | test.rs:5:5:11:5 | exit fn test_and_if_let (normal) | | +| test.rs:6:9:10:9 | if ... { ... } else { ... } | test.rs:5:67:11:5 | { ... } | | | test.rs:6:12:6:12 | a | test.rs:6:12:6:31 | [boolean(false)] ... && ... | false | -| test.rs:6:12:6:12 | a | test.rs:6:17:6:31 | LetExpr | true | +| test.rs:6:12:6:12 | a | test.rs:6:17:6:31 | let TupleStructPat = ... | true | | test.rs:6:12:6:31 | [boolean(false)] ... && ... | test.rs:9:13:9:17 | false | false | | test.rs:6:12:6:31 | [boolean(true)] ... && ... | test.rs:7:13:7:13 | d | true | -| test.rs:6:17:6:31 | LetExpr | test.rs:6:31:6:31 | b | | +| test.rs:6:17:6:31 | let TupleStructPat = ... | test.rs:6:31:6:31 | b | | | test.rs:6:21:6:27 | TupleStructPat | test.rs:6:12:6:31 | [boolean(false)] ... && ... | no-match | | test.rs:6:21:6:27 | TupleStructPat | test.rs:6:26:6:26 | d | match | | test.rs:6:26:6:26 | d | test.rs:6:12:6:31 | [boolean(true)] ... && ... | match | | test.rs:6:31:6:31 | b | test.rs:6:21:6:27 | TupleStructPat | | -| test.rs:6:33:8:9 | BlockExpr | test.rs:6:9:10:9 | IfExpr | | -| test.rs:7:13:7:13 | d | test.rs:6:33:8:9 | BlockExpr | | -| test.rs:8:16:10:9 | BlockExpr | test.rs:6:9:10:9 | IfExpr | | -| test.rs:9:13:9:17 | false | test.rs:8:16:10:9 | BlockExpr | | -| test.rs:13:5:21:5 | enter test_and_if_let2 | test.rs:13:25:13:25 | a | | -| test.rs:13:5:21:5 | exit test_and_if_let2 (normal) | test.rs:13:5:21:5 | exit test_and_if_let2 | | -| test.rs:13:25:13:25 | a | test.rs:13:25:13:31 | Param | match | -| test.rs:13:25:13:31 | Param | test.rs:13:34:13:34 | b | | -| test.rs:13:34:13:34 | b | test.rs:13:34:13:39 | Param | match | -| test.rs:13:34:13:39 | Param | test.rs:13:42:13:42 | c | | -| test.rs:13:42:13:42 | c | test.rs:13:42:13:48 | Param | match | -| test.rs:13:42:13:48 | Param | test.rs:14:12:14:12 | a | | -| test.rs:13:59:21:5 | BlockExpr | test.rs:13:5:21:5 | exit test_and_if_let2 (normal) | | -| test.rs:14:9:20:9 | IfExpr | test.rs:13:59:21:5 | BlockExpr | | +| test.rs:6:33:8:9 | { ... } | test.rs:6:9:10:9 | if ... { ... } else { ... } | | +| test.rs:7:13:7:13 | d | test.rs:6:33:8:9 | { ... } | | +| test.rs:8:16:10:9 | { ... } | test.rs:6:9:10:9 | if ... { ... } else { ... } | | +| test.rs:9:13:9:17 | false | test.rs:8:16:10:9 | { ... } | | +| test.rs:13:5:21:5 | enter fn test_and_if_let2 | test.rs:13:25:13:25 | a | | +| test.rs:13:5:21:5 | exit fn test_and_if_let2 (normal) | test.rs:13:5:21:5 | exit fn test_and_if_let2 | | +| test.rs:13:25:13:25 | a | test.rs:13:25:13:31 | a: bool | match | +| test.rs:13:25:13:31 | a: bool | test.rs:13:34:13:34 | b | | +| test.rs:13:34:13:34 | b | test.rs:13:34:13:39 | b: i64 | match | +| test.rs:13:34:13:39 | b: i64 | test.rs:13:42:13:42 | c | | +| test.rs:13:42:13:42 | c | test.rs:13:42:13:48 | c: bool | match | +| test.rs:13:42:13:48 | c: bool | test.rs:14:12:14:12 | a | | +| test.rs:13:59:21:5 | { ... } | test.rs:13:5:21:5 | exit fn test_and_if_let2 (normal) | | +| test.rs:14:9:20:9 | if ... { ... } else { ... } | test.rs:13:59:21:5 | { ... } | | | test.rs:14:12:14:12 | a | test.rs:14:12:14:25 | [boolean(false)] ... && ... | false | -| test.rs:14:12:14:12 | a | test.rs:14:17:14:25 | LetExpr | true | +| test.rs:14:12:14:12 | a | test.rs:14:17:14:25 | let d = ... | true | | test.rs:14:12:14:25 | [boolean(false)] ... && ... | test.rs:14:12:15:16 | [boolean(false)] ... && ... | false | | test.rs:14:12:14:25 | [boolean(true)] ... && ... | test.rs:15:16:15:16 | c | true | | test.rs:14:12:15:16 | [boolean(false)] ... && ... | test.rs:19:13:19:17 | false | false | | test.rs:14:12:15:16 | [boolean(true)] ... && ... | test.rs:17:13:17:13 | d | true | -| test.rs:14:17:14:25 | LetExpr | test.rs:14:25:14:25 | b | | +| test.rs:14:17:14:25 | let d = ... | test.rs:14:25:14:25 | b | | | test.rs:14:21:14:21 | d | test.rs:14:12:14:25 | [boolean(true)] ... && ... | match | | test.rs:14:25:14:25 | b | test.rs:14:21:14:21 | d | | | test.rs:15:16:15:16 | c | test.rs:14:12:15:16 | [boolean(false)] ... && ... | false | | test.rs:15:16:15:16 | c | test.rs:14:12:15:16 | [boolean(true)] ... && ... | true | -| test.rs:16:9:18:9 | BlockExpr | test.rs:14:9:20:9 | IfExpr | | +| test.rs:16:9:18:9 | { ... } | test.rs:14:9:20:9 | if ... { ... } else { ... } | | | test.rs:17:13:17:13 | d | test.rs:17:17:17:17 | 0 | | -| test.rs:17:13:17:17 | ... > ... | test.rs:16:9:18:9 | BlockExpr | | +| test.rs:17:13:17:17 | ... > ... | test.rs:16:9:18:9 | { ... } | | | test.rs:17:17:17:17 | 0 | test.rs:17:13:17:17 | ... > ... | | -| test.rs:18:16:20:9 | BlockExpr | test.rs:14:9:20:9 | IfExpr | | -| test.rs:19:13:19:17 | false | test.rs:18:16:20:9 | BlockExpr | | +| test.rs:18:16:20:9 | { ... } | test.rs:14:9:20:9 | if ... { ... } else { ... } | | +| test.rs:19:13:19:17 | false | test.rs:18:16:20:9 | { ... } | | breakTarget continueTarget diff --git a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected index 6a15bb25249..0739d922d8d 100644 --- a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected +++ b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected @@ -1,24 +1,24 @@ -| main.rs:13:5:13:13 | CallExpr | main.rs:1:1:3:1 | source | -| main.rs:17:13:17:23 | CallExpr | main.rs:12:1:14:1 | get_data | -| main.rs:18:5:18:11 | CallExpr | main.rs:5:1:7:1 | sink | -| main.rs:22:5:22:15 | CallExpr | main.rs:5:1:7:1 | sink | -| main.rs:26:13:26:21 | CallExpr | main.rs:1:1:3:1 | source | -| main.rs:27:5:27:14 | CallExpr | main.rs:21:1:23:1 | data_in | -| main.rs:35:13:35:21 | CallExpr | main.rs:1:1:3:1 | source | -| main.rs:36:13:36:27 | CallExpr | main.rs:30:1:32:1 | pass_through | -| main.rs:37:5:37:11 | CallExpr | main.rs:5:1:7:1 | sink | -| main.rs:49:9:49:15 | CallExpr | main.rs:5:1:7:1 | sink | -| main.rs:55:13:55:21 | CallExpr | main.rs:1:1:3:1 | source | -| main.rs:69:13:69:25 | ... .get_data(...) | main.rs:51:5:57:5 | get_data | -| main.rs:70:5:70:11 | CallExpr | main.rs:5:1:7:1 | sink | -| main.rs:75:13:75:21 | CallExpr | main.rs:1:1:3:1 | source | -| main.rs:76:5:76:17 | ... .data_in(...) | main.rs:48:5:50:5 | data_in | -| main.rs:81:13:81:21 | CallExpr | main.rs:1:1:3:1 | source | -| main.rs:82:5:82:22 | ... .data_through(...) | main.rs:58:5:64:5 | data_through | -| main.rs:83:5:83:11 | CallExpr | main.rs:5:1:7:1 | sink | -| main.rs:87:5:87:22 | CallExpr | main.rs:16:1:19:1 | data_out_of_call | -| main.rs:88:5:88:21 | CallExpr | main.rs:25:1:28:1 | data_in_to_call | -| main.rs:89:5:89:23 | CallExpr | main.rs:34:1:38:1 | data_through_call | -| main.rs:91:5:91:24 | CallExpr | main.rs:67:1:71:1 | data_out_of_method | -| main.rs:92:5:92:28 | CallExpr | main.rs:73:1:77:1 | data_in_to_method_call | -| main.rs:93:5:93:25 | CallExpr | main.rs:79:1:84:1 | data_through_method | +| main.rs:13:5:13:13 | ... (...) | main.rs:1:1:3:1 | fn source | +| main.rs:17:13:17:23 | ... (...) | main.rs:12:1:14:1 | fn get_data | +| main.rs:18:5:18:11 | ... (...) | main.rs:5:1:7:1 | fn sink | +| main.rs:22:5:22:15 | ... (...) | main.rs:5:1:7:1 | fn sink | +| main.rs:26:13:26:21 | ... (...) | main.rs:1:1:3:1 | fn source | +| main.rs:27:5:27:14 | ... (...) | main.rs:21:1:23:1 | fn data_in | +| main.rs:35:13:35:21 | ... (...) | main.rs:1:1:3:1 | fn source | +| main.rs:36:13:36:27 | ... (...) | main.rs:30:1:32:1 | fn pass_through | +| main.rs:37:5:37:11 | ... (...) | main.rs:5:1:7:1 | fn sink | +| main.rs:49:9:49:15 | ... (...) | main.rs:5:1:7:1 | fn sink | +| main.rs:55:13:55:21 | ... (...) | main.rs:1:1:3:1 | fn source | +| main.rs:69:13:69:25 | ... .get_data(...) | main.rs:51:5:57:5 | fn get_data | +| main.rs:70:5:70:11 | ... (...) | main.rs:5:1:7:1 | fn sink | +| main.rs:75:13:75:21 | ... (...) | main.rs:1:1:3:1 | fn source | +| main.rs:76:5:76:17 | ... .data_in(...) | main.rs:48:5:50:5 | fn data_in | +| main.rs:81:13:81:21 | ... (...) | main.rs:1:1:3:1 | fn source | +| main.rs:82:5:82:22 | ... .data_through(...) | main.rs:58:5:64:5 | fn data_through | +| main.rs:83:5:83:11 | ... (...) | main.rs:5:1:7:1 | fn sink | +| main.rs:87:5:87:22 | ... (...) | main.rs:16:1:19:1 | fn data_out_of_call | +| main.rs:88:5:88:21 | ... (...) | main.rs:25:1:28:1 | fn data_in_to_call | +| main.rs:89:5:89:23 | ... (...) | main.rs:34:1:38:1 | fn data_through_call | +| main.rs:91:5:91:24 | ... (...) | main.rs:67:1:71:1 | fn data_out_of_method | +| main.rs:92:5:92:28 | ... (...) | main.rs:73:1:77:1 | fn data_in_to_method_call | +| main.rs:93:5:93:25 | ... (...) | main.rs:79:1:84:1 | fn data_through_method | diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 8cc12598f62..ecce48be804 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -1,46 +1,46 @@ | main.rs:3:11:3:11 | [SSA] i | main.rs:4:12:4:12 | i | | main.rs:3:11:3:11 | i | main.rs:3:11:3:11 | [SSA] i | -| main.rs:4:5:4:12 | ... + ... | main.rs:3:26:5:1 | BlockExpr | +| main.rs:4:5:4:12 | ... + ... | main.rs:3:26:5:1 | { ... } | | main.rs:7:9:7:9 | [SSA] s | main.rs:8:20:8:20 | s | | main.rs:7:9:7:9 | s | main.rs:7:9:7:9 | [SSA] s | | main.rs:19:9:19:9 | [SSA] s | main.rs:20:10:20:10 | s | | main.rs:19:9:19:9 | s | main.rs:19:9:19:9 | [SSA] s | -| main.rs:19:13:19:21 | CallExpr | main.rs:19:9:19:9 | s | +| main.rs:19:13:19:21 | ... (...) | main.rs:19:9:19:9 | s | | main.rs:23:18:23:21 | [SSA] cond | main.rs:26:16:26:19 | cond | | main.rs:23:18:23:21 | cond | main.rs:23:18:23:21 | [SSA] cond | | main.rs:24:9:24:9 | [SSA] a | main.rs:26:23:26:23 | a | | main.rs:24:9:24:9 | a | main.rs:24:9:24:9 | [SSA] a | -| main.rs:24:13:24:21 | CallExpr | main.rs:24:9:24:9 | a | +| main.rs:24:13:24:21 | ... (...) | main.rs:24:9:24:9 | a | | main.rs:25:9:25:9 | [SSA] b | main.rs:26:34:26:34 | b | | main.rs:25:9:25:9 | b | main.rs:25:9:25:9 | [SSA] b | | main.rs:25:13:25:13 | 2 | main.rs:25:9:25:9 | b | | main.rs:26:9:26:9 | [SSA] c | main.rs:27:10:27:10 | c | | main.rs:26:9:26:9 | c | main.rs:26:9:26:9 | [SSA] c | -| main.rs:26:13:26:36 | IfExpr | main.rs:26:9:26:9 | c | -| main.rs:26:21:26:25 | BlockExpr | main.rs:26:13:26:36 | IfExpr | -| main.rs:26:23:26:23 | a | main.rs:26:21:26:25 | BlockExpr | -| main.rs:26:32:26:36 | BlockExpr | main.rs:26:13:26:36 | IfExpr | -| main.rs:26:34:26:34 | b | main.rs:26:32:26:36 | BlockExpr | +| main.rs:26:13:26:36 | if ... { ... } else { ... } | main.rs:26:9:26:9 | c | +| main.rs:26:21:26:25 | { ... } | main.rs:26:13:26:36 | if ... { ... } else { ... } | +| main.rs:26:23:26:23 | a | main.rs:26:21:26:25 | { ... } | +| main.rs:26:32:26:36 | { ... } | main.rs:26:13:26:36 | if ... { ... } else { ... } | +| main.rs:26:34:26:34 | b | main.rs:26:32:26:36 | { ... } | | main.rs:30:21:30:21 | [SSA] m | main.rs:32:19:32:19 | m | | main.rs:30:21:30:21 | m | main.rs:30:21:30:21 | [SSA] m | | main.rs:31:9:31:9 | [SSA] a | main.rs:33:20:33:20 | a | | main.rs:31:9:31:9 | a | main.rs:31:9:31:9 | [SSA] a | -| main.rs:31:13:31:21 | CallExpr | main.rs:31:9:31:9 | a | +| main.rs:31:13:31:21 | ... (...) | main.rs:31:9:31:9 | a | | main.rs:32:9:32:9 | [SSA] b | main.rs:36:10:36:10 | b | | main.rs:32:9:32:9 | b | main.rs:32:9:32:9 | [SSA] b | -| main.rs:32:13:35:5 | MatchExpr | main.rs:32:9:32:9 | b | -| main.rs:33:20:33:20 | a | main.rs:32:13:35:5 | MatchExpr | -| main.rs:34:17:34:17 | 0 | main.rs:32:13:35:5 | MatchExpr | +| main.rs:32:13:35:5 | match ... { ... } | main.rs:32:9:32:9 | b | +| main.rs:33:20:33:20 | a | main.rs:32:13:35:5 | match ... { ... } | +| main.rs:34:17:34:17 | 0 | main.rs:32:13:35:5 | match ... { ... } | | main.rs:40:9:40:9 | [SSA] a | main.rs:43:10:43:10 | a | | main.rs:40:9:40:9 | a | main.rs:40:9:40:9 | [SSA] a | -| main.rs:40:13:42:5 | LoopExpr | main.rs:40:9:40:9 | a | -| main.rs:41:9:41:15 | BreakExpr | main.rs:40:13:42:5 | LoopExpr | -| main.rs:41:15:41:15 | 1 | main.rs:41:9:41:15 | BreakExpr | +| main.rs:40:13:42:5 | loop {...} | main.rs:40:9:40:9 | a | +| main.rs:41:9:41:15 | (no string representation) | main.rs:40:13:42:5 | loop {...} | +| main.rs:41:15:41:15 | 1 | main.rs:41:9:41:15 | (no string representation) | | main.rs:44:9:44:9 | [SSA] b | main.rs:47:10:47:10 | b | | main.rs:44:9:44:9 | b | main.rs:44:9:44:9 | [SSA] b | -| main.rs:44:13:46:5 | LoopExpr | main.rs:44:9:44:9 | b | -| main.rs:45:9:45:23 | BreakExpr | main.rs:44:13:46:5 | LoopExpr | -| main.rs:45:15:45:23 | CallExpr | main.rs:45:9:45:23 | BreakExpr | +| main.rs:44:13:46:5 | loop {...} | main.rs:44:9:44:9 | b | +| main.rs:45:9:45:23 | (no string representation) | main.rs:44:13:46:5 | loop {...} | +| main.rs:45:15:45:23 | ... (...) | main.rs:45:9:45:23 | (no string representation) | | main.rs:51:9:51:13 | [SSA] i | main.rs:52:10:52:10 | i | | main.rs:51:9:51:13 | i | main.rs:51:9:51:13 | [SSA] i | | main.rs:51:17:51:17 | 1 | main.rs:51:9:51:13 | i | @@ -48,38 +48,38 @@ | main.rs:53:5:53:5 | i | main.rs:53:5:53:5 | [SSA] i | | main.rs:61:9:61:9 | [SSA] i | main.rs:62:11:62:11 | i | | main.rs:61:9:61:9 | i | main.rs:61:9:61:9 | [SSA] i | -| main.rs:61:13:61:31 | CallExpr | main.rs:61:9:61:9 | i | +| main.rs:61:13:61:31 | ... (...) | main.rs:61:9:61:9 | i | | main.rs:66:9:66:9 | [SSA] a | main.rs:67:10:67:10 | a | | main.rs:66:9:66:9 | a | main.rs:66:9:66:9 | [SSA] a | | main.rs:66:13:66:26 | TupleExpr | main.rs:66:9:66:9 | a | | main.rs:67:10:67:10 | a | main.rs:68:10:68:10 | a | | main.rs:78:9:78:9 | [SSA] p | main.rs:83:10:83:10 | p | | main.rs:78:9:78:9 | p | main.rs:78:9:78:9 | [SSA] p | -| main.rs:78:13:82:5 | RecordExpr | main.rs:78:9:78:9 | p | +| main.rs:78:13:82:5 | Point {...} | main.rs:78:9:78:9 | p | | main.rs:83:10:83:10 | p | main.rs:84:10:84:10 | p | | main.rs:84:10:84:10 | p | main.rs:85:10:85:10 | p | | main.rs:92:9:92:9 | [SSA] p | main.rs:97:38:97:38 | p | | main.rs:92:9:92:9 | p | main.rs:92:9:92:9 | [SSA] p | -| main.rs:92:13:96:5 | RecordExpr | main.rs:92:9:92:9 | p | +| main.rs:92:13:96:5 | Point {...} | main.rs:92:9:92:9 | p | | main.rs:97:20:97:20 | [SSA] a | main.rs:98:10:98:10 | a | | main.rs:97:20:97:20 | a | main.rs:97:20:97:20 | [SSA] a | | main.rs:97:26:97:26 | [SSA] b | main.rs:99:10:99:10 | b | | main.rs:97:26:97:26 | b | main.rs:97:26:97:26 | [SSA] b | | main.rs:97:32:97:32 | [SSA] c | main.rs:100:10:100:10 | c | | main.rs:97:32:97:32 | c | main.rs:97:32:97:32 | [SSA] c | -| main.rs:97:38:97:38 | p | main.rs:97:9:97:34 | RecordPat | +| main.rs:97:38:97:38 | p | main.rs:97:9:97:34 | Point {...} | | main.rs:104:9:104:10 | [SSA] s1 | main.rs:106:11:106:12 | s1 | | main.rs:104:9:104:10 | s1 | main.rs:104:9:104:10 | [SSA] s1 | -| main.rs:104:14:104:28 | CallExpr | main.rs:104:9:104:10 | s1 | +| main.rs:104:14:104:28 | ... (...) | main.rs:104:9:104:10 | s1 | | main.rs:105:9:105:10 | [SSA] s2 | main.rs:110:11:110:12 | s2 | | main.rs:105:9:105:10 | s2 | main.rs:105:9:105:10 | [SSA] s2 | -| main.rs:105:14:105:20 | CallExpr | main.rs:105:9:105:10 | s2 | +| main.rs:105:14:105:20 | ... (...) | main.rs:105:9:105:10 | s2 | | main.rs:107:14:107:14 | [SSA] n | main.rs:107:25:107:25 | n | | main.rs:107:14:107:14 | n | main.rs:107:14:107:14 | [SSA] n | -| main.rs:107:20:107:26 | CallExpr | main.rs:106:5:109:5 | MatchExpr | -| main.rs:108:17:108:23 | CallExpr | main.rs:106:5:109:5 | MatchExpr | -| main.rs:110:5:113:5 | MatchExpr | main.rs:103:27:114:1 | BlockExpr | +| main.rs:107:20:107:26 | ... (...) | main.rs:106:5:109:5 | match ... { ... } | +| main.rs:108:17:108:23 | ... (...) | main.rs:106:5:109:5 | match ... { ... } | +| main.rs:110:5:113:5 | match ... { ... } | main.rs:103:27:114:1 | { ... } | | main.rs:111:14:111:14 | [SSA] n | main.rs:111:25:111:25 | n | | main.rs:111:14:111:14 | n | main.rs:111:14:111:14 | [SSA] n | -| main.rs:111:20:111:26 | CallExpr | main.rs:110:5:113:5 | MatchExpr | -| main.rs:112:17:112:23 | CallExpr | main.rs:110:5:113:5 | MatchExpr | +| main.rs:111:20:111:26 | ... (...) | main.rs:110:5:113:5 | match ... { ... } | +| main.rs:112:17:112:23 | ... (...) | main.rs:110:5:113:5 | match ... { ... } | diff --git a/rust/ql/test/library-tests/variables/Ssa.expected b/rust/ql/test/library-tests/variables/Ssa.expected index f17152793a3..0ca5a421853 100644 --- a/rust/ql/test/library-tests/variables/Ssa.expected +++ b/rust/ql/test/library-tests/variables/Ssa.expected @@ -120,12 +120,12 @@ definition | variables.rs:418:9:418:13 | y | variables.rs:418:13:418:13 | y | | variables.rs:420:9:420:20 | closure2 | variables.rs:420:13:420:20 | closure2 | | variables.rs:421:9:421:9 | y | variables.rs:418:13:418:13 | y | -| variables.rs:423:5:423:14 | CallExpr | variables.rs:418:13:418:13 | y | +| variables.rs:423:5:423:14 | ... (...) | variables.rs:418:13:418:13 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | | variables.rs:436:9:436:13 | i | variables.rs:436:13:436:13 | i | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | | variables.rs:438:9:438:9 | i | variables.rs:436:13:436:13 | i | -| variables.rs:441:5:441:15 | AwaitExpr | variables.rs:436:13:436:13 | i | +| variables.rs:441:5:441:15 | await ... | variables.rs:436:13:436:13 | i | | variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | | variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | @@ -239,10 +239,10 @@ read | variables.rs:412:9:412:16 | closure1 | variables.rs:412:9:412:16 | closure1 | variables.rs:415:5:415:12 | closure1 | | variables.rs:412:20:414:5 | x | variables.rs:410:13:410:13 | x | variables.rs:413:19:413:19 | x | | variables.rs:420:9:420:20 | closure2 | variables.rs:420:13:420:20 | closure2 | variables.rs:423:5:423:12 | closure2 | -| variables.rs:423:5:423:14 | CallExpr | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | +| variables.rs:423:5:423:14 | ... (...) | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | -| variables.rs:441:5:441:15 | AwaitExpr | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | +| variables.rs:441:5:441:15 | await ... | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | | variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | variables.rs:449:8:449:8 | b | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:447:15:447:15 | x | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:448:15:448:15 | x | @@ -343,10 +343,10 @@ firstRead | variables.rs:412:9:412:16 | closure1 | variables.rs:412:9:412:16 | closure1 | variables.rs:415:5:415:12 | closure1 | | variables.rs:412:20:414:5 | x | variables.rs:410:13:410:13 | x | variables.rs:413:19:413:19 | x | | variables.rs:420:9:420:20 | closure2 | variables.rs:420:13:420:20 | closure2 | variables.rs:423:5:423:12 | closure2 | -| variables.rs:423:5:423:14 | CallExpr | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | +| variables.rs:423:5:423:14 | ... (...) | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | -| variables.rs:441:5:441:15 | AwaitExpr | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | +| variables.rs:441:5:441:15 | await ... | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | | variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | variables.rs:449:8:449:8 | b | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:447:15:447:15 | x | | variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | variables.rs:458:15:458:15 | x | @@ -443,10 +443,10 @@ lastRead | variables.rs:412:9:412:16 | closure1 | variables.rs:412:9:412:16 | closure1 | variables.rs:415:5:415:12 | closure1 | | variables.rs:412:20:414:5 | x | variables.rs:410:13:410:13 | x | variables.rs:413:19:413:19 | x | | variables.rs:420:9:420:20 | closure2 | variables.rs:420:13:420:20 | closure2 | variables.rs:423:5:423:12 | closure2 | -| variables.rs:423:5:423:14 | CallExpr | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | +| variables.rs:423:5:423:14 | ... (...) | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | -| variables.rs:441:5:441:15 | AwaitExpr | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | +| variables.rs:441:5:441:15 | await ... | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | | variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | variables.rs:449:8:449:8 | b | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:448:15:448:15 | x | | variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | variables.rs:458:15:458:15 | x | diff --git a/rust/ql/test/query-tests/diagnostics/DataFlowConsistencyCounts.expected b/rust/ql/test/query-tests/diagnostics/DataFlowConsistencyCounts.expected index 4d1cdfed89a..9c96e0fa334 100644 --- a/rust/ql/test/query-tests/diagnostics/DataFlowConsistencyCounts.expected +++ b/rust/ql/test/query-tests/diagnostics/DataFlowConsistencyCounts.expected @@ -11,7 +11,7 @@ | Node has multiple PostUpdateNodes | 0 | | Node should have one enclosing callable | 0 | | Node should have one location | 0 | -| Node should have one toString | 0 | +| Node should have one toString | 1 | | Node should have one type | 0 | | Node steps to itself | 0 | | Nodes without location | 0 | diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index aeba0ac1ee6..a3330d0eb1e 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -7,6 +7,6 @@ | Files extracted - without errors | 6 | | Inconsistencies - AST | 0 | | Inconsistencies - CFG | 0 | -| Inconsistencies - data flow | 0 | +| Inconsistencies - data flow | 1 | | Lines of code extracted | 59 | | Lines of user code extracted | 59 | diff --git a/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected index 0a61a151c20..f4a07cc45c2 100644 --- a/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected +++ b/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected @@ -3,3 +3,17 @@ uniqueEnclosingCallable | main.rs:198:28:198:28 | x | Node should have one enclosing callable but has 0. | | main.rs:202:28:202:28 | x | Node should have one enclosing callable but has 0. | | main.rs:206:28:206:28 | x | Node should have one enclosing callable but has 0. | +uniqueNodeToString +| main.rs:205:32:205:32 | (no string representation) | Node should have one toString but has 0. | +| main.rs:219:9:219:13 | (no string representation) | Node should have one toString but has 0. | +| main.rs:224:9:224:13 | (no string representation) | Node should have one toString but has 0. | +| main.rs:424:21:424:23 | (no string representation) | Node should have one toString but has 0. | +| main.rs:424:26:424:28 | (no string representation) | Node should have one toString but has 0. | +| main.rs:427:21:427:23 | (no string representation) | Node should have one toString but has 0. | +| main.rs:427:26:427:28 | (no string representation) | Node should have one toString but has 0. | +| main.rs:430:21:430:23 | (no string representation) | Node should have one toString but has 0. | +| main.rs:430:26:430:28 | (no string representation) | Node should have one toString but has 0. | +| main.rs:434:21:434:23 | (no string representation) | Node should have one toString but has 0. | +| main.rs:434:26:434:28 | (no string representation) | Node should have one toString but has 0. | +| unreachable.rs:10:34:10:34 | (no string representation) | Node should have one toString but has 0. | +| unreachable.rs:230:13:230:17 | (no string representation) | Node should have one toString but has 0. | From e4f982c12ce69cfe4b5cda5480646011e019cfa0 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 19 Nov 2024 17:34:18 +0100 Subject: [PATCH 100/470] Rust: accept integration test changes --- .../ql/integration-tests/hello-project/functions.expected | 2 +- .../integration-tests/hello-workspace/functions.expected | 4 ++-- rust/ql/integration-tests/options/cfg/functions.expected | 6 +++--- .../options/cfg/functions.override.expected | 8 ++++---- .../options/features/functions.all.expected | 6 +++--- .../options/features/functions.bar.expected | 4 ++-- .../integration-tests/options/features/functions.expected | 2 +- .../options/features/functions.foo.expected | 4 ++-- .../options/target/functions.Darwin.expected | 2 +- .../options/target/functions.Linux.expected | 2 +- .../options/target/functions.Windows.expected | 2 +- rust/ql/integration-tests/qltest/test.py | 3 ++- 12 files changed, 23 insertions(+), 22 deletions(-) diff --git a/rust/ql/integration-tests/hello-project/functions.expected b/rust/ql/integration-tests/hello-project/functions.expected index fc49564084e..2665ea7df76 100644 --- a/rust/ql/integration-tests/hello-project/functions.expected +++ b/rust/ql/integration-tests/hello-project/functions.expected @@ -1 +1 @@ -| src/main.rs:4:1:6:1 | main | +| src/main.rs:4:1:6:1 | fn main | diff --git a/rust/ql/integration-tests/hello-workspace/functions.expected b/rust/ql/integration-tests/hello-workspace/functions.expected index 0ec9937972e..0633774edf7 100644 --- a/rust/ql/integration-tests/hello-workspace/functions.expected +++ b/rust/ql/integration-tests/hello-workspace/functions.expected @@ -1,2 +1,2 @@ -| exe/src/main.rs:5:1:7:1 | main | -| lib/src/a_module/mod.rs:1:1:3:1 | hello | +| exe/src/main.rs:5:1:7:1 | fn main | +| lib/src/a_module/mod.rs:1:1:3:1 | fn hello | diff --git a/rust/ql/integration-tests/options/cfg/functions.expected b/rust/ql/integration-tests/options/cfg/functions.expected index a2042c5e4c4..cd022ca510e 100644 --- a/rust/ql/integration-tests/options/cfg/functions.expected +++ b/rust/ql/integration-tests/options/cfg/functions.expected @@ -1,3 +1,3 @@ -| src/lib.rs:7:1:8:19 | cfg_no_flag | -| src/lib.rs:10:1:11:18 | cfg_no_key | -| src/lib.rs:16:1:17:24 | pointer_width_64 | +| src/lib.rs:7:1:8:19 | fn cfg_no_flag | +| src/lib.rs:10:1:11:18 | fn cfg_no_key | +| src/lib.rs:16:1:17:24 | fn pointer_width_64 | diff --git a/rust/ql/integration-tests/options/cfg/functions.override.expected b/rust/ql/integration-tests/options/cfg/functions.override.expected index 4a19db56a74..34feddaf149 100644 --- a/rust/ql/integration-tests/options/cfg/functions.override.expected +++ b/rust/ql/integration-tests/options/cfg/functions.override.expected @@ -1,4 +1,4 @@ -| src/lib.rs:1:1:2:16 | cfg_flag | -| src/lib.rs:4:1:5:15 | cfg_key | -| src/lib.rs:13:1:14:12 | test | -| src/lib.rs:19:1:20:24 | pointer_width_32 | +| src/lib.rs:1:1:2:16 | fn cfg_flag | +| src/lib.rs:4:1:5:15 | fn cfg_key | +| src/lib.rs:13:1:14:12 | fn test | +| src/lib.rs:19:1:20:24 | fn pointer_width_32 | diff --git a/rust/ql/integration-tests/options/features/functions.all.expected b/rust/ql/integration-tests/options/features/functions.all.expected index 5ce4cae2ab0..1fa14be6da6 100644 --- a/rust/ql/integration-tests/options/features/functions.all.expected +++ b/rust/ql/integration-tests/options/features/functions.all.expected @@ -1,3 +1,3 @@ -| src/lib.rs:1:1:2:11 | foo | -| src/lib.rs:4:1:5:11 | bar | -| src/lib.rs:7:1:7:14 | always | +| src/lib.rs:1:1:2:11 | fn foo | +| src/lib.rs:4:1:5:11 | fn bar | +| src/lib.rs:7:1:7:14 | fn always | diff --git a/rust/ql/integration-tests/options/features/functions.bar.expected b/rust/ql/integration-tests/options/features/functions.bar.expected index cad441d6749..fae918e493a 100644 --- a/rust/ql/integration-tests/options/features/functions.bar.expected +++ b/rust/ql/integration-tests/options/features/functions.bar.expected @@ -1,2 +1,2 @@ -| src/lib.rs:4:1:5:11 | bar | -| src/lib.rs:7:1:7:14 | always | +| src/lib.rs:4:1:5:11 | fn bar | +| src/lib.rs:7:1:7:14 | fn always | diff --git a/rust/ql/integration-tests/options/features/functions.expected b/rust/ql/integration-tests/options/features/functions.expected index 523c2187688..d095a8993d8 100644 --- a/rust/ql/integration-tests/options/features/functions.expected +++ b/rust/ql/integration-tests/options/features/functions.expected @@ -1 +1 @@ -| src/lib.rs:7:1:7:14 | always | +| src/lib.rs:7:1:7:14 | fn always | diff --git a/rust/ql/integration-tests/options/features/functions.foo.expected b/rust/ql/integration-tests/options/features/functions.foo.expected index b7875423083..3768144364f 100644 --- a/rust/ql/integration-tests/options/features/functions.foo.expected +++ b/rust/ql/integration-tests/options/features/functions.foo.expected @@ -1,2 +1,2 @@ -| src/lib.rs:1:1:2:11 | foo | -| src/lib.rs:7:1:7:14 | always | +| src/lib.rs:1:1:2:11 | fn foo | +| src/lib.rs:7:1:7:14 | fn always | diff --git a/rust/ql/integration-tests/options/target/functions.Darwin.expected b/rust/ql/integration-tests/options/target/functions.Darwin.expected index 217974bb7c6..8b879e8ca7c 100644 --- a/rust/ql/integration-tests/options/target/functions.Darwin.expected +++ b/rust/ql/integration-tests/options/target/functions.Darwin.expected @@ -1 +1 @@ -| src/lib.rs:7:1:8:13 | macos | +| src/lib.rs:7:1:8:13 | fn macos | diff --git a/rust/ql/integration-tests/options/target/functions.Linux.expected b/rust/ql/integration-tests/options/target/functions.Linux.expected index 57662579f1f..2e023fb887c 100644 --- a/rust/ql/integration-tests/options/target/functions.Linux.expected +++ b/rust/ql/integration-tests/options/target/functions.Linux.expected @@ -1 +1 @@ -| src/lib.rs:1:1:2:13 | linux | +| src/lib.rs:1:1:2:13 | fn linux | diff --git a/rust/ql/integration-tests/options/target/functions.Windows.expected b/rust/ql/integration-tests/options/target/functions.Windows.expected index 8ae2d8c86cc..170a6e62e80 100644 --- a/rust/ql/integration-tests/options/target/functions.Windows.expected +++ b/rust/ql/integration-tests/options/target/functions.Windows.expected @@ -1 +1 @@ -| src/lib.rs:4:1:5:15 | windows | +| src/lib.rs:4:1:5:15 | fn windows | diff --git a/rust/ql/integration-tests/qltest/test.py b/rust/ql/integration-tests/qltest/test.py index e488dee2571..d130d5d2ff1 100644 --- a/rust/ql/integration-tests/qltest/test.py +++ b/rust/ql/integration-tests/qltest/test.py @@ -6,11 +6,12 @@ import pytest # (which skips `qltest.{sh,cmd}`) @pytest.fixture(autouse=True) -def default_options(codeql): +def default_options(codeql, pytestconfig): codeql.flags.update( threads = 1, show_extractor_output = True, check_databases = False, + learn = pytestconfig.getoption("learn"), ) @pytest.mark.parametrize("dir", ["lib", "main", "dependencies"]) From bf824cac0a55188f82b7de4fb84dc621f9dcfcd9 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 19 Nov 2024 15:57:31 +0000 Subject: [PATCH 101/470] Allow package-level variables in MaD --- go/ql/lib/semmle/go/dataflow/ExternalFlow.qll | 5 +++-- .../go/dataflow/internal/FlowSummaryImpl.qll | 18 ++++++++++++++++++ .../ExternalTaintFlow/completetest.ext.yml | 2 ++ .../dataflow/ExternalTaintFlow/sinks.expected | 1 + .../dataflow/ExternalTaintFlow/sinks.ext.yml | 1 + .../dataflow/ExternalTaintFlow/srcs.expected | 1 + .../go/dataflow/ExternalTaintFlow/srcs.ext.yml | 3 ++- .../go/dataflow/ExternalTaintFlow/test.go | 3 +++ .../vendor/github.com/nonexistent/test/stub.go | 3 +++ .../ExternalValueFlow/completetest.ext.yml | 2 ++ .../dataflow/ExternalValueFlow/sinks.expected | 1 + .../dataflow/ExternalValueFlow/sinks.ext.yml | 1 + .../dataflow/ExternalValueFlow/srcs.expected | 1 + .../go/dataflow/ExternalValueFlow/srcs.ext.yml | 3 ++- .../go/dataflow/ExternalValueFlow/test.go | 3 +++ .../vendor/github.com/nonexistent/test/stub.go | 3 +++ 16 files changed, 47 insertions(+), 4 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index a59c7294e80..5ae7b6a7f0d 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -38,7 +38,8 @@ * first 6 columns, and the `output` column specifies how data leaves the * element selected by the first 6 columns. An `input` can be either "", * "Argument[n]", or "Argument[n1..n2]": - * - "": Selects a write to the selected element in case this is a field. + * - "": Selects a write to the selected element in case this is a field or + * package-level variable. * - "Argument[n]": Selects an argument in a call to the selected element. * The arguments are zero-indexed, and `receiver` specifies the receiver. * - "Argument[n1..n2]": Similar to "Argument[n]" but selects any argument @@ -47,7 +48,7 @@ * An `output` can be either "", "Argument[n]", "Argument[n1..n2]", "Parameter", * "Parameter[n]", "Parameter[n1..n2]", , "ReturnValue", "ReturnValue[n]", or * "ReturnValue[n1..n2]": - * - "": Selects a read of a selected field. + * - "": Selects a read of a selected field or package-level variable. * - "Argument[n]": Selects the post-update value of an argument in a call to the * selected element. That is, the value of the argument after the call returns. * The arguments are zero-indexed, and `receiver` specifies the receiver. diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index b82039a32fe..40c68ceb900 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -399,6 +399,13 @@ module SourceSinkInterpretationInput implements c = "" and pragma[only_bind_into](e) = getElementWithQualifier(frn.getField(), frn.getBase()) ) + or + // A package-scope (or universe-scope) variable + exists(Variable v | not v instanceof Field | + c = "" and + n.(DataFlow::ReadNode).reads(v) and + pragma[only_bind_into](e).asEntity() = v + ) ) } @@ -420,6 +427,17 @@ module SourceSinkInterpretationInput implements fw.writesField(base, f, node.asNode()) and pragma[only_bind_into](e) = getElementWithQualifier(f, base) ) + or + // A package-scope (or universe-scope) variable + exists(Node n, SourceOrSinkElement e, DataFlow::Write w, Variable v | + n = node.asNode() and + e = mid.asElement() and + not v instanceof Field + | + c = "" and + w.writes(v, n) and + pragma[only_bind_into](e).asEntity() = v + ) } } diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/completetest.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/completetest.ext.yml index 79bf9128ef5..d89a9e04e16 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/completetest.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/completetest.ext.yml @@ -35,10 +35,12 @@ extensions: pack: codeql/go-all extensible: sourceModel data: + - ["github.com/nonexistent/test", "", False, "SourceVariable", "", "", "", "qltest", "manual"] - ["github.com/nonexistent/test", "A", False, "Src1", "", "", "ReturnValue", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: sinkModel data: + - ["github.com/nonexistent/test", "", False, "SinkVariable", "", "", "", "qltest", "manual"] - ["github.com/nonexistent/test", "B", False, "Sink1", "", "", "Argument[0]", "qltest", "manual"] - ["github.com/nonexistent/test", "B", False, "SinkManyArgs", "", "", "Argument[0..2]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/sinks.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/sinks.expected index fc9adff8942..755c3f82279 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/sinks.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/sinks.expected @@ -43,3 +43,4 @@ invalidModelRow | test.go:199:17:199:20 | arg1 | qltest | | test.go:199:23:199:26 | arg2 | qltest | | test.go:199:29:199:32 | arg3 | qltest | +| test.go:202:22:202:25 | temp | qltest | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/sinks.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/sinks.ext.yml index 426e094c00c..ec19b822a8c 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/sinks.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/sinks.ext.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/go-all extensible: sinkModel data: + - ["github.com/nonexistent/test", "", False, "SinkVariable", "", "", "", "qltest", "manual"] - ["github.com/nonexistent/test", "B", False, "Sink1", "", "", "Argument[0]", "qltest", "manual"] - ["github.com/nonexistent/test", "B", False, "SinkMethod", "", "", "Argument[receiver]", "qltest", "manual"] - ["github.com/nonexistent/test", "B", False, "SinkManyArgs", "", "", "Argument[0..2]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.expected index d63fedba3fd..bd1525a984b 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.expected @@ -21,3 +21,4 @@ invalidModelRow | test.go:183:17:183:24 | call to Src1 | qltest | | test.go:187:24:187:31 | call to Src1 | qltest | | test.go:191:24:191:31 | call to Src1 | qltest | +| test.go:201:10:201:28 | selection of SourceVariable | qltest | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.ext.yml index 5493650132c..cda2183894c 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.ext.yml @@ -3,9 +3,10 @@ extensions: pack: codeql/go-all extensible: sourceModel data: + - ["github.com/nonexistent/test", "", False, "SourceVariable", "", "", "", "qltest", "manual"] - ["github.com/nonexistent/test", "A", False, "Src1", "", "", "ReturnValue", "qltest", "manual"] - ["github.com/nonexistent/test", "A", False, "Src2", "", "", "ReturnValue", "qltest", "manual"] - ["github.com/nonexistent/test", "A", True, "Src2", "", "", "ReturnValue", "qltest-w-subtypes", "manual"] - ["github.com/nonexistent/test", "A", False, "SrcArg", "", "", "Argument[0]", "qltest-arg", "manual"] - ["github.com/nonexistent/test", "A", False, "Src3", "", "", "ReturnValue[0]", "qltest", "manual"] - - ["github.com/nonexistent/test", "A", True, "Src3", "", "", "ReturnValue[1]", "qltest-w-subtypes", "manual"] \ No newline at end of file + - ["github.com/nonexistent/test", "A", True, "Src3", "", "", "ReturnValue[1]", "qltest-w-subtypes", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/test.go b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/test.go index 33e980dac99..29ed066cd50 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/test.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/test.go @@ -197,6 +197,9 @@ func simpleflow() { arg3 := src arg4 := src b.SinkManyArgs(arg1, arg2, arg3, arg4) // $ hasTaintFlow="arg1" hasTaintFlow="arg2" hasTaintFlow="arg3" + + temp := test.SourceVariable + test.SinkVariable = temp // $ hasTaintFlow="temp" } type mapstringstringtype map[string]string diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/vendor/github.com/nonexistent/test/stub.go b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/vendor/github.com/nonexistent/test/stub.go index 05a5f741d76..72681cf7238 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/vendor/github.com/nonexistent/test/stub.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/vendor/github.com/nonexistent/test/stub.go @@ -72,3 +72,6 @@ func (c C) Get() string { return "" } func (c *C) SetThroughPointer(f string) {} func (c *C) GetThroughPointer() string { return "" } + +var SourceVariable string +var SinkVariable string diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/completetest.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/completetest.ext.yml index 8fbc26ff6cd..924e19a8a73 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/completetest.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/completetest.ext.yml @@ -35,10 +35,12 @@ extensions: pack: codeql/go-all extensible: sourceModel data: + - ["github.com/nonexistent/test", "", False, "SourceVariable", "", "", "", "qltest", "manual"] - ["github.com/nonexistent/test", "A", False, "Src1", "", "", "ReturnValue", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: sinkModel data: + - ["github.com/nonexistent/test", "", False, "SinkVariable", "", "", "", "qltest", "manual"] - ["github.com/nonexistent/test", "B", False, "Sink1", "", "", "Argument[0]", "qltest", "manual"] - ["github.com/nonexistent/test", "B", False, "SinkManyArgs", "", "", "Argument[0..2]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/sinks.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/sinks.expected index 0fe3a614e11..c9940e181c8 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/sinks.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/sinks.expected @@ -49,3 +49,4 @@ invalidModelRow | test.go:205:10:205:26 | call to min | qltest | | test.go:206:10:206:26 | call to min | qltest | | test.go:207:10:207:26 | call to min | qltest | +| test.go:210:22:210:25 | temp | qltest | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/sinks.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/sinks.ext.yml index 426e094c00c..ec19b822a8c 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/sinks.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/sinks.ext.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/go-all extensible: sinkModel data: + - ["github.com/nonexistent/test", "", False, "SinkVariable", "", "", "", "qltest", "manual"] - ["github.com/nonexistent/test", "B", False, "Sink1", "", "", "Argument[0]", "qltest", "manual"] - ["github.com/nonexistent/test", "B", False, "SinkMethod", "", "", "Argument[receiver]", "qltest", "manual"] - ["github.com/nonexistent/test", "B", False, "SinkManyArgs", "", "", "Argument[0..2]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/srcs.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/srcs.expected index d63fedba3fd..6fcfcc2a3bc 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/srcs.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/srcs.expected @@ -21,3 +21,4 @@ invalidModelRow | test.go:183:17:183:24 | call to Src1 | qltest | | test.go:187:24:187:31 | call to Src1 | qltest | | test.go:191:24:191:31 | call to Src1 | qltest | +| test.go:209:10:209:28 | selection of SourceVariable | qltest | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/srcs.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/srcs.ext.yml index 5493650132c..cda2183894c 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/srcs.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/srcs.ext.yml @@ -3,9 +3,10 @@ extensions: pack: codeql/go-all extensible: sourceModel data: + - ["github.com/nonexistent/test", "", False, "SourceVariable", "", "", "", "qltest", "manual"] - ["github.com/nonexistent/test", "A", False, "Src1", "", "", "ReturnValue", "qltest", "manual"] - ["github.com/nonexistent/test", "A", False, "Src2", "", "", "ReturnValue", "qltest", "manual"] - ["github.com/nonexistent/test", "A", True, "Src2", "", "", "ReturnValue", "qltest-w-subtypes", "manual"] - ["github.com/nonexistent/test", "A", False, "SrcArg", "", "", "Argument[0]", "qltest-arg", "manual"] - ["github.com/nonexistent/test", "A", False, "Src3", "", "", "ReturnValue[0]", "qltest", "manual"] - - ["github.com/nonexistent/test", "A", True, "Src3", "", "", "ReturnValue[1]", "qltest-w-subtypes", "manual"] \ No newline at end of file + - ["github.com/nonexistent/test", "A", True, "Src3", "", "", "ReturnValue[1]", "qltest-w-subtypes", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/test.go b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/test.go index 82419ae7d59..72c4db35248 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/test.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/test.go @@ -205,6 +205,9 @@ func simpleflow() { b.Sink1(min(srcInt, 0, 1)) // $ hasValueFlow="call to min" b.Sink1(min(0, srcInt, 1)) // $ hasValueFlow="call to min" b.Sink1(min(0, 1, srcInt)) // $ hasValueFlow="call to min" + + temp := test.SourceVariable + test.SinkVariable = temp // $ hasValueFlow="temp" } type mapstringstringtype map[string]string diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/vendor/github.com/nonexistent/test/stub.go b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/vendor/github.com/nonexistent/test/stub.go index 05a5f741d76..72681cf7238 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/vendor/github.com/nonexistent/test/stub.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/vendor/github.com/nonexistent/test/stub.go @@ -72,3 +72,6 @@ func (c C) Get() string { return "" } func (c *C) SetThroughPointer(f string) {} func (c *C) GetThroughPointer() string { return "" } + +var SourceVariable string +var SinkVariable string From dd87b1a9de94c184612367fc4b349bc2e237ebcc Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 19 Nov 2024 15:20:31 +0000 Subject: [PATCH 102/470] Convert `os.stdin` model to MaD --- go/ql/lib/ext/os.model.yml | 1 + go/ql/lib/semmle/go/frameworks/stdlib/Os.qll | 8 -------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/go/ql/lib/ext/os.model.yml b/go/ql/lib/ext/os.model.yml index 3d87eefe43f..2c1c64db93a 100644 --- a/go/ql/lib/ext/os.model.yml +++ b/go/ql/lib/ext/os.model.yml @@ -53,6 +53,7 @@ extensions: - ["os", "", False, "Open", "", "", "ReturnValue[0]", "file", "manual"] - ["os", "", False, "OpenFile", "", "", "ReturnValue[0]", "file", "manual"] - ["os", "", False, "ReadFile", "", "", "ReturnValue[0]", "file", "manual"] + - ["os", "", False, "Stdin", "", "", "", "stdin", "manual"] - ["os", "", False, "UserCacheDir", "", "", "ReturnValue[0]", "environment", "manual"] - ["os", "", False, "UserConfigDir", "", "", "ReturnValue[0]", "environment", "manual"] - ["os", "", False, "UserHomeDir", "", "", "ReturnValue[0]", "environment", "manual"] diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll index fb153451c59..72ea4cc6c57 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll @@ -43,12 +43,4 @@ module Os { input = inp and output = outp } } - - private class Stdin extends SourceNode { - Stdin() { - exists(Variable osStdin | osStdin.hasQualifiedName("os", "Stdin") | this = osStdin.getARead()) - } - - override string getThreatModel() { result = "stdin" } - } } From a2c62782829972af0e8351e8f3d879fddead15b3 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Tue, 19 Nov 2024 17:39:05 +0000 Subject: [PATCH 103/470] C++: fix typo in qhelp --- cpp/ql/src/Critical/UseAfterFree.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Critical/UseAfterFree.qhelp b/cpp/ql/src/Critical/UseAfterFree.qhelp index 6a532ed4d35..60dd1a6690e 100644 --- a/cpp/ql/src/Critical/UseAfterFree.qhelp +++ b/cpp/ql/src/Critical/UseAfterFree.qhelp @@ -8,7 +8,7 @@

    This rule finds accesses through a pointer of a memory location that has already been freed (i.e. through a dangling pointer). Such memory blocks have already been released to the dynamic memory manager, and modifying them can lead to anything -from a segfault to memory corruption that would cause subsequent calls to the dynamic memory manger to behave +from a segfault to memory corruption that would cause subsequent calls to the dynamic memory manager to behave erratically, to a possible security vulnerability.

    From 26d590a616fba45b40fa3e5d47791b59c6d38d13 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 19 Nov 2024 12:57:50 -0500 Subject: [PATCH 104/470] Putting back deleted file, and deprecating instead. Deprecating mayThrowException as well. --- .../code/cpp/models/interfaces/NonThrowing.qll | 13 +++++++++++++ .../semmle/code/cpp/models/interfaces/Throwing.qll | 7 +++++++ 2 files changed, 20 insertions(+) create mode 100644 cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll new file mode 100644 index 00000000000..9f2c28979b4 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll @@ -0,0 +1,13 @@ +/** + * Provides an abstract class for modeling functions that never throw. + */ + +import semmle.code.cpp.Function +import semmle.code.cpp.models.Models + +/** + * A function that is guaranteed to never throw. + * + * DEPRECATED: use `NonThrowingFunction` in `semmle.code.cpp.models.Models.Interfaces.Throwing` instead. + */ +abstract deprecated class NonThrowingFunction extends Function { } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll index 72db8c9e96c..bd64051d141 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll @@ -68,6 +68,13 @@ abstract class ThrowingFunction extends ExceptionAnnotation { */ abstract predicate raisesException(boolean unconditional); + /** + * DEPRECATES: use/extend `raisesException` instead. + */ + deprecated predicate mayThrowException(boolean unconditional){ + this.raisesException(unconditional) + } + /** * Holds if this function will always raise an exception if called */ From 07847762e1f7dc87408c0e74dba32edcd5d0be56 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 19 Nov 2024 13:17:10 -0500 Subject: [PATCH 105/470] bringing back mayThrowException to make it cleaner/easier for backwards compatibility. --- .../raw/internal/TranslatedCall.qll | 4 ++-- .../code/cpp/models/interfaces/Throwing.qll | 17 ++--------------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index 5f1b2fbe3b4..daa6bdaafcf 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -363,11 +363,11 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { } final override predicate mayThrowException() { - expr.getTarget().(ThrowingFunction).raisesException(_) + expr.getTarget().(ThrowingFunction).mayThrowException(_) } final override predicate mustThrowException() { - expr.getTarget().(ThrowingFunction).raisesException(true) + expr.getTarget().(ThrowingFunction).mayThrowException(true) } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll index bd64051d141..db6bd689b4f 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll @@ -66,23 +66,10 @@ abstract class ThrowingFunction extends ExceptionAnnotation { * Do not specify `none()` if no exception is raised, instead use the * `NonThrowingFunction` class instead. */ - abstract predicate raisesException(boolean unconditional); - - /** - * DEPRECATES: use/extend `raisesException` instead. - */ - deprecated predicate mayThrowException(boolean unconditional){ - this.raisesException(unconditional) - } + abstract predicate mayThrowException(boolean unconditional); /** * Holds if this function will always raise an exception if called */ - final predicate alwaysRaisesException() { this.raisesException(true) } - - /** - * Holds if this function may raise an exception if called but - * it is not guaranteed to do so. I.e., the function does not always raise an exception. - */ - final predicate mayRaiseException() { this.raisesException(false) } + final predicate alwaysRaisesException() { this.mayThrowException(true) } } From a69daa0d2018844fae600a420e7417de4f8600b8 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 19 Nov 2024 13:35:45 -0500 Subject: [PATCH 106/470] Missing change to 'mayThrowException' in StructuredExceptionHandling.qll --- .../cpp/models/implementations/StructuredExceptionHandling.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll index 485dc7137b8..36a2f6cdbe4 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll @@ -5,7 +5,7 @@ class WindowsDriverExceptionAnnotation extends ThrowingFunction { this.hasGlobalName(["RaiseException", "ExRaiseAccessViolation", "ExRaiseDatatypeMisalignment"]) } - override predicate raisesException(boolean unconditional) { unconditional = true } + override predicate mayThrowException(boolean unconditional) { unconditional = true } override TSehException getExceptionType() { any() } } From 4e777561f06ad9f891de48ab648135ebc50cd361 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 19 Nov 2024 15:10:15 -0500 Subject: [PATCH 107/470] Changing terminology back to "throws" vs "rasis" for alwaysThrowsException to be consistent with other backward compatibility changes. --- cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll index db6bd689b4f..d64ba61caa0 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll @@ -71,5 +71,5 @@ abstract class ThrowingFunction extends ExceptionAnnotation { /** * Holds if this function will always raise an exception if called */ - final predicate alwaysRaisesException() { this.mayThrowException(true) } + final predicate alwaysThrowsException() { this.mayThrowException(true) } } From cf84c08abfdffccb704c74cd042a7051bbd52a64 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 20 Nov 2024 00:18:55 +0000 Subject: [PATCH 108/470] Add change note --- go/ql/src/change-notes/2024-11-20-heuristic-logging-sinks.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 go/ql/src/change-notes/2024-11-20-heuristic-logging-sinks.md diff --git a/go/ql/src/change-notes/2024-11-20-heuristic-logging-sinks.md b/go/ql/src/change-notes/2024-11-20-heuristic-logging-sinks.md new file mode 100644 index 00000000000..7fcb5fa3a34 --- /dev/null +++ b/go/ql/src/change-notes/2024-11-20-heuristic-logging-sinks.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* A call to a method whose name starts with "Debug", "Error", "Fatal", "Info", "Log", "Output", "Panic", "Print", "Trace" or "Warn" defined on an interface whose name ends in "logger" or "Logger" is now considered a sink for `go/clear-text-logging` and `go/log-injection`. This may lead to some more alerts in those queries. From d80aa6fa6ad154538fdc69c6cd1ac353017e794d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 00:21:24 +0000 Subject: [PATCH 109/470] Add changed framework coverage reports --- .../library-coverage/coverage.csv | 27 +- .../library-coverage/coverage.rst | 6 +- .../library-coverage/coverage.csv | 242 +++++++++--------- .../library-coverage/coverage.rst | 4 +- 4 files changed, 140 insertions(+), 139 deletions(-) diff --git a/csharp/documentation/library-coverage/coverage.csv b/csharp/documentation/library-coverage/coverage.csv index 10b1c58ef31..6a48878f13e 100644 --- a/csharp/documentation/library-coverage/coverage.csv +++ b/csharp/documentation/library-coverage/coverage.csv @@ -8,39 +8,40 @@ ILLink.Shared,,,31,,,,,,,,,,,,,,,,,,,11,20 ILLink.Tasks,,,5,,,,,,,,,,,,,,,,,,,4,1 Internal.IL,,,54,,,,,,,,,,,,,,,,,,,28,26 Internal.Pgo,,,9,,,,,,,,,,,,,,,,,,,2,7 -Internal.TypeSystem,,,328,,,,,,,,,,,,,,,,,,,201,127 +Internal.TypeSystem,,,329,,,,,,,,,,,,,,,,,,,201,128 JsonToItemsTaskFactory,,,11,,,,,,,,,,,,,,,,,,,1,10 Microsoft.Android.Build,,1,14,,,,,,,,,,,,,1,,,,,,12,2 Microsoft.Apple.Build,,,7,,,,,,,,,,,,,,,,,,,7, Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,,,28,,,,,,,,,, Microsoft.CSharp,,,2,,,,,,,,,,,,,,,,,,,2, -Microsoft.Diagnostics.Tools.Pgo,,,23,,,,,,,,,,,,,,,,,,,2,21 +Microsoft.Diagnostics.Tools.Pgo,,,25,,,,,,,,,,,,,,,,,,,2,23 Microsoft.DotNet.Build.Tasks,,,10,,,,,,,,,,,,,,,,,,,8,2 +Microsoft.DotNet.PlatformAbstractions,,,1,,,,,,,,,,,,,,,,,,,1, Microsoft.EntityFrameworkCore,6,,12,,,,,,,,,,6,,,,,,,,,,12 Microsoft.Extensions.Caching.Distributed,,,3,,,,,,,,,,,,,,,,,,,,3 -Microsoft.Extensions.Caching.Memory,,,31,,,,,,,,,,,,,,,,,,,5,26 -Microsoft.Extensions.Configuration,,3,91,,,,,,,,,,,,,3,,,,,,25,66 -Microsoft.Extensions.DependencyInjection,,,130,,,,,,,,,,,,,,,,,,,17,113 +Microsoft.Extensions.Caching.Memory,,,37,,,,,,,,,,,,,,,,,,,5,32 +Microsoft.Extensions.Configuration,,3,101,,,,,,,,,,,,,3,,,,,,29,72 +Microsoft.Extensions.DependencyInjection,,,202,,,,,,,,,,,,,,,,,,,15,187 Microsoft.Extensions.DependencyModel,,1,16,,,,,,,,,,,,,1,,,,,,14,2 Microsoft.Extensions.Diagnostics.Metrics,,,14,,,,,,,,,,,,,,,,,,,1,13 Microsoft.Extensions.FileProviders,,,17,,,,,,,,,,,,,,,,,,,7,10 -Microsoft.Extensions.FileSystemGlobbing,,,22,,,,,,,,,,,,,,,,,,,11,11 -Microsoft.Extensions.Hosting,,,39,,,,,,,,,,,,,,,,,,,29,10 +Microsoft.Extensions.FileSystemGlobbing,,,21,,,,,,,,,,,,,,,,,,,10,11 +Microsoft.Extensions.Hosting,,,58,,,,,,,,,,,,,,,,,,,29,29 Microsoft.Extensions.Http,,,9,,,,,,,,,,,,,,,,,,,7,2 -Microsoft.Extensions.Logging,,,64,,,,,,,,,,,,,,,,,,,25,39 -Microsoft.Extensions.Options,,,14,,,,,,,,,,,,,,,,,,,14, -Microsoft.Extensions.Primitives,,,72,,,,,,,,,,,,,,,,,,,67,5 -Microsoft.Interop,,,137,,,,,,,,,,,,,,,,,,,70,67 +Microsoft.Extensions.Logging,,,91,,,,,,,,,,,,,,,,,,,25,66 +Microsoft.Extensions.Options,,,68,,,,,,,,,,,,,,,,,,,44,24 +Microsoft.Extensions.Primitives,,,73,,,,,,,,,,,,,,,,,,,67,6 +Microsoft.Interop,,,159,,,,,,,,,,,,,,,,,,,75,84 Microsoft.NET.Build.Tasks,,,5,,,,,,,,,,,,,,,,,,,3,2 Microsoft.NET.Sdk.WebAssembly,,,2,,,,,,,,,,,,,,,,,,,1,1 Microsoft.NET.WebAssembly.Webcil,,,6,,,,,,,,,,,,,,,,,,,6, Microsoft.VisualBasic,,,13,,,,,,,,,,,,,,,,,,,1,12 Microsoft.WebAssembly.Build.Tasks,,,9,,,,,,,,,,,,,,,,,,,8,1 Microsoft.Win32,,4,2,,,,,,,,,,,,,,,,,,4,,2 -Mono.Linker,,,287,,,,,,,,,,,,,,,,,,,145,142 +Mono.Linker,,,293,,,,,,,,,,,,,,,,,,,145,148 MySql.Data.MySqlClient,48,,,,,,,,,,,,48,,,,,,,,,, Newtonsoft.Json,,,91,,,,,,,,,,,,,,,,,,,73,18 ServiceStack,194,,7,27,,,,,75,,,,92,,,,,,,,,7, SourceGenerators,,,5,,,,,,,,,,,,,,,,,,,,5 -System,54,47,10313,,6,5,5,,,4,1,,33,2,,6,15,17,4,3,,5351,4962 +System,54,47,10818,,6,5,5,,,4,1,,33,2,,6,15,17,4,3,,5511,5307 Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,,,,,,,, diff --git a/csharp/documentation/library-coverage/coverage.rst b/csharp/documentation/library-coverage/coverage.rst index 5eaaad17457..82aa21d3d91 100644 --- a/csharp/documentation/library-coverage/coverage.rst +++ b/csharp/documentation/library-coverage/coverage.rst @@ -8,7 +8,7 @@ C# framework & library support Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting` `ServiceStack `_,"``ServiceStack.*``, ``ServiceStack``",,7,194, - System,"``System.*``, ``System``",47,10313,54,5 - Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.DotNet.Build.Tasks``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.Sdk.WebAssembly``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",57,1848,148, - Totals,,104,12168,396,5 + System,"``System.*``, ``System``",47,10818,54,5 + Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.DotNet.Build.Tasks``, ``Microsoft.DotNet.PlatformAbstractions``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.Sdk.WebAssembly``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",57,2068,148, + Totals,,104,12893,396,5 diff --git a/go/documentation/library-coverage/coverage.csv b/go/documentation/library-coverage/coverage.csv index 364e17aa94b..547f0aa79ac 100644 --- a/go/documentation/library-coverage/coverage.csv +++ b/go/documentation/library-coverage/coverage.csv @@ -1,121 +1,121 @@ -package,sink,source,summary,sink:command-injection,sink:credentials-key,sink:jwt,sink:path-injection,sink:regex-use[0],sink:regex-use[1],sink:regex-use[c],sink:request-forgery,sink:request-forgery[TCP Addr + Port],sink:url-redirection,sink:url-redirection[0],sink:url-redirection[receiver],sink:xpath-injection,source:environment,source:file,source:remote,summary:taint,summary:value -,,,8,,,,,,,,,,,,,,,,,3,5 -archive/tar,,,5,,,,,,,,,,,,,,,,,5, -archive/zip,,,6,,,,,,,,,,,,,,,,,6, -bufio,,,17,,,,,,,,,,,,,,,,,17, -bytes,,,43,,,,,,,,,,,,,,,,,43, -clevergo.tech/clevergo,1,,,,,,,,,,,,,,1,,,,,, -compress/bzip2,,,1,,,,,,,,,,,,,,,,,1, -compress/flate,,,4,,,,,,,,,,,,,,,,,4, -compress/gzip,,,3,,,,,,,,,,,,,,,,,3, -compress/lzw,,,1,,,,,,,,,,,,,,,,,1, -compress/zlib,,,4,,,,,,,,,,,,,,,,,4, -container/heap,,,5,,,,,,,,,,,,,,,,,5, -container/list,,,20,,,,,,,,,,,,,,,,,20, -container/ring,,,5,,,,,,,,,,,,,,,,,5, -context,,,5,,,,,,,,,,,,,,,,,5, -crypto,,,10,,,,,,,,,,,,,,,,,10, -database/sql,,,11,,,,,,,,,,,,,,,,,11, -encoding,,,77,,,,,,,,,,,,,,,,,77, -errors,,,3,,,,,,,,,,,,,,,,,3, -expvar,,,6,,,,,,,,,,,,,,,,,6, -fmt,,,16,,,,,,,,,,,,,,,,,16, -github.com/ChrisTrenkamp/goxpath,3,,,,,,,,,,,,,,,3,,,,, -github.com/antchfx/htmlquery,4,,,,,,,,,,,,,,,4,,,,, -github.com/antchfx/jsonquery,4,,,,,,,,,,,,,,,4,,,,, -github.com/antchfx/xmlquery,8,,,,,,,,,,,,,,,8,,,,, -github.com/antchfx/xpath,4,,,,,,,,,,,,,,,4,,,,, -github.com/appleboy/gin-jwt,1,,,,1,,,,,,,,,,,,,,,, -github.com/astaxie/beego,7,21,21,,,,5,,,,,,2,,,,,,21,21, -github.com/beego/beego,14,42,42,,,,10,,,,,,4,,,,,,42,42, -github.com/caarlos0/env,,5,2,,,,,,,,,,,,,,5,,,1,1 -github.com/clevergo/clevergo,1,,,,,,,,,,,,,,1,,,,,, -github.com/codeskyblue/go-sh,4,,,4,,,,,,,,,,,,,,,,, -github.com/couchbase/gocb,,,18,,,,,,,,,,,,,,,,,18, -github.com/couchbaselabs/gocb,,,18,,,,,,,,,,,,,,,,,18, -github.com/crankycoder/xmlpath,2,,,,,,,,,,,,,,,2,,,,, -github.com/cristalhq/jwt,1,,,,1,,,,,,,,,,,,,,,, -github.com/dgrijalva/jwt-go,3,,9,,2,1,,,,,,,,,,,,,,9, -github.com/elazarl/goproxy,,2,2,,,,,,,,,,,,,,,,2,2, -github.com/emicklei/go-restful,,7,,,,,,,,,,,,,,,,,7,, -github.com/evanphx/json-patch,,,12,,,,,,,,,,,,,,,,,12, -github.com/form3tech-oss/jwt-go,2,,,,2,,,,,,,,,,,,,,,, -github.com/gin-gonic/gin,3,46,2,,,,3,,,,,,,,,,,,46,2, -github.com/go-chi/chi,,3,,,,,,,,,,,,,,,,,3,, -github.com/go-chi/jwtauth,1,,,,1,,,,,,,,,,,,,,,, -github.com/go-jose/go-jose,3,,4,,2,1,,,,,,,,,,,,,,4, -github.com/go-kit/kit/auth/jwt,1,,,,1,,,,,,,,,,,,,,,, -github.com/go-pg/pg/orm,,,6,,,,,,,,,,,,,,,,,6, -github.com/go-xmlpath/xmlpath,2,,,,,,,,,,,,,,,2,,,,, -github.com/gobuffalo/envy,,7,,,,,,,,,,,,,,,7,,,, -github.com/gobwas/ws,,2,,,,,,,,,,,,,,,,,2,, -github.com/gofiber/fiber,5,,,,,,4,,,,,,,,1,,,,,, -github.com/gogf/gf-jwt,1,,,,1,,,,,,,,,,,,,,,, -github.com/going/toolkit/xmlpath,2,,,,,,,,,,,,,,,2,,,,, -github.com/golang-jwt/jwt,3,,11,,2,1,,,,,,,,,,,,,,11, -github.com/golang/protobuf/proto,,,4,,,,,,,,,,,,,,,,,4, -github.com/gorilla/mux,,1,,,,,,,,,,,,,,,,,1,, -github.com/gorilla/websocket,,3,,,,,,,,,,,,,,,,,3,, -github.com/hashicorp/go-envparse,,1,,,,,,,,,,,,,,,1,,,, -github.com/jbowtie/gokogiri/xml,4,,,,,,,,,,,,,,,4,,,,, -github.com/jbowtie/gokogiri/xpath,1,,,,,,,,,,,,,,,1,,,,, -github.com/joho/godotenv,,4,,,,,,,,,,,,,,,4,,,, -github.com/json-iterator/go,,,4,,,,,,,,,,,,,,,,,4, -github.com/kataras/iris/context,6,,,,,,6,,,,,,,,,,,,,, -github.com/kataras/iris/middleware/jwt,2,,,,2,,,,,,,,,,,,,,,, -github.com/kataras/iris/server/web/context,6,,,,,,6,,,,,,,,,,,,,, -github.com/kataras/jwt,5,,,,5,,,,,,,,,,,,,,,, -github.com/kelseyhightower/envconfig,,6,,,,,,,,,,,,,,,6,,,, -github.com/labstack/echo,3,12,2,,,,2,,,,,,1,,,,,,12,2, -github.com/lestrrat-go/jwx,2,,,,2,,,,,,,,,,,,,,,, -github.com/lestrrat-go/libxml2/parser,3,,,,,,,,,,,,,,,3,,,,, -github.com/lestrrat/go-jwx/jwk,1,,,,1,,,,,,,,,,,,,,,, -github.com/masterzen/xmlpath,2,,,,,,,,,,,,,,,2,,,,, -github.com/moovweb/gokogiri/xml,4,,,,,,,,,,,,,,,4,,,,, -github.com/moovweb/gokogiri/xpath,1,,,,,,,,,,,,,,,1,,,,, -github.com/ory/fosite/token/jwt,2,,,,2,,,,,,,,,,,,,,,, -github.com/revel/revel,2,23,10,,,,1,,,,,,1,,,,,,23,10, -github.com/robfig/revel,2,23,10,,,,1,,,,,,1,,,,,,23,10, -github.com/santhosh-tekuri/xpathparser,2,,,,,,,,,,,,,,,2,,,,, -github.com/sendgrid/sendgrid-go/helpers/mail,,,1,,,,,,,,,,,,,,,,,1, -github.com/spf13/afero,34,,,,,,34,,,,,,,,,,,,,, -github.com/square/go-jose,3,,4,,2,1,,,,,,,,,,,,,,4, -github.com/valyala/fasthttp,35,50,5,,,,8,,,,17,8,2,,,,,,50,5, -go.uber.org/zap,,,11,,,,,,,,,,,,,,,,,11, -golang.org/x/crypto/ssh,4,,,4,,,,,,,,,,,,,,,,, -golang.org/x/net/context,,,5,,,,,,,,,,,,,,,,,5, -golang.org/x/net/html,,,16,,,,,,,,,,,,,,,,,16, -golang.org/x/net/websocket,,2,,,,,,,,,,,,,,,,,2,, -google.golang.org/protobuf/internal/encoding/text,,,1,,,,,,,,,,,,,,,,,1, -google.golang.org/protobuf/internal/impl,,,2,,,,,,,,,,,,,,,,,2, -google.golang.org/protobuf/proto,,,8,,,,,,,,,,,,,,,,,8, -google.golang.org/protobuf/reflect/protoreflect,,,1,,,,,,,,,,,,,,,,,1, -gopkg.in/couchbase/gocb,,,18,,,,,,,,,,,,,,,,,18, -gopkg.in/go-jose/go-jose,3,,4,,2,1,,,,,,,,,,,,,,4, -gopkg.in/go-xmlpath/xmlpath,2,,,,,,,,,,,,,,,2,,,,, -gopkg.in/macaron,1,12,1,,,,,,,,,,,,1,,,,12,1, -gopkg.in/square/go-jose,3,,4,,2,1,,,,,,,,,,,,,,4, -gopkg.in/xmlpath,2,,,,,,,,,,,,,,,2,,,,, -gopkg.in/yaml,,,9,,,,,,,,,,,,,,,,,9, -html,,,8,,,,,,,,,,,,,,,,,8, -io,5,4,34,,,,5,,,,,,,,,,,4,,34, -k8s.io/api/core,,,10,,,,,,,,,,,,,,,,,10, -k8s.io/apimachinery/pkg/runtime,,,47,,,,,,,,,,,,,,,,,47, -launchpad.net/xmlpath,2,,,,,,,,,,,,,,,2,,,,, -log,,,3,,,,,,,,,,,,,,,,,3, -math/big,,,1,,,,,,,,,,,,,,,,,1, -mime,,,14,,,,,,,,,,,,,,,,,14, -net,2,16,100,,,,1,,,,,,,1,,,,,16,100, -nhooyr.io/websocket,,2,,,,,,,,,,,,,,,,,2,, -os,29,10,6,3,,,26,,,,,,,,,,7,3,,6, -path,,,18,,,,,,,,,,,,,,,,,18, -reflect,,,37,,,,,,,,,,,,,,,,,37, -regexp,10,,20,,,,,3,3,4,,,,,,,,,,20, -sort,,,1,,,,,,,,,,,,,,,,,1, -strconv,,,9,,,,,,,,,,,,,,,,,9, -strings,,,34,,,,,,,,,,,,,,,,,34, -sync,,,34,,,,,,,,,,,,,,,,,34, -syscall,5,2,8,5,,,,,,,,,,,,,2,,,8, -text/scanner,,,3,,,,,,,,,,,,,,,,,3, -text/tabwriter,,,1,,,,,,,,,,,,,,,,,1, -text/template,,,6,,,,,,,,,,,,,,,,,6, +package,sink,source,summary,sink:command-injection,sink:credentials-key,sink:jwt,sink:path-injection,sink:regex-use[0],sink:regex-use[1],sink:regex-use[c],sink:request-forgery,sink:request-forgery[TCP Addr + Port],sink:url-redirection,sink:url-redirection[0],sink:url-redirection[receiver],sink:xpath-injection,source:environment,source:file,source:remote,source:stdin,summary:taint,summary:value +,,,8,,,,,,,,,,,,,,,,,,3,5 +archive/tar,,,5,,,,,,,,,,,,,,,,,,5, +archive/zip,,,6,,,,,,,,,,,,,,,,,,6, +bufio,,,17,,,,,,,,,,,,,,,,,,17, +bytes,,,43,,,,,,,,,,,,,,,,,,43, +clevergo.tech/clevergo,1,,,,,,,,,,,,,,1,,,,,,, +compress/bzip2,,,1,,,,,,,,,,,,,,,,,,1, +compress/flate,,,4,,,,,,,,,,,,,,,,,,4, +compress/gzip,,,3,,,,,,,,,,,,,,,,,,3, +compress/lzw,,,1,,,,,,,,,,,,,,,,,,1, +compress/zlib,,,4,,,,,,,,,,,,,,,,,,4, +container/heap,,,5,,,,,,,,,,,,,,,,,,5, +container/list,,,20,,,,,,,,,,,,,,,,,,20, +container/ring,,,5,,,,,,,,,,,,,,,,,,5, +context,,,5,,,,,,,,,,,,,,,,,,5, +crypto,,,10,,,,,,,,,,,,,,,,,,10, +database/sql,,,11,,,,,,,,,,,,,,,,,,11, +encoding,,,77,,,,,,,,,,,,,,,,,,77, +errors,,,3,,,,,,,,,,,,,,,,,,3, +expvar,,,6,,,,,,,,,,,,,,,,,,6, +fmt,,,16,,,,,,,,,,,,,,,,,,16, +github.com/ChrisTrenkamp/goxpath,3,,,,,,,,,,,,,,,3,,,,,, +github.com/antchfx/htmlquery,4,,,,,,,,,,,,,,,4,,,,,, +github.com/antchfx/jsonquery,4,,,,,,,,,,,,,,,4,,,,,, +github.com/antchfx/xmlquery,8,,,,,,,,,,,,,,,8,,,,,, +github.com/antchfx/xpath,4,,,,,,,,,,,,,,,4,,,,,, +github.com/appleboy/gin-jwt,1,,,,1,,,,,,,,,,,,,,,,, +github.com/astaxie/beego,7,21,21,,,,5,,,,,,2,,,,,,21,,21, +github.com/beego/beego,14,42,42,,,,10,,,,,,4,,,,,,42,,42, +github.com/caarlos0/env,,5,2,,,,,,,,,,,,,,5,,,,1,1 +github.com/clevergo/clevergo,1,,,,,,,,,,,,,,1,,,,,,, +github.com/codeskyblue/go-sh,4,,,4,,,,,,,,,,,,,,,,,, +github.com/couchbase/gocb,,,18,,,,,,,,,,,,,,,,,,18, +github.com/couchbaselabs/gocb,,,18,,,,,,,,,,,,,,,,,,18, +github.com/crankycoder/xmlpath,2,,,,,,,,,,,,,,,2,,,,,, +github.com/cristalhq/jwt,1,,,,1,,,,,,,,,,,,,,,,, +github.com/dgrijalva/jwt-go,3,,9,,2,1,,,,,,,,,,,,,,,9, +github.com/elazarl/goproxy,,2,2,,,,,,,,,,,,,,,,2,,2, +github.com/emicklei/go-restful,,7,,,,,,,,,,,,,,,,,7,,, +github.com/evanphx/json-patch,,,12,,,,,,,,,,,,,,,,,,12, +github.com/form3tech-oss/jwt-go,2,,,,2,,,,,,,,,,,,,,,,, +github.com/gin-gonic/gin,3,46,2,,,,3,,,,,,,,,,,,46,,2, +github.com/go-chi/chi,,3,,,,,,,,,,,,,,,,,3,,, +github.com/go-chi/jwtauth,1,,,,1,,,,,,,,,,,,,,,,, +github.com/go-jose/go-jose,3,,4,,2,1,,,,,,,,,,,,,,,4, +github.com/go-kit/kit/auth/jwt,1,,,,1,,,,,,,,,,,,,,,,, +github.com/go-pg/pg/orm,,,6,,,,,,,,,,,,,,,,,,6, +github.com/go-xmlpath/xmlpath,2,,,,,,,,,,,,,,,2,,,,,, +github.com/gobuffalo/envy,,7,,,,,,,,,,,,,,,7,,,,, +github.com/gobwas/ws,,2,,,,,,,,,,,,,,,,,2,,, +github.com/gofiber/fiber,5,,,,,,4,,,,,,,,1,,,,,,, +github.com/gogf/gf-jwt,1,,,,1,,,,,,,,,,,,,,,,, +github.com/going/toolkit/xmlpath,2,,,,,,,,,,,,,,,2,,,,,, +github.com/golang-jwt/jwt,3,,11,,2,1,,,,,,,,,,,,,,,11, +github.com/golang/protobuf/proto,,,4,,,,,,,,,,,,,,,,,,4, +github.com/gorilla/mux,,1,,,,,,,,,,,,,,,,,1,,, +github.com/gorilla/websocket,,3,,,,,,,,,,,,,,,,,3,,, +github.com/hashicorp/go-envparse,,1,,,,,,,,,,,,,,,1,,,,, +github.com/jbowtie/gokogiri/xml,4,,,,,,,,,,,,,,,4,,,,,, +github.com/jbowtie/gokogiri/xpath,1,,,,,,,,,,,,,,,1,,,,,, +github.com/joho/godotenv,,4,,,,,,,,,,,,,,,4,,,,, +github.com/json-iterator/go,,,4,,,,,,,,,,,,,,,,,,4, +github.com/kataras/iris/context,6,,,,,,6,,,,,,,,,,,,,,, +github.com/kataras/iris/middleware/jwt,2,,,,2,,,,,,,,,,,,,,,,, +github.com/kataras/iris/server/web/context,6,,,,,,6,,,,,,,,,,,,,,, +github.com/kataras/jwt,5,,,,5,,,,,,,,,,,,,,,,, +github.com/kelseyhightower/envconfig,,6,,,,,,,,,,,,,,,6,,,,, +github.com/labstack/echo,3,12,2,,,,2,,,,,,1,,,,,,12,,2, +github.com/lestrrat-go/jwx,2,,,,2,,,,,,,,,,,,,,,,, +github.com/lestrrat-go/libxml2/parser,3,,,,,,,,,,,,,,,3,,,,,, +github.com/lestrrat/go-jwx/jwk,1,,,,1,,,,,,,,,,,,,,,,, +github.com/masterzen/xmlpath,2,,,,,,,,,,,,,,,2,,,,,, +github.com/moovweb/gokogiri/xml,4,,,,,,,,,,,,,,,4,,,,,, +github.com/moovweb/gokogiri/xpath,1,,,,,,,,,,,,,,,1,,,,,, +github.com/ory/fosite/token/jwt,2,,,,2,,,,,,,,,,,,,,,,, +github.com/revel/revel,2,23,10,,,,1,,,,,,1,,,,,,23,,10, +github.com/robfig/revel,2,23,10,,,,1,,,,,,1,,,,,,23,,10, +github.com/santhosh-tekuri/xpathparser,2,,,,,,,,,,,,,,,2,,,,,, +github.com/sendgrid/sendgrid-go/helpers/mail,,,1,,,,,,,,,,,,,,,,,,1, +github.com/spf13/afero,34,,,,,,34,,,,,,,,,,,,,,, +github.com/square/go-jose,3,,4,,2,1,,,,,,,,,,,,,,,4, +github.com/valyala/fasthttp,35,50,5,,,,8,,,,17,8,2,,,,,,50,,5, +go.uber.org/zap,,,11,,,,,,,,,,,,,,,,,,11, +golang.org/x/crypto/ssh,4,,,4,,,,,,,,,,,,,,,,,, +golang.org/x/net/context,,,5,,,,,,,,,,,,,,,,,,5, +golang.org/x/net/html,,,16,,,,,,,,,,,,,,,,,,16, +golang.org/x/net/websocket,,2,,,,,,,,,,,,,,,,,2,,, +google.golang.org/protobuf/internal/encoding/text,,,1,,,,,,,,,,,,,,,,,,1, +google.golang.org/protobuf/internal/impl,,,2,,,,,,,,,,,,,,,,,,2, +google.golang.org/protobuf/proto,,,8,,,,,,,,,,,,,,,,,,8, +google.golang.org/protobuf/reflect/protoreflect,,,1,,,,,,,,,,,,,,,,,,1, +gopkg.in/couchbase/gocb,,,18,,,,,,,,,,,,,,,,,,18, +gopkg.in/go-jose/go-jose,3,,4,,2,1,,,,,,,,,,,,,,,4, +gopkg.in/go-xmlpath/xmlpath,2,,,,,,,,,,,,,,,2,,,,,, +gopkg.in/macaron,1,12,1,,,,,,,,,,,,1,,,,12,,1, +gopkg.in/square/go-jose,3,,4,,2,1,,,,,,,,,,,,,,,4, +gopkg.in/xmlpath,2,,,,,,,,,,,,,,,2,,,,,, +gopkg.in/yaml,,,9,,,,,,,,,,,,,,,,,,9, +html,,,8,,,,,,,,,,,,,,,,,,8, +io,5,4,34,,,,5,,,,,,,,,,,4,,,34, +k8s.io/api/core,,,10,,,,,,,,,,,,,,,,,,10, +k8s.io/apimachinery/pkg/runtime,,,47,,,,,,,,,,,,,,,,,,47, +launchpad.net/xmlpath,2,,,,,,,,,,,,,,,2,,,,,, +log,,,3,,,,,,,,,,,,,,,,,,3, +math/big,,,1,,,,,,,,,,,,,,,,,,1, +mime,,,14,,,,,,,,,,,,,,,,,,14, +net,2,16,100,,,,1,,,,,,,1,,,,,16,,100, +nhooyr.io/websocket,,2,,,,,,,,,,,,,,,,,2,,, +os,29,11,6,3,,,26,,,,,,,,,,7,3,,1,6, +path,,,18,,,,,,,,,,,,,,,,,,18, +reflect,,,37,,,,,,,,,,,,,,,,,,37, +regexp,10,,20,,,,,3,3,4,,,,,,,,,,,20, +sort,,,1,,,,,,,,,,,,,,,,,,1, +strconv,,,9,,,,,,,,,,,,,,,,,,9, +strings,,,34,,,,,,,,,,,,,,,,,,34, +sync,,,34,,,,,,,,,,,,,,,,,,34, +syscall,5,2,8,5,,,,,,,,,,,,,2,,,,8, +text/scanner,,,3,,,,,,,,,,,,,,,,,,3, +text/tabwriter,,,1,,,,,,,,,,,,,,,,,,1, +text/template,,,6,,,,,,,,,,,,,,,,,,6, diff --git a/go/documentation/library-coverage/coverage.rst b/go/documentation/library-coverage/coverage.rst index 848d989d2d5..09c44b8aa80 100644 --- a/go/documentation/library-coverage/coverage.rst +++ b/go/documentation/library-coverage/coverage.rst @@ -26,7 +26,7 @@ Go framework & library support `Macaron `_,``gopkg.in/macaron*``,12,1,1 `Revel `_,"``github.com/revel/revel*``, ``github.com/robfig/revel*``",46,20,4 `SendGrid `_,``github.com/sendgrid/sendgrid-go*``,,1, - `Standard library `_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``",32,587,51 + `Standard library `_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``",33,587,51 `XPath `_,``github.com/antchfx/xpath*``,,,4 `appleboy/gin-jwt `_,``github.com/appleboy/gin-jwt*``,,,1 `beego `_,"``github.com/astaxie/beego*``, ``github.com/beego/beego*``",63,63,21 @@ -61,5 +61,5 @@ Go framework & library support `yaml `_,``gopkg.in/yaml*``,,9, `zap `_,``go.uber.org/zap*``,,11, Others,"``github.com/caarlos0/env``, ``github.com/gobuffalo/envy``, ``github.com/hashicorp/go-envparse``, ``github.com/joho/godotenv``, ``github.com/kelseyhightower/envconfig``",23,2, - Totals,,306,911,268 + Totals,,307,911,268 From 4fb028cbb2b2ff2d14a9abd00e9df84667cc2e9c Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 20 Nov 2024 09:45:15 +0100 Subject: [PATCH 110/470] Rust: accept last integration test changes Also make `--learn` work with the nested qltest tests. --- .../qltest/dependencies/functions.expected | 1 - .../qltest/dependencies/functions.nested.expected | 1 + rust/ql/integration-tests/qltest/lib/functions.expected | 1 - .../integration-tests/qltest/lib/functions.nested.expected | 1 + rust/ql/integration-tests/qltest/main/functions.expected | 2 -- .../qltest/main/functions.nested.expected | 2 ++ .../integration-tests/qltest/{test.py => test_qltest.py} | 7 ++++--- 7 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 rust/ql/integration-tests/qltest/dependencies/functions.expected create mode 100644 rust/ql/integration-tests/qltest/dependencies/functions.nested.expected delete mode 100644 rust/ql/integration-tests/qltest/lib/functions.expected create mode 100644 rust/ql/integration-tests/qltest/lib/functions.nested.expected delete mode 100644 rust/ql/integration-tests/qltest/main/functions.expected create mode 100644 rust/ql/integration-tests/qltest/main/functions.nested.expected rename rust/ql/integration-tests/qltest/{test.py => test_qltest.py} (81%) diff --git a/rust/ql/integration-tests/qltest/dependencies/functions.expected b/rust/ql/integration-tests/qltest/dependencies/functions.expected deleted file mode 100644 index c062595f923..00000000000 --- a/rust/ql/integration-tests/qltest/dependencies/functions.expected +++ /dev/null @@ -1 +0,0 @@ -| test.rs:4:1:7:1 | foo | diff --git a/rust/ql/integration-tests/qltest/dependencies/functions.nested.expected b/rust/ql/integration-tests/qltest/dependencies/functions.nested.expected new file mode 100644 index 00000000000..9ee4b080b97 --- /dev/null +++ b/rust/ql/integration-tests/qltest/dependencies/functions.nested.expected @@ -0,0 +1 @@ +| test.rs:4:1:7:1 | fn foo | diff --git a/rust/ql/integration-tests/qltest/lib/functions.expected b/rust/ql/integration-tests/qltest/lib/functions.expected deleted file mode 100644 index 613d53954dc..00000000000 --- a/rust/ql/integration-tests/qltest/lib/functions.expected +++ /dev/null @@ -1 +0,0 @@ -| test.rs:1:1:1:11 | foo | diff --git a/rust/ql/integration-tests/qltest/lib/functions.nested.expected b/rust/ql/integration-tests/qltest/lib/functions.nested.expected new file mode 100644 index 00000000000..74d1d680dae --- /dev/null +++ b/rust/ql/integration-tests/qltest/lib/functions.nested.expected @@ -0,0 +1 @@ +| test.rs:1:1:1:11 | fn foo | diff --git a/rust/ql/integration-tests/qltest/main/functions.expected b/rust/ql/integration-tests/qltest/main/functions.expected deleted file mode 100644 index 9d363103419..00000000000 --- a/rust/ql/integration-tests/qltest/main/functions.expected +++ /dev/null @@ -1,2 +0,0 @@ -| main.rs:1:1:1:12 | main | -| test.rs:1:1:1:11 | foo | diff --git a/rust/ql/integration-tests/qltest/main/functions.nested.expected b/rust/ql/integration-tests/qltest/main/functions.nested.expected new file mode 100644 index 00000000000..fc9c578919c --- /dev/null +++ b/rust/ql/integration-tests/qltest/main/functions.nested.expected @@ -0,0 +1,2 @@ +| main.rs:1:1:1:12 | fn main | +| test.rs:1:1:1:11 | fn foo | diff --git a/rust/ql/integration-tests/qltest/test.py b/rust/ql/integration-tests/qltest/test_qltest.py similarity index 81% rename from rust/ql/integration-tests/qltest/test.py rename to rust/ql/integration-tests/qltest/test_qltest.py index d130d5d2ff1..edd62bf600e 100644 --- a/rust/ql/integration-tests/qltest/test.py +++ b/rust/ql/integration-tests/qltest/test_qltest.py @@ -6,16 +6,17 @@ import pytest # (which skips `qltest.{sh,cmd}`) @pytest.fixture(autouse=True) -def default_options(codeql, pytestconfig): +def default_options(codeql): codeql.flags.update( threads = 1, show_extractor_output = True, check_databases = False, - learn = pytestconfig.getoption("learn"), + learn = True, ) @pytest.mark.parametrize("dir", ["lib", "main", "dependencies"]) -def test(codeql, rust, dir): +def test(codeql, rust, expected_files, dir): + expected_files.add(f"{dir}/functions.expected", expected=".nested.expected") codeql.test.run(dir) def test_failing_cargo_check(codeql, rust): From 57973df795385fd52d276b1058bc9614b1b822cc Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 20 Nov 2024 10:00:10 +0100 Subject: [PATCH 111/470] Rust: make `CallExpr.toString` use call identifier if present --- .../rust/elements/internal/CallExprImpl.qll | 12 +- .../AwaitExpr/AwaitExpr_getExpr.expected | 2 +- .../BecomeExpr/BecomeExpr_getExpr.expected | 2 +- .../generated/CallExpr/CallExpr.expected | 8 +- .../CallExpr/CallExpr_getArgList.expected | 8 +- .../CallExpr/CallExpr_getExpr.expected | 8 +- .../ExprStmt/ExprStmt_getExpr.expected | 4 +- .../LetStmt/LetStmt_getInitializer.expected | 2 +- .../dataflow/global/viableCallable.expected | 42 +- .../dataflow/local/DataFlowStep.expected | 22 +- .../dataflow/local/inline-flow.expected | 26 +- .../test/library-tests/variables/Cfg.expected | 1450 ++++++++--------- .../test/library-tests/variables/Ssa.expected | 8 +- .../variables/variables.expected | 470 +----- 14 files changed, 793 insertions(+), 1271 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll index 8b0ae58e2d9..4cf0272c008 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll @@ -5,6 +5,7 @@ */ private import codeql.rust.elements.internal.generated.CallExpr +private import codeql.rust.elements.PathExpr /** * INTERNAL: This module contains the customizable definition of `CallExpr` and should not @@ -22,6 +23,15 @@ module Impl { * ``` */ class CallExpr extends Generated::CallExpr { - override string toString() { result = "... (...)" } + override string toString() { + exists(string callee | + ( + callee = this.getExpr().(PathExpr).toString() + or + not this.getExpr() instanceof PathExpr and callee = "..." + ) and + result = callee + "(...)" + ) + } } } diff --git a/rust/ql/test/extractor-tests/generated/AwaitExpr/AwaitExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/AwaitExpr/AwaitExpr_getExpr.expected index 528d6f097a0..a1ea7809bb0 100644 --- a/rust/ql/test/extractor-tests/generated/AwaitExpr/AwaitExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/AwaitExpr/AwaitExpr_getExpr.expected @@ -1 +1 @@ -| gen_await_expr.rs:6:17:6:27 | await ... | gen_await_expr.rs:6:17:6:21 | ... (...) | +| gen_await_expr.rs:6:17:6:27 | await ... | gen_await_expr.rs:6:17:6:21 | foo(...) | diff --git a/rust/ql/test/extractor-tests/generated/BecomeExpr/BecomeExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/BecomeExpr/BecomeExpr_getExpr.expected index 4fbba61bc8c..d0cb86a0303 100644 --- a/rust/ql/test/extractor-tests/generated/BecomeExpr/BecomeExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/BecomeExpr/BecomeExpr_getExpr.expected @@ -1 +1 @@ -| gen_become_expr.rs:8:10:8:36 | become ... | gen_become_expr.rs:8:17:8:36 | ... (...) | +| gen_become_expr.rs:8:10:8:36 | become ... | gen_become_expr.rs:8:17:8:36 | fact_a(...) | diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected index 9e01b6bdc63..a3f108b5584 100644 --- a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected @@ -1,4 +1,4 @@ -| gen_call_expr.rs:5:5:5:11 | ... (...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | -| gen_call_expr.rs:6:5:6:23 | ... (...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | -| gen_call_expr.rs:7:5:7:14 | ... (...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | -| gen_call_expr.rs:8:5:8:10 | ... (...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | +| gen_call_expr.rs:5:5:5:11 | foo(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | +| gen_call_expr.rs:6:5:6:23 | foo::<...>(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | +| gen_call_expr.rs:7:5:7:14 | ...(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | +| gen_call_expr.rs:8:5:8:10 | foo(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getArgList.expected b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getArgList.expected index 1876a5b58d8..13c426db99d 100644 --- a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getArgList.expected +++ b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getArgList.expected @@ -1,4 +1,4 @@ -| gen_call_expr.rs:5:5:5:11 | ... (...) | gen_call_expr.rs:5:8:5:11 | ArgList | -| gen_call_expr.rs:6:5:6:23 | ... (...) | gen_call_expr.rs:6:20:6:23 | ArgList | -| gen_call_expr.rs:7:5:7:14 | ... (...) | gen_call_expr.rs:7:11:7:14 | ArgList | -| gen_call_expr.rs:8:5:8:10 | ... (...) | gen_call_expr.rs:8:8:8:10 | ArgList | +| gen_call_expr.rs:5:5:5:11 | foo(...) | gen_call_expr.rs:5:8:5:11 | ArgList | +| gen_call_expr.rs:6:5:6:23 | foo::<...>(...) | gen_call_expr.rs:6:20:6:23 | ArgList | +| gen_call_expr.rs:7:5:7:14 | ...(...) | gen_call_expr.rs:7:11:7:14 | ArgList | +| gen_call_expr.rs:8:5:8:10 | foo(...) | gen_call_expr.rs:8:8:8:10 | ArgList | diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.expected index 017a4656ffd..68113cf5725 100644 --- a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.expected @@ -1,4 +1,4 @@ -| gen_call_expr.rs:5:5:5:11 | ... (...) | gen_call_expr.rs:5:5:5:7 | foo | -| gen_call_expr.rs:6:5:6:23 | ... (...) | gen_call_expr.rs:6:5:6:19 | foo::<...> | -| gen_call_expr.rs:7:5:7:14 | ... (...) | gen_call_expr.rs:7:5:7:10 | ...[...] | -| gen_call_expr.rs:8:5:8:10 | ... (...) | gen_call_expr.rs:8:5:8:7 | foo | +| gen_call_expr.rs:5:5:5:11 | foo(...) | gen_call_expr.rs:5:5:5:7 | foo | +| gen_call_expr.rs:6:5:6:23 | foo::<...>(...) | gen_call_expr.rs:6:5:6:19 | foo::<...> | +| gen_call_expr.rs:7:5:7:14 | ...(...) | gen_call_expr.rs:7:5:7:10 | ...[...] | +| gen_call_expr.rs:8:5:8:10 | foo(...) | gen_call_expr.rs:8:5:8:7 | foo | diff --git a/rust/ql/test/extractor-tests/generated/ExprStmt/ExprStmt_getExpr.expected b/rust/ql/test/extractor-tests/generated/ExprStmt/ExprStmt_getExpr.expected index 08343b7e1e9..1cacf1e8424 100644 --- a/rust/ql/test/extractor-tests/generated/ExprStmt/ExprStmt_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/ExprStmt/ExprStmt_getExpr.expected @@ -1,2 +1,2 @@ -| gen_expr_stmt.rs:5:5:5:12 | ExprStmt | gen_expr_stmt.rs:5:5:5:11 | ... (...) | -| gen_expr_stmt.rs:6:5:6:13 | ExprStmt | gen_expr_stmt.rs:6:5:6:12 | ... (...) | +| gen_expr_stmt.rs:5:5:5:12 | ExprStmt | gen_expr_stmt.rs:5:5:5:11 | start(...) | +| gen_expr_stmt.rs:6:5:6:13 | ExprStmt | gen_expr_stmt.rs:6:5:6:12 | finish(...) | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected index 07b474609f7..a7323b834b3 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected @@ -1,4 +1,4 @@ | gen_let_stmt.rs:5:5:5:15 | let x = ... | gen_let_stmt.rs:5:13:5:14 | 42 | | gen_let_stmt.rs:6:5:6:20 | let x = ... | gen_let_stmt.rs:6:18:6:19 | 42 | | gen_let_stmt.rs:9:5:9:24 | let TuplePat = ... | gen_let_stmt.rs:9:18:9:23 | TupleExpr | -| gen_let_stmt.rs:10:5:12:6 | let TupleStructPat = ... else { ... } | gen_let_stmt.rs:10:19:10:38 | ... (...) | +| gen_let_stmt.rs:10:5:12:6 | let TupleStructPat = ... else { ... } | gen_let_stmt.rs:10:19:10:38 | std::env::var(...) | diff --git a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected index 0739d922d8d..28e43535c79 100644 --- a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected +++ b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected @@ -1,24 +1,24 @@ -| main.rs:13:5:13:13 | ... (...) | main.rs:1:1:3:1 | fn source | -| main.rs:17:13:17:23 | ... (...) | main.rs:12:1:14:1 | fn get_data | -| main.rs:18:5:18:11 | ... (...) | main.rs:5:1:7:1 | fn sink | -| main.rs:22:5:22:15 | ... (...) | main.rs:5:1:7:1 | fn sink | -| main.rs:26:13:26:21 | ... (...) | main.rs:1:1:3:1 | fn source | -| main.rs:27:5:27:14 | ... (...) | main.rs:21:1:23:1 | fn data_in | -| main.rs:35:13:35:21 | ... (...) | main.rs:1:1:3:1 | fn source | -| main.rs:36:13:36:27 | ... (...) | main.rs:30:1:32:1 | fn pass_through | -| main.rs:37:5:37:11 | ... (...) | main.rs:5:1:7:1 | fn sink | -| main.rs:49:9:49:15 | ... (...) | main.rs:5:1:7:1 | fn sink | -| main.rs:55:13:55:21 | ... (...) | main.rs:1:1:3:1 | fn source | +| main.rs:13:5:13:13 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:17:13:17:23 | get_data(...) | main.rs:12:1:14:1 | fn get_data | +| main.rs:18:5:18:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:22:5:22:15 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:26:13:26:21 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:27:5:27:14 | data_in(...) | main.rs:21:1:23:1 | fn data_in | +| main.rs:35:13:35:21 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:36:13:36:27 | pass_through(...) | main.rs:30:1:32:1 | fn pass_through | +| main.rs:37:5:37:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:49:9:49:15 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:55:13:55:21 | source(...) | main.rs:1:1:3:1 | fn source | | main.rs:69:13:69:25 | ... .get_data(...) | main.rs:51:5:57:5 | fn get_data | -| main.rs:70:5:70:11 | ... (...) | main.rs:5:1:7:1 | fn sink | -| main.rs:75:13:75:21 | ... (...) | main.rs:1:1:3:1 | fn source | +| main.rs:70:5:70:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:75:13:75:21 | source(...) | main.rs:1:1:3:1 | fn source | | main.rs:76:5:76:17 | ... .data_in(...) | main.rs:48:5:50:5 | fn data_in | -| main.rs:81:13:81:21 | ... (...) | main.rs:1:1:3:1 | fn source | +| main.rs:81:13:81:21 | source(...) | main.rs:1:1:3:1 | fn source | | main.rs:82:5:82:22 | ... .data_through(...) | main.rs:58:5:64:5 | fn data_through | -| main.rs:83:5:83:11 | ... (...) | main.rs:5:1:7:1 | fn sink | -| main.rs:87:5:87:22 | ... (...) | main.rs:16:1:19:1 | fn data_out_of_call | -| main.rs:88:5:88:21 | ... (...) | main.rs:25:1:28:1 | fn data_in_to_call | -| main.rs:89:5:89:23 | ... (...) | main.rs:34:1:38:1 | fn data_through_call | -| main.rs:91:5:91:24 | ... (...) | main.rs:67:1:71:1 | fn data_out_of_method | -| main.rs:92:5:92:28 | ... (...) | main.rs:73:1:77:1 | fn data_in_to_method_call | -| main.rs:93:5:93:25 | ... (...) | main.rs:79:1:84:1 | fn data_through_method | +| main.rs:83:5:83:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:87:5:87:22 | data_out_of_call(...) | main.rs:16:1:19:1 | fn data_out_of_call | +| main.rs:88:5:88:21 | data_in_to_call(...) | main.rs:25:1:28:1 | fn data_in_to_call | +| main.rs:89:5:89:23 | data_through_call(...) | main.rs:34:1:38:1 | fn data_through_call | +| main.rs:91:5:91:24 | data_out_of_method(...) | main.rs:67:1:71:1 | fn data_out_of_method | +| main.rs:92:5:92:28 | data_in_to_method_call(...) | main.rs:73:1:77:1 | fn data_in_to_method_call | +| main.rs:93:5:93:25 | data_through_method(...) | main.rs:79:1:84:1 | fn data_through_method | diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index ecce48be804..e12f2e14d19 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -5,12 +5,12 @@ | main.rs:7:9:7:9 | s | main.rs:7:9:7:9 | [SSA] s | | main.rs:19:9:19:9 | [SSA] s | main.rs:20:10:20:10 | s | | main.rs:19:9:19:9 | s | main.rs:19:9:19:9 | [SSA] s | -| main.rs:19:13:19:21 | ... (...) | main.rs:19:9:19:9 | s | +| main.rs:19:13:19:21 | source(...) | main.rs:19:9:19:9 | s | | main.rs:23:18:23:21 | [SSA] cond | main.rs:26:16:26:19 | cond | | main.rs:23:18:23:21 | cond | main.rs:23:18:23:21 | [SSA] cond | | main.rs:24:9:24:9 | [SSA] a | main.rs:26:23:26:23 | a | | main.rs:24:9:24:9 | a | main.rs:24:9:24:9 | [SSA] a | -| main.rs:24:13:24:21 | ... (...) | main.rs:24:9:24:9 | a | +| main.rs:24:13:24:21 | source(...) | main.rs:24:9:24:9 | a | | main.rs:25:9:25:9 | [SSA] b | main.rs:26:34:26:34 | b | | main.rs:25:9:25:9 | b | main.rs:25:9:25:9 | [SSA] b | | main.rs:25:13:25:13 | 2 | main.rs:25:9:25:9 | b | @@ -25,7 +25,7 @@ | main.rs:30:21:30:21 | m | main.rs:30:21:30:21 | [SSA] m | | main.rs:31:9:31:9 | [SSA] a | main.rs:33:20:33:20 | a | | main.rs:31:9:31:9 | a | main.rs:31:9:31:9 | [SSA] a | -| main.rs:31:13:31:21 | ... (...) | main.rs:31:9:31:9 | a | +| main.rs:31:13:31:21 | source(...) | main.rs:31:9:31:9 | a | | main.rs:32:9:32:9 | [SSA] b | main.rs:36:10:36:10 | b | | main.rs:32:9:32:9 | b | main.rs:32:9:32:9 | [SSA] b | | main.rs:32:13:35:5 | match ... { ... } | main.rs:32:9:32:9 | b | @@ -40,7 +40,7 @@ | main.rs:44:9:44:9 | b | main.rs:44:9:44:9 | [SSA] b | | main.rs:44:13:46:5 | loop {...} | main.rs:44:9:44:9 | b | | main.rs:45:9:45:23 | (no string representation) | main.rs:44:13:46:5 | loop {...} | -| main.rs:45:15:45:23 | ... (...) | main.rs:45:9:45:23 | (no string representation) | +| main.rs:45:15:45:23 | source(...) | main.rs:45:9:45:23 | (no string representation) | | main.rs:51:9:51:13 | [SSA] i | main.rs:52:10:52:10 | i | | main.rs:51:9:51:13 | i | main.rs:51:9:51:13 | [SSA] i | | main.rs:51:17:51:17 | 1 | main.rs:51:9:51:13 | i | @@ -48,7 +48,7 @@ | main.rs:53:5:53:5 | i | main.rs:53:5:53:5 | [SSA] i | | main.rs:61:9:61:9 | [SSA] i | main.rs:62:11:62:11 | i | | main.rs:61:9:61:9 | i | main.rs:61:9:61:9 | [SSA] i | -| main.rs:61:13:61:31 | ... (...) | main.rs:61:9:61:9 | i | +| main.rs:61:13:61:31 | Box::new(...) | main.rs:61:9:61:9 | i | | main.rs:66:9:66:9 | [SSA] a | main.rs:67:10:67:10 | a | | main.rs:66:9:66:9 | a | main.rs:66:9:66:9 | [SSA] a | | main.rs:66:13:66:26 | TupleExpr | main.rs:66:9:66:9 | a | @@ -70,16 +70,16 @@ | main.rs:97:38:97:38 | p | main.rs:97:9:97:34 | Point {...} | | main.rs:104:9:104:10 | [SSA] s1 | main.rs:106:11:106:12 | s1 | | main.rs:104:9:104:10 | s1 | main.rs:104:9:104:10 | [SSA] s1 | -| main.rs:104:14:104:28 | ... (...) | main.rs:104:9:104:10 | s1 | +| main.rs:104:14:104:28 | Some(...) | main.rs:104:9:104:10 | s1 | | main.rs:105:9:105:10 | [SSA] s2 | main.rs:110:11:110:12 | s2 | | main.rs:105:9:105:10 | s2 | main.rs:105:9:105:10 | [SSA] s2 | -| main.rs:105:14:105:20 | ... (...) | main.rs:105:9:105:10 | s2 | +| main.rs:105:14:105:20 | Some(...) | main.rs:105:9:105:10 | s2 | | main.rs:107:14:107:14 | [SSA] n | main.rs:107:25:107:25 | n | | main.rs:107:14:107:14 | n | main.rs:107:14:107:14 | [SSA] n | -| main.rs:107:20:107:26 | ... (...) | main.rs:106:5:109:5 | match ... { ... } | -| main.rs:108:17:108:23 | ... (...) | main.rs:106:5:109:5 | match ... { ... } | +| main.rs:107:20:107:26 | sink(...) | main.rs:106:5:109:5 | match ... { ... } | +| main.rs:108:17:108:23 | sink(...) | main.rs:106:5:109:5 | match ... { ... } | | main.rs:110:5:113:5 | match ... { ... } | main.rs:103:27:114:1 | { ... } | | main.rs:111:14:111:14 | [SSA] n | main.rs:111:25:111:25 | n | | main.rs:111:14:111:14 | n | main.rs:111:14:111:14 | [SSA] n | -| main.rs:111:20:111:26 | ... (...) | main.rs:110:5:113:5 | match ... { ... } | -| main.rs:112:17:112:23 | ... (...) | main.rs:110:5:113:5 | match ... { ... } | +| main.rs:111:20:111:26 | sink(...) | main.rs:110:5:113:5 | match ... { ... } | +| main.rs:112:17:112:23 | sink(...) | main.rs:110:5:113:5 | match ... { ... } | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index 72273334c6f..ea439e78d5b 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -1,24 +1,2 @@ -models -edges -| main.rs:19:13:19:21 | CallExpr : unit | main.rs:20:10:20:10 | s | provenance | | -| main.rs:24:13:24:21 | CallExpr : unit | main.rs:27:10:27:10 | c | provenance | | -| main.rs:31:13:31:21 | CallExpr : unit | main.rs:36:10:36:10 | b | provenance | | -| main.rs:45:15:45:23 | CallExpr : unit | main.rs:47:10:47:10 | b | provenance | | -nodes -| main.rs:15:10:15:18 | CallExpr | semmle.label | CallExpr | -| main.rs:19:13:19:21 | CallExpr : unit | semmle.label | CallExpr : unit | -| main.rs:20:10:20:10 | s | semmle.label | s | -| main.rs:24:13:24:21 | CallExpr : unit | semmle.label | CallExpr : unit | -| main.rs:27:10:27:10 | c | semmle.label | c | -| main.rs:31:13:31:21 | CallExpr : unit | semmle.label | CallExpr : unit | -| main.rs:36:10:36:10 | b | semmle.label | b | -| main.rs:45:15:45:23 | CallExpr : unit | semmle.label | CallExpr : unit | -| main.rs:47:10:47:10 | b | semmle.label | b | -subpaths -testFailures -#select -| main.rs:15:10:15:18 | CallExpr | main.rs:15:10:15:18 | CallExpr | main.rs:15:10:15:18 | CallExpr | $@ | main.rs:15:10:15:18 | CallExpr | CallExpr | -| main.rs:20:10:20:10 | s | main.rs:19:13:19:21 | CallExpr : unit | main.rs:20:10:20:10 | s | $@ | main.rs:19:13:19:21 | CallExpr : unit | CallExpr : unit | -| main.rs:27:10:27:10 | c | main.rs:24:13:24:21 | CallExpr : unit | main.rs:27:10:27:10 | c | $@ | main.rs:24:13:24:21 | CallExpr : unit | CallExpr : unit | -| main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | CallExpr : unit | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | CallExpr : unit | CallExpr : unit | -| main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | CallExpr : unit | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | CallExpr : unit | CallExpr : unit | +ERROR: empty recursive call: dispatch predicate for CommentImpl::Impl::Comment::getCommentMarker (CommentImpl.qll:23,47-63) +ERROR: empty recursive call: dispatch predicate for CommentImpl::Impl::Comment::getText (CommentImpl.qll:36,34-41) diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected index 3ff46aa9f7e..338af96a7c4 100644 --- a/rust/ql/test/library-tests/variables/Cfg.expected +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -1,292 +1,292 @@ edges -| variables.rs:3:1:5:1 | enter print_str | variables.rs:3:14:3:14 | s | | -| variables.rs:3:1:5:1 | exit print_str (normal) | variables.rs:3:1:5:1 | exit print_str | | -| variables.rs:3:14:3:14 | s | variables.rs:3:14:3:20 | Param | match | -| variables.rs:3:14:3:20 | Param | variables.rs:4:5:4:22 | ExprStmt | | -| variables.rs:3:23:5:1 | BlockExpr | variables.rs:3:1:5:1 | exit print_str (normal) | | +| variables.rs:3:1:5:1 | enter fn print_str | variables.rs:3:14:3:14 | s | | +| variables.rs:3:1:5:1 | exit fn print_str (normal) | variables.rs:3:1:5:1 | exit fn print_str | | +| variables.rs:3:14:3:14 | s | variables.rs:3:14:3:20 | s: RefType | match | +| variables.rs:3:14:3:20 | s: RefType | variables.rs:4:5:4:22 | ExprStmt | | +| variables.rs:3:23:5:1 | { ... } | variables.rs:3:1:5:1 | exit fn print_str (normal) | | | variables.rs:4:5:4:21 | $crate::io::_print | variables.rs:4:14:4:17 | "{}\\n" | | -| variables.rs:4:5:4:21 | MacroExpr | variables.rs:3:23:5:1 | BlockExpr | | +| variables.rs:4:5:4:21 | MacroExpr | variables.rs:3:23:5:1 | { ... } | | | variables.rs:4:5:4:22 | ExprStmt | variables.rs:4:14:4:20 | MacroStmts | | | variables.rs:4:14:4:17 | "{}\\n" | variables.rs:4:20:4:20 | s | | -| variables.rs:4:14:4:20 | BlockExpr | variables.rs:4:5:4:21 | MacroExpr | | -| variables.rs:4:14:4:20 | CallExpr | variables.rs:4:14:4:20 | BlockExpr | | +| variables.rs:4:14:4:20 | $crate::io::_print(...) | variables.rs:4:14:4:20 | { ... } | | | variables.rs:4:14:4:20 | ExprStmt | variables.rs:4:5:4:21 | $crate::io::_print | | | variables.rs:4:14:4:20 | FormatArgsExpr | variables.rs:4:14:4:20 | MacroExpr | | -| variables.rs:4:14:4:20 | MacroExpr | variables.rs:4:14:4:20 | CallExpr | | +| variables.rs:4:14:4:20 | MacroExpr | variables.rs:4:14:4:20 | $crate::io::_print(...) | | | variables.rs:4:14:4:20 | MacroStmts | variables.rs:4:14:4:20 | ExprStmt | | +| variables.rs:4:14:4:20 | { ... } | variables.rs:4:5:4:21 | MacroExpr | | | variables.rs:4:20:4:20 | s | variables.rs:4:14:4:20 | FormatArgsExpr | | -| variables.rs:7:1:9:1 | enter print_i64 | variables.rs:7:14:7:14 | i | | -| variables.rs:7:1:9:1 | exit print_i64 (normal) | variables.rs:7:1:9:1 | exit print_i64 | | -| variables.rs:7:14:7:14 | i | variables.rs:7:14:7:19 | Param | match | -| variables.rs:7:14:7:19 | Param | variables.rs:8:5:8:22 | ExprStmt | | -| variables.rs:7:22:9:1 | BlockExpr | variables.rs:7:1:9:1 | exit print_i64 (normal) | | +| variables.rs:7:1:9:1 | enter fn print_i64 | variables.rs:7:14:7:14 | i | | +| variables.rs:7:1:9:1 | exit fn print_i64 (normal) | variables.rs:7:1:9:1 | exit fn print_i64 | | +| variables.rs:7:14:7:14 | i | variables.rs:7:14:7:19 | i: i64 | match | +| variables.rs:7:14:7:19 | i: i64 | variables.rs:8:5:8:22 | ExprStmt | | +| variables.rs:7:22:9:1 | { ... } | variables.rs:7:1:9:1 | exit fn print_i64 (normal) | | | variables.rs:8:5:8:21 | $crate::io::_print | variables.rs:8:14:8:17 | "{}\\n" | | -| variables.rs:8:5:8:21 | MacroExpr | variables.rs:7:22:9:1 | BlockExpr | | +| variables.rs:8:5:8:21 | MacroExpr | variables.rs:7:22:9:1 | { ... } | | | variables.rs:8:5:8:22 | ExprStmt | variables.rs:8:14:8:20 | MacroStmts | | | variables.rs:8:14:8:17 | "{}\\n" | variables.rs:8:20:8:20 | i | | -| variables.rs:8:14:8:20 | BlockExpr | variables.rs:8:5:8:21 | MacroExpr | | -| variables.rs:8:14:8:20 | CallExpr | variables.rs:8:14:8:20 | BlockExpr | | +| variables.rs:8:14:8:20 | $crate::io::_print(...) | variables.rs:8:14:8:20 | { ... } | | | variables.rs:8:14:8:20 | ExprStmt | variables.rs:8:5:8:21 | $crate::io::_print | | | variables.rs:8:14:8:20 | FormatArgsExpr | variables.rs:8:14:8:20 | MacroExpr | | -| variables.rs:8:14:8:20 | MacroExpr | variables.rs:8:14:8:20 | CallExpr | | +| variables.rs:8:14:8:20 | MacroExpr | variables.rs:8:14:8:20 | $crate::io::_print(...) | | | variables.rs:8:14:8:20 | MacroStmts | variables.rs:8:14:8:20 | ExprStmt | | +| variables.rs:8:14:8:20 | { ... } | variables.rs:8:5:8:21 | MacroExpr | | | variables.rs:8:20:8:20 | i | variables.rs:8:14:8:20 | FormatArgsExpr | | -| variables.rs:11:1:13:1 | enter print_i64_ref | variables.rs:11:18:11:18 | i | | -| variables.rs:11:1:13:1 | exit print_i64_ref (normal) | variables.rs:11:1:13:1 | exit print_i64_ref | | -| variables.rs:11:18:11:18 | i | variables.rs:11:18:11:24 | Param | match | -| variables.rs:11:18:11:24 | Param | variables.rs:12:5:12:13 | print_i64 | | -| variables.rs:11:27:13:1 | BlockExpr | variables.rs:11:1:13:1 | exit print_i64_ref (normal) | | +| variables.rs:11:1:13:1 | enter fn print_i64_ref | variables.rs:11:18:11:18 | i | | +| variables.rs:11:1:13:1 | exit fn print_i64_ref (normal) | variables.rs:11:1:13:1 | exit fn print_i64_ref | | +| variables.rs:11:18:11:18 | i | variables.rs:11:18:11:24 | i: RefType | match | +| variables.rs:11:18:11:24 | i: RefType | variables.rs:12:5:12:13 | print_i64 | | +| variables.rs:11:27:13:1 | { ... } | variables.rs:11:1:13:1 | exit fn print_i64_ref (normal) | | | variables.rs:12:5:12:13 | print_i64 | variables.rs:12:16:12:16 | i | | -| variables.rs:12:5:12:17 | CallExpr | variables.rs:11:27:13:1 | BlockExpr | | -| variables.rs:12:15:12:16 | * ... | variables.rs:12:5:12:17 | CallExpr | | +| variables.rs:12:5:12:17 | print_i64(...) | variables.rs:11:27:13:1 | { ... } | | +| variables.rs:12:15:12:16 | * ... | variables.rs:12:5:12:17 | print_i64(...) | | | variables.rs:12:16:12:16 | i | variables.rs:12:15:12:16 | * ... | | -| variables.rs:15:1:18:1 | enter immutable_variable | variables.rs:16:5:16:17 | LetStmt | | -| variables.rs:15:1:18:1 | exit immutable_variable (normal) | variables.rs:15:1:18:1 | exit immutable_variable | | -| variables.rs:15:25:18:1 | BlockExpr | variables.rs:15:1:18:1 | exit immutable_variable (normal) | | -| variables.rs:16:5:16:17 | LetStmt | variables.rs:16:14:16:16 | "a" | | +| variables.rs:15:1:18:1 | enter fn immutable_variable | variables.rs:16:5:16:17 | let x1 = ... | | +| variables.rs:15:1:18:1 | exit fn immutable_variable (normal) | variables.rs:15:1:18:1 | exit fn immutable_variable | | +| variables.rs:15:25:18:1 | { ... } | variables.rs:15:1:18:1 | exit fn immutable_variable (normal) | | +| variables.rs:16:5:16:17 | let x1 = ... | variables.rs:16:14:16:16 | "a" | | | variables.rs:16:9:16:10 | x1 | variables.rs:17:5:17:18 | ExprStmt | match | | variables.rs:16:14:16:16 | "a" | variables.rs:16:9:16:10 | x1 | | | variables.rs:17:5:17:13 | print_str | variables.rs:17:15:17:16 | x1 | | -| variables.rs:17:5:17:17 | CallExpr | variables.rs:15:25:18:1 | BlockExpr | | +| variables.rs:17:5:17:17 | print_str(...) | variables.rs:15:25:18:1 | { ... } | | | variables.rs:17:5:17:18 | ExprStmt | variables.rs:17:5:17:13 | print_str | | -| variables.rs:17:15:17:16 | x1 | variables.rs:17:5:17:17 | CallExpr | | -| variables.rs:20:1:25:1 | enter mutable_variable | variables.rs:21:5:21:19 | LetStmt | | -| variables.rs:20:1:25:1 | exit mutable_variable (normal) | variables.rs:20:1:25:1 | exit mutable_variable | | -| variables.rs:20:23:25:1 | BlockExpr | variables.rs:20:1:25:1 | exit mutable_variable (normal) | | -| variables.rs:21:5:21:19 | LetStmt | variables.rs:21:18:21:18 | 4 | | +| variables.rs:17:15:17:16 | x1 | variables.rs:17:5:17:17 | print_str(...) | | +| variables.rs:20:1:25:1 | enter fn mutable_variable | variables.rs:21:5:21:19 | let x2 = ... | | +| variables.rs:20:1:25:1 | exit fn mutable_variable (normal) | variables.rs:20:1:25:1 | exit fn mutable_variable | | +| variables.rs:20:23:25:1 | { ... } | variables.rs:20:1:25:1 | exit fn mutable_variable (normal) | | +| variables.rs:21:5:21:19 | let x2 = ... | variables.rs:21:18:21:18 | 4 | | | variables.rs:21:9:21:14 | x2 | variables.rs:22:5:22:18 | ExprStmt | match | | variables.rs:21:18:21:18 | 4 | variables.rs:21:9:21:14 | x2 | | | variables.rs:22:5:22:13 | print_i64 | variables.rs:22:15:22:16 | x2 | | -| variables.rs:22:5:22:17 | CallExpr | variables.rs:23:5:23:11 | ExprStmt | | +| variables.rs:22:5:22:17 | print_i64(...) | variables.rs:23:5:23:11 | ExprStmt | | | variables.rs:22:5:22:18 | ExprStmt | variables.rs:22:5:22:13 | print_i64 | | -| variables.rs:22:15:22:16 | x2 | variables.rs:22:5:22:17 | CallExpr | | +| variables.rs:22:15:22:16 | x2 | variables.rs:22:5:22:17 | print_i64(...) | | | variables.rs:23:5:23:6 | x2 | variables.rs:23:10:23:10 | 5 | | | variables.rs:23:5:23:10 | ... = ... | variables.rs:24:5:24:18 | ExprStmt | | | variables.rs:23:5:23:11 | ExprStmt | variables.rs:23:5:23:6 | x2 | | | variables.rs:23:10:23:10 | 5 | variables.rs:23:5:23:10 | ... = ... | | | variables.rs:24:5:24:13 | print_i64 | variables.rs:24:15:24:16 | x2 | | -| variables.rs:24:5:24:17 | CallExpr | variables.rs:20:23:25:1 | BlockExpr | | +| variables.rs:24:5:24:17 | print_i64(...) | variables.rs:20:23:25:1 | { ... } | | | variables.rs:24:5:24:18 | ExprStmt | variables.rs:24:5:24:13 | print_i64 | | -| variables.rs:24:15:24:16 | x2 | variables.rs:24:5:24:17 | CallExpr | | -| variables.rs:27:1:32:1 | enter mutable_variable_immutable_borrow | variables.rs:28:5:28:18 | LetStmt | | -| variables.rs:27:1:32:1 | exit mutable_variable_immutable_borrow (normal) | variables.rs:27:1:32:1 | exit mutable_variable_immutable_borrow | | -| variables.rs:27:40:32:1 | BlockExpr | variables.rs:27:1:32:1 | exit mutable_variable_immutable_borrow (normal) | | -| variables.rs:28:5:28:18 | LetStmt | variables.rs:28:17:28:17 | 1 | | +| variables.rs:24:15:24:16 | x2 | variables.rs:24:5:24:17 | print_i64(...) | | +| variables.rs:27:1:32:1 | enter fn mutable_variable_immutable_borrow | variables.rs:28:5:28:18 | let x = ... | | +| variables.rs:27:1:32:1 | exit fn mutable_variable_immutable_borrow (normal) | variables.rs:27:1:32:1 | exit fn mutable_variable_immutable_borrow | | +| variables.rs:27:40:32:1 | { ... } | variables.rs:27:1:32:1 | exit fn mutable_variable_immutable_borrow (normal) | | +| variables.rs:28:5:28:18 | let x = ... | variables.rs:28:17:28:17 | 1 | | | variables.rs:28:9:28:13 | x | variables.rs:29:5:29:22 | ExprStmt | match | | variables.rs:28:17:28:17 | 1 | variables.rs:28:9:28:13 | x | | | variables.rs:29:5:29:17 | print_i64_ref | variables.rs:29:20:29:20 | x | | -| variables.rs:29:5:29:21 | CallExpr | variables.rs:30:5:30:10 | ExprStmt | | +| variables.rs:29:5:29:21 | print_i64_ref(...) | variables.rs:30:5:30:10 | ExprStmt | | | variables.rs:29:5:29:22 | ExprStmt | variables.rs:29:5:29:17 | print_i64_ref | | -| variables.rs:29:19:29:20 | RefExpr | variables.rs:29:5:29:21 | CallExpr | | -| variables.rs:29:20:29:20 | x | variables.rs:29:19:29:20 | RefExpr | | +| variables.rs:29:19:29:20 | &... | variables.rs:29:5:29:21 | print_i64_ref(...) | | +| variables.rs:29:20:29:20 | x | variables.rs:29:19:29:20 | &... | | | variables.rs:30:5:30:5 | x | variables.rs:30:9:30:9 | 2 | | | variables.rs:30:5:30:9 | ... = ... | variables.rs:31:5:31:22 | ExprStmt | | | variables.rs:30:5:30:10 | ExprStmt | variables.rs:30:5:30:5 | x | | | variables.rs:30:9:30:9 | 2 | variables.rs:30:5:30:9 | ... = ... | | | variables.rs:31:5:31:17 | print_i64_ref | variables.rs:31:20:31:20 | x | | -| variables.rs:31:5:31:21 | CallExpr | variables.rs:27:40:32:1 | BlockExpr | | +| variables.rs:31:5:31:21 | print_i64_ref(...) | variables.rs:27:40:32:1 | { ... } | | | variables.rs:31:5:31:22 | ExprStmt | variables.rs:31:5:31:17 | print_i64_ref | | -| variables.rs:31:19:31:20 | RefExpr | variables.rs:31:5:31:21 | CallExpr | | -| variables.rs:31:20:31:20 | x | variables.rs:31:19:31:20 | RefExpr | | -| variables.rs:34:1:40:1 | enter variable_shadow1 | variables.rs:35:5:35:15 | LetStmt | | -| variables.rs:34:1:40:1 | exit variable_shadow1 (normal) | variables.rs:34:1:40:1 | exit variable_shadow1 | | -| variables.rs:34:23:40:1 | BlockExpr | variables.rs:34:1:40:1 | exit variable_shadow1 (normal) | | -| variables.rs:35:5:35:15 | LetStmt | variables.rs:35:14:35:14 | 1 | | +| variables.rs:31:19:31:20 | &... | variables.rs:31:5:31:21 | print_i64_ref(...) | | +| variables.rs:31:20:31:20 | x | variables.rs:31:19:31:20 | &... | | +| variables.rs:34:1:40:1 | enter fn variable_shadow1 | variables.rs:35:5:35:15 | let x3 = ... | | +| variables.rs:34:1:40:1 | exit fn variable_shadow1 (normal) | variables.rs:34:1:40:1 | exit fn variable_shadow1 | | +| variables.rs:34:23:40:1 | { ... } | variables.rs:34:1:40:1 | exit fn variable_shadow1 (normal) | | +| variables.rs:35:5:35:15 | let x3 = ... | variables.rs:35:14:35:14 | 1 | | | variables.rs:35:9:35:10 | x3 | variables.rs:36:5:36:18 | ExprStmt | match | | variables.rs:35:14:35:14 | 1 | variables.rs:35:9:35:10 | x3 | | | variables.rs:36:5:36:13 | print_i64 | variables.rs:36:15:36:16 | x3 | | -| variables.rs:36:5:36:17 | CallExpr | variables.rs:37:5:38:15 | LetStmt | | +| variables.rs:36:5:36:17 | print_i64(...) | variables.rs:37:5:38:15 | let x3 = ... | | | variables.rs:36:5:36:18 | ExprStmt | variables.rs:36:5:36:13 | print_i64 | | -| variables.rs:36:15:36:16 | x3 | variables.rs:36:5:36:17 | CallExpr | | -| variables.rs:37:5:38:15 | LetStmt | variables.rs:38:9:38:10 | x3 | | +| variables.rs:36:15:36:16 | x3 | variables.rs:36:5:36:17 | print_i64(...) | | +| variables.rs:37:5:38:15 | let x3 = ... | variables.rs:38:9:38:10 | x3 | | | variables.rs:37:9:37:10 | x3 | variables.rs:39:5:39:18 | ExprStmt | match | | variables.rs:38:9:38:10 | x3 | variables.rs:38:14:38:14 | 1 | | | variables.rs:38:9:38:14 | ... + ... | variables.rs:37:9:37:10 | x3 | | | variables.rs:38:14:38:14 | 1 | variables.rs:38:9:38:14 | ... + ... | | | variables.rs:39:5:39:13 | print_i64 | variables.rs:39:15:39:16 | x3 | | -| variables.rs:39:5:39:17 | CallExpr | variables.rs:34:23:40:1 | BlockExpr | | +| variables.rs:39:5:39:17 | print_i64(...) | variables.rs:34:23:40:1 | { ... } | | | variables.rs:39:5:39:18 | ExprStmt | variables.rs:39:5:39:13 | print_i64 | | -| variables.rs:39:15:39:16 | x3 | variables.rs:39:5:39:17 | CallExpr | | -| variables.rs:42:1:50:1 | enter variable_shadow2 | variables.rs:43:5:43:17 | LetStmt | | -| variables.rs:42:1:50:1 | exit variable_shadow2 (normal) | variables.rs:42:1:50:1 | exit variable_shadow2 | | -| variables.rs:42:23:50:1 | BlockExpr | variables.rs:42:1:50:1 | exit variable_shadow2 (normal) | | -| variables.rs:43:5:43:17 | LetStmt | variables.rs:43:14:43:16 | "a" | | +| variables.rs:39:15:39:16 | x3 | variables.rs:39:5:39:17 | print_i64(...) | | +| variables.rs:42:1:50:1 | enter fn variable_shadow2 | variables.rs:43:5:43:17 | let x4 = ... | | +| variables.rs:42:1:50:1 | exit fn variable_shadow2 (normal) | variables.rs:42:1:50:1 | exit fn variable_shadow2 | | +| variables.rs:42:23:50:1 | { ... } | variables.rs:42:1:50:1 | exit fn variable_shadow2 (normal) | | +| variables.rs:43:5:43:17 | let x4 = ... | variables.rs:43:14:43:16 | "a" | | | variables.rs:43:9:43:10 | x4 | variables.rs:44:5:44:18 | ExprStmt | match | | variables.rs:43:14:43:16 | "a" | variables.rs:43:9:43:10 | x4 | | | variables.rs:44:5:44:13 | print_str | variables.rs:44:15:44:16 | x4 | | -| variables.rs:44:5:44:17 | CallExpr | variables.rs:45:5:48:5 | ExprStmt | | +| variables.rs:44:5:44:17 | print_str(...) | variables.rs:45:5:48:5 | ExprStmt | | | variables.rs:44:5:44:18 | ExprStmt | variables.rs:44:5:44:13 | print_str | | -| variables.rs:44:15:44:16 | x4 | variables.rs:44:5:44:17 | CallExpr | | -| variables.rs:45:5:48:5 | BlockExpr | variables.rs:49:5:49:18 | ExprStmt | | -| variables.rs:45:5:48:5 | ExprStmt | variables.rs:46:9:46:21 | LetStmt | | -| variables.rs:46:9:46:21 | LetStmt | variables.rs:46:18:46:20 | "b" | | +| variables.rs:44:15:44:16 | x4 | variables.rs:44:5:44:17 | print_str(...) | | +| variables.rs:45:5:48:5 | ExprStmt | variables.rs:46:9:46:21 | let x4 = ... | | +| variables.rs:45:5:48:5 | { ... } | variables.rs:49:5:49:18 | ExprStmt | | +| variables.rs:46:9:46:21 | let x4 = ... | variables.rs:46:18:46:20 | "b" | | | variables.rs:46:13:46:14 | x4 | variables.rs:47:9:47:22 | ExprStmt | match | | variables.rs:46:18:46:20 | "b" | variables.rs:46:13:46:14 | x4 | | | variables.rs:47:9:47:17 | print_str | variables.rs:47:19:47:20 | x4 | | -| variables.rs:47:9:47:21 | CallExpr | variables.rs:45:5:48:5 | BlockExpr | | +| variables.rs:47:9:47:21 | print_str(...) | variables.rs:45:5:48:5 | { ... } | | | variables.rs:47:9:47:22 | ExprStmt | variables.rs:47:9:47:17 | print_str | | -| variables.rs:47:19:47:20 | x4 | variables.rs:47:9:47:21 | CallExpr | | +| variables.rs:47:19:47:20 | x4 | variables.rs:47:9:47:21 | print_str(...) | | | variables.rs:49:5:49:13 | print_str | variables.rs:49:15:49:16 | x4 | | -| variables.rs:49:5:49:17 | CallExpr | variables.rs:42:23:50:1 | BlockExpr | | +| variables.rs:49:5:49:17 | print_str(...) | variables.rs:42:23:50:1 | { ... } | | | variables.rs:49:5:49:18 | ExprStmt | variables.rs:49:5:49:13 | print_str | | -| variables.rs:49:15:49:16 | x4 | variables.rs:49:5:49:17 | CallExpr | | -| variables.rs:57:1:72:1 | enter let_pattern1 | variables.rs:58:5:67:47 | LetStmt | | -| variables.rs:57:1:72:1 | exit let_pattern1 (normal) | variables.rs:57:1:72:1 | exit let_pattern1 | | -| variables.rs:57:19:72:1 | BlockExpr | variables.rs:57:1:72:1 | exit let_pattern1 (normal) | | -| variables.rs:58:5:67:47 | LetStmt | variables.rs:67:11:67:13 | "a" | | +| variables.rs:49:15:49:16 | x4 | variables.rs:49:5:49:17 | print_str(...) | | +| variables.rs:57:1:72:1 | enter fn let_pattern1 | variables.rs:58:5:67:47 | let TuplePat = ... | | +| variables.rs:57:1:72:1 | exit fn let_pattern1 (normal) | variables.rs:57:1:72:1 | exit fn let_pattern1 | | +| variables.rs:57:19:72:1 | { ... } | variables.rs:57:1:72:1 | exit fn let_pattern1 (normal) | | +| variables.rs:58:5:67:47 | let TuplePat = ... | variables.rs:67:11:67:13 | "a" | | | variables.rs:58:9:67:5 | TuplePat | variables.rs:59:9:62:9 | TuplePat | match | | variables.rs:59:9:62:9 | TuplePat | variables.rs:60:13:60:14 | a1 | match | | variables.rs:60:13:60:14 | a1 | variables.rs:61:13:61:14 | b1 | match | -| variables.rs:61:13:61:14 | b1 | variables.rs:63:9:66:9 | RecordPat | match | -| variables.rs:63:9:66:9 | RecordPat | variables.rs:64:13:64:13 | x | match | +| variables.rs:61:13:61:14 | b1 | variables.rs:63:9:66:9 | Point {...} | match | +| variables.rs:63:9:66:9 | Point {...} | variables.rs:64:13:64:13 | x | match | | variables.rs:64:13:64:13 | x | variables.rs:65:13:65:13 | y | match | | variables.rs:65:13:65:13 | y | variables.rs:68:5:68:18 | ExprStmt | match | | variables.rs:67:9:67:46 | TupleExpr | variables.rs:58:9:67:5 | TuplePat | | | variables.rs:67:10:67:19 | TupleExpr | variables.rs:67:33:67:35 | "x" | | | variables.rs:67:11:67:13 | "a" | variables.rs:67:16:67:18 | "b" | | | variables.rs:67:16:67:18 | "b" | variables.rs:67:10:67:19 | TupleExpr | | -| variables.rs:67:22:67:45 | RecordExpr | variables.rs:67:9:67:46 | TupleExpr | | +| variables.rs:67:22:67:45 | Point {...} | variables.rs:67:9:67:46 | TupleExpr | | | variables.rs:67:33:67:35 | "x" | variables.rs:67:41:67:43 | "y" | | -| variables.rs:67:41:67:43 | "y" | variables.rs:67:22:67:45 | RecordExpr | | +| variables.rs:67:41:67:43 | "y" | variables.rs:67:22:67:45 | Point {...} | | | variables.rs:68:5:68:13 | print_str | variables.rs:68:15:68:16 | a1 | | -| variables.rs:68:5:68:17 | CallExpr | variables.rs:69:5:69:18 | ExprStmt | | +| variables.rs:68:5:68:17 | print_str(...) | variables.rs:69:5:69:18 | ExprStmt | | | variables.rs:68:5:68:18 | ExprStmt | variables.rs:68:5:68:13 | print_str | | -| variables.rs:68:15:68:16 | a1 | variables.rs:68:5:68:17 | CallExpr | | +| variables.rs:68:15:68:16 | a1 | variables.rs:68:5:68:17 | print_str(...) | | | variables.rs:69:5:69:13 | print_str | variables.rs:69:15:69:16 | b1 | | -| variables.rs:69:5:69:17 | CallExpr | variables.rs:70:5:70:17 | ExprStmt | | +| variables.rs:69:5:69:17 | print_str(...) | variables.rs:70:5:70:17 | ExprStmt | | | variables.rs:69:5:69:18 | ExprStmt | variables.rs:69:5:69:13 | print_str | | -| variables.rs:69:15:69:16 | b1 | variables.rs:69:5:69:17 | CallExpr | | +| variables.rs:69:15:69:16 | b1 | variables.rs:69:5:69:17 | print_str(...) | | | variables.rs:70:5:70:13 | print_str | variables.rs:70:15:70:15 | x | | -| variables.rs:70:5:70:16 | CallExpr | variables.rs:71:5:71:17 | ExprStmt | | +| variables.rs:70:5:70:16 | print_str(...) | variables.rs:71:5:71:17 | ExprStmt | | | variables.rs:70:5:70:17 | ExprStmt | variables.rs:70:5:70:13 | print_str | | -| variables.rs:70:15:70:15 | x | variables.rs:70:5:70:16 | CallExpr | | +| variables.rs:70:15:70:15 | x | variables.rs:70:5:70:16 | print_str(...) | | | variables.rs:71:5:71:13 | print_str | variables.rs:71:15:71:15 | y | | -| variables.rs:71:5:71:16 | CallExpr | variables.rs:57:19:72:1 | BlockExpr | | +| variables.rs:71:5:71:16 | print_str(...) | variables.rs:57:19:72:1 | { ... } | | | variables.rs:71:5:71:17 | ExprStmt | variables.rs:71:5:71:13 | print_str | | -| variables.rs:71:15:71:15 | y | variables.rs:71:5:71:16 | CallExpr | | -| variables.rs:74:1:82:1 | enter let_pattern2 | variables.rs:75:5:75:38 | LetStmt | | -| variables.rs:74:1:82:1 | exit let_pattern2 (normal) | variables.rs:74:1:82:1 | exit let_pattern2 | | -| variables.rs:74:19:82:1 | BlockExpr | variables.rs:74:1:82:1 | exit let_pattern2 (normal) | | -| variables.rs:75:5:75:38 | LetStmt | variables.rs:75:25:75:27 | "a" | | -| variables.rs:75:9:75:10 | p1 | variables.rs:76:5:79:11 | LetStmt | match | -| variables.rs:75:14:75:37 | RecordExpr | variables.rs:75:9:75:10 | p1 | | +| variables.rs:71:15:71:15 | y | variables.rs:71:5:71:16 | print_str(...) | | +| variables.rs:74:1:82:1 | enter fn let_pattern2 | variables.rs:75:5:75:38 | let p1 = ... | | +| variables.rs:74:1:82:1 | exit fn let_pattern2 (normal) | variables.rs:74:1:82:1 | exit fn let_pattern2 | | +| variables.rs:74:19:82:1 | { ... } | variables.rs:74:1:82:1 | exit fn let_pattern2 (normal) | | +| variables.rs:75:5:75:38 | let p1 = ... | variables.rs:75:25:75:27 | "a" | | +| variables.rs:75:9:75:10 | p1 | variables.rs:76:5:79:11 | let Point {...} = ... | match | +| variables.rs:75:14:75:37 | Point {...} | variables.rs:75:9:75:10 | p1 | | | variables.rs:75:25:75:27 | "a" | variables.rs:75:33:75:35 | "b" | | -| variables.rs:75:33:75:35 | "b" | variables.rs:75:14:75:37 | RecordExpr | | -| variables.rs:76:5:79:11 | LetStmt | variables.rs:79:9:79:10 | p1 | | -| variables.rs:76:9:79:5 | RecordPat | variables.rs:77:12:77:13 | a2 | match | +| variables.rs:75:33:75:35 | "b" | variables.rs:75:14:75:37 | Point {...} | | +| variables.rs:76:5:79:11 | let Point {...} = ... | variables.rs:79:9:79:10 | p1 | | +| variables.rs:76:9:79:5 | Point {...} | variables.rs:77:12:77:13 | a2 | match | | variables.rs:77:12:77:13 | a2 | variables.rs:78:12:78:13 | b2 | match | | variables.rs:78:12:78:13 | b2 | variables.rs:80:5:80:18 | ExprStmt | match | -| variables.rs:79:9:79:10 | p1 | variables.rs:76:9:79:5 | RecordPat | | +| variables.rs:79:9:79:10 | p1 | variables.rs:76:9:79:5 | Point {...} | | | variables.rs:80:5:80:13 | print_str | variables.rs:80:15:80:16 | a2 | | -| variables.rs:80:5:80:17 | CallExpr | variables.rs:81:5:81:18 | ExprStmt | | +| variables.rs:80:5:80:17 | print_str(...) | variables.rs:81:5:81:18 | ExprStmt | | | variables.rs:80:5:80:18 | ExprStmt | variables.rs:80:5:80:13 | print_str | | -| variables.rs:80:15:80:16 | a2 | variables.rs:80:5:80:17 | CallExpr | | +| variables.rs:80:15:80:16 | a2 | variables.rs:80:5:80:17 | print_str(...) | | | variables.rs:81:5:81:13 | print_str | variables.rs:81:15:81:16 | b2 | | -| variables.rs:81:5:81:17 | CallExpr | variables.rs:74:19:82:1 | BlockExpr | | +| variables.rs:81:5:81:17 | print_str(...) | variables.rs:74:19:82:1 | { ... } | | | variables.rs:81:5:81:18 | ExprStmt | variables.rs:81:5:81:13 | print_str | | -| variables.rs:81:15:81:16 | b2 | variables.rs:81:5:81:17 | CallExpr | | -| variables.rs:84:1:91:1 | enter let_pattern3 | variables.rs:85:5:85:42 | LetStmt | | -| variables.rs:84:1:91:1 | exit let_pattern3 (normal) | variables.rs:84:1:91:1 | exit let_pattern3 | | -| variables.rs:84:19:91:1 | BlockExpr | variables.rs:84:1:91:1 | exit let_pattern3 (normal) | | -| variables.rs:85:5:85:42 | LetStmt | variables.rs:85:14:85:17 | Some | | -| variables.rs:85:9:85:10 | s1 | variables.rs:87:8:88:12 | LetExpr | match | +| variables.rs:81:15:81:16 | b2 | variables.rs:81:5:81:17 | print_str(...) | | +| variables.rs:84:1:91:1 | enter fn let_pattern3 | variables.rs:85:5:85:42 | let s1 = ... | | +| variables.rs:84:1:91:1 | exit fn let_pattern3 (normal) | variables.rs:84:1:91:1 | exit fn let_pattern3 | | +| variables.rs:84:19:91:1 | { ... } | variables.rs:84:1:91:1 | exit fn let_pattern3 (normal) | | +| variables.rs:85:5:85:42 | let s1 = ... | variables.rs:85:14:85:17 | Some | | +| variables.rs:85:9:85:10 | s1 | variables.rs:87:8:88:12 | let TupleStructPat = ... | match | | variables.rs:85:14:85:17 | Some | variables.rs:85:19:85:30 | String::from | | -| variables.rs:85:14:85:41 | CallExpr | variables.rs:85:9:85:10 | s1 | | +| variables.rs:85:14:85:41 | Some(...) | variables.rs:85:9:85:10 | s1 | | | variables.rs:85:19:85:30 | String::from | variables.rs:85:32:85:39 | "Hello!" | | -| variables.rs:85:19:85:40 | CallExpr | variables.rs:85:14:85:41 | CallExpr | | -| variables.rs:85:32:85:39 | "Hello!" | variables.rs:85:19:85:40 | CallExpr | | -| variables.rs:87:5:90:5 | IfExpr | variables.rs:84:19:91:1 | BlockExpr | | -| variables.rs:87:8:88:12 | LetExpr | variables.rs:88:11:88:12 | s1 | | -| variables.rs:87:12:87:23 | TupleStructPat | variables.rs:87:5:90:5 | IfExpr | no-match | +| variables.rs:85:19:85:40 | String::from(...) | variables.rs:85:14:85:41 | Some(...) | | +| variables.rs:85:32:85:39 | "Hello!" | variables.rs:85:19:85:40 | String::from(...) | | +| variables.rs:87:5:90:5 | if ... { ... } | variables.rs:84:19:91:1 | { ... } | | +| variables.rs:87:8:88:12 | let TupleStructPat = ... | variables.rs:88:11:88:12 | s1 | | +| variables.rs:87:12:87:23 | TupleStructPat | variables.rs:87:5:90:5 | if ... { ... } | no-match | | variables.rs:87:12:87:23 | TupleStructPat | variables.rs:87:17:87:22 | s2 | match | | variables.rs:87:17:87:22 | s2 | variables.rs:89:9:89:22 | ExprStmt | match | | variables.rs:88:11:88:12 | s1 | variables.rs:87:12:87:23 | TupleStructPat | | -| variables.rs:88:14:90:5 | BlockExpr | variables.rs:87:5:90:5 | IfExpr | | +| variables.rs:88:14:90:5 | { ... } | variables.rs:87:5:90:5 | if ... { ... } | | | variables.rs:89:9:89:17 | print_str | variables.rs:89:19:89:20 | s2 | | -| variables.rs:89:9:89:21 | CallExpr | variables.rs:88:14:90:5 | BlockExpr | | +| variables.rs:89:9:89:21 | print_str(...) | variables.rs:88:14:90:5 | { ... } | | | variables.rs:89:9:89:22 | ExprStmt | variables.rs:89:9:89:17 | print_str | | -| variables.rs:89:19:89:20 | s2 | variables.rs:89:9:89:21 | CallExpr | | -| variables.rs:93:1:99:1 | enter let_pattern4 | variables.rs:94:5:97:10 | LetStmt | | -| variables.rs:93:1:99:1 | exit let_pattern4 (normal) | variables.rs:93:1:99:1 | exit let_pattern4 | | -| variables.rs:93:19:99:1 | BlockExpr | variables.rs:93:1:99:1 | exit let_pattern4 (normal) | | -| variables.rs:94:5:97:10 | LetStmt | variables.rs:94:34:94:37 | Some | | +| variables.rs:89:19:89:20 | s2 | variables.rs:89:9:89:21 | print_str(...) | | +| variables.rs:93:1:99:1 | enter fn let_pattern4 | variables.rs:94:5:97:10 | let TupleStructPat = ... else { ... } | | +| variables.rs:93:1:99:1 | exit fn let_pattern4 (normal) | variables.rs:93:1:99:1 | exit fn let_pattern4 | | +| variables.rs:93:19:99:1 | { ... } | variables.rs:93:1:99:1 | exit fn let_pattern4 (normal) | | +| variables.rs:94:5:97:10 | let TupleStructPat = ... else { ... } | variables.rs:94:34:94:37 | Some | | | variables.rs:94:9:94:16 | TupleStructPat | variables.rs:94:14:94:15 | x5 | match | | variables.rs:94:9:94:16 | TupleStructPat | variables.rs:96:13:96:19 | MacroStmts | no-match | | variables.rs:94:14:94:15 | x5 | variables.rs:98:5:98:18 | ExprStmt | match | | variables.rs:94:34:94:37 | Some | variables.rs:94:39:94:42 | "x5" | | -| variables.rs:94:34:94:43 | CallExpr | variables.rs:94:9:94:16 | TupleStructPat | | -| variables.rs:94:39:94:42 | "x5" | variables.rs:94:34:94:43 | CallExpr | | -| variables.rs:96:13:96:19 | "not yet implemented" | variables.rs:96:13:96:19 | CallExpr | | +| variables.rs:94:34:94:43 | Some(...) | variables.rs:94:9:94:16 | TupleStructPat | | +| variables.rs:94:39:94:42 | "x5" | variables.rs:94:34:94:43 | Some(...) | | +| variables.rs:96:13:96:19 | "not yet implemented" | variables.rs:96:13:96:19 | $crate::panicking::panic(...) | | | variables.rs:96:13:96:19 | $crate::panicking::panic | variables.rs:96:13:96:19 | "not yet implemented" | | -| variables.rs:96:13:96:19 | CallExpr | variables.rs:96:13:96:19 | MacroExpr | | -| variables.rs:96:13:96:19 | MacroExpr | variables.rs:95:14:97:9 | BlockExpr | | +| variables.rs:96:13:96:19 | $crate::panicking::panic(...) | variables.rs:96:13:96:19 | MacroExpr | | +| variables.rs:96:13:96:19 | MacroExpr | variables.rs:95:14:97:9 | { ... } | | | variables.rs:96:13:96:19 | MacroStmts | variables.rs:96:13:96:19 | $crate::panicking::panic | | | variables.rs:98:5:98:13 | print_str | variables.rs:98:15:98:16 | x5 | | -| variables.rs:98:5:98:17 | CallExpr | variables.rs:93:19:99:1 | BlockExpr | | +| variables.rs:98:5:98:17 | print_str(...) | variables.rs:93:19:99:1 | { ... } | | | variables.rs:98:5:98:18 | ExprStmt | variables.rs:98:5:98:13 | print_str | | -| variables.rs:98:15:98:16 | x5 | variables.rs:98:5:98:17 | CallExpr | | -| variables.rs:101:1:108:1 | enter let_pattern5 | variables.rs:102:5:102:42 | LetStmt | | -| variables.rs:101:1:108:1 | exit let_pattern5 (normal) | variables.rs:101:1:108:1 | exit let_pattern5 | | -| variables.rs:101:19:108:1 | BlockExpr | variables.rs:101:1:108:1 | exit let_pattern5 (normal) | | -| variables.rs:102:5:102:42 | LetStmt | variables.rs:102:14:102:17 | Some | | -| variables.rs:102:9:102:10 | s1 | variables.rs:104:11:105:12 | LetExpr | match | +| variables.rs:98:15:98:16 | x5 | variables.rs:98:5:98:17 | print_str(...) | | +| variables.rs:101:1:108:1 | enter fn let_pattern5 | variables.rs:102:5:102:42 | let s1 = ... | | +| variables.rs:101:1:108:1 | exit fn let_pattern5 (normal) | variables.rs:101:1:108:1 | exit fn let_pattern5 | | +| variables.rs:101:19:108:1 | { ... } | variables.rs:101:1:108:1 | exit fn let_pattern5 (normal) | | +| variables.rs:102:5:102:42 | let s1 = ... | variables.rs:102:14:102:17 | Some | | +| variables.rs:102:9:102:10 | s1 | variables.rs:104:11:105:12 | let TupleStructPat = ... | match | | variables.rs:102:14:102:17 | Some | variables.rs:102:19:102:30 | String::from | | -| variables.rs:102:14:102:41 | CallExpr | variables.rs:102:9:102:10 | s1 | | +| variables.rs:102:14:102:41 | Some(...) | variables.rs:102:9:102:10 | s1 | | | variables.rs:102:19:102:30 | String::from | variables.rs:102:32:102:39 | "Hello!" | | -| variables.rs:102:19:102:40 | CallExpr | variables.rs:102:14:102:41 | CallExpr | | -| variables.rs:102:32:102:39 | "Hello!" | variables.rs:102:19:102:40 | CallExpr | | -| variables.rs:104:5:107:5 | WhileExpr | variables.rs:101:19:108:1 | BlockExpr | | -| variables.rs:104:11:105:12 | LetExpr | variables.rs:105:11:105:12 | s1 | | -| variables.rs:104:15:104:26 | TupleStructPat | variables.rs:104:5:107:5 | WhileExpr | no-match | +| variables.rs:102:19:102:40 | String::from(...) | variables.rs:102:14:102:41 | Some(...) | | +| variables.rs:102:32:102:39 | "Hello!" | variables.rs:102:19:102:40 | String::from(...) | | +| variables.rs:104:5:107:5 | while ... { ... } | variables.rs:101:19:108:1 | { ... } | | +| variables.rs:104:11:105:12 | let TupleStructPat = ... | variables.rs:105:11:105:12 | s1 | | +| variables.rs:104:15:104:26 | TupleStructPat | variables.rs:104:5:107:5 | while ... { ... } | no-match | | variables.rs:104:15:104:26 | TupleStructPat | variables.rs:104:20:104:25 | s2 | match | | variables.rs:104:20:104:25 | s2 | variables.rs:106:9:106:22 | ExprStmt | match | | variables.rs:105:11:105:12 | s1 | variables.rs:104:15:104:26 | TupleStructPat | | -| variables.rs:105:14:107:5 | BlockExpr | variables.rs:104:11:105:12 | LetExpr | | +| variables.rs:105:14:107:5 | { ... } | variables.rs:104:11:105:12 | let TupleStructPat = ... | | | variables.rs:106:9:106:17 | print_str | variables.rs:106:19:106:20 | s2 | | -| variables.rs:106:9:106:21 | CallExpr | variables.rs:105:14:107:5 | BlockExpr | | +| variables.rs:106:9:106:21 | print_str(...) | variables.rs:105:14:107:5 | { ... } | | | variables.rs:106:9:106:22 | ExprStmt | variables.rs:106:9:106:17 | print_str | | -| variables.rs:106:19:106:20 | s2 | variables.rs:106:9:106:21 | CallExpr | | -| variables.rs:110:1:125:1 | enter match_pattern1 | variables.rs:111:5:111:21 | LetStmt | | -| variables.rs:110:1:125:1 | exit match_pattern1 (normal) | variables.rs:110:1:125:1 | exit match_pattern1 | | -| variables.rs:110:21:125:1 | BlockExpr | variables.rs:110:1:125:1 | exit match_pattern1 (normal) | | -| variables.rs:111:5:111:21 | LetStmt | variables.rs:111:14:111:17 | Some | | -| variables.rs:111:9:111:10 | x6 | variables.rs:112:5:112:16 | LetStmt | match | +| variables.rs:106:19:106:20 | s2 | variables.rs:106:9:106:21 | print_str(...) | | +| variables.rs:110:1:125:1 | enter fn match_pattern1 | variables.rs:111:5:111:21 | let x6 = ... | | +| variables.rs:110:1:125:1 | exit fn match_pattern1 (normal) | variables.rs:110:1:125:1 | exit fn match_pattern1 | | +| variables.rs:110:21:125:1 | { ... } | variables.rs:110:1:125:1 | exit fn match_pattern1 (normal) | | +| variables.rs:111:5:111:21 | let x6 = ... | variables.rs:111:14:111:17 | Some | | +| variables.rs:111:9:111:10 | x6 | variables.rs:112:5:112:16 | let y1 = ... | match | | variables.rs:111:14:111:17 | Some | variables.rs:111:19:111:19 | 5 | | -| variables.rs:111:14:111:20 | CallExpr | variables.rs:111:9:111:10 | x6 | | -| variables.rs:111:19:111:19 | 5 | variables.rs:111:14:111:20 | CallExpr | | -| variables.rs:112:5:112:16 | LetStmt | variables.rs:112:14:112:15 | 10 | | +| variables.rs:111:14:111:20 | Some(...) | variables.rs:111:9:111:10 | x6 | | +| variables.rs:111:19:111:19 | 5 | variables.rs:111:14:111:20 | Some(...) | | +| variables.rs:112:5:112:16 | let y1 = ... | variables.rs:112:14:112:15 | 10 | | | variables.rs:112:9:112:10 | y1 | variables.rs:114:5:122:5 | ExprStmt | match | | variables.rs:112:14:112:15 | 10 | variables.rs:112:9:112:10 | y1 | | | variables.rs:114:5:122:5 | ExprStmt | variables.rs:114:11:114:12 | x6 | | -| variables.rs:114:5:122:5 | MatchExpr | variables.rs:124:5:124:18 | ExprStmt | | +| variables.rs:114:5:122:5 | match ... { ... } | variables.rs:124:5:124:18 | ExprStmt | | | variables.rs:114:11:114:12 | x6 | variables.rs:115:9:115:16 | TupleStructPat | | | variables.rs:115:9:115:16 | TupleStructPat | variables.rs:115:14:115:15 | 50 | match | | variables.rs:115:9:115:16 | TupleStructPat | variables.rs:116:9:116:16 | TupleStructPat | no-match | -| variables.rs:115:14:115:15 | 50 | variables.rs:115:14:115:15 | LiteralPat | | -| variables.rs:115:14:115:15 | LiteralPat | variables.rs:115:21:115:29 | print_str | match | -| variables.rs:115:14:115:15 | LiteralPat | variables.rs:116:9:116:16 | TupleStructPat | no-match | +| variables.rs:115:14:115:15 | 50 | variables.rs:115:14:115:15 | 50 | | +| variables.rs:115:14:115:15 | 50 | variables.rs:115:21:115:29 | print_str | match | +| variables.rs:115:14:115:15 | 50 | variables.rs:116:9:116:16 | TupleStructPat | no-match | | variables.rs:115:21:115:29 | print_str | variables.rs:115:31:115:38 | "Got 50" | | -| variables.rs:115:21:115:39 | CallExpr | variables.rs:114:5:122:5 | MatchExpr | | -| variables.rs:115:31:115:38 | "Got 50" | variables.rs:115:21:115:39 | CallExpr | | +| variables.rs:115:21:115:39 | print_str(...) | variables.rs:114:5:122:5 | match ... { ... } | | +| variables.rs:115:31:115:38 | "Got 50" | variables.rs:115:21:115:39 | print_str(...) | | | variables.rs:116:9:116:16 | TupleStructPat | variables.rs:116:14:116:15 | y1 | match | | variables.rs:116:9:116:16 | TupleStructPat | variables.rs:121:9:121:12 | None | no-match | | variables.rs:116:14:116:15 | y1 | variables.rs:119:13:119:21 | print_i64 | match | -| variables.rs:118:9:120:9 | BlockExpr | variables.rs:114:5:122:5 | MatchExpr | | +| variables.rs:118:9:120:9 | { ... } | variables.rs:114:5:122:5 | match ... { ... } | | | variables.rs:119:13:119:21 | print_i64 | variables.rs:119:23:119:24 | y1 | | -| variables.rs:119:13:119:25 | CallExpr | variables.rs:118:9:120:9 | BlockExpr | | -| variables.rs:119:23:119:24 | y1 | variables.rs:119:13:119:25 | CallExpr | | +| variables.rs:119:13:119:25 | print_i64(...) | variables.rs:118:9:120:9 | { ... } | | +| variables.rs:119:23:119:24 | y1 | variables.rs:119:13:119:25 | print_i64(...) | | | variables.rs:121:9:121:12 | None | variables.rs:121:17:121:25 | print_str | match | | variables.rs:121:17:121:25 | print_str | variables.rs:121:27:121:32 | "NONE" | | -| variables.rs:121:17:121:33 | CallExpr | variables.rs:114:5:122:5 | MatchExpr | | -| variables.rs:121:27:121:32 | "NONE" | variables.rs:121:17:121:33 | CallExpr | | +| variables.rs:121:17:121:33 | print_str(...) | variables.rs:114:5:122:5 | match ... { ... } | | +| variables.rs:121:27:121:32 | "NONE" | variables.rs:121:17:121:33 | print_str(...) | | | variables.rs:124:5:124:13 | print_i64 | variables.rs:124:15:124:16 | y1 | | -| variables.rs:124:5:124:17 | CallExpr | variables.rs:110:21:125:1 | BlockExpr | | +| variables.rs:124:5:124:17 | print_i64(...) | variables.rs:110:21:125:1 | { ... } | | | variables.rs:124:5:124:18 | ExprStmt | variables.rs:124:5:124:13 | print_i64 | | -| variables.rs:124:15:124:16 | y1 | variables.rs:124:5:124:17 | CallExpr | | -| variables.rs:127:1:152:1 | enter match_pattern2 | variables.rs:128:5:128:36 | LetStmt | | -| variables.rs:127:1:152:1 | exit match_pattern2 (normal) | variables.rs:127:1:152:1 | exit match_pattern2 | | -| variables.rs:127:21:152:1 | BlockExpr | variables.rs:127:1:152:1 | exit match_pattern2 (normal) | | -| variables.rs:128:5:128:36 | LetStmt | variables.rs:128:20:128:20 | 2 | | +| variables.rs:124:15:124:16 | y1 | variables.rs:124:5:124:17 | print_i64(...) | | +| variables.rs:127:1:152:1 | enter fn match_pattern2 | variables.rs:128:5:128:36 | let numbers = ... | | +| variables.rs:127:1:152:1 | exit fn match_pattern2 (normal) | variables.rs:127:1:152:1 | exit fn match_pattern2 | | +| variables.rs:127:21:152:1 | { ... } | variables.rs:127:1:152:1 | exit fn match_pattern2 (normal) | | +| variables.rs:128:5:128:36 | let numbers = ... | variables.rs:128:20:128:20 | 2 | | | variables.rs:128:9:128:15 | numbers | variables.rs:130:5:140:5 | ExprStmt | match | | variables.rs:128:19:128:35 | TupleExpr | variables.rs:128:9:128:15 | numbers | | | variables.rs:128:20:128:20 | 2 | variables.rs:128:23:128:23 | 4 | | @@ -295,311 +295,311 @@ edges | variables.rs:128:29:128:30 | 16 | variables.rs:128:33:128:34 | 32 | | | variables.rs:128:33:128:34 | 32 | variables.rs:128:19:128:35 | TupleExpr | | | variables.rs:130:5:140:5 | ExprStmt | variables.rs:130:11:130:17 | numbers | | -| variables.rs:130:5:140:5 | MatchExpr | variables.rs:142:11:142:17 | numbers | | +| variables.rs:130:5:140:5 | match ... { ... } | variables.rs:142:11:142:17 | numbers | | | variables.rs:130:11:130:17 | numbers | variables.rs:131:9:135:9 | TuplePat | | | variables.rs:131:9:135:9 | TuplePat | variables.rs:132:13:132:17 | first | match | -| variables.rs:132:13:132:17 | first | variables.rs:132:20:132:20 | WildcardPat | match | -| variables.rs:132:20:132:20 | WildcardPat | variables.rs:133:13:133:17 | third | match | -| variables.rs:133:13:133:17 | third | variables.rs:133:20:133:20 | WildcardPat | match | -| variables.rs:133:20:133:20 | WildcardPat | variables.rs:134:13:134:17 | fifth | match | +| variables.rs:132:13:132:17 | first | variables.rs:132:20:132:20 | _ | match | +| variables.rs:132:20:132:20 | _ | variables.rs:133:13:133:17 | third | match | +| variables.rs:133:13:133:17 | third | variables.rs:133:20:133:20 | _ | match | +| variables.rs:133:20:133:20 | _ | variables.rs:134:13:134:17 | fifth | match | | variables.rs:134:13:134:17 | fifth | variables.rs:136:13:136:29 | ExprStmt | match | -| variables.rs:135:14:139:9 | BlockExpr | variables.rs:130:5:140:5 | MatchExpr | | +| variables.rs:135:14:139:9 | { ... } | variables.rs:130:5:140:5 | match ... { ... } | | | variables.rs:136:13:136:21 | print_i64 | variables.rs:136:23:136:27 | first | | -| variables.rs:136:13:136:28 | CallExpr | variables.rs:137:13:137:29 | ExprStmt | | +| variables.rs:136:13:136:28 | print_i64(...) | variables.rs:137:13:137:29 | ExprStmt | | | variables.rs:136:13:136:29 | ExprStmt | variables.rs:136:13:136:21 | print_i64 | | -| variables.rs:136:23:136:27 | first | variables.rs:136:13:136:28 | CallExpr | | +| variables.rs:136:23:136:27 | first | variables.rs:136:13:136:28 | print_i64(...) | | | variables.rs:137:13:137:21 | print_i64 | variables.rs:137:23:137:27 | third | | -| variables.rs:137:13:137:28 | CallExpr | variables.rs:138:13:138:29 | ExprStmt | | +| variables.rs:137:13:137:28 | print_i64(...) | variables.rs:138:13:138:29 | ExprStmt | | | variables.rs:137:13:137:29 | ExprStmt | variables.rs:137:13:137:21 | print_i64 | | -| variables.rs:137:23:137:27 | third | variables.rs:137:13:137:28 | CallExpr | | +| variables.rs:137:23:137:27 | third | variables.rs:137:13:137:28 | print_i64(...) | | | variables.rs:138:13:138:21 | print_i64 | variables.rs:138:23:138:27 | fifth | | -| variables.rs:138:13:138:28 | CallExpr | variables.rs:135:14:139:9 | BlockExpr | | +| variables.rs:138:13:138:28 | print_i64(...) | variables.rs:135:14:139:9 | { ... } | | | variables.rs:138:13:138:29 | ExprStmt | variables.rs:138:13:138:21 | print_i64 | | -| variables.rs:138:23:138:27 | fifth | variables.rs:138:13:138:28 | CallExpr | | -| variables.rs:142:5:151:5 | MatchExpr | variables.rs:127:21:152:1 | BlockExpr | | +| variables.rs:138:23:138:27 | fifth | variables.rs:138:13:138:28 | print_i64(...) | | +| variables.rs:142:5:151:5 | match ... { ... } | variables.rs:127:21:152:1 | { ... } | | | variables.rs:142:11:142:17 | numbers | variables.rs:143:9:147:9 | TuplePat | | | variables.rs:143:9:147:9 | TuplePat | variables.rs:144:13:144:17 | first | match | -| variables.rs:144:13:144:17 | first | variables.rs:145:13:145:14 | RestPat | match | -| variables.rs:145:13:145:14 | RestPat | variables.rs:146:13:146:16 | last | match | +| variables.rs:144:13:144:17 | first | variables.rs:145:13:145:14 | .. | match | +| variables.rs:145:13:145:14 | .. | variables.rs:146:13:146:16 | last | match | | variables.rs:146:13:146:16 | last | variables.rs:148:13:148:29 | ExprStmt | match | -| variables.rs:147:14:150:9 | BlockExpr | variables.rs:142:5:151:5 | MatchExpr | | +| variables.rs:147:14:150:9 | { ... } | variables.rs:142:5:151:5 | match ... { ... } | | | variables.rs:148:13:148:21 | print_i64 | variables.rs:148:23:148:27 | first | | -| variables.rs:148:13:148:28 | CallExpr | variables.rs:149:13:149:28 | ExprStmt | | +| variables.rs:148:13:148:28 | print_i64(...) | variables.rs:149:13:149:28 | ExprStmt | | | variables.rs:148:13:148:29 | ExprStmt | variables.rs:148:13:148:21 | print_i64 | | -| variables.rs:148:23:148:27 | first | variables.rs:148:13:148:28 | CallExpr | | +| variables.rs:148:23:148:27 | first | variables.rs:148:13:148:28 | print_i64(...) | | | variables.rs:149:13:149:21 | print_i64 | variables.rs:149:23:149:26 | last | | -| variables.rs:149:13:149:27 | CallExpr | variables.rs:147:14:150:9 | BlockExpr | | +| variables.rs:149:13:149:27 | print_i64(...) | variables.rs:147:14:150:9 | { ... } | | | variables.rs:149:13:149:28 | ExprStmt | variables.rs:149:13:149:21 | print_i64 | | -| variables.rs:149:23:149:26 | last | variables.rs:149:13:149:27 | CallExpr | | -| variables.rs:154:1:162:1 | enter match_pattern3 | variables.rs:155:5:155:38 | LetStmt | | -| variables.rs:154:1:162:1 | exit match_pattern3 (normal) | variables.rs:154:1:162:1 | exit match_pattern3 | | -| variables.rs:154:21:162:1 | BlockExpr | variables.rs:154:1:162:1 | exit match_pattern3 (normal) | | -| variables.rs:155:5:155:38 | LetStmt | variables.rs:155:25:155:27 | "x" | | +| variables.rs:149:23:149:26 | last | variables.rs:149:13:149:27 | print_i64(...) | | +| variables.rs:154:1:162:1 | enter fn match_pattern3 | variables.rs:155:5:155:38 | let p2 = ... | | +| variables.rs:154:1:162:1 | exit fn match_pattern3 (normal) | variables.rs:154:1:162:1 | exit fn match_pattern3 | | +| variables.rs:154:21:162:1 | { ... } | variables.rs:154:1:162:1 | exit fn match_pattern3 (normal) | | +| variables.rs:155:5:155:38 | let p2 = ... | variables.rs:155:25:155:27 | "x" | | | variables.rs:155:9:155:10 | p2 | variables.rs:157:11:157:12 | p2 | match | -| variables.rs:155:14:155:37 | RecordExpr | variables.rs:155:9:155:10 | p2 | | +| variables.rs:155:14:155:37 | Point {...} | variables.rs:155:9:155:10 | p2 | | | variables.rs:155:25:155:27 | "x" | variables.rs:155:33:155:35 | "y" | | -| variables.rs:155:33:155:35 | "y" | variables.rs:155:14:155:37 | RecordExpr | | -| variables.rs:157:5:161:5 | MatchExpr | variables.rs:154:21:162:1 | BlockExpr | | -| variables.rs:157:11:157:12 | p2 | variables.rs:158:9:160:9 | RecordPat | | -| variables.rs:158:9:160:9 | RecordPat | variables.rs:159:16:159:17 | x7 | match | -| variables.rs:159:16:159:17 | x7 | variables.rs:159:20:159:21 | RestPat | match | -| variables.rs:159:20:159:21 | RestPat | variables.rs:160:14:160:22 | print_str | match | +| variables.rs:155:33:155:35 | "y" | variables.rs:155:14:155:37 | Point {...} | | +| variables.rs:157:5:161:5 | match ... { ... } | variables.rs:154:21:162:1 | { ... } | | +| variables.rs:157:11:157:12 | p2 | variables.rs:158:9:160:9 | Point {...} | | +| variables.rs:158:9:160:9 | Point {...} | variables.rs:159:16:159:17 | x7 | match | +| variables.rs:159:16:159:17 | x7 | variables.rs:159:20:159:21 | .. | match | +| variables.rs:159:20:159:21 | .. | variables.rs:160:14:160:22 | print_str | match | | variables.rs:160:14:160:22 | print_str | variables.rs:160:24:160:25 | x7 | | -| variables.rs:160:14:160:26 | CallExpr | variables.rs:157:5:161:5 | MatchExpr | | -| variables.rs:160:24:160:25 | x7 | variables.rs:160:14:160:26 | CallExpr | | -| variables.rs:168:1:181:1 | enter match_pattern4 | variables.rs:169:5:169:39 | LetStmt | | -| variables.rs:168:1:181:1 | exit match_pattern4 (normal) | variables.rs:168:1:181:1 | exit match_pattern4 | | -| variables.rs:168:21:181:1 | BlockExpr | variables.rs:168:1:181:1 | exit match_pattern4 (normal) | | -| variables.rs:169:5:169:39 | LetStmt | variables.rs:169:36:169:36 | 0 | | +| variables.rs:160:14:160:26 | print_str(...) | variables.rs:157:5:161:5 | match ... { ... } | | +| variables.rs:160:24:160:25 | x7 | variables.rs:160:14:160:26 | print_str(...) | | +| variables.rs:168:1:181:1 | enter fn match_pattern4 | variables.rs:169:5:169:39 | let msg = ... | | +| variables.rs:168:1:181:1 | exit fn match_pattern4 (normal) | variables.rs:168:1:181:1 | exit fn match_pattern4 | | +| variables.rs:168:21:181:1 | { ... } | variables.rs:168:1:181:1 | exit fn match_pattern4 (normal) | | +| variables.rs:169:5:169:39 | let msg = ... | variables.rs:169:36:169:36 | 0 | | | variables.rs:169:9:169:11 | msg | variables.rs:171:11:171:13 | msg | match | -| variables.rs:169:15:169:38 | RecordExpr | variables.rs:169:9:169:11 | msg | | -| variables.rs:169:36:169:36 | 0 | variables.rs:169:15:169:38 | RecordExpr | | -| variables.rs:171:5:180:5 | MatchExpr | variables.rs:168:21:181:1 | BlockExpr | | -| variables.rs:171:11:171:13 | msg | variables.rs:172:9:174:9 | RecordPat | | -| variables.rs:172:9:174:9 | RecordPat | variables.rs:173:31:173:35 | RangePat | match | -| variables.rs:172:9:174:9 | RecordPat | variables.rs:175:9:175:38 | RecordPat | no-match | +| variables.rs:169:15:169:38 | Message::Hello {...} | variables.rs:169:9:169:11 | msg | | +| variables.rs:169:36:169:36 | 0 | variables.rs:169:15:169:38 | Message::Hello {...} | | +| variables.rs:171:5:180:5 | match ... { ... } | variables.rs:168:21:181:1 | { ... } | | +| variables.rs:171:11:171:13 | msg | variables.rs:172:9:174:9 | Message::Hello {...} | | +| variables.rs:172:9:174:9 | Message::Hello {...} | variables.rs:173:31:173:35 | RangePat | match | +| variables.rs:172:9:174:9 | Message::Hello {...} | variables.rs:175:9:175:38 | Message::Hello {...} | no-match | | variables.rs:173:17:173:35 | [match(true)] id_variable | variables.rs:174:14:174:22 | print_i64 | match | -| variables.rs:173:31:173:31 | 3 | variables.rs:173:31:173:31 | LiteralPat | | -| variables.rs:173:31:173:31 | LiteralPat | variables.rs:173:35:173:35 | 7 | match | -| variables.rs:173:31:173:31 | LiteralPat | variables.rs:175:9:175:38 | RecordPat | no-match | +| variables.rs:173:31:173:31 | 3 | variables.rs:173:31:173:31 | 3 | | +| variables.rs:173:31:173:31 | 3 | variables.rs:173:35:173:35 | 7 | match | +| variables.rs:173:31:173:31 | 3 | variables.rs:175:9:175:38 | Message::Hello {...} | no-match | | variables.rs:173:31:173:35 | RangePat | variables.rs:173:31:173:31 | 3 | match | -| variables.rs:173:31:173:35 | RangePat | variables.rs:175:9:175:38 | RecordPat | no-match | -| variables.rs:173:35:173:35 | 7 | variables.rs:173:35:173:35 | LiteralPat | | -| variables.rs:173:35:173:35 | LiteralPat | variables.rs:173:17:173:35 | [match(true)] id_variable | match | -| variables.rs:173:35:173:35 | LiteralPat | variables.rs:175:9:175:38 | RecordPat | no-match | +| variables.rs:173:31:173:35 | RangePat | variables.rs:175:9:175:38 | Message::Hello {...} | no-match | +| variables.rs:173:35:173:35 | 7 | variables.rs:173:17:173:35 | [match(true)] id_variable | match | +| variables.rs:173:35:173:35 | 7 | variables.rs:173:35:173:35 | 7 | | +| variables.rs:173:35:173:35 | 7 | variables.rs:175:9:175:38 | Message::Hello {...} | no-match | | variables.rs:174:14:174:22 | print_i64 | variables.rs:174:24:174:34 | id_variable | | -| variables.rs:174:14:174:35 | CallExpr | variables.rs:171:5:180:5 | MatchExpr | | -| variables.rs:174:24:174:34 | id_variable | variables.rs:174:14:174:35 | CallExpr | | -| variables.rs:175:9:175:38 | RecordPat | variables.rs:175:30:175:36 | RangePat | match | -| variables.rs:175:9:175:38 | RecordPat | variables.rs:178:9:178:29 | RecordPat | no-match | -| variables.rs:175:30:175:31 | 10 | variables.rs:175:30:175:31 | LiteralPat | | -| variables.rs:175:30:175:31 | LiteralPat | variables.rs:175:35:175:36 | 12 | match | -| variables.rs:175:30:175:31 | LiteralPat | variables.rs:178:9:178:29 | RecordPat | no-match | +| variables.rs:174:14:174:35 | print_i64(...) | variables.rs:171:5:180:5 | match ... { ... } | | +| variables.rs:174:24:174:34 | id_variable | variables.rs:174:14:174:35 | print_i64(...) | | +| variables.rs:175:9:175:38 | Message::Hello {...} | variables.rs:175:30:175:36 | RangePat | match | +| variables.rs:175:9:175:38 | Message::Hello {...} | variables.rs:178:9:178:29 | Message::Hello {...} | no-match | +| variables.rs:175:30:175:31 | 10 | variables.rs:175:30:175:31 | 10 | | +| variables.rs:175:30:175:31 | 10 | variables.rs:175:35:175:36 | 12 | match | +| variables.rs:175:30:175:31 | 10 | variables.rs:178:9:178:29 | Message::Hello {...} | no-match | | variables.rs:175:30:175:36 | RangePat | variables.rs:175:30:175:31 | 10 | match | -| variables.rs:175:30:175:36 | RangePat | variables.rs:178:9:178:29 | RecordPat | no-match | -| variables.rs:175:35:175:36 | 12 | variables.rs:175:35:175:36 | LiteralPat | | -| variables.rs:175:35:175:36 | LiteralPat | variables.rs:176:22:176:51 | MacroStmts | match | -| variables.rs:175:35:175:36 | LiteralPat | variables.rs:178:9:178:29 | RecordPat | no-match | -| variables.rs:175:43:177:9 | BlockExpr | variables.rs:171:5:180:5 | MatchExpr | | +| variables.rs:175:30:175:36 | RangePat | variables.rs:178:9:178:29 | Message::Hello {...} | no-match | +| variables.rs:175:35:175:36 | 12 | variables.rs:175:35:175:36 | 12 | | +| variables.rs:175:35:175:36 | 12 | variables.rs:176:22:176:51 | MacroStmts | match | +| variables.rs:175:35:175:36 | 12 | variables.rs:178:9:178:29 | Message::Hello {...} | no-match | +| variables.rs:175:43:177:9 | { ... } | variables.rs:171:5:180:5 | match ... { ... } | | | variables.rs:176:13:176:52 | $crate::io::_print | variables.rs:176:22:176:51 | "Found an id in another range\\n" | | -| variables.rs:176:13:176:52 | MacroExpr | variables.rs:175:43:177:9 | BlockExpr | | +| variables.rs:176:13:176:52 | MacroExpr | variables.rs:175:43:177:9 | { ... } | | | variables.rs:176:22:176:51 | "Found an id in another range\\n" | variables.rs:176:22:176:51 | FormatArgsExpr | | -| variables.rs:176:22:176:51 | BlockExpr | variables.rs:176:13:176:52 | MacroExpr | | -| variables.rs:176:22:176:51 | CallExpr | variables.rs:176:22:176:51 | BlockExpr | | +| variables.rs:176:22:176:51 | $crate::io::_print(...) | variables.rs:176:22:176:51 | { ... } | | | variables.rs:176:22:176:51 | ExprStmt | variables.rs:176:13:176:52 | $crate::io::_print | | | variables.rs:176:22:176:51 | FormatArgsExpr | variables.rs:176:22:176:51 | MacroExpr | | -| variables.rs:176:22:176:51 | MacroExpr | variables.rs:176:22:176:51 | CallExpr | | +| variables.rs:176:22:176:51 | MacroExpr | variables.rs:176:22:176:51 | $crate::io::_print(...) | | | variables.rs:176:22:176:51 | MacroStmts | variables.rs:176:22:176:51 | ExprStmt | | -| variables.rs:178:9:178:29 | RecordPat | variables.rs:178:26:178:27 | id | match | +| variables.rs:176:22:176:51 | { ... } | variables.rs:176:13:176:52 | MacroExpr | | +| variables.rs:178:9:178:29 | Message::Hello {...} | variables.rs:178:26:178:27 | id | match | | variables.rs:178:26:178:27 | id | variables.rs:179:13:179:21 | print_i64 | match | | variables.rs:179:13:179:21 | print_i64 | variables.rs:179:23:179:24 | id | | -| variables.rs:179:13:179:25 | CallExpr | variables.rs:171:5:180:5 | MatchExpr | | -| variables.rs:179:23:179:24 | id | variables.rs:179:13:179:25 | CallExpr | | -| variables.rs:188:1:194:1 | enter match_pattern5 | variables.rs:189:5:189:34 | LetStmt | | -| variables.rs:188:1:194:1 | exit match_pattern5 (normal) | variables.rs:188:1:194:1 | exit match_pattern5 | | -| variables.rs:188:21:194:1 | BlockExpr | variables.rs:188:1:194:1 | exit match_pattern5 (normal) | | -| variables.rs:189:5:189:34 | LetStmt | variables.rs:189:18:189:29 | Either::Left | | +| variables.rs:179:13:179:25 | print_i64(...) | variables.rs:171:5:180:5 | match ... { ... } | | +| variables.rs:179:23:179:24 | id | variables.rs:179:13:179:25 | print_i64(...) | | +| variables.rs:188:1:194:1 | enter fn match_pattern5 | variables.rs:189:5:189:34 | let either = ... | | +| variables.rs:188:1:194:1 | exit fn match_pattern5 (normal) | variables.rs:188:1:194:1 | exit fn match_pattern5 | | +| variables.rs:188:21:194:1 | { ... } | variables.rs:188:1:194:1 | exit fn match_pattern5 (normal) | | +| variables.rs:189:5:189:34 | let either = ... | variables.rs:189:18:189:29 | Either::Left | | | variables.rs:189:9:189:14 | either | variables.rs:190:11:190:16 | either | match | | variables.rs:189:18:189:29 | Either::Left | variables.rs:189:31:189:32 | 32 | | -| variables.rs:189:18:189:33 | CallExpr | variables.rs:189:9:189:14 | either | | -| variables.rs:189:31:189:32 | 32 | variables.rs:189:18:189:33 | CallExpr | | -| variables.rs:190:5:193:5 | MatchExpr | variables.rs:188:21:194:1 | BlockExpr | | +| variables.rs:189:18:189:33 | Either::Left(...) | variables.rs:189:9:189:14 | either | | +| variables.rs:189:31:189:32 | 32 | variables.rs:189:18:189:33 | Either::Left(...) | | +| variables.rs:190:5:193:5 | match ... { ... } | variables.rs:188:21:194:1 | { ... } | | | variables.rs:190:11:190:16 | either | variables.rs:191:9:191:24 | TupleStructPat | | | variables.rs:191:9:191:24 | TupleStructPat | variables.rs:191:22:191:23 | a3 | match | | variables.rs:191:9:191:24 | TupleStructPat | variables.rs:191:28:191:44 | TupleStructPat | no-match | -| variables.rs:191:9:191:44 | [match(true)] OrPat | variables.rs:192:16:192:24 | print_i64 | match | -| variables.rs:191:22:191:23 | a3 | variables.rs:191:9:191:44 | [match(true)] OrPat | match | +| variables.rs:191:9:191:44 | [match(true)] ... \| ... | variables.rs:192:16:192:24 | print_i64 | match | +| variables.rs:191:22:191:23 | a3 | variables.rs:191:9:191:44 | [match(true)] ... \| ... | match | | variables.rs:191:28:191:44 | TupleStructPat | variables.rs:191:42:191:43 | a3 | match | -| variables.rs:191:42:191:43 | a3 | variables.rs:191:9:191:44 | [match(true)] OrPat | match | +| variables.rs:191:42:191:43 | a3 | variables.rs:191:9:191:44 | [match(true)] ... \| ... | match | | variables.rs:192:16:192:24 | print_i64 | variables.rs:192:26:192:27 | a3 | | -| variables.rs:192:16:192:28 | CallExpr | variables.rs:190:5:193:5 | MatchExpr | | -| variables.rs:192:26:192:27 | a3 | variables.rs:192:16:192:28 | CallExpr | | -| variables.rs:202:1:216:1 | enter match_pattern6 | variables.rs:203:5:203:37 | LetStmt | | -| variables.rs:202:1:216:1 | exit match_pattern6 (normal) | variables.rs:202:1:216:1 | exit match_pattern6 | | -| variables.rs:202:21:216:1 | BlockExpr | variables.rs:202:1:216:1 | exit match_pattern6 (normal) | | -| variables.rs:203:5:203:37 | LetStmt | variables.rs:203:14:203:32 | ThreeValued::Second | | +| variables.rs:192:16:192:28 | print_i64(...) | variables.rs:190:5:193:5 | match ... { ... } | | +| variables.rs:192:26:192:27 | a3 | variables.rs:192:16:192:28 | print_i64(...) | | +| variables.rs:202:1:216:1 | enter fn match_pattern6 | variables.rs:203:5:203:37 | let tv = ... | | +| variables.rs:202:1:216:1 | exit fn match_pattern6 (normal) | variables.rs:202:1:216:1 | exit fn match_pattern6 | | +| variables.rs:202:21:216:1 | { ... } | variables.rs:202:1:216:1 | exit fn match_pattern6 (normal) | | +| variables.rs:203:5:203:37 | let tv = ... | variables.rs:203:14:203:32 | ThreeValued::Second | | | variables.rs:203:9:203:10 | tv | variables.rs:204:5:207:5 | ExprStmt | match | | variables.rs:203:14:203:32 | ThreeValued::Second | variables.rs:203:34:203:35 | 62 | | -| variables.rs:203:14:203:36 | CallExpr | variables.rs:203:9:203:10 | tv | | -| variables.rs:203:34:203:35 | 62 | variables.rs:203:14:203:36 | CallExpr | | +| variables.rs:203:14:203:36 | ThreeValued::Second(...) | variables.rs:203:9:203:10 | tv | | +| variables.rs:203:34:203:35 | 62 | variables.rs:203:14:203:36 | ThreeValued::Second(...) | | | variables.rs:204:5:207:5 | ExprStmt | variables.rs:204:11:204:12 | tv | | -| variables.rs:204:5:207:5 | MatchExpr | variables.rs:208:5:211:5 | ExprStmt | | +| variables.rs:204:5:207:5 | match ... { ... } | variables.rs:208:5:211:5 | ExprStmt | | | variables.rs:204:11:204:12 | tv | variables.rs:205:9:205:30 | TupleStructPat | | | variables.rs:205:9:205:30 | TupleStructPat | variables.rs:205:28:205:29 | a4 | match | | variables.rs:205:9:205:30 | TupleStructPat | variables.rs:205:34:205:56 | TupleStructPat | no-match | -| variables.rs:205:9:205:81 | [match(true)] OrPat | variables.rs:206:16:206:24 | print_i64 | match | -| variables.rs:205:28:205:29 | a4 | variables.rs:205:9:205:81 | [match(true)] OrPat | match | +| variables.rs:205:9:205:81 | [match(true)] ... \| ... | variables.rs:206:16:206:24 | print_i64 | match | +| variables.rs:205:28:205:29 | a4 | variables.rs:205:9:205:81 | [match(true)] ... \| ... | match | | variables.rs:205:34:205:56 | TupleStructPat | variables.rs:205:54:205:55 | a4 | match | | variables.rs:205:34:205:56 | TupleStructPat | variables.rs:205:60:205:81 | TupleStructPat | no-match | -| variables.rs:205:54:205:55 | a4 | variables.rs:205:9:205:81 | [match(true)] OrPat | match | +| variables.rs:205:54:205:55 | a4 | variables.rs:205:9:205:81 | [match(true)] ... \| ... | match | | variables.rs:205:60:205:81 | TupleStructPat | variables.rs:205:79:205:80 | a4 | match | -| variables.rs:205:79:205:80 | a4 | variables.rs:205:9:205:81 | [match(true)] OrPat | match | +| variables.rs:205:79:205:80 | a4 | variables.rs:205:9:205:81 | [match(true)] ... \| ... | match | | variables.rs:206:16:206:24 | print_i64 | variables.rs:206:26:206:27 | a4 | | -| variables.rs:206:16:206:28 | CallExpr | variables.rs:204:5:207:5 | MatchExpr | | -| variables.rs:206:26:206:27 | a4 | variables.rs:206:16:206:28 | CallExpr | | +| variables.rs:206:16:206:28 | print_i64(...) | variables.rs:204:5:207:5 | match ... { ... } | | +| variables.rs:206:26:206:27 | a4 | variables.rs:206:16:206:28 | print_i64(...) | | | variables.rs:208:5:211:5 | ExprStmt | variables.rs:208:11:208:12 | tv | | -| variables.rs:208:5:211:5 | MatchExpr | variables.rs:212:11:212:12 | tv | | +| variables.rs:208:5:211:5 | match ... { ... } | variables.rs:212:11:212:12 | tv | | | variables.rs:208:11:208:12 | tv | variables.rs:209:10:209:31 | TupleStructPat | | -| variables.rs:209:9:209:83 | [match(true)] OrPat | variables.rs:210:16:210:24 | print_i64 | match | +| variables.rs:209:9:209:83 | [match(true)] ... \| ... | variables.rs:210:16:210:24 | print_i64 | match | | variables.rs:209:10:209:31 | TupleStructPat | variables.rs:209:29:209:30 | a5 | match | | variables.rs:209:10:209:31 | TupleStructPat | variables.rs:209:35:209:57 | TupleStructPat | no-match | -| variables.rs:209:10:209:57 | [match(false)] OrPat | variables.rs:209:62:209:83 | TupleStructPat | no-match | -| variables.rs:209:10:209:57 | [match(true)] OrPat | variables.rs:209:9:209:83 | [match(true)] OrPat | match | -| variables.rs:209:29:209:30 | a5 | variables.rs:209:10:209:57 | [match(true)] OrPat | match | -| variables.rs:209:35:209:57 | TupleStructPat | variables.rs:209:10:209:57 | [match(false)] OrPat | no-match | +| variables.rs:209:10:209:57 | [match(false)] ... \| ... | variables.rs:209:62:209:83 | TupleStructPat | no-match | +| variables.rs:209:10:209:57 | [match(true)] ... \| ... | variables.rs:209:9:209:83 | [match(true)] ... \| ... | match | +| variables.rs:209:29:209:30 | a5 | variables.rs:209:10:209:57 | [match(true)] ... \| ... | match | +| variables.rs:209:35:209:57 | TupleStructPat | variables.rs:209:10:209:57 | [match(false)] ... \| ... | no-match | | variables.rs:209:35:209:57 | TupleStructPat | variables.rs:209:55:209:56 | a5 | match | -| variables.rs:209:55:209:56 | a5 | variables.rs:209:10:209:57 | [match(true)] OrPat | match | +| variables.rs:209:55:209:56 | a5 | variables.rs:209:10:209:57 | [match(true)] ... \| ... | match | | variables.rs:209:62:209:83 | TupleStructPat | variables.rs:209:81:209:82 | a5 | match | -| variables.rs:209:81:209:82 | a5 | variables.rs:209:9:209:83 | [match(true)] OrPat | match | +| variables.rs:209:81:209:82 | a5 | variables.rs:209:9:209:83 | [match(true)] ... \| ... | match | | variables.rs:210:16:210:24 | print_i64 | variables.rs:210:26:210:27 | a5 | | -| variables.rs:210:16:210:28 | CallExpr | variables.rs:208:5:211:5 | MatchExpr | | -| variables.rs:210:26:210:27 | a5 | variables.rs:210:16:210:28 | CallExpr | | -| variables.rs:212:5:215:5 | MatchExpr | variables.rs:202:21:216:1 | BlockExpr | | +| variables.rs:210:16:210:28 | print_i64(...) | variables.rs:208:5:211:5 | match ... { ... } | | +| variables.rs:210:26:210:27 | a5 | variables.rs:210:16:210:28 | print_i64(...) | | +| variables.rs:212:5:215:5 | match ... { ... } | variables.rs:202:21:216:1 | { ... } | | | variables.rs:212:11:212:12 | tv | variables.rs:213:9:213:30 | TupleStructPat | | | variables.rs:213:9:213:30 | TupleStructPat | variables.rs:213:28:213:29 | a6 | match | | variables.rs:213:9:213:30 | TupleStructPat | variables.rs:213:35:213:57 | TupleStructPat | no-match | -| variables.rs:213:9:213:83 | [match(true)] OrPat | variables.rs:214:16:214:24 | print_i64 | match | -| variables.rs:213:28:213:29 | a6 | variables.rs:213:9:213:83 | [match(true)] OrPat | match | +| variables.rs:213:9:213:83 | [match(true)] ... \| ... | variables.rs:214:16:214:24 | print_i64 | match | +| variables.rs:213:28:213:29 | a6 | variables.rs:213:9:213:83 | [match(true)] ... \| ... | match | | variables.rs:213:35:213:57 | TupleStructPat | variables.rs:213:55:213:56 | a6 | match | | variables.rs:213:35:213:57 | TupleStructPat | variables.rs:213:61:213:82 | TupleStructPat | no-match | -| variables.rs:213:35:213:82 | [match(true)] OrPat | variables.rs:213:9:213:83 | [match(true)] OrPat | match | -| variables.rs:213:55:213:56 | a6 | variables.rs:213:35:213:82 | [match(true)] OrPat | match | +| variables.rs:213:35:213:82 | [match(true)] ... \| ... | variables.rs:213:9:213:83 | [match(true)] ... \| ... | match | +| variables.rs:213:55:213:56 | a6 | variables.rs:213:35:213:82 | [match(true)] ... \| ... | match | | variables.rs:213:61:213:82 | TupleStructPat | variables.rs:213:80:213:81 | a6 | match | -| variables.rs:213:80:213:81 | a6 | variables.rs:213:35:213:82 | [match(true)] OrPat | match | +| variables.rs:213:80:213:81 | a6 | variables.rs:213:35:213:82 | [match(true)] ... \| ... | match | | variables.rs:214:16:214:24 | print_i64 | variables.rs:214:26:214:27 | a6 | | -| variables.rs:214:16:214:28 | CallExpr | variables.rs:212:5:215:5 | MatchExpr | | -| variables.rs:214:26:214:27 | a6 | variables.rs:214:16:214:28 | CallExpr | | -| variables.rs:218:1:226:1 | enter match_pattern7 | variables.rs:219:5:219:34 | LetStmt | | -| variables.rs:218:1:226:1 | exit match_pattern7 (normal) | variables.rs:218:1:226:1 | exit match_pattern7 | | -| variables.rs:218:21:226:1 | BlockExpr | variables.rs:218:1:226:1 | exit match_pattern7 (normal) | | -| variables.rs:219:5:219:34 | LetStmt | variables.rs:219:18:219:29 | Either::Left | | +| variables.rs:214:16:214:28 | print_i64(...) | variables.rs:212:5:215:5 | match ... { ... } | | +| variables.rs:214:26:214:27 | a6 | variables.rs:214:16:214:28 | print_i64(...) | | +| variables.rs:218:1:226:1 | enter fn match_pattern7 | variables.rs:219:5:219:34 | let either = ... | | +| variables.rs:218:1:226:1 | exit fn match_pattern7 (normal) | variables.rs:218:1:226:1 | exit fn match_pattern7 | | +| variables.rs:218:21:226:1 | { ... } | variables.rs:218:1:226:1 | exit fn match_pattern7 (normal) | | +| variables.rs:219:5:219:34 | let either = ... | variables.rs:219:18:219:29 | Either::Left | | | variables.rs:219:9:219:14 | either | variables.rs:220:11:220:16 | either | match | | variables.rs:219:18:219:29 | Either::Left | variables.rs:219:31:219:32 | 32 | | -| variables.rs:219:18:219:33 | CallExpr | variables.rs:219:9:219:14 | either | | -| variables.rs:219:31:219:32 | 32 | variables.rs:219:18:219:33 | CallExpr | | -| variables.rs:220:5:225:5 | MatchExpr | variables.rs:218:21:226:1 | BlockExpr | | +| variables.rs:219:18:219:33 | Either::Left(...) | variables.rs:219:9:219:14 | either | | +| variables.rs:219:31:219:32 | 32 | variables.rs:219:18:219:33 | Either::Left(...) | | +| variables.rs:220:5:225:5 | match ... { ... } | variables.rs:218:21:226:1 | { ... } | | | variables.rs:220:11:220:16 | either | variables.rs:221:9:221:24 | TupleStructPat | | | variables.rs:221:9:221:24 | TupleStructPat | variables.rs:221:22:221:23 | a7 | match | | variables.rs:221:9:221:24 | TupleStructPat | variables.rs:221:28:221:44 | TupleStructPat | no-match | -| variables.rs:221:9:221:44 | [match(false)] OrPat | variables.rs:224:9:224:9 | WildcardPat | no-match | -| variables.rs:221:9:221:44 | [match(true)] OrPat | variables.rs:222:16:222:17 | a7 | match | -| variables.rs:221:22:221:23 | a7 | variables.rs:221:9:221:44 | [match(true)] OrPat | match | -| variables.rs:221:28:221:44 | TupleStructPat | variables.rs:221:9:221:44 | [match(false)] OrPat | no-match | +| variables.rs:221:9:221:44 | [match(false)] ... \| ... | variables.rs:224:9:224:9 | _ | no-match | +| variables.rs:221:9:221:44 | [match(true)] ... \| ... | variables.rs:222:16:222:17 | a7 | match | +| variables.rs:221:22:221:23 | a7 | variables.rs:221:9:221:44 | [match(true)] ... \| ... | match | +| variables.rs:221:28:221:44 | TupleStructPat | variables.rs:221:9:221:44 | [match(false)] ... \| ... | no-match | | variables.rs:221:28:221:44 | TupleStructPat | variables.rs:221:42:221:43 | a7 | match | -| variables.rs:221:42:221:43 | a7 | variables.rs:221:9:221:44 | [match(true)] OrPat | match | +| variables.rs:221:42:221:43 | a7 | variables.rs:221:9:221:44 | [match(true)] ... \| ... | match | | variables.rs:222:16:222:17 | a7 | variables.rs:222:21:222:21 | 0 | | | variables.rs:222:16:222:21 | ... > ... | variables.rs:223:16:223:24 | print_i64 | true | -| variables.rs:222:16:222:21 | ... > ... | variables.rs:224:9:224:9 | WildcardPat | false | +| variables.rs:222:16:222:21 | ... > ... | variables.rs:224:9:224:9 | _ | false | | variables.rs:222:21:222:21 | 0 | variables.rs:222:16:222:21 | ... > ... | | | variables.rs:223:16:223:24 | print_i64 | variables.rs:223:26:223:27 | a7 | | -| variables.rs:223:16:223:28 | CallExpr | variables.rs:220:5:225:5 | MatchExpr | | -| variables.rs:223:26:223:27 | a7 | variables.rs:223:16:223:28 | CallExpr | | -| variables.rs:224:9:224:9 | WildcardPat | variables.rs:224:14:224:15 | TupleExpr | match | -| variables.rs:224:14:224:15 | TupleExpr | variables.rs:220:5:225:5 | MatchExpr | | -| variables.rs:228:1:243:1 | enter match_pattern8 | variables.rs:229:5:229:34 | LetStmt | | -| variables.rs:228:1:243:1 | exit match_pattern8 (normal) | variables.rs:228:1:243:1 | exit match_pattern8 | | -| variables.rs:228:21:243:1 | BlockExpr | variables.rs:228:1:243:1 | exit match_pattern8 (normal) | | -| variables.rs:229:5:229:34 | LetStmt | variables.rs:229:18:229:29 | Either::Left | | +| variables.rs:223:16:223:28 | print_i64(...) | variables.rs:220:5:225:5 | match ... { ... } | | +| variables.rs:223:26:223:27 | a7 | variables.rs:223:16:223:28 | print_i64(...) | | +| variables.rs:224:9:224:9 | _ | variables.rs:224:14:224:15 | TupleExpr | match | +| variables.rs:224:14:224:15 | TupleExpr | variables.rs:220:5:225:5 | match ... { ... } | | +| variables.rs:228:1:243:1 | enter fn match_pattern8 | variables.rs:229:5:229:34 | let either = ... | | +| variables.rs:228:1:243:1 | exit fn match_pattern8 (normal) | variables.rs:228:1:243:1 | exit fn match_pattern8 | | +| variables.rs:228:21:243:1 | { ... } | variables.rs:228:1:243:1 | exit fn match_pattern8 (normal) | | +| variables.rs:229:5:229:34 | let either = ... | variables.rs:229:18:229:29 | Either::Left | | | variables.rs:229:9:229:14 | either | variables.rs:231:11:231:16 | either | match | | variables.rs:229:18:229:29 | Either::Left | variables.rs:229:31:229:32 | 32 | | -| variables.rs:229:18:229:33 | CallExpr | variables.rs:229:9:229:14 | either | | -| variables.rs:229:31:229:32 | 32 | variables.rs:229:18:229:33 | CallExpr | | -| variables.rs:231:5:242:5 | MatchExpr | variables.rs:228:21:243:1 | BlockExpr | | +| variables.rs:229:18:229:33 | Either::Left(...) | variables.rs:229:9:229:14 | either | | +| variables.rs:229:31:229:32 | 32 | variables.rs:229:18:229:33 | Either::Left(...) | | +| variables.rs:231:5:242:5 | match ... { ... } | variables.rs:228:21:243:1 | { ... } | | | variables.rs:231:11:231:16 | either | variables.rs:233:14:233:30 | TupleStructPat | | | variables.rs:232:9:233:52 | [match(true)] e | variables.rs:235:13:235:27 | ExprStmt | match | | variables.rs:233:14:233:30 | TupleStructPat | variables.rs:233:27:233:29 | a11 | match | | variables.rs:233:14:233:30 | TupleStructPat | variables.rs:233:34:233:51 | TupleStructPat | no-match | -| variables.rs:233:14:233:51 | [match(false)] OrPat | variables.rs:241:9:241:9 | WildcardPat | no-match | -| variables.rs:233:14:233:51 | [match(true)] OrPat | variables.rs:232:9:233:52 | [match(true)] e | match | -| variables.rs:233:27:233:29 | a11 | variables.rs:233:14:233:51 | [match(true)] OrPat | match | -| variables.rs:233:34:233:51 | TupleStructPat | variables.rs:233:14:233:51 | [match(false)] OrPat | no-match | +| variables.rs:233:14:233:51 | [match(false)] ... \| ... | variables.rs:241:9:241:9 | _ | no-match | +| variables.rs:233:14:233:51 | [match(true)] ... \| ... | variables.rs:232:9:233:52 | [match(true)] e | match | +| variables.rs:233:27:233:29 | a11 | variables.rs:233:14:233:51 | [match(true)] ... \| ... | match | +| variables.rs:233:34:233:51 | TupleStructPat | variables.rs:233:14:233:51 | [match(false)] ... \| ... | no-match | | variables.rs:233:34:233:51 | TupleStructPat | variables.rs:233:48:233:50 | a11 | match | -| variables.rs:233:48:233:50 | a11 | variables.rs:233:14:233:51 | [match(true)] OrPat | match | -| variables.rs:234:12:240:9 | BlockExpr | variables.rs:231:5:242:5 | MatchExpr | | +| variables.rs:233:48:233:50 | a11 | variables.rs:233:14:233:51 | [match(true)] ... \| ... | match | +| variables.rs:234:12:240:9 | { ... } | variables.rs:231:5:242:5 | match ... { ... } | | | variables.rs:235:13:235:21 | print_i64 | variables.rs:235:23:235:25 | a11 | | -| variables.rs:235:13:235:26 | CallExpr | variables.rs:236:16:237:15 | LetExpr | | +| variables.rs:235:13:235:26 | print_i64(...) | variables.rs:236:16:237:15 | let TupleStructPat = ... | | | variables.rs:235:13:235:27 | ExprStmt | variables.rs:235:13:235:21 | print_i64 | | -| variables.rs:235:23:235:25 | a11 | variables.rs:235:13:235:26 | CallExpr | | -| variables.rs:236:13:239:13 | IfExpr | variables.rs:234:12:240:9 | BlockExpr | | -| variables.rs:236:16:237:15 | LetExpr | variables.rs:237:15:237:15 | e | | -| variables.rs:236:20:236:36 | TupleStructPat | variables.rs:236:13:239:13 | IfExpr | no-match | +| variables.rs:235:23:235:25 | a11 | variables.rs:235:13:235:26 | print_i64(...) | | +| variables.rs:236:13:239:13 | if ... { ... } | variables.rs:234:12:240:9 | { ... } | | +| variables.rs:236:16:237:15 | let TupleStructPat = ... | variables.rs:237:15:237:15 | e | | +| variables.rs:236:20:236:36 | TupleStructPat | variables.rs:236:13:239:13 | if ... { ... } | no-match | | variables.rs:236:20:236:36 | TupleStructPat | variables.rs:236:33:236:35 | a12 | match | | variables.rs:236:33:236:35 | a12 | variables.rs:238:17:238:32 | ExprStmt | match | | variables.rs:237:15:237:15 | e | variables.rs:236:20:236:36 | TupleStructPat | | -| variables.rs:237:17:239:13 | BlockExpr | variables.rs:236:13:239:13 | IfExpr | | +| variables.rs:237:17:239:13 | { ... } | variables.rs:236:13:239:13 | if ... { ... } | | | variables.rs:238:17:238:25 | print_i64 | variables.rs:238:28:238:30 | a12 | | -| variables.rs:238:17:238:31 | CallExpr | variables.rs:237:17:239:13 | BlockExpr | | +| variables.rs:238:17:238:31 | print_i64(...) | variables.rs:237:17:239:13 | { ... } | | | variables.rs:238:17:238:32 | ExprStmt | variables.rs:238:17:238:25 | print_i64 | | -| variables.rs:238:27:238:30 | * ... | variables.rs:238:17:238:31 | CallExpr | | +| variables.rs:238:27:238:30 | * ... | variables.rs:238:17:238:31 | print_i64(...) | | | variables.rs:238:28:238:30 | a12 | variables.rs:238:27:238:30 | * ... | | -| variables.rs:241:9:241:9 | WildcardPat | variables.rs:241:14:241:15 | TupleExpr | match | -| variables.rs:241:14:241:15 | TupleExpr | variables.rs:231:5:242:5 | MatchExpr | | -| variables.rs:252:1:258:1 | enter match_pattern9 | variables.rs:253:5:253:36 | LetStmt | | -| variables.rs:252:1:258:1 | exit match_pattern9 (normal) | variables.rs:252:1:258:1 | exit match_pattern9 | | -| variables.rs:252:21:258:1 | BlockExpr | variables.rs:252:1:258:1 | exit match_pattern9 (normal) | | -| variables.rs:253:5:253:36 | LetStmt | variables.rs:253:14:253:31 | FourValued::Second | | +| variables.rs:241:9:241:9 | _ | variables.rs:241:14:241:15 | TupleExpr | match | +| variables.rs:241:14:241:15 | TupleExpr | variables.rs:231:5:242:5 | match ... { ... } | | +| variables.rs:252:1:258:1 | enter fn match_pattern9 | variables.rs:253:5:253:36 | let fv = ... | | +| variables.rs:252:1:258:1 | exit fn match_pattern9 (normal) | variables.rs:252:1:258:1 | exit fn match_pattern9 | | +| variables.rs:252:21:258:1 | { ... } | variables.rs:252:1:258:1 | exit fn match_pattern9 (normal) | | +| variables.rs:253:5:253:36 | let fv = ... | variables.rs:253:14:253:31 | FourValued::Second | | | variables.rs:253:9:253:10 | fv | variables.rs:254:11:254:12 | fv | match | | variables.rs:253:14:253:31 | FourValued::Second | variables.rs:253:33:253:34 | 62 | | -| variables.rs:253:14:253:35 | CallExpr | variables.rs:253:9:253:10 | fv | | -| variables.rs:253:33:253:34 | 62 | variables.rs:253:14:253:35 | CallExpr | | -| variables.rs:254:5:257:5 | MatchExpr | variables.rs:252:21:258:1 | BlockExpr | | +| variables.rs:253:14:253:35 | FourValued::Second(...) | variables.rs:253:9:253:10 | fv | | +| variables.rs:253:33:253:34 | 62 | variables.rs:253:14:253:35 | FourValued::Second(...) | | +| variables.rs:254:5:257:5 | match ... { ... } | variables.rs:252:21:258:1 | { ... } | | | variables.rs:254:11:254:12 | fv | variables.rs:255:9:255:30 | TupleStructPat | | | variables.rs:255:9:255:30 | TupleStructPat | variables.rs:255:27:255:29 | a13 | match | | variables.rs:255:9:255:30 | TupleStructPat | variables.rs:255:35:255:57 | TupleStructPat | no-match | -| variables.rs:255:9:255:109 | [match(true)] OrPat | variables.rs:256:16:256:24 | print_i64 | match | -| variables.rs:255:27:255:29 | a13 | variables.rs:255:9:255:109 | [match(true)] OrPat | match | +| variables.rs:255:9:255:109 | [match(true)] ... \| ... | variables.rs:256:16:256:24 | print_i64 | match | +| variables.rs:255:27:255:29 | a13 | variables.rs:255:9:255:109 | [match(true)] ... \| ... | match | | variables.rs:255:35:255:57 | TupleStructPat | variables.rs:255:54:255:56 | a13 | match | | variables.rs:255:35:255:57 | TupleStructPat | variables.rs:255:61:255:82 | TupleStructPat | no-match | -| variables.rs:255:35:255:82 | [match(false)] OrPat | variables.rs:255:87:255:109 | TupleStructPat | no-match | -| variables.rs:255:35:255:82 | [match(true)] OrPat | variables.rs:255:9:255:109 | [match(true)] OrPat | match | -| variables.rs:255:54:255:56 | a13 | variables.rs:255:35:255:82 | [match(true)] OrPat | match | -| variables.rs:255:61:255:82 | TupleStructPat | variables.rs:255:35:255:82 | [match(false)] OrPat | no-match | +| variables.rs:255:35:255:82 | [match(false)] ... \| ... | variables.rs:255:87:255:109 | TupleStructPat | no-match | +| variables.rs:255:35:255:82 | [match(true)] ... \| ... | variables.rs:255:9:255:109 | [match(true)] ... \| ... | match | +| variables.rs:255:54:255:56 | a13 | variables.rs:255:35:255:82 | [match(true)] ... \| ... | match | +| variables.rs:255:61:255:82 | TupleStructPat | variables.rs:255:35:255:82 | [match(false)] ... \| ... | no-match | | variables.rs:255:61:255:82 | TupleStructPat | variables.rs:255:79:255:81 | a13 | match | -| variables.rs:255:79:255:81 | a13 | variables.rs:255:35:255:82 | [match(true)] OrPat | match | +| variables.rs:255:79:255:81 | a13 | variables.rs:255:35:255:82 | [match(true)] ... \| ... | match | | variables.rs:255:87:255:109 | TupleStructPat | variables.rs:255:106:255:108 | a13 | match | -| variables.rs:255:106:255:108 | a13 | variables.rs:255:9:255:109 | [match(true)] OrPat | match | +| variables.rs:255:106:255:108 | a13 | variables.rs:255:9:255:109 | [match(true)] ... \| ... | match | | variables.rs:256:16:256:24 | print_i64 | variables.rs:256:26:256:28 | a13 | | -| variables.rs:256:16:256:29 | CallExpr | variables.rs:254:5:257:5 | MatchExpr | | -| variables.rs:256:26:256:28 | a13 | variables.rs:256:16:256:29 | CallExpr | | -| variables.rs:260:1:269:1 | enter param_pattern1 | variables.rs:261:5:261:6 | a8 | | -| variables.rs:260:1:269:1 | exit param_pattern1 (normal) | variables.rs:260:1:269:1 | exit param_pattern1 | | -| variables.rs:261:5:261:6 | a8 | variables.rs:261:5:261:12 | Param | match | -| variables.rs:261:5:261:12 | Param | variables.rs:262:5:265:5 | TuplePat | | +| variables.rs:256:16:256:29 | print_i64(...) | variables.rs:254:5:257:5 | match ... { ... } | | +| variables.rs:256:26:256:28 | a13 | variables.rs:256:16:256:29 | print_i64(...) | | +| variables.rs:260:1:269:1 | enter fn param_pattern1 | variables.rs:261:5:261:6 | a8 | | +| variables.rs:260:1:269:1 | exit fn param_pattern1 (normal) | variables.rs:260:1:269:1 | exit fn param_pattern1 | | +| variables.rs:261:5:261:6 | a8 | variables.rs:261:5:261:12 | a8: RefType | match | +| variables.rs:261:5:261:12 | a8: RefType | variables.rs:262:5:265:5 | TuplePat | | | variables.rs:262:5:265:5 | TuplePat | variables.rs:263:9:263:10 | b3 | match | -| variables.rs:262:5:265:19 | Param | variables.rs:266:5:266:18 | ExprStmt | | +| variables.rs:262:5:265:19 | TuplePat: TupleType | variables.rs:266:5:266:18 | ExprStmt | | | variables.rs:263:9:263:10 | b3 | variables.rs:264:9:264:10 | c1 | match | -| variables.rs:264:9:264:10 | c1 | variables.rs:262:5:265:19 | Param | match | -| variables.rs:265:28:269:1 | BlockExpr | variables.rs:260:1:269:1 | exit param_pattern1 (normal) | | +| variables.rs:264:9:264:10 | c1 | variables.rs:262:5:265:19 | TuplePat: TupleType | match | +| variables.rs:265:28:269:1 | { ... } | variables.rs:260:1:269:1 | exit fn param_pattern1 (normal) | | | variables.rs:266:5:266:13 | print_str | variables.rs:266:15:266:16 | a8 | | -| variables.rs:266:5:266:17 | CallExpr | variables.rs:267:5:267:18 | ExprStmt | | +| variables.rs:266:5:266:17 | print_str(...) | variables.rs:267:5:267:18 | ExprStmt | | | variables.rs:266:5:266:18 | ExprStmt | variables.rs:266:5:266:13 | print_str | | -| variables.rs:266:15:266:16 | a8 | variables.rs:266:5:266:17 | CallExpr | | +| variables.rs:266:15:266:16 | a8 | variables.rs:266:5:266:17 | print_str(...) | | | variables.rs:267:5:267:13 | print_str | variables.rs:267:15:267:16 | b3 | | -| variables.rs:267:5:267:17 | CallExpr | variables.rs:268:5:268:18 | ExprStmt | | +| variables.rs:267:5:267:17 | print_str(...) | variables.rs:268:5:268:18 | ExprStmt | | | variables.rs:267:5:267:18 | ExprStmt | variables.rs:267:5:267:13 | print_str | | -| variables.rs:267:15:267:16 | b3 | variables.rs:267:5:267:17 | CallExpr | | +| variables.rs:267:15:267:16 | b3 | variables.rs:267:5:267:17 | print_str(...) | | | variables.rs:268:5:268:13 | print_str | variables.rs:268:15:268:16 | c1 | | -| variables.rs:268:5:268:17 | CallExpr | variables.rs:265:28:269:1 | BlockExpr | | +| variables.rs:268:5:268:17 | print_str(...) | variables.rs:265:28:269:1 | { ... } | | | variables.rs:268:5:268:18 | ExprStmt | variables.rs:268:5:268:13 | print_str | | -| variables.rs:268:15:268:16 | c1 | variables.rs:268:5:268:17 | CallExpr | | -| variables.rs:271:1:275:1 | enter param_pattern2 | variables.rs:272:6:272:21 | TupleStructPat | | -| variables.rs:271:1:275:1 | exit param_pattern2 (normal) | variables.rs:271:1:275:1 | exit param_pattern2 | | -| variables.rs:272:5:272:50 | Param | variables.rs:274:5:274:18 | ExprStmt | | +| variables.rs:268:15:268:16 | c1 | variables.rs:268:5:268:17 | print_str(...) | | +| variables.rs:271:1:275:1 | enter fn param_pattern2 | variables.rs:272:6:272:21 | TupleStructPat | | +| variables.rs:271:1:275:1 | exit fn param_pattern2 (normal) | variables.rs:271:1:275:1 | exit fn param_pattern2 | | +| variables.rs:272:5:272:50 | (...): Either | variables.rs:274:5:274:18 | ExprStmt | | | variables.rs:272:6:272:21 | TupleStructPat | variables.rs:272:19:272:20 | a9 | match | | variables.rs:272:6:272:21 | TupleStructPat | variables.rs:272:25:272:41 | TupleStructPat | no-match | -| variables.rs:272:6:272:41 | [match(true)] OrPat | variables.rs:272:5:272:50 | Param | match | -| variables.rs:272:19:272:20 | a9 | variables.rs:272:6:272:41 | [match(true)] OrPat | match | +| variables.rs:272:6:272:41 | [match(true)] ... \| ... | variables.rs:272:5:272:50 | (...): Either | match | +| variables.rs:272:19:272:20 | a9 | variables.rs:272:6:272:41 | [match(true)] ... \| ... | match | | variables.rs:272:25:272:41 | TupleStructPat | variables.rs:272:39:272:40 | a9 | match | -| variables.rs:272:39:272:40 | a9 | variables.rs:272:6:272:41 | [match(true)] OrPat | match | -| variables.rs:273:9:275:1 | BlockExpr | variables.rs:271:1:275:1 | exit param_pattern2 (normal) | | +| variables.rs:272:39:272:40 | a9 | variables.rs:272:6:272:41 | [match(true)] ... \| ... | match | +| variables.rs:273:9:275:1 | { ... } | variables.rs:271:1:275:1 | exit fn param_pattern2 (normal) | | | variables.rs:274:5:274:13 | print_i64 | variables.rs:274:15:274:16 | a9 | | -| variables.rs:274:5:274:17 | CallExpr | variables.rs:273:9:275:1 | BlockExpr | | +| variables.rs:274:5:274:17 | print_i64(...) | variables.rs:273:9:275:1 | { ... } | | | variables.rs:274:5:274:18 | ExprStmt | variables.rs:274:5:274:13 | print_i64 | | -| variables.rs:274:15:274:16 | a9 | variables.rs:274:5:274:17 | CallExpr | | -| variables.rs:277:1:312:1 | enter destruct_assignment | variables.rs:278:5:282:18 | LetStmt | | -| variables.rs:277:1:312:1 | exit destruct_assignment (normal) | variables.rs:277:1:312:1 | exit destruct_assignment | | -| variables.rs:277:26:312:1 | BlockExpr | variables.rs:277:1:312:1 | exit destruct_assignment (normal) | | -| variables.rs:278:5:282:18 | LetStmt | variables.rs:282:10:282:10 | 1 | | +| variables.rs:274:15:274:16 | a9 | variables.rs:274:5:274:17 | print_i64(...) | | +| variables.rs:277:1:312:1 | enter fn destruct_assignment | variables.rs:278:5:282:18 | let TuplePat = ... | | +| variables.rs:277:1:312:1 | exit fn destruct_assignment (normal) | variables.rs:277:1:312:1 | exit fn destruct_assignment | | +| variables.rs:277:26:312:1 | { ... } | variables.rs:277:1:312:1 | exit fn destruct_assignment (normal) | | +| variables.rs:278:5:282:18 | let TuplePat = ... | variables.rs:282:10:282:10 | 1 | | | variables.rs:278:9:282:5 | TuplePat | variables.rs:279:9:279:15 | a10 | match | | variables.rs:279:9:279:15 | a10 | variables.rs:280:9:280:14 | b4 | match | | variables.rs:280:9:280:14 | b4 | variables.rs:281:9:281:14 | c2 | match | @@ -609,17 +609,17 @@ edges | variables.rs:282:13:282:13 | 2 | variables.rs:282:16:282:16 | 3 | | | variables.rs:282:16:282:16 | 3 | variables.rs:282:9:282:17 | TupleExpr | | | variables.rs:283:5:283:13 | print_i64 | variables.rs:283:15:283:17 | a10 | | -| variables.rs:283:5:283:18 | CallExpr | variables.rs:284:5:284:18 | ExprStmt | | +| variables.rs:283:5:283:18 | print_i64(...) | variables.rs:284:5:284:18 | ExprStmt | | | variables.rs:283:5:283:19 | ExprStmt | variables.rs:283:5:283:13 | print_i64 | | -| variables.rs:283:15:283:17 | a10 | variables.rs:283:5:283:18 | CallExpr | | +| variables.rs:283:15:283:17 | a10 | variables.rs:283:5:283:18 | print_i64(...) | | | variables.rs:284:5:284:13 | print_i64 | variables.rs:284:15:284:16 | b4 | | -| variables.rs:284:5:284:17 | CallExpr | variables.rs:285:5:285:18 | ExprStmt | | +| variables.rs:284:5:284:17 | print_i64(...) | variables.rs:285:5:285:18 | ExprStmt | | | variables.rs:284:5:284:18 | ExprStmt | variables.rs:284:5:284:13 | print_i64 | | -| variables.rs:284:15:284:16 | b4 | variables.rs:284:5:284:17 | CallExpr | | +| variables.rs:284:15:284:16 | b4 | variables.rs:284:5:284:17 | print_i64(...) | | | variables.rs:285:5:285:13 | print_i64 | variables.rs:285:15:285:16 | c2 | | -| variables.rs:285:5:285:17 | CallExpr | variables.rs:287:5:295:6 | ExprStmt | | +| variables.rs:285:5:285:17 | print_i64(...) | variables.rs:287:5:295:6 | ExprStmt | | | variables.rs:285:5:285:18 | ExprStmt | variables.rs:285:5:285:13 | print_i64 | | -| variables.rs:285:15:285:16 | c2 | variables.rs:285:5:285:17 | CallExpr | | +| variables.rs:285:15:285:16 | c2 | variables.rs:285:5:285:17 | print_i64(...) | | | variables.rs:287:5:291:5 | TupleExpr | variables.rs:292:9:292:11 | a10 | | | variables.rs:287:5:295:5 | ... = ... | variables.rs:296:5:296:19 | ExprStmt | | | variables.rs:287:5:295:6 | ExprStmt | variables.rs:288:9:288:10 | c2 | | @@ -631,105 +631,105 @@ edges | variables.rs:293:9:293:10 | b4 | variables.rs:294:9:294:10 | c2 | | | variables.rs:294:9:294:10 | c2 | variables.rs:291:9:295:5 | TupleExpr | | | variables.rs:296:5:296:13 | print_i64 | variables.rs:296:15:296:17 | a10 | | -| variables.rs:296:5:296:18 | CallExpr | variables.rs:297:5:297:18 | ExprStmt | | +| variables.rs:296:5:296:18 | print_i64(...) | variables.rs:297:5:297:18 | ExprStmt | | | variables.rs:296:5:296:19 | ExprStmt | variables.rs:296:5:296:13 | print_i64 | | -| variables.rs:296:15:296:17 | a10 | variables.rs:296:5:296:18 | CallExpr | | +| variables.rs:296:15:296:17 | a10 | variables.rs:296:5:296:18 | print_i64(...) | | | variables.rs:297:5:297:13 | print_i64 | variables.rs:297:15:297:16 | b4 | | -| variables.rs:297:5:297:17 | CallExpr | variables.rs:298:5:298:18 | ExprStmt | | +| variables.rs:297:5:297:17 | print_i64(...) | variables.rs:298:5:298:18 | ExprStmt | | | variables.rs:297:5:297:18 | ExprStmt | variables.rs:297:5:297:13 | print_i64 | | -| variables.rs:297:15:297:16 | b4 | variables.rs:297:5:297:17 | CallExpr | | +| variables.rs:297:15:297:16 | b4 | variables.rs:297:5:297:17 | print_i64(...) | | | variables.rs:298:5:298:13 | print_i64 | variables.rs:298:15:298:16 | c2 | | -| variables.rs:298:5:298:17 | CallExpr | variables.rs:300:5:308:5 | ExprStmt | | +| variables.rs:298:5:298:17 | print_i64(...) | variables.rs:300:5:308:5 | ExprStmt | | | variables.rs:298:5:298:18 | ExprStmt | variables.rs:298:5:298:13 | print_i64 | | -| variables.rs:298:15:298:16 | c2 | variables.rs:298:5:298:17 | CallExpr | | +| variables.rs:298:15:298:16 | c2 | variables.rs:298:5:298:17 | print_i64(...) | | | variables.rs:300:5:308:5 | ExprStmt | variables.rs:300:12:300:12 | 4 | | -| variables.rs:300:5:308:5 | MatchExpr | variables.rs:310:5:310:19 | ExprStmt | | +| variables.rs:300:5:308:5 | match ... { ... } | variables.rs:310:5:310:19 | ExprStmt | | | variables.rs:300:11:300:16 | TupleExpr | variables.rs:301:9:304:9 | TuplePat | | | variables.rs:300:12:300:12 | 4 | variables.rs:300:15:300:15 | 5 | | | variables.rs:300:15:300:15 | 5 | variables.rs:300:11:300:16 | TupleExpr | | | variables.rs:301:9:304:9 | TuplePat | variables.rs:302:13:302:15 | a10 | match | | variables.rs:302:13:302:15 | a10 | variables.rs:303:13:303:14 | b4 | match | | variables.rs:303:13:303:14 | b4 | variables.rs:305:13:305:27 | ExprStmt | match | -| variables.rs:304:14:307:9 | BlockExpr | variables.rs:300:5:308:5 | MatchExpr | | +| variables.rs:304:14:307:9 | { ... } | variables.rs:300:5:308:5 | match ... { ... } | | | variables.rs:305:13:305:21 | print_i64 | variables.rs:305:23:305:25 | a10 | | -| variables.rs:305:13:305:26 | CallExpr | variables.rs:306:13:306:26 | ExprStmt | | +| variables.rs:305:13:305:26 | print_i64(...) | variables.rs:306:13:306:26 | ExprStmt | | | variables.rs:305:13:305:27 | ExprStmt | variables.rs:305:13:305:21 | print_i64 | | -| variables.rs:305:23:305:25 | a10 | variables.rs:305:13:305:26 | CallExpr | | +| variables.rs:305:23:305:25 | a10 | variables.rs:305:13:305:26 | print_i64(...) | | | variables.rs:306:13:306:21 | print_i64 | variables.rs:306:23:306:24 | b4 | | -| variables.rs:306:13:306:25 | CallExpr | variables.rs:304:14:307:9 | BlockExpr | | +| variables.rs:306:13:306:25 | print_i64(...) | variables.rs:304:14:307:9 | { ... } | | | variables.rs:306:13:306:26 | ExprStmt | variables.rs:306:13:306:21 | print_i64 | | -| variables.rs:306:23:306:24 | b4 | variables.rs:306:13:306:25 | CallExpr | | +| variables.rs:306:23:306:24 | b4 | variables.rs:306:13:306:25 | print_i64(...) | | | variables.rs:310:5:310:13 | print_i64 | variables.rs:310:15:310:17 | a10 | | -| variables.rs:310:5:310:18 | CallExpr | variables.rs:311:5:311:18 | ExprStmt | | +| variables.rs:310:5:310:18 | print_i64(...) | variables.rs:311:5:311:18 | ExprStmt | | | variables.rs:310:5:310:19 | ExprStmt | variables.rs:310:5:310:13 | print_i64 | | -| variables.rs:310:15:310:17 | a10 | variables.rs:310:5:310:18 | CallExpr | | +| variables.rs:310:15:310:17 | a10 | variables.rs:310:5:310:18 | print_i64(...) | | | variables.rs:311:5:311:13 | print_i64 | variables.rs:311:15:311:16 | b4 | | -| variables.rs:311:5:311:17 | CallExpr | variables.rs:277:26:312:1 | BlockExpr | | +| variables.rs:311:5:311:17 | print_i64(...) | variables.rs:277:26:312:1 | { ... } | | | variables.rs:311:5:311:18 | ExprStmt | variables.rs:311:5:311:13 | print_i64 | | -| variables.rs:311:15:311:16 | b4 | variables.rs:311:5:311:17 | CallExpr | | -| variables.rs:314:1:329:1 | enter closure_variable | variables.rs:315:5:317:10 | LetStmt | | -| variables.rs:314:1:329:1 | exit closure_variable (normal) | variables.rs:314:1:329:1 | exit closure_variable | | -| variables.rs:314:23:329:1 | BlockExpr | variables.rs:314:1:329:1 | exit closure_variable (normal) | | -| variables.rs:315:5:317:10 | LetStmt | variables.rs:316:9:317:9 | ClosureExpr | | -| variables.rs:315:9:315:23 | example_closure | variables.rs:318:5:319:27 | LetStmt | match | -| variables.rs:316:9:317:9 | ClosureExpr | variables.rs:315:9:315:23 | example_closure | | -| variables.rs:316:9:317:9 | enter ClosureExpr | variables.rs:316:10:316:10 | x | | -| variables.rs:316:9:317:9 | exit ClosureExpr (normal) | variables.rs:316:9:317:9 | exit ClosureExpr | | -| variables.rs:316:10:316:10 | x | variables.rs:316:10:316:15 | Param | match | -| variables.rs:316:10:316:15 | Param | variables.rs:317:9:317:9 | x | | -| variables.rs:317:9:317:9 | x | variables.rs:316:9:317:9 | exit ClosureExpr (normal) | | -| variables.rs:318:5:319:27 | LetStmt | variables.rs:319:9:319:23 | example_closure | | +| variables.rs:311:15:311:16 | b4 | variables.rs:311:5:311:17 | print_i64(...) | | +| variables.rs:314:1:329:1 | enter fn closure_variable | variables.rs:315:5:317:10 | let example_closure = ... | | +| variables.rs:314:1:329:1 | exit fn closure_variable (normal) | variables.rs:314:1:329:1 | exit fn closure_variable | | +| variables.rs:314:23:329:1 | { ... } | variables.rs:314:1:329:1 | exit fn closure_variable (normal) | | +| variables.rs:315:5:317:10 | let example_closure = ... | variables.rs:316:9:317:9 | \|...\| ... | | +| variables.rs:315:9:315:23 | example_closure | variables.rs:318:5:319:27 | let n1 = ... | match | +| variables.rs:316:9:317:9 | \|...\| ... | variables.rs:315:9:315:23 | example_closure | | +| variables.rs:316:9:317:9 | enter \|...\| ... | variables.rs:316:10:316:10 | x | | +| variables.rs:316:9:317:9 | exit \|...\| ... (normal) | variables.rs:316:9:317:9 | exit \|...\| ... | | +| variables.rs:316:10:316:10 | x | variables.rs:316:10:316:15 | x: i64 | match | +| variables.rs:316:10:316:15 | x: i64 | variables.rs:317:9:317:9 | x | | +| variables.rs:317:9:317:9 | x | variables.rs:316:9:317:9 | exit \|...\| ... (normal) | | +| variables.rs:318:5:319:27 | let n1 = ... | variables.rs:319:9:319:23 | example_closure | | | variables.rs:318:9:318:10 | n1 | variables.rs:320:5:320:18 | ExprStmt | match | | variables.rs:319:9:319:23 | example_closure | variables.rs:319:25:319:25 | 5 | | -| variables.rs:319:9:319:26 | CallExpr | variables.rs:318:9:318:10 | n1 | | -| variables.rs:319:25:319:25 | 5 | variables.rs:319:9:319:26 | CallExpr | | +| variables.rs:319:9:319:26 | example_closure(...) | variables.rs:318:9:318:10 | n1 | | +| variables.rs:319:25:319:25 | 5 | variables.rs:319:9:319:26 | example_closure(...) | | | variables.rs:320:5:320:13 | print_i64 | variables.rs:320:15:320:16 | n1 | | -| variables.rs:320:5:320:17 | CallExpr | variables.rs:322:5:322:25 | ExprStmt | | +| variables.rs:320:5:320:17 | print_i64(...) | variables.rs:322:5:322:25 | ExprStmt | | | variables.rs:320:5:320:18 | ExprStmt | variables.rs:320:5:320:13 | print_i64 | | -| variables.rs:320:15:320:16 | n1 | variables.rs:320:5:320:17 | CallExpr | | -| variables.rs:322:5:322:22 | immutable_variable | variables.rs:322:5:322:24 | CallExpr | | -| variables.rs:322:5:322:24 | CallExpr | variables.rs:323:5:325:10 | LetStmt | | +| variables.rs:320:15:320:16 | n1 | variables.rs:320:5:320:17 | print_i64(...) | | +| variables.rs:322:5:322:22 | immutable_variable | variables.rs:322:5:322:24 | immutable_variable(...) | | +| variables.rs:322:5:322:24 | immutable_variable(...) | variables.rs:323:5:325:10 | let immutable_variable = ... | | | variables.rs:322:5:322:25 | ExprStmt | variables.rs:322:5:322:22 | immutable_variable | | -| variables.rs:323:5:325:10 | LetStmt | variables.rs:324:9:325:9 | ClosureExpr | | -| variables.rs:323:9:323:26 | immutable_variable | variables.rs:326:5:327:30 | LetStmt | match | -| variables.rs:324:9:325:9 | ClosureExpr | variables.rs:323:9:323:26 | immutable_variable | | -| variables.rs:324:9:325:9 | enter ClosureExpr | variables.rs:324:10:324:10 | x | | -| variables.rs:324:9:325:9 | exit ClosureExpr (normal) | variables.rs:324:9:325:9 | exit ClosureExpr | | -| variables.rs:324:10:324:10 | x | variables.rs:324:10:324:15 | Param | match | -| variables.rs:324:10:324:15 | Param | variables.rs:325:9:325:9 | x | | -| variables.rs:325:9:325:9 | x | variables.rs:324:9:325:9 | exit ClosureExpr (normal) | | -| variables.rs:326:5:327:30 | LetStmt | variables.rs:327:9:327:26 | immutable_variable | | +| variables.rs:323:5:325:10 | let immutable_variable = ... | variables.rs:324:9:325:9 | \|...\| ... | | +| variables.rs:323:9:323:26 | immutable_variable | variables.rs:326:5:327:30 | let n2 = ... | match | +| variables.rs:324:9:325:9 | \|...\| ... | variables.rs:323:9:323:26 | immutable_variable | | +| variables.rs:324:9:325:9 | enter \|...\| ... | variables.rs:324:10:324:10 | x | | +| variables.rs:324:9:325:9 | exit \|...\| ... (normal) | variables.rs:324:9:325:9 | exit \|...\| ... | | +| variables.rs:324:10:324:10 | x | variables.rs:324:10:324:15 | x: i64 | match | +| variables.rs:324:10:324:15 | x: i64 | variables.rs:325:9:325:9 | x | | +| variables.rs:325:9:325:9 | x | variables.rs:324:9:325:9 | exit \|...\| ... (normal) | | +| variables.rs:326:5:327:30 | let n2 = ... | variables.rs:327:9:327:26 | immutable_variable | | | variables.rs:326:9:326:10 | n2 | variables.rs:328:5:328:18 | ExprStmt | match | | variables.rs:327:9:327:26 | immutable_variable | variables.rs:327:28:327:28 | 6 | | -| variables.rs:327:9:327:29 | CallExpr | variables.rs:326:9:326:10 | n2 | | -| variables.rs:327:28:327:28 | 6 | variables.rs:327:9:327:29 | CallExpr | | +| variables.rs:327:9:327:29 | immutable_variable(...) | variables.rs:326:9:326:10 | n2 | | +| variables.rs:327:28:327:28 | 6 | variables.rs:327:9:327:29 | immutable_variable(...) | | | variables.rs:328:5:328:13 | print_i64 | variables.rs:328:15:328:16 | n2 | | -| variables.rs:328:5:328:17 | CallExpr | variables.rs:314:23:329:1 | BlockExpr | | +| variables.rs:328:5:328:17 | print_i64(...) | variables.rs:314:23:329:1 | { ... } | | | variables.rs:328:5:328:18 | ExprStmt | variables.rs:328:5:328:13 | print_i64 | | -| variables.rs:328:15:328:16 | n2 | variables.rs:328:5:328:17 | CallExpr | | -| variables.rs:331:1:338:1 | enter for_variable | variables.rs:332:5:332:42 | LetStmt | | -| variables.rs:331:1:338:1 | exit for_variable (normal) | variables.rs:331:1:338:1 | exit for_variable | | -| variables.rs:331:19:338:1 | BlockExpr | variables.rs:331:1:338:1 | exit for_variable (normal) | | -| variables.rs:332:5:332:42 | LetStmt | variables.rs:332:15:332:22 | "apples" | | +| variables.rs:328:15:328:16 | n2 | variables.rs:328:5:328:17 | print_i64(...) | | +| variables.rs:331:1:338:1 | enter fn for_variable | variables.rs:332:5:332:42 | let v = ... | | +| variables.rs:331:1:338:1 | exit fn for_variable (normal) | variables.rs:331:1:338:1 | exit fn for_variable | | +| variables.rs:331:19:338:1 | { ... } | variables.rs:331:1:338:1 | exit fn for_variable (normal) | | +| variables.rs:332:5:332:42 | let v = ... | variables.rs:332:15:332:22 | "apples" | | | variables.rs:332:9:332:9 | v | variables.rs:335:12:335:12 | v | match | -| variables.rs:332:13:332:41 | RefExpr | variables.rs:332:9:332:9 | v | | -| variables.rs:332:14:332:41 | ArrayExpr | variables.rs:332:13:332:41 | RefExpr | | +| variables.rs:332:13:332:41 | &... | variables.rs:332:9:332:9 | v | | +| variables.rs:332:14:332:41 | [...] | variables.rs:332:13:332:41 | &... | | | variables.rs:332:15:332:22 | "apples" | variables.rs:332:25:332:30 | "cake" | | | variables.rs:332:25:332:30 | "cake" | variables.rs:332:33:332:40 | "coffee" | | -| variables.rs:332:33:332:40 | "coffee" | variables.rs:332:14:332:41 | ArrayExpr | | -| variables.rs:334:5:337:5 | ForExpr | variables.rs:331:19:338:1 | BlockExpr | | +| variables.rs:332:33:332:40 | "coffee" | variables.rs:332:14:332:41 | [...] | | +| variables.rs:334:5:337:5 | ForExpr | variables.rs:331:19:338:1 | { ... } | | | variables.rs:334:9:334:12 | text | variables.rs:334:5:337:5 | ForExpr | no-match | | variables.rs:334:9:334:12 | text | variables.rs:336:9:336:24 | ExprStmt | match | | variables.rs:335:12:335:12 | v | variables.rs:334:9:334:12 | text | | -| variables.rs:335:14:337:5 | BlockExpr | variables.rs:334:9:334:12 | text | | +| variables.rs:335:14:337:5 | { ... } | variables.rs:334:9:334:12 | text | | | variables.rs:336:9:336:17 | print_str | variables.rs:336:19:336:22 | text | | -| variables.rs:336:9:336:23 | CallExpr | variables.rs:335:14:337:5 | BlockExpr | | +| variables.rs:336:9:336:23 | print_str(...) | variables.rs:335:14:337:5 | { ... } | | | variables.rs:336:9:336:24 | ExprStmt | variables.rs:336:9:336:17 | print_str | | -| variables.rs:336:19:336:22 | text | variables.rs:336:9:336:23 | CallExpr | | -| variables.rs:340:1:346:1 | enter add_assign | variables.rs:341:5:341:18 | LetStmt | | -| variables.rs:340:1:346:1 | exit add_assign (normal) | variables.rs:340:1:346:1 | exit add_assign | | -| variables.rs:340:17:346:1 | BlockExpr | variables.rs:340:1:346:1 | exit add_assign (normal) | | -| variables.rs:341:5:341:18 | LetStmt | variables.rs:341:17:341:17 | 0 | | +| variables.rs:336:19:336:22 | text | variables.rs:336:9:336:23 | print_str(...) | | +| variables.rs:340:1:346:1 | enter fn add_assign | variables.rs:341:5:341:18 | let a = ... | | +| variables.rs:340:1:346:1 | exit fn add_assign (normal) | variables.rs:340:1:346:1 | exit fn add_assign | | +| variables.rs:340:17:346:1 | { ... } | variables.rs:340:1:346:1 | exit fn add_assign (normal) | | +| variables.rs:341:5:341:18 | let a = ... | variables.rs:341:17:341:17 | 0 | | | variables.rs:341:9:341:13 | a | variables.rs:342:5:342:11 | ExprStmt | match | | variables.rs:341:17:341:17 | 0 | variables.rs:341:9:341:13 | a | | | variables.rs:342:5:342:5 | a | variables.rs:342:10:342:10 | 1 | | @@ -737,41 +737,41 @@ edges | variables.rs:342:5:342:11 | ExprStmt | variables.rs:342:5:342:5 | a | | | variables.rs:342:10:342:10 | 1 | variables.rs:342:5:342:10 | ... += ... | | | variables.rs:343:5:343:13 | print_i64 | variables.rs:343:15:343:15 | a | | -| variables.rs:343:5:343:16 | CallExpr | variables.rs:344:5:344:28 | ExprStmt | | +| variables.rs:343:5:343:16 | print_i64(...) | variables.rs:344:5:344:28 | ExprStmt | | | variables.rs:343:5:343:17 | ExprStmt | variables.rs:343:5:343:13 | print_i64 | | -| variables.rs:343:15:343:15 | a | variables.rs:343:5:343:16 | CallExpr | | +| variables.rs:343:15:343:15 | a | variables.rs:343:5:343:16 | print_i64(...) | | | variables.rs:344:5:344:27 | ... .add_assign(...) | variables.rs:345:5:345:17 | ExprStmt | | | variables.rs:344:5:344:28 | ExprStmt | variables.rs:344:11:344:11 | a | | -| variables.rs:344:6:344:11 | RefExpr | variables.rs:344:25:344:26 | 10 | | -| variables.rs:344:11:344:11 | a | variables.rs:344:6:344:11 | RefExpr | | +| variables.rs:344:6:344:11 | &mut ... | variables.rs:344:25:344:26 | 10 | | +| variables.rs:344:11:344:11 | a | variables.rs:344:6:344:11 | &mut ... | | | variables.rs:344:25:344:26 | 10 | variables.rs:344:5:344:27 | ... .add_assign(...) | | | variables.rs:345:5:345:13 | print_i64 | variables.rs:345:15:345:15 | a | | -| variables.rs:345:5:345:16 | CallExpr | variables.rs:340:17:346:1 | BlockExpr | | +| variables.rs:345:5:345:16 | print_i64(...) | variables.rs:340:17:346:1 | { ... } | | | variables.rs:345:5:345:17 | ExprStmt | variables.rs:345:5:345:13 | print_i64 | | -| variables.rs:345:15:345:15 | a | variables.rs:345:5:345:16 | CallExpr | | -| variables.rs:348:1:354:1 | enter mutate | variables.rs:349:5:349:18 | LetStmt | | -| variables.rs:348:1:354:1 | exit mutate (normal) | variables.rs:348:1:354:1 | exit mutate | | -| variables.rs:348:13:354:1 | BlockExpr | variables.rs:348:1:354:1 | exit mutate (normal) | | -| variables.rs:349:5:349:18 | LetStmt | variables.rs:349:17:349:17 | 1 | | -| variables.rs:349:9:349:13 | i | variables.rs:350:5:351:15 | LetStmt | match | +| variables.rs:345:15:345:15 | a | variables.rs:345:5:345:16 | print_i64(...) | | +| variables.rs:348:1:354:1 | enter fn mutate | variables.rs:349:5:349:18 | let i = ... | | +| variables.rs:348:1:354:1 | exit fn mutate (normal) | variables.rs:348:1:354:1 | exit fn mutate | | +| variables.rs:348:13:354:1 | { ... } | variables.rs:348:1:354:1 | exit fn mutate (normal) | | +| variables.rs:349:5:349:18 | let i = ... | variables.rs:349:17:349:17 | 1 | | +| variables.rs:349:9:349:13 | i | variables.rs:350:5:351:15 | let ref_i = ... | match | | variables.rs:349:17:349:17 | 1 | variables.rs:349:9:349:13 | i | | -| variables.rs:350:5:351:15 | LetStmt | variables.rs:351:14:351:14 | i | | +| variables.rs:350:5:351:15 | let ref_i = ... | variables.rs:351:14:351:14 | i | | | variables.rs:350:9:350:13 | ref_i | variables.rs:352:5:352:15 | ExprStmt | match | -| variables.rs:351:9:351:14 | RefExpr | variables.rs:350:9:350:13 | ref_i | | -| variables.rs:351:14:351:14 | i | variables.rs:351:9:351:14 | RefExpr | | +| variables.rs:351:9:351:14 | &mut ... | variables.rs:350:9:350:13 | ref_i | | +| variables.rs:351:14:351:14 | i | variables.rs:351:9:351:14 | &mut ... | | | variables.rs:352:5:352:10 | * ... | variables.rs:352:14:352:14 | 2 | | | variables.rs:352:5:352:14 | ... = ... | variables.rs:353:5:353:17 | ExprStmt | | | variables.rs:352:5:352:15 | ExprStmt | variables.rs:352:6:352:10 | ref_i | | | variables.rs:352:6:352:10 | ref_i | variables.rs:352:5:352:10 | * ... | | | variables.rs:352:14:352:14 | 2 | variables.rs:352:5:352:14 | ... = ... | | | variables.rs:353:5:353:13 | print_i64 | variables.rs:353:15:353:15 | i | | -| variables.rs:353:5:353:16 | CallExpr | variables.rs:348:13:354:1 | BlockExpr | | +| variables.rs:353:5:353:16 | print_i64(...) | variables.rs:348:13:354:1 | { ... } | | | variables.rs:353:5:353:17 | ExprStmt | variables.rs:353:5:353:13 | print_i64 | | -| variables.rs:353:15:353:15 | i | variables.rs:353:5:353:16 | CallExpr | | -| variables.rs:356:1:361:1 | enter mutate_param | variables.rs:356:17:356:17 | x | | -| variables.rs:356:1:361:1 | exit mutate_param (normal) | variables.rs:356:1:361:1 | exit mutate_param | | -| variables.rs:356:17:356:17 | x | variables.rs:356:17:356:28 | Param | match | -| variables.rs:356:17:356:28 | Param | variables.rs:357:5:359:11 | ExprStmt | | +| variables.rs:353:15:353:15 | i | variables.rs:353:5:353:16 | print_i64(...) | | +| variables.rs:356:1:361:1 | enter fn mutate_param | variables.rs:356:17:356:17 | x | | +| variables.rs:356:1:361:1 | exit fn mutate_param (normal) | variables.rs:356:1:361:1 | exit fn mutate_param | | +| variables.rs:356:17:356:17 | x | variables.rs:356:17:356:28 | x: RefType | match | +| variables.rs:356:17:356:28 | x: RefType | variables.rs:357:5:359:11 | ExprStmt | | | variables.rs:357:5:357:6 | * ... | variables.rs:358:10:358:10 | x | | | variables.rs:357:5:359:10 | ... = ... | variables.rs:360:5:360:13 | ExprStmt | | | variables.rs:357:5:359:11 | ExprStmt | variables.rs:357:6:357:6 | x | | @@ -781,16 +781,16 @@ edges | variables.rs:358:10:358:10 | x | variables.rs:358:9:358:10 | * ... | | | variables.rs:359:9:359:10 | * ... | variables.rs:358:9:359:10 | ... + ... | | | variables.rs:359:10:359:10 | x | variables.rs:359:9:359:10 | * ... | | -| variables.rs:360:5:360:12 | ReturnExpr | variables.rs:356:1:361:1 | exit mutate_param (normal) | return | +| variables.rs:360:5:360:12 | return ... | variables.rs:356:1:361:1 | exit fn mutate_param (normal) | return | | variables.rs:360:5:360:13 | ExprStmt | variables.rs:360:12:360:12 | x | | -| variables.rs:360:12:360:12 | x | variables.rs:360:5:360:12 | ReturnExpr | | -| variables.rs:363:1:369:1 | enter mutate_param2 | variables.rs:363:22:363:22 | x | | -| variables.rs:363:1:369:1 | exit mutate_param2 (normal) | variables.rs:363:1:369:1 | exit mutate_param2 | | -| variables.rs:363:22:363:22 | x | variables.rs:363:22:363:36 | Param | match | -| variables.rs:363:22:363:36 | Param | variables.rs:363:39:363:39 | y | | -| variables.rs:363:39:363:39 | y | variables.rs:363:39:363:57 | Param | match | -| variables.rs:363:39:363:57 | Param | variables.rs:364:5:366:11 | ExprStmt | | -| variables.rs:363:60:369:1 | BlockExpr | variables.rs:363:1:369:1 | exit mutate_param2 (normal) | | +| variables.rs:360:12:360:12 | x | variables.rs:360:5:360:12 | return ... | | +| variables.rs:363:1:369:1 | enter fn mutate_param2 | variables.rs:363:22:363:22 | x | | +| variables.rs:363:1:369:1 | exit fn mutate_param2 (normal) | variables.rs:363:1:369:1 | exit fn mutate_param2 | | +| variables.rs:363:22:363:22 | x | variables.rs:363:22:363:36 | x: RefType | match | +| variables.rs:363:22:363:36 | x: RefType | variables.rs:363:39:363:39 | y | | +| variables.rs:363:39:363:39 | y | variables.rs:363:39:363:57 | y: RefType | match | +| variables.rs:363:39:363:57 | y: RefType | variables.rs:364:5:366:11 | ExprStmt | | +| variables.rs:363:60:369:1 | { ... } | variables.rs:363:1:369:1 | exit fn mutate_param2 (normal) | | | variables.rs:364:5:364:6 | * ... | variables.rs:365:10:365:10 | x | | | variables.rs:364:5:366:10 | ... = ... | variables.rs:367:5:368:10 | ExprStmt | | | variables.rs:364:5:366:11 | ExprStmt | variables.rs:364:6:364:6 | x | | @@ -801,45 +801,45 @@ edges | variables.rs:366:9:366:10 | * ... | variables.rs:365:9:366:10 | ... + ... | | | variables.rs:366:10:366:10 | x | variables.rs:366:9:366:10 | * ... | | | variables.rs:367:5:367:6 | * ... | variables.rs:368:9:368:9 | x | | -| variables.rs:367:5:368:9 | ... = ... | variables.rs:363:60:369:1 | BlockExpr | | +| variables.rs:367:5:368:9 | ... = ... | variables.rs:363:60:369:1 | { ... } | | | variables.rs:367:5:368:10 | ExprStmt | variables.rs:367:6:367:6 | y | | | variables.rs:367:6:367:6 | y | variables.rs:367:5:367:6 | * ... | | | variables.rs:368:9:368:9 | x | variables.rs:367:5:368:9 | ... = ... | | -| variables.rs:371:1:389:1 | enter mutate_arg | variables.rs:372:5:372:18 | LetStmt | | -| variables.rs:371:1:389:1 | exit mutate_arg (normal) | variables.rs:371:1:389:1 | exit mutate_arg | | -| variables.rs:371:17:389:1 | BlockExpr | variables.rs:371:1:389:1 | exit mutate_arg (normal) | | -| variables.rs:372:5:372:18 | LetStmt | variables.rs:372:17:372:17 | 2 | | -| variables.rs:372:9:372:13 | x | variables.rs:373:5:374:29 | LetStmt | match | +| variables.rs:371:1:389:1 | enter fn mutate_arg | variables.rs:372:5:372:18 | let x = ... | | +| variables.rs:371:1:389:1 | exit fn mutate_arg (normal) | variables.rs:371:1:389:1 | exit fn mutate_arg | | +| variables.rs:371:17:389:1 | { ... } | variables.rs:371:1:389:1 | exit fn mutate_arg (normal) | | +| variables.rs:372:5:372:18 | let x = ... | variables.rs:372:17:372:17 | 2 | | +| variables.rs:372:9:372:13 | x | variables.rs:373:5:374:29 | let y = ... | match | | variables.rs:372:17:372:17 | 2 | variables.rs:372:9:372:13 | x | | -| variables.rs:373:5:374:29 | LetStmt | variables.rs:374:9:374:20 | mutate_param | | +| variables.rs:373:5:374:29 | let y = ... | variables.rs:374:9:374:20 | mutate_param | | | variables.rs:373:9:373:9 | y | variables.rs:375:5:375:12 | ExprStmt | match | | variables.rs:374:9:374:20 | mutate_param | variables.rs:374:27:374:27 | x | | -| variables.rs:374:9:374:28 | CallExpr | variables.rs:373:9:373:9 | y | | -| variables.rs:374:22:374:27 | RefExpr | variables.rs:374:9:374:28 | CallExpr | | -| variables.rs:374:27:374:27 | x | variables.rs:374:22:374:27 | RefExpr | | +| variables.rs:374:9:374:28 | mutate_param(...) | variables.rs:373:9:373:9 | y | | +| variables.rs:374:22:374:27 | &mut ... | variables.rs:374:9:374:28 | mutate_param(...) | | +| variables.rs:374:27:374:27 | x | variables.rs:374:22:374:27 | &mut ... | | | variables.rs:375:5:375:6 | * ... | variables.rs:375:10:375:11 | 10 | | | variables.rs:375:5:375:11 | ... = ... | variables.rs:377:5:377:17 | ExprStmt | | | variables.rs:375:5:375:12 | ExprStmt | variables.rs:375:6:375:6 | y | | | variables.rs:375:6:375:6 | y | variables.rs:375:5:375:6 | * ... | | | variables.rs:375:10:375:11 | 10 | variables.rs:375:5:375:11 | ... = ... | | | variables.rs:377:5:377:13 | print_i64 | variables.rs:377:15:377:15 | x | | -| variables.rs:377:5:377:16 | CallExpr | variables.rs:379:5:379:18 | LetStmt | | +| variables.rs:377:5:377:16 | print_i64(...) | variables.rs:379:5:379:18 | let z = ... | | | variables.rs:377:5:377:17 | ExprStmt | variables.rs:377:5:377:13 | print_i64 | | -| variables.rs:377:15:377:15 | x | variables.rs:377:5:377:16 | CallExpr | | -| variables.rs:379:5:379:18 | LetStmt | variables.rs:379:17:379:17 | 4 | | -| variables.rs:379:9:379:13 | z | variables.rs:380:5:381:20 | LetStmt | match | +| variables.rs:377:15:377:15 | x | variables.rs:377:5:377:16 | print_i64(...) | | +| variables.rs:379:5:379:18 | let z = ... | variables.rs:379:17:379:17 | 4 | | +| variables.rs:379:9:379:13 | z | variables.rs:380:5:381:20 | let w = ... | match | | variables.rs:379:17:379:17 | 4 | variables.rs:379:9:379:13 | z | | -| variables.rs:380:5:381:20 | LetStmt | variables.rs:381:19:381:19 | x | | +| variables.rs:380:5:381:20 | let w = ... | variables.rs:381:19:381:19 | x | | | variables.rs:380:9:380:9 | w | variables.rs:382:5:385:6 | ExprStmt | match | -| variables.rs:381:9:381:19 | RefExpr | variables.rs:380:9:380:9 | w | | -| variables.rs:381:14:381:19 | RefExpr | variables.rs:381:9:381:19 | RefExpr | | -| variables.rs:381:19:381:19 | x | variables.rs:381:14:381:19 | RefExpr | | +| variables.rs:381:9:381:19 | &mut ... | variables.rs:380:9:380:9 | w | | +| variables.rs:381:14:381:19 | &mut ... | variables.rs:381:9:381:19 | &mut ... | | +| variables.rs:381:19:381:19 | x | variables.rs:381:14:381:19 | &mut ... | | | variables.rs:382:5:382:17 | mutate_param2 | variables.rs:383:14:383:14 | z | | -| variables.rs:382:5:385:5 | CallExpr | variables.rs:386:5:386:13 | ExprStmt | | +| variables.rs:382:5:385:5 | mutate_param2(...) | variables.rs:386:5:386:13 | ExprStmt | | | variables.rs:382:5:385:6 | ExprStmt | variables.rs:382:5:382:17 | mutate_param2 | | -| variables.rs:383:9:383:14 | RefExpr | variables.rs:384:9:384:9 | w | | -| variables.rs:383:14:383:14 | z | variables.rs:383:9:383:14 | RefExpr | | -| variables.rs:384:9:384:9 | w | variables.rs:382:5:385:5 | CallExpr | | +| variables.rs:383:9:383:14 | &mut ... | variables.rs:384:9:384:9 | w | | +| variables.rs:383:14:383:14 | z | variables.rs:383:9:383:14 | &mut ... | | +| variables.rs:384:9:384:9 | w | variables.rs:382:5:385:5 | mutate_param2(...) | | | variables.rs:386:5:386:7 | * ... | variables.rs:386:11:386:12 | 11 | | | variables.rs:386:5:386:12 | ... = ... | variables.rs:388:5:388:17 | ExprStmt | | | variables.rs:386:5:386:13 | ExprStmt | variables.rs:386:7:386:7 | w | | @@ -847,422 +847,422 @@ edges | variables.rs:386:7:386:7 | w | variables.rs:386:6:386:7 | * ... | | | variables.rs:386:11:386:12 | 11 | variables.rs:386:5:386:12 | ... = ... | | | variables.rs:388:5:388:13 | print_i64 | variables.rs:388:15:388:15 | z | | -| variables.rs:388:5:388:16 | CallExpr | variables.rs:371:17:389:1 | BlockExpr | | +| variables.rs:388:5:388:16 | print_i64(...) | variables.rs:371:17:389:1 | { ... } | | | variables.rs:388:5:388:17 | ExprStmt | variables.rs:388:5:388:13 | print_i64 | | -| variables.rs:388:15:388:15 | z | variables.rs:388:5:388:16 | CallExpr | | -| variables.rs:391:1:397:1 | enter alias | variables.rs:392:5:392:18 | LetStmt | | -| variables.rs:391:1:397:1 | exit alias (normal) | variables.rs:391:1:397:1 | exit alias | | -| variables.rs:391:12:397:1 | BlockExpr | variables.rs:391:1:397:1 | exit alias (normal) | | -| variables.rs:392:5:392:18 | LetStmt | variables.rs:392:17:392:17 | 1 | | -| variables.rs:392:9:392:13 | x | variables.rs:393:5:394:15 | LetStmt | match | +| variables.rs:388:15:388:15 | z | variables.rs:388:5:388:16 | print_i64(...) | | +| variables.rs:391:1:397:1 | enter fn alias | variables.rs:392:5:392:18 | let x = ... | | +| variables.rs:391:1:397:1 | exit fn alias (normal) | variables.rs:391:1:397:1 | exit fn alias | | +| variables.rs:391:12:397:1 | { ... } | variables.rs:391:1:397:1 | exit fn alias (normal) | | +| variables.rs:392:5:392:18 | let x = ... | variables.rs:392:17:392:17 | 1 | | +| variables.rs:392:9:392:13 | x | variables.rs:393:5:394:15 | let y = ... | match | | variables.rs:392:17:392:17 | 1 | variables.rs:392:9:392:13 | x | | -| variables.rs:393:5:394:15 | LetStmt | variables.rs:394:14:394:14 | x | | +| variables.rs:393:5:394:15 | let y = ... | variables.rs:394:14:394:14 | x | | | variables.rs:393:9:393:9 | y | variables.rs:395:5:395:11 | ExprStmt | match | -| variables.rs:394:9:394:14 | RefExpr | variables.rs:393:9:393:9 | y | | -| variables.rs:394:14:394:14 | x | variables.rs:394:9:394:14 | RefExpr | | +| variables.rs:394:9:394:14 | &mut ... | variables.rs:393:9:393:9 | y | | +| variables.rs:394:14:394:14 | x | variables.rs:394:9:394:14 | &mut ... | | | variables.rs:395:5:395:6 | * ... | variables.rs:395:10:395:10 | 2 | | | variables.rs:395:5:395:10 | ... = ... | variables.rs:396:5:396:17 | ExprStmt | | | variables.rs:395:5:395:11 | ExprStmt | variables.rs:395:6:395:6 | y | | | variables.rs:395:6:395:6 | y | variables.rs:395:5:395:6 | * ... | | | variables.rs:395:10:395:10 | 2 | variables.rs:395:5:395:10 | ... = ... | | | variables.rs:396:5:396:13 | print_i64 | variables.rs:396:15:396:15 | x | | -| variables.rs:396:5:396:16 | CallExpr | variables.rs:391:12:397:1 | BlockExpr | | +| variables.rs:396:5:396:16 | print_i64(...) | variables.rs:391:12:397:1 | { ... } | | | variables.rs:396:5:396:17 | ExprStmt | variables.rs:396:5:396:13 | print_i64 | | -| variables.rs:396:15:396:15 | x | variables.rs:396:5:396:16 | CallExpr | | -| variables.rs:399:1:407:1 | enter capture_immut | variables.rs:400:5:400:16 | LetStmt | | -| variables.rs:399:1:407:1 | exit capture_immut (normal) | variables.rs:399:1:407:1 | exit capture_immut | | -| variables.rs:399:20:407:1 | BlockExpr | variables.rs:399:1:407:1 | exit capture_immut (normal) | | -| variables.rs:400:5:400:16 | LetStmt | variables.rs:400:13:400:15 | 100 | | -| variables.rs:400:9:400:9 | x | variables.rs:402:5:404:6 | LetStmt | match | +| variables.rs:396:15:396:15 | x | variables.rs:396:5:396:16 | print_i64(...) | | +| variables.rs:399:1:407:1 | enter fn capture_immut | variables.rs:400:5:400:16 | let x = ... | | +| variables.rs:399:1:407:1 | exit fn capture_immut (normal) | variables.rs:399:1:407:1 | exit fn capture_immut | | +| variables.rs:399:20:407:1 | { ... } | variables.rs:399:1:407:1 | exit fn capture_immut (normal) | | +| variables.rs:400:5:400:16 | let x = ... | variables.rs:400:13:400:15 | 100 | | +| variables.rs:400:9:400:9 | x | variables.rs:402:5:404:6 | let cap = ... | match | | variables.rs:400:13:400:15 | 100 | variables.rs:400:9:400:9 | x | | -| variables.rs:402:5:404:6 | LetStmt | variables.rs:402:15:404:5 | ClosureExpr | | +| variables.rs:402:5:404:6 | let cap = ... | variables.rs:402:15:404:5 | \|...\| ... | | | variables.rs:402:9:402:11 | cap | variables.rs:405:5:405:10 | ExprStmt | match | -| variables.rs:402:15:404:5 | ClosureExpr | variables.rs:402:9:402:11 | cap | | -| variables.rs:402:15:404:5 | enter ClosureExpr | variables.rs:403:9:403:21 | ExprStmt | | -| variables.rs:402:15:404:5 | exit ClosureExpr (normal) | variables.rs:402:15:404:5 | exit ClosureExpr | | -| variables.rs:402:18:404:5 | BlockExpr | variables.rs:402:15:404:5 | exit ClosureExpr (normal) | | +| variables.rs:402:15:404:5 | \|...\| ... | variables.rs:402:9:402:11 | cap | | +| variables.rs:402:15:404:5 | enter \|...\| ... | variables.rs:403:9:403:21 | ExprStmt | | +| variables.rs:402:15:404:5 | exit \|...\| ... (normal) | variables.rs:402:15:404:5 | exit \|...\| ... | | +| variables.rs:402:18:404:5 | { ... } | variables.rs:402:15:404:5 | exit \|...\| ... (normal) | | | variables.rs:403:9:403:17 | print_i64 | variables.rs:403:19:403:19 | x | | -| variables.rs:403:9:403:20 | CallExpr | variables.rs:402:18:404:5 | BlockExpr | | +| variables.rs:403:9:403:20 | print_i64(...) | variables.rs:402:18:404:5 | { ... } | | | variables.rs:403:9:403:21 | ExprStmt | variables.rs:403:9:403:17 | print_i64 | | -| variables.rs:403:19:403:19 | x | variables.rs:403:9:403:20 | CallExpr | | -| variables.rs:405:5:405:7 | cap | variables.rs:405:5:405:9 | CallExpr | | -| variables.rs:405:5:405:9 | CallExpr | variables.rs:406:5:406:17 | ExprStmt | | +| variables.rs:403:19:403:19 | x | variables.rs:403:9:403:20 | print_i64(...) | | +| variables.rs:405:5:405:7 | cap | variables.rs:405:5:405:9 | cap(...) | | +| variables.rs:405:5:405:9 | cap(...) | variables.rs:406:5:406:17 | ExprStmt | | | variables.rs:405:5:405:10 | ExprStmt | variables.rs:405:5:405:7 | cap | | | variables.rs:406:5:406:13 | print_i64 | variables.rs:406:15:406:15 | x | | -| variables.rs:406:5:406:16 | CallExpr | variables.rs:399:20:407:1 | BlockExpr | | +| variables.rs:406:5:406:16 | print_i64(...) | variables.rs:399:20:407:1 | { ... } | | | variables.rs:406:5:406:17 | ExprStmt | variables.rs:406:5:406:13 | print_i64 | | -| variables.rs:406:15:406:15 | x | variables.rs:406:5:406:16 | CallExpr | | -| variables.rs:409:1:433:1 | enter capture_mut | variables.rs:410:5:410:18 | LetStmt | | -| variables.rs:409:1:433:1 | exit capture_mut (normal) | variables.rs:409:1:433:1 | exit capture_mut | | -| variables.rs:409:18:433:1 | BlockExpr | variables.rs:409:1:433:1 | exit capture_mut (normal) | | -| variables.rs:410:5:410:18 | LetStmt | variables.rs:410:17:410:17 | 1 | | -| variables.rs:410:9:410:13 | x | variables.rs:412:5:414:6 | LetStmt | match | +| variables.rs:406:15:406:15 | x | variables.rs:406:5:406:16 | print_i64(...) | | +| variables.rs:409:1:433:1 | enter fn capture_mut | variables.rs:410:5:410:18 | let x = ... | | +| variables.rs:409:1:433:1 | exit fn capture_mut (normal) | variables.rs:409:1:433:1 | exit fn capture_mut | | +| variables.rs:409:18:433:1 | { ... } | variables.rs:409:1:433:1 | exit fn capture_mut (normal) | | +| variables.rs:410:5:410:18 | let x = ... | variables.rs:410:17:410:17 | 1 | | +| variables.rs:410:9:410:13 | x | variables.rs:412:5:414:6 | let closure1 = ... | match | | variables.rs:410:17:410:17 | 1 | variables.rs:410:9:410:13 | x | | -| variables.rs:412:5:414:6 | LetStmt | variables.rs:412:20:414:5 | ClosureExpr | | +| variables.rs:412:5:414:6 | let closure1 = ... | variables.rs:412:20:414:5 | \|...\| ... | | | variables.rs:412:9:412:16 | closure1 | variables.rs:415:5:415:15 | ExprStmt | match | -| variables.rs:412:20:414:5 | ClosureExpr | variables.rs:412:9:412:16 | closure1 | | -| variables.rs:412:20:414:5 | enter ClosureExpr | variables.rs:413:9:413:21 | ExprStmt | | -| variables.rs:412:20:414:5 | exit ClosureExpr (normal) | variables.rs:412:20:414:5 | exit ClosureExpr | | -| variables.rs:412:23:414:5 | BlockExpr | variables.rs:412:20:414:5 | exit ClosureExpr (normal) | | +| variables.rs:412:20:414:5 | \|...\| ... | variables.rs:412:9:412:16 | closure1 | | +| variables.rs:412:20:414:5 | enter \|...\| ... | variables.rs:413:9:413:21 | ExprStmt | | +| variables.rs:412:20:414:5 | exit \|...\| ... (normal) | variables.rs:412:20:414:5 | exit \|...\| ... | | +| variables.rs:412:23:414:5 | { ... } | variables.rs:412:20:414:5 | exit \|...\| ... (normal) | | | variables.rs:413:9:413:17 | print_i64 | variables.rs:413:19:413:19 | x | | -| variables.rs:413:9:413:20 | CallExpr | variables.rs:412:23:414:5 | BlockExpr | | +| variables.rs:413:9:413:20 | print_i64(...) | variables.rs:412:23:414:5 | { ... } | | | variables.rs:413:9:413:21 | ExprStmt | variables.rs:413:9:413:17 | print_i64 | | -| variables.rs:413:19:413:19 | x | variables.rs:413:9:413:20 | CallExpr | | -| variables.rs:415:5:415:12 | closure1 | variables.rs:415:5:415:14 | CallExpr | | -| variables.rs:415:5:415:14 | CallExpr | variables.rs:416:5:416:17 | ExprStmt | | +| variables.rs:413:19:413:19 | x | variables.rs:413:9:413:20 | print_i64(...) | | +| variables.rs:415:5:415:12 | closure1 | variables.rs:415:5:415:14 | closure1(...) | | +| variables.rs:415:5:415:14 | closure1(...) | variables.rs:416:5:416:17 | ExprStmt | | | variables.rs:415:5:415:15 | ExprStmt | variables.rs:415:5:415:12 | closure1 | | | variables.rs:416:5:416:13 | print_i64 | variables.rs:416:15:416:15 | x | | -| variables.rs:416:5:416:16 | CallExpr | variables.rs:418:5:418:18 | LetStmt | | +| variables.rs:416:5:416:16 | print_i64(...) | variables.rs:418:5:418:18 | let y = ... | | | variables.rs:416:5:416:17 | ExprStmt | variables.rs:416:5:416:13 | print_i64 | | -| variables.rs:416:15:416:15 | x | variables.rs:416:5:416:16 | CallExpr | | -| variables.rs:418:5:418:18 | LetStmt | variables.rs:418:17:418:17 | 2 | | -| variables.rs:418:9:418:13 | y | variables.rs:420:5:422:6 | LetStmt | match | +| variables.rs:416:15:416:15 | x | variables.rs:416:5:416:16 | print_i64(...) | | +| variables.rs:418:5:418:18 | let y = ... | variables.rs:418:17:418:17 | 2 | | +| variables.rs:418:9:418:13 | y | variables.rs:420:5:422:6 | let closure2 = ... | match | | variables.rs:418:17:418:17 | 2 | variables.rs:418:9:418:13 | y | | -| variables.rs:420:5:422:6 | LetStmt | variables.rs:420:24:422:5 | ClosureExpr | | +| variables.rs:420:5:422:6 | let closure2 = ... | variables.rs:420:24:422:5 | \|...\| ... | | | variables.rs:420:9:420:20 | closure2 | variables.rs:423:5:423:15 | ExprStmt | match | -| variables.rs:420:24:422:5 | ClosureExpr | variables.rs:420:9:420:20 | closure2 | | -| variables.rs:420:24:422:5 | enter ClosureExpr | variables.rs:421:9:421:14 | ExprStmt | | -| variables.rs:420:24:422:5 | exit ClosureExpr (normal) | variables.rs:420:24:422:5 | exit ClosureExpr | | -| variables.rs:420:27:422:5 | BlockExpr | variables.rs:420:24:422:5 | exit ClosureExpr (normal) | | +| variables.rs:420:24:422:5 | \|...\| ... | variables.rs:420:9:420:20 | closure2 | | +| variables.rs:420:24:422:5 | enter \|...\| ... | variables.rs:421:9:421:14 | ExprStmt | | +| variables.rs:420:24:422:5 | exit \|...\| ... (normal) | variables.rs:420:24:422:5 | exit \|...\| ... | | +| variables.rs:420:27:422:5 | { ... } | variables.rs:420:24:422:5 | exit \|...\| ... (normal) | | | variables.rs:421:9:421:9 | y | variables.rs:421:13:421:13 | 3 | | -| variables.rs:421:9:421:13 | ... = ... | variables.rs:420:27:422:5 | BlockExpr | | +| variables.rs:421:9:421:13 | ... = ... | variables.rs:420:27:422:5 | { ... } | | | variables.rs:421:9:421:14 | ExprStmt | variables.rs:421:9:421:9 | y | | | variables.rs:421:13:421:13 | 3 | variables.rs:421:9:421:13 | ... = ... | | -| variables.rs:423:5:423:12 | closure2 | variables.rs:423:5:423:14 | CallExpr | | -| variables.rs:423:5:423:14 | CallExpr | variables.rs:424:5:424:17 | ExprStmt | | +| variables.rs:423:5:423:12 | closure2 | variables.rs:423:5:423:14 | closure2(...) | | +| variables.rs:423:5:423:14 | closure2(...) | variables.rs:424:5:424:17 | ExprStmt | | | variables.rs:423:5:423:15 | ExprStmt | variables.rs:423:5:423:12 | closure2 | | | variables.rs:424:5:424:13 | print_i64 | variables.rs:424:15:424:15 | y | | -| variables.rs:424:5:424:16 | CallExpr | variables.rs:426:5:426:18 | LetStmt | | +| variables.rs:424:5:424:16 | print_i64(...) | variables.rs:426:5:426:18 | let z = ... | | | variables.rs:424:5:424:17 | ExprStmt | variables.rs:424:5:424:13 | print_i64 | | -| variables.rs:424:15:424:15 | y | variables.rs:424:5:424:16 | CallExpr | | -| variables.rs:426:5:426:18 | LetStmt | variables.rs:426:17:426:17 | 2 | | -| variables.rs:426:9:426:13 | z | variables.rs:428:5:430:6 | LetStmt | match | +| variables.rs:424:15:424:15 | y | variables.rs:424:5:424:16 | print_i64(...) | | +| variables.rs:426:5:426:18 | let z = ... | variables.rs:426:17:426:17 | 2 | | +| variables.rs:426:9:426:13 | z | variables.rs:428:5:430:6 | let closure3 = ... | match | | variables.rs:426:17:426:17 | 2 | variables.rs:426:9:426:13 | z | | -| variables.rs:428:5:430:6 | LetStmt | variables.rs:428:24:430:5 | ClosureExpr | | +| variables.rs:428:5:430:6 | let closure3 = ... | variables.rs:428:24:430:5 | \|...\| ... | | | variables.rs:428:9:428:20 | closure3 | variables.rs:431:5:431:15 | ExprStmt | match | -| variables.rs:428:24:430:5 | ClosureExpr | variables.rs:428:9:428:20 | closure3 | | -| variables.rs:428:24:430:5 | enter ClosureExpr | variables.rs:429:9:429:24 | ExprStmt | | -| variables.rs:428:24:430:5 | exit ClosureExpr (normal) | variables.rs:428:24:430:5 | exit ClosureExpr | | -| variables.rs:428:27:430:5 | BlockExpr | variables.rs:428:24:430:5 | exit ClosureExpr (normal) | | +| variables.rs:428:24:430:5 | \|...\| ... | variables.rs:428:9:428:20 | closure3 | | +| variables.rs:428:24:430:5 | enter \|...\| ... | variables.rs:429:9:429:24 | ExprStmt | | +| variables.rs:428:24:430:5 | exit \|...\| ... (normal) | variables.rs:428:24:430:5 | exit \|...\| ... | | +| variables.rs:428:27:430:5 | { ... } | variables.rs:428:24:430:5 | exit \|...\| ... (normal) | | | variables.rs:429:9:429:9 | z | variables.rs:429:22:429:22 | 1 | | -| variables.rs:429:9:429:23 | ... .add_assign(...) | variables.rs:428:27:430:5 | BlockExpr | | +| variables.rs:429:9:429:23 | ... .add_assign(...) | variables.rs:428:27:430:5 | { ... } | | | variables.rs:429:9:429:24 | ExprStmt | variables.rs:429:9:429:9 | z | | | variables.rs:429:22:429:22 | 1 | variables.rs:429:9:429:23 | ... .add_assign(...) | | -| variables.rs:431:5:431:12 | closure3 | variables.rs:431:5:431:14 | CallExpr | | -| variables.rs:431:5:431:14 | CallExpr | variables.rs:432:5:432:17 | ExprStmt | | +| variables.rs:431:5:431:12 | closure3 | variables.rs:431:5:431:14 | closure3(...) | | +| variables.rs:431:5:431:14 | closure3(...) | variables.rs:432:5:432:17 | ExprStmt | | | variables.rs:431:5:431:15 | ExprStmt | variables.rs:431:5:431:12 | closure3 | | | variables.rs:432:5:432:13 | print_i64 | variables.rs:432:15:432:15 | z | | -| variables.rs:432:5:432:16 | CallExpr | variables.rs:409:18:433:1 | BlockExpr | | +| variables.rs:432:5:432:16 | print_i64(...) | variables.rs:409:18:433:1 | { ... } | | | variables.rs:432:5:432:17 | ExprStmt | variables.rs:432:5:432:13 | print_i64 | | -| variables.rs:432:15:432:15 | z | variables.rs:432:5:432:16 | CallExpr | | -| variables.rs:435:1:443:1 | enter async_block_capture | variables.rs:436:5:436:23 | LetStmt | | -| variables.rs:435:1:443:1 | exit async_block_capture (normal) | variables.rs:435:1:443:1 | exit async_block_capture | | -| variables.rs:435:32:443:1 | BlockExpr | variables.rs:435:1:443:1 | exit async_block_capture (normal) | | -| variables.rs:436:5:436:23 | LetStmt | variables.rs:436:22:436:22 | 0 | | -| variables.rs:436:9:436:13 | i | variables.rs:437:5:439:6 | LetStmt | match | +| variables.rs:432:15:432:15 | z | variables.rs:432:5:432:16 | print_i64(...) | | +| variables.rs:435:1:443:1 | enter fn async_block_capture | variables.rs:436:5:436:23 | let i = ... | | +| variables.rs:435:1:443:1 | exit fn async_block_capture (normal) | variables.rs:435:1:443:1 | exit fn async_block_capture | | +| variables.rs:435:32:443:1 | { ... } | variables.rs:435:1:443:1 | exit fn async_block_capture (normal) | | +| variables.rs:436:5:436:23 | let i = ... | variables.rs:436:22:436:22 | 0 | | +| variables.rs:436:9:436:13 | i | variables.rs:437:5:439:6 | let block = ... | match | | variables.rs:436:22:436:22 | 0 | variables.rs:436:9:436:13 | i | | -| variables.rs:437:5:439:6 | LetStmt | variables.rs:437:17:439:5 | BlockExpr | | +| variables.rs:437:5:439:6 | let block = ... | variables.rs:437:17:439:5 | { ... } | | | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:16 | ExprStmt | match | -| variables.rs:437:17:439:5 | BlockExpr | variables.rs:437:9:437:13 | block | | -| variables.rs:437:17:439:5 | enter BlockExpr | variables.rs:438:9:438:14 | ExprStmt | | -| variables.rs:437:17:439:5 | exit BlockExpr (normal) | variables.rs:437:17:439:5 | exit BlockExpr | | +| variables.rs:437:17:439:5 | enter { ... } | variables.rs:438:9:438:14 | ExprStmt | | +| variables.rs:437:17:439:5 | exit { ... } (normal) | variables.rs:437:17:439:5 | exit { ... } | | +| variables.rs:437:17:439:5 | { ... } | variables.rs:437:9:437:13 | block | | | variables.rs:438:9:438:9 | i | variables.rs:438:13:438:13 | 1 | | -| variables.rs:438:9:438:13 | ... = ... | variables.rs:437:17:439:5 | exit BlockExpr (normal) | | +| variables.rs:438:9:438:13 | ... = ... | variables.rs:437:17:439:5 | exit { ... } (normal) | | | variables.rs:438:9:438:14 | ExprStmt | variables.rs:438:9:438:9 | i | | | variables.rs:438:13:438:13 | 1 | variables.rs:438:9:438:13 | ... = ... | | -| variables.rs:441:5:441:9 | block | variables.rs:441:5:441:15 | AwaitExpr | | -| variables.rs:441:5:441:15 | AwaitExpr | variables.rs:442:5:442:17 | ExprStmt | | +| variables.rs:441:5:441:9 | block | variables.rs:441:5:441:15 | await ... | | +| variables.rs:441:5:441:15 | await ... | variables.rs:442:5:442:17 | ExprStmt | | | variables.rs:441:5:441:16 | ExprStmt | variables.rs:441:5:441:9 | block | | | variables.rs:442:5:442:13 | print_i64 | variables.rs:442:15:442:15 | i | | -| variables.rs:442:5:442:16 | CallExpr | variables.rs:435:32:443:1 | BlockExpr | | +| variables.rs:442:5:442:16 | print_i64(...) | variables.rs:435:32:443:1 | { ... } | | | variables.rs:442:5:442:17 | ExprStmt | variables.rs:442:5:442:13 | print_i64 | | -| variables.rs:442:15:442:15 | i | variables.rs:442:5:442:16 | CallExpr | | -| variables.rs:445:1:459:1 | enter phi | variables.rs:445:8:445:8 | b | | -| variables.rs:445:1:459:1 | exit phi (normal) | variables.rs:445:1:459:1 | exit phi | | -| variables.rs:445:8:445:8 | b | variables.rs:445:8:445:15 | Param | match | -| variables.rs:445:8:445:15 | Param | variables.rs:446:5:446:18 | LetStmt | | -| variables.rs:445:18:459:1 | BlockExpr | variables.rs:445:1:459:1 | exit phi (normal) | | -| variables.rs:446:5:446:18 | LetStmt | variables.rs:446:17:446:17 | 1 | | +| variables.rs:442:15:442:15 | i | variables.rs:442:5:442:16 | print_i64(...) | | +| variables.rs:445:1:459:1 | enter fn phi | variables.rs:445:8:445:8 | b | | +| variables.rs:445:1:459:1 | exit fn phi (normal) | variables.rs:445:1:459:1 | exit fn phi | | +| variables.rs:445:8:445:8 | b | variables.rs:445:8:445:15 | b: bool | match | +| variables.rs:445:8:445:15 | b: bool | variables.rs:446:5:446:18 | let x = ... | | +| variables.rs:445:18:459:1 | { ... } | variables.rs:445:1:459:1 | exit fn phi (normal) | | +| variables.rs:446:5:446:18 | let x = ... | variables.rs:446:17:446:17 | 1 | | | variables.rs:446:9:446:13 | x | variables.rs:447:5:447:17 | ExprStmt | match | | variables.rs:446:17:446:17 | 1 | variables.rs:446:9:446:13 | x | | | variables.rs:447:5:447:13 | print_i64 | variables.rs:447:15:447:15 | x | | -| variables.rs:447:5:447:16 | CallExpr | variables.rs:448:5:448:21 | ExprStmt | | +| variables.rs:447:5:447:16 | print_i64(...) | variables.rs:448:5:448:21 | ExprStmt | | | variables.rs:447:5:447:17 | ExprStmt | variables.rs:447:5:447:13 | print_i64 | | -| variables.rs:447:15:447:15 | x | variables.rs:447:5:447:16 | CallExpr | | +| variables.rs:447:15:447:15 | x | variables.rs:447:5:447:16 | print_i64(...) | | | variables.rs:448:5:448:13 | print_i64 | variables.rs:448:15:448:15 | x | | -| variables.rs:448:5:448:20 | CallExpr | variables.rs:449:5:457:5 | ExprStmt | | +| variables.rs:448:5:448:20 | print_i64(...) | variables.rs:449:5:457:5 | ExprStmt | | | variables.rs:448:5:448:21 | ExprStmt | variables.rs:448:5:448:13 | print_i64 | | | variables.rs:448:15:448:15 | x | variables.rs:448:19:448:19 | 1 | | -| variables.rs:448:15:448:19 | ... + ... | variables.rs:448:5:448:20 | CallExpr | | +| variables.rs:448:15:448:19 | ... + ... | variables.rs:448:5:448:20 | print_i64(...) | | | variables.rs:448:19:448:19 | 1 | variables.rs:448:15:448:19 | ... + ... | | | variables.rs:449:5:457:5 | ExprStmt | variables.rs:449:8:449:8 | b | | -| variables.rs:449:5:457:5 | IfExpr | variables.rs:458:5:458:17 | ExprStmt | | +| variables.rs:449:5:457:5 | if ... { ... } else { ... } | variables.rs:458:5:458:17 | ExprStmt | | | variables.rs:449:8:449:8 | b | variables.rs:450:9:450:14 | ExprStmt | true | | variables.rs:449:8:449:8 | b | variables.rs:454:9:454:14 | ExprStmt | false | -| variables.rs:449:10:453:5 | BlockExpr | variables.rs:449:5:457:5 | IfExpr | | +| variables.rs:449:10:453:5 | { ... } | variables.rs:449:5:457:5 | if ... { ... } else { ... } | | | variables.rs:450:9:450:9 | x | variables.rs:450:13:450:13 | 2 | | | variables.rs:450:9:450:13 | ... = ... | variables.rs:451:9:451:21 | ExprStmt | | | variables.rs:450:9:450:14 | ExprStmt | variables.rs:450:9:450:9 | x | | | variables.rs:450:13:450:13 | 2 | variables.rs:450:9:450:13 | ... = ... | | | variables.rs:451:9:451:17 | print_i64 | variables.rs:451:19:451:19 | x | | -| variables.rs:451:9:451:20 | CallExpr | variables.rs:452:9:452:25 | ExprStmt | | +| variables.rs:451:9:451:20 | print_i64(...) | variables.rs:452:9:452:25 | ExprStmt | | | variables.rs:451:9:451:21 | ExprStmt | variables.rs:451:9:451:17 | print_i64 | | -| variables.rs:451:19:451:19 | x | variables.rs:451:9:451:20 | CallExpr | | +| variables.rs:451:19:451:19 | x | variables.rs:451:9:451:20 | print_i64(...) | | | variables.rs:452:9:452:17 | print_i64 | variables.rs:452:19:452:19 | x | | -| variables.rs:452:9:452:24 | CallExpr | variables.rs:449:10:453:5 | BlockExpr | | +| variables.rs:452:9:452:24 | print_i64(...) | variables.rs:449:10:453:5 | { ... } | | | variables.rs:452:9:452:25 | ExprStmt | variables.rs:452:9:452:17 | print_i64 | | | variables.rs:452:19:452:19 | x | variables.rs:452:23:452:23 | 1 | | -| variables.rs:452:19:452:23 | ... + ... | variables.rs:452:9:452:24 | CallExpr | | +| variables.rs:452:19:452:23 | ... + ... | variables.rs:452:9:452:24 | print_i64(...) | | | variables.rs:452:23:452:23 | 1 | variables.rs:452:19:452:23 | ... + ... | | -| variables.rs:453:12:457:5 | BlockExpr | variables.rs:449:5:457:5 | IfExpr | | +| variables.rs:453:12:457:5 | { ... } | variables.rs:449:5:457:5 | if ... { ... } else { ... } | | | variables.rs:454:9:454:9 | x | variables.rs:454:13:454:13 | 3 | | | variables.rs:454:9:454:13 | ... = ... | variables.rs:455:9:455:21 | ExprStmt | | | variables.rs:454:9:454:14 | ExprStmt | variables.rs:454:9:454:9 | x | | | variables.rs:454:13:454:13 | 3 | variables.rs:454:9:454:13 | ... = ... | | | variables.rs:455:9:455:17 | print_i64 | variables.rs:455:19:455:19 | x | | -| variables.rs:455:9:455:20 | CallExpr | variables.rs:456:9:456:25 | ExprStmt | | +| variables.rs:455:9:455:20 | print_i64(...) | variables.rs:456:9:456:25 | ExprStmt | | | variables.rs:455:9:455:21 | ExprStmt | variables.rs:455:9:455:17 | print_i64 | | -| variables.rs:455:19:455:19 | x | variables.rs:455:9:455:20 | CallExpr | | +| variables.rs:455:19:455:19 | x | variables.rs:455:9:455:20 | print_i64(...) | | | variables.rs:456:9:456:17 | print_i64 | variables.rs:456:19:456:19 | x | | -| variables.rs:456:9:456:24 | CallExpr | variables.rs:453:12:457:5 | BlockExpr | | +| variables.rs:456:9:456:24 | print_i64(...) | variables.rs:453:12:457:5 | { ... } | | | variables.rs:456:9:456:25 | ExprStmt | variables.rs:456:9:456:17 | print_i64 | | | variables.rs:456:19:456:19 | x | variables.rs:456:23:456:23 | 1 | | -| variables.rs:456:19:456:23 | ... + ... | variables.rs:456:9:456:24 | CallExpr | | +| variables.rs:456:19:456:23 | ... + ... | variables.rs:456:9:456:24 | print_i64(...) | | | variables.rs:456:23:456:23 | 1 | variables.rs:456:19:456:23 | ... + ... | | | variables.rs:458:5:458:13 | print_i64 | variables.rs:458:15:458:15 | x | | -| variables.rs:458:5:458:16 | CallExpr | variables.rs:445:18:459:1 | BlockExpr | | +| variables.rs:458:5:458:16 | print_i64(...) | variables.rs:445:18:459:1 | { ... } | | | variables.rs:458:5:458:17 | ExprStmt | variables.rs:458:5:458:13 | print_i64 | | -| variables.rs:458:15:458:15 | x | variables.rs:458:5:458:16 | CallExpr | | -| variables.rs:461:1:474:1 | enter phi_read | variables.rs:461:13:461:14 | b1 | | -| variables.rs:461:1:474:1 | exit phi_read (normal) | variables.rs:461:1:474:1 | exit phi_read | | -| variables.rs:461:13:461:14 | b1 | variables.rs:461:13:461:21 | Param | match | -| variables.rs:461:13:461:21 | Param | variables.rs:461:24:461:25 | b2 | | -| variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:32 | Param | match | -| variables.rs:461:24:461:32 | Param | variables.rs:462:5:462:14 | LetStmt | | -| variables.rs:461:35:474:1 | BlockExpr | variables.rs:461:1:474:1 | exit phi_read (normal) | | -| variables.rs:462:5:462:14 | LetStmt | variables.rs:462:13:462:13 | 1 | | +| variables.rs:458:15:458:15 | x | variables.rs:458:5:458:16 | print_i64(...) | | +| variables.rs:461:1:474:1 | enter fn phi_read | variables.rs:461:13:461:14 | b1 | | +| variables.rs:461:1:474:1 | exit fn phi_read (normal) | variables.rs:461:1:474:1 | exit fn phi_read | | +| variables.rs:461:13:461:14 | b1 | variables.rs:461:13:461:21 | b1: bool | match | +| variables.rs:461:13:461:21 | b1: bool | variables.rs:461:24:461:25 | b2 | | +| variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:32 | b2: bool | match | +| variables.rs:461:24:461:32 | b2: bool | variables.rs:462:5:462:14 | let x = ... | | +| variables.rs:461:35:474:1 | { ... } | variables.rs:461:1:474:1 | exit fn phi_read (normal) | | +| variables.rs:462:5:462:14 | let x = ... | variables.rs:462:13:462:13 | 1 | | | variables.rs:462:9:462:9 | x | variables.rs:463:5:467:5 | ExprStmt | match | | variables.rs:462:13:462:13 | 1 | variables.rs:462:9:462:9 | x | | | variables.rs:463:5:467:5 | ExprStmt | variables.rs:463:8:463:9 | b1 | | -| variables.rs:463:5:467:5 | IfExpr | variables.rs:469:8:469:9 | b2 | | +| variables.rs:463:5:467:5 | if ... { ... } else { ... } | variables.rs:469:8:469:9 | b2 | | | variables.rs:463:8:463:9 | b1 | variables.rs:464:9:464:21 | ExprStmt | true | | variables.rs:463:8:463:9 | b1 | variables.rs:466:9:466:21 | ExprStmt | false | -| variables.rs:463:11:465:5 | BlockExpr | variables.rs:463:5:467:5 | IfExpr | | +| variables.rs:463:11:465:5 | { ... } | variables.rs:463:5:467:5 | if ... { ... } else { ... } | | | variables.rs:464:9:464:17 | print_i64 | variables.rs:464:19:464:19 | x | | -| variables.rs:464:9:464:20 | CallExpr | variables.rs:463:11:465:5 | BlockExpr | | +| variables.rs:464:9:464:20 | print_i64(...) | variables.rs:463:11:465:5 | { ... } | | | variables.rs:464:9:464:21 | ExprStmt | variables.rs:464:9:464:17 | print_i64 | | -| variables.rs:464:19:464:19 | x | variables.rs:464:9:464:20 | CallExpr | | -| variables.rs:465:12:467:5 | BlockExpr | variables.rs:463:5:467:5 | IfExpr | | +| variables.rs:464:19:464:19 | x | variables.rs:464:9:464:20 | print_i64(...) | | +| variables.rs:465:12:467:5 | { ... } | variables.rs:463:5:467:5 | if ... { ... } else { ... } | | | variables.rs:466:9:466:17 | print_i64 | variables.rs:466:19:466:19 | x | | -| variables.rs:466:9:466:20 | CallExpr | variables.rs:465:12:467:5 | BlockExpr | | +| variables.rs:466:9:466:20 | print_i64(...) | variables.rs:465:12:467:5 | { ... } | | | variables.rs:466:9:466:21 | ExprStmt | variables.rs:466:9:466:17 | print_i64 | | -| variables.rs:466:19:466:19 | x | variables.rs:466:9:466:20 | CallExpr | | -| variables.rs:469:5:473:5 | IfExpr | variables.rs:461:35:474:1 | BlockExpr | | +| variables.rs:466:19:466:19 | x | variables.rs:466:9:466:20 | print_i64(...) | | +| variables.rs:469:5:473:5 | if ... { ... } else { ... } | variables.rs:461:35:474:1 | { ... } | | | variables.rs:469:8:469:9 | b2 | variables.rs:470:9:470:21 | ExprStmt | true | | variables.rs:469:8:469:9 | b2 | variables.rs:472:9:472:21 | ExprStmt | false | -| variables.rs:469:11:471:5 | BlockExpr | variables.rs:469:5:473:5 | IfExpr | | +| variables.rs:469:11:471:5 | { ... } | variables.rs:469:5:473:5 | if ... { ... } else { ... } | | | variables.rs:470:9:470:17 | print_i64 | variables.rs:470:19:470:19 | x | | -| variables.rs:470:9:470:20 | CallExpr | variables.rs:469:11:471:5 | BlockExpr | | +| variables.rs:470:9:470:20 | print_i64(...) | variables.rs:469:11:471:5 | { ... } | | | variables.rs:470:9:470:21 | ExprStmt | variables.rs:470:9:470:17 | print_i64 | | -| variables.rs:470:19:470:19 | x | variables.rs:470:9:470:20 | CallExpr | | -| variables.rs:471:12:473:5 | BlockExpr | variables.rs:469:5:473:5 | IfExpr | | +| variables.rs:470:19:470:19 | x | variables.rs:470:9:470:20 | print_i64(...) | | +| variables.rs:471:12:473:5 | { ... } | variables.rs:469:5:473:5 | if ... { ... } else { ... } | | | variables.rs:472:9:472:17 | print_i64 | variables.rs:472:19:472:19 | x | | -| variables.rs:472:9:472:20 | CallExpr | variables.rs:471:12:473:5 | BlockExpr | | +| variables.rs:472:9:472:20 | print_i64(...) | variables.rs:471:12:473:5 | { ... } | | | variables.rs:472:9:472:21 | ExprStmt | variables.rs:472:9:472:17 | print_i64 | | -| variables.rs:472:19:472:19 | x | variables.rs:472:9:472:20 | CallExpr | | -| variables.rs:482:5:484:5 | enter my_get | variables.rs:483:9:483:24 | ExprStmt | | -| variables.rs:482:5:484:5 | exit my_get (normal) | variables.rs:482:5:484:5 | exit my_get | | -| variables.rs:483:9:483:23 | ReturnExpr | variables.rs:482:5:484:5 | exit my_get (normal) | return | +| variables.rs:472:19:472:19 | x | variables.rs:472:9:472:20 | print_i64(...) | | +| variables.rs:482:5:484:5 | enter fn my_get | variables.rs:483:9:483:24 | ExprStmt | | +| variables.rs:482:5:484:5 | exit fn my_get (normal) | variables.rs:482:5:484:5 | exit fn my_get | | +| variables.rs:483:9:483:23 | return ... | variables.rs:482:5:484:5 | exit fn my_get (normal) | return | | variables.rs:483:9:483:24 | ExprStmt | variables.rs:483:16:483:19 | self | | -| variables.rs:483:16:483:19 | self | variables.rs:483:16:483:23 | FieldExpr | | -| variables.rs:483:16:483:23 | FieldExpr | variables.rs:483:9:483:23 | ReturnExpr | | -| variables.rs:487:1:494:1 | enter structs | variables.rs:488:5:488:36 | LetStmt | | -| variables.rs:487:1:494:1 | exit structs (normal) | variables.rs:487:1:494:1 | exit structs | | -| variables.rs:487:14:494:1 | BlockExpr | variables.rs:487:1:494:1 | exit structs (normal) | | -| variables.rs:488:5:488:36 | LetStmt | variables.rs:488:33:488:33 | 1 | | +| variables.rs:483:16:483:19 | self | variables.rs:483:16:483:23 | ... .val | | +| variables.rs:483:16:483:23 | ... .val | variables.rs:483:9:483:23 | return ... | | +| variables.rs:487:1:494:1 | enter fn structs | variables.rs:488:5:488:36 | let a = ... | | +| variables.rs:487:1:494:1 | exit fn structs (normal) | variables.rs:487:1:494:1 | exit fn structs | | +| variables.rs:487:14:494:1 | { ... } | variables.rs:487:1:494:1 | exit fn structs (normal) | | +| variables.rs:488:5:488:36 | let a = ... | variables.rs:488:33:488:33 | 1 | | | variables.rs:488:9:488:13 | a | variables.rs:489:5:489:26 | ExprStmt | match | -| variables.rs:488:17:488:35 | RecordExpr | variables.rs:488:9:488:13 | a | | -| variables.rs:488:33:488:33 | 1 | variables.rs:488:17:488:35 | RecordExpr | | +| variables.rs:488:17:488:35 | MyStruct {...} | variables.rs:488:9:488:13 | a | | +| variables.rs:488:33:488:33 | 1 | variables.rs:488:17:488:35 | MyStruct {...} | | | variables.rs:489:5:489:13 | print_i64 | variables.rs:489:15:489:15 | a | | -| variables.rs:489:5:489:25 | CallExpr | variables.rs:490:5:490:14 | ExprStmt | | +| variables.rs:489:5:489:25 | print_i64(...) | variables.rs:490:5:490:14 | ExprStmt | | | variables.rs:489:5:489:26 | ExprStmt | variables.rs:489:5:489:13 | print_i64 | | | variables.rs:489:15:489:15 | a | variables.rs:489:15:489:24 | ... .my_get(...) | | -| variables.rs:489:15:489:24 | ... .my_get(...) | variables.rs:489:5:489:25 | CallExpr | | -| variables.rs:490:5:490:5 | a | variables.rs:490:5:490:9 | FieldExpr | | -| variables.rs:490:5:490:9 | FieldExpr | variables.rs:490:13:490:13 | 5 | | +| variables.rs:489:15:489:24 | ... .my_get(...) | variables.rs:489:5:489:25 | print_i64(...) | | +| variables.rs:490:5:490:5 | a | variables.rs:490:5:490:9 | ... .val | | +| variables.rs:490:5:490:9 | ... .val | variables.rs:490:13:490:13 | 5 | | | variables.rs:490:5:490:13 | ... = ... | variables.rs:491:5:491:26 | ExprStmt | | | variables.rs:490:5:490:14 | ExprStmt | variables.rs:490:5:490:5 | a | | | variables.rs:490:13:490:13 | 5 | variables.rs:490:5:490:13 | ... = ... | | | variables.rs:491:5:491:13 | print_i64 | variables.rs:491:15:491:15 | a | | -| variables.rs:491:5:491:25 | CallExpr | variables.rs:492:5:492:28 | ExprStmt | | +| variables.rs:491:5:491:25 | print_i64(...) | variables.rs:492:5:492:28 | ExprStmt | | | variables.rs:491:5:491:26 | ExprStmt | variables.rs:491:5:491:13 | print_i64 | | | variables.rs:491:15:491:15 | a | variables.rs:491:15:491:24 | ... .my_get(...) | | -| variables.rs:491:15:491:24 | ... .my_get(...) | variables.rs:491:5:491:25 | CallExpr | | +| variables.rs:491:15:491:24 | ... .my_get(...) | variables.rs:491:5:491:25 | print_i64(...) | | | variables.rs:492:5:492:5 | a | variables.rs:492:25:492:25 | 2 | | | variables.rs:492:5:492:27 | ... = ... | variables.rs:493:5:493:26 | ExprStmt | | | variables.rs:492:5:492:28 | ExprStmt | variables.rs:492:5:492:5 | a | | -| variables.rs:492:9:492:27 | RecordExpr | variables.rs:492:5:492:27 | ... = ... | | -| variables.rs:492:25:492:25 | 2 | variables.rs:492:9:492:27 | RecordExpr | | +| variables.rs:492:9:492:27 | MyStruct {...} | variables.rs:492:5:492:27 | ... = ... | | +| variables.rs:492:25:492:25 | 2 | variables.rs:492:9:492:27 | MyStruct {...} | | | variables.rs:493:5:493:13 | print_i64 | variables.rs:493:15:493:15 | a | | -| variables.rs:493:5:493:25 | CallExpr | variables.rs:487:14:494:1 | BlockExpr | | +| variables.rs:493:5:493:25 | print_i64(...) | variables.rs:487:14:494:1 | { ... } | | | variables.rs:493:5:493:26 | ExprStmt | variables.rs:493:5:493:13 | print_i64 | | | variables.rs:493:15:493:15 | a | variables.rs:493:15:493:24 | ... .my_get(...) | | -| variables.rs:493:15:493:24 | ... .my_get(...) | variables.rs:493:5:493:25 | CallExpr | | -| variables.rs:496:1:503:1 | enter ref_arg | variables.rs:497:5:497:15 | LetStmt | | -| variables.rs:496:1:503:1 | exit ref_arg (normal) | variables.rs:496:1:503:1 | exit ref_arg | | -| variables.rs:496:14:503:1 | BlockExpr | variables.rs:496:1:503:1 | exit ref_arg (normal) | | -| variables.rs:497:5:497:15 | LetStmt | variables.rs:497:13:497:14 | 16 | | +| variables.rs:493:15:493:24 | ... .my_get(...) | variables.rs:493:5:493:25 | print_i64(...) | | +| variables.rs:496:1:503:1 | enter fn ref_arg | variables.rs:497:5:497:15 | let x = ... | | +| variables.rs:496:1:503:1 | exit fn ref_arg (normal) | variables.rs:496:1:503:1 | exit fn ref_arg | | +| variables.rs:496:14:503:1 | { ... } | variables.rs:496:1:503:1 | exit fn ref_arg (normal) | | +| variables.rs:497:5:497:15 | let x = ... | variables.rs:497:13:497:14 | 16 | | | variables.rs:497:9:497:9 | x | variables.rs:498:5:498:22 | ExprStmt | match | | variables.rs:497:13:497:14 | 16 | variables.rs:497:9:497:9 | x | | | variables.rs:498:5:498:17 | print_i64_ref | variables.rs:498:20:498:20 | x | | -| variables.rs:498:5:498:21 | CallExpr | variables.rs:499:5:499:17 | ExprStmt | | +| variables.rs:498:5:498:21 | print_i64_ref(...) | variables.rs:499:5:499:17 | ExprStmt | | | variables.rs:498:5:498:22 | ExprStmt | variables.rs:498:5:498:17 | print_i64_ref | | -| variables.rs:498:19:498:20 | RefExpr | variables.rs:498:5:498:21 | CallExpr | | -| variables.rs:498:20:498:20 | x | variables.rs:498:19:498:20 | RefExpr | | +| variables.rs:498:19:498:20 | &... | variables.rs:498:5:498:21 | print_i64_ref(...) | | +| variables.rs:498:20:498:20 | x | variables.rs:498:19:498:20 | &... | | | variables.rs:499:5:499:13 | print_i64 | variables.rs:499:15:499:15 | x | | -| variables.rs:499:5:499:16 | CallExpr | variables.rs:501:5:501:15 | LetStmt | | +| variables.rs:499:5:499:16 | print_i64(...) | variables.rs:501:5:501:15 | let z = ... | | | variables.rs:499:5:499:17 | ExprStmt | variables.rs:499:5:499:13 | print_i64 | | -| variables.rs:499:15:499:15 | x | variables.rs:499:5:499:16 | CallExpr | | -| variables.rs:501:5:501:15 | LetStmt | variables.rs:501:13:501:14 | 17 | | +| variables.rs:499:15:499:15 | x | variables.rs:499:5:499:16 | print_i64(...) | | +| variables.rs:501:5:501:15 | let z = ... | variables.rs:501:13:501:14 | 17 | | | variables.rs:501:9:501:9 | z | variables.rs:502:5:502:22 | ExprStmt | match | | variables.rs:501:13:501:14 | 17 | variables.rs:501:9:501:9 | z | | | variables.rs:502:5:502:17 | print_i64_ref | variables.rs:502:20:502:20 | z | | -| variables.rs:502:5:502:21 | CallExpr | variables.rs:496:14:503:1 | BlockExpr | | +| variables.rs:502:5:502:21 | print_i64_ref(...) | variables.rs:496:14:503:1 | { ... } | | | variables.rs:502:5:502:22 | ExprStmt | variables.rs:502:5:502:17 | print_i64_ref | | -| variables.rs:502:19:502:20 | RefExpr | variables.rs:502:5:502:21 | CallExpr | | -| variables.rs:502:20:502:20 | z | variables.rs:502:19:502:20 | RefExpr | | -| variables.rs:510:3:512:3 | enter bar | variables.rs:511:5:511:32 | ExprStmt | | -| variables.rs:510:3:512:3 | exit bar (normal) | variables.rs:510:3:512:3 | exit bar | | -| variables.rs:510:21:512:3 | BlockExpr | variables.rs:510:3:512:3 | exit bar (normal) | | +| variables.rs:502:19:502:20 | &... | variables.rs:502:5:502:21 | print_i64_ref(...) | | +| variables.rs:502:20:502:20 | z | variables.rs:502:19:502:20 | &... | | +| variables.rs:510:3:512:3 | enter fn bar | variables.rs:511:5:511:32 | ExprStmt | | +| variables.rs:510:3:512:3 | exit fn bar (normal) | variables.rs:510:3:512:3 | exit fn bar | | +| variables.rs:510:21:512:3 | { ... } | variables.rs:510:3:512:3 | exit fn bar (normal) | | | variables.rs:511:5:511:9 | * ... | variables.rs:511:29:511:29 | 3 | | -| variables.rs:511:5:511:31 | ... = ... | variables.rs:510:21:512:3 | BlockExpr | | +| variables.rs:511:5:511:31 | ... = ... | variables.rs:510:21:512:3 | { ... } | | | variables.rs:511:5:511:32 | ExprStmt | variables.rs:511:6:511:9 | self | | | variables.rs:511:6:511:9 | self | variables.rs:511:5:511:9 | * ... | | -| variables.rs:511:13:511:31 | RecordExpr | variables.rs:511:5:511:31 | ... = ... | | -| variables.rs:511:29:511:29 | 3 | variables.rs:511:13:511:31 | RecordExpr | | -| variables.rs:515:1:520:1 | enter ref_methodcall_receiver | variables.rs:516:3:516:34 | LetStmt | | -| variables.rs:515:1:520:1 | exit ref_methodcall_receiver (normal) | variables.rs:515:1:520:1 | exit ref_methodcall_receiver | | -| variables.rs:515:30:520:1 | BlockExpr | variables.rs:515:1:520:1 | exit ref_methodcall_receiver (normal) | | -| variables.rs:516:3:516:34 | LetStmt | variables.rs:516:31:516:31 | 1 | | +| variables.rs:511:13:511:31 | MyStruct {...} | variables.rs:511:5:511:31 | ... = ... | | +| variables.rs:511:29:511:29 | 3 | variables.rs:511:13:511:31 | MyStruct {...} | | +| variables.rs:515:1:520:1 | enter fn ref_methodcall_receiver | variables.rs:516:3:516:34 | let a = ... | | +| variables.rs:515:1:520:1 | exit fn ref_methodcall_receiver (normal) | variables.rs:515:1:520:1 | exit fn ref_methodcall_receiver | | +| variables.rs:515:30:520:1 | { ... } | variables.rs:515:1:520:1 | exit fn ref_methodcall_receiver (normal) | | +| variables.rs:516:3:516:34 | let a = ... | variables.rs:516:31:516:31 | 1 | | | variables.rs:516:7:516:11 | a | variables.rs:517:3:517:10 | ExprStmt | match | -| variables.rs:516:15:516:33 | RecordExpr | variables.rs:516:7:516:11 | a | | -| variables.rs:516:31:516:31 | 1 | variables.rs:516:15:516:33 | RecordExpr | | +| variables.rs:516:15:516:33 | MyStruct {...} | variables.rs:516:7:516:11 | a | | +| variables.rs:516:31:516:31 | 1 | variables.rs:516:15:516:33 | MyStruct {...} | | | variables.rs:517:3:517:3 | a | variables.rs:517:3:517:9 | ... .bar(...) | | | variables.rs:517:3:517:9 | ... .bar(...) | variables.rs:519:3:519:19 | ExprStmt | | | variables.rs:517:3:517:10 | ExprStmt | variables.rs:517:3:517:3 | a | | | variables.rs:519:3:519:11 | print_i64 | variables.rs:519:13:519:13 | a | | -| variables.rs:519:3:519:18 | CallExpr | variables.rs:515:30:520:1 | BlockExpr | | +| variables.rs:519:3:519:18 | print_i64(...) | variables.rs:515:30:520:1 | { ... } | | | variables.rs:519:3:519:19 | ExprStmt | variables.rs:519:3:519:11 | print_i64 | | -| variables.rs:519:13:519:13 | a | variables.rs:519:13:519:17 | FieldExpr | | -| variables.rs:519:13:519:17 | FieldExpr | variables.rs:519:3:519:18 | CallExpr | | -| variables.rs:522:1:556:1 | enter main | variables.rs:523:5:523:25 | ExprStmt | | -| variables.rs:522:1:556:1 | exit main (normal) | variables.rs:522:1:556:1 | exit main | | -| variables.rs:522:11:556:1 | BlockExpr | variables.rs:522:1:556:1 | exit main (normal) | | -| variables.rs:523:5:523:22 | immutable_variable | variables.rs:523:5:523:24 | CallExpr | | -| variables.rs:523:5:523:24 | CallExpr | variables.rs:524:5:524:23 | ExprStmt | | +| variables.rs:519:13:519:13 | a | variables.rs:519:13:519:17 | ... .val | | +| variables.rs:519:13:519:17 | ... .val | variables.rs:519:3:519:18 | print_i64(...) | | +| variables.rs:522:1:556:1 | enter fn main | variables.rs:523:5:523:25 | ExprStmt | | +| variables.rs:522:1:556:1 | exit fn main (normal) | variables.rs:522:1:556:1 | exit fn main | | +| variables.rs:522:11:556:1 | { ... } | variables.rs:522:1:556:1 | exit fn main (normal) | | +| variables.rs:523:5:523:22 | immutable_variable | variables.rs:523:5:523:24 | immutable_variable(...) | | +| variables.rs:523:5:523:24 | immutable_variable(...) | variables.rs:524:5:524:23 | ExprStmt | | | variables.rs:523:5:523:25 | ExprStmt | variables.rs:523:5:523:22 | immutable_variable | | -| variables.rs:524:5:524:20 | mutable_variable | variables.rs:524:5:524:22 | CallExpr | | -| variables.rs:524:5:524:22 | CallExpr | variables.rs:525:5:525:40 | ExprStmt | | +| variables.rs:524:5:524:20 | mutable_variable | variables.rs:524:5:524:22 | mutable_variable(...) | | +| variables.rs:524:5:524:22 | mutable_variable(...) | variables.rs:525:5:525:40 | ExprStmt | | | variables.rs:524:5:524:23 | ExprStmt | variables.rs:524:5:524:20 | mutable_variable | | -| variables.rs:525:5:525:37 | mutable_variable_immutable_borrow | variables.rs:525:5:525:39 | CallExpr | | -| variables.rs:525:5:525:39 | CallExpr | variables.rs:526:5:526:23 | ExprStmt | | +| variables.rs:525:5:525:37 | mutable_variable_immutable_borrow | variables.rs:525:5:525:39 | mutable_variable_immutable_borrow(...) | | +| variables.rs:525:5:525:39 | mutable_variable_immutable_borrow(...) | variables.rs:526:5:526:23 | ExprStmt | | | variables.rs:525:5:525:40 | ExprStmt | variables.rs:525:5:525:37 | mutable_variable_immutable_borrow | | -| variables.rs:526:5:526:20 | variable_shadow1 | variables.rs:526:5:526:22 | CallExpr | | -| variables.rs:526:5:526:22 | CallExpr | variables.rs:527:5:527:23 | ExprStmt | | +| variables.rs:526:5:526:20 | variable_shadow1 | variables.rs:526:5:526:22 | variable_shadow1(...) | | +| variables.rs:526:5:526:22 | variable_shadow1(...) | variables.rs:527:5:527:23 | ExprStmt | | | variables.rs:526:5:526:23 | ExprStmt | variables.rs:526:5:526:20 | variable_shadow1 | | -| variables.rs:527:5:527:20 | variable_shadow2 | variables.rs:527:5:527:22 | CallExpr | | -| variables.rs:527:5:527:22 | CallExpr | variables.rs:528:5:528:19 | ExprStmt | | +| variables.rs:527:5:527:20 | variable_shadow2 | variables.rs:527:5:527:22 | variable_shadow2(...) | | +| variables.rs:527:5:527:22 | variable_shadow2(...) | variables.rs:528:5:528:19 | ExprStmt | | | variables.rs:527:5:527:23 | ExprStmt | variables.rs:527:5:527:20 | variable_shadow2 | | -| variables.rs:528:5:528:16 | let_pattern1 | variables.rs:528:5:528:18 | CallExpr | | -| variables.rs:528:5:528:18 | CallExpr | variables.rs:529:5:529:19 | ExprStmt | | +| variables.rs:528:5:528:16 | let_pattern1 | variables.rs:528:5:528:18 | let_pattern1(...) | | +| variables.rs:528:5:528:18 | let_pattern1(...) | variables.rs:529:5:529:19 | ExprStmt | | | variables.rs:528:5:528:19 | ExprStmt | variables.rs:528:5:528:16 | let_pattern1 | | -| variables.rs:529:5:529:16 | let_pattern2 | variables.rs:529:5:529:18 | CallExpr | | -| variables.rs:529:5:529:18 | CallExpr | variables.rs:530:5:530:19 | ExprStmt | | +| variables.rs:529:5:529:16 | let_pattern2 | variables.rs:529:5:529:18 | let_pattern2(...) | | +| variables.rs:529:5:529:18 | let_pattern2(...) | variables.rs:530:5:530:19 | ExprStmt | | | variables.rs:529:5:529:19 | ExprStmt | variables.rs:529:5:529:16 | let_pattern2 | | -| variables.rs:530:5:530:16 | let_pattern3 | variables.rs:530:5:530:18 | CallExpr | | -| variables.rs:530:5:530:18 | CallExpr | variables.rs:531:5:531:19 | ExprStmt | | +| variables.rs:530:5:530:16 | let_pattern3 | variables.rs:530:5:530:18 | let_pattern3(...) | | +| variables.rs:530:5:530:18 | let_pattern3(...) | variables.rs:531:5:531:19 | ExprStmt | | | variables.rs:530:5:530:19 | ExprStmt | variables.rs:530:5:530:16 | let_pattern3 | | -| variables.rs:531:5:531:16 | let_pattern4 | variables.rs:531:5:531:18 | CallExpr | | -| variables.rs:531:5:531:18 | CallExpr | variables.rs:532:5:532:21 | ExprStmt | | +| variables.rs:531:5:531:16 | let_pattern4 | variables.rs:531:5:531:18 | let_pattern4(...) | | +| variables.rs:531:5:531:18 | let_pattern4(...) | variables.rs:532:5:532:21 | ExprStmt | | | variables.rs:531:5:531:19 | ExprStmt | variables.rs:531:5:531:16 | let_pattern4 | | -| variables.rs:532:5:532:18 | match_pattern1 | variables.rs:532:5:532:20 | CallExpr | | -| variables.rs:532:5:532:20 | CallExpr | variables.rs:533:5:533:21 | ExprStmt | | +| variables.rs:532:5:532:18 | match_pattern1 | variables.rs:532:5:532:20 | match_pattern1(...) | | +| variables.rs:532:5:532:20 | match_pattern1(...) | variables.rs:533:5:533:21 | ExprStmt | | | variables.rs:532:5:532:21 | ExprStmt | variables.rs:532:5:532:18 | match_pattern1 | | -| variables.rs:533:5:533:18 | match_pattern2 | variables.rs:533:5:533:20 | CallExpr | | -| variables.rs:533:5:533:20 | CallExpr | variables.rs:534:5:534:21 | ExprStmt | | +| variables.rs:533:5:533:18 | match_pattern2 | variables.rs:533:5:533:20 | match_pattern2(...) | | +| variables.rs:533:5:533:20 | match_pattern2(...) | variables.rs:534:5:534:21 | ExprStmt | | | variables.rs:533:5:533:21 | ExprStmt | variables.rs:533:5:533:18 | match_pattern2 | | -| variables.rs:534:5:534:18 | match_pattern3 | variables.rs:534:5:534:20 | CallExpr | | -| variables.rs:534:5:534:20 | CallExpr | variables.rs:535:5:535:21 | ExprStmt | | +| variables.rs:534:5:534:18 | match_pattern3 | variables.rs:534:5:534:20 | match_pattern3(...) | | +| variables.rs:534:5:534:20 | match_pattern3(...) | variables.rs:535:5:535:21 | ExprStmt | | | variables.rs:534:5:534:21 | ExprStmt | variables.rs:534:5:534:18 | match_pattern3 | | -| variables.rs:535:5:535:18 | match_pattern4 | variables.rs:535:5:535:20 | CallExpr | | -| variables.rs:535:5:535:20 | CallExpr | variables.rs:536:5:536:21 | ExprStmt | | +| variables.rs:535:5:535:18 | match_pattern4 | variables.rs:535:5:535:20 | match_pattern4(...) | | +| variables.rs:535:5:535:20 | match_pattern4(...) | variables.rs:536:5:536:21 | ExprStmt | | | variables.rs:535:5:535:21 | ExprStmt | variables.rs:535:5:535:18 | match_pattern4 | | -| variables.rs:536:5:536:18 | match_pattern5 | variables.rs:536:5:536:20 | CallExpr | | -| variables.rs:536:5:536:20 | CallExpr | variables.rs:537:5:537:21 | ExprStmt | | +| variables.rs:536:5:536:18 | match_pattern5 | variables.rs:536:5:536:20 | match_pattern5(...) | | +| variables.rs:536:5:536:20 | match_pattern5(...) | variables.rs:537:5:537:21 | ExprStmt | | | variables.rs:536:5:536:21 | ExprStmt | variables.rs:536:5:536:18 | match_pattern5 | | -| variables.rs:537:5:537:18 | match_pattern6 | variables.rs:537:5:537:20 | CallExpr | | -| variables.rs:537:5:537:20 | CallExpr | variables.rs:538:5:538:21 | ExprStmt | | +| variables.rs:537:5:537:18 | match_pattern6 | variables.rs:537:5:537:20 | match_pattern6(...) | | +| variables.rs:537:5:537:20 | match_pattern6(...) | variables.rs:538:5:538:21 | ExprStmt | | | variables.rs:537:5:537:21 | ExprStmt | variables.rs:537:5:537:18 | match_pattern6 | | -| variables.rs:538:5:538:18 | match_pattern7 | variables.rs:538:5:538:20 | CallExpr | | -| variables.rs:538:5:538:20 | CallExpr | variables.rs:539:5:539:21 | ExprStmt | | +| variables.rs:538:5:538:18 | match_pattern7 | variables.rs:538:5:538:20 | match_pattern7(...) | | +| variables.rs:538:5:538:20 | match_pattern7(...) | variables.rs:539:5:539:21 | ExprStmt | | | variables.rs:538:5:538:21 | ExprStmt | variables.rs:538:5:538:18 | match_pattern7 | | -| variables.rs:539:5:539:18 | match_pattern8 | variables.rs:539:5:539:20 | CallExpr | | -| variables.rs:539:5:539:20 | CallExpr | variables.rs:540:5:540:21 | ExprStmt | | +| variables.rs:539:5:539:18 | match_pattern8 | variables.rs:539:5:539:20 | match_pattern8(...) | | +| variables.rs:539:5:539:20 | match_pattern8(...) | variables.rs:540:5:540:21 | ExprStmt | | | variables.rs:539:5:539:21 | ExprStmt | variables.rs:539:5:539:18 | match_pattern8 | | -| variables.rs:540:5:540:18 | match_pattern9 | variables.rs:540:5:540:20 | CallExpr | | -| variables.rs:540:5:540:20 | CallExpr | variables.rs:541:5:541:36 | ExprStmt | | +| variables.rs:540:5:540:18 | match_pattern9 | variables.rs:540:5:540:20 | match_pattern9(...) | | +| variables.rs:540:5:540:20 | match_pattern9(...) | variables.rs:541:5:541:36 | ExprStmt | | | variables.rs:540:5:540:21 | ExprStmt | variables.rs:540:5:540:18 | match_pattern9 | | | variables.rs:541:5:541:18 | param_pattern1 | variables.rs:541:20:541:22 | "a" | | -| variables.rs:541:5:541:35 | CallExpr | variables.rs:542:5:542:37 | ExprStmt | | +| variables.rs:541:5:541:35 | param_pattern1(...) | variables.rs:542:5:542:37 | ExprStmt | | | variables.rs:541:5:541:36 | ExprStmt | variables.rs:541:5:541:18 | param_pattern1 | | | variables.rs:541:20:541:22 | "a" | variables.rs:541:26:541:28 | "b" | | -| variables.rs:541:25:541:34 | TupleExpr | variables.rs:541:5:541:35 | CallExpr | | +| variables.rs:541:25:541:34 | TupleExpr | variables.rs:541:5:541:35 | param_pattern1(...) | | | variables.rs:541:26:541:28 | "b" | variables.rs:541:31:541:33 | "c" | | | variables.rs:541:31:541:33 | "c" | variables.rs:541:25:541:34 | TupleExpr | | | variables.rs:542:5:542:18 | param_pattern2 | variables.rs:542:20:542:31 | Either::Left | | -| variables.rs:542:5:542:36 | CallExpr | variables.rs:543:5:543:26 | ExprStmt | | +| variables.rs:542:5:542:36 | param_pattern2(...) | variables.rs:543:5:543:26 | ExprStmt | | | variables.rs:542:5:542:37 | ExprStmt | variables.rs:542:5:542:18 | param_pattern2 | | | variables.rs:542:20:542:31 | Either::Left | variables.rs:542:33:542:34 | 45 | | -| variables.rs:542:20:542:35 | CallExpr | variables.rs:542:5:542:36 | CallExpr | | -| variables.rs:542:33:542:34 | 45 | variables.rs:542:20:542:35 | CallExpr | | -| variables.rs:543:5:543:23 | destruct_assignment | variables.rs:543:5:543:25 | CallExpr | | -| variables.rs:543:5:543:25 | CallExpr | variables.rs:544:5:544:23 | ExprStmt | | +| variables.rs:542:20:542:35 | Either::Left(...) | variables.rs:542:5:542:36 | param_pattern2(...) | | +| variables.rs:542:33:542:34 | 45 | variables.rs:542:20:542:35 | Either::Left(...) | | +| variables.rs:543:5:543:23 | destruct_assignment | variables.rs:543:5:543:25 | destruct_assignment(...) | | +| variables.rs:543:5:543:25 | destruct_assignment(...) | variables.rs:544:5:544:23 | ExprStmt | | | variables.rs:543:5:543:26 | ExprStmt | variables.rs:543:5:543:23 | destruct_assignment | | -| variables.rs:544:5:544:20 | closure_variable | variables.rs:544:5:544:22 | CallExpr | | -| variables.rs:544:5:544:22 | CallExpr | variables.rs:545:5:545:19 | ExprStmt | | +| variables.rs:544:5:544:20 | closure_variable | variables.rs:544:5:544:22 | closure_variable(...) | | +| variables.rs:544:5:544:22 | closure_variable(...) | variables.rs:545:5:545:19 | ExprStmt | | | variables.rs:544:5:544:23 | ExprStmt | variables.rs:544:5:544:20 | closure_variable | | -| variables.rs:545:5:545:16 | for_variable | variables.rs:545:5:545:18 | CallExpr | | -| variables.rs:545:5:545:18 | CallExpr | variables.rs:546:5:546:17 | ExprStmt | | +| variables.rs:545:5:545:16 | for_variable | variables.rs:545:5:545:18 | for_variable(...) | | +| variables.rs:545:5:545:18 | for_variable(...) | variables.rs:546:5:546:17 | ExprStmt | | | variables.rs:545:5:545:19 | ExprStmt | variables.rs:545:5:545:16 | for_variable | | -| variables.rs:546:5:546:14 | add_assign | variables.rs:546:5:546:16 | CallExpr | | -| variables.rs:546:5:546:16 | CallExpr | variables.rs:547:5:547:13 | ExprStmt | | +| variables.rs:546:5:546:14 | add_assign | variables.rs:546:5:546:16 | add_assign(...) | | +| variables.rs:546:5:546:16 | add_assign(...) | variables.rs:547:5:547:13 | ExprStmt | | | variables.rs:546:5:546:17 | ExprStmt | variables.rs:546:5:546:14 | add_assign | | -| variables.rs:547:5:547:10 | mutate | variables.rs:547:5:547:12 | CallExpr | | -| variables.rs:547:5:547:12 | CallExpr | variables.rs:548:5:548:17 | ExprStmt | | +| variables.rs:547:5:547:10 | mutate | variables.rs:547:5:547:12 | mutate(...) | | +| variables.rs:547:5:547:12 | mutate(...) | variables.rs:548:5:548:17 | ExprStmt | | | variables.rs:547:5:547:13 | ExprStmt | variables.rs:547:5:547:10 | mutate | | -| variables.rs:548:5:548:14 | mutate_arg | variables.rs:548:5:548:16 | CallExpr | | -| variables.rs:548:5:548:16 | CallExpr | variables.rs:549:5:549:12 | ExprStmt | | +| variables.rs:548:5:548:14 | mutate_arg | variables.rs:548:5:548:16 | mutate_arg(...) | | +| variables.rs:548:5:548:16 | mutate_arg(...) | variables.rs:549:5:549:12 | ExprStmt | | | variables.rs:548:5:548:17 | ExprStmt | variables.rs:548:5:548:14 | mutate_arg | | -| variables.rs:549:5:549:9 | alias | variables.rs:549:5:549:11 | CallExpr | | -| variables.rs:549:5:549:11 | CallExpr | variables.rs:550:5:550:18 | ExprStmt | | +| variables.rs:549:5:549:9 | alias | variables.rs:549:5:549:11 | alias(...) | | +| variables.rs:549:5:549:11 | alias(...) | variables.rs:550:5:550:18 | ExprStmt | | | variables.rs:549:5:549:12 | ExprStmt | variables.rs:549:5:549:9 | alias | | -| variables.rs:550:5:550:15 | capture_mut | variables.rs:550:5:550:17 | CallExpr | | -| variables.rs:550:5:550:17 | CallExpr | variables.rs:551:5:551:20 | ExprStmt | | +| variables.rs:550:5:550:15 | capture_mut | variables.rs:550:5:550:17 | capture_mut(...) | | +| variables.rs:550:5:550:17 | capture_mut(...) | variables.rs:551:5:551:20 | ExprStmt | | | variables.rs:550:5:550:18 | ExprStmt | variables.rs:550:5:550:15 | capture_mut | | -| variables.rs:551:5:551:17 | capture_immut | variables.rs:551:5:551:19 | CallExpr | | -| variables.rs:551:5:551:19 | CallExpr | variables.rs:552:5:552:26 | ExprStmt | | +| variables.rs:551:5:551:17 | capture_immut | variables.rs:551:5:551:19 | capture_immut(...) | | +| variables.rs:551:5:551:19 | capture_immut(...) | variables.rs:552:5:552:26 | ExprStmt | | | variables.rs:551:5:551:20 | ExprStmt | variables.rs:551:5:551:17 | capture_immut | | -| variables.rs:552:5:552:23 | async_block_capture | variables.rs:552:5:552:25 | CallExpr | | -| variables.rs:552:5:552:25 | CallExpr | variables.rs:553:5:553:14 | ExprStmt | | +| variables.rs:552:5:552:23 | async_block_capture | variables.rs:552:5:552:25 | async_block_capture(...) | | +| variables.rs:552:5:552:25 | async_block_capture(...) | variables.rs:553:5:553:14 | ExprStmt | | | variables.rs:552:5:552:26 | ExprStmt | variables.rs:552:5:552:23 | async_block_capture | | -| variables.rs:553:5:553:11 | structs | variables.rs:553:5:553:13 | CallExpr | | -| variables.rs:553:5:553:13 | CallExpr | variables.rs:554:5:554:14 | ExprStmt | | +| variables.rs:553:5:553:11 | structs | variables.rs:553:5:553:13 | structs(...) | | +| variables.rs:553:5:553:13 | structs(...) | variables.rs:554:5:554:14 | ExprStmt | | | variables.rs:553:5:553:14 | ExprStmt | variables.rs:553:5:553:11 | structs | | -| variables.rs:554:5:554:11 | ref_arg | variables.rs:554:5:554:13 | CallExpr | | -| variables.rs:554:5:554:13 | CallExpr | variables.rs:555:5:555:30 | ExprStmt | | +| variables.rs:554:5:554:11 | ref_arg | variables.rs:554:5:554:13 | ref_arg(...) | | +| variables.rs:554:5:554:13 | ref_arg(...) | variables.rs:555:5:555:30 | ExprStmt | | | variables.rs:554:5:554:14 | ExprStmt | variables.rs:554:5:554:11 | ref_arg | | -| variables.rs:555:5:555:27 | ref_methodcall_receiver | variables.rs:555:5:555:29 | CallExpr | | -| variables.rs:555:5:555:29 | CallExpr | variables.rs:522:11:556:1 | BlockExpr | | +| variables.rs:555:5:555:27 | ref_methodcall_receiver | variables.rs:555:5:555:29 | ref_methodcall_receiver(...) | | +| variables.rs:555:5:555:29 | ref_methodcall_receiver(...) | variables.rs:522:11:556:1 | { ... } | | | variables.rs:555:5:555:30 | ExprStmt | variables.rs:555:5:555:27 | ref_methodcall_receiver | | breakTarget continueTarget diff --git a/rust/ql/test/library-tests/variables/Ssa.expected b/rust/ql/test/library-tests/variables/Ssa.expected index 0ca5a421853..8eb885d77d3 100644 --- a/rust/ql/test/library-tests/variables/Ssa.expected +++ b/rust/ql/test/library-tests/variables/Ssa.expected @@ -120,7 +120,7 @@ definition | variables.rs:418:9:418:13 | y | variables.rs:418:13:418:13 | y | | variables.rs:420:9:420:20 | closure2 | variables.rs:420:13:420:20 | closure2 | | variables.rs:421:9:421:9 | y | variables.rs:418:13:418:13 | y | -| variables.rs:423:5:423:14 | ... (...) | variables.rs:418:13:418:13 | y | +| variables.rs:423:5:423:14 | closure2(...) | variables.rs:418:13:418:13 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | | variables.rs:436:9:436:13 | i | variables.rs:436:13:436:13 | i | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | @@ -239,7 +239,7 @@ read | variables.rs:412:9:412:16 | closure1 | variables.rs:412:9:412:16 | closure1 | variables.rs:415:5:415:12 | closure1 | | variables.rs:412:20:414:5 | x | variables.rs:410:13:410:13 | x | variables.rs:413:19:413:19 | x | | variables.rs:420:9:420:20 | closure2 | variables.rs:420:13:420:20 | closure2 | variables.rs:423:5:423:12 | closure2 | -| variables.rs:423:5:423:14 | ... (...) | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | +| variables.rs:423:5:423:14 | closure2(...) | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | | variables.rs:441:5:441:15 | await ... | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | @@ -343,7 +343,7 @@ firstRead | variables.rs:412:9:412:16 | closure1 | variables.rs:412:9:412:16 | closure1 | variables.rs:415:5:415:12 | closure1 | | variables.rs:412:20:414:5 | x | variables.rs:410:13:410:13 | x | variables.rs:413:19:413:19 | x | | variables.rs:420:9:420:20 | closure2 | variables.rs:420:13:420:20 | closure2 | variables.rs:423:5:423:12 | closure2 | -| variables.rs:423:5:423:14 | ... (...) | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | +| variables.rs:423:5:423:14 | closure2(...) | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | | variables.rs:441:5:441:15 | await ... | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | @@ -443,7 +443,7 @@ lastRead | variables.rs:412:9:412:16 | closure1 | variables.rs:412:9:412:16 | closure1 | variables.rs:415:5:415:12 | closure1 | | variables.rs:412:20:414:5 | x | variables.rs:410:13:410:13 | x | variables.rs:413:19:413:19 | x | | variables.rs:420:9:420:20 | closure2 | variables.rs:420:13:420:20 | closure2 | variables.rs:423:5:423:12 | closure2 | -| variables.rs:423:5:423:14 | ... (...) | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | +| variables.rs:423:5:423:14 | closure2(...) | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | | variables.rs:441:5:441:15 | await ... | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index 6760f9bcdde..ea439e78d5b 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -1,468 +1,2 @@ -testFailures -failures -variable -| variables.rs:3:14:3:14 | s | -| variables.rs:7:14:7:14 | i | -| variables.rs:11:18:11:18 | i | -| variables.rs:16:9:16:10 | x1 | -| variables.rs:21:13:21:14 | x2 | -| variables.rs:28:13:28:13 | x | -| variables.rs:35:9:35:10 | x3 | -| variables.rs:37:9:37:10 | x3 | -| variables.rs:43:9:43:10 | x4 | -| variables.rs:46:13:46:14 | x4 | -| variables.rs:60:13:60:14 | a1 | -| variables.rs:61:13:61:14 | b1 | -| variables.rs:64:13:64:13 | x | -| variables.rs:65:13:65:13 | y | -| variables.rs:75:9:75:10 | p1 | -| variables.rs:77:12:77:13 | a2 | -| variables.rs:78:12:78:13 | b2 | -| variables.rs:85:9:85:10 | s1 | -| variables.rs:87:21:87:22 | s2 | -| variables.rs:94:14:94:15 | x5 | -| variables.rs:102:9:102:10 | s1 | -| variables.rs:104:24:104:25 | s2 | -| variables.rs:111:9:111:10 | x6 | -| variables.rs:112:9:112:10 | y1 | -| variables.rs:116:14:116:15 | y1 | -| variables.rs:128:9:128:15 | numbers | -| variables.rs:132:13:132:17 | first | -| variables.rs:133:13:133:17 | third | -| variables.rs:134:13:134:17 | fifth | -| variables.rs:144:13:144:17 | first | -| variables.rs:146:13:146:16 | last | -| variables.rs:155:9:155:10 | p2 | -| variables.rs:159:16:159:17 | x7 | -| variables.rs:169:9:169:11 | msg | -| variables.rs:173:17:173:27 | id_variable | -| variables.rs:178:26:178:27 | id | -| variables.rs:189:9:189:14 | either | -| variables.rs:191:9:191:44 | a3 | -| variables.rs:203:9:203:10 | tv | -| variables.rs:205:9:205:81 | a4 | -| variables.rs:209:9:209:83 | a5 | -| variables.rs:213:9:213:83 | a6 | -| variables.rs:219:9:219:14 | either | -| variables.rs:221:9:221:44 | a7 | -| variables.rs:229:9:229:14 | either | -| variables.rs:232:13:232:13 | e | -| variables.rs:233:14:233:51 | a11 | -| variables.rs:236:33:236:35 | a12 | -| variables.rs:253:9:253:10 | fv | -| variables.rs:255:9:255:109 | a13 | -| variables.rs:261:5:261:6 | a8 | -| variables.rs:263:9:263:10 | b3 | -| variables.rs:264:9:264:10 | c1 | -| variables.rs:272:6:272:41 | a9 | -| variables.rs:279:13:279:15 | a10 | -| variables.rs:280:13:280:14 | b4 | -| variables.rs:281:13:281:14 | c2 | -| variables.rs:302:13:302:15 | a10 | -| variables.rs:303:13:303:14 | b4 | -| variables.rs:315:9:315:23 | example_closure | -| variables.rs:316:10:316:10 | x | -| variables.rs:318:9:318:10 | n1 | -| variables.rs:323:9:323:26 | immutable_variable | -| variables.rs:324:10:324:10 | x | -| variables.rs:326:9:326:10 | n2 | -| variables.rs:332:9:332:9 | v | -| variables.rs:334:9:334:12 | text | -| variables.rs:341:13:341:13 | a | -| variables.rs:349:13:349:13 | i | -| variables.rs:350:9:350:13 | ref_i | -| variables.rs:356:17:356:17 | x | -| variables.rs:363:22:363:22 | x | -| variables.rs:363:39:363:39 | y | -| variables.rs:372:13:372:13 | x | -| variables.rs:373:9:373:9 | y | -| variables.rs:379:13:379:13 | z | -| variables.rs:380:9:380:9 | w | -| variables.rs:392:13:392:13 | x | -| variables.rs:393:9:393:9 | y | -| variables.rs:400:9:400:9 | x | -| variables.rs:402:9:402:11 | cap | -| variables.rs:410:13:410:13 | x | -| variables.rs:412:9:412:16 | closure1 | -| variables.rs:418:13:418:13 | y | -| variables.rs:420:13:420:20 | closure2 | -| variables.rs:426:13:426:13 | z | -| variables.rs:428:13:428:20 | closure3 | -| variables.rs:436:13:436:13 | i | -| variables.rs:437:9:437:13 | block | -| variables.rs:445:8:445:8 | b | -| variables.rs:446:13:446:13 | x | -| variables.rs:461:13:461:14 | b1 | -| variables.rs:461:24:461:25 | b2 | -| variables.rs:462:9:462:9 | x | -| variables.rs:488:13:488:13 | a | -| variables.rs:497:9:497:9 | x | -| variables.rs:501:9:501:9 | z | -| variables.rs:516:11:516:11 | a | -variableAccess -| variables.rs:4:20:4:20 | s | variables.rs:3:14:3:14 | s | -| variables.rs:8:20:8:20 | i | variables.rs:7:14:7:14 | i | -| variables.rs:12:16:12:16 | i | variables.rs:11:18:11:18 | i | -| variables.rs:17:15:17:16 | x1 | variables.rs:16:9:16:10 | x1 | -| variables.rs:22:15:22:16 | x2 | variables.rs:21:13:21:14 | x2 | -| variables.rs:23:5:23:6 | x2 | variables.rs:21:13:21:14 | x2 | -| variables.rs:24:15:24:16 | x2 | variables.rs:21:13:21:14 | x2 | -| variables.rs:29:20:29:20 | x | variables.rs:28:13:28:13 | x | -| variables.rs:30:5:30:5 | x | variables.rs:28:13:28:13 | x | -| variables.rs:31:20:31:20 | x | variables.rs:28:13:28:13 | x | -| variables.rs:36:15:36:16 | x3 | variables.rs:35:9:35:10 | x3 | -| variables.rs:38:9:38:10 | x3 | variables.rs:35:9:35:10 | x3 | -| variables.rs:39:15:39:16 | x3 | variables.rs:37:9:37:10 | x3 | -| variables.rs:44:15:44:16 | x4 | variables.rs:43:9:43:10 | x4 | -| variables.rs:47:19:47:20 | x4 | variables.rs:46:13:46:14 | x4 | -| variables.rs:49:15:49:16 | x4 | variables.rs:43:9:43:10 | x4 | -| variables.rs:68:15:68:16 | a1 | variables.rs:60:13:60:14 | a1 | -| variables.rs:69:15:69:16 | b1 | variables.rs:61:13:61:14 | b1 | -| variables.rs:70:15:70:15 | x | variables.rs:64:13:64:13 | x | -| variables.rs:71:15:71:15 | y | variables.rs:65:13:65:13 | y | -| variables.rs:79:9:79:10 | p1 | variables.rs:75:9:75:10 | p1 | -| variables.rs:80:15:80:16 | a2 | variables.rs:77:12:77:13 | a2 | -| variables.rs:81:15:81:16 | b2 | variables.rs:78:12:78:13 | b2 | -| variables.rs:88:11:88:12 | s1 | variables.rs:85:9:85:10 | s1 | -| variables.rs:89:19:89:20 | s2 | variables.rs:87:21:87:22 | s2 | -| variables.rs:98:15:98:16 | x5 | variables.rs:94:14:94:15 | x5 | -| variables.rs:105:11:105:12 | s1 | variables.rs:102:9:102:10 | s1 | -| variables.rs:106:19:106:20 | s2 | variables.rs:104:24:104:25 | s2 | -| variables.rs:114:11:114:12 | x6 | variables.rs:111:9:111:10 | x6 | -| variables.rs:119:23:119:24 | y1 | variables.rs:116:14:116:15 | y1 | -| variables.rs:124:15:124:16 | y1 | variables.rs:112:9:112:10 | y1 | -| variables.rs:130:11:130:17 | numbers | variables.rs:128:9:128:15 | numbers | -| variables.rs:136:23:136:27 | first | variables.rs:132:13:132:17 | first | -| variables.rs:137:23:137:27 | third | variables.rs:133:13:133:17 | third | -| variables.rs:138:23:138:27 | fifth | variables.rs:134:13:134:17 | fifth | -| variables.rs:142:11:142:17 | numbers | variables.rs:128:9:128:15 | numbers | -| variables.rs:148:23:148:27 | first | variables.rs:144:13:144:17 | first | -| variables.rs:149:23:149:26 | last | variables.rs:146:13:146:16 | last | -| variables.rs:157:11:157:12 | p2 | variables.rs:155:9:155:10 | p2 | -| variables.rs:160:24:160:25 | x7 | variables.rs:159:16:159:17 | x7 | -| variables.rs:171:11:171:13 | msg | variables.rs:169:9:169:11 | msg | -| variables.rs:174:24:174:34 | id_variable | variables.rs:173:17:173:27 | id_variable | -| variables.rs:179:23:179:24 | id | variables.rs:178:26:178:27 | id | -| variables.rs:190:11:190:16 | either | variables.rs:189:9:189:14 | either | -| variables.rs:192:26:192:27 | a3 | variables.rs:191:9:191:44 | a3 | -| variables.rs:204:11:204:12 | tv | variables.rs:203:9:203:10 | tv | -| variables.rs:206:26:206:27 | a4 | variables.rs:205:9:205:81 | a4 | -| variables.rs:208:11:208:12 | tv | variables.rs:203:9:203:10 | tv | -| variables.rs:210:26:210:27 | a5 | variables.rs:209:9:209:83 | a5 | -| variables.rs:212:11:212:12 | tv | variables.rs:203:9:203:10 | tv | -| variables.rs:214:26:214:27 | a6 | variables.rs:213:9:213:83 | a6 | -| variables.rs:220:11:220:16 | either | variables.rs:219:9:219:14 | either | -| variables.rs:222:16:222:17 | a7 | variables.rs:221:9:221:44 | a7 | -| variables.rs:223:26:223:27 | a7 | variables.rs:221:9:221:44 | a7 | -| variables.rs:231:11:231:16 | either | variables.rs:229:9:229:14 | either | -| variables.rs:235:23:235:25 | a11 | variables.rs:233:14:233:51 | a11 | -| variables.rs:237:15:237:15 | e | variables.rs:232:13:232:13 | e | -| variables.rs:238:28:238:30 | a12 | variables.rs:236:33:236:35 | a12 | -| variables.rs:254:11:254:12 | fv | variables.rs:253:9:253:10 | fv | -| variables.rs:256:26:256:28 | a13 | variables.rs:255:9:255:109 | a13 | -| variables.rs:266:15:266:16 | a8 | variables.rs:261:5:261:6 | a8 | -| variables.rs:267:15:267:16 | b3 | variables.rs:263:9:263:10 | b3 | -| variables.rs:268:15:268:16 | c1 | variables.rs:264:9:264:10 | c1 | -| variables.rs:274:15:274:16 | a9 | variables.rs:272:6:272:41 | a9 | -| variables.rs:283:15:283:17 | a10 | variables.rs:279:13:279:15 | a10 | -| variables.rs:284:15:284:16 | b4 | variables.rs:280:13:280:14 | b4 | -| variables.rs:285:15:285:16 | c2 | variables.rs:281:13:281:14 | c2 | -| variables.rs:288:9:288:10 | c2 | variables.rs:281:13:281:14 | c2 | -| variables.rs:289:9:289:10 | b4 | variables.rs:280:13:280:14 | b4 | -| variables.rs:290:9:290:11 | a10 | variables.rs:279:13:279:15 | a10 | -| variables.rs:292:9:292:11 | a10 | variables.rs:279:13:279:15 | a10 | -| variables.rs:293:9:293:10 | b4 | variables.rs:280:13:280:14 | b4 | -| variables.rs:294:9:294:10 | c2 | variables.rs:281:13:281:14 | c2 | -| variables.rs:296:15:296:17 | a10 | variables.rs:279:13:279:15 | a10 | -| variables.rs:297:15:297:16 | b4 | variables.rs:280:13:280:14 | b4 | -| variables.rs:298:15:298:16 | c2 | variables.rs:281:13:281:14 | c2 | -| variables.rs:305:23:305:25 | a10 | variables.rs:302:13:302:15 | a10 | -| variables.rs:306:23:306:24 | b4 | variables.rs:303:13:303:14 | b4 | -| variables.rs:310:15:310:17 | a10 | variables.rs:279:13:279:15 | a10 | -| variables.rs:311:15:311:16 | b4 | variables.rs:280:13:280:14 | b4 | -| variables.rs:317:9:317:9 | x | variables.rs:316:10:316:10 | x | -| variables.rs:319:9:319:23 | example_closure | variables.rs:315:9:315:23 | example_closure | -| variables.rs:320:15:320:16 | n1 | variables.rs:318:9:318:10 | n1 | -| variables.rs:325:9:325:9 | x | variables.rs:324:10:324:10 | x | -| variables.rs:327:9:327:26 | immutable_variable | variables.rs:323:9:323:26 | immutable_variable | -| variables.rs:328:15:328:16 | n2 | variables.rs:326:9:326:10 | n2 | -| variables.rs:335:12:335:12 | v | variables.rs:332:9:332:9 | v | -| variables.rs:336:19:336:22 | text | variables.rs:334:9:334:12 | text | -| variables.rs:342:5:342:5 | a | variables.rs:341:13:341:13 | a | -| variables.rs:343:15:343:15 | a | variables.rs:341:13:341:13 | a | -| variables.rs:344:11:344:11 | a | variables.rs:341:13:341:13 | a | -| variables.rs:345:15:345:15 | a | variables.rs:341:13:341:13 | a | -| variables.rs:351:14:351:14 | i | variables.rs:349:13:349:13 | i | -| variables.rs:352:6:352:10 | ref_i | variables.rs:350:9:350:13 | ref_i | -| variables.rs:353:15:353:15 | i | variables.rs:349:13:349:13 | i | -| variables.rs:357:6:357:6 | x | variables.rs:356:17:356:17 | x | -| variables.rs:358:10:358:10 | x | variables.rs:356:17:356:17 | x | -| variables.rs:359:10:359:10 | x | variables.rs:356:17:356:17 | x | -| variables.rs:360:12:360:12 | x | variables.rs:356:17:356:17 | x | -| variables.rs:364:6:364:6 | x | variables.rs:363:22:363:22 | x | -| variables.rs:365:10:365:10 | x | variables.rs:363:22:363:22 | x | -| variables.rs:366:10:366:10 | x | variables.rs:363:22:363:22 | x | -| variables.rs:367:6:367:6 | y | variables.rs:363:39:363:39 | y | -| variables.rs:368:9:368:9 | x | variables.rs:363:22:363:22 | x | -| variables.rs:374:27:374:27 | x | variables.rs:372:13:372:13 | x | -| variables.rs:375:6:375:6 | y | variables.rs:373:9:373:9 | y | -| variables.rs:377:15:377:15 | x | variables.rs:372:13:372:13 | x | -| variables.rs:381:19:381:19 | x | variables.rs:372:13:372:13 | x | -| variables.rs:383:14:383:14 | z | variables.rs:379:13:379:13 | z | -| variables.rs:384:9:384:9 | w | variables.rs:380:9:380:9 | w | -| variables.rs:386:7:386:7 | w | variables.rs:380:9:380:9 | w | -| variables.rs:388:15:388:15 | z | variables.rs:379:13:379:13 | z | -| variables.rs:394:14:394:14 | x | variables.rs:392:13:392:13 | x | -| variables.rs:395:6:395:6 | y | variables.rs:393:9:393:9 | y | -| variables.rs:396:15:396:15 | x | variables.rs:392:13:392:13 | x | -| variables.rs:403:19:403:19 | x | variables.rs:400:9:400:9 | x | -| variables.rs:405:5:405:7 | cap | variables.rs:402:9:402:11 | cap | -| variables.rs:406:15:406:15 | x | variables.rs:400:9:400:9 | x | -| variables.rs:413:19:413:19 | x | variables.rs:410:13:410:13 | x | -| variables.rs:415:5:415:12 | closure1 | variables.rs:412:9:412:16 | closure1 | -| variables.rs:416:15:416:15 | x | variables.rs:410:13:410:13 | x | -| variables.rs:421:9:421:9 | y | variables.rs:418:13:418:13 | y | -| variables.rs:423:5:423:12 | closure2 | variables.rs:420:13:420:20 | closure2 | -| variables.rs:424:15:424:15 | y | variables.rs:418:13:418:13 | y | -| variables.rs:429:9:429:9 | z | variables.rs:426:13:426:13 | z | -| variables.rs:431:5:431:12 | closure3 | variables.rs:428:13:428:20 | closure3 | -| variables.rs:432:15:432:15 | z | variables.rs:426:13:426:13 | z | -| variables.rs:438:9:438:9 | i | variables.rs:436:13:436:13 | i | -| variables.rs:441:5:441:9 | block | variables.rs:437:9:437:13 | block | -| variables.rs:442:15:442:15 | i | variables.rs:436:13:436:13 | i | -| variables.rs:447:15:447:15 | x | variables.rs:446:13:446:13 | x | -| variables.rs:448:15:448:15 | x | variables.rs:446:13:446:13 | x | -| variables.rs:449:8:449:8 | b | variables.rs:445:8:445:8 | b | -| variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x | -| variables.rs:451:19:451:19 | x | variables.rs:446:13:446:13 | x | -| variables.rs:452:19:452:19 | x | variables.rs:446:13:446:13 | x | -| variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x | -| variables.rs:455:19:455:19 | x | variables.rs:446:13:446:13 | x | -| variables.rs:456:19:456:19 | x | variables.rs:446:13:446:13 | x | -| variables.rs:458:15:458:15 | x | variables.rs:446:13:446:13 | x | -| variables.rs:463:8:463:9 | b1 | variables.rs:461:13:461:14 | b1 | -| variables.rs:464:19:464:19 | x | variables.rs:462:9:462:9 | x | -| variables.rs:466:19:466:19 | x | variables.rs:462:9:462:9 | x | -| variables.rs:469:8:469:9 | b2 | variables.rs:461:24:461:25 | b2 | -| variables.rs:470:19:470:19 | x | variables.rs:462:9:462:9 | x | -| variables.rs:472:19:472:19 | x | variables.rs:462:9:462:9 | x | -| variables.rs:489:15:489:15 | a | variables.rs:488:13:488:13 | a | -| variables.rs:490:5:490:5 | a | variables.rs:488:13:488:13 | a | -| variables.rs:491:15:491:15 | a | variables.rs:488:13:488:13 | a | -| variables.rs:492:5:492:5 | a | variables.rs:488:13:488:13 | a | -| variables.rs:493:15:493:15 | a | variables.rs:488:13:488:13 | a | -| variables.rs:498:20:498:20 | x | variables.rs:497:9:497:9 | x | -| variables.rs:499:15:499:15 | x | variables.rs:497:9:497:9 | x | -| variables.rs:502:20:502:20 | z | variables.rs:501:9:501:9 | z | -| variables.rs:517:3:517:3 | a | variables.rs:516:11:516:11 | a | -| variables.rs:519:13:519:13 | a | variables.rs:516:11:516:11 | a | -variableWriteAccess -| variables.rs:23:5:23:6 | x2 | variables.rs:21:13:21:14 | x2 | -| variables.rs:30:5:30:5 | x | variables.rs:28:13:28:13 | x | -| variables.rs:288:9:288:10 | c2 | variables.rs:281:13:281:14 | c2 | -| variables.rs:289:9:289:10 | b4 | variables.rs:280:13:280:14 | b4 | -| variables.rs:290:9:290:11 | a10 | variables.rs:279:13:279:15 | a10 | -| variables.rs:421:9:421:9 | y | variables.rs:418:13:418:13 | y | -| variables.rs:438:9:438:9 | i | variables.rs:436:13:436:13 | i | -| variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x | -| variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x | -| variables.rs:492:5:492:5 | a | variables.rs:488:13:488:13 | a | -variableReadAccess -| variables.rs:4:20:4:20 | s | variables.rs:3:14:3:14 | s | -| variables.rs:8:20:8:20 | i | variables.rs:7:14:7:14 | i | -| variables.rs:12:16:12:16 | i | variables.rs:11:18:11:18 | i | -| variables.rs:17:15:17:16 | x1 | variables.rs:16:9:16:10 | x1 | -| variables.rs:22:15:22:16 | x2 | variables.rs:21:13:21:14 | x2 | -| variables.rs:24:15:24:16 | x2 | variables.rs:21:13:21:14 | x2 | -| variables.rs:36:15:36:16 | x3 | variables.rs:35:9:35:10 | x3 | -| variables.rs:38:9:38:10 | x3 | variables.rs:35:9:35:10 | x3 | -| variables.rs:39:15:39:16 | x3 | variables.rs:37:9:37:10 | x3 | -| variables.rs:44:15:44:16 | x4 | variables.rs:43:9:43:10 | x4 | -| variables.rs:47:19:47:20 | x4 | variables.rs:46:13:46:14 | x4 | -| variables.rs:49:15:49:16 | x4 | variables.rs:43:9:43:10 | x4 | -| variables.rs:68:15:68:16 | a1 | variables.rs:60:13:60:14 | a1 | -| variables.rs:69:15:69:16 | b1 | variables.rs:61:13:61:14 | b1 | -| variables.rs:70:15:70:15 | x | variables.rs:64:13:64:13 | x | -| variables.rs:71:15:71:15 | y | variables.rs:65:13:65:13 | y | -| variables.rs:79:9:79:10 | p1 | variables.rs:75:9:75:10 | p1 | -| variables.rs:80:15:80:16 | a2 | variables.rs:77:12:77:13 | a2 | -| variables.rs:81:15:81:16 | b2 | variables.rs:78:12:78:13 | b2 | -| variables.rs:88:11:88:12 | s1 | variables.rs:85:9:85:10 | s1 | -| variables.rs:89:19:89:20 | s2 | variables.rs:87:21:87:22 | s2 | -| variables.rs:98:15:98:16 | x5 | variables.rs:94:14:94:15 | x5 | -| variables.rs:105:11:105:12 | s1 | variables.rs:102:9:102:10 | s1 | -| variables.rs:106:19:106:20 | s2 | variables.rs:104:24:104:25 | s2 | -| variables.rs:114:11:114:12 | x6 | variables.rs:111:9:111:10 | x6 | -| variables.rs:119:23:119:24 | y1 | variables.rs:116:14:116:15 | y1 | -| variables.rs:124:15:124:16 | y1 | variables.rs:112:9:112:10 | y1 | -| variables.rs:130:11:130:17 | numbers | variables.rs:128:9:128:15 | numbers | -| variables.rs:136:23:136:27 | first | variables.rs:132:13:132:17 | first | -| variables.rs:137:23:137:27 | third | variables.rs:133:13:133:17 | third | -| variables.rs:138:23:138:27 | fifth | variables.rs:134:13:134:17 | fifth | -| variables.rs:142:11:142:17 | numbers | variables.rs:128:9:128:15 | numbers | -| variables.rs:148:23:148:27 | first | variables.rs:144:13:144:17 | first | -| variables.rs:149:23:149:26 | last | variables.rs:146:13:146:16 | last | -| variables.rs:157:11:157:12 | p2 | variables.rs:155:9:155:10 | p2 | -| variables.rs:160:24:160:25 | x7 | variables.rs:159:16:159:17 | x7 | -| variables.rs:171:11:171:13 | msg | variables.rs:169:9:169:11 | msg | -| variables.rs:174:24:174:34 | id_variable | variables.rs:173:17:173:27 | id_variable | -| variables.rs:179:23:179:24 | id | variables.rs:178:26:178:27 | id | -| variables.rs:190:11:190:16 | either | variables.rs:189:9:189:14 | either | -| variables.rs:192:26:192:27 | a3 | variables.rs:191:9:191:44 | a3 | -| variables.rs:204:11:204:12 | tv | variables.rs:203:9:203:10 | tv | -| variables.rs:206:26:206:27 | a4 | variables.rs:205:9:205:81 | a4 | -| variables.rs:208:11:208:12 | tv | variables.rs:203:9:203:10 | tv | -| variables.rs:210:26:210:27 | a5 | variables.rs:209:9:209:83 | a5 | -| variables.rs:212:11:212:12 | tv | variables.rs:203:9:203:10 | tv | -| variables.rs:214:26:214:27 | a6 | variables.rs:213:9:213:83 | a6 | -| variables.rs:220:11:220:16 | either | variables.rs:219:9:219:14 | either | -| variables.rs:222:16:222:17 | a7 | variables.rs:221:9:221:44 | a7 | -| variables.rs:223:26:223:27 | a7 | variables.rs:221:9:221:44 | a7 | -| variables.rs:231:11:231:16 | either | variables.rs:229:9:229:14 | either | -| variables.rs:235:23:235:25 | a11 | variables.rs:233:14:233:51 | a11 | -| variables.rs:237:15:237:15 | e | variables.rs:232:13:232:13 | e | -| variables.rs:238:28:238:30 | a12 | variables.rs:236:33:236:35 | a12 | -| variables.rs:254:11:254:12 | fv | variables.rs:253:9:253:10 | fv | -| variables.rs:256:26:256:28 | a13 | variables.rs:255:9:255:109 | a13 | -| variables.rs:266:15:266:16 | a8 | variables.rs:261:5:261:6 | a8 | -| variables.rs:267:15:267:16 | b3 | variables.rs:263:9:263:10 | b3 | -| variables.rs:268:15:268:16 | c1 | variables.rs:264:9:264:10 | c1 | -| variables.rs:274:15:274:16 | a9 | variables.rs:272:6:272:41 | a9 | -| variables.rs:283:15:283:17 | a10 | variables.rs:279:13:279:15 | a10 | -| variables.rs:284:15:284:16 | b4 | variables.rs:280:13:280:14 | b4 | -| variables.rs:285:15:285:16 | c2 | variables.rs:281:13:281:14 | c2 | -| variables.rs:292:9:292:11 | a10 | variables.rs:279:13:279:15 | a10 | -| variables.rs:293:9:293:10 | b4 | variables.rs:280:13:280:14 | b4 | -| variables.rs:294:9:294:10 | c2 | variables.rs:281:13:281:14 | c2 | -| variables.rs:296:15:296:17 | a10 | variables.rs:279:13:279:15 | a10 | -| variables.rs:297:15:297:16 | b4 | variables.rs:280:13:280:14 | b4 | -| variables.rs:298:15:298:16 | c2 | variables.rs:281:13:281:14 | c2 | -| variables.rs:305:23:305:25 | a10 | variables.rs:302:13:302:15 | a10 | -| variables.rs:306:23:306:24 | b4 | variables.rs:303:13:303:14 | b4 | -| variables.rs:310:15:310:17 | a10 | variables.rs:279:13:279:15 | a10 | -| variables.rs:311:15:311:16 | b4 | variables.rs:280:13:280:14 | b4 | -| variables.rs:317:9:317:9 | x | variables.rs:316:10:316:10 | x | -| variables.rs:319:9:319:23 | example_closure | variables.rs:315:9:315:23 | example_closure | -| variables.rs:320:15:320:16 | n1 | variables.rs:318:9:318:10 | n1 | -| variables.rs:325:9:325:9 | x | variables.rs:324:10:324:10 | x | -| variables.rs:327:9:327:26 | immutable_variable | variables.rs:323:9:323:26 | immutable_variable | -| variables.rs:328:15:328:16 | n2 | variables.rs:326:9:326:10 | n2 | -| variables.rs:335:12:335:12 | v | variables.rs:332:9:332:9 | v | -| variables.rs:336:19:336:22 | text | variables.rs:334:9:334:12 | text | -| variables.rs:343:15:343:15 | a | variables.rs:341:13:341:13 | a | -| variables.rs:345:15:345:15 | a | variables.rs:341:13:341:13 | a | -| variables.rs:352:6:352:10 | ref_i | variables.rs:350:9:350:13 | ref_i | -| variables.rs:353:15:353:15 | i | variables.rs:349:13:349:13 | i | -| variables.rs:357:6:357:6 | x | variables.rs:356:17:356:17 | x | -| variables.rs:358:10:358:10 | x | variables.rs:356:17:356:17 | x | -| variables.rs:359:10:359:10 | x | variables.rs:356:17:356:17 | x | -| variables.rs:360:12:360:12 | x | variables.rs:356:17:356:17 | x | -| variables.rs:364:6:364:6 | x | variables.rs:363:22:363:22 | x | -| variables.rs:365:10:365:10 | x | variables.rs:363:22:363:22 | x | -| variables.rs:366:10:366:10 | x | variables.rs:363:22:363:22 | x | -| variables.rs:367:6:367:6 | y | variables.rs:363:39:363:39 | y | -| variables.rs:368:9:368:9 | x | variables.rs:363:22:363:22 | x | -| variables.rs:375:6:375:6 | y | variables.rs:373:9:373:9 | y | -| variables.rs:377:15:377:15 | x | variables.rs:372:13:372:13 | x | -| variables.rs:384:9:384:9 | w | variables.rs:380:9:380:9 | w | -| variables.rs:386:7:386:7 | w | variables.rs:380:9:380:9 | w | -| variables.rs:388:15:388:15 | z | variables.rs:379:13:379:13 | z | -| variables.rs:395:6:395:6 | y | variables.rs:393:9:393:9 | y | -| variables.rs:396:15:396:15 | x | variables.rs:392:13:392:13 | x | -| variables.rs:403:19:403:19 | x | variables.rs:400:9:400:9 | x | -| variables.rs:405:5:405:7 | cap | variables.rs:402:9:402:11 | cap | -| variables.rs:406:15:406:15 | x | variables.rs:400:9:400:9 | x | -| variables.rs:413:19:413:19 | x | variables.rs:410:13:410:13 | x | -| variables.rs:415:5:415:12 | closure1 | variables.rs:412:9:412:16 | closure1 | -| variables.rs:416:15:416:15 | x | variables.rs:410:13:410:13 | x | -| variables.rs:423:5:423:12 | closure2 | variables.rs:420:13:420:20 | closure2 | -| variables.rs:424:15:424:15 | y | variables.rs:418:13:418:13 | y | -| variables.rs:429:9:429:9 | z | variables.rs:426:13:426:13 | z | -| variables.rs:431:5:431:12 | closure3 | variables.rs:428:13:428:20 | closure3 | -| variables.rs:432:15:432:15 | z | variables.rs:426:13:426:13 | z | -| variables.rs:441:5:441:9 | block | variables.rs:437:9:437:13 | block | -| variables.rs:442:15:442:15 | i | variables.rs:436:13:436:13 | i | -| variables.rs:447:15:447:15 | x | variables.rs:446:13:446:13 | x | -| variables.rs:448:15:448:15 | x | variables.rs:446:13:446:13 | x | -| variables.rs:449:8:449:8 | b | variables.rs:445:8:445:8 | b | -| variables.rs:451:19:451:19 | x | variables.rs:446:13:446:13 | x | -| variables.rs:452:19:452:19 | x | variables.rs:446:13:446:13 | x | -| variables.rs:455:19:455:19 | x | variables.rs:446:13:446:13 | x | -| variables.rs:456:19:456:19 | x | variables.rs:446:13:446:13 | x | -| variables.rs:458:15:458:15 | x | variables.rs:446:13:446:13 | x | -| variables.rs:463:8:463:9 | b1 | variables.rs:461:13:461:14 | b1 | -| variables.rs:464:19:464:19 | x | variables.rs:462:9:462:9 | x | -| variables.rs:466:19:466:19 | x | variables.rs:462:9:462:9 | x | -| variables.rs:469:8:469:9 | b2 | variables.rs:461:24:461:25 | b2 | -| variables.rs:470:19:470:19 | x | variables.rs:462:9:462:9 | x | -| variables.rs:472:19:472:19 | x | variables.rs:462:9:462:9 | x | -| variables.rs:489:15:489:15 | a | variables.rs:488:13:488:13 | a | -| variables.rs:490:5:490:5 | a | variables.rs:488:13:488:13 | a | -| variables.rs:491:15:491:15 | a | variables.rs:488:13:488:13 | a | -| variables.rs:493:15:493:15 | a | variables.rs:488:13:488:13 | a | -| variables.rs:499:15:499:15 | x | variables.rs:497:9:497:9 | x | -| variables.rs:517:3:517:3 | a | variables.rs:516:11:516:11 | a | -| variables.rs:519:13:519:13 | a | variables.rs:516:11:516:11 | a | -variableInitializer -| variables.rs:16:9:16:10 | x1 | variables.rs:16:14:16:16 | "a" | -| variables.rs:21:13:21:14 | x2 | variables.rs:21:18:21:18 | 4 | -| variables.rs:28:13:28:13 | x | variables.rs:28:17:28:17 | 1 | -| variables.rs:35:9:35:10 | x3 | variables.rs:35:14:35:14 | 1 | -| variables.rs:37:9:37:10 | x3 | variables.rs:38:9:38:14 | ... + ... | -| variables.rs:43:9:43:10 | x4 | variables.rs:43:14:43:16 | "a" | -| variables.rs:46:13:46:14 | x4 | variables.rs:46:18:46:20 | "b" | -| variables.rs:75:9:75:10 | p1 | variables.rs:75:14:75:37 | RecordExpr | -| variables.rs:85:9:85:10 | s1 | variables.rs:85:14:85:41 | CallExpr | -| variables.rs:102:9:102:10 | s1 | variables.rs:102:14:102:41 | CallExpr | -| variables.rs:111:9:111:10 | x6 | variables.rs:111:14:111:20 | CallExpr | -| variables.rs:112:9:112:10 | y1 | variables.rs:112:14:112:15 | 10 | -| variables.rs:128:9:128:15 | numbers | variables.rs:128:19:128:35 | TupleExpr | -| variables.rs:155:9:155:10 | p2 | variables.rs:155:14:155:37 | RecordExpr | -| variables.rs:169:9:169:11 | msg | variables.rs:169:15:169:38 | RecordExpr | -| variables.rs:189:9:189:14 | either | variables.rs:189:18:189:33 | CallExpr | -| variables.rs:203:9:203:10 | tv | variables.rs:203:14:203:36 | CallExpr | -| variables.rs:219:9:219:14 | either | variables.rs:219:18:219:33 | CallExpr | -| variables.rs:229:9:229:14 | either | variables.rs:229:18:229:33 | CallExpr | -| variables.rs:253:9:253:10 | fv | variables.rs:253:14:253:35 | CallExpr | -| variables.rs:315:9:315:23 | example_closure | variables.rs:316:9:317:9 | ClosureExpr | -| variables.rs:318:9:318:10 | n1 | variables.rs:319:9:319:26 | CallExpr | -| variables.rs:323:9:323:26 | immutable_variable | variables.rs:324:9:325:9 | ClosureExpr | -| variables.rs:326:9:326:10 | n2 | variables.rs:327:9:327:29 | CallExpr | -| variables.rs:332:9:332:9 | v | variables.rs:332:13:332:41 | RefExpr | -| variables.rs:341:13:341:13 | a | variables.rs:341:17:341:17 | 0 | -| variables.rs:349:13:349:13 | i | variables.rs:349:17:349:17 | 1 | -| variables.rs:350:9:350:13 | ref_i | variables.rs:351:9:351:14 | RefExpr | -| variables.rs:372:13:372:13 | x | variables.rs:372:17:372:17 | 2 | -| variables.rs:373:9:373:9 | y | variables.rs:374:9:374:28 | CallExpr | -| variables.rs:379:13:379:13 | z | variables.rs:379:17:379:17 | 4 | -| variables.rs:380:9:380:9 | w | variables.rs:381:9:381:19 | RefExpr | -| variables.rs:392:13:392:13 | x | variables.rs:392:17:392:17 | 1 | -| variables.rs:393:9:393:9 | y | variables.rs:394:9:394:14 | RefExpr | -| variables.rs:400:9:400:9 | x | variables.rs:400:13:400:15 | 100 | -| variables.rs:402:9:402:11 | cap | variables.rs:402:15:404:5 | ClosureExpr | -| variables.rs:410:13:410:13 | x | variables.rs:410:17:410:17 | 1 | -| variables.rs:412:9:412:16 | closure1 | variables.rs:412:20:414:5 | ClosureExpr | -| variables.rs:418:13:418:13 | y | variables.rs:418:17:418:17 | 2 | -| variables.rs:420:13:420:20 | closure2 | variables.rs:420:24:422:5 | ClosureExpr | -| variables.rs:426:13:426:13 | z | variables.rs:426:17:426:17 | 2 | -| variables.rs:428:13:428:20 | closure3 | variables.rs:428:24:430:5 | ClosureExpr | -| variables.rs:436:13:436:13 | i | variables.rs:436:22:436:22 | 0 | -| variables.rs:437:9:437:13 | block | variables.rs:437:17:439:5 | BlockExpr | -| variables.rs:446:13:446:13 | x | variables.rs:446:17:446:17 | 1 | -| variables.rs:462:9:462:9 | x | variables.rs:462:13:462:13 | 1 | -| variables.rs:488:13:488:13 | a | variables.rs:488:17:488:35 | RecordExpr | -| variables.rs:497:9:497:9 | x | variables.rs:497:13:497:14 | 16 | -| variables.rs:501:9:501:9 | z | variables.rs:501:13:501:14 | 17 | -| variables.rs:516:11:516:11 | a | variables.rs:516:15:516:33 | RecordExpr | -capturedVariable -| variables.rs:400:9:400:9 | x | -| variables.rs:410:13:410:13 | x | -| variables.rs:418:13:418:13 | y | -| variables.rs:426:13:426:13 | z | -| variables.rs:436:13:436:13 | i | -capturedAccess -| variables.rs:403:19:403:19 | x | -| variables.rs:413:19:413:19 | x | -| variables.rs:421:9:421:9 | y | -| variables.rs:429:9:429:9 | z | -| variables.rs:438:9:438:9 | i | +ERROR: empty recursive call: dispatch predicate for CommentImpl::Impl::Comment::getCommentMarker (CommentImpl.qll:23,47-63) +ERROR: empty recursive call: dispatch predicate for CommentImpl::Impl::Comment::getText (CommentImpl.qll:36,34-41) From 55121d866cd96939c126d9c2988af6e21a3e9346 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 20 Nov 2024 11:45:42 +0100 Subject: [PATCH 112/470] Rust: Add CFG tests for method definitions with self parameters --- .../library-tests/controlflow/Cfg.expected | 30 +++++++++++++++++++ .../ql/test/library-tests/controlflow/test.rs | 18 +++++++++++ 2 files changed, 48 insertions(+) diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 620837abc82..6b2642e6512 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -1044,6 +1044,36 @@ edges | test.rs:490:5:490:19 | ExprStmt | test.rs:490:5:490:10 | nested | | | test.rs:490:12:490:17 | RefExpr | test.rs:490:5:490:18 | CallExpr | | | test.rs:490:17:490:17 | x | test.rs:490:12:490:17 | RefExpr | | +| test.rs:502:5:504:5 | enter new | test.rs:502:12:502:12 | a | | +| test.rs:502:5:504:5 | exit new (normal) | test.rs:502:5:504:5 | exit new | | +| test.rs:502:12:502:12 | a | test.rs:502:12:502:17 | Param | match | +| test.rs:502:12:502:17 | Param | test.rs:503:23:503:23 | a | | +| test.rs:502:28:504:5 | BlockExpr | test.rs:502:5:504:5 | exit new (normal) | | +| test.rs:503:9:503:25 | RecordExpr | test.rs:502:28:504:5 | BlockExpr | | +| test.rs:503:23:503:23 | a | test.rs:503:9:503:25 | RecordExpr | | +| test.rs:506:5:508:5 | enter negated | test.rs:507:23:507:26 | self | | +| test.rs:506:5:508:5 | exit negated (normal) | test.rs:506:5:508:5 | exit negated | | +| test.rs:506:30:508:5 | BlockExpr | test.rs:506:5:508:5 | exit negated (normal) | | +| test.rs:507:9:507:30 | RecordExpr | test.rs:506:30:508:5 | BlockExpr | | +| test.rs:507:23:507:26 | self | test.rs:507:23:507:28 | FieldExpr | | +| test.rs:507:23:507:28 | FieldExpr | test.rs:507:9:507:30 | RecordExpr | | +| test.rs:510:5:512:5 | enter multifly_add | test.rs:510:32:510:32 | a | | +| test.rs:510:5:512:5 | exit multifly_add (normal) | test.rs:510:5:512:5 | exit multifly_add | | +| test.rs:510:32:510:32 | a | test.rs:510:32:510:37 | Param | match | +| test.rs:510:32:510:37 | Param | test.rs:510:40:510:40 | b | | +| test.rs:510:40:510:40 | b | test.rs:510:40:510:45 | Param | match | +| test.rs:510:40:510:45 | Param | test.rs:511:9:511:34 | ExprStmt | | +| test.rs:510:48:512:5 | BlockExpr | test.rs:510:5:512:5 | exit multifly_add (normal) | | +| test.rs:511:9:511:12 | self | test.rs:511:9:511:14 | FieldExpr | | +| test.rs:511:9:511:14 | FieldExpr | test.rs:511:19:511:22 | self | | +| test.rs:511:9:511:33 | ... = ... | test.rs:510:48:512:5 | BlockExpr | | +| test.rs:511:9:511:34 | ExprStmt | test.rs:511:9:511:12 | self | | +| test.rs:511:18:511:33 | ... + ... | test.rs:511:9:511:33 | ... = ... | | +| test.rs:511:19:511:22 | self | test.rs:511:19:511:24 | FieldExpr | | +| test.rs:511:19:511:24 | FieldExpr | test.rs:511:28:511:28 | a | | +| test.rs:511:19:511:28 | ... * ... | test.rs:511:33:511:33 | b | | +| test.rs:511:28:511:28 | a | test.rs:511:19:511:28 | ... * ... | | +| test.rs:511:33:511:33 | b | test.rs:511:18:511:33 | ... + ... | | breakTarget | test.rs:34:17:34:21 | BreakExpr | test.rs:28:9:40:9 | LoopExpr | | test.rs:48:21:48:25 | BreakExpr | test.rs:46:13:53:13 | LoopExpr | diff --git a/rust/ql/test/library-tests/controlflow/test.rs b/rust/ql/test/library-tests/controlflow/test.rs index e1d59618806..42094c5432e 100644 --- a/rust/ql/test/library-tests/controlflow/test.rs +++ b/rust/ql/test/library-tests/controlflow/test.rs @@ -493,3 +493,21 @@ fn test_nested_function2() { trait MyFrom { fn my_from(x: T) -> Self; } + +struct MyNumber { + n: i64, +} + +impl MyNumber { + fn new(a: i64) -> Self { + MyNumber { n: a } + } + + fn negated(self) -> Self { + MyNumber { n: self.n } + } + + fn multifly_add(&mut self, a: i64, b: i64) { + self.n = (self.n * a) + b; + } +} From 24adbb80c7adaa0ee084cd4dac18acd5dc3c4c0c Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 20 Nov 2024 11:50:46 +0100 Subject: [PATCH 113/470] Rust: Include self parameters in the CFG --- .../controlflow/internal/ControlFlowGraphImpl.qll | 15 +++++++++++++-- .../test/library-tests/controlflow/Cfg.expected | 8 ++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index b331ddd2d54..ef4f7808fa2 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -72,10 +72,17 @@ import CfgImpl class CallableScopeTree extends StandardTree, PreOrderTree, PostOrderTree, Scope::CallableScope { override predicate propagatesAbnormal(AstNode child) { none() } + private int getNumberOfSelfParams() { + if this.getParamList().hasSelfParam() then result = 1 else result = 0 + } + override AstNode getChildNode(int i) { - result = this.getParamList().getParam(i) + i = 0 and + result = this.getParamList().getSelfParam() or - i = this.getParamList().getNumberOfParams() and + result = this.getParamList().getParam(i - this.getNumberOfSelfParams()) + or + i = this.getParamList().getNumberOfParams() + this.getNumberOfSelfParams() and result = this.getBody() } } @@ -191,6 +198,10 @@ class NameTree extends LeafTree, Name { } class NameRefTree extends LeafTree, NameRef { } +class SelfParamTree extends StandardPostOrderTree, SelfParam { + override AstNode getChildNode(int i) { i = 0 and result = this.getName() } +} + class TypeRefTree extends LeafTree instanceof TypeRef { } /** diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 6b2642e6512..8fd71a451b8 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -1051,14 +1051,18 @@ edges | test.rs:502:28:504:5 | BlockExpr | test.rs:502:5:504:5 | exit new (normal) | | | test.rs:503:9:503:25 | RecordExpr | test.rs:502:28:504:5 | BlockExpr | | | test.rs:503:23:503:23 | a | test.rs:503:9:503:25 | RecordExpr | | -| test.rs:506:5:508:5 | enter negated | test.rs:507:23:507:26 | self | | +| test.rs:506:5:508:5 | enter negated | test.rs:506:16:506:19 | self | | | test.rs:506:5:508:5 | exit negated (normal) | test.rs:506:5:508:5 | exit negated | | +| test.rs:506:16:506:19 | SelfParam | test.rs:507:23:507:26 | self | | +| test.rs:506:16:506:19 | self | test.rs:506:16:506:19 | SelfParam | | | test.rs:506:30:508:5 | BlockExpr | test.rs:506:5:508:5 | exit negated (normal) | | | test.rs:507:9:507:30 | RecordExpr | test.rs:506:30:508:5 | BlockExpr | | | test.rs:507:23:507:26 | self | test.rs:507:23:507:28 | FieldExpr | | | test.rs:507:23:507:28 | FieldExpr | test.rs:507:9:507:30 | RecordExpr | | -| test.rs:510:5:512:5 | enter multifly_add | test.rs:510:32:510:32 | a | | +| test.rs:510:5:512:5 | enter multifly_add | test.rs:510:26:510:29 | self | | | test.rs:510:5:512:5 | exit multifly_add (normal) | test.rs:510:5:512:5 | exit multifly_add | | +| test.rs:510:21:510:29 | SelfParam | test.rs:510:32:510:32 | a | | +| test.rs:510:26:510:29 | self | test.rs:510:21:510:29 | SelfParam | | | test.rs:510:32:510:32 | a | test.rs:510:32:510:37 | Param | match | | test.rs:510:32:510:37 | Param | test.rs:510:40:510:40 | b | | | test.rs:510:40:510:40 | b | test.rs:510:40:510:45 | Param | match | From 9b4b01a442dc37f83e5d0ac450f6653e6d1bc8c9 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 20 Nov 2024 10:59:27 +0000 Subject: [PATCH 114/470] Fix typo --- .../test/library-tests/dataflow/global-or-captured-vars/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py index 3874d67e4a4..f60458ca4f9 100644 --- a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py +++ b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py @@ -64,7 +64,7 @@ def test6(): def bar6(): time.sleep(1) - ensure_tainted(foo[0]) # $tainted + ensure_tainted(foo6[0]) # $tainted foo6.append(TAINTED_STRING) bar6() From 4d04c5af830bb275d62503b273776491d613752b Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 20 Nov 2024 12:08:51 +0100 Subject: [PATCH 115/470] Rust: fix non-existent string representations --- rust/ql/.generated.list | 2 - rust/ql/.gitattributes | 2 - .../rust/elements/internal/BreakExprImpl.qll | 4 +- .../rust/elements/internal/CommentImpl.qll | 30 +- .../rust/elements/internal/ForExprImpl.qll | 6 +- .../rust/elements/internal/LifetimeImpl.qll | 6 +- .../rust/elements/internal/ParamImpl.qll | 9 +- .../rust/elements/internal/UnionImpl.qll | 6 +- .../generated/BreakExpr/BreakExpr.expected | 6 +- .../BreakExpr/BreakExpr_getExpr.expected | 4 +- .../BreakExpr/BreakExpr_getLifetime.expected | 4 +- .../library-tests/controlflow/Cfg.expected | 1444 ++++++++--------- .../dataflow/barrier/inline-flow.expected | 16 +- .../dataflow/local/DataFlowStep.expected | 8 +- .../dataflow/local/inline-flow.expected | 26 +- .../DataFlowConsistencyCounts.expected | 2 +- .../diagnostics/ExtractionWarnings.expected | 1 - .../diagnostics/SummaryStats.expected | 6 +- .../diagnostics/does_not_compile.rs | 2 +- 19 files changed, 813 insertions(+), 771 deletions(-) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index a26f1d4155e..1c56649d476 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -221,7 +221,6 @@ lib/codeql/rust/elements/internal/FieldListImpl.qll 02a09d1d146030c68cead4614f4e lib/codeql/rust/elements/internal/FnPtrTypeConstructor.qll 494c53ee599039c02145f91394d8dfe7635b32d03f9fcde5efcc99ced437fec8 992462b1b6b9e64b6201f3c6c232ca524f126efcb562c9f0c176677bb559f33c lib/codeql/rust/elements/internal/FnPtrTypeImpl.qll 5d70f71e08341dfa851fc53a47cf362786b57f44244a636e2fbbad3d1c41371e 51d6a1b1132204129bb8ee9d2b72c6d13ce4b3ec8b185d3732d2e64d3f80e807 lib/codeql/rust/elements/internal/ForExprConstructor.qll d79b88dac19256300b758ba0f37ce3f07e9f848d6ae0c1fdb87bd348e760aa3e 62123b11858293429aa609ea77d2f45cb8c8eebae80a1d81da6f3ad7d1dbc19b -lib/codeql/rust/elements/internal/ForExprImpl.qll 88fc37b7030d3bfca6071f275c4eac6760ad7dea9a01135cee2079170efeb9d5 cd7216c460f8382498dfb0d61d65d83a9aa608b6a9b6657ccd552b82b55ffc5a lib/codeql/rust/elements/internal/ForTypeConstructor.qll 32c40b78aded314b5f51af904bfbd5ae4f1f0ea65854dd6249983cc26b8601bc 729069d58fac648a4b212b0068fb6bca348443b502c38978f171a7539b24333f lib/codeql/rust/elements/internal/ForTypeImpl.qll b515639844778d0fbe51e6161a2ec19201b0ba15156a91cdfecc93523081fd61 ab0c09ee415e55db6abcc07493a5d880c5ae0974f0cb760194e40b68a961676b lib/codeql/rust/elements/internal/FormatArgsArgConstructor.qll 8bd9b4e035ef8adeb3ac510dd68043934c0140facb933be1f240096d01cdfa11 74e9d3bbd8882ae59a7e88935d468e0a90a6529a4e2af6a3d83e93944470f0ee @@ -386,7 +385,6 @@ lib/codeql/rust/elements/internal/UnextractedImpl.qll 5c23df7e448184d76ccab2c227 lib/codeql/rust/elements/internal/UnimplementedConstructor.qll 70b0489fdc75fed389de8203947ed9c8eabb91373a1264eb2c8018ddbb2d9baa 0f2592c1697a2f2f913014ecd73b0e3ff1ec5b038ba1c3a22e7939bf8759e664 lib/codeql/rust/elements/internal/UnimplementedImpl.qll 06771abc088e0a8fc24032c9d2633618e8e40343ef8757a68cc0a70f1617165a 5738f626f1f4f573fdf7dcd5bd57a0948d290ed89342b9160e95ef3c84044f9a lib/codeql/rust/elements/internal/UnionConstructor.qll d650551a1b3ef29c5a770bdad626269cf539ed0c675af954bc847d2c6111f3f6 aca9064ad653a126ab4f03703e96b274587c852dc5e7ff3fea0fec4d45993f10 -lib/codeql/rust/elements/internal/UnionImpl.qll f1765a7a37fb29eff98d67d166c35df4921eafc8cb61c11c7848185535f0497b 9f041f6ee82bd3cda2ddea0ee58d7a996123b1713b9d127f764eb74a9387f685 lib/codeql/rust/elements/internal/UseConstructor.qll a4f790795e18abc29a50d6fbaa0db64cba781e3259a42cbf0468c24ac66b63e7 2fa288f073ac094a838c11f091def2c790b347b6a1b79407c11b10c73d6bff57 lib/codeql/rust/elements/internal/UseImpl.qll ba779517c3c928ab6e794360b6344829e84ec6da5e1de1b03b4eaf8bdae58ce9 0f4ead9eecb584eb9827502276ffe8cb1da0d2fa4b8f660d2afc26ac4e0fba86 lib/codeql/rust/elements/internal/UseTreeConstructor.qll 3e6e834100fcc7249f8a20f8bd9debe09b705fcf5a0e655537e71ac1c6f7956b cdbc84b8f1b009be1e4a7aaba7f5237823cea62c86b38f1794aad97e3dfcf64b diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 8e644be8e46..7411c9cba35 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -223,7 +223,6 @@ /lib/codeql/rust/elements/internal/FnPtrTypeConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/FnPtrTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ForExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/ForExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ForTypeConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ForTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/FormatArgsArgConstructor.qll linguist-generated @@ -388,7 +387,6 @@ /lib/codeql/rust/elements/internal/UnimplementedConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/UnimplementedImpl.qll linguist-generated /lib/codeql/rust/elements/internal/UnionConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/UnionImpl.qll linguist-generated /lib/codeql/rust/elements/internal/UseConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/UseImpl.qll linguist-generated /lib/codeql/rust/elements/internal/UseTreeConstructor.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll index 49bca4b25a2..6cfba697828 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll @@ -106,9 +106,9 @@ module Impl { override string toString() { exists(string label, string expr | ( - result = " " + this.getLifetime().toString() + label = " " + this.getLifetime().toString() or - not this.hasLifetime() and result = "" + not this.hasLifetime() and label = "" ) and (if this.hasExpr() then expr = " ..." else expr = "") and result = "break" + label + expr diff --git a/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.qll index 2e7beca481d..85b2a4d80d3 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.qll @@ -20,20 +20,30 @@ module Impl { * ``` */ class Comment extends Generated::Comment { - override string getText() { result = this.getCommentMarker() + " ..." } - - /** - * Gets the text of this comment, excluding the comment marker. - */ - string getCommentText() { - exists(string s | s = this.getText() | result = s.regexpCapture("///?\\s*(.*)", 1)) + override string toString() { + result = this.getCommentMarker() + "..." + this.getCommentEndMarker() } /** - * Gets the marker of this comment, that is `//` or `///`. + * Gets the text of this comment, excluding the comment markers. */ - string getCommentMarker() { - exists(string s | s = this.getText() | result = s.regexpCapture("(///?).*", 1)) + string getCommentText() { + exists(string s | s = this.getText() | + result = + [ + s.regexpCapture("///?\\s*(.*)", 1), + s.regexpCapture("(?s)/\\*\\*?\\s*(.*?)\\s*\\*/", 1) + ] + ) + } + + /** + * Gets the marker of this comment, that is `"//"`, `"///"`, `"/*"` or `"/**"`. + */ + string getCommentMarker() { result = this.getText().regexpCapture("(?s)(///?|/\\*\\*?).*", 1) } + + private string getCommentEndMarker() { + if this.getCommentMarker() = ["//", "///"] then result = "" else result = "*/" } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ForExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ForExprImpl.qll index a196a6802e9..da62b58732b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ForExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ForExprImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `ForExpr`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.ForExpr * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A ForExpr. For example: * ```rust * todo!() * ``` */ - class ForExpr extends Generated::ForExpr { } + class ForExpr extends Generated::ForExpr { + override string toString() { result = "for " + this.getPat().toString() + " in ... { ... }" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LifetimeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LifetimeImpl.qll index a51bf3c6b12..27b29f64cc9 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LifetimeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LifetimeImpl.qll @@ -19,6 +19,10 @@ module Impl { * ``` */ class Lifetime extends Generated::Lifetime { - override string toString() { result = "'" + this.getText() } + override string toString() { + result = "'" + this.getText() + or + not this.hasText() and result = "'_" + } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll index 5a961383094..5f135cc94ca 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll @@ -20,7 +20,14 @@ module Impl { */ class Param extends Generated::Param { override string toString() { - result = this.getPat().toString() + ": " + this.getTy().toString() + exists(string ty | + ( + ty = ": " + this.getTy().toString() + or + not this.hasTy() and ty = "" + ) and + result = this.getPat().toString() + ty + ) } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll index dc850eac4d1..4357dcf68a9 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `Union`. * @@ -12,11 +11,14 @@ private import codeql.rust.elements.internal.generated.Union * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A Union. For example: * ```rust * todo!() * ``` */ - class Union extends Generated::Union { } + class Union extends Generated::Union { + override string toString() { result = "union " + this.getName().toString() } + } } diff --git a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected index f4c8df0a100..2ffdacb6890 100644 --- a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected +++ b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected @@ -1,3 +1,3 @@ -| gen_break_expr.rs:7:13:7:17 | (no string representation) | getNumberOfAttrs: | 0 | hasExpr: | no | hasLifetime: | no | -| gen_break_expr.rs:12:13:12:27 | (no string representation) | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | -| gen_break_expr.rs:17:13:17:27 | (no string representation) | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | +| gen_break_expr.rs:7:13:7:17 | break | getNumberOfAttrs: | 0 | hasExpr: | no | hasLifetime: | no | +| gen_break_expr.rs:12:13:12:27 | break ''label ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | +| gen_break_expr.rs:17:13:17:27 | break ''label ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | diff --git a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected index f99723114fb..864069115df 100644 --- a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected @@ -1,2 +1,2 @@ -| gen_break_expr.rs:12:13:12:27 | (no string representation) | gen_break_expr.rs:12:26:12:27 | 42 | -| gen_break_expr.rs:17:13:17:27 | (no string representation) | gen_break_expr.rs:17:26:17:27 | 42 | +| gen_break_expr.rs:12:13:12:27 | break ''label ... | gen_break_expr.rs:12:26:12:27 | 42 | +| gen_break_expr.rs:17:13:17:27 | break ''label ... | gen_break_expr.rs:17:26:17:27 | 42 | diff --git a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected index a1a828c744a..adbf9b15ff2 100644 --- a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected +++ b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected @@ -1,2 +1,2 @@ -| gen_break_expr.rs:12:13:12:27 | (no string representation) | gen_break_expr.rs:12:19:12:24 | ''label | -| gen_break_expr.rs:17:13:17:27 | (no string representation) | gen_break_expr.rs:17:19:17:24 | ''label | +| gen_break_expr.rs:12:13:12:27 | break ''label ... | gen_break_expr.rs:12:19:12:24 | ''label | +| gen_break_expr.rs:17:13:17:27 | break ''label ... | gen_break_expr.rs:17:19:17:24 | ''label | diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 620837abc82..6260c2328a6 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -1,479 +1,479 @@ edges -| test.rs:5:5:8:5 | enter function_call | test.rs:6:9:6:64 | ExprStmt | | -| test.rs:5:5:8:5 | exit function_call (normal) | test.rs:5:5:8:5 | exit function_call | | -| test.rs:5:24:8:5 | BlockExpr | test.rs:5:5:8:5 | exit function_call (normal) | | +| test.rs:5:5:8:5 | enter fn function_call | test.rs:6:9:6:64 | ExprStmt | | +| test.rs:5:5:8:5 | exit fn function_call (normal) | test.rs:5:5:8:5 | exit fn function_call | | +| test.rs:5:24:8:5 | { ... } | test.rs:5:5:8:5 | exit fn function_call (normal) | | | test.rs:6:9:6:44 | logical_operators::test_and_operator | test.rs:6:46:6:49 | true | | -| test.rs:6:9:6:63 | CallExpr | test.rs:7:9:7:22 | ExprStmt | | +| test.rs:6:9:6:63 | logical_operators::test_and_operator(...) | test.rs:7:9:7:22 | ExprStmt | | | test.rs:6:9:6:64 | ExprStmt | test.rs:6:9:6:44 | logical_operators::test_and_operator | | | test.rs:6:46:6:49 | true | test.rs:6:52:6:56 | false | | | test.rs:6:52:6:56 | false | test.rs:6:59:6:62 | true | | -| test.rs:6:59:6:62 | true | test.rs:6:9:6:63 | CallExpr | | -| test.rs:7:9:7:19 | method_call | test.rs:7:9:7:21 | CallExpr | | -| test.rs:7:9:7:21 | CallExpr | test.rs:5:24:8:5 | BlockExpr | | +| test.rs:6:59:6:62 | true | test.rs:6:9:6:63 | logical_operators::test_and_operator(...) | | +| test.rs:7:9:7:19 | method_call | test.rs:7:9:7:21 | method_call(...) | | +| test.rs:7:9:7:21 | method_call(...) | test.rs:5:24:8:5 | { ... } | | | test.rs:7:9:7:22 | ExprStmt | test.rs:7:9:7:19 | method_call | | -| test.rs:10:5:13:5 | enter method_call | test.rs:11:9:11:37 | LetStmt | | -| test.rs:10:5:13:5 | exit method_call (normal) | test.rs:10:5:13:5 | exit method_call | | -| test.rs:10:22:13:5 | BlockExpr | test.rs:10:5:13:5 | exit method_call (normal) | | -| test.rs:11:9:11:37 | LetStmt | test.rs:11:23:11:34 | HashMap::new | | +| test.rs:10:5:13:5 | enter fn method_call | test.rs:11:9:11:37 | let map = ... | | +| test.rs:10:5:13:5 | exit fn method_call (normal) | test.rs:10:5:13:5 | exit fn method_call | | +| test.rs:10:22:13:5 | { ... } | test.rs:10:5:13:5 | exit fn method_call (normal) | | +| test.rs:11:9:11:37 | let map = ... | test.rs:11:23:11:34 | HashMap::new | | | test.rs:11:13:11:19 | map | test.rs:12:9:12:28 | ExprStmt | match | -| test.rs:11:23:11:34 | HashMap::new | test.rs:11:23:11:36 | CallExpr | | -| test.rs:11:23:11:36 | CallExpr | test.rs:11:13:11:19 | map | | +| test.rs:11:23:11:34 | HashMap::new | test.rs:11:23:11:36 | HashMap::new(...) | | +| test.rs:11:23:11:36 | HashMap::new(...) | test.rs:11:13:11:19 | map | | | test.rs:12:9:12:11 | map | test.rs:12:20:12:21 | 37 | | -| test.rs:12:9:12:27 | ... .insert(...) | test.rs:10:22:13:5 | BlockExpr | | +| test.rs:12:9:12:27 | ... .insert(...) | test.rs:10:22:13:5 | { ... } | | | test.rs:12:9:12:28 | ExprStmt | test.rs:12:9:12:11 | map | | | test.rs:12:20:12:21 | 37 | test.rs:12:24:12:26 | "a" | | | test.rs:12:24:12:26 | "a" | test.rs:12:9:12:27 | ... .insert(...) | | -| test.rs:18:5:24:5 | enter next | test.rs:18:13:18:13 | n | | -| test.rs:18:5:24:5 | exit next (normal) | test.rs:18:5:24:5 | exit next | | -| test.rs:18:13:18:13 | n | test.rs:18:13:18:18 | Param | match | -| test.rs:18:13:18:18 | Param | test.rs:19:12:19:12 | n | | -| test.rs:18:28:24:5 | BlockExpr | test.rs:18:5:24:5 | exit next (normal) | | -| test.rs:19:9:23:9 | IfExpr | test.rs:18:28:24:5 | BlockExpr | | +| test.rs:18:5:24:5 | enter fn next | test.rs:18:13:18:13 | n | | +| test.rs:18:5:24:5 | exit fn next (normal) | test.rs:18:5:24:5 | exit fn next | | +| test.rs:18:13:18:13 | n | test.rs:18:13:18:18 | n: i64 | match | +| test.rs:18:13:18:18 | n: i64 | test.rs:19:12:19:12 | n | | +| test.rs:18:28:24:5 | { ... } | test.rs:18:5:24:5 | exit fn next (normal) | | +| test.rs:19:9:23:9 | if ... { ... } else { ... } | test.rs:18:28:24:5 | { ... } | | | test.rs:19:12:19:12 | n | test.rs:19:16:19:16 | 2 | | | test.rs:19:12:19:16 | ... % ... | test.rs:19:21:19:21 | 0 | | | test.rs:19:12:19:21 | ... == ... | test.rs:20:13:20:13 | n | true | | test.rs:19:12:19:21 | ... == ... | test.rs:22:13:22:13 | 3 | false | | test.rs:19:16:19:16 | 2 | test.rs:19:12:19:16 | ... % ... | | | test.rs:19:21:19:21 | 0 | test.rs:19:12:19:21 | ... == ... | | -| test.rs:19:23:21:9 | BlockExpr | test.rs:19:9:23:9 | IfExpr | | +| test.rs:19:23:21:9 | { ... } | test.rs:19:9:23:9 | if ... { ... } else { ... } | | | test.rs:20:13:20:13 | n | test.rs:20:17:20:17 | 2 | | -| test.rs:20:13:20:17 | ... / ... | test.rs:19:23:21:9 | BlockExpr | | +| test.rs:20:13:20:17 | ... / ... | test.rs:19:23:21:9 | { ... } | | | test.rs:20:17:20:17 | 2 | test.rs:20:13:20:17 | ... / ... | | -| test.rs:21:16:23:9 | BlockExpr | test.rs:19:9:23:9 | IfExpr | | +| test.rs:21:16:23:9 | { ... } | test.rs:19:9:23:9 | if ... { ... } else { ... } | | | test.rs:22:13:22:13 | 3 | test.rs:22:17:22:17 | n | | | test.rs:22:13:22:17 | ... * ... | test.rs:22:21:22:21 | 1 | | -| test.rs:22:13:22:21 | ... + ... | test.rs:21:16:23:9 | BlockExpr | | +| test.rs:22:13:22:21 | ... + ... | test.rs:21:16:23:9 | { ... } | | | test.rs:22:17:22:17 | n | test.rs:22:13:22:17 | ... * ... | | | test.rs:22:21:22:21 | 1 | test.rs:22:13:22:21 | ... + ... | | -| test.rs:26:5:42:5 | enter test_break_and_continue | test.rs:26:32:26:32 | n | | -| test.rs:26:5:42:5 | exit test_break_and_continue (normal) | test.rs:26:5:42:5 | exit test_break_and_continue | | -| test.rs:26:32:26:32 | n | test.rs:26:32:26:37 | Param | match | -| test.rs:26:32:26:37 | Param | test.rs:27:9:27:22 | LetStmt | | -| test.rs:27:9:27:22 | LetStmt | test.rs:27:21:27:21 | n | | +| test.rs:26:5:42:5 | enter fn test_break_and_continue | test.rs:26:32:26:32 | n | | +| test.rs:26:5:42:5 | exit fn test_break_and_continue (normal) | test.rs:26:5:42:5 | exit fn test_break_and_continue | | +| test.rs:26:32:26:32 | n | test.rs:26:32:26:37 | n: i64 | match | +| test.rs:26:32:26:37 | n: i64 | test.rs:27:9:27:22 | let i = ... | | +| test.rs:27:9:27:22 | let i = ... | test.rs:27:21:27:21 | n | | | test.rs:27:13:27:17 | i | test.rs:28:9:40:9 | ExprStmt | match | | test.rs:27:21:27:21 | n | test.rs:27:13:27:17 | i | | | test.rs:28:9:40:9 | ExprStmt | test.rs:29:13:29:24 | ExprStmt | | -| test.rs:28:9:40:9 | LoopExpr | test.rs:41:9:41:20 | ExprStmt | | -| test.rs:28:14:40:9 | BlockExpr | test.rs:29:13:29:24 | ExprStmt | | +| test.rs:28:9:40:9 | loop {...} | test.rs:41:9:41:20 | ExprStmt | | +| test.rs:28:14:40:9 | { ... } | test.rs:29:13:29:24 | ExprStmt | | | test.rs:29:13:29:13 | i | test.rs:29:17:29:20 | next | | | test.rs:29:13:29:23 | ... = ... | test.rs:30:13:32:13 | ExprStmt | | | test.rs:29:13:29:24 | ExprStmt | test.rs:29:13:29:13 | i | | | test.rs:29:17:29:20 | next | test.rs:29:22:29:22 | i | | -| test.rs:29:17:29:23 | CallExpr | test.rs:29:13:29:23 | ... = ... | | -| test.rs:29:22:29:22 | i | test.rs:29:17:29:23 | CallExpr | | +| test.rs:29:17:29:23 | next(...) | test.rs:29:13:29:23 | ... = ... | | +| test.rs:29:22:29:22 | i | test.rs:29:17:29:23 | next(...) | | | test.rs:30:13:32:13 | ExprStmt | test.rs:30:16:30:16 | i | | -| test.rs:30:13:32:13 | IfExpr | test.rs:33:13:35:13 | ExprStmt | | +| test.rs:30:13:32:13 | if ... { ... } | test.rs:33:13:35:13 | ExprStmt | | | test.rs:30:16:30:16 | i | test.rs:30:20:30:24 | 10000 | | -| test.rs:30:16:30:24 | ... > ... | test.rs:30:13:32:13 | IfExpr | false | +| test.rs:30:16:30:24 | ... > ... | test.rs:30:13:32:13 | if ... { ... } | false | | test.rs:30:16:30:24 | ... > ... | test.rs:31:17:31:29 | ExprStmt | true | | test.rs:30:20:30:24 | 10000 | test.rs:30:16:30:24 | ... > ... | | -| test.rs:31:17:31:28 | ReturnExpr | test.rs:26:5:42:5 | exit test_break_and_continue (normal) | return | +| test.rs:31:17:31:28 | return ... | test.rs:26:5:42:5 | exit fn test_break_and_continue (normal) | return | | test.rs:31:17:31:29 | ExprStmt | test.rs:31:24:31:28 | false | | -| test.rs:31:24:31:28 | false | test.rs:31:17:31:28 | ReturnExpr | | +| test.rs:31:24:31:28 | false | test.rs:31:17:31:28 | return ... | | | test.rs:33:13:35:13 | ExprStmt | test.rs:33:16:33:16 | i | | -| test.rs:33:13:35:13 | IfExpr | test.rs:36:13:38:13 | ExprStmt | | +| test.rs:33:13:35:13 | if ... { ... } | test.rs:36:13:38:13 | ExprStmt | | | test.rs:33:16:33:16 | i | test.rs:33:21:33:21 | 1 | | -| test.rs:33:16:33:21 | ... == ... | test.rs:33:13:35:13 | IfExpr | false | +| test.rs:33:16:33:21 | ... == ... | test.rs:33:13:35:13 | if ... { ... } | false | | test.rs:33:16:33:21 | ... == ... | test.rs:34:17:34:22 | ExprStmt | true | | test.rs:33:21:33:21 | 1 | test.rs:33:16:33:21 | ... == ... | | -| test.rs:34:17:34:21 | BreakExpr | test.rs:28:9:40:9 | LoopExpr | break | -| test.rs:34:17:34:22 | ExprStmt | test.rs:34:17:34:21 | BreakExpr | | +| test.rs:34:17:34:21 | break | test.rs:28:9:40:9 | loop {...} | break | +| test.rs:34:17:34:22 | ExprStmt | test.rs:34:17:34:21 | break | | | test.rs:36:13:38:13 | ExprStmt | test.rs:36:16:36:16 | i | | -| test.rs:36:13:38:13 | IfExpr | test.rs:39:13:39:13 | i | | +| test.rs:36:13:38:13 | if ... { ... } | test.rs:39:13:39:13 | i | | | test.rs:36:16:36:16 | i | test.rs:36:20:36:20 | 2 | | | test.rs:36:16:36:20 | ... % ... | test.rs:36:25:36:25 | 0 | | -| test.rs:36:16:36:25 | ... != ... | test.rs:36:13:38:13 | IfExpr | false | +| test.rs:36:16:36:25 | ... != ... | test.rs:36:13:38:13 | if ... { ... } | false | | test.rs:36:16:36:25 | ... != ... | test.rs:37:17:37:25 | ExprStmt | true | | test.rs:36:20:36:20 | 2 | test.rs:36:16:36:20 | ... % ... | | | test.rs:36:25:36:25 | 0 | test.rs:36:16:36:25 | ... != ... | | -| test.rs:37:17:37:24 | ContinueExpr | test.rs:29:13:29:24 | ExprStmt | continue | -| test.rs:37:17:37:25 | ExprStmt | test.rs:37:17:37:24 | ContinueExpr | | +| test.rs:37:17:37:24 | continue | test.rs:29:13:29:24 | ExprStmt | continue | +| test.rs:37:17:37:25 | ExprStmt | test.rs:37:17:37:24 | continue | | | test.rs:39:13:39:13 | i | test.rs:39:17:39:17 | i | | -| test.rs:39:13:39:21 | ... = ... | test.rs:28:14:40:9 | BlockExpr | | +| test.rs:39:13:39:21 | ... = ... | test.rs:28:14:40:9 | { ... } | | | test.rs:39:17:39:17 | i | test.rs:39:21:39:21 | 2 | | | test.rs:39:17:39:21 | ... / ... | test.rs:39:13:39:21 | ... = ... | | | test.rs:39:21:39:21 | 2 | test.rs:39:17:39:21 | ... / ... | | -| test.rs:41:9:41:19 | ReturnExpr | test.rs:26:5:42:5 | exit test_break_and_continue (normal) | return | +| test.rs:41:9:41:19 | return ... | test.rs:26:5:42:5 | exit fn test_break_and_continue (normal) | return | | test.rs:41:9:41:20 | ExprStmt | test.rs:41:16:41:19 | true | | -| test.rs:41:16:41:19 | true | test.rs:41:9:41:19 | ReturnExpr | | -| test.rs:44:5:56:5 | enter test_break_with_labels | test.rs:44:31:44:31 | b | | -| test.rs:44:5:56:5 | exit test_break_with_labels (normal) | test.rs:44:5:56:5 | exit test_break_with_labels | | -| test.rs:44:31:44:31 | b | test.rs:44:31:44:37 | Param | match | -| test.rs:44:31:44:37 | Param | test.rs:45:9:54:9 | ExprStmt | | -| test.rs:44:48:56:5 | BlockExpr | test.rs:44:5:56:5 | exit test_break_with_labels (normal) | | +| test.rs:41:16:41:19 | true | test.rs:41:9:41:19 | return ... | | +| test.rs:44:5:56:5 | enter fn test_break_with_labels | test.rs:44:31:44:31 | b | | +| test.rs:44:5:56:5 | exit fn test_break_with_labels (normal) | test.rs:44:5:56:5 | exit fn test_break_with_labels | | +| test.rs:44:31:44:31 | b | test.rs:44:31:44:37 | b: bool | match | +| test.rs:44:31:44:37 | b: bool | test.rs:45:9:54:9 | ExprStmt | | +| test.rs:44:48:56:5 | { ... } | test.rs:44:5:56:5 | exit fn test_break_with_labels (normal) | | | test.rs:45:9:54:9 | ExprStmt | test.rs:47:17:51:17 | ExprStmt | | -| test.rs:45:9:54:9 | LoopExpr | test.rs:55:9:55:12 | true | | -| test.rs:45:22:54:9 | BlockExpr | test.rs:47:17:51:17 | ExprStmt | | -| test.rs:46:13:53:13 | LoopExpr | test.rs:45:22:54:9 | BlockExpr | | +| test.rs:45:9:54:9 | loop {...} | test.rs:55:9:55:12 | true | | +| test.rs:45:22:54:9 | { ... } | test.rs:47:17:51:17 | ExprStmt | | +| test.rs:46:13:53:13 | loop {...} | test.rs:45:22:54:9 | { ... } | | | test.rs:47:17:51:17 | ExprStmt | test.rs:47:20:47:20 | b | | -| test.rs:47:17:51:17 | IfExpr | test.rs:52:17:52:29 | ExprStmt | | +| test.rs:47:17:51:17 | if ... { ... } else { ... } | test.rs:52:17:52:29 | ExprStmt | | | test.rs:47:20:47:20 | b | test.rs:48:21:48:26 | ExprStmt | true | | test.rs:47:20:47:20 | b | test.rs:49:27:49:27 | b | false | -| test.rs:48:21:48:25 | BreakExpr | test.rs:46:13:53:13 | LoopExpr | break | -| test.rs:48:21:48:26 | ExprStmt | test.rs:48:21:48:25 | BreakExpr | | -| test.rs:49:24:51:17 | IfExpr | test.rs:47:17:51:17 | IfExpr | | -| test.rs:49:27:49:27 | b | test.rs:49:24:51:17 | IfExpr | false | +| test.rs:48:21:48:25 | break | test.rs:46:13:53:13 | loop {...} | break | +| test.rs:48:21:48:26 | ExprStmt | test.rs:48:21:48:25 | break | | +| test.rs:49:24:51:17 | if ... { ... } | test.rs:47:17:51:17 | if ... { ... } else { ... } | | +| test.rs:49:27:49:27 | b | test.rs:49:24:51:17 | if ... { ... } | false | | test.rs:49:27:49:27 | b | test.rs:50:21:50:33 | ExprStmt | true | -| test.rs:50:21:50:32 | BreakExpr | test.rs:45:9:54:9 | LoopExpr | break | -| test.rs:50:21:50:33 | ExprStmt | test.rs:50:21:50:32 | BreakExpr | | -| test.rs:52:17:52:28 | BreakExpr | test.rs:46:13:53:13 | LoopExpr | break | -| test.rs:52:17:52:29 | ExprStmt | test.rs:52:17:52:28 | BreakExpr | | -| test.rs:55:9:55:12 | true | test.rs:44:48:56:5 | BlockExpr | | -| test.rs:58:5:70:5 | enter test_continue_with_labels | test.rs:58:34:58:34 | b | | -| test.rs:58:34:58:34 | b | test.rs:58:34:58:40 | Param | match | -| test.rs:58:34:58:40 | Param | test.rs:60:13:60:14 | ExprStmt | | +| test.rs:50:21:50:32 | break ''outer | test.rs:45:9:54:9 | loop {...} | break | +| test.rs:50:21:50:33 | ExprStmt | test.rs:50:21:50:32 | break ''outer | | +| test.rs:52:17:52:28 | break ''inner | test.rs:46:13:53:13 | loop {...} | break | +| test.rs:52:17:52:29 | ExprStmt | test.rs:52:17:52:28 | break ''inner | | +| test.rs:55:9:55:12 | true | test.rs:44:48:56:5 | { ... } | | +| test.rs:58:5:70:5 | enter fn test_continue_with_labels | test.rs:58:34:58:34 | b | | +| test.rs:58:34:58:34 | b | test.rs:58:34:58:40 | b: bool | match | +| test.rs:58:34:58:40 | b: bool | test.rs:60:13:60:14 | ExprStmt | | | test.rs:60:13:60:13 | 1 | test.rs:62:17:66:17 | ExprStmt | | | test.rs:60:13:60:14 | ExprStmt | test.rs:60:13:60:13 | 1 | | | test.rs:62:17:66:17 | ExprStmt | test.rs:62:20:62:20 | b | | -| test.rs:62:17:66:17 | IfExpr | test.rs:67:17:67:32 | ExprStmt | | +| test.rs:62:17:66:17 | if ... { ... } else { ... } | test.rs:67:17:67:32 | ExprStmt | | | test.rs:62:20:62:20 | b | test.rs:63:21:63:29 | ExprStmt | true | | test.rs:62:20:62:20 | b | test.rs:64:27:64:27 | b | false | -| test.rs:63:21:63:28 | ContinueExpr | test.rs:62:17:66:17 | ExprStmt | continue | -| test.rs:63:21:63:29 | ExprStmt | test.rs:63:21:63:28 | ContinueExpr | | -| test.rs:64:24:66:17 | IfExpr | test.rs:62:17:66:17 | IfExpr | | -| test.rs:64:27:64:27 | b | test.rs:64:24:66:17 | IfExpr | false | +| test.rs:63:21:63:28 | continue | test.rs:62:17:66:17 | ExprStmt | continue | +| test.rs:63:21:63:29 | ExprStmt | test.rs:63:21:63:28 | continue | | +| test.rs:64:24:66:17 | if ... { ... } | test.rs:62:17:66:17 | if ... { ... } else { ... } | | +| test.rs:64:27:64:27 | b | test.rs:64:24:66:17 | if ... { ... } | false | | test.rs:64:27:64:27 | b | test.rs:65:21:65:36 | ExprStmt | true | -| test.rs:65:21:65:35 | ContinueExpr | test.rs:60:13:60:14 | ExprStmt | continue | -| test.rs:65:21:65:36 | ExprStmt | test.rs:65:21:65:35 | ContinueExpr | | -| test.rs:67:17:67:31 | ContinueExpr | test.rs:62:17:66:17 | ExprStmt | continue | -| test.rs:67:17:67:32 | ExprStmt | test.rs:67:17:67:31 | ContinueExpr | | -| test.rs:72:5:84:5 | enter test_loop_label_shadowing | test.rs:72:34:72:34 | b | | -| test.rs:72:34:72:34 | b | test.rs:72:34:72:40 | Param | match | -| test.rs:72:34:72:40 | Param | test.rs:74:13:74:14 | ExprStmt | | +| test.rs:65:21:65:35 | continue 'outer | test.rs:60:13:60:14 | ExprStmt | continue | +| test.rs:65:21:65:36 | ExprStmt | test.rs:65:21:65:35 | continue 'outer | | +| test.rs:67:17:67:31 | continue 'inner | test.rs:62:17:66:17 | ExprStmt | continue | +| test.rs:67:17:67:32 | ExprStmt | test.rs:67:17:67:31 | continue 'inner | | +| test.rs:72:5:84:5 | enter fn test_loop_label_shadowing | test.rs:72:34:72:34 | b | | +| test.rs:72:34:72:34 | b | test.rs:72:34:72:40 | b: bool | match | +| test.rs:72:34:72:40 | b: bool | test.rs:74:13:74:14 | ExprStmt | | | test.rs:74:13:74:13 | 1 | test.rs:76:17:80:17 | ExprStmt | | | test.rs:74:13:74:14 | ExprStmt | test.rs:74:13:74:13 | 1 | | | test.rs:76:17:80:17 | ExprStmt | test.rs:76:20:76:20 | b | | -| test.rs:76:17:80:17 | IfExpr | test.rs:81:17:81:32 | ExprStmt | | +| test.rs:76:17:80:17 | if ... { ... } else { ... } | test.rs:81:17:81:32 | ExprStmt | | | test.rs:76:20:76:20 | b | test.rs:77:21:77:29 | ExprStmt | true | | test.rs:76:20:76:20 | b | test.rs:78:27:78:27 | b | false | -| test.rs:77:21:77:28 | ContinueExpr | test.rs:76:17:80:17 | ExprStmt | continue | -| test.rs:77:21:77:29 | ExprStmt | test.rs:77:21:77:28 | ContinueExpr | | -| test.rs:78:24:80:17 | IfExpr | test.rs:76:17:80:17 | IfExpr | | -| test.rs:78:27:78:27 | b | test.rs:78:24:80:17 | IfExpr | false | +| test.rs:77:21:77:28 | continue | test.rs:76:17:80:17 | ExprStmt | continue | +| test.rs:77:21:77:29 | ExprStmt | test.rs:77:21:77:28 | continue | | +| test.rs:78:24:80:17 | if ... { ... } | test.rs:76:17:80:17 | if ... { ... } else { ... } | | +| test.rs:78:27:78:27 | b | test.rs:78:24:80:17 | if ... { ... } | false | | test.rs:78:27:78:27 | b | test.rs:79:21:79:36 | ExprStmt | true | -| test.rs:79:21:79:35 | ContinueExpr | test.rs:76:17:80:17 | ExprStmt | continue | -| test.rs:79:21:79:36 | ExprStmt | test.rs:79:21:79:35 | ContinueExpr | | -| test.rs:81:17:81:31 | ContinueExpr | test.rs:76:17:80:17 | ExprStmt | continue | -| test.rs:81:17:81:32 | ExprStmt | test.rs:81:17:81:31 | ContinueExpr | | -| test.rs:86:5:95:5 | enter test_while | test.rs:86:19:86:19 | i | | -| test.rs:86:5:95:5 | exit test_while (normal) | test.rs:86:5:95:5 | exit test_while | | -| test.rs:86:19:86:19 | i | test.rs:86:19:86:24 | Param | match | -| test.rs:86:19:86:24 | Param | test.rs:87:9:87:25 | LetStmt | | -| test.rs:86:27:95:5 | BlockExpr | test.rs:86:5:95:5 | exit test_while (normal) | | -| test.rs:87:9:87:25 | LetStmt | test.rs:87:21:87:24 | true | | +| test.rs:79:21:79:35 | continue 'label | test.rs:76:17:80:17 | ExprStmt | continue | +| test.rs:79:21:79:36 | ExprStmt | test.rs:79:21:79:35 | continue 'label | | +| test.rs:81:17:81:31 | continue 'label | test.rs:76:17:80:17 | ExprStmt | continue | +| test.rs:81:17:81:32 | ExprStmt | test.rs:81:17:81:31 | continue 'label | | +| test.rs:86:5:95:5 | enter fn test_while | test.rs:86:19:86:19 | i | | +| test.rs:86:5:95:5 | exit fn test_while (normal) | test.rs:86:5:95:5 | exit fn test_while | | +| test.rs:86:19:86:19 | i | test.rs:86:19:86:24 | i: i64 | match | +| test.rs:86:19:86:24 | i: i64 | test.rs:87:9:87:25 | let b = ... | | +| test.rs:86:27:95:5 | { ... } | test.rs:86:5:95:5 | exit fn test_while (normal) | | +| test.rs:87:9:87:25 | let b = ... | test.rs:87:21:87:24 | true | | | test.rs:87:13:87:17 | b | test.rs:88:15:88:15 | b | match | | test.rs:87:21:87:24 | true | test.rs:87:13:87:17 | b | | -| test.rs:88:9:94:9 | WhileExpr | test.rs:86:27:95:5 | BlockExpr | | -| test.rs:88:15:88:15 | b | test.rs:88:9:94:9 | WhileExpr | false | +| test.rs:88:9:94:9 | while ... { ... } | test.rs:86:27:95:5 | { ... } | | +| test.rs:88:15:88:15 | b | test.rs:88:9:94:9 | while ... { ... } | false | | test.rs:88:15:88:15 | b | test.rs:89:13:89:14 | ExprStmt | true | -| test.rs:88:17:94:9 | BlockExpr | test.rs:88:15:88:15 | b | | +| test.rs:88:17:94:9 | { ... } | test.rs:88:15:88:15 | b | | | test.rs:89:13:89:13 | 1 | test.rs:90:13:92:13 | ExprStmt | | | test.rs:89:13:89:14 | ExprStmt | test.rs:89:13:89:13 | 1 | | | test.rs:90:13:92:13 | ExprStmt | test.rs:90:17:90:17 | i | | -| test.rs:90:13:92:13 | IfExpr | test.rs:93:13:93:22 | ExprStmt | | +| test.rs:90:13:92:13 | if ... { ... } | test.rs:93:13:93:22 | ExprStmt | | | test.rs:90:17:90:17 | i | test.rs:90:21:90:21 | 0 | | -| test.rs:90:17:90:21 | ... > ... | test.rs:90:13:92:13 | IfExpr | false | +| test.rs:90:17:90:21 | ... > ... | test.rs:90:13:92:13 | if ... { ... } | false | | test.rs:90:17:90:21 | ... > ... | test.rs:91:17:91:22 | ExprStmt | true | | test.rs:90:21:90:21 | 0 | test.rs:90:17:90:21 | ... > ... | | -| test.rs:91:17:91:21 | BreakExpr | test.rs:88:9:94:9 | WhileExpr | break | -| test.rs:91:17:91:22 | ExprStmt | test.rs:91:17:91:21 | BreakExpr | | +| test.rs:91:17:91:21 | break | test.rs:88:9:94:9 | while ... { ... } | break | +| test.rs:91:17:91:22 | ExprStmt | test.rs:91:17:91:21 | break | | | test.rs:93:13:93:13 | b | test.rs:93:17:93:21 | false | | -| test.rs:93:13:93:21 | ... = ... | test.rs:88:17:94:9 | BlockExpr | | +| test.rs:93:13:93:21 | ... = ... | test.rs:88:17:94:9 | { ... } | | | test.rs:93:13:93:22 | ExprStmt | test.rs:93:13:93:13 | b | | | test.rs:93:17:93:21 | false | test.rs:93:13:93:21 | ... = ... | | -| test.rs:97:5:104:5 | enter test_while_let | test.rs:98:9:98:29 | LetStmt | | -| test.rs:97:5:104:5 | exit test_while_let (normal) | test.rs:97:5:104:5 | exit test_while_let | | -| test.rs:97:25:104:5 | BlockExpr | test.rs:97:5:104:5 | exit test_while_let (normal) | | -| test.rs:98:9:98:29 | LetStmt | test.rs:98:24:98:24 | 1 | | -| test.rs:98:13:98:20 | iter | test.rs:99:15:99:39 | LetExpr | match | +| test.rs:97:5:104:5 | enter fn test_while_let | test.rs:98:9:98:29 | let iter = ... | | +| test.rs:97:5:104:5 | exit fn test_while_let (normal) | test.rs:97:5:104:5 | exit fn test_while_let | | +| test.rs:97:25:104:5 | { ... } | test.rs:97:5:104:5 | exit fn test_while_let (normal) | | +| test.rs:98:9:98:29 | let iter = ... | test.rs:98:24:98:24 | 1 | | +| test.rs:98:13:98:20 | iter | test.rs:99:15:99:39 | let TupleStructPat = ... | match | | test.rs:98:24:98:24 | 1 | test.rs:98:27:98:28 | 10 | | -| test.rs:98:24:98:28 | RangeExpr | test.rs:98:13:98:20 | iter | | -| test.rs:98:27:98:28 | 10 | test.rs:98:24:98:28 | RangeExpr | | -| test.rs:99:9:103:9 | WhileExpr | test.rs:97:25:104:5 | BlockExpr | | -| test.rs:99:15:99:39 | LetExpr | test.rs:99:29:99:32 | iter | | -| test.rs:99:19:99:25 | TupleStructPat | test.rs:99:9:103:9 | WhileExpr | no-match | +| test.rs:98:24:98:28 | ... .. ... | test.rs:98:13:98:20 | iter | | +| test.rs:98:27:98:28 | 10 | test.rs:98:24:98:28 | ... .. ... | | +| test.rs:99:9:103:9 | while ... { ... } | test.rs:97:25:104:5 | { ... } | | +| test.rs:99:15:99:39 | let TupleStructPat = ... | test.rs:99:29:99:32 | iter | | +| test.rs:99:19:99:25 | TupleStructPat | test.rs:99:9:103:9 | while ... { ... } | no-match | | test.rs:99:19:99:25 | TupleStructPat | test.rs:99:24:99:24 | x | match | | test.rs:99:24:99:24 | x | test.rs:100:17:100:17 | x | match | | test.rs:99:29:99:32 | iter | test.rs:99:29:99:39 | ... .next(...) | | | test.rs:99:29:99:39 | ... .next(...) | test.rs:99:19:99:25 | TupleStructPat | | -| test.rs:99:41:103:9 | BlockExpr | test.rs:99:15:99:39 | LetExpr | | -| test.rs:100:13:102:13 | IfExpr | test.rs:99:41:103:9 | BlockExpr | | +| test.rs:99:41:103:9 | { ... } | test.rs:99:15:99:39 | let TupleStructPat = ... | | +| test.rs:100:13:102:13 | if ... { ... } | test.rs:99:41:103:9 | { ... } | | | test.rs:100:17:100:17 | x | test.rs:100:22:100:22 | 5 | | -| test.rs:100:17:100:22 | ... == ... | test.rs:100:13:102:13 | IfExpr | false | +| test.rs:100:17:100:22 | ... == ... | test.rs:100:13:102:13 | if ... { ... } | false | | test.rs:100:17:100:22 | ... == ... | test.rs:101:17:101:22 | ExprStmt | true | | test.rs:100:22:100:22 | 5 | test.rs:100:17:100:22 | ... == ... | | -| test.rs:101:17:101:21 | BreakExpr | test.rs:99:9:103:9 | WhileExpr | break | -| test.rs:101:17:101:22 | ExprStmt | test.rs:101:17:101:21 | BreakExpr | | -| test.rs:106:5:113:5 | enter test_for | test.rs:106:17:106:17 | j | | -| test.rs:106:5:113:5 | exit test_for (normal) | test.rs:106:5:113:5 | exit test_for | | -| test.rs:106:17:106:17 | j | test.rs:106:17:106:22 | Param | match | -| test.rs:106:17:106:22 | Param | test.rs:107:18:107:18 | 0 | | -| test.rs:106:25:113:5 | BlockExpr | test.rs:106:5:113:5 | exit test_for (normal) | | -| test.rs:107:9:112:9 | ForExpr | test.rs:106:25:113:5 | BlockExpr | | -| test.rs:107:13:107:13 | i | test.rs:107:9:112:9 | ForExpr | no-match | +| test.rs:101:17:101:21 | break | test.rs:99:9:103:9 | while ... { ... } | break | +| test.rs:101:17:101:22 | ExprStmt | test.rs:101:17:101:21 | break | | +| test.rs:106:5:113:5 | enter fn test_for | test.rs:106:17:106:17 | j | | +| test.rs:106:5:113:5 | exit fn test_for (normal) | test.rs:106:5:113:5 | exit fn test_for | | +| test.rs:106:17:106:17 | j | test.rs:106:17:106:22 | j: i64 | match | +| test.rs:106:17:106:22 | j: i64 | test.rs:107:18:107:18 | 0 | | +| test.rs:106:25:113:5 | { ... } | test.rs:106:5:113:5 | exit fn test_for (normal) | | +| test.rs:107:9:112:9 | for i in ... { ... } | test.rs:106:25:113:5 | { ... } | | +| test.rs:107:13:107:13 | i | test.rs:107:9:112:9 | for i in ... { ... } | no-match | | test.rs:107:13:107:13 | i | test.rs:108:13:110:13 | ExprStmt | match | | test.rs:107:18:107:18 | 0 | test.rs:107:21:107:22 | 10 | | -| test.rs:107:18:107:22 | RangeExpr | test.rs:107:13:107:13 | i | | -| test.rs:107:21:107:22 | 10 | test.rs:107:18:107:22 | RangeExpr | | -| test.rs:107:24:112:9 | BlockExpr | test.rs:107:13:107:13 | i | | +| test.rs:107:18:107:22 | ... .. ... | test.rs:107:13:107:13 | i | | +| test.rs:107:21:107:22 | 10 | test.rs:107:18:107:22 | ... .. ... | | +| test.rs:107:24:112:9 | { ... } | test.rs:107:13:107:13 | i | | | test.rs:108:13:110:13 | ExprStmt | test.rs:108:17:108:17 | i | | -| test.rs:108:13:110:13 | IfExpr | test.rs:111:13:111:14 | ExprStmt | | +| test.rs:108:13:110:13 | if ... { ... } | test.rs:111:13:111:14 | ExprStmt | | | test.rs:108:17:108:17 | i | test.rs:108:22:108:22 | j | | -| test.rs:108:17:108:22 | ... == ... | test.rs:108:13:110:13 | IfExpr | false | +| test.rs:108:17:108:22 | ... == ... | test.rs:108:13:110:13 | if ... { ... } | false | | test.rs:108:17:108:22 | ... == ... | test.rs:109:17:109:22 | ExprStmt | true | | test.rs:108:22:108:22 | j | test.rs:108:17:108:22 | ... == ... | | -| test.rs:109:17:109:21 | BreakExpr | test.rs:107:9:112:9 | ForExpr | break | -| test.rs:109:17:109:22 | ExprStmt | test.rs:109:17:109:21 | BreakExpr | | -| test.rs:111:13:111:13 | 1 | test.rs:107:24:112:9 | BlockExpr | | +| test.rs:109:17:109:21 | break | test.rs:107:9:112:9 | for i in ... { ... } | break | +| test.rs:109:17:109:22 | ExprStmt | test.rs:109:17:109:21 | break | | +| test.rs:111:13:111:13 | 1 | test.rs:107:24:112:9 | { ... } | | | test.rs:111:13:111:14 | ExprStmt | test.rs:111:13:111:13 | 1 | | -| test.rs:115:5:119:5 | enter break_with_return | test.rs:117:13:117:27 | ExprStmt | | -| test.rs:115:5:119:5 | exit break_with_return (normal) | test.rs:115:5:119:5 | exit break_with_return | | +| test.rs:115:5:119:5 | enter fn break_with_return | test.rs:117:13:117:27 | ExprStmt | | +| test.rs:115:5:119:5 | exit fn break_with_return (normal) | test.rs:115:5:119:5 | exit fn break_with_return | | | test.rs:117:13:117:27 | ExprStmt | test.rs:117:26:117:26 | 1 | | -| test.rs:117:19:117:26 | ReturnExpr | test.rs:115:5:119:5 | exit break_with_return (normal) | return | -| test.rs:117:26:117:26 | 1 | test.rs:117:19:117:26 | ReturnExpr | | -| test.rs:122:1:125:1 | enter test_nested_function | test.rs:122:25:122:25 | n | | -| test.rs:122:1:125:1 | exit test_nested_function (normal) | test.rs:122:1:125:1 | exit test_nested_function | | -| test.rs:122:25:122:25 | n | test.rs:122:25:122:30 | Param | match | -| test.rs:122:25:122:30 | Param | test.rs:123:5:123:28 | LetStmt | | -| test.rs:122:40:125:1 | BlockExpr | test.rs:122:1:125:1 | exit test_nested_function (normal) | | -| test.rs:123:5:123:28 | LetStmt | test.rs:123:19:123:27 | ClosureExpr | | +| test.rs:117:19:117:26 | return ... | test.rs:115:5:119:5 | exit fn break_with_return (normal) | return | +| test.rs:117:26:117:26 | 1 | test.rs:117:19:117:26 | return ... | | +| test.rs:122:1:125:1 | enter fn test_nested_function | test.rs:122:25:122:25 | n | | +| test.rs:122:1:125:1 | exit fn test_nested_function (normal) | test.rs:122:1:125:1 | exit fn test_nested_function | | +| test.rs:122:25:122:25 | n | test.rs:122:25:122:30 | n: i64 | match | +| test.rs:122:25:122:30 | n: i64 | test.rs:123:5:123:28 | let add_one = ... | | +| test.rs:122:40:125:1 | { ... } | test.rs:122:1:125:1 | exit fn test_nested_function (normal) | | +| test.rs:123:5:123:28 | let add_one = ... | test.rs:123:19:123:27 | \|...\| ... | | | test.rs:123:9:123:15 | add_one | test.rs:124:5:124:11 | add_one | match | -| test.rs:123:19:123:27 | ClosureExpr | test.rs:123:9:123:15 | add_one | | -| test.rs:123:19:123:27 | enter ClosureExpr | test.rs:123:20:123:20 | i | | -| test.rs:123:19:123:27 | exit ClosureExpr (normal) | test.rs:123:19:123:27 | exit ClosureExpr | | -| test.rs:123:20:123:20 | Param | test.rs:123:23:123:23 | i | | -| test.rs:123:20:123:20 | i | test.rs:123:20:123:20 | Param | match | +| test.rs:123:19:123:27 | \|...\| ... | test.rs:123:9:123:15 | add_one | | +| test.rs:123:19:123:27 | enter \|...\| ... | test.rs:123:20:123:20 | i | | +| test.rs:123:19:123:27 | exit \|...\| ... (normal) | test.rs:123:19:123:27 | exit \|...\| ... | | +| test.rs:123:20:123:20 | i | test.rs:123:20:123:20 | i | match | +| test.rs:123:20:123:20 | i | test.rs:123:23:123:23 | i | | | test.rs:123:23:123:23 | i | test.rs:123:27:123:27 | 1 | | -| test.rs:123:23:123:27 | ... + ... | test.rs:123:19:123:27 | exit ClosureExpr (normal) | | +| test.rs:123:23:123:27 | ... + ... | test.rs:123:19:123:27 | exit \|...\| ... (normal) | | | test.rs:123:27:123:27 | 1 | test.rs:123:23:123:27 | ... + ... | | | test.rs:124:5:124:11 | add_one | test.rs:124:13:124:19 | add_one | | -| test.rs:124:5:124:23 | CallExpr | test.rs:122:40:125:1 | BlockExpr | | +| test.rs:124:5:124:23 | add_one(...) | test.rs:122:40:125:1 | { ... } | | | test.rs:124:13:124:19 | add_one | test.rs:124:21:124:21 | n | | -| test.rs:124:13:124:22 | CallExpr | test.rs:124:5:124:23 | CallExpr | | -| test.rs:124:21:124:21 | n | test.rs:124:13:124:22 | CallExpr | | -| test.rs:129:5:135:5 | enter test_if_else | test.rs:129:21:129:21 | n | | -| test.rs:129:5:135:5 | exit test_if_else (normal) | test.rs:129:5:135:5 | exit test_if_else | | -| test.rs:129:21:129:21 | n | test.rs:129:21:129:26 | Param | match | -| test.rs:129:21:129:26 | Param | test.rs:130:12:130:12 | n | | -| test.rs:129:36:135:5 | BlockExpr | test.rs:129:5:135:5 | exit test_if_else (normal) | | -| test.rs:130:9:134:9 | IfExpr | test.rs:129:36:135:5 | BlockExpr | | +| test.rs:124:13:124:22 | add_one(...) | test.rs:124:5:124:23 | add_one(...) | | +| test.rs:124:21:124:21 | n | test.rs:124:13:124:22 | add_one(...) | | +| test.rs:129:5:135:5 | enter fn test_if_else | test.rs:129:21:129:21 | n | | +| test.rs:129:5:135:5 | exit fn test_if_else (normal) | test.rs:129:5:135:5 | exit fn test_if_else | | +| test.rs:129:21:129:21 | n | test.rs:129:21:129:26 | n: i64 | match | +| test.rs:129:21:129:26 | n: i64 | test.rs:130:12:130:12 | n | | +| test.rs:129:36:135:5 | { ... } | test.rs:129:5:135:5 | exit fn test_if_else (normal) | | +| test.rs:130:9:134:9 | if ... { ... } else { ... } | test.rs:129:36:135:5 | { ... } | | | test.rs:130:12:130:12 | n | test.rs:130:17:130:17 | 0 | | | test.rs:130:12:130:17 | ... <= ... | test.rs:131:13:131:13 | 0 | true | | test.rs:130:12:130:17 | ... <= ... | test.rs:133:13:133:13 | n | false | | test.rs:130:17:130:17 | 0 | test.rs:130:12:130:17 | ... <= ... | | -| test.rs:130:19:132:9 | BlockExpr | test.rs:130:9:134:9 | IfExpr | | -| test.rs:131:13:131:13 | 0 | test.rs:130:19:132:9 | BlockExpr | | -| test.rs:132:16:134:9 | BlockExpr | test.rs:130:9:134:9 | IfExpr | | +| test.rs:130:19:132:9 | { ... } | test.rs:130:9:134:9 | if ... { ... } else { ... } | | +| test.rs:131:13:131:13 | 0 | test.rs:130:19:132:9 | { ... } | | +| test.rs:132:16:134:9 | { ... } | test.rs:130:9:134:9 | if ... { ... } else { ... } | | | test.rs:133:13:133:13 | n | test.rs:133:17:133:17 | 1 | | -| test.rs:133:13:133:17 | ... - ... | test.rs:132:16:134:9 | BlockExpr | | +| test.rs:133:13:133:17 | ... - ... | test.rs:132:16:134:9 | { ... } | | | test.rs:133:17:133:17 | 1 | test.rs:133:13:133:17 | ... - ... | | -| test.rs:137:5:143:5 | enter test_if_let_else | test.rs:137:25:137:25 | a | | -| test.rs:137:5:143:5 | exit test_if_let_else (normal) | test.rs:137:5:143:5 | exit test_if_let_else | | -| test.rs:137:25:137:25 | a | test.rs:137:25:137:38 | Param | match | -| test.rs:137:25:137:38 | Param | test.rs:138:12:138:26 | LetExpr | | -| test.rs:137:48:143:5 | BlockExpr | test.rs:137:5:143:5 | exit test_if_let_else (normal) | | -| test.rs:138:9:142:9 | IfExpr | test.rs:137:48:143:5 | BlockExpr | | -| test.rs:138:12:138:26 | LetExpr | test.rs:138:26:138:26 | a | | +| test.rs:137:5:143:5 | enter fn test_if_let_else | test.rs:137:25:137:25 | a | | +| test.rs:137:5:143:5 | exit fn test_if_let_else (normal) | test.rs:137:5:143:5 | exit fn test_if_let_else | | +| test.rs:137:25:137:25 | a | test.rs:137:25:137:38 | a: Option::<...> | match | +| test.rs:137:25:137:38 | a: Option::<...> | test.rs:138:12:138:26 | let TupleStructPat = ... | | +| test.rs:137:48:143:5 | { ... } | test.rs:137:5:143:5 | exit fn test_if_let_else (normal) | | +| test.rs:138:9:142:9 | if ... { ... } else { ... } | test.rs:137:48:143:5 | { ... } | | +| test.rs:138:12:138:26 | let TupleStructPat = ... | test.rs:138:26:138:26 | a | | | test.rs:138:16:138:22 | TupleStructPat | test.rs:138:21:138:21 | n | match | | test.rs:138:16:138:22 | TupleStructPat | test.rs:141:13:141:13 | 0 | no-match | | test.rs:138:21:138:21 | n | test.rs:139:13:139:13 | n | match | | test.rs:138:26:138:26 | a | test.rs:138:16:138:22 | TupleStructPat | | -| test.rs:138:28:140:9 | BlockExpr | test.rs:138:9:142:9 | IfExpr | | -| test.rs:139:13:139:13 | n | test.rs:138:28:140:9 | BlockExpr | | -| test.rs:140:16:142:9 | BlockExpr | test.rs:138:9:142:9 | IfExpr | | -| test.rs:141:13:141:13 | 0 | test.rs:140:16:142:9 | BlockExpr | | -| test.rs:145:5:150:5 | enter test_if_let | test.rs:145:20:145:20 | a | | -| test.rs:145:5:150:5 | exit test_if_let (normal) | test.rs:145:5:150:5 | exit test_if_let | | -| test.rs:145:20:145:20 | a | test.rs:145:20:145:33 | Param | match | -| test.rs:145:20:145:33 | Param | test.rs:146:9:148:9 | ExprStmt | | -| test.rs:145:43:150:5 | BlockExpr | test.rs:145:5:150:5 | exit test_if_let (normal) | | -| test.rs:146:9:148:9 | ExprStmt | test.rs:146:12:146:26 | LetExpr | | -| test.rs:146:9:148:9 | IfExpr | test.rs:149:9:149:9 | 0 | | -| test.rs:146:12:146:26 | LetExpr | test.rs:146:26:146:26 | a | | -| test.rs:146:16:146:22 | TupleStructPat | test.rs:146:9:148:9 | IfExpr | no-match | +| test.rs:138:28:140:9 | { ... } | test.rs:138:9:142:9 | if ... { ... } else { ... } | | +| test.rs:139:13:139:13 | n | test.rs:138:28:140:9 | { ... } | | +| test.rs:140:16:142:9 | { ... } | test.rs:138:9:142:9 | if ... { ... } else { ... } | | +| test.rs:141:13:141:13 | 0 | test.rs:140:16:142:9 | { ... } | | +| test.rs:145:5:150:5 | enter fn test_if_let | test.rs:145:20:145:20 | a | | +| test.rs:145:5:150:5 | exit fn test_if_let (normal) | test.rs:145:5:150:5 | exit fn test_if_let | | +| test.rs:145:20:145:20 | a | test.rs:145:20:145:33 | a: Option::<...> | match | +| test.rs:145:20:145:33 | a: Option::<...> | test.rs:146:9:148:9 | ExprStmt | | +| test.rs:145:43:150:5 | { ... } | test.rs:145:5:150:5 | exit fn test_if_let (normal) | | +| test.rs:146:9:148:9 | ExprStmt | test.rs:146:12:146:26 | let TupleStructPat = ... | | +| test.rs:146:9:148:9 | if ... { ... } | test.rs:149:9:149:9 | 0 | | +| test.rs:146:12:146:26 | let TupleStructPat = ... | test.rs:146:26:146:26 | a | | +| test.rs:146:16:146:22 | TupleStructPat | test.rs:146:9:148:9 | if ... { ... } | no-match | | test.rs:146:16:146:22 | TupleStructPat | test.rs:146:21:146:21 | n | match | | test.rs:146:21:146:21 | n | test.rs:147:13:147:21 | ExprStmt | match | | test.rs:146:26:146:26 | a | test.rs:146:16:146:22 | TupleStructPat | | -| test.rs:147:13:147:20 | ReturnExpr | test.rs:145:5:150:5 | exit test_if_let (normal) | return | +| test.rs:147:13:147:20 | return ... | test.rs:145:5:150:5 | exit fn test_if_let (normal) | return | | test.rs:147:13:147:21 | ExprStmt | test.rs:147:20:147:20 | n | | -| test.rs:147:20:147:20 | n | test.rs:147:13:147:20 | ReturnExpr | | -| test.rs:149:9:149:9 | 0 | test.rs:145:43:150:5 | BlockExpr | | -| test.rs:152:5:158:5 | enter test_nested_if | test.rs:152:23:152:23 | a | | -| test.rs:152:5:158:5 | exit test_nested_if (normal) | test.rs:152:5:158:5 | exit test_nested_if | | -| test.rs:152:23:152:23 | a | test.rs:152:23:152:28 | Param | match | -| test.rs:152:23:152:28 | Param | test.rs:153:16:153:16 | a | | -| test.rs:152:38:158:5 | BlockExpr | test.rs:152:5:158:5 | exit test_nested_if (normal) | | -| test.rs:153:9:157:9 | IfExpr | test.rs:152:38:158:5 | BlockExpr | | -| test.rs:153:13:153:48 | [boolean(false)] IfExpr | test.rs:156:13:156:13 | 0 | false | -| test.rs:153:13:153:48 | [boolean(true)] IfExpr | test.rs:154:13:154:13 | 1 | true | +| test.rs:147:20:147:20 | n | test.rs:147:13:147:20 | return ... | | +| test.rs:149:9:149:9 | 0 | test.rs:145:43:150:5 | { ... } | | +| test.rs:152:5:158:5 | enter fn test_nested_if | test.rs:152:23:152:23 | a | | +| test.rs:152:5:158:5 | exit fn test_nested_if (normal) | test.rs:152:5:158:5 | exit fn test_nested_if | | +| test.rs:152:23:152:23 | a | test.rs:152:23:152:28 | a: i64 | match | +| test.rs:152:23:152:28 | a: i64 | test.rs:153:16:153:16 | a | | +| test.rs:152:38:158:5 | { ... } | test.rs:152:5:158:5 | exit fn test_nested_if (normal) | | +| test.rs:153:9:157:9 | if ... { ... } else { ... } | test.rs:152:38:158:5 | { ... } | | +| test.rs:153:13:153:48 | [boolean(false)] if ... { ... } else { ... } | test.rs:156:13:156:13 | 0 | false | +| test.rs:153:13:153:48 | [boolean(true)] if ... { ... } else { ... } | test.rs:154:13:154:13 | 1 | true | | test.rs:153:16:153:16 | a | test.rs:153:20:153:20 | 0 | | | test.rs:153:16:153:20 | ... < ... | test.rs:153:24:153:24 | a | true | | test.rs:153:16:153:20 | ... < ... | test.rs:153:41:153:41 | a | false | | test.rs:153:20:153:20 | 0 | test.rs:153:16:153:20 | ... < ... | | -| test.rs:153:22:153:32 | [boolean(false)] BlockExpr | test.rs:153:13:153:48 | [boolean(false)] IfExpr | false | -| test.rs:153:22:153:32 | [boolean(true)] BlockExpr | test.rs:153:13:153:48 | [boolean(true)] IfExpr | true | +| test.rs:153:22:153:32 | [boolean(false)] { ... } | test.rs:153:13:153:48 | [boolean(false)] if ... { ... } else { ... } | false | +| test.rs:153:22:153:32 | [boolean(true)] { ... } | test.rs:153:13:153:48 | [boolean(true)] if ... { ... } else { ... } | true | | test.rs:153:24:153:24 | a | test.rs:153:29:153:30 | 10 | | -| test.rs:153:24:153:30 | ... < ... | test.rs:153:22:153:32 | [boolean(false)] BlockExpr | false | -| test.rs:153:24:153:30 | ... < ... | test.rs:153:22:153:32 | [boolean(true)] BlockExpr | true | +| test.rs:153:24:153:30 | ... < ... | test.rs:153:22:153:32 | [boolean(false)] { ... } | false | +| test.rs:153:24:153:30 | ... < ... | test.rs:153:22:153:32 | [boolean(true)] { ... } | true | | test.rs:153:28:153:30 | - ... | test.rs:153:24:153:30 | ... < ... | | | test.rs:153:29:153:30 | 10 | test.rs:153:28:153:30 | - ... | | -| test.rs:153:39:153:48 | [boolean(false)] BlockExpr | test.rs:153:13:153:48 | [boolean(false)] IfExpr | false | -| test.rs:153:39:153:48 | [boolean(true)] BlockExpr | test.rs:153:13:153:48 | [boolean(true)] IfExpr | true | +| test.rs:153:39:153:48 | [boolean(false)] { ... } | test.rs:153:13:153:48 | [boolean(false)] if ... { ... } else { ... } | false | +| test.rs:153:39:153:48 | [boolean(true)] { ... } | test.rs:153:13:153:48 | [boolean(true)] if ... { ... } else { ... } | true | | test.rs:153:41:153:41 | a | test.rs:153:45:153:46 | 10 | | -| test.rs:153:41:153:46 | ... > ... | test.rs:153:39:153:48 | [boolean(false)] BlockExpr | false | -| test.rs:153:41:153:46 | ... > ... | test.rs:153:39:153:48 | [boolean(true)] BlockExpr | true | +| test.rs:153:41:153:46 | ... > ... | test.rs:153:39:153:48 | [boolean(false)] { ... } | false | +| test.rs:153:41:153:46 | ... > ... | test.rs:153:39:153:48 | [boolean(true)] { ... } | true | | test.rs:153:45:153:46 | 10 | test.rs:153:41:153:46 | ... > ... | | -| test.rs:153:51:155:9 | BlockExpr | test.rs:153:9:157:9 | IfExpr | | -| test.rs:154:13:154:13 | 1 | test.rs:153:51:155:9 | BlockExpr | | -| test.rs:155:16:157:9 | BlockExpr | test.rs:153:9:157:9 | IfExpr | | -| test.rs:156:13:156:13 | 0 | test.rs:155:16:157:9 | BlockExpr | | -| test.rs:160:5:169:5 | enter test_nested_if_match | test.rs:160:29:160:29 | a | | -| test.rs:160:5:169:5 | exit test_nested_if_match (normal) | test.rs:160:5:169:5 | exit test_nested_if_match | | -| test.rs:160:29:160:29 | a | test.rs:160:29:160:34 | Param | match | -| test.rs:160:29:160:34 | Param | test.rs:161:19:161:19 | a | | -| test.rs:160:44:169:5 | BlockExpr | test.rs:160:5:169:5 | exit test_nested_if_match (normal) | | -| test.rs:161:9:168:9 | IfExpr | test.rs:160:44:169:5 | BlockExpr | | -| test.rs:161:13:164:9 | [boolean(false)] MatchExpr | test.rs:167:13:167:13 | 0 | false | -| test.rs:161:13:164:9 | [boolean(true)] MatchExpr | test.rs:165:13:165:13 | 1 | true | +| test.rs:153:51:155:9 | { ... } | test.rs:153:9:157:9 | if ... { ... } else { ... } | | +| test.rs:154:13:154:13 | 1 | test.rs:153:51:155:9 | { ... } | | +| test.rs:155:16:157:9 | { ... } | test.rs:153:9:157:9 | if ... { ... } else { ... } | | +| test.rs:156:13:156:13 | 0 | test.rs:155:16:157:9 | { ... } | | +| test.rs:160:5:169:5 | enter fn test_nested_if_match | test.rs:160:29:160:29 | a | | +| test.rs:160:5:169:5 | exit fn test_nested_if_match (normal) | test.rs:160:5:169:5 | exit fn test_nested_if_match | | +| test.rs:160:29:160:29 | a | test.rs:160:29:160:34 | a: i64 | match | +| test.rs:160:29:160:34 | a: i64 | test.rs:161:19:161:19 | a | | +| test.rs:160:44:169:5 | { ... } | test.rs:160:5:169:5 | exit fn test_nested_if_match (normal) | | +| test.rs:161:9:168:9 | if ... { ... } else { ... } | test.rs:160:44:169:5 | { ... } | | +| test.rs:161:13:164:9 | [boolean(false)] match ... { ... } | test.rs:167:13:167:13 | 0 | false | +| test.rs:161:13:164:9 | [boolean(true)] match ... { ... } | test.rs:165:13:165:13 | 1 | true | | test.rs:161:19:161:19 | a | test.rs:162:13:162:13 | 0 | | -| test.rs:162:13:162:13 | 0 | test.rs:162:13:162:13 | LiteralPat | | -| test.rs:162:13:162:13 | LiteralPat | test.rs:162:18:162:21 | true | match | -| test.rs:162:13:162:13 | LiteralPat | test.rs:163:13:163:13 | WildcardPat | no-match | -| test.rs:162:18:162:21 | true | test.rs:161:13:164:9 | [boolean(true)] MatchExpr | true | -| test.rs:163:13:163:13 | WildcardPat | test.rs:163:18:163:22 | false | match | -| test.rs:163:18:163:22 | false | test.rs:161:13:164:9 | [boolean(false)] MatchExpr | false | -| test.rs:164:12:166:9 | BlockExpr | test.rs:161:9:168:9 | IfExpr | | -| test.rs:165:13:165:13 | 1 | test.rs:164:12:166:9 | BlockExpr | | -| test.rs:166:16:168:9 | BlockExpr | test.rs:161:9:168:9 | IfExpr | | -| test.rs:167:13:167:13 | 0 | test.rs:166:16:168:9 | BlockExpr | | -| test.rs:171:5:180:5 | enter test_nested_if_block | test.rs:171:29:171:29 | a | | -| test.rs:171:5:180:5 | exit test_nested_if_block (normal) | test.rs:171:5:180:5 | exit test_nested_if_block | | -| test.rs:171:29:171:29 | a | test.rs:171:29:171:34 | Param | match | -| test.rs:171:29:171:34 | Param | test.rs:173:13:173:15 | ExprStmt | | -| test.rs:171:44:180:5 | BlockExpr | test.rs:171:5:180:5 | exit test_nested_if_block (normal) | | -| test.rs:172:9:179:9 | IfExpr | test.rs:171:44:180:5 | BlockExpr | | -| test.rs:172:12:175:9 | [boolean(false)] BlockExpr | test.rs:178:13:178:13 | 0 | false | -| test.rs:172:12:175:9 | [boolean(true)] BlockExpr | test.rs:176:13:176:13 | 1 | true | +| test.rs:162:13:162:13 | 0 | test.rs:162:13:162:13 | 0 | | +| test.rs:162:13:162:13 | 0 | test.rs:162:18:162:21 | true | match | +| test.rs:162:13:162:13 | 0 | test.rs:163:13:163:13 | _ | no-match | +| test.rs:162:18:162:21 | true | test.rs:161:13:164:9 | [boolean(true)] match ... { ... } | true | +| test.rs:163:13:163:13 | _ | test.rs:163:18:163:22 | false | match | +| test.rs:163:18:163:22 | false | test.rs:161:13:164:9 | [boolean(false)] match ... { ... } | false | +| test.rs:164:12:166:9 | { ... } | test.rs:161:9:168:9 | if ... { ... } else { ... } | | +| test.rs:165:13:165:13 | 1 | test.rs:164:12:166:9 | { ... } | | +| test.rs:166:16:168:9 | { ... } | test.rs:161:9:168:9 | if ... { ... } else { ... } | | +| test.rs:167:13:167:13 | 0 | test.rs:166:16:168:9 | { ... } | | +| test.rs:171:5:180:5 | enter fn test_nested_if_block | test.rs:171:29:171:29 | a | | +| test.rs:171:5:180:5 | exit fn test_nested_if_block (normal) | test.rs:171:5:180:5 | exit fn test_nested_if_block | | +| test.rs:171:29:171:29 | a | test.rs:171:29:171:34 | a: i64 | match | +| test.rs:171:29:171:34 | a: i64 | test.rs:173:13:173:15 | ExprStmt | | +| test.rs:171:44:180:5 | { ... } | test.rs:171:5:180:5 | exit fn test_nested_if_block (normal) | | +| test.rs:172:9:179:9 | if ... { ... } else { ... } | test.rs:171:44:180:5 | { ... } | | +| test.rs:172:12:175:9 | [boolean(false)] { ... } | test.rs:178:13:178:13 | 0 | false | +| test.rs:172:12:175:9 | [boolean(true)] { ... } | test.rs:176:13:176:13 | 1 | true | | test.rs:173:13:173:14 | TupleExpr | test.rs:174:13:174:13 | a | | | test.rs:173:13:173:15 | ExprStmt | test.rs:173:13:173:14 | TupleExpr | | | test.rs:174:13:174:13 | a | test.rs:174:17:174:17 | 0 | | -| test.rs:174:13:174:17 | ... > ... | test.rs:172:12:175:9 | [boolean(false)] BlockExpr | false | -| test.rs:174:13:174:17 | ... > ... | test.rs:172:12:175:9 | [boolean(true)] BlockExpr | true | +| test.rs:174:13:174:17 | ... > ... | test.rs:172:12:175:9 | [boolean(false)] { ... } | false | +| test.rs:174:13:174:17 | ... > ... | test.rs:172:12:175:9 | [boolean(true)] { ... } | true | | test.rs:174:17:174:17 | 0 | test.rs:174:13:174:17 | ... > ... | | -| test.rs:175:11:177:9 | BlockExpr | test.rs:172:9:179:9 | IfExpr | | -| test.rs:176:13:176:13 | 1 | test.rs:175:11:177:9 | BlockExpr | | -| test.rs:177:16:179:9 | BlockExpr | test.rs:172:9:179:9 | IfExpr | | -| test.rs:178:13:178:13 | 0 | test.rs:177:16:179:9 | BlockExpr | | -| test.rs:182:5:192:5 | enter test_if_assignment | test.rs:182:27:182:27 | a | | -| test.rs:182:5:192:5 | exit test_if_assignment (normal) | test.rs:182:5:192:5 | exit test_if_assignment | | -| test.rs:182:27:182:27 | a | test.rs:182:27:182:32 | Param | match | -| test.rs:182:27:182:32 | Param | test.rs:183:9:183:26 | LetStmt | | -| test.rs:182:42:192:5 | BlockExpr | test.rs:182:5:192:5 | exit test_if_assignment (normal) | | -| test.rs:183:9:183:26 | LetStmt | test.rs:183:21:183:25 | false | | +| test.rs:175:11:177:9 | { ... } | test.rs:172:9:179:9 | if ... { ... } else { ... } | | +| test.rs:176:13:176:13 | 1 | test.rs:175:11:177:9 | { ... } | | +| test.rs:177:16:179:9 | { ... } | test.rs:172:9:179:9 | if ... { ... } else { ... } | | +| test.rs:178:13:178:13 | 0 | test.rs:177:16:179:9 | { ... } | | +| test.rs:182:5:192:5 | enter fn test_if_assignment | test.rs:182:27:182:27 | a | | +| test.rs:182:5:192:5 | exit fn test_if_assignment (normal) | test.rs:182:5:192:5 | exit fn test_if_assignment | | +| test.rs:182:27:182:27 | a | test.rs:182:27:182:32 | a: i64 | match | +| test.rs:182:27:182:32 | a: i64 | test.rs:183:9:183:26 | let x = ... | | +| test.rs:182:42:192:5 | { ... } | test.rs:182:5:192:5 | exit fn test_if_assignment (normal) | | +| test.rs:183:9:183:26 | let x = ... | test.rs:183:21:183:25 | false | | | test.rs:183:13:183:17 | x | test.rs:185:13:185:21 | ExprStmt | match | | test.rs:183:21:183:25 | false | test.rs:183:13:183:17 | x | | -| test.rs:184:9:191:9 | IfExpr | test.rs:182:42:192:5 | BlockExpr | | -| test.rs:184:12:187:9 | [boolean(false)] BlockExpr | test.rs:190:13:190:13 | 0 | false | -| test.rs:184:12:187:9 | [boolean(true)] BlockExpr | test.rs:188:13:188:13 | 1 | true | +| test.rs:184:9:191:9 | if ... { ... } else { ... } | test.rs:182:42:192:5 | { ... } | | +| test.rs:184:12:187:9 | [boolean(false)] { ... } | test.rs:190:13:190:13 | 0 | false | +| test.rs:184:12:187:9 | [boolean(true)] { ... } | test.rs:188:13:188:13 | 1 | true | | test.rs:185:13:185:13 | x | test.rs:185:17:185:20 | true | | | test.rs:185:13:185:20 | ... = ... | test.rs:186:13:186:13 | x | | | test.rs:185:13:185:21 | ExprStmt | test.rs:185:13:185:13 | x | | | test.rs:185:17:185:20 | true | test.rs:185:13:185:20 | ... = ... | | -| test.rs:186:13:186:13 | x | test.rs:184:12:187:9 | [boolean(false)] BlockExpr | false | -| test.rs:186:13:186:13 | x | test.rs:184:12:187:9 | [boolean(true)] BlockExpr | true | -| test.rs:187:11:189:9 | BlockExpr | test.rs:184:9:191:9 | IfExpr | | -| test.rs:188:13:188:13 | 1 | test.rs:187:11:189:9 | BlockExpr | | -| test.rs:189:16:191:9 | BlockExpr | test.rs:184:9:191:9 | IfExpr | | -| test.rs:190:13:190:13 | 0 | test.rs:189:16:191:9 | BlockExpr | | -| test.rs:194:5:205:5 | enter test_if_loop1 | test.rs:194:22:194:22 | a | | -| test.rs:194:5:205:5 | exit test_if_loop1 (normal) | test.rs:194:5:205:5 | exit test_if_loop1 | | -| test.rs:194:22:194:22 | a | test.rs:194:22:194:27 | Param | match | -| test.rs:194:22:194:27 | Param | test.rs:196:13:198:14 | ExprStmt | | -| test.rs:194:37:205:5 | BlockExpr | test.rs:194:5:205:5 | exit test_if_loop1 (normal) | | -| test.rs:195:9:204:9 | IfExpr | test.rs:194:37:205:5 | BlockExpr | | -| test.rs:195:13:200:9 | [boolean(false)] LoopExpr | test.rs:203:13:203:13 | 0 | false | -| test.rs:195:13:200:9 | [boolean(true)] LoopExpr | test.rs:201:13:201:13 | 1 | true | -| test.rs:195:18:200:9 | BlockExpr | test.rs:196:13:198:14 | ExprStmt | | -| test.rs:196:13:198:13 | IfExpr | test.rs:199:13:199:19 | ExprStmt | | +| test.rs:186:13:186:13 | x | test.rs:184:12:187:9 | [boolean(false)] { ... } | false | +| test.rs:186:13:186:13 | x | test.rs:184:12:187:9 | [boolean(true)] { ... } | true | +| test.rs:187:11:189:9 | { ... } | test.rs:184:9:191:9 | if ... { ... } else { ... } | | +| test.rs:188:13:188:13 | 1 | test.rs:187:11:189:9 | { ... } | | +| test.rs:189:16:191:9 | { ... } | test.rs:184:9:191:9 | if ... { ... } else { ... } | | +| test.rs:190:13:190:13 | 0 | test.rs:189:16:191:9 | { ... } | | +| test.rs:194:5:205:5 | enter fn test_if_loop1 | test.rs:194:22:194:22 | a | | +| test.rs:194:5:205:5 | exit fn test_if_loop1 (normal) | test.rs:194:5:205:5 | exit fn test_if_loop1 | | +| test.rs:194:22:194:22 | a | test.rs:194:22:194:27 | a: i64 | match | +| test.rs:194:22:194:27 | a: i64 | test.rs:196:13:198:14 | ExprStmt | | +| test.rs:194:37:205:5 | { ... } | test.rs:194:5:205:5 | exit fn test_if_loop1 (normal) | | +| test.rs:195:9:204:9 | if ... { ... } else { ... } | test.rs:194:37:205:5 | { ... } | | +| test.rs:195:13:200:9 | [boolean(false)] loop {...} | test.rs:203:13:203:13 | 0 | false | +| test.rs:195:13:200:9 | [boolean(true)] loop {...} | test.rs:201:13:201:13 | 1 | true | +| test.rs:195:18:200:9 | { ... } | test.rs:196:13:198:14 | ExprStmt | | +| test.rs:196:13:198:13 | if ... { ... } | test.rs:199:13:199:19 | ExprStmt | | | test.rs:196:13:198:14 | ExprStmt | test.rs:196:16:196:16 | a | | | test.rs:196:16:196:16 | a | test.rs:196:20:196:20 | 0 | | -| test.rs:196:16:196:20 | ... > ... | test.rs:196:13:198:13 | IfExpr | false | +| test.rs:196:16:196:20 | ... > ... | test.rs:196:13:198:13 | if ... { ... } | false | | test.rs:196:16:196:20 | ... > ... | test.rs:197:17:197:29 | ExprStmt | true | | test.rs:196:20:196:20 | 0 | test.rs:196:16:196:20 | ... > ... | | -| test.rs:197:17:197:28 | [boolean(false)] BreakExpr | test.rs:195:13:200:9 | [boolean(false)] LoopExpr | break | -| test.rs:197:17:197:28 | [boolean(true)] BreakExpr | test.rs:195:13:200:9 | [boolean(true)] LoopExpr | break | +| test.rs:197:17:197:28 | [boolean(false)] break ... | test.rs:195:13:200:9 | [boolean(false)] loop {...} | break | +| test.rs:197:17:197:28 | [boolean(true)] break ... | test.rs:195:13:200:9 | [boolean(true)] loop {...} | break | | test.rs:197:17:197:29 | ExprStmt | test.rs:197:23:197:23 | a | | | test.rs:197:23:197:23 | a | test.rs:197:27:197:28 | 10 | | -| test.rs:197:23:197:28 | ... > ... | test.rs:197:17:197:28 | [boolean(false)] BreakExpr | false | -| test.rs:197:23:197:28 | ... > ... | test.rs:197:17:197:28 | [boolean(true)] BreakExpr | true | +| test.rs:197:23:197:28 | ... > ... | test.rs:197:17:197:28 | [boolean(false)] break ... | false | +| test.rs:197:23:197:28 | ... > ... | test.rs:197:17:197:28 | [boolean(true)] break ... | true | | test.rs:197:27:197:28 | 10 | test.rs:197:23:197:28 | ... > ... | | | test.rs:199:13:199:13 | a | test.rs:199:17:199:18 | 10 | | -| test.rs:199:13:199:18 | ... < ... | test.rs:195:18:200:9 | BlockExpr | | +| test.rs:199:13:199:18 | ... < ... | test.rs:195:18:200:9 | { ... } | | | test.rs:199:13:199:19 | ExprStmt | test.rs:199:13:199:13 | a | | | test.rs:199:17:199:18 | 10 | test.rs:199:13:199:18 | ... < ... | | -| test.rs:200:12:202:9 | BlockExpr | test.rs:195:9:204:9 | IfExpr | | -| test.rs:201:13:201:13 | 1 | test.rs:200:12:202:9 | BlockExpr | | -| test.rs:202:16:204:9 | BlockExpr | test.rs:195:9:204:9 | IfExpr | | -| test.rs:203:13:203:13 | 0 | test.rs:202:16:204:9 | BlockExpr | | -| test.rs:207:5:218:5 | enter test_if_loop2 | test.rs:207:22:207:22 | a | | -| test.rs:207:5:218:5 | exit test_if_loop2 (normal) | test.rs:207:5:218:5 | exit test_if_loop2 | | -| test.rs:207:22:207:22 | a | test.rs:207:22:207:27 | Param | match | -| test.rs:207:22:207:27 | Param | test.rs:209:13:211:14 | ExprStmt | | -| test.rs:207:37:218:5 | BlockExpr | test.rs:207:5:218:5 | exit test_if_loop2 (normal) | | -| test.rs:208:9:217:9 | IfExpr | test.rs:207:37:218:5 | BlockExpr | | -| test.rs:208:13:213:9 | [boolean(false)] LoopExpr | test.rs:216:13:216:13 | 0 | false | -| test.rs:208:13:213:9 | [boolean(true)] LoopExpr | test.rs:214:13:214:13 | 1 | true | -| test.rs:208:26:213:9 | BlockExpr | test.rs:209:13:211:14 | ExprStmt | | -| test.rs:209:13:211:13 | IfExpr | test.rs:212:13:212:19 | ExprStmt | | +| test.rs:200:12:202:9 | { ... } | test.rs:195:9:204:9 | if ... { ... } else { ... } | | +| test.rs:201:13:201:13 | 1 | test.rs:200:12:202:9 | { ... } | | +| test.rs:202:16:204:9 | { ... } | test.rs:195:9:204:9 | if ... { ... } else { ... } | | +| test.rs:203:13:203:13 | 0 | test.rs:202:16:204:9 | { ... } | | +| test.rs:207:5:218:5 | enter fn test_if_loop2 | test.rs:207:22:207:22 | a | | +| test.rs:207:5:218:5 | exit fn test_if_loop2 (normal) | test.rs:207:5:218:5 | exit fn test_if_loop2 | | +| test.rs:207:22:207:22 | a | test.rs:207:22:207:27 | a: i64 | match | +| test.rs:207:22:207:27 | a: i64 | test.rs:209:13:211:14 | ExprStmt | | +| test.rs:207:37:218:5 | { ... } | test.rs:207:5:218:5 | exit fn test_if_loop2 (normal) | | +| test.rs:208:9:217:9 | if ... { ... } else { ... } | test.rs:207:37:218:5 | { ... } | | +| test.rs:208:13:213:9 | [boolean(false)] loop {...} | test.rs:216:13:216:13 | 0 | false | +| test.rs:208:13:213:9 | [boolean(true)] loop {...} | test.rs:214:13:214:13 | 1 | true | +| test.rs:208:26:213:9 | { ... } | test.rs:209:13:211:14 | ExprStmt | | +| test.rs:209:13:211:13 | if ... { ... } | test.rs:212:13:212:19 | ExprStmt | | | test.rs:209:13:211:14 | ExprStmt | test.rs:209:16:209:16 | a | | | test.rs:209:16:209:16 | a | test.rs:209:20:209:20 | 0 | | -| test.rs:209:16:209:20 | ... > ... | test.rs:209:13:211:13 | IfExpr | false | +| test.rs:209:16:209:20 | ... > ... | test.rs:209:13:211:13 | if ... { ... } | false | | test.rs:209:16:209:20 | ... > ... | test.rs:210:17:210:36 | ExprStmt | true | | test.rs:209:20:209:20 | 0 | test.rs:209:16:209:20 | ... > ... | | -| test.rs:210:17:210:35 | [boolean(false)] BreakExpr | test.rs:208:13:213:9 | [boolean(false)] LoopExpr | break | -| test.rs:210:17:210:35 | [boolean(true)] BreakExpr | test.rs:208:13:213:9 | [boolean(true)] LoopExpr | break | +| test.rs:210:17:210:35 | [boolean(false)] break ''label ... | test.rs:208:13:213:9 | [boolean(false)] loop {...} | break | +| test.rs:210:17:210:35 | [boolean(true)] break ''label ... | test.rs:208:13:213:9 | [boolean(true)] loop {...} | break | | test.rs:210:17:210:36 | ExprStmt | test.rs:210:30:210:30 | a | | | test.rs:210:30:210:30 | a | test.rs:210:34:210:35 | 10 | | -| test.rs:210:30:210:35 | ... > ... | test.rs:210:17:210:35 | [boolean(false)] BreakExpr | false | -| test.rs:210:30:210:35 | ... > ... | test.rs:210:17:210:35 | [boolean(true)] BreakExpr | true | +| test.rs:210:30:210:35 | ... > ... | test.rs:210:17:210:35 | [boolean(false)] break ''label ... | false | +| test.rs:210:30:210:35 | ... > ... | test.rs:210:17:210:35 | [boolean(true)] break ''label ... | true | | test.rs:210:34:210:35 | 10 | test.rs:210:30:210:35 | ... > ... | | | test.rs:212:13:212:13 | a | test.rs:212:17:212:18 | 10 | | -| test.rs:212:13:212:18 | ... < ... | test.rs:208:26:213:9 | BlockExpr | | +| test.rs:212:13:212:18 | ... < ... | test.rs:208:26:213:9 | { ... } | | | test.rs:212:13:212:19 | ExprStmt | test.rs:212:13:212:13 | a | | | test.rs:212:17:212:18 | 10 | test.rs:212:13:212:18 | ... < ... | | -| test.rs:213:12:215:9 | BlockExpr | test.rs:208:9:217:9 | IfExpr | | -| test.rs:214:13:214:13 | 1 | test.rs:213:12:215:9 | BlockExpr | | -| test.rs:215:16:217:9 | BlockExpr | test.rs:208:9:217:9 | IfExpr | | -| test.rs:216:13:216:13 | 0 | test.rs:215:16:217:9 | BlockExpr | | -| test.rs:220:5:228:5 | enter test_labelled_block | test.rs:220:28:220:28 | a | | -| test.rs:220:5:228:5 | exit test_labelled_block (normal) | test.rs:220:5:228:5 | exit test_labelled_block | | -| test.rs:220:28:220:28 | a | test.rs:220:28:220:33 | Param | match | -| test.rs:220:28:220:33 | Param | test.rs:222:13:222:31 | ExprStmt | | -| test.rs:220:43:228:5 | BlockExpr | test.rs:220:5:228:5 | exit test_labelled_block (normal) | | -| test.rs:221:9:227:9 | IfExpr | test.rs:220:43:228:5 | BlockExpr | | -| test.rs:221:13:223:9 | [boolean(false)] BlockExpr | test.rs:226:13:226:13 | 0 | false | -| test.rs:221:13:223:9 | [boolean(true)] BlockExpr | test.rs:224:13:224:13 | 1 | true | -| test.rs:222:13:222:30 | [boolean(false)] BreakExpr | test.rs:221:13:223:9 | [boolean(false)] BlockExpr | break | -| test.rs:222:13:222:30 | [boolean(true)] BreakExpr | test.rs:221:13:223:9 | [boolean(true)] BlockExpr | break | +| test.rs:213:12:215:9 | { ... } | test.rs:208:9:217:9 | if ... { ... } else { ... } | | +| test.rs:214:13:214:13 | 1 | test.rs:213:12:215:9 | { ... } | | +| test.rs:215:16:217:9 | { ... } | test.rs:208:9:217:9 | if ... { ... } else { ... } | | +| test.rs:216:13:216:13 | 0 | test.rs:215:16:217:9 | { ... } | | +| test.rs:220:5:228:5 | enter fn test_labelled_block | test.rs:220:28:220:28 | a | | +| test.rs:220:5:228:5 | exit fn test_labelled_block (normal) | test.rs:220:5:228:5 | exit fn test_labelled_block | | +| test.rs:220:28:220:28 | a | test.rs:220:28:220:33 | a: i64 | match | +| test.rs:220:28:220:33 | a: i64 | test.rs:222:13:222:31 | ExprStmt | | +| test.rs:220:43:228:5 | { ... } | test.rs:220:5:228:5 | exit fn test_labelled_block (normal) | | +| test.rs:221:9:227:9 | if ... { ... } else { ... } | test.rs:220:43:228:5 | { ... } | | +| test.rs:221:13:223:9 | [boolean(false)] { ... } | test.rs:226:13:226:13 | 0 | false | +| test.rs:221:13:223:9 | [boolean(true)] { ... } | test.rs:224:13:224:13 | 1 | true | +| test.rs:222:13:222:30 | [boolean(false)] break ''block ... | test.rs:221:13:223:9 | [boolean(false)] { ... } | break | +| test.rs:222:13:222:30 | [boolean(true)] break ''block ... | test.rs:221:13:223:9 | [boolean(true)] { ... } | break | | test.rs:222:13:222:31 | ExprStmt | test.rs:222:26:222:26 | a | | | test.rs:222:26:222:26 | a | test.rs:222:30:222:30 | 0 | | -| test.rs:222:26:222:30 | ... > ... | test.rs:222:13:222:30 | [boolean(false)] BreakExpr | false | -| test.rs:222:26:222:30 | ... > ... | test.rs:222:13:222:30 | [boolean(true)] BreakExpr | true | +| test.rs:222:26:222:30 | ... > ... | test.rs:222:13:222:30 | [boolean(false)] break ''block ... | false | +| test.rs:222:26:222:30 | ... > ... | test.rs:222:13:222:30 | [boolean(true)] break ''block ... | true | | test.rs:222:30:222:30 | 0 | test.rs:222:26:222:30 | ... > ... | | -| test.rs:223:12:225:9 | BlockExpr | test.rs:221:9:227:9 | IfExpr | | -| test.rs:224:13:224:13 | 1 | test.rs:223:12:225:9 | BlockExpr | | -| test.rs:225:16:227:9 | BlockExpr | test.rs:221:9:227:9 | IfExpr | | -| test.rs:226:13:226:13 | 0 | test.rs:225:16:227:9 | BlockExpr | | -| test.rs:233:5:236:5 | enter test_and_operator | test.rs:233:30:233:30 | a | | -| test.rs:233:5:236:5 | exit test_and_operator (normal) | test.rs:233:5:236:5 | exit test_and_operator | | -| test.rs:233:30:233:30 | a | test.rs:233:30:233:36 | Param | match | -| test.rs:233:30:233:36 | Param | test.rs:233:39:233:39 | b | | -| test.rs:233:39:233:39 | b | test.rs:233:39:233:45 | Param | match | -| test.rs:233:39:233:45 | Param | test.rs:233:48:233:48 | c | | -| test.rs:233:48:233:48 | c | test.rs:233:48:233:54 | Param | match | -| test.rs:233:48:233:54 | Param | test.rs:234:9:234:28 | LetStmt | | -| test.rs:233:65:236:5 | BlockExpr | test.rs:233:5:236:5 | exit test_and_operator (normal) | | -| test.rs:234:9:234:28 | LetStmt | test.rs:234:17:234:17 | a | | +| test.rs:223:12:225:9 | { ... } | test.rs:221:9:227:9 | if ... { ... } else { ... } | | +| test.rs:224:13:224:13 | 1 | test.rs:223:12:225:9 | { ... } | | +| test.rs:225:16:227:9 | { ... } | test.rs:221:9:227:9 | if ... { ... } else { ... } | | +| test.rs:226:13:226:13 | 0 | test.rs:225:16:227:9 | { ... } | | +| test.rs:233:5:236:5 | enter fn test_and_operator | test.rs:233:30:233:30 | a | | +| test.rs:233:5:236:5 | exit fn test_and_operator (normal) | test.rs:233:5:236:5 | exit fn test_and_operator | | +| test.rs:233:30:233:30 | a | test.rs:233:30:233:36 | a: bool | match | +| test.rs:233:30:233:36 | a: bool | test.rs:233:39:233:39 | b | | +| test.rs:233:39:233:39 | b | test.rs:233:39:233:45 | b: bool | match | +| test.rs:233:39:233:45 | b: bool | test.rs:233:48:233:48 | c | | +| test.rs:233:48:233:48 | c | test.rs:233:48:233:54 | c: bool | match | +| test.rs:233:48:233:54 | c: bool | test.rs:234:9:234:28 | let d = ... | | +| test.rs:233:65:236:5 | { ... } | test.rs:233:5:236:5 | exit fn test_and_operator (normal) | | +| test.rs:234:9:234:28 | let d = ... | test.rs:234:17:234:17 | a | | | test.rs:234:13:234:13 | d | test.rs:235:9:235:9 | d | match | | test.rs:234:17:234:17 | a | test.rs:234:17:234:22 | [boolean(false)] ... && ... | false | | test.rs:234:17:234:17 | a | test.rs:234:22:234:22 | b | true | @@ -483,17 +483,17 @@ edges | test.rs:234:22:234:22 | b | test.rs:234:17:234:22 | [boolean(false)] ... && ... | false | | test.rs:234:22:234:22 | b | test.rs:234:17:234:22 | [boolean(true)] ... && ... | true | | test.rs:234:27:234:27 | c | test.rs:234:17:234:27 | ... && ... | | -| test.rs:235:9:235:9 | d | test.rs:233:65:236:5 | BlockExpr | | -| test.rs:238:5:241:5 | enter test_or_operator | test.rs:238:25:238:25 | a | | -| test.rs:238:5:241:5 | exit test_or_operator (normal) | test.rs:238:5:241:5 | exit test_or_operator | | -| test.rs:238:25:238:25 | a | test.rs:238:25:238:31 | Param | match | -| test.rs:238:25:238:31 | Param | test.rs:238:34:238:34 | b | | -| test.rs:238:34:238:34 | b | test.rs:238:34:238:40 | Param | match | -| test.rs:238:34:238:40 | Param | test.rs:238:43:238:43 | c | | -| test.rs:238:43:238:43 | c | test.rs:238:43:238:49 | Param | match | -| test.rs:238:43:238:49 | Param | test.rs:239:9:239:28 | LetStmt | | -| test.rs:238:60:241:5 | BlockExpr | test.rs:238:5:241:5 | exit test_or_operator (normal) | | -| test.rs:239:9:239:28 | LetStmt | test.rs:239:17:239:17 | a | | +| test.rs:235:9:235:9 | d | test.rs:233:65:236:5 | { ... } | | +| test.rs:238:5:241:5 | enter fn test_or_operator | test.rs:238:25:238:25 | a | | +| test.rs:238:5:241:5 | exit fn test_or_operator (normal) | test.rs:238:5:241:5 | exit fn test_or_operator | | +| test.rs:238:25:238:25 | a | test.rs:238:25:238:31 | a: bool | match | +| test.rs:238:25:238:31 | a: bool | test.rs:238:34:238:34 | b | | +| test.rs:238:34:238:34 | b | test.rs:238:34:238:40 | b: bool | match | +| test.rs:238:34:238:40 | b: bool | test.rs:238:43:238:43 | c | | +| test.rs:238:43:238:43 | c | test.rs:238:43:238:49 | c: bool | match | +| test.rs:238:43:238:49 | c: bool | test.rs:239:9:239:28 | let d = ... | | +| test.rs:238:60:241:5 | { ... } | test.rs:238:5:241:5 | exit fn test_or_operator (normal) | | +| test.rs:239:9:239:28 | let d = ... | test.rs:239:17:239:17 | a | | | test.rs:239:13:239:13 | d | test.rs:240:9:240:9 | d | match | | test.rs:239:17:239:17 | a | test.rs:239:17:239:22 | [boolean(true)] ... \|\| ... | true | | test.rs:239:17:239:17 | a | test.rs:239:22:239:22 | b | false | @@ -503,17 +503,17 @@ edges | test.rs:239:22:239:22 | b | test.rs:239:17:239:22 | [boolean(false)] ... \|\| ... | false | | test.rs:239:22:239:22 | b | test.rs:239:17:239:22 | [boolean(true)] ... \|\| ... | true | | test.rs:239:27:239:27 | c | test.rs:239:17:239:27 | ... \|\| ... | | -| test.rs:240:9:240:9 | d | test.rs:238:60:241:5 | BlockExpr | | -| test.rs:243:5:246:5 | enter test_or_operator_2 | test.rs:243:27:243:27 | a | | -| test.rs:243:5:246:5 | exit test_or_operator_2 (normal) | test.rs:243:5:246:5 | exit test_or_operator_2 | | -| test.rs:243:27:243:27 | a | test.rs:243:27:243:33 | Param | match | -| test.rs:243:27:243:33 | Param | test.rs:243:36:243:36 | b | | -| test.rs:243:36:243:36 | b | test.rs:243:36:243:41 | Param | match | -| test.rs:243:36:243:41 | Param | test.rs:243:44:243:44 | c | | -| test.rs:243:44:243:44 | c | test.rs:243:44:243:50 | Param | match | -| test.rs:243:44:243:50 | Param | test.rs:244:9:244:36 | LetStmt | | -| test.rs:243:61:246:5 | BlockExpr | test.rs:243:5:246:5 | exit test_or_operator_2 (normal) | | -| test.rs:244:9:244:36 | LetStmt | test.rs:244:17:244:17 | a | | +| test.rs:240:9:240:9 | d | test.rs:238:60:241:5 | { ... } | | +| test.rs:243:5:246:5 | enter fn test_or_operator_2 | test.rs:243:27:243:27 | a | | +| test.rs:243:5:246:5 | exit fn test_or_operator_2 (normal) | test.rs:243:5:246:5 | exit fn test_or_operator_2 | | +| test.rs:243:27:243:27 | a | test.rs:243:27:243:33 | a: bool | match | +| test.rs:243:27:243:33 | a: bool | test.rs:243:36:243:36 | b | | +| test.rs:243:36:243:36 | b | test.rs:243:36:243:41 | b: i64 | match | +| test.rs:243:36:243:41 | b: i64 | test.rs:243:44:243:44 | c | | +| test.rs:243:44:243:44 | c | test.rs:243:44:243:50 | c: bool | match | +| test.rs:243:44:243:50 | c: bool | test.rs:244:9:244:36 | let d = ... | | +| test.rs:243:61:246:5 | { ... } | test.rs:243:5:246:5 | exit fn test_or_operator_2 (normal) | | +| test.rs:244:9:244:36 | let d = ... | test.rs:244:17:244:17 | a | | | test.rs:244:13:244:13 | d | test.rs:245:9:245:9 | d | match | | test.rs:244:17:244:17 | a | test.rs:244:17:244:30 | [boolean(true)] ... \|\| ... | true | | test.rs:244:17:244:17 | a | test.rs:244:23:244:23 | b | false | @@ -525,27 +525,27 @@ edges | test.rs:244:23:244:29 | ... == ... | test.rs:244:17:244:30 | [boolean(true)] ... \|\| ... | true | | test.rs:244:28:244:29 | 28 | test.rs:244:23:244:29 | ... == ... | | | test.rs:244:35:244:35 | c | test.rs:244:17:244:35 | ... \|\| ... | | -| test.rs:245:9:245:9 | d | test.rs:243:61:246:5 | BlockExpr | | -| test.rs:248:5:251:5 | enter test_not_operator | test.rs:248:26:248:26 | a | | -| test.rs:248:5:251:5 | exit test_not_operator (normal) | test.rs:248:5:251:5 | exit test_not_operator | | -| test.rs:248:26:248:26 | a | test.rs:248:26:248:32 | Param | match | -| test.rs:248:26:248:32 | Param | test.rs:249:9:249:19 | LetStmt | | -| test.rs:248:43:251:5 | BlockExpr | test.rs:248:5:251:5 | exit test_not_operator (normal) | | -| test.rs:249:9:249:19 | LetStmt | test.rs:249:18:249:18 | a | | +| test.rs:245:9:245:9 | d | test.rs:243:61:246:5 | { ... } | | +| test.rs:248:5:251:5 | enter fn test_not_operator | test.rs:248:26:248:26 | a | | +| test.rs:248:5:251:5 | exit fn test_not_operator (normal) | test.rs:248:5:251:5 | exit fn test_not_operator | | +| test.rs:248:26:248:26 | a | test.rs:248:26:248:32 | a: bool | match | +| test.rs:248:26:248:32 | a: bool | test.rs:249:9:249:19 | let d = ... | | +| test.rs:248:43:251:5 | { ... } | test.rs:248:5:251:5 | exit fn test_not_operator (normal) | | +| test.rs:249:9:249:19 | let d = ... | test.rs:249:18:249:18 | a | | | test.rs:249:13:249:13 | d | test.rs:250:9:250:9 | d | match | | test.rs:249:17:249:18 | ! ... | test.rs:249:13:249:13 | d | | | test.rs:249:18:249:18 | a | test.rs:249:17:249:18 | ! ... | | -| test.rs:250:9:250:9 | d | test.rs:248:43:251:5 | BlockExpr | | -| test.rs:253:5:259:5 | enter test_if_and_operator | test.rs:253:29:253:29 | a | | -| test.rs:253:5:259:5 | exit test_if_and_operator (normal) | test.rs:253:5:259:5 | exit test_if_and_operator | | -| test.rs:253:29:253:29 | a | test.rs:253:29:253:35 | Param | match | -| test.rs:253:29:253:35 | Param | test.rs:253:38:253:38 | b | | -| test.rs:253:38:253:38 | b | test.rs:253:38:253:44 | Param | match | -| test.rs:253:38:253:44 | Param | test.rs:253:47:253:47 | c | | -| test.rs:253:47:253:47 | c | test.rs:253:47:253:53 | Param | match | -| test.rs:253:47:253:53 | Param | test.rs:254:12:254:12 | a | | -| test.rs:253:64:259:5 | BlockExpr | test.rs:253:5:259:5 | exit test_if_and_operator (normal) | | -| test.rs:254:9:258:9 | IfExpr | test.rs:253:64:259:5 | BlockExpr | | +| test.rs:250:9:250:9 | d | test.rs:248:43:251:5 | { ... } | | +| test.rs:253:5:259:5 | enter fn test_if_and_operator | test.rs:253:29:253:29 | a | | +| test.rs:253:5:259:5 | exit fn test_if_and_operator (normal) | test.rs:253:5:259:5 | exit fn test_if_and_operator | | +| test.rs:253:29:253:29 | a | test.rs:253:29:253:35 | a: bool | match | +| test.rs:253:29:253:35 | a: bool | test.rs:253:38:253:38 | b | | +| test.rs:253:38:253:38 | b | test.rs:253:38:253:44 | b: bool | match | +| test.rs:253:38:253:44 | b: bool | test.rs:253:47:253:47 | c | | +| test.rs:253:47:253:47 | c | test.rs:253:47:253:53 | c: bool | match | +| test.rs:253:47:253:53 | c: bool | test.rs:254:12:254:12 | a | | +| test.rs:253:64:259:5 | { ... } | test.rs:253:5:259:5 | exit fn test_if_and_operator (normal) | | +| test.rs:254:9:258:9 | if ... { ... } else { ... } | test.rs:253:64:259:5 | { ... } | | | test.rs:254:12:254:12 | a | test.rs:254:12:254:17 | [boolean(false)] ... && ... | false | | test.rs:254:12:254:12 | a | test.rs:254:17:254:17 | b | true | | test.rs:254:12:254:17 | [boolean(false)] ... && ... | test.rs:254:12:254:22 | [boolean(false)] ... && ... | false | @@ -556,20 +556,20 @@ edges | test.rs:254:17:254:17 | b | test.rs:254:12:254:17 | [boolean(true)] ... && ... | true | | test.rs:254:22:254:22 | c | test.rs:254:12:254:22 | [boolean(false)] ... && ... | false | | test.rs:254:22:254:22 | c | test.rs:254:12:254:22 | [boolean(true)] ... && ... | true | -| test.rs:254:24:256:9 | BlockExpr | test.rs:254:9:258:9 | IfExpr | | -| test.rs:255:13:255:16 | true | test.rs:254:24:256:9 | BlockExpr | | -| test.rs:256:16:258:9 | BlockExpr | test.rs:254:9:258:9 | IfExpr | | -| test.rs:257:13:257:17 | false | test.rs:256:16:258:9 | BlockExpr | | -| test.rs:261:5:267:5 | enter test_if_or_operator | test.rs:261:28:261:28 | a | | -| test.rs:261:5:267:5 | exit test_if_or_operator (normal) | test.rs:261:5:267:5 | exit test_if_or_operator | | -| test.rs:261:28:261:28 | a | test.rs:261:28:261:34 | Param | match | -| test.rs:261:28:261:34 | Param | test.rs:261:37:261:37 | b | | -| test.rs:261:37:261:37 | b | test.rs:261:37:261:43 | Param | match | -| test.rs:261:37:261:43 | Param | test.rs:261:46:261:46 | c | | -| test.rs:261:46:261:46 | c | test.rs:261:46:261:52 | Param | match | -| test.rs:261:46:261:52 | Param | test.rs:262:12:262:12 | a | | -| test.rs:261:63:267:5 | BlockExpr | test.rs:261:5:267:5 | exit test_if_or_operator (normal) | | -| test.rs:262:9:266:9 | IfExpr | test.rs:261:63:267:5 | BlockExpr | | +| test.rs:254:24:256:9 | { ... } | test.rs:254:9:258:9 | if ... { ... } else { ... } | | +| test.rs:255:13:255:16 | true | test.rs:254:24:256:9 | { ... } | | +| test.rs:256:16:258:9 | { ... } | test.rs:254:9:258:9 | if ... { ... } else { ... } | | +| test.rs:257:13:257:17 | false | test.rs:256:16:258:9 | { ... } | | +| test.rs:261:5:267:5 | enter fn test_if_or_operator | test.rs:261:28:261:28 | a | | +| test.rs:261:5:267:5 | exit fn test_if_or_operator (normal) | test.rs:261:5:267:5 | exit fn test_if_or_operator | | +| test.rs:261:28:261:28 | a | test.rs:261:28:261:34 | a: bool | match | +| test.rs:261:28:261:34 | a: bool | test.rs:261:37:261:37 | b | | +| test.rs:261:37:261:37 | b | test.rs:261:37:261:43 | b: bool | match | +| test.rs:261:37:261:43 | b: bool | test.rs:261:46:261:46 | c | | +| test.rs:261:46:261:46 | c | test.rs:261:46:261:52 | c: bool | match | +| test.rs:261:46:261:52 | c: bool | test.rs:262:12:262:12 | a | | +| test.rs:261:63:267:5 | { ... } | test.rs:261:5:267:5 | exit fn test_if_or_operator (normal) | | +| test.rs:262:9:266:9 | if ... { ... } else { ... } | test.rs:261:63:267:5 | { ... } | | | test.rs:262:12:262:12 | a | test.rs:262:12:262:17 | [boolean(true)] ... \|\| ... | true | | test.rs:262:12:262:12 | a | test.rs:262:17:262:17 | b | false | | test.rs:262:12:262:17 | [boolean(false)] ... \|\| ... | test.rs:262:22:262:22 | c | false | @@ -580,73 +580,73 @@ edges | test.rs:262:17:262:17 | b | test.rs:262:12:262:17 | [boolean(true)] ... \|\| ... | true | | test.rs:262:22:262:22 | c | test.rs:262:12:262:22 | [boolean(false)] ... \|\| ... | false | | test.rs:262:22:262:22 | c | test.rs:262:12:262:22 | [boolean(true)] ... \|\| ... | true | -| test.rs:262:24:264:9 | BlockExpr | test.rs:262:9:266:9 | IfExpr | | -| test.rs:263:13:263:16 | true | test.rs:262:24:264:9 | BlockExpr | | -| test.rs:264:16:266:9 | BlockExpr | test.rs:262:9:266:9 | IfExpr | | -| test.rs:265:13:265:17 | false | test.rs:264:16:266:9 | BlockExpr | | -| test.rs:269:5:275:5 | enter test_if_not_operator | test.rs:269:29:269:29 | a | | -| test.rs:269:5:275:5 | exit test_if_not_operator (normal) | test.rs:269:5:275:5 | exit test_if_not_operator | | -| test.rs:269:29:269:29 | a | test.rs:269:29:269:35 | Param | match | -| test.rs:269:29:269:35 | Param | test.rs:270:13:270:13 | a | | -| test.rs:269:46:275:5 | BlockExpr | test.rs:269:5:275:5 | exit test_if_not_operator (normal) | | -| test.rs:270:9:274:9 | IfExpr | test.rs:269:46:275:5 | BlockExpr | | +| test.rs:262:24:264:9 | { ... } | test.rs:262:9:266:9 | if ... { ... } else { ... } | | +| test.rs:263:13:263:16 | true | test.rs:262:24:264:9 | { ... } | | +| test.rs:264:16:266:9 | { ... } | test.rs:262:9:266:9 | if ... { ... } else { ... } | | +| test.rs:265:13:265:17 | false | test.rs:264:16:266:9 | { ... } | | +| test.rs:269:5:275:5 | enter fn test_if_not_operator | test.rs:269:29:269:29 | a | | +| test.rs:269:5:275:5 | exit fn test_if_not_operator (normal) | test.rs:269:5:275:5 | exit fn test_if_not_operator | | +| test.rs:269:29:269:29 | a | test.rs:269:29:269:35 | a: bool | match | +| test.rs:269:29:269:35 | a: bool | test.rs:270:13:270:13 | a | | +| test.rs:269:46:275:5 | { ... } | test.rs:269:5:275:5 | exit fn test_if_not_operator (normal) | | +| test.rs:270:9:274:9 | if ... { ... } else { ... } | test.rs:269:46:275:5 | { ... } | | | test.rs:270:12:270:13 | [boolean(false)] ! ... | test.rs:273:13:273:17 | false | false | | test.rs:270:12:270:13 | [boolean(true)] ! ... | test.rs:271:13:271:16 | true | true | | test.rs:270:13:270:13 | a | test.rs:270:12:270:13 | [boolean(false)] ! ... | true | | test.rs:270:13:270:13 | a | test.rs:270:12:270:13 | [boolean(true)] ! ... | false | -| test.rs:270:15:272:9 | BlockExpr | test.rs:270:9:274:9 | IfExpr | | -| test.rs:271:13:271:16 | true | test.rs:270:15:272:9 | BlockExpr | | -| test.rs:272:16:274:9 | BlockExpr | test.rs:270:9:274:9 | IfExpr | | -| test.rs:273:13:273:17 | false | test.rs:272:16:274:9 | BlockExpr | | -| test.rs:277:5:279:5 | enter test_and_return | test.rs:277:24:277:24 | a | | -| test.rs:277:5:279:5 | exit test_and_return (normal) | test.rs:277:5:279:5 | exit test_and_return | | -| test.rs:277:24:277:24 | a | test.rs:277:24:277:30 | Param | match | -| test.rs:277:24:277:30 | Param | test.rs:278:9:278:20 | ExprStmt | | -| test.rs:277:33:279:5 | BlockExpr | test.rs:277:5:279:5 | exit test_and_return (normal) | | +| test.rs:270:15:272:9 | { ... } | test.rs:270:9:274:9 | if ... { ... } else { ... } | | +| test.rs:271:13:271:16 | true | test.rs:270:15:272:9 | { ... } | | +| test.rs:272:16:274:9 | { ... } | test.rs:270:9:274:9 | if ... { ... } else { ... } | | +| test.rs:273:13:273:17 | false | test.rs:272:16:274:9 | { ... } | | +| test.rs:277:5:279:5 | enter fn test_and_return | test.rs:277:24:277:24 | a | | +| test.rs:277:5:279:5 | exit fn test_and_return (normal) | test.rs:277:5:279:5 | exit fn test_and_return | | +| test.rs:277:24:277:24 | a | test.rs:277:24:277:30 | a: bool | match | +| test.rs:277:24:277:30 | a: bool | test.rs:278:9:278:20 | ExprStmt | | +| test.rs:277:33:279:5 | { ... } | test.rs:277:5:279:5 | exit fn test_and_return (normal) | | | test.rs:278:9:278:9 | a | test.rs:278:9:278:19 | ... && ... | false | -| test.rs:278:9:278:9 | a | test.rs:278:14:278:19 | ReturnExpr | true | -| test.rs:278:9:278:19 | ... && ... | test.rs:277:33:279:5 | BlockExpr | | +| test.rs:278:9:278:9 | a | test.rs:278:14:278:19 | return | true | +| test.rs:278:9:278:19 | ... && ... | test.rs:277:33:279:5 | { ... } | | | test.rs:278:9:278:20 | ExprStmt | test.rs:278:9:278:9 | a | | -| test.rs:278:14:278:19 | ReturnExpr | test.rs:277:5:279:5 | exit test_and_return (normal) | return | -| test.rs:285:5:287:5 | enter test_question_mark_operator_1 | test.rs:285:38:285:38 | s | | -| test.rs:285:5:287:5 | exit test_question_mark_operator_1 (normal) | test.rs:285:5:287:5 | exit test_question_mark_operator_1 | | -| test.rs:285:38:285:38 | s | test.rs:285:38:285:44 | Param | match | -| test.rs:285:38:285:44 | Param | test.rs:286:9:286:10 | Ok | | -| test.rs:285:87:287:5 | BlockExpr | test.rs:285:5:287:5 | exit test_question_mark_operator_1 (normal) | | +| test.rs:278:14:278:19 | return | test.rs:277:5:279:5 | exit fn test_and_return (normal) | return | +| test.rs:285:5:287:5 | enter fn test_question_mark_operator_1 | test.rs:285:38:285:38 | s | | +| test.rs:285:5:287:5 | exit fn test_question_mark_operator_1 (normal) | test.rs:285:5:287:5 | exit fn test_question_mark_operator_1 | | +| test.rs:285:38:285:38 | s | test.rs:285:38:285:44 | s: RefType | match | +| test.rs:285:38:285:44 | s: RefType | test.rs:286:9:286:10 | Ok | | +| test.rs:285:87:287:5 | { ... } | test.rs:285:5:287:5 | exit fn test_question_mark_operator_1 (normal) | | | test.rs:286:9:286:10 | Ok | test.rs:286:12:286:12 | s | | -| test.rs:286:9:286:33 | CallExpr | test.rs:285:87:287:5 | BlockExpr | | +| test.rs:286:9:286:33 | Ok(...) | test.rs:285:87:287:5 | { ... } | | | test.rs:286:12:286:12 | s | test.rs:286:12:286:27 | ... .parse(...) | | | test.rs:286:12:286:27 | ... .parse(...) | test.rs:286:12:286:28 | TryExpr | | -| test.rs:286:12:286:28 | TryExpr | test.rs:285:5:287:5 | exit test_question_mark_operator_1 (normal) | return | +| test.rs:286:12:286:28 | TryExpr | test.rs:285:5:287:5 | exit fn test_question_mark_operator_1 (normal) | return | | test.rs:286:12:286:28 | TryExpr | test.rs:286:32:286:32 | 4 | match | -| test.rs:286:12:286:32 | ... + ... | test.rs:286:9:286:33 | CallExpr | | +| test.rs:286:12:286:32 | ... + ... | test.rs:286:9:286:33 | Ok(...) | | | test.rs:286:32:286:32 | 4 | test.rs:286:12:286:32 | ... + ... | | -| test.rs:289:5:294:5 | enter test_question_mark_operator_2 | test.rs:289:38:289:38 | b | | -| test.rs:289:5:294:5 | exit test_question_mark_operator_2 (normal) | test.rs:289:5:294:5 | exit test_question_mark_operator_2 | | -| test.rs:289:38:289:38 | b | test.rs:289:38:289:52 | Param | match | -| test.rs:289:38:289:52 | Param | test.rs:290:15:290:15 | b | | -| test.rs:289:71:294:5 | BlockExpr | test.rs:289:5:294:5 | exit test_question_mark_operator_2 (normal) | | -| test.rs:290:9:293:9 | MatchExpr | test.rs:289:71:294:5 | BlockExpr | | +| test.rs:289:5:294:5 | enter fn test_question_mark_operator_2 | test.rs:289:38:289:38 | b | | +| test.rs:289:5:294:5 | exit fn test_question_mark_operator_2 (normal) | test.rs:289:5:294:5 | exit fn test_question_mark_operator_2 | | +| test.rs:289:38:289:38 | b | test.rs:289:38:289:52 | b: Option::<...> | match | +| test.rs:289:38:289:52 | b: Option::<...> | test.rs:290:15:290:15 | b | | +| test.rs:289:71:294:5 | { ... } | test.rs:289:5:294:5 | exit fn test_question_mark_operator_2 (normal) | | +| test.rs:290:9:293:9 | match ... { ... } | test.rs:289:71:294:5 | { ... } | | | test.rs:290:15:290:15 | b | test.rs:290:15:290:16 | TryExpr | | -| test.rs:290:15:290:16 | TryExpr | test.rs:289:5:294:5 | exit test_question_mark_operator_2 (normal) | return | +| test.rs:290:15:290:16 | TryExpr | test.rs:289:5:294:5 | exit fn test_question_mark_operator_2 (normal) | return | | test.rs:290:15:290:16 | TryExpr | test.rs:291:13:291:16 | true | match | -| test.rs:291:13:291:16 | LiteralPat | test.rs:291:21:291:24 | Some | match | -| test.rs:291:13:291:16 | LiteralPat | test.rs:292:13:292:17 | false | no-match | -| test.rs:291:13:291:16 | true | test.rs:291:13:291:16 | LiteralPat | | +| test.rs:291:13:291:16 | true | test.rs:291:13:291:16 | true | | +| test.rs:291:13:291:16 | true | test.rs:291:21:291:24 | Some | match | +| test.rs:291:13:291:16 | true | test.rs:292:13:292:17 | false | no-match | | test.rs:291:21:291:24 | Some | test.rs:291:26:291:30 | false | | -| test.rs:291:21:291:31 | CallExpr | test.rs:290:9:293:9 | MatchExpr | | -| test.rs:291:26:291:30 | false | test.rs:291:21:291:31 | CallExpr | | -| test.rs:292:13:292:17 | LiteralPat | test.rs:292:22:292:25 | Some | match | -| test.rs:292:13:292:17 | false | test.rs:292:13:292:17 | LiteralPat | | +| test.rs:291:21:291:31 | Some(...) | test.rs:290:9:293:9 | match ... { ... } | | +| test.rs:291:26:291:30 | false | test.rs:291:21:291:31 | Some(...) | | +| test.rs:292:13:292:17 | false | test.rs:292:13:292:17 | false | | +| test.rs:292:13:292:17 | false | test.rs:292:22:292:25 | Some | match | | test.rs:292:22:292:25 | Some | test.rs:292:27:292:30 | true | | -| test.rs:292:22:292:31 | CallExpr | test.rs:290:9:293:9 | MatchExpr | | -| test.rs:292:27:292:30 | true | test.rs:292:22:292:31 | CallExpr | | -| test.rs:300:5:306:5 | enter test_match | test.rs:300:19:300:29 | maybe_digit | | -| test.rs:300:5:306:5 | exit test_match (normal) | test.rs:300:5:306:5 | exit test_match | | -| test.rs:300:19:300:29 | maybe_digit | test.rs:300:19:300:42 | Param | match | -| test.rs:300:19:300:42 | Param | test.rs:301:15:301:25 | maybe_digit | | -| test.rs:300:52:306:5 | BlockExpr | test.rs:300:5:306:5 | exit test_match (normal) | | -| test.rs:301:9:305:9 | MatchExpr | test.rs:300:52:306:5 | BlockExpr | | +| test.rs:292:22:292:31 | Some(...) | test.rs:290:9:293:9 | match ... { ... } | | +| test.rs:292:27:292:30 | true | test.rs:292:22:292:31 | Some(...) | | +| test.rs:300:5:306:5 | enter fn test_match | test.rs:300:19:300:29 | maybe_digit | | +| test.rs:300:5:306:5 | exit fn test_match (normal) | test.rs:300:5:306:5 | exit fn test_match | | +| test.rs:300:19:300:29 | maybe_digit | test.rs:300:19:300:42 | maybe_digit: Option::<...> | match | +| test.rs:300:19:300:42 | maybe_digit: Option::<...> | test.rs:301:15:301:25 | maybe_digit | | +| test.rs:300:52:306:5 | { ... } | test.rs:300:5:306:5 | exit fn test_match (normal) | | +| test.rs:301:9:305:9 | match ... { ... } | test.rs:300:52:306:5 | { ... } | | | test.rs:301:15:301:25 | maybe_digit | test.rs:302:13:302:27 | TupleStructPat | | | test.rs:302:13:302:27 | TupleStructPat | test.rs:302:26:302:26 | x | match | | test.rs:302:13:302:27 | TupleStructPat | test.rs:303:13:303:27 | TupleStructPat | no-match | @@ -656,414 +656,414 @@ edges | test.rs:302:32:302:37 | ... < ... | test.rs:303:13:303:27 | TupleStructPat | false | | test.rs:302:36:302:37 | 10 | test.rs:302:32:302:37 | ... < ... | | | test.rs:302:42:302:42 | x | test.rs:302:46:302:46 | 5 | | -| test.rs:302:42:302:46 | ... + ... | test.rs:301:9:305:9 | MatchExpr | | +| test.rs:302:42:302:46 | ... + ... | test.rs:301:9:305:9 | match ... { ... } | | | test.rs:302:46:302:46 | 5 | test.rs:302:42:302:46 | ... + ... | | | test.rs:303:13:303:27 | TupleStructPat | test.rs:303:26:303:26 | x | match | -| test.rs:303:13:303:27 | TupleStructPat | test.rs:304:13:304:24 | PathPat | no-match | +| test.rs:303:13:303:27 | TupleStructPat | test.rs:304:13:304:24 | Option::None | no-match | | test.rs:303:26:303:26 | x | test.rs:303:32:303:32 | x | match | -| test.rs:303:32:303:32 | x | test.rs:301:9:305:9 | MatchExpr | | -| test.rs:304:13:304:24 | PathPat | test.rs:304:29:304:29 | 5 | match | -| test.rs:304:29:304:29 | 5 | test.rs:301:9:305:9 | MatchExpr | | -| test.rs:308:5:317:5 | enter test_match_with_return_in_scrutinee | test.rs:308:44:308:54 | maybe_digit | | -| test.rs:308:5:317:5 | exit test_match_with_return_in_scrutinee (normal) | test.rs:308:5:317:5 | exit test_match_with_return_in_scrutinee | | -| test.rs:308:44:308:54 | maybe_digit | test.rs:308:44:308:67 | Param | match | -| test.rs:308:44:308:67 | Param | test.rs:309:19:309:29 | maybe_digit | | -| test.rs:308:77:317:5 | BlockExpr | test.rs:308:5:317:5 | exit test_match_with_return_in_scrutinee (normal) | | -| test.rs:309:9:316:9 | MatchExpr | test.rs:308:77:317:5 | BlockExpr | | -| test.rs:309:16:313:9 | IfExpr | test.rs:314:13:314:27 | TupleStructPat | | +| test.rs:303:32:303:32 | x | test.rs:301:9:305:9 | match ... { ... } | | +| test.rs:304:13:304:24 | Option::None | test.rs:304:29:304:29 | 5 | match | +| test.rs:304:29:304:29 | 5 | test.rs:301:9:305:9 | match ... { ... } | | +| test.rs:308:5:317:5 | enter fn test_match_with_return_in_scrutinee | test.rs:308:44:308:54 | maybe_digit | | +| test.rs:308:5:317:5 | exit fn test_match_with_return_in_scrutinee (normal) | test.rs:308:5:317:5 | exit fn test_match_with_return_in_scrutinee | | +| test.rs:308:44:308:54 | maybe_digit | test.rs:308:44:308:67 | maybe_digit: Option::<...> | match | +| test.rs:308:44:308:67 | maybe_digit: Option::<...> | test.rs:309:19:309:29 | maybe_digit | | +| test.rs:308:77:317:5 | { ... } | test.rs:308:5:317:5 | exit fn test_match_with_return_in_scrutinee (normal) | | +| test.rs:309:9:316:9 | match ... { ... } | test.rs:308:77:317:5 | { ... } | | +| test.rs:309:16:313:9 | if ... { ... } else { ... } | test.rs:314:13:314:27 | TupleStructPat | | | test.rs:309:19:309:29 | maybe_digit | test.rs:309:34:309:37 | Some | | | test.rs:309:19:309:40 | ... == ... | test.rs:310:13:310:21 | ExprStmt | true | | test.rs:309:19:309:40 | ... == ... | test.rs:312:13:312:23 | maybe_digit | false | | test.rs:309:34:309:37 | Some | test.rs:309:39:309:39 | 3 | | -| test.rs:309:34:309:40 | CallExpr | test.rs:309:19:309:40 | ... == ... | | -| test.rs:309:39:309:39 | 3 | test.rs:309:34:309:40 | CallExpr | | -| test.rs:310:13:310:20 | ReturnExpr | test.rs:308:5:317:5 | exit test_match_with_return_in_scrutinee (normal) | return | +| test.rs:309:34:309:40 | Some(...) | test.rs:309:19:309:40 | ... == ... | | +| test.rs:309:39:309:39 | 3 | test.rs:309:34:309:40 | Some(...) | | +| test.rs:310:13:310:20 | return ... | test.rs:308:5:317:5 | exit fn test_match_with_return_in_scrutinee (normal) | return | | test.rs:310:13:310:21 | ExprStmt | test.rs:310:20:310:20 | 3 | | -| test.rs:310:20:310:20 | 3 | test.rs:310:13:310:20 | ReturnExpr | | -| test.rs:311:16:313:9 | BlockExpr | test.rs:309:16:313:9 | IfExpr | | -| test.rs:312:13:312:23 | maybe_digit | test.rs:311:16:313:9 | BlockExpr | | +| test.rs:310:20:310:20 | 3 | test.rs:310:13:310:20 | return ... | | +| test.rs:311:16:313:9 | { ... } | test.rs:309:16:313:9 | if ... { ... } else { ... } | | +| test.rs:312:13:312:23 | maybe_digit | test.rs:311:16:313:9 | { ... } | | | test.rs:314:13:314:27 | TupleStructPat | test.rs:314:26:314:26 | x | match | -| test.rs:314:13:314:27 | TupleStructPat | test.rs:315:13:315:24 | PathPat | no-match | +| test.rs:314:13:314:27 | TupleStructPat | test.rs:315:13:315:24 | Option::None | no-match | | test.rs:314:26:314:26 | x | test.rs:314:32:314:32 | x | match | | test.rs:314:32:314:32 | x | test.rs:314:36:314:36 | 5 | | -| test.rs:314:32:314:36 | ... + ... | test.rs:309:9:316:9 | MatchExpr | | +| test.rs:314:32:314:36 | ... + ... | test.rs:309:9:316:9 | match ... { ... } | | | test.rs:314:36:314:36 | 5 | test.rs:314:32:314:36 | ... + ... | | -| test.rs:315:13:315:24 | PathPat | test.rs:315:29:315:29 | 5 | match | -| test.rs:315:29:315:29 | 5 | test.rs:309:9:316:9 | MatchExpr | | -| test.rs:319:5:324:5 | enter test_match_and | test.rs:319:23:319:26 | cond | | -| test.rs:319:5:324:5 | exit test_match_and (normal) | test.rs:319:5:324:5 | exit test_match_and | | -| test.rs:319:23:319:26 | cond | test.rs:319:23:319:32 | Param | match | -| test.rs:319:23:319:32 | Param | test.rs:319:35:319:35 | r | | -| test.rs:319:35:319:35 | r | test.rs:319:35:319:49 | Param | match | -| test.rs:319:35:319:49 | Param | test.rs:320:16:320:16 | r | | -| test.rs:319:60:324:5 | BlockExpr | test.rs:319:5:324:5 | exit test_match_and (normal) | | -| test.rs:320:9:323:18 | ... && ... | test.rs:319:60:324:5 | BlockExpr | | -| test.rs:320:10:323:9 | [boolean(false)] MatchExpr | test.rs:320:9:323:18 | ... && ... | false | -| test.rs:320:10:323:9 | [boolean(true)] MatchExpr | test.rs:323:15:323:18 | cond | true | +| test.rs:315:13:315:24 | Option::None | test.rs:315:29:315:29 | 5 | match | +| test.rs:315:29:315:29 | 5 | test.rs:309:9:316:9 | match ... { ... } | | +| test.rs:319:5:324:5 | enter fn test_match_and | test.rs:319:23:319:26 | cond | | +| test.rs:319:5:324:5 | exit fn test_match_and (normal) | test.rs:319:5:324:5 | exit fn test_match_and | | +| test.rs:319:23:319:26 | cond | test.rs:319:23:319:32 | cond: bool | match | +| test.rs:319:23:319:32 | cond: bool | test.rs:319:35:319:35 | r | | +| test.rs:319:35:319:35 | r | test.rs:319:35:319:49 | r: Option::<...> | match | +| test.rs:319:35:319:49 | r: Option::<...> | test.rs:320:16:320:16 | r | | +| test.rs:319:60:324:5 | { ... } | test.rs:319:5:324:5 | exit fn test_match_and (normal) | | +| test.rs:320:9:323:18 | ... && ... | test.rs:319:60:324:5 | { ... } | | +| test.rs:320:10:323:9 | [boolean(false)] match ... { ... } | test.rs:320:9:323:18 | ... && ... | false | +| test.rs:320:10:323:9 | [boolean(true)] match ... { ... } | test.rs:323:15:323:18 | cond | true | | test.rs:320:16:320:16 | r | test.rs:321:13:321:19 | TupleStructPat | | | test.rs:321:13:321:19 | TupleStructPat | test.rs:321:18:321:18 | a | match | -| test.rs:321:13:321:19 | TupleStructPat | test.rs:322:13:322:13 | WildcardPat | no-match | +| test.rs:321:13:321:19 | TupleStructPat | test.rs:322:13:322:13 | _ | no-match | | test.rs:321:18:321:18 | a | test.rs:321:24:321:24 | a | match | -| test.rs:321:24:321:24 | a | test.rs:320:10:323:9 | [boolean(false)] MatchExpr | false | -| test.rs:321:24:321:24 | a | test.rs:320:10:323:9 | [boolean(true)] MatchExpr | true | -| test.rs:322:13:322:13 | WildcardPat | test.rs:322:18:322:22 | false | match | -| test.rs:322:18:322:22 | false | test.rs:320:10:323:9 | [boolean(false)] MatchExpr | false | +| test.rs:321:24:321:24 | a | test.rs:320:10:323:9 | [boolean(false)] match ... { ... } | false | +| test.rs:321:24:321:24 | a | test.rs:320:10:323:9 | [boolean(true)] match ... { ... } | true | +| test.rs:322:13:322:13 | _ | test.rs:322:18:322:22 | false | match | +| test.rs:322:18:322:22 | false | test.rs:320:10:323:9 | [boolean(false)] match ... { ... } | false | | test.rs:323:15:323:18 | cond | test.rs:320:9:323:18 | ... && ... | | -| test.rs:326:5:331:5 | enter test_match_with_no_arms | test.rs:326:35:326:35 | r | | -| test.rs:326:5:331:5 | exit test_match_with_no_arms (normal) | test.rs:326:5:331:5 | exit test_match_with_no_arms | | -| test.rs:326:35:326:35 | r | test.rs:326:35:326:58 | Param | match | -| test.rs:326:35:326:58 | Param | test.rs:327:15:327:15 | r | | -| test.rs:326:66:331:5 | BlockExpr | test.rs:326:5:331:5 | exit test_match_with_no_arms (normal) | | -| test.rs:327:9:330:9 | MatchExpr | test.rs:326:66:331:5 | BlockExpr | | +| test.rs:326:5:331:5 | enter fn test_match_with_no_arms | test.rs:326:35:326:35 | r | | +| test.rs:326:5:331:5 | exit fn test_match_with_no_arms (normal) | test.rs:326:5:331:5 | exit fn test_match_with_no_arms | | +| test.rs:326:35:326:35 | r | test.rs:326:35:326:58 | r: Result::<...> | match | +| test.rs:326:35:326:58 | r: Result::<...> | test.rs:327:15:327:15 | r | | +| test.rs:326:66:331:5 | { ... } | test.rs:326:5:331:5 | exit fn test_match_with_no_arms (normal) | | +| test.rs:327:9:330:9 | match ... { ... } | test.rs:326:66:331:5 | { ... } | | | test.rs:327:15:327:15 | r | test.rs:328:13:328:21 | TupleStructPat | | | test.rs:328:13:328:21 | TupleStructPat | test.rs:328:16:328:20 | value | match | | test.rs:328:13:328:21 | TupleStructPat | test.rs:329:13:329:22 | TupleStructPat | no-match | | test.rs:328:16:328:20 | value | test.rs:328:26:328:30 | value | match | -| test.rs:328:26:328:30 | value | test.rs:327:9:330:9 | MatchExpr | | +| test.rs:328:26:328:30 | value | test.rs:327:9:330:9 | match ... { ... } | | | test.rs:329:13:329:22 | TupleStructPat | test.rs:329:17:329:21 | never | match | | test.rs:329:17:329:21 | never | test.rs:329:33:329:37 | never | match | -| test.rs:329:27:329:40 | MatchExpr | test.rs:327:9:330:9 | MatchExpr | | -| test.rs:329:33:329:37 | never | test.rs:329:27:329:40 | MatchExpr | | -| test.rs:336:5:339:5 | enter test_let_match | test.rs:336:23:336:23 | a | | -| test.rs:336:5:339:5 | exit test_let_match (normal) | test.rs:336:5:339:5 | exit test_let_match | | -| test.rs:336:23:336:23 | a | test.rs:336:23:336:36 | Param | match | -| test.rs:336:23:336:36 | Param | test.rs:337:9:337:57 | LetStmt | | -| test.rs:336:46:339:5 | BlockExpr | test.rs:336:5:339:5 | exit test_let_match (normal) | | -| test.rs:337:9:337:57 | LetStmt | test.rs:337:23:337:23 | a | | +| test.rs:329:27:329:40 | match ... { ... } | test.rs:327:9:330:9 | match ... { ... } | | +| test.rs:329:33:329:37 | never | test.rs:329:27:329:40 | match ... { ... } | | +| test.rs:336:5:339:5 | enter fn test_let_match | test.rs:336:23:336:23 | a | | +| test.rs:336:5:339:5 | exit fn test_let_match (normal) | test.rs:336:5:339:5 | exit fn test_let_match | | +| test.rs:336:23:336:23 | a | test.rs:336:23:336:36 | a: Option::<...> | match | +| test.rs:336:23:336:36 | a: Option::<...> | test.rs:337:9:337:57 | let TupleStructPat = ... else { ... } | | +| test.rs:336:46:339:5 | { ... } | test.rs:336:5:339:5 | exit fn test_let_match (normal) | | +| test.rs:337:9:337:57 | let TupleStructPat = ... else { ... } | test.rs:337:23:337:23 | a | | | test.rs:337:13:337:19 | TupleStructPat | test.rs:337:18:337:18 | n | match | | test.rs:337:13:337:19 | TupleStructPat | test.rs:337:39:337:53 | MacroStmts | no-match | | test.rs:337:18:337:18 | n | test.rs:338:9:338:9 | n | match | | test.rs:337:23:337:23 | a | test.rs:337:13:337:19 | TupleStructPat | | | test.rs:337:32:337:54 | $crate::panicking::panic_fmt | test.rs:337:39:337:53 | "Expected some" | | -| test.rs:337:32:337:54 | MacroExpr | test.rs:337:30:337:56 | BlockExpr | | +| test.rs:337:32:337:54 | MacroExpr | test.rs:337:30:337:56 | { ... } | | | test.rs:337:39:337:53 | "Expected some" | test.rs:337:39:337:53 | FormatArgsExpr | | -| test.rs:337:39:337:53 | BlockExpr | test.rs:337:39:337:53 | MacroExpr | | -| test.rs:337:39:337:53 | CallExpr | test.rs:337:39:337:53 | BlockExpr | | +| test.rs:337:39:337:53 | $crate::panicking::panic_fmt(...) | test.rs:337:39:337:53 | { ... } | | | test.rs:337:39:337:53 | ExprStmt | test.rs:337:32:337:54 | $crate::panicking::panic_fmt | | | test.rs:337:39:337:53 | FormatArgsExpr | test.rs:337:39:337:53 | MacroExpr | | | test.rs:337:39:337:53 | MacroExpr | test.rs:337:32:337:54 | MacroExpr | | -| test.rs:337:39:337:53 | MacroExpr | test.rs:337:39:337:53 | CallExpr | | +| test.rs:337:39:337:53 | MacroExpr | test.rs:337:39:337:53 | $crate::panicking::panic_fmt(...) | | | test.rs:337:39:337:53 | MacroStmts | test.rs:337:39:337:53 | ExprStmt | | | test.rs:337:39:337:53 | MacroStmts | test.rs:337:39:337:53 | MacroStmts | | -| test.rs:338:9:338:9 | n | test.rs:336:46:339:5 | BlockExpr | | -| test.rs:341:5:347:5 | enter test_let_with_return | test.rs:341:29:341:29 | m | | -| test.rs:341:5:347:5 | exit test_let_with_return (normal) | test.rs:341:5:347:5 | exit test_let_with_return | | -| test.rs:341:29:341:29 | m | test.rs:341:29:341:42 | Param | match | -| test.rs:341:29:341:42 | Param | test.rs:342:9:345:10 | LetStmt | | -| test.rs:341:53:347:5 | BlockExpr | test.rs:341:5:347:5 | exit test_let_with_return (normal) | | -| test.rs:342:9:345:10 | LetStmt | test.rs:342:25:342:25 | m | | +| test.rs:337:39:337:53 | { ... } | test.rs:337:39:337:53 | MacroExpr | | +| test.rs:338:9:338:9 | n | test.rs:336:46:339:5 | { ... } | | +| test.rs:341:5:347:5 | enter fn test_let_with_return | test.rs:341:29:341:29 | m | | +| test.rs:341:5:347:5 | exit fn test_let_with_return (normal) | test.rs:341:5:347:5 | exit fn test_let_with_return | | +| test.rs:341:29:341:29 | m | test.rs:341:29:341:42 | m: Option::<...> | match | +| test.rs:341:29:341:42 | m: Option::<...> | test.rs:342:9:345:10 | let ret = ... | | +| test.rs:341:53:347:5 | { ... } | test.rs:341:5:347:5 | exit fn test_let_with_return (normal) | | +| test.rs:342:9:345:10 | let ret = ... | test.rs:342:25:342:25 | m | | | test.rs:342:13:342:15 | ret | test.rs:346:9:346:12 | true | match | -| test.rs:342:19:345:9 | MatchExpr | test.rs:342:13:342:15 | ret | | +| test.rs:342:19:345:9 | match ... { ... } | test.rs:342:13:342:15 | ret | | | test.rs:342:25:342:25 | m | test.rs:343:13:343:21 | TupleStructPat | | | test.rs:343:13:343:21 | TupleStructPat | test.rs:343:18:343:20 | ret | match | | test.rs:343:13:343:21 | TupleStructPat | test.rs:344:13:344:16 | None | no-match | | test.rs:343:18:343:20 | ret | test.rs:343:26:343:28 | ret | match | -| test.rs:343:26:343:28 | ret | test.rs:342:19:345:9 | MatchExpr | | +| test.rs:343:26:343:28 | ret | test.rs:342:19:345:9 | match ... { ... } | | | test.rs:344:13:344:16 | None | test.rs:344:28:344:32 | false | match | -| test.rs:344:21:344:32 | ReturnExpr | test.rs:341:5:347:5 | exit test_let_with_return (normal) | return | -| test.rs:344:28:344:32 | false | test.rs:344:21:344:32 | ReturnExpr | | -| test.rs:346:9:346:12 | true | test.rs:341:53:347:5 | BlockExpr | | -| test.rs:352:5:355:5 | enter empty_tuple_pattern | test.rs:352:28:352:31 | unit | | -| test.rs:352:5:355:5 | exit empty_tuple_pattern (normal) | test.rs:352:5:355:5 | exit empty_tuple_pattern | | -| test.rs:352:28:352:31 | unit | test.rs:352:28:352:35 | Param | match | -| test.rs:352:28:352:35 | Param | test.rs:353:9:353:22 | LetStmt | | -| test.rs:353:9:353:22 | LetStmt | test.rs:353:18:353:21 | unit | | +| test.rs:344:21:344:32 | return ... | test.rs:341:5:347:5 | exit fn test_let_with_return (normal) | return | +| test.rs:344:28:344:32 | false | test.rs:344:21:344:32 | return ... | | +| test.rs:346:9:346:12 | true | test.rs:341:53:347:5 | { ... } | | +| test.rs:352:5:355:5 | enter fn empty_tuple_pattern | test.rs:352:28:352:31 | unit | | +| test.rs:352:5:355:5 | exit fn empty_tuple_pattern (normal) | test.rs:352:5:355:5 | exit fn empty_tuple_pattern | | +| test.rs:352:28:352:31 | unit | test.rs:352:28:352:35 | unit: TupleType | match | +| test.rs:352:28:352:35 | unit: TupleType | test.rs:353:9:353:22 | let TuplePat = ... | | +| test.rs:353:9:353:22 | let TuplePat = ... | test.rs:353:18:353:21 | unit | | | test.rs:353:13:353:14 | TuplePat | test.rs:354:9:354:15 | ExprStmt | match | | test.rs:353:18:353:21 | unit | test.rs:353:13:353:14 | TuplePat | | -| test.rs:354:9:354:14 | ReturnExpr | test.rs:352:5:355:5 | exit empty_tuple_pattern (normal) | return | -| test.rs:354:9:354:15 | ExprStmt | test.rs:354:9:354:14 | ReturnExpr | | -| test.rs:359:5:363:5 | enter empty_struct_pattern | test.rs:359:29:359:30 | st | | -| test.rs:359:5:363:5 | exit empty_struct_pattern (normal) | test.rs:359:5:363:5 | exit empty_struct_pattern | | -| test.rs:359:29:359:30 | st | test.rs:359:29:359:40 | Param | match | -| test.rs:359:29:359:40 | Param | test.rs:360:15:360:16 | st | | -| test.rs:359:50:363:5 | BlockExpr | test.rs:359:5:363:5 | exit empty_struct_pattern (normal) | | -| test.rs:360:9:362:9 | MatchExpr | test.rs:359:50:363:5 | BlockExpr | | -| test.rs:360:15:360:16 | st | test.rs:361:13:361:27 | RecordPat | | -| test.rs:361:13:361:27 | RecordPat | test.rs:361:24:361:25 | RestPat | match | -| test.rs:361:24:361:25 | RestPat | test.rs:361:32:361:32 | 1 | match | -| test.rs:361:32:361:32 | 1 | test.rs:360:9:362:9 | MatchExpr | | -| test.rs:365:5:372:5 | enter range_pattern | test.rs:366:15:366:16 | 42 | | -| test.rs:365:5:372:5 | exit range_pattern (normal) | test.rs:365:5:372:5 | exit range_pattern | | -| test.rs:365:31:372:5 | BlockExpr | test.rs:365:5:372:5 | exit range_pattern (normal) | | -| test.rs:366:9:371:9 | MatchExpr | test.rs:365:31:372:5 | BlockExpr | | +| test.rs:354:9:354:14 | return | test.rs:352:5:355:5 | exit fn empty_tuple_pattern (normal) | return | +| test.rs:354:9:354:15 | ExprStmt | test.rs:354:9:354:14 | return | | +| test.rs:359:5:363:5 | enter fn empty_struct_pattern | test.rs:359:29:359:30 | st | | +| test.rs:359:5:363:5 | exit fn empty_struct_pattern (normal) | test.rs:359:5:363:5 | exit fn empty_struct_pattern | | +| test.rs:359:29:359:30 | st | test.rs:359:29:359:40 | st: MyStruct | match | +| test.rs:359:29:359:40 | st: MyStruct | test.rs:360:15:360:16 | st | | +| test.rs:359:50:363:5 | { ... } | test.rs:359:5:363:5 | exit fn empty_struct_pattern (normal) | | +| test.rs:360:9:362:9 | match ... { ... } | test.rs:359:50:363:5 | { ... } | | +| test.rs:360:15:360:16 | st | test.rs:361:13:361:27 | MyStruct {...} | | +| test.rs:361:13:361:27 | MyStruct {...} | test.rs:361:24:361:25 | .. | match | +| test.rs:361:24:361:25 | .. | test.rs:361:32:361:32 | 1 | match | +| test.rs:361:32:361:32 | 1 | test.rs:360:9:362:9 | match ... { ... } | | +| test.rs:365:5:372:5 | enter fn range_pattern | test.rs:366:15:366:16 | 42 | | +| test.rs:365:5:372:5 | exit fn range_pattern (normal) | test.rs:365:5:372:5 | exit fn range_pattern | | +| test.rs:365:31:372:5 | { ... } | test.rs:365:5:372:5 | exit fn range_pattern (normal) | | +| test.rs:366:9:371:9 | match ... { ... } | test.rs:365:31:372:5 | { ... } | | | test.rs:366:15:366:16 | 42 | test.rs:367:13:367:15 | RangePat | | | test.rs:367:13:367:15 | RangePat | test.rs:367:15:367:15 | 0 | match | | test.rs:367:13:367:15 | RangePat | test.rs:368:13:368:16 | RangePat | no-match | -| test.rs:367:15:367:15 | 0 | test.rs:367:15:367:15 | LiteralPat | | -| test.rs:367:15:367:15 | LiteralPat | test.rs:367:20:367:20 | 1 | match | -| test.rs:367:15:367:15 | LiteralPat | test.rs:368:13:368:16 | RangePat | no-match | -| test.rs:367:20:367:20 | 1 | test.rs:366:9:371:9 | MatchExpr | | -| test.rs:368:13:368:13 | 1 | test.rs:368:13:368:13 | LiteralPat | | -| test.rs:368:13:368:13 | LiteralPat | test.rs:368:16:368:16 | 2 | match | -| test.rs:368:13:368:13 | LiteralPat | test.rs:369:13:369:15 | RangePat | no-match | +| test.rs:367:15:367:15 | 0 | test.rs:367:15:367:15 | 0 | | +| test.rs:367:15:367:15 | 0 | test.rs:367:20:367:20 | 1 | match | +| test.rs:367:15:367:15 | 0 | test.rs:368:13:368:16 | RangePat | no-match | +| test.rs:367:20:367:20 | 1 | test.rs:366:9:371:9 | match ... { ... } | | +| test.rs:368:13:368:13 | 1 | test.rs:368:13:368:13 | 1 | | +| test.rs:368:13:368:13 | 1 | test.rs:368:16:368:16 | 2 | match | +| test.rs:368:13:368:13 | 1 | test.rs:369:13:369:15 | RangePat | no-match | | test.rs:368:13:368:16 | RangePat | test.rs:368:13:368:13 | 1 | match | | test.rs:368:13:368:16 | RangePat | test.rs:369:13:369:15 | RangePat | no-match | -| test.rs:368:16:368:16 | 2 | test.rs:368:16:368:16 | LiteralPat | | -| test.rs:368:16:368:16 | LiteralPat | test.rs:368:21:368:21 | 2 | match | -| test.rs:368:16:368:16 | LiteralPat | test.rs:369:13:369:15 | RangePat | no-match | -| test.rs:368:21:368:21 | 2 | test.rs:366:9:371:9 | MatchExpr | | -| test.rs:369:13:369:13 | 5 | test.rs:369:13:369:13 | LiteralPat | | -| test.rs:369:13:369:13 | LiteralPat | test.rs:369:20:369:20 | 3 | match | -| test.rs:369:13:369:13 | LiteralPat | test.rs:370:13:370:13 | WildcardPat | no-match | +| test.rs:368:16:368:16 | 2 | test.rs:368:16:368:16 | 2 | | +| test.rs:368:16:368:16 | 2 | test.rs:368:21:368:21 | 2 | match | +| test.rs:368:16:368:16 | 2 | test.rs:369:13:369:15 | RangePat | no-match | +| test.rs:368:21:368:21 | 2 | test.rs:366:9:371:9 | match ... { ... } | | +| test.rs:369:13:369:13 | 5 | test.rs:369:13:369:13 | 5 | | +| test.rs:369:13:369:13 | 5 | test.rs:369:20:369:20 | 3 | match | +| test.rs:369:13:369:13 | 5 | test.rs:370:13:370:13 | _ | no-match | | test.rs:369:13:369:15 | RangePat | test.rs:369:13:369:13 | 5 | match | -| test.rs:369:13:369:15 | RangePat | test.rs:370:13:370:13 | WildcardPat | no-match | -| test.rs:369:20:369:20 | 3 | test.rs:366:9:371:9 | MatchExpr | | -| test.rs:370:13:370:13 | WildcardPat | test.rs:370:18:370:18 | 4 | match | -| test.rs:370:18:370:18 | 4 | test.rs:366:9:371:9 | MatchExpr | | -| test.rs:376:5:381:5 | enter test_infinite_loop | test.rs:377:9:379:9 | ExprStmt | | +| test.rs:369:13:369:15 | RangePat | test.rs:370:13:370:13 | _ | no-match | +| test.rs:369:20:369:20 | 3 | test.rs:366:9:371:9 | match ... { ... } | | +| test.rs:370:13:370:13 | _ | test.rs:370:18:370:18 | 4 | match | +| test.rs:370:18:370:18 | 4 | test.rs:366:9:371:9 | match ... { ... } | | +| test.rs:376:5:381:5 | enter fn test_infinite_loop | test.rs:377:9:379:9 | ExprStmt | | | test.rs:377:9:379:9 | ExprStmt | test.rs:378:13:378:14 | TupleExpr | | -| test.rs:377:14:379:9 | BlockExpr | test.rs:378:13:378:14 | TupleExpr | | -| test.rs:378:13:378:14 | TupleExpr | test.rs:377:14:379:9 | BlockExpr | | -| test.rs:385:5:387:5 | enter say_hello | test.rs:386:9:386:34 | ExprStmt | | -| test.rs:385:5:387:5 | exit say_hello (normal) | test.rs:385:5:387:5 | exit say_hello | | -| test.rs:385:26:387:5 | BlockExpr | test.rs:385:5:387:5 | exit say_hello (normal) | | +| test.rs:377:14:379:9 | { ... } | test.rs:378:13:378:14 | TupleExpr | | +| test.rs:378:13:378:14 | TupleExpr | test.rs:377:14:379:9 | { ... } | | +| test.rs:385:5:387:5 | enter fn say_hello | test.rs:386:9:386:34 | ExprStmt | | +| test.rs:385:5:387:5 | exit fn say_hello (normal) | test.rs:385:5:387:5 | exit fn say_hello | | +| test.rs:385:26:387:5 | { ... } | test.rs:385:5:387:5 | exit fn say_hello (normal) | | | test.rs:386:9:386:33 | $crate::io::_print | test.rs:386:18:386:32 | "hello, world!\\n" | | -| test.rs:386:9:386:33 | MacroExpr | test.rs:385:26:387:5 | BlockExpr | | +| test.rs:386:9:386:33 | MacroExpr | test.rs:385:26:387:5 | { ... } | | | test.rs:386:9:386:34 | ExprStmt | test.rs:386:18:386:32 | MacroStmts | | | test.rs:386:18:386:32 | "hello, world!\\n" | test.rs:386:18:386:32 | FormatArgsExpr | | -| test.rs:386:18:386:32 | BlockExpr | test.rs:386:9:386:33 | MacroExpr | | -| test.rs:386:18:386:32 | CallExpr | test.rs:386:18:386:32 | BlockExpr | | +| test.rs:386:18:386:32 | $crate::io::_print(...) | test.rs:386:18:386:32 | { ... } | | | test.rs:386:18:386:32 | ExprStmt | test.rs:386:9:386:33 | $crate::io::_print | | | test.rs:386:18:386:32 | FormatArgsExpr | test.rs:386:18:386:32 | MacroExpr | | -| test.rs:386:18:386:32 | MacroExpr | test.rs:386:18:386:32 | CallExpr | | +| test.rs:386:18:386:32 | MacroExpr | test.rs:386:18:386:32 | $crate::io::_print(...) | | | test.rs:386:18:386:32 | MacroStmts | test.rs:386:18:386:32 | ExprStmt | | -| test.rs:389:5:408:5 | enter async_block | test.rs:389:26:389:26 | b | | -| test.rs:389:5:408:5 | exit async_block (normal) | test.rs:389:5:408:5 | exit async_block | | -| test.rs:389:26:389:26 | b | test.rs:389:26:389:32 | Param | match | -| test.rs:389:26:389:32 | Param | test.rs:390:9:392:10 | LetStmt | | -| test.rs:389:35:408:5 | BlockExpr | test.rs:389:5:408:5 | exit async_block (normal) | | -| test.rs:390:9:392:10 | LetStmt | test.rs:390:26:392:9 | BlockExpr | | -| test.rs:390:13:390:22 | say_godbye | test.rs:393:9:395:10 | LetStmt | match | -| test.rs:390:26:392:9 | BlockExpr | test.rs:390:13:390:22 | say_godbye | | -| test.rs:390:26:392:9 | enter BlockExpr | test.rs:391:13:391:42 | ExprStmt | | -| test.rs:390:26:392:9 | exit BlockExpr (normal) | test.rs:390:26:392:9 | exit BlockExpr | | +| test.rs:386:18:386:32 | { ... } | test.rs:386:9:386:33 | MacroExpr | | +| test.rs:389:5:408:5 | enter fn async_block | test.rs:389:26:389:26 | b | | +| test.rs:389:5:408:5 | exit fn async_block (normal) | test.rs:389:5:408:5 | exit fn async_block | | +| test.rs:389:26:389:26 | b | test.rs:389:26:389:32 | b: bool | match | +| test.rs:389:26:389:32 | b: bool | test.rs:390:9:392:10 | let say_godbye = ... | | +| test.rs:389:35:408:5 | { ... } | test.rs:389:5:408:5 | exit fn async_block (normal) | | +| test.rs:390:9:392:10 | let say_godbye = ... | test.rs:390:26:392:9 | { ... } | | +| test.rs:390:13:390:22 | say_godbye | test.rs:393:9:395:10 | let say_how_are_you = ... | match | +| test.rs:390:26:392:9 | enter { ... } | test.rs:391:13:391:42 | ExprStmt | | +| test.rs:390:26:392:9 | exit { ... } (normal) | test.rs:390:26:392:9 | exit { ... } | | +| test.rs:390:26:392:9 | { ... } | test.rs:390:13:390:22 | say_godbye | | | test.rs:391:13:391:41 | $crate::io::_print | test.rs:391:22:391:40 | "godbye, everyone!\\n" | | -| test.rs:391:13:391:41 | MacroExpr | test.rs:390:26:392:9 | exit BlockExpr (normal) | | +| test.rs:391:13:391:41 | MacroExpr | test.rs:390:26:392:9 | exit { ... } (normal) | | | test.rs:391:13:391:42 | ExprStmt | test.rs:391:22:391:40 | MacroStmts | | | test.rs:391:22:391:40 | "godbye, everyone!\\n" | test.rs:391:22:391:40 | FormatArgsExpr | | -| test.rs:391:22:391:40 | BlockExpr | test.rs:391:13:391:41 | MacroExpr | | -| test.rs:391:22:391:40 | CallExpr | test.rs:391:22:391:40 | BlockExpr | | +| test.rs:391:22:391:40 | $crate::io::_print(...) | test.rs:391:22:391:40 | { ... } | | | test.rs:391:22:391:40 | ExprStmt | test.rs:391:13:391:41 | $crate::io::_print | | | test.rs:391:22:391:40 | FormatArgsExpr | test.rs:391:22:391:40 | MacroExpr | | -| test.rs:391:22:391:40 | MacroExpr | test.rs:391:22:391:40 | CallExpr | | +| test.rs:391:22:391:40 | MacroExpr | test.rs:391:22:391:40 | $crate::io::_print(...) | | | test.rs:391:22:391:40 | MacroStmts | test.rs:391:22:391:40 | ExprStmt | | -| test.rs:393:9:395:10 | LetStmt | test.rs:393:31:395:9 | BlockExpr | | -| test.rs:393:13:393:27 | say_how_are_you | test.rs:396:9:396:28 | LetStmt | match | -| test.rs:393:31:395:9 | BlockExpr | test.rs:393:13:393:27 | say_how_are_you | | -| test.rs:393:31:395:9 | enter BlockExpr | test.rs:394:13:394:37 | ExprStmt | | -| test.rs:393:31:395:9 | exit BlockExpr (normal) | test.rs:393:31:395:9 | exit BlockExpr | | +| test.rs:391:22:391:40 | { ... } | test.rs:391:13:391:41 | MacroExpr | | +| test.rs:393:9:395:10 | let say_how_are_you = ... | test.rs:393:31:395:9 | { ... } | | +| test.rs:393:13:393:27 | say_how_are_you | test.rs:396:9:396:28 | let noop = ... | match | +| test.rs:393:31:395:9 | enter { ... } | test.rs:394:13:394:37 | ExprStmt | | +| test.rs:393:31:395:9 | exit { ... } (normal) | test.rs:393:31:395:9 | exit { ... } | | +| test.rs:393:31:395:9 | { ... } | test.rs:393:13:393:27 | say_how_are_you | | | test.rs:394:13:394:36 | $crate::io::_print | test.rs:394:22:394:35 | "how are you?\\n" | | -| test.rs:394:13:394:36 | MacroExpr | test.rs:393:31:395:9 | exit BlockExpr (normal) | | +| test.rs:394:13:394:36 | MacroExpr | test.rs:393:31:395:9 | exit { ... } (normal) | | | test.rs:394:13:394:37 | ExprStmt | test.rs:394:22:394:35 | MacroStmts | | | test.rs:394:22:394:35 | "how are you?\\n" | test.rs:394:22:394:35 | FormatArgsExpr | | -| test.rs:394:22:394:35 | BlockExpr | test.rs:394:13:394:36 | MacroExpr | | -| test.rs:394:22:394:35 | CallExpr | test.rs:394:22:394:35 | BlockExpr | | +| test.rs:394:22:394:35 | $crate::io::_print(...) | test.rs:394:22:394:35 | { ... } | | | test.rs:394:22:394:35 | ExprStmt | test.rs:394:13:394:36 | $crate::io::_print | | | test.rs:394:22:394:35 | FormatArgsExpr | test.rs:394:22:394:35 | MacroExpr | | -| test.rs:394:22:394:35 | MacroExpr | test.rs:394:22:394:35 | CallExpr | | +| test.rs:394:22:394:35 | MacroExpr | test.rs:394:22:394:35 | $crate::io::_print(...) | | | test.rs:394:22:394:35 | MacroStmts | test.rs:394:22:394:35 | ExprStmt | | -| test.rs:396:9:396:28 | LetStmt | test.rs:396:20:396:27 | BlockExpr | | +| test.rs:394:22:394:35 | { ... } | test.rs:394:13:394:36 | MacroExpr | | +| test.rs:396:9:396:28 | let noop = ... | test.rs:396:20:396:27 | { ... } | | | test.rs:396:13:396:16 | noop | test.rs:397:9:397:26 | ExprStmt | match | -| test.rs:396:20:396:27 | BlockExpr | test.rs:396:13:396:16 | noop | | -| test.rs:397:9:397:17 | say_hello | test.rs:397:9:397:19 | CallExpr | | -| test.rs:397:9:397:19 | CallExpr | test.rs:397:9:397:25 | AwaitExpr | | -| test.rs:397:9:397:25 | AwaitExpr | test.rs:398:9:398:30 | ExprStmt | | +| test.rs:396:20:396:27 | { ... } | test.rs:396:13:396:16 | noop | | +| test.rs:397:9:397:17 | say_hello | test.rs:397:9:397:19 | say_hello(...) | | +| test.rs:397:9:397:19 | say_hello(...) | test.rs:397:9:397:25 | await ... | | +| test.rs:397:9:397:25 | await ... | test.rs:398:9:398:30 | ExprStmt | | | test.rs:397:9:397:26 | ExprStmt | test.rs:397:9:397:17 | say_hello | | -| test.rs:398:9:398:23 | say_how_are_you | test.rs:398:9:398:29 | AwaitExpr | | -| test.rs:398:9:398:29 | AwaitExpr | test.rs:399:9:399:25 | ExprStmt | | +| test.rs:398:9:398:23 | say_how_are_you | test.rs:398:9:398:29 | await ... | | +| test.rs:398:9:398:29 | await ... | test.rs:399:9:399:25 | ExprStmt | | | test.rs:398:9:398:30 | ExprStmt | test.rs:398:9:398:23 | say_how_are_you | | -| test.rs:399:9:399:18 | say_godbye | test.rs:399:9:399:24 | AwaitExpr | | -| test.rs:399:9:399:24 | AwaitExpr | test.rs:400:9:400:19 | ExprStmt | | +| test.rs:399:9:399:18 | say_godbye | test.rs:399:9:399:24 | await ... | | +| test.rs:399:9:399:24 | await ... | test.rs:400:9:400:19 | ExprStmt | | | test.rs:399:9:399:25 | ExprStmt | test.rs:399:9:399:18 | say_godbye | | -| test.rs:400:9:400:12 | noop | test.rs:400:9:400:18 | AwaitExpr | | -| test.rs:400:9:400:18 | AwaitExpr | test.rs:402:9:407:10 | LetStmt | | +| test.rs:400:9:400:12 | noop | test.rs:400:9:400:18 | await ... | | +| test.rs:400:9:400:18 | await ... | test.rs:402:9:407:10 | let lambda = ... | | | test.rs:400:9:400:19 | ExprStmt | test.rs:400:9:400:12 | noop | | -| test.rs:402:9:407:10 | LetStmt | test.rs:402:22:407:9 | ClosureExpr | | -| test.rs:402:13:402:18 | lambda | test.rs:389:35:408:5 | BlockExpr | match | -| test.rs:402:22:407:9 | ClosureExpr | test.rs:402:13:402:18 | lambda | | -| test.rs:402:22:407:9 | enter ClosureExpr | test.rs:402:23:402:25 | foo | | -| test.rs:402:22:407:9 | exit ClosureExpr (normal) | test.rs:402:22:407:9 | exit ClosureExpr | | -| test.rs:402:23:402:25 | Param | test.rs:402:28:407:9 | BlockExpr | | -| test.rs:402:23:402:25 | foo | test.rs:402:23:402:25 | Param | match | -| test.rs:402:28:407:9 | BlockExpr | test.rs:402:22:407:9 | exit ClosureExpr (normal) | | -| test.rs:402:28:407:9 | enter BlockExpr | test.rs:403:13:405:14 | ExprStmt | | -| test.rs:402:28:407:9 | exit BlockExpr (normal) | test.rs:402:28:407:9 | exit BlockExpr | | -| test.rs:403:13:405:13 | IfExpr | test.rs:406:13:406:15 | foo | | +| test.rs:402:9:407:10 | let lambda = ... | test.rs:402:22:407:9 | \|...\| ... | | +| test.rs:402:13:402:18 | lambda | test.rs:389:35:408:5 | { ... } | match | +| test.rs:402:22:407:9 | \|...\| ... | test.rs:402:13:402:18 | lambda | | +| test.rs:402:22:407:9 | enter \|...\| ... | test.rs:402:23:402:25 | foo | | +| test.rs:402:22:407:9 | exit \|...\| ... (normal) | test.rs:402:22:407:9 | exit \|...\| ... | | +| test.rs:402:23:402:25 | foo | test.rs:402:23:402:25 | foo | match | +| test.rs:402:23:402:25 | foo | test.rs:402:28:407:9 | { ... } | | +| test.rs:402:28:407:9 | enter { ... } | test.rs:403:13:405:14 | ExprStmt | | +| test.rs:402:28:407:9 | exit { ... } (normal) | test.rs:402:28:407:9 | exit { ... } | | +| test.rs:402:28:407:9 | { ... } | test.rs:402:22:407:9 | exit \|...\| ... (normal) | | +| test.rs:403:13:405:13 | if ... { ... } | test.rs:406:13:406:15 | foo | | | test.rs:403:13:405:14 | ExprStmt | test.rs:403:16:403:16 | b | | -| test.rs:403:16:403:16 | b | test.rs:403:13:405:13 | IfExpr | false | +| test.rs:403:16:403:16 | b | test.rs:403:13:405:13 | if ... { ... } | false | | test.rs:403:16:403:16 | b | test.rs:404:17:404:41 | ExprStmt | true | -| test.rs:404:17:404:40 | ReturnExpr | test.rs:402:28:407:9 | exit BlockExpr (normal) | return | +| test.rs:404:17:404:40 | return ... | test.rs:402:28:407:9 | exit { ... } (normal) | return | | test.rs:404:17:404:41 | ExprStmt | test.rs:404:24:404:34 | async_block | | | test.rs:404:24:404:34 | async_block | test.rs:404:36:404:39 | true | | -| test.rs:404:24:404:40 | CallExpr | test.rs:404:17:404:40 | ReturnExpr | | -| test.rs:404:36:404:39 | true | test.rs:404:24:404:40 | CallExpr | | -| test.rs:406:13:406:15 | foo | test.rs:402:28:407:9 | exit BlockExpr (normal) | | -| test.rs:414:5:416:5 | enter add_two | test.rs:414:22:414:22 | n | | -| test.rs:414:5:416:5 | exit add_two (normal) | test.rs:414:5:416:5 | exit add_two | | -| test.rs:414:22:414:22 | n | test.rs:414:22:414:27 | Param | match | -| test.rs:414:22:414:27 | Param | test.rs:415:9:415:9 | n | | -| test.rs:414:37:416:5 | BlockExpr | test.rs:414:5:416:5 | exit add_two (normal) | | +| test.rs:404:24:404:40 | async_block(...) | test.rs:404:17:404:40 | return ... | | +| test.rs:404:36:404:39 | true | test.rs:404:24:404:40 | async_block(...) | | +| test.rs:406:13:406:15 | foo | test.rs:402:28:407:9 | exit { ... } (normal) | | +| test.rs:414:5:416:5 | enter fn add_two | test.rs:414:22:414:22 | n | | +| test.rs:414:5:416:5 | exit fn add_two (normal) | test.rs:414:5:416:5 | exit fn add_two | | +| test.rs:414:22:414:22 | n | test.rs:414:22:414:27 | n: i64 | match | +| test.rs:414:22:414:27 | n: i64 | test.rs:415:9:415:9 | n | | +| test.rs:414:37:416:5 | { ... } | test.rs:414:5:416:5 | exit fn add_two (normal) | | | test.rs:415:9:415:9 | n | test.rs:415:13:415:13 | 2 | | -| test.rs:415:9:415:13 | ... + ... | test.rs:414:37:416:5 | BlockExpr | | +| test.rs:415:9:415:13 | ... + ... | test.rs:414:37:416:5 | { ... } | | | test.rs:415:13:415:13 | 2 | test.rs:415:9:415:13 | ... + ... | | -| test.rs:420:5:428:5 | enter const_block_assert | test.rs:423:9:425:9 | ExprStmt | | -| test.rs:420:5:428:5 | exit const_block_assert (normal) | test.rs:420:5:428:5 | exit const_block_assert | | -| test.rs:420:41:428:5 | BlockExpr | test.rs:420:5:428:5 | exit const_block_assert (normal) | | -| test.rs:423:9:425:9 | BlockExpr | test.rs:427:9:427:10 | 42 | | +| test.rs:420:5:428:5 | enter fn const_block_assert | test.rs:423:9:425:9 | ExprStmt | | +| test.rs:420:5:428:5 | exit fn const_block_assert (normal) | test.rs:420:5:428:5 | exit fn const_block_assert | | +| test.rs:420:41:428:5 | { ... } | test.rs:420:5:428:5 | exit fn const_block_assert (normal) | | | test.rs:423:9:425:9 | ExprStmt | test.rs:424:13:424:50 | ExprStmt | | -| test.rs:424:13:424:49 | $crate::panicking::panic_explicit | test.rs:424:13:424:49 | CallExpr | | -| test.rs:424:13:424:49 | BlockExpr | test.rs:424:13:424:49 | MacroExpr | | -| test.rs:424:13:424:49 | BlockExpr | test.rs:424:13:424:49 | exit panic_cold_explicit (normal) | | -| test.rs:424:13:424:49 | BlockExpr | test.rs:424:21:424:48 | IfExpr | | -| test.rs:424:13:424:49 | CallExpr | test.rs:424:13:424:49 | BlockExpr | | -| test.rs:424:13:424:49 | CallExpr | test.rs:424:13:424:49 | BlockExpr | | +| test.rs:423:9:425:9 | { ... } | test.rs:427:9:427:10 | 42 | | +| test.rs:424:13:424:49 | $crate::panicking::panic_explicit | test.rs:424:13:424:49 | $crate::panicking::panic_explicit(...) | | +| test.rs:424:13:424:49 | $crate::panicking::panic_explicit(...) | test.rs:424:13:424:49 | { ... } | | | test.rs:424:13:424:49 | ExprStmt | test.rs:424:13:424:49 | MacroStmts | | | test.rs:424:13:424:49 | ExprStmt | test.rs:424:13:424:49 | panic_cold_explicit | | -| test.rs:424:13:424:49 | MacroExpr | test.rs:423:9:425:9 | BlockExpr | | -| test.rs:424:13:424:49 | MacroExpr | test.rs:424:13:424:49 | BlockExpr | | -| test.rs:424:13:424:49 | MacroStmts | test.rs:424:13:424:49 | panic_cold_explicit | | -| test.rs:424:13:424:49 | enter panic_cold_explicit | test.rs:424:13:424:49 | $crate::panicking::panic_explicit | | -| test.rs:424:13:424:49 | exit panic_cold_explicit (normal) | test.rs:424:13:424:49 | exit panic_cold_explicit | | -| test.rs:424:13:424:49 | panic_cold_explicit | test.rs:424:13:424:49 | CallExpr | | -| test.rs:424:13:424:49 | panic_cold_explicit | test.rs:424:13:424:49 | ExprStmt | | +| test.rs:424:13:424:49 | MacroExpr | test.rs:423:9:425:9 | { ... } | | +| test.rs:424:13:424:49 | MacroExpr | test.rs:424:13:424:49 | { ... } | | +| test.rs:424:13:424:49 | MacroStmts | test.rs:424:13:424:49 | fn panic_cold_explicit | | +| test.rs:424:13:424:49 | enter fn panic_cold_explicit | test.rs:424:13:424:49 | $crate::panicking::panic_explicit | | +| test.rs:424:13:424:49 | exit fn panic_cold_explicit (normal) | test.rs:424:13:424:49 | exit fn panic_cold_explicit | | +| test.rs:424:13:424:49 | fn panic_cold_explicit | test.rs:424:13:424:49 | ExprStmt | | +| test.rs:424:13:424:49 | panic_cold_explicit | test.rs:424:13:424:49 | panic_cold_explicit(...) | | +| test.rs:424:13:424:49 | panic_cold_explicit(...) | test.rs:424:13:424:49 | { ... } | | +| test.rs:424:13:424:49 | { ... } | test.rs:424:13:424:49 | MacroExpr | | +| test.rs:424:13:424:49 | { ... } | test.rs:424:13:424:49 | exit fn panic_cold_explicit (normal) | | +| test.rs:424:13:424:49 | { ... } | test.rs:424:21:424:48 | if ... { ... } | | | test.rs:424:13:424:50 | ExprStmt | test.rs:424:21:424:48 | MacroStmts | | -| test.rs:424:21:424:42 | std::mem::size_of::<...> | test.rs:424:21:424:44 | CallExpr | | -| test.rs:424:21:424:44 | CallExpr | test.rs:424:48:424:48 | 0 | | +| test.rs:424:21:424:42 | std::mem::size_of::<...> | test.rs:424:21:424:44 | std::mem::size_of::<...>(...) | | +| test.rs:424:21:424:44 | std::mem::size_of::<...>(...) | test.rs:424:48:424:48 | 0 | | | test.rs:424:21:424:48 | ... > ... | test.rs:424:21:424:48 | [boolean(false)] ! ... | true | | test.rs:424:21:424:48 | ... > ... | test.rs:424:21:424:48 | [boolean(true)] ! ... | false | -| test.rs:424:21:424:48 | BlockExpr | test.rs:424:13:424:49 | MacroExpr | | -| test.rs:424:21:424:48 | IfExpr | test.rs:424:21:424:48 | BlockExpr | | | test.rs:424:21:424:48 | MacroStmts | test.rs:424:21:424:42 | std::mem::size_of::<...> | | -| test.rs:424:21:424:48 | [boolean(false)] ! ... | test.rs:424:21:424:48 | IfExpr | false | +| test.rs:424:21:424:48 | [boolean(false)] ! ... | test.rs:424:21:424:48 | if ... { ... } | false | | test.rs:424:21:424:48 | [boolean(true)] ! ... | test.rs:424:13:424:49 | ExprStmt | true | +| test.rs:424:21:424:48 | if ... { ... } | test.rs:424:21:424:48 | { ... } | | +| test.rs:424:21:424:48 | { ... } | test.rs:424:13:424:49 | MacroExpr | | | test.rs:424:48:424:48 | 0 | test.rs:424:21:424:48 | ... > ... | | -| test.rs:427:9:427:10 | 42 | test.rs:420:41:428:5 | BlockExpr | | -| test.rs:430:5:439:5 | enter const_block_panic | test.rs:431:9:431:30 | Const | | -| test.rs:430:5:439:5 | exit const_block_panic (normal) | test.rs:430:5:439:5 | exit const_block_panic | | -| test.rs:430:35:439:5 | BlockExpr | test.rs:430:5:439:5 | exit const_block_panic (normal) | | +| test.rs:427:9:427:10 | 42 | test.rs:420:41:428:5 | { ... } | | +| test.rs:430:5:439:5 | enter fn const_block_panic | test.rs:431:9:431:30 | Const | | +| test.rs:430:5:439:5 | exit fn const_block_panic (normal) | test.rs:430:5:439:5 | exit fn const_block_panic | | +| test.rs:430:35:439:5 | { ... } | test.rs:430:5:439:5 | exit fn const_block_panic (normal) | | | test.rs:431:9:431:30 | Const | test.rs:432:9:437:9 | ExprStmt | | | test.rs:432:9:437:9 | ExprStmt | test.rs:432:12:432:16 | false | | -| test.rs:432:9:437:9 | IfExpr | test.rs:438:9:438:9 | N | | -| test.rs:432:12:432:16 | false | test.rs:432:9:437:9 | IfExpr | false | -| test.rs:435:17:435:24 | $crate::panicking::panic_explicit | test.rs:435:17:435:24 | CallExpr | | -| test.rs:435:17:435:24 | BlockExpr | test.rs:435:17:435:24 | exit panic_cold_explicit (normal) | | -| test.rs:435:17:435:24 | CallExpr | test.rs:435:17:435:24 | BlockExpr | | -| test.rs:435:17:435:24 | enter panic_cold_explicit | test.rs:435:17:435:24 | $crate::panicking::panic_explicit | | -| test.rs:435:17:435:24 | exit panic_cold_explicit (normal) | test.rs:435:17:435:24 | exit panic_cold_explicit | | -| test.rs:438:9:438:9 | N | test.rs:430:35:439:5 | BlockExpr | | -| test.rs:442:1:447:1 | enter dead_code | test.rs:443:5:445:5 | ExprStmt | | -| test.rs:442:1:447:1 | exit dead_code (normal) | test.rs:442:1:447:1 | exit dead_code | | +| test.rs:432:9:437:9 | if ... { ... } | test.rs:438:9:438:9 | N | | +| test.rs:432:12:432:16 | false | test.rs:432:9:437:9 | if ... { ... } | false | +| test.rs:435:17:435:24 | $crate::panicking::panic_explicit | test.rs:435:17:435:24 | $crate::panicking::panic_explicit(...) | | +| test.rs:435:17:435:24 | $crate::panicking::panic_explicit(...) | test.rs:435:17:435:24 | { ... } | | +| test.rs:435:17:435:24 | enter fn panic_cold_explicit | test.rs:435:17:435:24 | $crate::panicking::panic_explicit | | +| test.rs:435:17:435:24 | exit fn panic_cold_explicit (normal) | test.rs:435:17:435:24 | exit fn panic_cold_explicit | | +| test.rs:435:17:435:24 | { ... } | test.rs:435:17:435:24 | exit fn panic_cold_explicit (normal) | | +| test.rs:438:9:438:9 | N | test.rs:430:35:439:5 | { ... } | | +| test.rs:442:1:447:1 | enter fn dead_code | test.rs:443:5:445:5 | ExprStmt | | +| test.rs:442:1:447:1 | exit fn dead_code (normal) | test.rs:442:1:447:1 | exit fn dead_code | | | test.rs:443:5:445:5 | ExprStmt | test.rs:443:9:443:12 | true | | | test.rs:443:9:443:12 | true | test.rs:444:9:444:17 | ExprStmt | true | -| test.rs:444:9:444:16 | ReturnExpr | test.rs:442:1:447:1 | exit dead_code (normal) | return | +| test.rs:444:9:444:16 | return ... | test.rs:442:1:447:1 | exit fn dead_code (normal) | return | | test.rs:444:9:444:17 | ExprStmt | test.rs:444:16:444:16 | 0 | | -| test.rs:444:16:444:16 | 0 | test.rs:444:9:444:16 | ReturnExpr | | -| test.rs:449:1:449:16 | enter do_thing | test.rs:449:15:449:16 | BlockExpr | | -| test.rs:449:1:449:16 | exit do_thing (normal) | test.rs:449:1:449:16 | exit do_thing | | -| test.rs:449:15:449:16 | BlockExpr | test.rs:449:1:449:16 | exit do_thing (normal) | | -| test.rs:451:1:453:1 | enter condition_not_met | test.rs:452:5:452:9 | false | | -| test.rs:451:1:453:1 | exit condition_not_met (normal) | test.rs:451:1:453:1 | exit condition_not_met | | -| test.rs:451:32:453:1 | BlockExpr | test.rs:451:1:453:1 | exit condition_not_met (normal) | | -| test.rs:452:5:452:9 | false | test.rs:451:32:453:1 | BlockExpr | | -| test.rs:455:1:455:21 | enter do_next_thing | test.rs:455:20:455:21 | BlockExpr | | -| test.rs:455:1:455:21 | exit do_next_thing (normal) | test.rs:455:1:455:21 | exit do_next_thing | | -| test.rs:455:20:455:21 | BlockExpr | test.rs:455:1:455:21 | exit do_next_thing (normal) | | -| test.rs:457:1:457:21 | enter do_last_thing | test.rs:457:20:457:21 | BlockExpr | | -| test.rs:457:1:457:21 | exit do_last_thing (normal) | test.rs:457:1:457:21 | exit do_last_thing | | -| test.rs:457:20:457:21 | BlockExpr | test.rs:457:1:457:21 | exit do_last_thing (normal) | | -| test.rs:459:1:473:1 | enter labelled_block1 | test.rs:460:5:471:6 | LetStmt | | -| test.rs:459:1:473:1 | exit labelled_block1 (normal) | test.rs:459:1:473:1 | exit labelled_block1 | | -| test.rs:459:29:473:1 | BlockExpr | test.rs:459:1:473:1 | exit labelled_block1 (normal) | | -| test.rs:460:5:471:6 | LetStmt | test.rs:461:9:461:19 | ExprStmt | | +| test.rs:444:16:444:16 | 0 | test.rs:444:9:444:16 | return ... | | +| test.rs:449:1:449:16 | enter fn do_thing | test.rs:449:15:449:16 | { ... } | | +| test.rs:449:1:449:16 | exit fn do_thing (normal) | test.rs:449:1:449:16 | exit fn do_thing | | +| test.rs:449:15:449:16 | { ... } | test.rs:449:1:449:16 | exit fn do_thing (normal) | | +| test.rs:451:1:453:1 | enter fn condition_not_met | test.rs:452:5:452:9 | false | | +| test.rs:451:1:453:1 | exit fn condition_not_met (normal) | test.rs:451:1:453:1 | exit fn condition_not_met | | +| test.rs:451:32:453:1 | { ... } | test.rs:451:1:453:1 | exit fn condition_not_met (normal) | | +| test.rs:452:5:452:9 | false | test.rs:451:32:453:1 | { ... } | | +| test.rs:455:1:455:21 | enter fn do_next_thing | test.rs:455:20:455:21 | { ... } | | +| test.rs:455:1:455:21 | exit fn do_next_thing (normal) | test.rs:455:1:455:21 | exit fn do_next_thing | | +| test.rs:455:20:455:21 | { ... } | test.rs:455:1:455:21 | exit fn do_next_thing (normal) | | +| test.rs:457:1:457:21 | enter fn do_last_thing | test.rs:457:20:457:21 | { ... } | | +| test.rs:457:1:457:21 | exit fn do_last_thing (normal) | test.rs:457:1:457:21 | exit fn do_last_thing | | +| test.rs:457:20:457:21 | { ... } | test.rs:457:1:457:21 | exit fn do_last_thing (normal) | | +| test.rs:459:1:473:1 | enter fn labelled_block1 | test.rs:460:5:471:6 | let result = ... | | +| test.rs:459:1:473:1 | exit fn labelled_block1 (normal) | test.rs:459:1:473:1 | exit fn labelled_block1 | | +| test.rs:459:29:473:1 | { ... } | test.rs:459:1:473:1 | exit fn labelled_block1 (normal) | | +| test.rs:460:5:471:6 | let result = ... | test.rs:461:9:461:19 | ExprStmt | | | test.rs:460:9:460:14 | result | test.rs:472:5:472:10 | result | match | -| test.rs:460:18:471:5 | BlockExpr | test.rs:460:9:460:14 | result | | -| test.rs:461:9:461:16 | do_thing | test.rs:461:9:461:18 | CallExpr | | -| test.rs:461:9:461:18 | CallExpr | test.rs:462:9:464:9 | ExprStmt | | +| test.rs:460:18:471:5 | { ... } | test.rs:460:9:460:14 | result | | +| test.rs:461:9:461:16 | do_thing | test.rs:461:9:461:18 | do_thing(...) | | +| test.rs:461:9:461:18 | do_thing(...) | test.rs:462:9:464:9 | ExprStmt | | | test.rs:461:9:461:19 | ExprStmt | test.rs:461:9:461:16 | do_thing | | | test.rs:462:9:464:9 | ExprStmt | test.rs:462:12:462:28 | condition_not_met | | -| test.rs:462:9:464:9 | IfExpr | test.rs:465:9:465:24 | ExprStmt | | -| test.rs:462:12:462:28 | condition_not_met | test.rs:462:12:462:30 | CallExpr | | -| test.rs:462:12:462:30 | CallExpr | test.rs:462:9:464:9 | IfExpr | false | -| test.rs:462:12:462:30 | CallExpr | test.rs:463:13:463:27 | ExprStmt | true | -| test.rs:463:13:463:26 | BreakExpr | test.rs:460:18:471:5 | BlockExpr | break | +| test.rs:462:9:464:9 | if ... { ... } | test.rs:465:9:465:24 | ExprStmt | | +| test.rs:462:12:462:28 | condition_not_met | test.rs:462:12:462:30 | condition_not_met(...) | | +| test.rs:462:12:462:30 | condition_not_met(...) | test.rs:462:9:464:9 | if ... { ... } | false | +| test.rs:462:12:462:30 | condition_not_met(...) | test.rs:463:13:463:27 | ExprStmt | true | +| test.rs:463:13:463:26 | break ''block ... | test.rs:460:18:471:5 | { ... } | break | | test.rs:463:13:463:27 | ExprStmt | test.rs:463:26:463:26 | 1 | | -| test.rs:463:26:463:26 | 1 | test.rs:463:13:463:26 | BreakExpr | | -| test.rs:465:9:465:21 | do_next_thing | test.rs:465:9:465:23 | CallExpr | | -| test.rs:465:9:465:23 | CallExpr | test.rs:466:9:468:9 | ExprStmt | | +| test.rs:463:26:463:26 | 1 | test.rs:463:13:463:26 | break ''block ... | | +| test.rs:465:9:465:21 | do_next_thing | test.rs:465:9:465:23 | do_next_thing(...) | | +| test.rs:465:9:465:23 | do_next_thing(...) | test.rs:466:9:468:9 | ExprStmt | | | test.rs:465:9:465:24 | ExprStmt | test.rs:465:9:465:21 | do_next_thing | | | test.rs:466:9:468:9 | ExprStmt | test.rs:466:12:466:28 | condition_not_met | | -| test.rs:466:9:468:9 | IfExpr | test.rs:469:9:469:24 | ExprStmt | | -| test.rs:466:12:466:28 | condition_not_met | test.rs:466:12:466:30 | CallExpr | | -| test.rs:466:12:466:30 | CallExpr | test.rs:466:9:468:9 | IfExpr | false | -| test.rs:466:12:466:30 | CallExpr | test.rs:467:13:467:27 | ExprStmt | true | -| test.rs:467:13:467:26 | BreakExpr | test.rs:460:18:471:5 | BlockExpr | break | +| test.rs:466:9:468:9 | if ... { ... } | test.rs:469:9:469:24 | ExprStmt | | +| test.rs:466:12:466:28 | condition_not_met | test.rs:466:12:466:30 | condition_not_met(...) | | +| test.rs:466:12:466:30 | condition_not_met(...) | test.rs:466:9:468:9 | if ... { ... } | false | +| test.rs:466:12:466:30 | condition_not_met(...) | test.rs:467:13:467:27 | ExprStmt | true | +| test.rs:467:13:467:26 | break ''block ... | test.rs:460:18:471:5 | { ... } | break | | test.rs:467:13:467:27 | ExprStmt | test.rs:467:26:467:26 | 2 | | -| test.rs:467:26:467:26 | 2 | test.rs:467:13:467:26 | BreakExpr | | -| test.rs:469:9:469:21 | do_last_thing | test.rs:469:9:469:23 | CallExpr | | -| test.rs:469:9:469:23 | CallExpr | test.rs:470:9:470:9 | 3 | | +| test.rs:467:26:467:26 | 2 | test.rs:467:13:467:26 | break ''block ... | | +| test.rs:469:9:469:21 | do_last_thing | test.rs:469:9:469:23 | do_last_thing(...) | | +| test.rs:469:9:469:23 | do_last_thing(...) | test.rs:470:9:470:9 | 3 | | | test.rs:469:9:469:24 | ExprStmt | test.rs:469:9:469:21 | do_last_thing | | -| test.rs:470:9:470:9 | 3 | test.rs:460:18:471:5 | BlockExpr | | -| test.rs:472:5:472:10 | result | test.rs:459:29:473:1 | BlockExpr | | -| test.rs:475:1:483:1 | enter labelled_block2 | test.rs:476:5:482:6 | LetStmt | | -| test.rs:475:1:483:1 | exit labelled_block2 (normal) | test.rs:475:1:483:1 | exit labelled_block2 | | -| test.rs:475:22:483:1 | BlockExpr | test.rs:475:1:483:1 | exit labelled_block2 (normal) | | -| test.rs:476:5:482:6 | LetStmt | test.rs:477:9:477:34 | LetStmt | | -| test.rs:476:9:476:14 | result | test.rs:475:22:483:1 | BlockExpr | match | -| test.rs:476:18:482:5 | BlockExpr | test.rs:476:9:476:14 | result | | -| test.rs:477:9:477:34 | LetStmt | test.rs:477:30:477:33 | None | | -| test.rs:477:13:477:13 | x | test.rs:478:9:480:10 | LetStmt | match | +| test.rs:470:9:470:9 | 3 | test.rs:460:18:471:5 | { ... } | | +| test.rs:472:5:472:10 | result | test.rs:459:29:473:1 | { ... } | | +| test.rs:475:1:483:1 | enter fn labelled_block2 | test.rs:476:5:482:6 | let result = ... | | +| test.rs:475:1:483:1 | exit fn labelled_block2 (normal) | test.rs:475:1:483:1 | exit fn labelled_block2 | | +| test.rs:475:22:483:1 | { ... } | test.rs:475:1:483:1 | exit fn labelled_block2 (normal) | | +| test.rs:476:5:482:6 | let result = ... | test.rs:477:9:477:34 | let x = ... | | +| test.rs:476:9:476:14 | result | test.rs:475:22:483:1 | { ... } | match | +| test.rs:476:18:482:5 | { ... } | test.rs:476:9:476:14 | result | | +| test.rs:477:9:477:34 | let x = ... | test.rs:477:30:477:33 | None | | +| test.rs:477:13:477:13 | x | test.rs:478:9:480:10 | let TupleStructPat = ... else { ... } | match | | test.rs:477:30:477:33 | None | test.rs:477:13:477:13 | x | | -| test.rs:478:9:480:10 | LetStmt | test.rs:478:23:478:23 | x | | +| test.rs:478:9:480:10 | let TupleStructPat = ... else { ... } | test.rs:478:23:478:23 | x | | | test.rs:478:13:478:19 | TupleStructPat | test.rs:478:18:478:18 | y | match | | test.rs:478:13:478:19 | TupleStructPat | test.rs:479:13:479:27 | ExprStmt | no-match | | test.rs:478:18:478:18 | y | test.rs:481:9:481:9 | 0 | match | | test.rs:478:23:478:23 | x | test.rs:478:13:478:19 | TupleStructPat | | -| test.rs:479:13:479:26 | BreakExpr | test.rs:476:18:482:5 | BlockExpr | break | +| test.rs:479:13:479:26 | break ''block ... | test.rs:476:18:482:5 | { ... } | break | | test.rs:479:13:479:27 | ExprStmt | test.rs:479:26:479:26 | 1 | | -| test.rs:479:26:479:26 | 1 | test.rs:479:13:479:26 | BreakExpr | | -| test.rs:481:9:481:9 | 0 | test.rs:476:18:482:5 | BlockExpr | | -| test.rs:485:1:491:1 | enter test_nested_function2 | test.rs:486:5:486:18 | LetStmt | | -| test.rs:485:1:491:1 | exit test_nested_function2 (normal) | test.rs:485:1:491:1 | exit test_nested_function2 | | -| test.rs:485:28:491:1 | BlockExpr | test.rs:485:1:491:1 | exit test_nested_function2 (normal) | | -| test.rs:486:5:486:18 | LetStmt | test.rs:486:17:486:17 | 0 | | -| test.rs:486:9:486:13 | x | test.rs:487:5:489:5 | nested | match | +| test.rs:479:26:479:26 | 1 | test.rs:479:13:479:26 | break ''block ... | | +| test.rs:481:9:481:9 | 0 | test.rs:476:18:482:5 | { ... } | | +| test.rs:485:1:491:1 | enter fn test_nested_function2 | test.rs:486:5:486:18 | let x = ... | | +| test.rs:485:1:491:1 | exit fn test_nested_function2 (normal) | test.rs:485:1:491:1 | exit fn test_nested_function2 | | +| test.rs:485:28:491:1 | { ... } | test.rs:485:1:491:1 | exit fn test_nested_function2 (normal) | | +| test.rs:486:5:486:18 | let x = ... | test.rs:486:17:486:17 | 0 | | +| test.rs:486:9:486:13 | x | test.rs:487:5:489:5 | fn nested | match | | test.rs:486:17:486:17 | 0 | test.rs:486:9:486:13 | x | | -| test.rs:487:5:489:5 | enter nested | test.rs:487:15:487:15 | x | | -| test.rs:487:5:489:5 | exit nested (normal) | test.rs:487:5:489:5 | exit nested | | -| test.rs:487:5:489:5 | nested | test.rs:490:5:490:19 | ExprStmt | | -| test.rs:487:15:487:15 | x | test.rs:487:15:487:25 | Param | match | -| test.rs:487:15:487:25 | Param | test.rs:488:9:488:16 | ExprStmt | | -| test.rs:487:28:489:5 | BlockExpr | test.rs:487:5:489:5 | exit nested (normal) | | +| test.rs:487:5:489:5 | enter fn nested | test.rs:487:15:487:15 | x | | +| test.rs:487:5:489:5 | exit fn nested (normal) | test.rs:487:5:489:5 | exit fn nested | | +| test.rs:487:5:489:5 | fn nested | test.rs:490:5:490:19 | ExprStmt | | +| test.rs:487:15:487:15 | x | test.rs:487:15:487:25 | x: RefType | match | +| test.rs:487:15:487:25 | x: RefType | test.rs:488:9:488:16 | ExprStmt | | +| test.rs:487:28:489:5 | { ... } | test.rs:487:5:489:5 | exit fn nested (normal) | | | test.rs:488:9:488:10 | * ... | test.rs:488:15:488:15 | 1 | | -| test.rs:488:9:488:15 | ... += ... | test.rs:487:28:489:5 | BlockExpr | | +| test.rs:488:9:488:15 | ... += ... | test.rs:487:28:489:5 | { ... } | | | test.rs:488:9:488:16 | ExprStmt | test.rs:488:10:488:10 | x | | | test.rs:488:10:488:10 | x | test.rs:488:9:488:10 | * ... | | | test.rs:488:15:488:15 | 1 | test.rs:488:9:488:15 | ... += ... | | | test.rs:490:5:490:10 | nested | test.rs:490:17:490:17 | x | | -| test.rs:490:5:490:18 | CallExpr | test.rs:485:28:491:1 | BlockExpr | | +| test.rs:490:5:490:18 | nested(...) | test.rs:485:28:491:1 | { ... } | | | test.rs:490:5:490:19 | ExprStmt | test.rs:490:5:490:10 | nested | | -| test.rs:490:12:490:17 | RefExpr | test.rs:490:5:490:18 | CallExpr | | -| test.rs:490:17:490:17 | x | test.rs:490:12:490:17 | RefExpr | | +| test.rs:490:12:490:17 | &mut ... | test.rs:490:5:490:18 | nested(...) | | +| test.rs:490:17:490:17 | x | test.rs:490:12:490:17 | &mut ... | | breakTarget -| test.rs:34:17:34:21 | BreakExpr | test.rs:28:9:40:9 | LoopExpr | -| test.rs:48:21:48:25 | BreakExpr | test.rs:46:13:53:13 | LoopExpr | -| test.rs:50:21:50:32 | BreakExpr | test.rs:45:9:54:9 | LoopExpr | -| test.rs:52:17:52:28 | BreakExpr | test.rs:46:13:53:13 | LoopExpr | -| test.rs:91:17:91:21 | BreakExpr | test.rs:88:9:94:9 | WhileExpr | -| test.rs:101:17:101:21 | BreakExpr | test.rs:99:9:103:9 | WhileExpr | -| test.rs:109:17:109:21 | BreakExpr | test.rs:107:9:112:9 | ForExpr | -| test.rs:117:13:117:26 | BreakExpr | test.rs:116:9:118:9 | LoopExpr | -| test.rs:197:17:197:28 | BreakExpr | test.rs:195:13:200:9 | LoopExpr | -| test.rs:210:17:210:35 | BreakExpr | test.rs:208:13:213:9 | LoopExpr | -| test.rs:222:13:222:30 | BreakExpr | test.rs:221:13:223:9 | BlockExpr | -| test.rs:463:13:463:26 | BreakExpr | test.rs:460:18:471:5 | BlockExpr | -| test.rs:467:13:467:26 | BreakExpr | test.rs:460:18:471:5 | BlockExpr | -| test.rs:479:13:479:26 | BreakExpr | test.rs:476:18:482:5 | BlockExpr | +| test.rs:34:17:34:21 | break | test.rs:28:9:40:9 | loop {...} | +| test.rs:48:21:48:25 | break | test.rs:46:13:53:13 | loop {...} | +| test.rs:50:21:50:32 | break ''outer | test.rs:45:9:54:9 | loop {...} | +| test.rs:52:17:52:28 | break ''inner | test.rs:46:13:53:13 | loop {...} | +| test.rs:91:17:91:21 | break | test.rs:88:9:94:9 | while ... { ... } | +| test.rs:101:17:101:21 | break | test.rs:99:9:103:9 | while ... { ... } | +| test.rs:109:17:109:21 | break | test.rs:107:9:112:9 | for i in ... { ... } | +| test.rs:117:13:117:26 | break ... | test.rs:116:9:118:9 | loop {...} | +| test.rs:197:17:197:28 | break ... | test.rs:195:13:200:9 | loop {...} | +| test.rs:210:17:210:35 | break ''label ... | test.rs:208:13:213:9 | loop {...} | +| test.rs:222:13:222:30 | break ''block ... | test.rs:221:13:223:9 | { ... } | +| test.rs:463:13:463:26 | break ''block ... | test.rs:460:18:471:5 | { ... } | +| test.rs:467:13:467:26 | break ''block ... | test.rs:460:18:471:5 | { ... } | +| test.rs:479:13:479:26 | break ''block ... | test.rs:476:18:482:5 | { ... } | continueTarget -| test.rs:37:17:37:24 | ContinueExpr | test.rs:28:9:40:9 | LoopExpr | -| test.rs:63:21:63:28 | ContinueExpr | test.rs:61:13:68:13 | LoopExpr | -| test.rs:65:21:65:35 | ContinueExpr | test.rs:59:9:69:9 | LoopExpr | -| test.rs:67:17:67:31 | ContinueExpr | test.rs:61:13:68:13 | LoopExpr | -| test.rs:77:21:77:28 | ContinueExpr | test.rs:75:13:82:13 | LoopExpr | -| test.rs:79:21:79:35 | ContinueExpr | test.rs:75:13:82:13 | LoopExpr | -| test.rs:81:17:81:31 | ContinueExpr | test.rs:75:13:82:13 | LoopExpr | +| test.rs:37:17:37:24 | continue | test.rs:28:9:40:9 | loop {...} | +| test.rs:63:21:63:28 | continue | test.rs:61:13:68:13 | loop {...} | +| test.rs:65:21:65:35 | continue 'outer | test.rs:59:9:69:9 | loop {...} | +| test.rs:67:17:67:31 | continue 'inner | test.rs:61:13:68:13 | loop {...} | +| test.rs:77:21:77:28 | continue | test.rs:75:13:82:13 | loop {...} | +| test.rs:79:21:79:35 | continue 'label | test.rs:75:13:82:13 | loop {...} | +| test.rs:81:17:81:31 | continue 'label | test.rs:75:13:82:13 | loop {...} | diff --git a/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected b/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected index a54c75d0c17..c8d53f467e9 100644 --- a/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected @@ -1,16 +1,16 @@ models edges -| main.rs:21:13:21:21 | CallExpr : unit | main.rs:22:10:22:10 | s | provenance | | -| main.rs:32:13:32:21 | CallExpr : unit | main.rs:33:10:33:10 | s | provenance | | +| main.rs:21:13:21:21 | source(...) : unit | main.rs:22:10:22:10 | s | provenance | | +| main.rs:32:13:32:21 | source(...) : unit | main.rs:33:10:33:10 | s | provenance | | nodes -| main.rs:17:10:17:18 | CallExpr | semmle.label | CallExpr | -| main.rs:21:13:21:21 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:17:10:17:18 | source(...) | semmle.label | source(...) | +| main.rs:21:13:21:21 | source(...) : unit | semmle.label | source(...) : unit | | main.rs:22:10:22:10 | s | semmle.label | s | -| main.rs:32:13:32:21 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:32:13:32:21 | source(...) : unit | semmle.label | source(...) : unit | | main.rs:33:10:33:10 | s | semmle.label | s | subpaths testFailures #select -| main.rs:17:10:17:18 | CallExpr | main.rs:17:10:17:18 | CallExpr | main.rs:17:10:17:18 | CallExpr | $@ | main.rs:17:10:17:18 | CallExpr | CallExpr | -| main.rs:22:10:22:10 | s | main.rs:21:13:21:21 | CallExpr : unit | main.rs:22:10:22:10 | s | $@ | main.rs:21:13:21:21 | CallExpr : unit | CallExpr : unit | -| main.rs:33:10:33:10 | s | main.rs:32:13:32:21 | CallExpr : unit | main.rs:33:10:33:10 | s | $@ | main.rs:32:13:32:21 | CallExpr : unit | CallExpr : unit | +| main.rs:17:10:17:18 | source(...) | main.rs:17:10:17:18 | source(...) | main.rs:17:10:17:18 | source(...) | $@ | main.rs:17:10:17:18 | source(...) | source(...) | +| main.rs:22:10:22:10 | s | main.rs:21:13:21:21 | source(...) : unit | main.rs:22:10:22:10 | s | $@ | main.rs:21:13:21:21 | source(...) : unit | source(...) : unit | +| main.rs:33:10:33:10 | s | main.rs:32:13:32:21 | source(...) : unit | main.rs:33:10:33:10 | s | $@ | main.rs:32:13:32:21 | source(...) : unit | source(...) : unit | diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index e12f2e14d19..3639294bd49 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -34,13 +34,13 @@ | main.rs:40:9:40:9 | [SSA] a | main.rs:43:10:43:10 | a | | main.rs:40:9:40:9 | a | main.rs:40:9:40:9 | [SSA] a | | main.rs:40:13:42:5 | loop {...} | main.rs:40:9:40:9 | a | -| main.rs:41:9:41:15 | (no string representation) | main.rs:40:13:42:5 | loop {...} | -| main.rs:41:15:41:15 | 1 | main.rs:41:9:41:15 | (no string representation) | +| main.rs:41:9:41:15 | break ... | main.rs:40:13:42:5 | loop {...} | +| main.rs:41:15:41:15 | 1 | main.rs:41:9:41:15 | break ... | | main.rs:44:9:44:9 | [SSA] b | main.rs:47:10:47:10 | b | | main.rs:44:9:44:9 | b | main.rs:44:9:44:9 | [SSA] b | | main.rs:44:13:46:5 | loop {...} | main.rs:44:9:44:9 | b | -| main.rs:45:9:45:23 | (no string representation) | main.rs:44:13:46:5 | loop {...} | -| main.rs:45:15:45:23 | source(...) | main.rs:45:9:45:23 | (no string representation) | +| main.rs:45:9:45:23 | break ... | main.rs:44:13:46:5 | loop {...} | +| main.rs:45:15:45:23 | source(...) | main.rs:45:9:45:23 | break ... | | main.rs:51:9:51:13 | [SSA] i | main.rs:52:10:52:10 | i | | main.rs:51:9:51:13 | i | main.rs:51:9:51:13 | [SSA] i | | main.rs:51:17:51:17 | 1 | main.rs:51:9:51:13 | i | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index ea439e78d5b..b4c292a93d9 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -1,2 +1,24 @@ -ERROR: empty recursive call: dispatch predicate for CommentImpl::Impl::Comment::getCommentMarker (CommentImpl.qll:23,47-63) -ERROR: empty recursive call: dispatch predicate for CommentImpl::Impl::Comment::getText (CommentImpl.qll:36,34-41) +models +edges +| main.rs:19:13:19:21 | source(...) : unit | main.rs:20:10:20:10 | s | provenance | | +| main.rs:24:13:24:21 | source(...) : unit | main.rs:27:10:27:10 | c | provenance | | +| main.rs:31:13:31:21 | source(...) : unit | main.rs:36:10:36:10 | b | provenance | | +| main.rs:45:15:45:23 | source(...) : unit | main.rs:47:10:47:10 | b | provenance | | +nodes +| main.rs:15:10:15:18 | source(...) | semmle.label | source(...) | +| main.rs:19:13:19:21 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:20:10:20:10 | s | semmle.label | s | +| main.rs:24:13:24:21 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:27:10:27:10 | c | semmle.label | c | +| main.rs:31:13:31:21 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:36:10:36:10 | b | semmle.label | b | +| main.rs:45:15:45:23 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:47:10:47:10 | b | semmle.label | b | +subpaths +testFailures +#select +| main.rs:15:10:15:18 | source(...) | main.rs:15:10:15:18 | source(...) | main.rs:15:10:15:18 | source(...) | $@ | main.rs:15:10:15:18 | source(...) | source(...) | +| main.rs:20:10:20:10 | s | main.rs:19:13:19:21 | source(...) : unit | main.rs:20:10:20:10 | s | $@ | main.rs:19:13:19:21 | source(...) : unit | source(...) : unit | +| main.rs:27:10:27:10 | c | main.rs:24:13:24:21 | source(...) : unit | main.rs:27:10:27:10 | c | $@ | main.rs:24:13:24:21 | source(...) : unit | source(...) : unit | +| main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | source(...) : unit | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | source(...) : unit | source(...) : unit | +| main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | source(...) : unit | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | source(...) : unit | source(...) : unit | diff --git a/rust/ql/test/query-tests/diagnostics/DataFlowConsistencyCounts.expected b/rust/ql/test/query-tests/diagnostics/DataFlowConsistencyCounts.expected index 9c96e0fa334..4d1cdfed89a 100644 --- a/rust/ql/test/query-tests/diagnostics/DataFlowConsistencyCounts.expected +++ b/rust/ql/test/query-tests/diagnostics/DataFlowConsistencyCounts.expected @@ -11,7 +11,7 @@ | Node has multiple PostUpdateNodes | 0 | | Node should have one enclosing callable | 0 | | Node should have one location | 0 | -| Node should have one toString | 1 | +| Node should have one toString | 0 | | Node should have one type | 0 | | Node steps to itself | 0 | | Nodes without location | 0 | diff --git a/rust/ql/test/query-tests/diagnostics/ExtractionWarnings.expected b/rust/ql/test/query-tests/diagnostics/ExtractionWarnings.expected index 1ebd7e23221..5ea7e808176 100644 --- a/rust/ql/test/query-tests/diagnostics/ExtractionWarnings.expected +++ b/rust/ql/test/query-tests/diagnostics/ExtractionWarnings.expected @@ -3,5 +3,4 @@ | does_not_compile.rs:2:13:2:12 | expected SEMICOLON | Extraction warning in does_not_compile.rs with message expected SEMICOLON | 1 | | does_not_compile.rs:2:21:2:20 | expected SEMICOLON | Extraction warning in does_not_compile.rs with message expected SEMICOLON | 1 | | does_not_compile.rs:2:26:2:25 | expected SEMICOLON | Extraction warning in does_not_compile.rs with message expected SEMICOLON | 1 | -| does_not_compile.rs:2:32:2:31 | expected field name or number | Extraction warning in does_not_compile.rs with message expected field name or number | 1 | | error.rs:2:5:2:17 | An error! | Extraction warning in error.rs with message An error! | 1 | diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index a3330d0eb1e..a1ece2b1fd7 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -1,12 +1,12 @@ -| Elements extracted | 376 | +| Elements extracted | 375 | | Elements unextracted | 0 | | Extraction errors | 0 | -| Extraction warnings | 7 | +| Extraction warnings | 6 | | Files extracted - total | 8 | | Files extracted - with errors | 2 | | Files extracted - without errors | 6 | | Inconsistencies - AST | 0 | | Inconsistencies - CFG | 0 | -| Inconsistencies - data flow | 1 | +| Inconsistencies - data flow | 0 | | Lines of code extracted | 59 | | Lines of user code extracted | 59 | diff --git a/rust/ql/test/query-tests/diagnostics/does_not_compile.rs b/rust/ql/test/query-tests/diagnostics/does_not_compile.rs index 9aedaffcd93..15f85e1ab4b 100644 --- a/rust/ql/test/query-tests/diagnostics/does_not_compile.rs +++ b/rust/ql/test/query-tests/diagnostics/does_not_compile.rs @@ -1,3 +1,3 @@ pub fn my_func() { - This is not correct Rust code. + This is not correct Rust code } From 52cd7f2c5c9d49b14975d02abf944500b5975c18 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 20 Nov 2024 11:22:42 +0000 Subject: [PATCH 116/470] Add 2 more cases --- .../dataflow/global-or-captured-vars/test.py | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py index f60458ca4f9..7719021890f 100644 --- a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py +++ b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py @@ -85,4 +85,34 @@ def baz7(loc_foo): threading.Thread(target=bar7).start() -baz7(foo7) \ No newline at end of file +baz7(foo7) + +# Test 8 +# FN - Flow is also *not* found in the above case through a direct call + +foo8 = [] + +def bar8(): + time.sleep(1) + ensure_tainted(foo8[0]) # $MISSING: tainted + +def baz8(loc_foo): + loc_foo.append(TAINTED_STRING) + +baz8(foo8) +bar8() + +# Test 9 +# TP - Flow is found in the above case when the variable is captured rather than global + +def test9(): + foo9 = [] + def bar9(): + time.sleep(1) + ensure_tainted(foo9[0]) # $tainted + + def baz9(loc_foo): + loc_foo.append(TAINTED_STRING) + + baz9(foo9) + bar9() \ No newline at end of file From aab0d5e9e4fbdf3447b928c0239f0bdb2ef394ac Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 20 Nov 2024 12:35:52 +0100 Subject: [PATCH 117/470] Rust: Refactor to avoid needing `getNumberOfSelfParams` --- .../rust/controlflow/internal/ControlFlowGraphImpl.qll | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index ef4f7808fa2..938b933cba0 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -72,17 +72,13 @@ import CfgImpl class CallableScopeTree extends StandardTree, PreOrderTree, PostOrderTree, Scope::CallableScope { override predicate propagatesAbnormal(AstNode child) { none() } - private int getNumberOfSelfParams() { - if this.getParamList().hasSelfParam() then result = 1 else result = 0 - } - override AstNode getChildNode(int i) { i = 0 and result = this.getParamList().getSelfParam() or - result = this.getParamList().getParam(i - this.getNumberOfSelfParams()) + result = this.getParamList().getParam(i - 1) or - i = this.getParamList().getNumberOfParams() + this.getNumberOfSelfParams() and + i = this.getParamList().getNumberOfParams() + 1 and result = this.getBody() } } From 93f6f042e1a1b144f3bc8f3cfa2f2105da99794f Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 20 Nov 2024 12:39:31 +0100 Subject: [PATCH 118/470] Rust: Update expected file --- rust/ql/test/library-tests/variables/Cfg.expected | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected index 3ff46aa9f7e..bb635f78879 100644 --- a/rust/ql/test/library-tests/variables/Cfg.expected +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -1070,8 +1070,10 @@ edges | variables.rs:472:9:472:20 | CallExpr | variables.rs:471:12:473:5 | BlockExpr | | | variables.rs:472:9:472:21 | ExprStmt | variables.rs:472:9:472:17 | print_i64 | | | variables.rs:472:19:472:19 | x | variables.rs:472:9:472:20 | CallExpr | | -| variables.rs:482:5:484:5 | enter my_get | variables.rs:483:9:483:24 | ExprStmt | | +| variables.rs:482:5:484:5 | enter my_get | variables.rs:482:20:482:23 | self | | | variables.rs:482:5:484:5 | exit my_get (normal) | variables.rs:482:5:484:5 | exit my_get | | +| variables.rs:482:15:482:23 | SelfParam | variables.rs:483:9:483:24 | ExprStmt | | +| variables.rs:482:20:482:23 | self | variables.rs:482:15:482:23 | SelfParam | | | variables.rs:483:9:483:23 | ReturnExpr | variables.rs:482:5:484:5 | exit my_get (normal) | return | | variables.rs:483:9:483:24 | ExprStmt | variables.rs:483:16:483:19 | self | | | variables.rs:483:16:483:19 | self | variables.rs:483:16:483:23 | FieldExpr | | @@ -1131,8 +1133,10 @@ edges | variables.rs:502:5:502:22 | ExprStmt | variables.rs:502:5:502:17 | print_i64_ref | | | variables.rs:502:19:502:20 | RefExpr | variables.rs:502:5:502:21 | CallExpr | | | variables.rs:502:20:502:20 | z | variables.rs:502:19:502:20 | RefExpr | | -| variables.rs:510:3:512:3 | enter bar | variables.rs:511:5:511:32 | ExprStmt | | +| variables.rs:510:3:512:3 | enter bar | variables.rs:510:15:510:18 | self | | | variables.rs:510:3:512:3 | exit bar (normal) | variables.rs:510:3:512:3 | exit bar | | +| variables.rs:510:10:510:18 | SelfParam | variables.rs:511:5:511:32 | ExprStmt | | +| variables.rs:510:15:510:18 | self | variables.rs:510:10:510:18 | SelfParam | | | variables.rs:510:21:512:3 | BlockExpr | variables.rs:510:3:512:3 | exit bar (normal) | | | variables.rs:511:5:511:9 | * ... | variables.rs:511:29:511:29 | 3 | | | variables.rs:511:5:511:31 | ... = ... | variables.rs:510:21:512:3 | BlockExpr | | From e5eed2302f40bbf57dcd5f3b8a2d33281faf9831 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 30 Oct 2024 14:56:55 +0100 Subject: [PATCH 119/470] Data flow: Track call contexts in `parameterFlow` --- .../dataflow/internal/DataFlowImplCommon.qll | 140 +++++++++++++----- 1 file changed, 100 insertions(+), 40 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll index 81f9946126d..cd2af163405 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll @@ -628,6 +628,8 @@ module MakeImplCommon Lang> { override string toString() { exists(DataFlowCall call | this = TReturn(_, call) | result = "CcReturn(" + call + ")") } + + predicate isReturn(DataFlowCallable c, DataFlowCall call) { this = TReturn(c, call) } } pragma[nomagic] @@ -678,6 +680,8 @@ module MakeImplCommon Lang> { class CcNoCall = CallContextNoCall; + class CcReturn = CallContextReturn; + Cc ccNone() { result instanceof CallContextAny } CcCall ccSomeCall() { result instanceof CallContextSomeCall } @@ -1338,6 +1342,7 @@ module MakeImplCommon Lang> { * or summarized as a single read step with before and after types recorded * in the `ReadStepTypesOption` parameter. * - Types are checked using the `compatibleTypes()` relation. + * - Call contexts are taken into account. */ private module Final { /** @@ -1348,8 +1353,12 @@ module MakeImplCommon Lang> { * If a read step was taken, then `read` captures the `Content`, the * container type, and the content type. */ - predicate parameterValueFlow(ParamNode p, Node node, ReadStepTypesOption read, string model) { - parameterValueFlow0(p, node, read, model) and + predicate parameterValueFlow( + ParamNode p, Node node, ReadStepTypesOption read, string model, + CachedCallContextSensitivity::CcNoCall ctx + ) { + parameterValueFlow0(p, node, read, model, ctx) and + Cand::cand(p, node) and if node instanceof CastingNode then // normal flow through @@ -1369,16 +1378,18 @@ module MakeImplCommon Lang> { pragma[nomagic] private predicate parameterValueFlow0( - ParamNode p, Node node, ReadStepTypesOption read, string model + ParamNode p, Node node, ReadStepTypesOption read, string model, + CachedCallContextSensitivity::CcNoCall ctx ) { p = node and Cand::cand(p, _) and read = TReadStepTypesNone() and - model = "" + model = "" and + CachedCallContextSensitivity::viableImplNotCallContextReducedReverse(ctx) or // local flow exists(Node mid, string model1, string model2 | - parameterValueFlow(p, mid, read, model1) and + parameterValueFlow(p, mid, read, model1, ctx) and simpleLocalFlowStep(mid, node, model2) and validParameterAliasStep(mid, node) and model = mergeModels(model1, model2) @@ -1386,50 +1397,109 @@ module MakeImplCommon Lang> { or // read exists(Node mid | - parameterValueFlow(p, mid, TReadStepTypesNone(), model) and + parameterValueFlow(p, mid, TReadStepTypesNone(), model, ctx) and readStepWithTypes(mid, read.getContainerType(), read.getContent(), node, read.getContentType()) and Cand::parameterValueFlowReturnCand(p, _, true) and compatibleTypesFilter(getNodeDataFlowType(p), read.getContainerType()) ) or - parameterValueFlow0_0(TReadStepTypesNone(), p, node, read, model) + parameterValueFlow0_0(TReadStepTypesNone(), p, node, read, model, ctx) + } + + bindingset[ctx1, ctx2] + pragma[inline_late] + private CachedCallContextSensitivity::CcNoCall mergeContexts( + CachedCallContextSensitivity::CcNoCall ctx1, CachedCallContextSensitivity::CcNoCall ctx2 + ) { + if CachedCallContextSensitivity::viableImplNotCallContextReducedReverse(ctx1) + then result = ctx2 + else + if CachedCallContextSensitivity::viableImplNotCallContextReducedReverse(ctx2) + then result = ctx1 + else + // check that `ctx1` is compatible with `ctx2` for at least _some_ outer call, + // and then (arbitrarily) continue with `ctx2` + exists(DataFlowCall someOuterCall, DataFlowCallable callable | + someOuterCall = + CachedCallContextSensitivity::viableImplCallContextReducedReverse(callable, ctx1) and + someOuterCall = + CachedCallContextSensitivity::viableImplCallContextReducedReverse(callable, ctx2) and + result = ctx2 + ) } pragma[nomagic] private predicate parameterValueFlow0_0( ReadStepTypesOption mustBeNone, ParamNode p, Node node, ReadStepTypesOption read, - string model + string model, CachedCallContextSensitivity::CcNoCall ctx ) { - // flow through: no prior read - exists(ArgNode arg, string model1, string model2 | - parameterValueFlowArg(p, arg, mustBeNone, model1) and - argumentValueFlowsThrough(arg, read, node, model2) and - model = mergeModels(model1, model2) - ) - or - // flow through: no read inside method - exists(ArgNode arg, string model1, string model2 | - parameterValueFlowArg(p, arg, read, model1) and - argumentValueFlowsThrough(arg, mustBeNone, node, model2) and - model = mergeModels(model1, model2) + exists( + DataFlowCall call, DataFlowCallable callable, ArgNode arg, string model1, string model2, + CachedCallContextSensitivity::CcNoCall ctx1, CachedCallContextSensitivity::CcNoCall ctx2 + | + model = mergeModels(model1, model2) and + ( + // call may restrict the set of call sites that can be returned to + ctx2.(CachedCallContextSensitivity::CcReturn).isReturn(callable, call) + or + // call does not restrict the set of call sites that can be returned to + not exists(CachedCallContextSensitivity::CcReturn ret | ret.isReturn(callable, call)) and + CachedCallContextSensitivity::viableImplNotCallContextReducedReverse(ctx2) + ) and + ctx = mergeContexts(ctx1, ctx2) + | + // flow through: no prior read + parameterValueFlowArg(p, arg, mustBeNone, model1, ctx1) and + argumentValueFlowsThrough(call, callable, arg, read, node, model2) + or + // flow through: no read inside method + parameterValueFlowArg(p, arg, read, model1, ctx1) and + argumentValueFlowsThrough(call, callable, arg, mustBeNone, node, model2) ) } pragma[nomagic] private predicate parameterValueFlowArg( - ParamNode p, ArgNode arg, ReadStepTypesOption read, string model + ParamNode p, ArgNode arg, ReadStepTypesOption read, string model, + CachedCallContextSensitivity::CcNoCall ctx ) { - parameterValueFlow(p, arg, read, model) and + parameterValueFlow(p, arg, read, model, ctx) and Cand::argumentValueFlowsThroughCand(arg, _, _) } pragma[nomagic] private predicate argumentValueFlowsThrough0( - DataFlowCall call, ArgNode arg, ReturnKind kind, ReadStepTypesOption read, string model + DataFlowCall call, DataFlowCallable callable, ArgNode arg, ReturnKind kind, + ReadStepTypesOption read, string model ) { - exists(ParamNode param | viableParamArg(call, param, arg) | - parameterValueFlowReturn(param, kind, read, model) + exists(ParamNode param, CachedCallContextSensitivity::CcNoCall ctx | + viableParamArg(call, param, arg) and + parameterValueFlowReturn(param, kind, read, model, ctx) and + callable = nodeGetEnclosingCallable(param) + | + CachedCallContextSensitivity::viableImplNotCallContextReducedReverse(ctx) + or + call = CachedCallContextSensitivity::viableImplCallContextReducedReverse(callable, ctx) + ) + } + + pragma[nomagic] + private predicate argumentValueFlowsThrough( + DataFlowCall call, DataFlowCallable callable, ArgNode arg, ReadStepTypesOption read, + Node out, string model + ) { + exists(ReturnKind kind | + argumentValueFlowsThrough0(call, callable, arg, kind, read, model) and + out = getAnOutNode(call, kind) + | + // normal flow through + read = TReadStepTypesNone() and + compatibleTypesFilter(getNodeDataFlowType(arg), getNodeDataFlowType(out)) + or + // getter + compatibleTypesFilter(getNodeDataFlowType(arg), read.getContainerType()) and + compatibleTypesFilter(read.getContentType(), getNodeDataFlowType(out)) ) } @@ -1445,18 +1515,7 @@ module MakeImplCommon Lang> { predicate argumentValueFlowsThrough( ArgNode arg, ReadStepTypesOption read, Node out, string model ) { - exists(DataFlowCall call, ReturnKind kind | - argumentValueFlowsThrough0(call, arg, kind, read, model) and - out = getAnOutNode(call, kind) - | - // normal flow through - read = TReadStepTypesNone() and - compatibleTypesFilter(getNodeDataFlowType(arg), getNodeDataFlowType(out)) - or - // getter - compatibleTypesFilter(getNodeDataFlowType(arg), read.getContainerType()) and - compatibleTypesFilter(read.getContentType(), getNodeDataFlowType(out)) - ) + argumentValueFlowsThrough(_, _, arg, read, out, model) } /** @@ -1479,10 +1538,11 @@ module MakeImplCommon Lang> { * container type, and the content type. */ private predicate parameterValueFlowReturn( - ParamNode p, ReturnKind kind, ReadStepTypesOption read, string model + ParamNode p, ReturnKind kind, ReadStepTypesOption read, string model, + CachedCallContextSensitivity::CcNoCall ctx ) { exists(ReturnNode ret | - parameterValueFlow(p, ret, read, model) and + parameterValueFlow(p, ret, read, model, ctx) and kind = ret.getKind() ) } @@ -1498,7 +1558,7 @@ module MakeImplCommon Lang> { * node `n`, in the same callable, using only value-preserving steps. */ private predicate parameterValueFlowsToPreUpdate(ParamNode p, PostUpdateNode n) { - parameterValueFlow(p, n.getPreUpdateNode(), TReadStepTypesNone(), _) + parameterValueFlow(p, n.getPreUpdateNode(), TReadStepTypesNone(), _, _) } cached From 5f9b8c05bdf63578aaaeba5cd0be8c56f7748948 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 30 Oct 2024 16:01:32 +0100 Subject: [PATCH 120/470] Java: Update expected test output --- java/ql/test/library-tests/dataflow/getter/getter.expected | 1 - 1 file changed, 1 deletion(-) diff --git a/java/ql/test/library-tests/dataflow/getter/getter.expected b/java/ql/test/library-tests/dataflow/getter/getter.expected index b5af3f91a59..9a36107f198 100644 --- a/java/ql/test/library-tests/dataflow/getter/getter.expected +++ b/java/ql/test/library-tests/dataflow/getter/getter.expected @@ -1,6 +1,5 @@ | A.java:5:12:5:15 | this | A.java:5:12:5:19 | this.foo | A.java:2:7:2:9 | foo | | A.java:21:13:21:13 | a | A.java:21:13:21:22 | getFoo(...) | A.java:2:7:2:9 | foo | | A.java:23:9:23:9 | a | A.java:23:9:23:19 | aGetter(...) | A.java:2:7:2:9 | foo | -| A.java:24:9:24:10 | a2 | A.java:24:9:24:23 | notAGetter(...) | A.java:2:7:2:9 | foo | | A.java:45:12:45:38 | maybeIdWrap(...) | A.java:45:12:45:42 | maybeIdWrap(...).foo | A.java:2:7:2:9 | foo | | A.java:49:12:49:38 | maybeIdWrap(...) | A.java:49:12:49:42 | maybeIdWrap(...).foo | A.java:2:7:2:9 | foo | From 42e0d7ce10afe8510088cc4999cbc1fb1bb6f2b9 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 20 Nov 2024 13:09:59 +0100 Subject: [PATCH 121/470] Util: Refactor `DenseRank` implementation --- .../rust/elements/internal/VariableImpl.qll | 4 +- shared/util/codeql/util/DenseRank.qll | 40 +++++++++---------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index 4b94546d802..80c70f6f6fa 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -378,7 +378,7 @@ module Impl { } } - private module DenseRankInput implements DenseRankInputSig3 { + private module DenseRankInput implements DenseRankInputSig2 { class C1 = VariableScope; class C2 = string; @@ -401,7 +401,7 @@ module Impl { * to a variable named `name` in the variable scope `scope`. */ private int rankVariableOrAccess(VariableScope scope, string name, VariableOrAccessCand v) { - result = DenseRank3::denseRank(scope, name, v) - 1 + v = DenseRank2::denseRank(scope, name, result + 1) } /** diff --git a/shared/util/codeql/util/DenseRank.qll b/shared/util/codeql/util/DenseRank.qll index d1ba4ae4b62..0dccbbd4880 100644 --- a/shared/util/codeql/util/DenseRank.qll +++ b/shared/util/codeql/util/DenseRank.qll @@ -58,12 +58,12 @@ module DenseRank { rnk = rank[result](int rnk0 | rnk0 = getRank(_) | rnk0) } - /** Gets the dense rank of `r`. */ - int denseRank(Ranked r) { result = rankRank(r, getRank(r)) } + /** Gets the `Ranked` value for which the dense rank is `rnk`. */ + Ranked denseRank(int rnk) { rnk = rankRank(result, getRank(result)) } } -/** Provides the input to `DenseRank2`. */ -signature module DenseRankInputSig2 { +/** Provides the input to `DenseRank1`. */ +signature module DenseRankInputSig1 { /** A ranking context. */ bindingset[this] class C; @@ -77,7 +77,7 @@ signature module DenseRankInputSig2 { } /** Same as `DenseRank`, but allows for a context consisting of one element. */ -module DenseRank2 { +module DenseRank1 { private import Input private int rankRank(C c, Ranked r, int rnk) { @@ -85,17 +85,15 @@ module DenseRank2 { rnk = rank[result](int rnk0 | rnk0 = getRank(c, _) | rnk0) } - /** Gets the dense rank of `r` in the context provided by `c`. */ - int denseRank(C c, Ranked r) { - exists(int rnk | - result = rankRank(c, r, rnk) and - rnk = getRank(c, r) - ) - } + /** + * Gets the `Ranked` value for which the dense rank in the context provided by + * `c` is `rnk`. + */ + Ranked denseRank(C c, int rnk) { rnk = rankRank(c, result, getRank(c, result)) } } -/** Provides the input to `DenseRank3`. */ -signature module DenseRankInputSig3 { +/** Provides the input to `DenseRank2`. */ +signature module DenseRankInputSig2 { /** A ranking context. */ bindingset[this] class C1; @@ -113,7 +111,7 @@ signature module DenseRankInputSig3 { } /** Same as `DenseRank`, but allows for a context consisting of two elements. */ -module DenseRank3 { +module DenseRank2 { private import Input private int rankRank(C1 c1, C2 c2, Ranked r, int rnk) { @@ -121,11 +119,11 @@ module DenseRank3 { rnk = rank[result](int rnk0 | rnk0 = getRank(c1, c2, _) | rnk0) } - /** Gets the dense rank of `r` in the context provided by `c1` and `c2`. */ - int denseRank(C1 c1, C2 c2, Ranked r) { - exists(int rnk | - result = rankRank(c1, c2, r, rnk) and - rnk = getRank(c1, c2, r) - ) + /** + * Gets the `Ranked` value for which the dense rank in the context provided by + * `c1` and `c2` is `rnk`. + */ + Ranked denseRank(C1 c1, C2 c2, int rnk) { + rnk = rankRank(c1, c2, result, getRank(c1, c2, result)) } } From 3f56fc9e894d7c92aa7b2cb594cae0ae2a300a30 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 20 Nov 2024 12:58:30 +0100 Subject: [PATCH 122/470] Address review comments --- .../dataflow/internal/DataFlowImplCommon.qll | 49 +++++++++---------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll index cd2af163405..e477913a59b 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll @@ -628,8 +628,6 @@ module MakeImplCommon Lang> { override string toString() { exists(DataFlowCall call | this = TReturn(_, call) | result = "CcReturn(" + call + ")") } - - predicate isReturn(DataFlowCallable c, DataFlowCall call) { this = TReturn(c, call) } } pragma[nomagic] @@ -1435,27 +1433,19 @@ module MakeImplCommon Lang> { string model, CachedCallContextSensitivity::CcNoCall ctx ) { exists( - DataFlowCall call, DataFlowCallable callable, ArgNode arg, string model1, string model2, - CachedCallContextSensitivity::CcNoCall ctx1, CachedCallContextSensitivity::CcNoCall ctx2 + ArgNode arg, string model1, string model2, CachedCallContextSensitivity::CcNoCall ctx1, + CachedCallContextSensitivity::CcNoCall ctx2 | model = mergeModels(model1, model2) and - ( - // call may restrict the set of call sites that can be returned to - ctx2.(CachedCallContextSensitivity::CcReturn).isReturn(callable, call) - or - // call does not restrict the set of call sites that can be returned to - not exists(CachedCallContextSensitivity::CcReturn ret | ret.isReturn(callable, call)) and - CachedCallContextSensitivity::viableImplNotCallContextReducedReverse(ctx2) - ) and ctx = mergeContexts(ctx1, ctx2) | // flow through: no prior read parameterValueFlowArg(p, arg, mustBeNone, model1, ctx1) and - argumentValueFlowsThrough(call, callable, arg, read, node, model2) + argumentValueFlowsThrough(arg, read, node, model2, ctx2) or // flow through: no read inside method parameterValueFlowArg(p, arg, read, model1, ctx1) and - argumentValueFlowsThrough(call, callable, arg, mustBeNone, node, model2) + argumentValueFlowsThrough(arg, mustBeNone, node, model2, ctx2) ) } @@ -1470,27 +1460,32 @@ module MakeImplCommon Lang> { pragma[nomagic] private predicate argumentValueFlowsThrough0( - DataFlowCall call, DataFlowCallable callable, ArgNode arg, ReturnKind kind, - ReadStepTypesOption read, string model + DataFlowCall call, ArgNode arg, ReturnKind kind, ReadStepTypesOption read, string model, + CachedCallContextSensitivity::CcNoCall outerCtx ) { - exists(ParamNode param, CachedCallContextSensitivity::CcNoCall ctx | - viableParamArg(call, param, arg) and - parameterValueFlowReturn(param, kind, read, model, ctx) and - callable = nodeGetEnclosingCallable(param) + exists( + ParamNode param, DataFlowCallable callable, + CachedCallContextSensitivity::CcNoCall innerCtx | - CachedCallContextSensitivity::viableImplNotCallContextReducedReverse(ctx) + viableParamArg(call, param, arg) and + parameterValueFlowReturn(param, kind, read, model, innerCtx) and + callable = nodeGetEnclosingCallable(param) and + outerCtx = CachedCallContextSensitivity::getCallContextReturn(callable, call) + | + CachedCallContextSensitivity::viableImplNotCallContextReducedReverse(innerCtx) or - call = CachedCallContextSensitivity::viableImplCallContextReducedReverse(callable, ctx) + call = + CachedCallContextSensitivity::viableImplCallContextReducedReverse(callable, innerCtx) ) } pragma[nomagic] private predicate argumentValueFlowsThrough( - DataFlowCall call, DataFlowCallable callable, ArgNode arg, ReadStepTypesOption read, - Node out, string model + ArgNode arg, ReadStepTypesOption read, Node out, string model, + CachedCallContextSensitivity::CcNoCall ctx ) { - exists(ReturnKind kind | - argumentValueFlowsThrough0(call, callable, arg, kind, read, model) and + exists(DataFlowCall call, ReturnKind kind | + argumentValueFlowsThrough0(call, arg, kind, read, model, ctx) and out = getAnOutNode(call, kind) | // normal flow through @@ -1515,7 +1510,7 @@ module MakeImplCommon Lang> { predicate argumentValueFlowsThrough( ArgNode arg, ReadStepTypesOption read, Node out, string model ) { - argumentValueFlowsThrough(_, _, arg, read, out, model) + argumentValueFlowsThrough(arg, read, out, model, _) } /** From 6344f83e4b7740dbe3e406f877064388b4dfdc2a Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 20 Nov 2024 13:22:53 +0100 Subject: [PATCH 123/470] JS: Add: tests for taint tracking in groupBy functions --- .../TaintTracking/BasicTaintTracking.expected | 4 ++++ .../test/library-tests/TaintTracking/tst.js | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 79be56cbb7e..ecbab868513 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -246,6 +246,10 @@ typeInferenceMismatch | tst.js:2:13:2:20 | source() | tst.js:70:10:70:18 | xReversed | | tst.js:2:13:2:20 | source() | tst.js:72:10:72:31 | Map.gro ... z => z) | | tst.js:2:13:2:20 | source() | tst.js:74:10:74:34 | Object. ... z => z) | +| tst.js:2:13:2:20 | source() | tst.js:79:14:79:20 | grouped | +| tst.js:75:22:75:29 | source() | tst.js:75:10:75:52 | Map.gro ... (item)) | +| tst.js:82:23:82:30 | source() | tst.js:84:14:84:20 | grouped | +| tst.js:87:22:87:29 | source() | tst.js:90:14:90:25 | taintedValue | | xml.js:5:18:5:25 | source() | xml.js:8:14:8:17 | text | | xml.js:12:17:12:24 | source() | xml.js:13:14:13:19 | result | | xml.js:23:18:23:25 | source() | xml.js:20:14:20:17 | attr | diff --git a/javascript/ql/test/library-tests/TaintTracking/tst.js b/javascript/ql/test/library-tests/TaintTracking/tst.js index 0fab561954d..0c642b3a2c0 100644 --- a/javascript/ql/test/library-tests/TaintTracking/tst.js +++ b/javascript/ql/test/library-tests/TaintTracking/tst.js @@ -72,4 +72,28 @@ function test() { sink(Map.groupBy(x, z => z)); // NOT OK sink(Custom.groupBy(x, z => z)); // OK sink(Object.groupBy(x, z => z)); // NOT OK + sink(Map.groupBy(source(), (item) => sink(item))); // NOT OK + + { + const grouped = Map.groupBy(x, (item) => sink(item)); // NOT OK -- Should be tainted, but it is not + sink(grouped); // NOT OK + } + { + const list = [source()]; + const grouped = Map.groupBy(list, (item) => sink(item)); // NOT OK -- Should be tainted, but it is not + sink(grouped); // NOT OK + } + { + const data = source(); + const result = Object.groupBy(data, item => item); + const taintedValue = result[notDefined()]; + sink(taintedValue); // NOT OK + } + { + const data = source(); + const map = Map.groupBy(data, item => item); + const taintedValue = map.get(true); + sink(taintedValue); // NOT OK -- Should be tainted, but it is not + sink(map.get(true)); // NOT OK -- Should be tainted, but it is not + } } From 58faa2d71edf98ce13009a048a417e1032bd390b Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 20 Nov 2024 13:34:11 +0100 Subject: [PATCH 124/470] JS: Add: dataflow step for static method of groupBy from Map. --- .../ql/lib/semmle/javascript/Collections.qll | 17 ++++++++++++++++- .../TaintTracking/BasicTaintTracking.expected | 5 +++++ .../TaintTracking/DataFlowTracking.expected | 2 ++ .../ql/test/library-tests/TaintTracking/tst.js | 8 ++++---- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/Collections.qll b/javascript/ql/lib/semmle/javascript/Collections.qll index c7348e603f4..df7ad317014 100644 --- a/javascript/ql/lib/semmle/javascript/Collections.qll +++ b/javascript/ql/lib/semmle/javascript/Collections.qll @@ -160,7 +160,22 @@ private module CollectionDataFlow { exists(DataFlow::MethodCallNode call | call = DataFlow::globalVarRef(["Map", "Object"]).getAMemberCall("groupBy") and pred = call.getArgument(0) and - succ = call + (succ = call.getCallback(1).getParameter(0) or succ = call.getALocalUse()) + ) + } + } + + /** + * A step for handling data flow and taint tracking for the groupBy method on iterable objects. + * Ensures propagation of taint and data flow through the groupBy operation. + */ + private class GroupByDataFlowStep extends PreCallGraphStep { + override predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { + exists(DataFlow::MethodCallNode call | + call = DataFlow::globalVarRef("Map").getAMemberCall("groupBy") and + pred = call.getArgument(0) and + succ = call and + prop = mapValueUnknownKey() ) } } diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index ecbab868513..005327d188e 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -246,10 +246,15 @@ typeInferenceMismatch | tst.js:2:13:2:20 | source() | tst.js:70:10:70:18 | xReversed | | tst.js:2:13:2:20 | source() | tst.js:72:10:72:31 | Map.gro ... z => z) | | tst.js:2:13:2:20 | source() | tst.js:74:10:74:34 | Object. ... z => z) | +| tst.js:2:13:2:20 | source() | tst.js:78:55:78:58 | item | | tst.js:2:13:2:20 | source() | tst.js:79:14:79:20 | grouped | | tst.js:75:22:75:29 | source() | tst.js:75:10:75:52 | Map.gro ... (item)) | +| tst.js:75:22:75:29 | source() | tst.js:75:47:75:50 | item | +| tst.js:82:23:82:30 | source() | tst.js:83:58:83:61 | item | | tst.js:82:23:82:30 | source() | tst.js:84:14:84:20 | grouped | | tst.js:87:22:87:29 | source() | tst.js:90:14:90:25 | taintedValue | +| tst.js:93:22:93:29 | source() | tst.js:96:14:96:25 | taintedValue | +| tst.js:93:22:93:29 | source() | tst.js:97:14:97:26 | map.get(true) | | xml.js:5:18:5:25 | source() | xml.js:8:14:8:17 | text | | xml.js:12:17:12:24 | source() | xml.js:13:14:13:19 | result | | xml.js:23:18:23:25 | source() | xml.js:20:14:20:17 | attr | diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected index 33a27661ecd..3b89229b2d7 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected @@ -112,3 +112,5 @@ | thisAssignments.js:7:19:7:26 | source() | thisAssignments.js:8:10:8:20 | this.field2 | | tst.js:2:13:2:20 | source() | tst.js:4:10:4:10 | x | | tst.js:2:13:2:20 | source() | tst.js:54:14:54:19 | unsafe | +| tst.js:93:22:93:29 | source() | tst.js:96:14:96:25 | taintedValue | +| tst.js:93:22:93:29 | source() | tst.js:97:14:97:26 | map.get(true) | diff --git a/javascript/ql/test/library-tests/TaintTracking/tst.js b/javascript/ql/test/library-tests/TaintTracking/tst.js index 0c642b3a2c0..a0b596802b7 100644 --- a/javascript/ql/test/library-tests/TaintTracking/tst.js +++ b/javascript/ql/test/library-tests/TaintTracking/tst.js @@ -75,12 +75,12 @@ function test() { sink(Map.groupBy(source(), (item) => sink(item))); // NOT OK { - const grouped = Map.groupBy(x, (item) => sink(item)); // NOT OK -- Should be tainted, but it is not + const grouped = Map.groupBy(x, (item) => sink(item)); // NOT OK sink(grouped); // NOT OK } { const list = [source()]; - const grouped = Map.groupBy(list, (item) => sink(item)); // NOT OK -- Should be tainted, but it is not + const grouped = Map.groupBy(list, (item) => sink(item)); // NOT OK sink(grouped); // NOT OK } { @@ -93,7 +93,7 @@ function test() { const data = source(); const map = Map.groupBy(data, item => item); const taintedValue = map.get(true); - sink(taintedValue); // NOT OK -- Should be tainted, but it is not - sink(map.get(true)); // NOT OK -- Should be tainted, but it is not + sink(taintedValue); // NOT OK + sink(map.get(true)); // NOT OK } } From cdf43f7118e2e535fdc751aa1870e663a6da499d Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 20 Nov 2024 14:06:44 +0100 Subject: [PATCH 125/470] Added change notes --- .../ql/lib/change-notes/2024-11-20-ES2024-group-functions.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 javascript/ql/lib/change-notes/2024-11-20-ES2024-group-functions.md diff --git a/javascript/ql/lib/change-notes/2024-11-20-ES2024-group-functions.md b/javascript/ql/lib/change-notes/2024-11-20-ES2024-group-functions.md new file mode 100644 index 00000000000..8511727f8e7 --- /dev/null +++ b/javascript/ql/lib/change-notes/2024-11-20-ES2024-group-functions.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added taint-steps for `Map.groupBy` and `Object.groupBy`. From d9a830e008d230d21aaaac5be5c2e57b3a4a83da Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 20 Nov 2024 13:50:59 +0000 Subject: [PATCH 126/470] Add log function prefix "With" for heuristic logger --- go/ql/lib/semmle/go/Concepts.qll | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/go/ql/lib/semmle/go/Concepts.qll b/go/ql/lib/semmle/go/Concepts.qll index 16b32466f3d..3f0cd0f8885 100644 --- a/go/ql/lib/semmle/go/Concepts.qll +++ b/go/ql/lib/semmle/go/Concepts.qll @@ -397,15 +397,18 @@ private class DefaultLoggerCall extends LoggerCall::Range, DataFlow::CallNode { */ private class HeuristicLoggerCall extends LoggerCall::Range, DataFlow::CallNode { HeuristicLoggerCall() { - exists(Method m, string tp, string logLevel, string name | + exists(Method m, string tp, string logFunctionPrefix, string name | m = this.getTarget() and m.hasQualifiedName(_, tp, name) and m.getReceiverBaseType().getUnderlyingType() instanceof InterfaceType | tp.regexpMatch(".*[lL]ogger") and - logLevel = - ["Debug", "Error", "Fatal", "Info", "Log", "Output", "Panic", "Print", "Trace", "Warn"] and - name.matches(logLevel + "%") + logFunctionPrefix = + [ + "Debug", "Error", "Fatal", "Info", "Log", "Output", "Panic", "Print", "Trace", "Warn", + "With" + ] and + name.matches(logFunctionPrefix + "%") ) } From dcf3b31f622323fb541027ed02a21ef21ff79f8d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 20 Nov 2024 13:52:22 +0000 Subject: [PATCH 127/470] Move and update change note --- .../lib/change-notes/2024-11-20-heuristic-logging-sinks.md | 4 ++++ go/ql/src/change-notes/2024-11-20-heuristic-logging-sinks.md | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/2024-11-20-heuristic-logging-sinks.md delete mode 100644 go/ql/src/change-notes/2024-11-20-heuristic-logging-sinks.md diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/2024-11-20-heuristic-logging-sinks.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/2024-11-20-heuristic-logging-sinks.md new file mode 100644 index 00000000000..46f5988b379 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/2024-11-20-heuristic-logging-sinks.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* A call to a method whose name starts with "Debug", "Error", "Fatal", "Info", "Log", "Output", "Panic", "Print", "Trace", "Warn" or "With" defined on an interface whose name ends in "logger" or "Logger" is now considered a LoggerCall. In particular, it is a sink for `go/clear-text-logging` and `go/log-injection`. This may lead to some more alerts in those queries. diff --git a/go/ql/src/change-notes/2024-11-20-heuristic-logging-sinks.md b/go/ql/src/change-notes/2024-11-20-heuristic-logging-sinks.md deleted file mode 100644 index 7fcb5fa3a34..00000000000 --- a/go/ql/src/change-notes/2024-11-20-heuristic-logging-sinks.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* A call to a method whose name starts with "Debug", "Error", "Fatal", "Info", "Log", "Output", "Panic", "Print", "Trace" or "Warn" defined on an interface whose name ends in "logger" or "Logger" is now considered a sink for `go/clear-text-logging` and `go/log-injection`. This may lead to some more alerts in those queries. From 9dbf7d1828b2b2f70cd26c346956ad091993c14f Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 20 Nov 2024 14:54:06 +0100 Subject: [PATCH 128/470] JS: removed unnecessary getALocalSource from ArrayCallBackDataTaintStep --- javascript/ql/lib/semmle/javascript/Arrays.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/Arrays.qll b/javascript/ql/lib/semmle/javascript/Arrays.qll index 95301820dc1..25a6b97430b 100644 --- a/javascript/ql/lib/semmle/javascript/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/Arrays.qll @@ -505,7 +505,7 @@ private module ArrayLibraries { override predicate step(DataFlow::Node obj, DataFlow::Node element) { exists(DataFlow::MethodCallNode call | call.getMethodName() = ["findLast", "find", "findLastIndex"] and - obj = call.getReceiver().getALocalSource() and + obj = call.getReceiver() and element = call.getCallback(0).getParameter(0) ) } From 64c45debdb4c1326f933d100eacac71c7898792d Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 20 Nov 2024 14:57:00 +0100 Subject: [PATCH 129/470] JS: removed unnecessary getALocalSource from ArrayCallBackDataFlowStep --- javascript/ql/lib/semmle/javascript/Arrays.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/Arrays.qll b/javascript/ql/lib/semmle/javascript/Arrays.qll index 25a6b97430b..bec711b835a 100644 --- a/javascript/ql/lib/semmle/javascript/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/Arrays.qll @@ -492,7 +492,7 @@ private module ArrayLibraries { exists(DataFlow::MethodCallNode call | call.getMethodName() = ["findLast", "find", "findLastIndex"] and prop = arrayLikeElement() and - obj = call.getReceiver().getALocalSource() and + obj = call.getReceiver() and element = call.getCallback(0).getParameter(0) ) } From 69df07ed1208ca12a82e83c1c2da9f430dbd458a Mon Sep 17 00:00:00 2001 From: Ben Rodes Date: Wed, 20 Nov 2024 09:06:44 -0500 Subject: [PATCH 130/470] Update cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md Co-authored-by: Mathias Vorreiter Pedersen --- cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md b/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md index f3c33f40b51..114822e6c8f 100644 --- a/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md +++ b/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md @@ -1,4 +1,4 @@ --- -category: minorAnalysis +category: deprecated --- -* Removed NonThrowing.qll. Throwing meta-data now part of Throwing.qll. Updated models and IR to use the new Throwing library and predicates. \ No newline at end of file +* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonThrowing` class from `semmle.code.cpp.models.interfaces.Throwing` instead. \ No newline at end of file From 69ad69c38ae329916467bed91444426e1a417b6b Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 20 Nov 2024 14:21:28 +0000 Subject: [PATCH 131/470] Move change note out of C# folder --- .../ql}/lib/change-notes/2024-11-20-heuristic-logging-sinks.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {csharp/ql/campaigns/Solorigate => go/ql}/lib/change-notes/2024-11-20-heuristic-logging-sinks.md (100%) diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/2024-11-20-heuristic-logging-sinks.md b/go/ql/lib/change-notes/2024-11-20-heuristic-logging-sinks.md similarity index 100% rename from csharp/ql/campaigns/Solorigate/lib/change-notes/2024-11-20-heuristic-logging-sinks.md rename to go/ql/lib/change-notes/2024-11-20-heuristic-logging-sinks.md From b4af5a61d12c8b4e9c45bfbcc4a0ae33716fcf31 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 20 Nov 2024 16:21:23 +0100 Subject: [PATCH 132/470] Rust: more advanced `toString` --- rust/extractor/src/generated/.generated.list | 2 +- rust/extractor/src/generated/top.rs | 770 +++++++++++------- rust/ql/.generated.list | 38 +- rust/ql/.gitattributes | 6 + rust/ql/lib/codeql/rust/elements.qll | 2 + .../ql/lib/codeql/rust/elements/BlockExpr.qll | 3 +- rust/ql/lib/codeql/rust/elements/ForExpr.qll | 3 +- .../codeql/rust/elements/LabelableExpr.qll | 13 + rust/ql/lib/codeql/rust/elements/LoopExpr.qll | 4 +- .../lib/codeql/rust/elements/LoopingExpr.qll | 13 + .../ql/lib/codeql/rust/elements/WhileExpr.qll | 3 +- .../rust/elements/internal/AwaitExprImpl.qll | 2 +- .../rust/elements/internal/BecomeExprImpl.qll | 2 +- .../rust/elements/internal/BlockExprImpl.qll | 6 +- .../rust/elements/internal/BoxPatImpl.qll | 2 +- .../rust/elements/internal/BreakExprImpl.qll | 19 +- .../rust/elements/internal/CallExprImpl.qll | 11 +- .../rust/elements/internal/CastExprImpl.qll | 4 +- .../elements/internal/ClosureExprImpl.qll | 2 +- .../elements/internal/ContinueExprImpl.qll | 17 +- .../rust/elements/internal/ElementImpl.qll | 8 + .../rust/elements/internal/FieldExprImpl.qll | 8 +- .../rust/elements/internal/ForExprImpl.qll | 4 +- .../rust/elements/internal/IfExprImpl.qll | 15 +- .../rust/elements/internal/IndexExprImpl.qll | 5 +- .../elements/internal/LabelableExprImpl.qll | 30 + .../rust/elements/internal/LetExprImpl.qll | 13 +- .../rust/elements/internal/LetStmtImpl.qll | 16 +- .../elements/internal/LiteralExprImpl.qll | 2 + .../rust/elements/internal/LiteralPatImpl.qll | 4 +- .../rust/elements/internal/LoopExprImpl.qll | 2 +- .../elements/internal/LoopingExprImpl.qll | 19 + .../rust/elements/internal/MatchArmImpl.qll | 15 +- .../rust/elements/internal/MatchExprImpl.qll | 4 +- .../rust/elements/internal/NeverTypeImpl.qll | 4 +- .../rust/elements/internal/OrPatImpl.qll | 4 +- .../rust/elements/internal/ParamImpl.qll | 15 +- .../rust/elements/internal/ParenExprImpl.qll | 2 +- .../rust/elements/internal/ParenPatImpl.qll | 2 +- .../rust/elements/internal/ParenTypeImpl.qll | 2 +- .../rust/elements/internal/PathExprImpl.qll | 4 +- .../rust/elements/internal/PathImpl.qll | 10 +- .../rust/elements/internal/PathPatImpl.qll | 4 +- .../elements/internal/PathSegmentImpl.qll | 4 +- .../rust/elements/internal/PathTypeImpl.qll | 4 +- .../rust/elements/internal/RangeExprImpl.qll | 24 +- .../elements/internal/RecordExprFieldImpl.qll | 11 +- .../rust/elements/internal/RefExprImpl.qll | 17 +- .../rust/elements/internal/RefPatImpl.qll | 11 +- .../rust/elements/internal/RestPatImpl.qll | 4 +- .../rust/elements/internal/ReturnExprImpl.qll | 8 +- .../elements/internal/UnderscoreExprImpl.qll | 4 +- .../rust/elements/internal/WhileExprImpl.qll | 4 +- .../elements/internal/WildcardPatImpl.qll | 4 +- .../elements/internal/generated/BlockExpr.qll | 18 +- .../elements/internal/generated/ForExpr.qll | 32 +- .../internal/generated/LabelableExpr.qll | 38 + .../elements/internal/generated/LoopExpr.qll | 34 +- .../internal/generated/LoopingExpr.qll | 38 + .../internal/generated/ParentChild.qll | 238 +++--- .../rust/elements/internal/generated/Raw.qll | 337 ++++---- .../elements/internal/generated/Synth.qll | 86 +- .../elements/internal/generated/WhileExpr.qll | 34 +- rust/ql/lib/rust.dbscheme | 266 +++--- .../generated/BlockExpr/BlockExpr.ql | 10 +- .../generated/ForExpr/ForExpr.ql | 10 +- .../generated/LoopExpr/LoopExpr.ql | 8 +- .../generated/WhileExpr/WhileExpr.ql | 12 +- .../library-tests/controlflow/Cfg.expected | 680 ++++++++-------- .../dataflow/barrier/inline-flow.expected | 16 +- .../dataflow/global/viableCallable.expected | 42 +- .../dataflow/local/DataFlowStep.expected | 38 +- .../dataflow/local/inline-flow.expected | 28 +- rust/schema/annotations.py | 28 +- 74 files changed, 1777 insertions(+), 1425 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/elements/LabelableExpr.qll create mode 100644 rust/ql/lib/codeql/rust/elements/LoopingExpr.qll create mode 100644 rust/ql/lib/codeql/rust/elements/internal/LabelableExprImpl.qll create mode 100644 rust/ql/lib/codeql/rust/elements/internal/LoopingExprImpl.qll create mode 100644 rust/ql/lib/codeql/rust/elements/internal/generated/LabelableExpr.qll create mode 100644 rust/ql/lib/codeql/rust/elements/internal/generated/LoopingExpr.qll diff --git a/rust/extractor/src/generated/.generated.list b/rust/extractor/src/generated/.generated.list index 7335c95f7b8..0f781aae8da 100644 --- a/rust/extractor/src/generated/.generated.list +++ b/rust/extractor/src/generated/.generated.list @@ -1,2 +1,2 @@ mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 -top.rs cdfb9890318d847e6db320abd8b9e9939524ecc47bcdc8491b9c8253bd3178c2 cdfb9890318d847e6db320abd8b9e9939524ecc47bcdc8491b9c8253bd3178c2 +top.rs 7a5bbe75eae6069f4f255db13787a3575e706742af1f57122c02d46895de9a1b 7a5bbe75eae6069f4f255db13787a3575e706742af1f57122c02d46895de9a1b diff --git a/rust/extractor/src/generated/top.rs b/rust/extractor/src/generated/top.rs index 13a0adecbca..eb1f16f8cc6 100644 --- a/rust/extractor/src/generated/top.rs +++ b/rust/extractor/src/generated/top.rs @@ -3568,97 +3568,6 @@ impl From> for trap::Label { } } -#[derive(Debug)] -pub struct BlockExpr { - pub id: trap::TrapId, - pub attrs: Vec>, - pub is_async: bool, - pub is_const: bool, - pub is_gen: bool, - pub is_move: bool, - pub is_try: bool, - pub is_unsafe: bool, - pub label: Option>, - pub stmt_list: Option>, -} - -impl trap::TrapEntry for BlockExpr { - fn extract_id(&mut self) -> trap::TrapId { - std::mem::replace(&mut self.id, trap::TrapId::Star) - } - - fn emit(self, id: trap::Label, out: &mut trap::Writer) { - out.add_tuple("block_exprs", vec![id.into()]); - for (i, v) in self.attrs.into_iter().enumerate() { - out.add_tuple("block_expr_attrs", vec![id.into(), i.into(), v.into()]); - } - if self.is_async { - out.add_tuple("block_expr_is_async", vec![id.into()]); - } - if self.is_const { - out.add_tuple("block_expr_is_const", vec![id.into()]); - } - if self.is_gen { - out.add_tuple("block_expr_is_gen", vec![id.into()]); - } - if self.is_move { - out.add_tuple("block_expr_is_move", vec![id.into()]); - } - if self.is_try { - out.add_tuple("block_expr_is_try", vec![id.into()]); - } - if self.is_unsafe { - out.add_tuple("block_expr_is_unsafe", vec![id.into()]); - } - if let Some(v) = self.label { - out.add_tuple("block_expr_labels", vec![id.into(), v.into()]); - } - if let Some(v) = self.stmt_list { - out.add_tuple("block_expr_stmt_lists", vec![id.into(), v.into()]); - } - } -} - -impl trap::TrapClass for BlockExpr { - fn class_name() -> &'static str { "BlockExpr" } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme BlockExpr is a subclass of AstNode - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme BlockExpr is a subclass of Element - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme BlockExpr is a subclass of Expr - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme BlockExpr is a subclass of Locatable - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - #[derive(Debug)] pub struct BoxPat { pub id: trap::TrapId, @@ -4582,81 +4491,6 @@ impl From> for trap::Label { } } -#[derive(Debug)] -pub struct ForExpr { - pub id: trap::TrapId, - pub attrs: Vec>, - pub iterable: Option>, - pub label: Option>, - pub loop_body: Option>, - pub pat: Option>, -} - -impl trap::TrapEntry for ForExpr { - fn extract_id(&mut self) -> trap::TrapId { - std::mem::replace(&mut self.id, trap::TrapId::Star) - } - - fn emit(self, id: trap::Label, out: &mut trap::Writer) { - out.add_tuple("for_exprs", vec![id.into()]); - for (i, v) in self.attrs.into_iter().enumerate() { - out.add_tuple("for_expr_attrs", vec![id.into(), i.into(), v.into()]); - } - if let Some(v) = self.iterable { - out.add_tuple("for_expr_iterables", vec![id.into(), v.into()]); - } - if let Some(v) = self.label { - out.add_tuple("for_expr_labels", vec![id.into(), v.into()]); - } - if let Some(v) = self.loop_body { - out.add_tuple("for_expr_loop_bodies", vec![id.into(), v.into()]); - } - if let Some(v) = self.pat { - out.add_tuple("for_expr_pats", vec![id.into(), v.into()]); - } - } -} - -impl trap::TrapClass for ForExpr { - fn class_name() -> &'static str { "ForExpr" } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme ForExpr is a subclass of AstNode - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme ForExpr is a subclass of Element - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme ForExpr is a subclass of Expr - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme ForExpr is a subclass of Locatable - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - #[derive(Debug)] pub struct ForType { pub id: trap::TrapId, @@ -5168,6 +5002,51 @@ impl From> for trap::Label { } } +#[derive(Debug)] +pub struct LabelableExpr { + _unused: () +} + +impl trap::TrapClass for LabelableExpr { + fn class_name() -> &'static str { "LabelableExpr" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LabelableExpr is a subclass of AstNode + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LabelableExpr is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LabelableExpr is a subclass of Expr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LabelableExpr is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + #[derive(Debug)] pub struct LetExpr { pub id: trap::TrapId, @@ -5558,73 +5437,6 @@ impl From> for trap::Label { } } -#[derive(Debug)] -pub struct LoopExpr { - pub id: trap::TrapId, - pub attrs: Vec>, - pub label: Option>, - pub loop_body: Option>, -} - -impl trap::TrapEntry for LoopExpr { - fn extract_id(&mut self) -> trap::TrapId { - std::mem::replace(&mut self.id, trap::TrapId::Star) - } - - fn emit(self, id: trap::Label, out: &mut trap::Writer) { - out.add_tuple("loop_exprs", vec![id.into()]); - for (i, v) in self.attrs.into_iter().enumerate() { - out.add_tuple("loop_expr_attrs", vec![id.into(), i.into(), v.into()]); - } - if let Some(v) = self.label { - out.add_tuple("loop_expr_labels", vec![id.into(), v.into()]); - } - if let Some(v) = self.loop_body { - out.add_tuple("loop_expr_loop_bodies", vec![id.into(), v.into()]); - } - } -} - -impl trap::TrapClass for LoopExpr { - fn class_name() -> &'static str { "LoopExpr" } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme LoopExpr is a subclass of AstNode - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme LoopExpr is a subclass of Element - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme LoopExpr is a subclass of Expr - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme LoopExpr is a subclass of Locatable - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - #[derive(Debug)] pub struct MacroExpr { pub id: trap::TrapId, @@ -7914,77 +7726,6 @@ impl From> for trap::Label { } } -#[derive(Debug)] -pub struct WhileExpr { - pub id: trap::TrapId, - pub attrs: Vec>, - pub condition: Option>, - pub label: Option>, - pub loop_body: Option>, -} - -impl trap::TrapEntry for WhileExpr { - fn extract_id(&mut self) -> trap::TrapId { - std::mem::replace(&mut self.id, trap::TrapId::Star) - } - - fn emit(self, id: trap::Label, out: &mut trap::Writer) { - out.add_tuple("while_exprs", vec![id.into()]); - for (i, v) in self.attrs.into_iter().enumerate() { - out.add_tuple("while_expr_attrs", vec![id.into(), i.into(), v.into()]); - } - if let Some(v) = self.condition { - out.add_tuple("while_expr_conditions", vec![id.into(), v.into()]); - } - if let Some(v) = self.label { - out.add_tuple("while_expr_labels", vec![id.into(), v.into()]); - } - if let Some(v) = self.loop_body { - out.add_tuple("while_expr_loop_bodies", vec![id.into(), v.into()]); - } - } -} - -impl trap::TrapClass for WhileExpr { - fn class_name() -> &'static str { "WhileExpr" } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme WhileExpr is a subclass of AstNode - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme WhileExpr is a subclass of Element - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme WhileExpr is a subclass of Expr - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme WhileExpr is a subclass of Locatable - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - #[derive(Debug)] pub struct WildcardPat { pub id: trap::TrapId, @@ -8166,6 +7907,106 @@ impl From> for trap::Label { } } +#[derive(Debug)] +pub struct BlockExpr { + pub id: trap::TrapId, + pub label: Option>, + pub attrs: Vec>, + pub is_async: bool, + pub is_const: bool, + pub is_gen: bool, + pub is_move: bool, + pub is_try: bool, + pub is_unsafe: bool, + pub stmt_list: Option>, +} + +impl trap::TrapEntry for BlockExpr { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("block_exprs", vec![id.into()]); + if let Some(v) = self.label { + out.add_tuple("labelable_expr_labels", vec![id.into(), v.into()]); + } + for (i, v) in self.attrs.into_iter().enumerate() { + out.add_tuple("block_expr_attrs", vec![id.into(), i.into(), v.into()]); + } + if self.is_async { + out.add_tuple("block_expr_is_async", vec![id.into()]); + } + if self.is_const { + out.add_tuple("block_expr_is_const", vec![id.into()]); + } + if self.is_gen { + out.add_tuple("block_expr_is_gen", vec![id.into()]); + } + if self.is_move { + out.add_tuple("block_expr_is_move", vec![id.into()]); + } + if self.is_try { + out.add_tuple("block_expr_is_try", vec![id.into()]); + } + if self.is_unsafe { + out.add_tuple("block_expr_is_unsafe", vec![id.into()]); + } + if let Some(v) = self.stmt_list { + out.add_tuple("block_expr_stmt_lists", vec![id.into(), v.into()]); + } + } +} + +impl trap::TrapClass for BlockExpr { + fn class_name() -> &'static str { "BlockExpr" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme BlockExpr is a subclass of AstNode + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme BlockExpr is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme BlockExpr is a subclass of Expr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme BlockExpr is a subclass of LabelableExpr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme BlockExpr is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + #[derive(Debug)] pub struct CallExpr { pub id: trap::TrapId, @@ -8842,6 +8683,60 @@ impl From> for trap::Label { } } +#[derive(Debug)] +pub struct LoopingExpr { + _unused: () +} + +impl trap::TrapClass for LoopingExpr { + fn class_name() -> &'static str { "LoopingExpr" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LoopingExpr is a subclass of AstNode + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LoopingExpr is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LoopingExpr is a subclass of Expr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LoopingExpr is a subclass of LabelableExpr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LoopingExpr is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + #[derive(Debug)] pub struct MacroCall { pub id: trap::TrapId, @@ -10005,3 +9900,270 @@ impl From> for trap::Label { } } } + +#[derive(Debug)] +pub struct ForExpr { + pub id: trap::TrapId, + pub label: Option>, + pub loop_body: Option>, + pub attrs: Vec>, + pub iterable: Option>, + pub pat: Option>, +} + +impl trap::TrapEntry for ForExpr { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("for_exprs", vec![id.into()]); + if let Some(v) = self.label { + out.add_tuple("labelable_expr_labels", vec![id.into(), v.into()]); + } + if let Some(v) = self.loop_body { + out.add_tuple("looping_expr_loop_bodies", vec![id.into(), v.into()]); + } + for (i, v) in self.attrs.into_iter().enumerate() { + out.add_tuple("for_expr_attrs", vec![id.into(), i.into(), v.into()]); + } + if let Some(v) = self.iterable { + out.add_tuple("for_expr_iterables", vec![id.into(), v.into()]); + } + if let Some(v) = self.pat { + out.add_tuple("for_expr_pats", vec![id.into(), v.into()]); + } + } +} + +impl trap::TrapClass for ForExpr { + fn class_name() -> &'static str { "ForExpr" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ForExpr is a subclass of AstNode + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ForExpr is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ForExpr is a subclass of Expr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ForExpr is a subclass of LabelableExpr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ForExpr is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ForExpr is a subclass of LoopingExpr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct LoopExpr { + pub id: trap::TrapId, + pub label: Option>, + pub loop_body: Option>, + pub attrs: Vec>, +} + +impl trap::TrapEntry for LoopExpr { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("loop_exprs", vec![id.into()]); + if let Some(v) = self.label { + out.add_tuple("labelable_expr_labels", vec![id.into(), v.into()]); + } + if let Some(v) = self.loop_body { + out.add_tuple("looping_expr_loop_bodies", vec![id.into(), v.into()]); + } + for (i, v) in self.attrs.into_iter().enumerate() { + out.add_tuple("loop_expr_attrs", vec![id.into(), i.into(), v.into()]); + } + } +} + +impl trap::TrapClass for LoopExpr { + fn class_name() -> &'static str { "LoopExpr" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LoopExpr is a subclass of AstNode + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LoopExpr is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LoopExpr is a subclass of Expr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LoopExpr is a subclass of LabelableExpr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LoopExpr is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme LoopExpr is a subclass of LoopingExpr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct WhileExpr { + pub id: trap::TrapId, + pub label: Option>, + pub loop_body: Option>, + pub attrs: Vec>, + pub condition: Option>, +} + +impl trap::TrapEntry for WhileExpr { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("while_exprs", vec![id.into()]); + if let Some(v) = self.label { + out.add_tuple("labelable_expr_labels", vec![id.into(), v.into()]); + } + if let Some(v) = self.loop_body { + out.add_tuple("looping_expr_loop_bodies", vec![id.into(), v.into()]); + } + for (i, v) in self.attrs.into_iter().enumerate() { + out.add_tuple("while_expr_attrs", vec![id.into(), i.into(), v.into()]); + } + if let Some(v) = self.condition { + out.add_tuple("while_expr_conditions", vec![id.into(), v.into()]); + } + } +} + +impl trap::TrapClass for WhileExpr { + fn class_name() -> &'static str { "WhileExpr" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme WhileExpr is a subclass of AstNode + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme WhileExpr is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme WhileExpr is a subclass of Expr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme WhileExpr is a subclass of LabelableExpr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme WhileExpr is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme WhileExpr is a subclass of LoopingExpr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 1c56649d476..3e240b0b61d 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -11,7 +11,7 @@ lib/codeql/rust/elements/Attr.qll 53887a49513b95e38344b57d824a7474331467561f1edf lib/codeql/rust/elements/AwaitExpr.qll d8b37c01f7d27f0ec40d92a533a8f09a06af7ece1ae832b4ea8f2450c1762511 92cdb7ff0efddf26bed2b7b2729fddd197e26c1a11c8fec0c747aab642710c21 lib/codeql/rust/elements/BecomeExpr.qll 7a3cfc4894feb6be1cde664f675b18936434e68ccea52e55314c33d01491e34f 49666eca509b30d44bb02702bda67239c76bf8d9f231022c9cf6ecca123f8616 lib/codeql/rust/elements/BinaryExpr.qll 394522da3bc3a716fc7bc40c3560143ca840f5d210cfcba2a752c3026dd0f725 fbbd6fb79bf16a7d9820613654c584cd7ff3e7a29988f3920b6cfbe746acfd8d -lib/codeql/rust/elements/BlockExpr.qll b952fd44b89de248931d4089834d2c9406f6f2fc1a3f5c2365156be4e55157cf daccc07ab11ac696679b9fadc99f40b1bf579c90bf6c7cca6e82eaa313932ede +lib/codeql/rust/elements/BlockExpr.qll b5cf57119b15f27d0bc258dfa375b0ef2730c157870ff543f0dc7a8cfe514182 f6a01999606b010c81ef9c6ff1385e6640632b6f5ce067ffeb0ef0af0a0aeb92 lib/codeql/rust/elements/BoxPat.qll 1b2c3fff171aa6aa238c9460b122f26c79e04577cea67fa856de99842ba873d4 0caf8d23ed6e0997a6b8751def27641582151fba6e24fccf798712a4690b42f1 lib/codeql/rust/elements/BreakExpr.qll 7ca3807a20e9a9a988d1fd7abebf240325ed422fcb45c719ba46272f031f94db dffb7379d3f3ba220acfbd05eb7bb6cfd9cfda211e9c8b1f5240ca5fa61be3fc lib/codeql/rust/elements/CallExpr.qll f336500ca7a611b164d48b90e80edb0c0d3816792b0ececce659ac1ff1ffeb3e f99a9c55466418ef53860c44d9f2d6161af4b492178ddd9e5870dff742b70ae5 @@ -38,7 +38,7 @@ lib/codeql/rust/elements/ExternItemList.qll bc96f188970e8dc0cd1e77dea3e49b715edf lib/codeql/rust/elements/FieldExpr.qll 8102cd659f9059cf6af2a22033cfcd2aae9c35204b86f7d219a05f1f8de54b3b f818169dddf5102095ae1410583615f80031376a08b5307d0c464e79953c3975 lib/codeql/rust/elements/FieldList.qll bd243adc4696c60f636055a1c2da28039fe2028476c9247eb6a68003b849b757 ab63cdf410afd1e515f873b49f46bb5c2bf27e6c78fd206ccbdba064c4c0a4b2 lib/codeql/rust/elements/FnPtrType.qll c4a90dc660cf620972dc23b95494f5caf9f050eabd4bdb52fdc061f8797ba9a1 f8defc91582fa503607664668f9e2e6c2cd8b320c7c449610f21e52e332a129f -lib/codeql/rust/elements/ForExpr.qll 312804d53dd9236a2f2a15c9d6ec348b46e139a54eb5893e7e12487725df7444 fa5e20099b1179033bc209bad3548e3d1d4019c7fe0e455cec8ca1a9d48692ab +lib/codeql/rust/elements/ForExpr.qll 0cc8bfe10b8baf62a1ff65c8463cfb17ab64b41c30c9e1edb962a227df2036d9 b1be73294e6da0f49fd32177ad0b05fecf26081d5ce424f288be99a4bd59cc84 lib/codeql/rust/elements/ForType.qll 0036bed8749358c356d78c4a0eef40d73e2796284293cde5604ae70ddd6d0470 4edcaf8f7c67d42ebe3ebb1be6a7643758717d4fe88f5f648b6a1c5ff4ee4de7 lib/codeql/rust/elements/Format.qll 506172d176f4b965f428585c032464f4abe07a0e47c574f8e011d8641ec45370 653e81bf233b8729649064de64f4a7a8533f8864ac6d2ea913f347088c924c60 lib/codeql/rust/elements/FormatArgsArg.qll 5bc9b4cd1bac7131165836e93838c45452a08ea6011741cbddace3cbf9c69440 f825140e98dc9800d5c045402186793c7b21511448e2f6bf6402d1e06305219c @@ -59,6 +59,7 @@ lib/codeql/rust/elements/InferType.qll c71184ae6aa181be94e299882503350e057493e17 lib/codeql/rust/elements/Item.qll 5c9148ff0eaeb4404c2d8156e7df0ef5753fd44ead972da05a49659ddaa25480 78446f788617e40525d4d4b489848e75f2143a90e18d40974c3bff7b1e7c825c lib/codeql/rust/elements/ItemList.qll c33e46a9ee45ccb194a0fe5b30a6ad3bcecb0f51486c94e0191a943710a17a7d 5a69c4e7712b4529681c4406d23dc1b6b9e5b3c03552688c55addab271912ed5 lib/codeql/rust/elements/Label.qll a31d41db351af7f99a55b26cdbbc7f13b4e96b660a74e2f1cc90c17ee8df8d73 689f87cb056c8a2aefe1a0bfc2486a32feb44eb3175803c61961a6aeee53d66e +lib/codeql/rust/elements/LabelableExpr.qll 598be487cd051b004ab95cbbc3029100069dc9955851c492029d80f230e56f0d 92c49b3cfdaba07982f950e18a8d62dae4e96f5d9ae0d7d2f4292628361f0ddc lib/codeql/rust/elements/LetElse.qll 85d16cb9cb2162493a9bacfe4b9e6a3b325d9466175b6d1a8e649bdf2191b864 c268d0878e9f82e8ede930b3825745c39ab8cd4db818eb9be6dc5ca49bee7579 lib/codeql/rust/elements/LetExpr.qll 435f233890799a9f52972a023e381bc6fe2e0b3df1e696dc98b21682a3c1d88e b34da72dd222a381e098f160551ec614ebb98eb46af35c6e1d337e173d8ec4b9 lib/codeql/rust/elements/LetStmt.qll e589d750ff87c25e28e15dab61e1a3555a45ced42158b05c991c6f5873abd86a 383484181b825cd7bc20e014fc4d5888f66e1f257502e1893f3d55aed2cdef3d @@ -68,7 +69,8 @@ lib/codeql/rust/elements/LifetimeParam.qll db9f2c7bb32d49808993b400875e79560ac54 lib/codeql/rust/elements/LiteralExpr.qll 40b67404b7c2b81e5afabc53a2a93e0a503f687bb31a2b4bfa4e07b2d764eb8d 67ab1be2286e769fba7a50ca16748e3c141760ccaefaebae99faa71f523a43d5 lib/codeql/rust/elements/LiteralPat.qll daffb5f380a47543669c8cc92628b0e0de478c3ac82685802c63e8d75a206bed adfe9796598cf6ca4a9170c89ffd871e117f1cea6dd7dd80ecbbb947327a1a5d lib/codeql/rust/elements/Locatable.qll 2855efa4a469b54e0ca85daa89309a8b991cded6f3f10db361010831ba1e11d3 00c3406d14603f90abea11bf074eaf2c0b623a30e29cf6afc3a247cb58b92f0f -lib/codeql/rust/elements/LoopExpr.qll 58ade0bc4a01a1cc361363682fde3ea56f4c5fbb4b28f5723ceff52ebaf897d7 fa299162c742bcf3b2211dc20821b312e3c133350c288a050eb26e6f8b5a5c78 +lib/codeql/rust/elements/LoopExpr.qll ee171177650fa23eef102a9580765f4b6073a1cc41bab1ec31ad4f84ffe6c2c9 bfcf0cca4dc944270d9748a202829a38c64dfae167c0d3a4202788ceb9daf5f6 +lib/codeql/rust/elements/LoopingExpr.qll 7ad7d4bbfd05adc0bb9b4ca90ff3377b8298121ca5360ffb45d5a7a1e20fe37a 964168b2045ee9bad827bba53f10a64d649b3513f2d1e3c17a1b1f11d0fc7f3a lib/codeql/rust/elements/MacroCall.qll a39a11d387355f59af3007dcbab3282e2b9e3289c1f8f4c6b96154ddb802f8c3 88d4575e462af2aa780219ba1338a790547fdfc1d267c4b84f1b929f4bc08d05 lib/codeql/rust/elements/MacroDef.qll acb39275a1a3257084314a46ad4d8477946130f57e401c70c5949ad6aafc5c5f 6a8a8db12a3ec345fede51ca36e8c6acbdce58c5144388bb94f0706416fa152a lib/codeql/rust/elements/MacroExpr.qll ea9fed13f610bab1a2c4541c994510e0cb806530b60beef0d0c36b23e3b620f0 ad11a6bbd3a229ad97a16049cc6b0f3c8740f9f75ea61bbf4eebb072db9b12d2 @@ -160,7 +162,7 @@ lib/codeql/rust/elements/VariantList.qll 07adfe5750b2d5b50c8629f36feba24edd84f75 lib/codeql/rust/elements/Visibility.qll d2cf0727efaf8df6b3808cb4a6b2e26d18e42db766d92e97ad3ef046d91cb9e5 8947a1e2d48b532c6455ddf143fa5b1dff28c40da1f1c6a72769fc9db7ecbaf6 lib/codeql/rust/elements/WhereClause.qll da51212766700e40713fff968078a0172a4f73eebc5425d8e0d60b03c2fe59fa 0ec036aea729b8f4af0eb8118911dce715e2eb4640ae7b5e40a007a48da03899 lib/codeql/rust/elements/WherePred.qll 4815cd8f2a536c895e1f6831bef2ee6b9ea42c4fea12df1f164de1c965795bc1 3b46806767d81218d2e21656afe39c957c364ff7067c9af3ae8bacbf7f93858b -lib/codeql/rust/elements/WhileExpr.qll 9c12c26f953163c70020669327bd8c931493ef7fb4b75e6711202c0bab1d2697 2e2c96425bcd4414c65d9069a71a5123a3a10dd1449cafc121ac08f91ea49728 +lib/codeql/rust/elements/WhileExpr.qll 9e0c23057bf3fa3e050d5f6de0650f554ce576861783ea7d1e4c7d35db129ad3 b294c4f6e4dea922a4274779287edcb484409b2654a553298626ded9d1e8c5a4 lib/codeql/rust/elements/WildcardPat.qll 4f941afc5f9f8d319719312399a8f787c75a0dbb709ec7cf488f019339635aab a9140a86da752f9126e586ddb9424b23b3fb4841a5420bac48108c38bb218930 lib/codeql/rust/elements/YeetExpr.qll 4172bf70de31cab17639da6eed4a12a7afcefd7aa9182216c3811c822d3d6b17 88223aab1bef696f508e0605615d6b83e1eaef755314e6a651ae977edd3757c3 lib/codeql/rust/elements/YieldExpr.qll de2dc096a077f6c57bba9d1c2b2dcdbecce501333753b866d77c3ffbe06aa516 1f3e8949689c09ed356ff4777394fe39f2ed2b1e6c381fd391790da4f5d5c76a @@ -184,6 +186,7 @@ lib/codeql/rust/elements/internal/AwaitExprConstructor.qll 44ff1653e73d5b9f6885c lib/codeql/rust/elements/internal/BecomeExprConstructor.qll ba073aaa256cb8827a0307c3128d50f62b11aac0b1f324e48c95f30351a9b942 3a787ded505c3158fa4f4923f66e8ecdcb7b5f86f27f64c5412dc32dca031f18 lib/codeql/rust/elements/internal/BinaryExprConstructor.qll 7f9b17757f78b9fb7c46e21d2040a77fa50083bef4911c8464991c3d1ad91d87 a59390cd8e896c0bfbdc9ba0674e06d980ffcefa710fbc9886be52ed427e9717 lib/codeql/rust/elements/internal/BlockExprConstructor.qll 438337c807645e98a01440f3f4610d68b0567ba15c8f51dc43bf5a30c9af3696 48ce7a546910c884619762349b8ada9836284f8008298fdb0070a38f7ddf25a0 +lib/codeql/rust/elements/internal/BlockExprImpl.qll 36ac09e4a6eeeec22919b62b1d004bdb5bb2527e67932c308aec383a770768d6 3b4b2a2014f6fe075c63a2d633b297566b548ef2e4343cadf067a9edbcadc876 lib/codeql/rust/elements/internal/BoxPatConstructor.qll 153f110ba25fd6c889092bfd16f73bb610fa60d6e0c8965d5f44d2446fcd48a2 9324cf0d8aa29945551bf8ab64801d598f57aab8cd4e19bcd4e9ef8a4a4e06eb lib/codeql/rust/elements/internal/BreakExprConstructor.qll 356be043c28e0b34fdf925a119c945632ee883c6f5ebb9a27003c6a8d250afd9 bb77e66b04bb9489340e7506931559b94285c6904b6f9d2f83b214cba4f3cfd5 lib/codeql/rust/elements/internal/CallExprBaseImpl.qll d2749cc1a9d7ee8bf7f34b6c3e0238a576a68e439a8c10a503c164ff45ffcbeb ffc7b0a8841945fe6736b0e1aed7d9ed69185db03dee2b16da121325b39397c7 @@ -256,6 +259,7 @@ lib/codeql/rust/elements/internal/LifetimeParamImpl.qll 8909288801bff8d3e87096df lib/codeql/rust/elements/internal/LiteralExprConstructor.qll 8ea3569bd50704ce7d57be790d2dfd38f4c40cb0b12e0dd60d6830e8145a686f 88d07ad3298003f314f74bd8e3d64a3094de32080ad42a7e6741c416c3856095 lib/codeql/rust/elements/internal/LiteralPatConstructor.qll b660cb428a0cba0b713fc7b07d5d2921de4a2f65a805535fb6387684c40620de 2dbc9fbc56e9de53d24265d6b13738ef5b9ced33cc3c4c1c270e04dc2fc1330f lib/codeql/rust/elements/internal/LoopExprConstructor.qll 45f3f8f7441fcab6adc58831421679ee07bac68ac0417f3cbc90c97426cc805b f7ab3361b4a11e898126378ea277d76949466946762cd6cb5e9e9b4bb9860420 +lib/codeql/rust/elements/internal/LoopingExprImpl.qll 17885c1bcf7b5a3f9c7bbad3d4d55e24372af0dedd5e7fc0efcfc0a8b2cdad70 104dc45ca399b9f6e8227ad561679f728d60170398a52b31fc90cb2a2dd3c33c lib/codeql/rust/elements/internal/MacroCallConstructor.qll 707fee4fba1fd632cd00128f493e8919eaaea552ad653af4c1b7a138e362907d b49e7e36bf9306199f2326af042740ff858871b5c79f6aeddf3d5037044dbf1f lib/codeql/rust/elements/internal/MacroDefConstructor.qll 382a3bdf46905d112ee491620cc94f87d584d72f49e01eb1483f749e4709c055 eb61b90d8d8d655c2b00ff576ae20c8da9709eeef754212bc64d8e1558ad05ce lib/codeql/rust/elements/internal/MacroDefImpl.qll f26e787ffd43e8cb079db01eba04412dbf32c338938acf1bc09a2f094bbdfdfe 044f43bc94fe4b6df22afae32e9f039d1d0d9e85ad9f24b6388be71211c37ce5 @@ -420,7 +424,7 @@ lib/codeql/rust/elements/internal/generated/Attr.qll 2e7983b2c462750065ed58cc10c lib/codeql/rust/elements/internal/generated/AwaitExpr.qll 1d71af702a1f397fb231fae3e0642b3deeba0cd5a43c1d8fabdff29cac979340 e0bfa007bdecc5a09a266d449d723ae35f5a24fbdfc11e4e48aeea3ec0c5147c lib/codeql/rust/elements/internal/generated/BecomeExpr.qll 7a211b785a4a2f961242d1d73fd031d381aad809f7b600ce7f7f864518bb7242 17a0388680007871748cfdc6621f700a7c2817b9601e1bd817fb48561e7c63ad lib/codeql/rust/elements/internal/generated/BinaryExpr.qll 64e9bd9c571edd6e5f3e7662b956b1d87fa0354ce6fe95da9caf25ac16b66c68 3fca09fdbe879db2ca3293618896a462e96376a2963d15cce3d5b1baac552fcb -lib/codeql/rust/elements/internal/generated/BlockExpr.qll ccfbdc7bd268735a0424ff08dcf37d0e1fed61d5fe0520593c23f2490d400438 0facad59f6aba13ee0c069b691c99f52c04b723a2bfad4da226190c3c42dcabf +lib/codeql/rust/elements/internal/generated/BlockExpr.qll 5a5ddbe34bc478a7bd9b0d07d3b6f017c2d1f20581d859251a963314e6514d1f 9804c30b8b279038b864c52557535f854bd012bacdfe8e5840f1f777c74e52df lib/codeql/rust/elements/internal/generated/BoxPat.qll ec946a3e671ab7417e04b0207967adad004df512c570c4f0780ca5816d12d75f b0e64860855c4e85914042b1a51034899ff7cd1b2c6857188de89310a2726ea3 lib/codeql/rust/elements/internal/generated/BreakExpr.qll 0f428a8b2f4209b134c2ffc3e1c93c30bc6b0e9c9172f140cefa88c1f77d8690 957b39f38ff6befe9061f55bc0b403c2f1c366dd0cf63b874bae6f8216576d76 lib/codeql/rust/elements/internal/generated/CallExpr.qll 23ee64e3bf643cd5e6ff705181d2bb31e1aeaffecb5bdce73836172dbf15f12f 34b280139b1f8f70d78e1432392f03c971be392e8cb68d014eb325d0c101bddd @@ -447,7 +451,7 @@ lib/codeql/rust/elements/internal/generated/ExternItemList.qll 6bc97fdae6c411cab lib/codeql/rust/elements/internal/generated/FieldExpr.qll 3e506b5cb93793ec30f56bb637a600db869fcba6181b068516a671d55c362739 7bbf953696d763ad6b210f378f487ba85b875fa115b22c0c0508599a63633502 lib/codeql/rust/elements/internal/generated/FieldList.qll 43c13c6e3c9ba75a7a4cb870fc4f18752001584d48b9df0734055a6ebb789331 7c51b0b13eb02f1286d3365e53a976ba2655c4dbd8e735bc11c8b205c829e1ee lib/codeql/rust/elements/internal/generated/FnPtrType.qll 748d766dbefd19a7d644734c57885eeede66897029bbfe1b87919517f43bfde2 5a7d80acc00e56594ed85026a8ea4923104d2e98c2e42db8c5bcd32ddd164e48 -lib/codeql/rust/elements/internal/generated/ForExpr.qll 541b62b48911d4999f9ed64ab6c8b9910073ac4add0225761f319677328cf120 976c3a91c9eedfb1e2d9ea76ac501348643b3d23c723d7a777042258d416d091 +lib/codeql/rust/elements/internal/generated/ForExpr.qll d81751e9599874a1292a0aace80b2de60ab36fc43f74ec08fbdfe044fc19e5c1 34a64586f8ffbadd44d0e747f69ab550a16149b658a9c92d9593689cb9a4f6fc lib/codeql/rust/elements/internal/generated/ForType.qll 3d43d044a1189281f09c55caafb6c8020a836f49e2866077086101925a573cf2 646b59bfd1b428aaf7211f574c49f79cb4c6a79ca151aa0663b2b31480298721 lib/codeql/rust/elements/internal/generated/Format.qll 37ad20cf2bf363b4027a8913d095292c8a4eb8ccdf2a9965f2fb7d41930f9bfe 329b89cdd75ce951269273dd18897e32ff5cfcc94f451001c64143386c1e48dd lib/codeql/rust/elements/internal/generated/FormatArgsArg.qll e07a1ae310f590003f1b88fada7dcf4847c99adb9d4c838d1c88e66e1da85c5f 0ef7342451fe2cb06e765fb4b33bb8c4a9b927f5edbc8feb5c6ba3655697f447 @@ -468,6 +472,7 @@ lib/codeql/rust/elements/internal/generated/InferType.qll 23ee25135c59ea5578cdf7 lib/codeql/rust/elements/internal/generated/Item.qll 25e645cb41222c21065798fb6cb0488bfef007aeb9b89717f58913f9b29d5559 3146941e55db2ff7c51ec030b4414e20d66d154cf6854b1a3fa42e74a09dfb77 lib/codeql/rust/elements/internal/generated/ItemList.qll 73c8398a96d4caa47a2dc114d76c657bd3fcc59e4c63cb397ffac4a85b8cf8ab 540a13ca68d414e3727c3d53c6b1cc97687994d572bc74b3df99ecc8b7d8e791 lib/codeql/rust/elements/internal/generated/Label.qll 6630fe16e9d2de6c759ff2684f5b9950bc8566a1525c835c131ebb26f3eea63e 671143775e811fd88ec90961837a6c0ee4db96e54f42efd80c5ae2571661f108 +lib/codeql/rust/elements/internal/generated/LabelableExpr.qll 896fd165b438b60d7169e8f30fa2a94946490c4d284e1bbadfec4253b909ee6c 5c6b029ea0b22cf096df2b15fe6f9384ad3e65b50b253cae7f19a2e5ffb04a58 lib/codeql/rust/elements/internal/generated/LetElse.qll 7ca556118b5446bfc85abba8f0edd4970e029b30d414ea824a1b5f568310a76c a403540881336f9d0269cbcdb4b87107a17ab234a985247dc52a380f150a1641 lib/codeql/rust/elements/internal/generated/LetExpr.qll 9af0f89b294c8a0a751317e7074fe370339563d36c1df4911d1ea082a4df77fd 68272593d1feb88990bfbd0b8c222776f085e49694894384fc6d96e9464ba734 lib/codeql/rust/elements/internal/generated/LetStmt.qll aa1852db86ec29f857a90677f0c6b4a07f0fd965fc193d4141be95ce15862fca 40f32a37c0cc161b099fe0b4c7d713da928781d3e2c3de90db991df1d9062647 @@ -477,7 +482,8 @@ lib/codeql/rust/elements/internal/generated/LifetimeParam.qll bcbde38bfb99034e47 lib/codeql/rust/elements/internal/generated/LiteralExpr.qll f3a564d0a3ed0d915f5ab48e12246777e4972ad987cd9deaafeb94cf407b2877 2337c3d5f60361bd10f6aeca301e88255f5dffb85301cf36cbbfa1a65bfad1cd lib/codeql/rust/elements/internal/generated/LiteralPat.qll ecc2bfe559abfce1be873fbf7b61b5728897c9afc3bb3f69551d8320d273da71 42196fb6a4a0ff9b570fd0bdbc920f24744b3f46772efbb46648af7fbfe1fbda lib/codeql/rust/elements/internal/generated/Locatable.qll c897dc1bdd4dfcb6ded83a4a93332ca3d8f421bae02493ea2a0555023071775e b32d242f8c9480dc9b53c1e13a5cb8dcfce575b0373991c082c1db460a3e37b8 -lib/codeql/rust/elements/internal/generated/LoopExpr.qll 22b755dfaf238ecea722c0c94c399992014e23481ec6fdd61f803bbec012b6f9 08731630c2dc05aa1e0ada222a6057752d9ce737329c62076708828247a358be +lib/codeql/rust/elements/internal/generated/LoopExpr.qll db6bc87e795c9852426ec661fa2c2c54106805897408b43a67f5b82fb4657afd 1492866ccf8213469be85bbdbcae0142f4e2a39df305d4c0d664229ecd1ebdb9 +lib/codeql/rust/elements/internal/generated/LoopingExpr.qll 0792c38d84b8c68114da2bbdfef32ef803b696cb0fd06e10e101756d5c46976c 111fe961fad512722006323c3f2a075fddf59bd3eb5c7afc349835fcec8eb102 lib/codeql/rust/elements/internal/generated/MacroCall.qll fc8988696493992cc4fdce8c0e5610c54ee92ea52ebb05262338f8b612353f50 188a2d7a484bd402a521787371e64f6e00e928306c8d437e6b19bf890a7aa14e lib/codeql/rust/elements/internal/generated/MacroDef.qll e9b3f07ba41aa12a8e0bd6ec1437b26a6c363065ce134b6d059478e96c2273a6 87470dea99da1a6afb3a19565291f9382e851ba864b50a995ac6f29589efbd70 lib/codeql/rust/elements/internal/generated/MacroExpr.qll 03a1daa41866f51e479ac20f51f8406d04e9946b24f3875e3cf75a6b172c3d35 1ae8ca0ee96bd2be32575d87c07cc999a6ff7770151b66c0e3406f9454153786 @@ -504,7 +510,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60 lib/codeql/rust/elements/internal/generated/ParenPat.qll ce24b8f8ecbf0f204af200317405724063887257460c80cf250c39b2fdf37185 e7c87d37e1a0ca7ea03840017e1aa9ddb7f927f1f3b6396c0305b46aeee33db6 lib/codeql/rust/elements/internal/generated/ParenType.qll 9cc954d73f8330dcac7b475f97748b63af5c8766dee9d2f2872c0a7e4c903537 c07534c8a9c683c4a9b11d490095647e420de0a0bfc23273eaf6f31b00244273 -lib/codeql/rust/elements/internal/generated/ParentChild.qll b4d25c43ed44715053255c3c2f8aeb8d21826adc365f24026b2123a4f25cba86 1bc4bb0380a1a8b69055ffeac203b11b2a1b94e5ad88d1b32ff659e8feb26016 +lib/codeql/rust/elements/internal/generated/ParentChild.qll 2237ba700c7d790cbbf7ad4d86889d22c6d210af62474ad8d363d79abb574722 36f9d47b002a241f0f793816ca9e6327fbbefb02268665553c56ded6012f82ec lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4 lib/codeql/rust/elements/internal/generated/Path.qll f2b1be2f8f44001a6533533c978c4a9a8b7d64838d6f39eef5f0c0e7890611b8 d724a00a38f42429ffa8fb3bffbb5ec69e16a32ceeeb1d1f026fc7adf87424a8 lib/codeql/rust/elements/internal/generated/PathExpr.qll 2096e3c1db22ee488a761690adabfc9cfdea501c99f7c5d96c0019cb113fc506 54245ce0449c4e263173213df01e079d5168a758503a5dbd61b25ad35a311140 @@ -517,7 +523,7 @@ lib/codeql/rust/elements/internal/generated/PtrType.qll 40099c5a4041314b66932dfd lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll efd93730de217cf50dcba5875595263a5eadf9f7e4e1272401342a094d158614 229b251b3d118932e31e78ac4dfb75f48b766f240f20d436062785606d44467b -lib/codeql/rust/elements/internal/generated/Raw.qll 5f83209cda8319c5c6c932631b60c6f2163d2d9cf7be63f63523e2206c01d004 3581039746e86365f37644e86ac2c89d67e2123aa1b039d9e0afdffc7156c96d +lib/codeql/rust/elements/internal/generated/Raw.qll 462d87edee9e0fc463f789a765e19d94c4c027a73db876ad306f918dd87e9511 33a6782598a6ba0e02e6b772b5b74ebbe609b0bc3a92180f85db7472e00aa8d9 lib/codeql/rust/elements/internal/generated/RecordExpr.qll eb6cb662e463f9260efae1a6ce874fa781172063b916ef1963f861e9942d308d 1a21cbccc8f3799ff13281e822818ebfb21d81591720a427cac3625512cb9d40 lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1 lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0 @@ -543,7 +549,7 @@ lib/codeql/rust/elements/internal/generated/Static.qll 5fbd6879858cf356d4bdaa6da lib/codeql/rust/elements/internal/generated/Stmt.qll 8473ff532dd5cc9d7decaddcd174b94d610f6ca0aec8e473cc051dad9f3db917 6ef7d2b5237c2dbdcacbf7d8b39109d4dc100229f2b28b5c9e3e4fbf673ba72b lib/codeql/rust/elements/internal/generated/StmtList.qll a667193e32341e17400867c6e359878c4e645ef9f5f4d97676afc0283a33a026 a320ed678ee359302e2fc1b70a9476705cd616fcfa44a499d32f0c7715627f73 lib/codeql/rust/elements/internal/generated/Struct.qll 4d57f0db12dc7ad3e31e750a24172ef1505406b4dab16386af0674bd18bf8f4b 1a73c83df926b996f629316f74c61ea775be04532ab61b56af904223354f033e -lib/codeql/rust/elements/internal/generated/Synth.qll 1ba88215c3f0640558a644534b954e4b93acb15a0f51a1e4887230f451718aa9 747eb3bec1c7245e59ea2b500604f5b4e614e4f061473d1a22fa398ee48ba080 +lib/codeql/rust/elements/internal/generated/Synth.qll 0e5767568fd119df13928adf00950586f5f9f355dae520059b2d6daa7a2bda56 219b40f6458fec2cc436dc2cf80bb1dbfb34dfdbe8576606b5e25f78d36d6210 lib/codeql/rust/elements/internal/generated/SynthConstructors.qll e929c49ea60810a2bbc19ad38110b8bbaf21db54dae90393b21a3459a54abf6f e929c49ea60810a2bbc19ad38110b8bbaf21db54dae90393b21a3459a54abf6f lib/codeql/rust/elements/internal/generated/Token.qll 77a91a25ca5669703cf3a4353b591cef4d72caa6b0b9db07bb9e005d69c848d1 2fdffc4882ed3a6ca9ac6d1fb5f1ac5a471ca703e2ffdc642885fa558d6e373b lib/codeql/rust/elements/internal/generated/TokenTree.qll 8577c2b097c1be2f0f7daa5acfcf146f78674a424d99563e08a84dd3e6d91b46 d2f30764e84dbfc0a6a5d3d8a5f935cd432413688cb32da9c94e420fbc10665c @@ -574,11 +580,11 @@ lib/codeql/rust/elements/internal/generated/VariantList.qll 4eb923ca341033c256ca lib/codeql/rust/elements/internal/generated/Visibility.qll aba81820f30bed0fd2cd06831f7256af15ae32525b2a437896420b4cc067ea38 d6aed90b27124b812daf2ddd14b4e181277cbe638b4ccaab74e27681ac30e4ab lib/codeql/rust/elements/internal/generated/WhereClause.qll d6c8f72bbec5d71c024f0d365c1c5e474f4d24ded0d34c56c1f66b1e4a384e9d ed14311d140eee00d3b26a4972f53e20d5af1bddf88fb5618e7e2d3ae1d816f3 lib/codeql/rust/elements/internal/generated/WherePred.qll 342050e824ca6eb6116488d46cfc03efa79193b4de6049e1f5d4a9fe527b3036 ed07a81de7d63f853c93cbb7291eea3d7169953e34c2f2f98b570028dd1f8cd9 -lib/codeql/rust/elements/internal/generated/WhileExpr.qll fec8a9211b82a80601bf731db17409c5de6bf145295623bd86e28f96452fd91d 3916cf0c0e3b82b834727fc37809dd3e158f395bdf39971abe40b98e5f95a4d2 +lib/codeql/rust/elements/internal/generated/WhileExpr.qll 7edf1f23fbf953a2baabcdbf753a20dff9cf2bc645dcf935f1e68f412971a8f7 d2fa7ada1f48f6b4566c75747584068e925be925d39d6e6ebf61d21bde3b6522 lib/codeql/rust/elements/internal/generated/WildcardPat.qll d74b70b57a0a66bfae017a329352a5b27a6b9e73dd5521d627f680e810c6c59e 4b913b548ba27ff3c82fcd32cf996ff329cb57d176d3bebd0fcef394486ea499 lib/codeql/rust/elements/internal/generated/YeetExpr.qll cac328200872a35337b4bcb15c851afb4743f82c080f9738d295571eb01d7392 94af734eea08129b587fed849b643e7572800e8330c0b57d727d41abda47930b lib/codeql/rust/elements/internal/generated/YieldExpr.qll 37e5f0c1e373a22bbc53d8b7f2c0e1f476e5be5080b8437c5e964f4e83fad79a 4a9a68643401637bf48e5c2b2f74a6bf0ddcb4ff76f6bffb61d436b685621e85 -lib/codeql/rust/elements.qll 173d5ffbcc2874757033caab37559e84dbcbfed319730f8e41a4e9e10b146835 173d5ffbcc2874757033caab37559e84dbcbfed319730f8e41a4e9e10b146835 +lib/codeql/rust/elements.qll 76fe494d20d2665777bcb5c5ced016a262789a0e6aa874c1a77ce4cb134422b6 76fe494d20d2665777bcb5c5ced016a262789a0e6aa874c1a77ce4cb134422b6 test/extractor-tests/generated/Abi/Abi.ql 7f6e7dc4af86eca3ebdc79b10373988cd0871bd78b51997d3cffd969105e5fdd 2f936b6ca005c6157c755121584410c03e4a3949c23bee302fbe05ee10ce118f test/extractor-tests/generated/Abi/Abi_getAbiString.ql a496762fcec5a0887b87023bbf93e9b650f02e20113e25c44d6e4281ae8f5335 14109c7ce11ba25e3cd6e7f1b3fcb4cb00622f2a4eac91bfe43145c5f366bc52 test/extractor-tests/generated/ArgList/ArgList.ql e412927756e72165d0e7c5c9bd3fca89d08197bbf760db8fb7683c64bb2229bc 043dba8506946fbb87753e22c387987d7eded6ddb963aa067f9e60ef9024d684 @@ -614,7 +620,7 @@ test/extractor-tests/generated/BinaryExpr/BinaryExpr_getAttr.ql 26d985ac4b668d78 test/extractor-tests/generated/BinaryExpr/BinaryExpr_getLhs.ql c3f19d8a60066ad6b1810291a669473c75b659cd2f6ac3ab9ed3db2203d4145c c05c5e0226e30f923155669ffc79cfe63af1ca464e8dfc85888dda5f7049711b test/extractor-tests/generated/BinaryExpr/BinaryExpr_getOperatorName.ql 33612159be1c111e3306009d0b04579450fc962a81119b6ea4e255d3c409b401 1a0995b298f50242217cfef81dca8ac978e19e06f90a5f4caadcb6f84460fec2 test/extractor-tests/generated/BinaryExpr/BinaryExpr_getRhs.ql 3bcd36b678e87d5c29a43b69c54c80468a89aefa7e69481b48158ae794a53160 a629dc1472b3f6fd7c608ff760e83d8e1363db81dfe9a4b2968690c2ba4925ca -test/extractor-tests/generated/BlockExpr/BlockExpr.ql 0ab66b190d4e2aa784e61088c4779ef4d08cb4453677ea087c4f9aa369494bc2 1c3b5794008114d1297695d82590220929e3974e27836b2c6062d14b73379a40 +test/extractor-tests/generated/BlockExpr/BlockExpr.ql 19caa39aaa39356219dda740b7152f85e43a4f8d6295841e2c535c7e3bda7a5a bd668574ba41021e758e391d4790b871439badb2486ccf6a5aaf788ad6ae4142 test/extractor-tests/generated/BlockExpr/BlockExpr_getAttr.ql 15d4d9853d3262ce6ec629c075c60a76eb112dcafe34b71df0e09b39282223cf 792c498bc7079bb5b93034b8a87db3b275a591d78954e844821aeacffe4258ea test/extractor-tests/generated/BlockExpr/BlockExpr_getLabel.ql de3c28a2677ed71ebd95207aa43ce270765f7f556283f095f1f6296622b80cbc 414ebbb2bfbe4350f933fc3d3636b49a6bb8242e200180780caf95ab8523adb0 test/extractor-tests/generated/BlockExpr/BlockExpr_getStmtList.ql 8c391dfeb69bd92c547a2417bf231cc960a8f34845802722214294728772316a f3e847fa594e9d9cf25d09a0396a10176aad1100c1977a24756ff6287a79e69e @@ -698,7 +704,7 @@ test/extractor-tests/generated/FnPtrType/FnPtrType.ql 50b76d678582cd0b8d7cc4a765 test/extractor-tests/generated/FnPtrType/FnPtrType_getAbi.ql de1706382c2980c02dbdd295e0a2320c992afa3f19af0c2378b9980a7cd0c481 a3fa36711949d9d5ac53cc5dd39cb19b397c3f2e47c1d457df470c6e5142f9be test/extractor-tests/generated/FnPtrType/FnPtrType_getParamList.ql 9ea393acf37919e2fd1bbc16e738440e00a56552bf80baef9bfd2a9a405afb93 3b4237b22eea569cef0081eb3ea16b2d0f01f8f070f21e16390267e9cbe0cf57 test/extractor-tests/generated/FnPtrType/FnPtrType_getRetType.ql 57f662e4778e1bf4103f061bb8085def0708528f94045c9ff4a95ce802fff13d 924b924c7d766458e956afa0963e6eb1bfc083e5f9aeae64cf2d08929f79612c -test/extractor-tests/generated/ForExpr/ForExpr.ql eff335a301b9a71292bb6da0dffdf901c7a51df9960e9250f9eb980aaaa0c7ae ce7ab100c21c6fc334a4445b2ee311ae6c67992ef659ca32c94d60ac884936e3 +test/extractor-tests/generated/ForExpr/ForExpr.ql 1f8b7a9bbe7a8c077864be64dc51d91ec267c4f34f1cad80fc79902cc0af04ff ae999fb206b04ed81fa08bdd7617cbfe932c5e4109285e10108613cdebba8f7a test/extractor-tests/generated/ForExpr/ForExpr_getAttr.ql d3399b7453e10ff48efc79ec38dd9b6e06bb472b9c39f559242d003e7f63b1d9 ba37e6bf129e1c2f9094e093bbfbf41864f2cb7725a64334f9443270dafdbfdc test/extractor-tests/generated/ForExpr/ForExpr_getIterable.ql 90a6540f8a91cfe3ed1bdde1e680786ce5a00edbb797a8fe70bcc0507c438fcc 65c67ad5890aa502628ee73efd26bcbd4597a8bdfc9839233ede9e26393638f8 test/extractor-tests/generated/ForExpr/ForExpr_getLabel.ql ce90da75e040f448d524187357f3ceededba72407a84c1dc8e1498ed9788044d 0e23d43e0b3412fe90c6a5a4331f8da85eebe19e05b8c7d9710056857280797b @@ -786,7 +792,7 @@ test/extractor-tests/generated/LiteralExpr/LiteralExpr_getAttr.ql 6e76da2bb7858f test/extractor-tests/generated/LiteralExpr/LiteralExpr_getTextValue.ql 7049fec0bbbf0e048af1ff318f42f43d0f8a7354a5638dc21174c4ea725b54ce 2edc94cc0a7f58ec9808b63ddb4d20a3907c88e50bd9ffb14f0281b433f5621b test/extractor-tests/generated/LiteralPat/LiteralPat.ql 3d3db6cad0eb13f84b69efa24a9f9a32d35c62582274d2751cc3ac54dca3b538 7feb64af87546ea64c139c61ac20176a99ad40b9949b361742a424b164fe6d54 test/extractor-tests/generated/LiteralPat/LiteralPat_getLiteral.ql 2cb03a22220e99237d4f3cd94d5090757cd6e57df708d32e80bca3964507651f 4dd9a6c1e23ad9851d9aa8c42c79535f7a2c7224bbaaff286eac7fd04b39c6f0 -test/extractor-tests/generated/LoopExpr/LoopExpr.ql 636c28bff5f8c1ca0fb834f614b3215e02bdb00826fd8be26f9c4fa22c68a79a 1694c27850419d4edf366fe3f1d60fff578094adc3aeeb9691a3d6a8ec0100e1 +test/extractor-tests/generated/LoopExpr/LoopExpr.ql 37b320acefa3734331f87414de270c98ab3309fe069d428550738197e3498a8c e744c25640b5c46aab53ce5114b789e13319572b0c99d0f2bc3c177849e61541 test/extractor-tests/generated/LoopExpr/LoopExpr_getAttr.ql d557c1a34ae8762b32702d6b50e79c25bc506275c33a896b6b94bbbe73d04c49 34846c9eefa0219f4a16e28b518b2afa23f372d0aa03b08d042c5a35375e0cd6 test/extractor-tests/generated/LoopExpr/LoopExpr_getLabel.ql 0b77b9d9fb5903d37bce5a2c0d6b276e6269da56fcb37b83cd931872fb88490f c7f09c526e59dcadec13ec9719980d68b8619d630caab2c26b8368b06c1f2cc0 test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.ql 0267f54077640f3dfeb38524577e4a1229115eeb1c839398d0c5f460c1d65129 96ec876635b8c561f7add19e57574444f630eae3df9ab9bc33ac180e61f3a7b8 @@ -1100,7 +1106,7 @@ test/extractor-tests/generated/WherePred/WherePred_getGenericParamList.ql 21c3aa test/extractor-tests/generated/WherePred/WherePred_getLifetime.ql e08d9d6cccf634746f42a6ee583bbb3e7e9a9edbb63242e73b2bff4463df55d8 139543750c18f88d9c1ad2cdbcf1699d597cf2264bbb6b02a7e5792444e277ef test/extractor-tests/generated/WherePred/WherePred_getTy.ql 34cee0335bbaf8946fe15e3c32449150d07a730fcca56b4faed554fbb8689e21 883976c8c27c276c402d591ebd89d076c2c4d8da4d4f738f3c860c34d4a03b97 test/extractor-tests/generated/WherePred/WherePred_getTypeBoundList.ql c78e31ff4d1822a6b76f403e5ccb8f5529b4f784e14e618833df0378adca55fc 8bb1c9b5a1cfca0f5e8335464f7439aa098063176fbd3edbaf3407169f1899e6 -test/extractor-tests/generated/WhileExpr/WhileExpr.ql e061fac7584adf999d31ed0785041e2cc14b26a1c9901281f90c859335d8f614 fb1e597e28841e3b2d275d697aa6de7158db51b70a348d634291a75b25e4e80a +test/extractor-tests/generated/WhileExpr/WhileExpr.ql 61c49414f2ed786a68b79bd9a77093e4086457edb6c136cf8a94f2ac830c2f5b 7737f724a297d011c12143e009a63926812c63c08a1067b03e8677697ab00f83 test/extractor-tests/generated/WhileExpr/WhileExpr_getAttr.ql f8527130eb2492743c0e629c97db291abcefe3d35302c840fee327ab0d8f10fd b41bedd429e5566fd68a50140ff1f50b51e2c7c351cbc8253fbc126527073f7e test/extractor-tests/generated/WhileExpr/WhileExpr_getCondition.ql 84a021806423425b24eaeb9fb9967a6aadabe823c24e77a0dfefcb3509041597 147aa8bbe4dbf9b90be2467db8207dc96aed281e722eb6b9c998442a90911a6c test/extractor-tests/generated/WhileExpr/WhileExpr_getLabel.ql 60ef4de57d85c7df23c0518b944b3839a9b2478044326829b5bf709a8c8d7240 3916e9ff50733c58afdc09837339b72a555a043f92f1c4e09e1652866029b017 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 7411c9cba35..91644fc94af 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -61,6 +61,7 @@ /lib/codeql/rust/elements/Item.qll linguist-generated /lib/codeql/rust/elements/ItemList.qll linguist-generated /lib/codeql/rust/elements/Label.qll linguist-generated +/lib/codeql/rust/elements/LabelableExpr.qll linguist-generated /lib/codeql/rust/elements/LetElse.qll linguist-generated /lib/codeql/rust/elements/LetExpr.qll linguist-generated /lib/codeql/rust/elements/LetStmt.qll linguist-generated @@ -71,6 +72,7 @@ /lib/codeql/rust/elements/LiteralPat.qll linguist-generated /lib/codeql/rust/elements/Locatable.qll linguist-generated /lib/codeql/rust/elements/LoopExpr.qll linguist-generated +/lib/codeql/rust/elements/LoopingExpr.qll linguist-generated /lib/codeql/rust/elements/MacroCall.qll linguist-generated /lib/codeql/rust/elements/MacroDef.qll linguist-generated /lib/codeql/rust/elements/MacroExpr.qll linguist-generated @@ -186,6 +188,7 @@ /lib/codeql/rust/elements/internal/BecomeExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/BinaryExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/BlockExprConstructor.qll linguist-generated +/lib/codeql/rust/elements/internal/BlockExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/BoxPatConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/BreakExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/CallExprBaseImpl.qll linguist-generated @@ -258,6 +261,7 @@ /lib/codeql/rust/elements/internal/LiteralExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/LiteralPatConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/LoopExprConstructor.qll linguist-generated +/lib/codeql/rust/elements/internal/LoopingExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/MacroCallConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/MacroDefConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/MacroDefImpl.qll linguist-generated @@ -470,6 +474,7 @@ /lib/codeql/rust/elements/internal/generated/Item.qll linguist-generated /lib/codeql/rust/elements/internal/generated/ItemList.qll linguist-generated /lib/codeql/rust/elements/internal/generated/Label.qll linguist-generated +/lib/codeql/rust/elements/internal/generated/LabelableExpr.qll linguist-generated /lib/codeql/rust/elements/internal/generated/LetElse.qll linguist-generated /lib/codeql/rust/elements/internal/generated/LetExpr.qll linguist-generated /lib/codeql/rust/elements/internal/generated/LetStmt.qll linguist-generated @@ -480,6 +485,7 @@ /lib/codeql/rust/elements/internal/generated/LiteralPat.qll linguist-generated /lib/codeql/rust/elements/internal/generated/Locatable.qll linguist-generated /lib/codeql/rust/elements/internal/generated/LoopExpr.qll linguist-generated +/lib/codeql/rust/elements/internal/generated/LoopingExpr.qll linguist-generated /lib/codeql/rust/elements/internal/generated/MacroCall.qll linguist-generated /lib/codeql/rust/elements/internal/generated/MacroDef.qll linguist-generated /lib/codeql/rust/elements/internal/generated/MacroExpr.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/elements.qll b/rust/ql/lib/codeql/rust/elements.qll index b516d8a9d18..6bb59b42882 100644 --- a/rust/ql/lib/codeql/rust/elements.qll +++ b/rust/ql/lib/codeql/rust/elements.qll @@ -64,6 +64,7 @@ import codeql.rust.elements.InferType import codeql.rust.elements.Item import codeql.rust.elements.ItemList import codeql.rust.elements.Label +import codeql.rust.elements.LabelableExpr import codeql.rust.elements.LetElse import codeql.rust.elements.LetExpr import codeql.rust.elements.LetStmt @@ -74,6 +75,7 @@ import codeql.rust.elements.LiteralExpr import codeql.rust.elements.LiteralPat import codeql.rust.elements.Locatable import codeql.rust.elements.LoopExpr +import codeql.rust.elements.LoopingExpr import codeql.rust.elements.MacroCall import codeql.rust.elements.MacroDef import codeql.rust.elements.MacroExpr diff --git a/rust/ql/lib/codeql/rust/elements/BlockExpr.qll b/rust/ql/lib/codeql/rust/elements/BlockExpr.qll index a87bbe47252..9e87d381525 100644 --- a/rust/ql/lib/codeql/rust/elements/BlockExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/BlockExpr.qll @@ -5,8 +5,7 @@ private import internal.BlockExprImpl import codeql.rust.elements.Attr -import codeql.rust.elements.Expr -import codeql.rust.elements.Label +import codeql.rust.elements.LabelableExpr import codeql.rust.elements.StmtList /** diff --git a/rust/ql/lib/codeql/rust/elements/ForExpr.qll b/rust/ql/lib/codeql/rust/elements/ForExpr.qll index c4ef6f9faff..cfb2586202e 100644 --- a/rust/ql/lib/codeql/rust/elements/ForExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/ForExpr.qll @@ -5,9 +5,8 @@ private import internal.ForExprImpl import codeql.rust.elements.Attr -import codeql.rust.elements.BlockExpr import codeql.rust.elements.Expr -import codeql.rust.elements.Label +import codeql.rust.elements.LoopingExpr import codeql.rust.elements.Pat /** diff --git a/rust/ql/lib/codeql/rust/elements/LabelableExpr.qll b/rust/ql/lib/codeql/rust/elements/LabelableExpr.qll new file mode 100644 index 00000000000..c2a042595a1 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/LabelableExpr.qll @@ -0,0 +1,13 @@ +// generated by codegen, do not edit +/** + * This module provides the public class `LabelableExpr`. + */ + +private import internal.LabelableExprImpl +import codeql.rust.elements.Expr +import codeql.rust.elements.Label + +/** + * The base class for expressions that can be labeled (`LoopExpr`, `ForExpr`, `WhileExpr` or `BlockExpr`). + */ +final class LabelableExpr = Impl::LabelableExpr; diff --git a/rust/ql/lib/codeql/rust/elements/LoopExpr.qll b/rust/ql/lib/codeql/rust/elements/LoopExpr.qll index 6abc449c626..cdb6d743b50 100644 --- a/rust/ql/lib/codeql/rust/elements/LoopExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/LoopExpr.qll @@ -5,9 +5,7 @@ private import internal.LoopExprImpl import codeql.rust.elements.Attr -import codeql.rust.elements.BlockExpr -import codeql.rust.elements.Expr -import codeql.rust.elements.Label +import codeql.rust.elements.LoopingExpr /** * A loop expression. For example: diff --git a/rust/ql/lib/codeql/rust/elements/LoopingExpr.qll b/rust/ql/lib/codeql/rust/elements/LoopingExpr.qll new file mode 100644 index 00000000000..6078afdf762 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/LoopingExpr.qll @@ -0,0 +1,13 @@ +// generated by codegen, do not edit +/** + * This module provides the public class `LoopingExpr`. + */ + +private import internal.LoopingExprImpl +import codeql.rust.elements.BlockExpr +import codeql.rust.elements.LabelableExpr + +/** + * The base class for expressions that loop (`LoopExpr`, `ForExpr` or `WhileExpr`). + */ +final class LoopingExpr = Impl::LoopingExpr; diff --git a/rust/ql/lib/codeql/rust/elements/WhileExpr.qll b/rust/ql/lib/codeql/rust/elements/WhileExpr.qll index 9dcbe9c6346..fc704d35095 100644 --- a/rust/ql/lib/codeql/rust/elements/WhileExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/WhileExpr.qll @@ -5,9 +5,8 @@ private import internal.WhileExprImpl import codeql.rust.elements.Attr -import codeql.rust.elements.BlockExpr import codeql.rust.elements.Expr -import codeql.rust.elements.Label +import codeql.rust.elements.LoopingExpr /** * A WhileExpr. For example: diff --git a/rust/ql/lib/codeql/rust/elements/internal/AwaitExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/AwaitExprImpl.qll index 17abcfdaaba..d9aa0f8bf44 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/AwaitExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/AwaitExprImpl.qll @@ -22,6 +22,6 @@ module Impl { * ``` */ class AwaitExpr extends Generated::AwaitExpr { - override string toString() { result = "await ..." } + override string toString() { result = "await " + this.getExpr().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/BecomeExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/BecomeExprImpl.qll index 806e1d7506d..ded01ec4ef8 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/BecomeExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/BecomeExprImpl.qll @@ -25,6 +25,6 @@ module Impl { * ``` */ class BecomeExpr extends Generated::BecomeExpr { - override string toString() { result = "become ..." } + override string toString() { result = "become " + this.getExpr().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/BlockExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/BlockExprImpl.qll index bdfc8a56d7d..9011109b194 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/BlockExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/BlockExprImpl.qll @@ -1,3 +1,4 @@ +// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `BlockExpr`. * @@ -11,7 +12,6 @@ private import codeql.rust.elements.internal.generated.BlockExpr * be referenced directly. */ module Impl { - // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A block expression. For example: * ```rust @@ -26,7 +26,5 @@ module Impl { * } * ``` */ - class BlockExpr extends Generated::BlockExpr { - override string toString() { result = "{ ... }" } - } + class BlockExpr extends Generated::BlockExpr { } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/BoxPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/BoxPatImpl.qll index 5c6ffe229eb..45870d14297 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/BoxPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/BoxPatImpl.qll @@ -22,6 +22,6 @@ module Impl { * ``` */ class BoxPat extends Generated::BoxPat { - override string toString() { result = "box ..." } + override string toString() { result = "box " + this.getPat().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll index 6cfba697828..9104a07a547 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll @@ -5,6 +5,7 @@ */ private import codeql.rust.elements.internal.generated.BreakExpr +import codeql.rust.elements.LabelableExpr /** * INTERNAL: This module contains the customizable definition of `BreakExpr` and should not @@ -103,16 +104,14 @@ module Impl { ) } - override string toString() { - exists(string label, string expr | - ( - label = " " + this.getLifetime().toString() - or - not this.hasLifetime() and label = "" - ) and - (if this.hasExpr() then expr = " ..." else expr = "") and - result = "break" + label + expr - ) + override string toString() { result = concat(int i | | this.toStringPart(i), " " order by i) } + + private string toStringPart(int index) { + index = 0 and result = "break" + or + index = 1 and result = this.getLifetime().toString() + or + index = 2 and result = this.getExpr().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll index 4cf0272c008..3da29db7df1 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll @@ -23,15 +23,6 @@ module Impl { * ``` */ class CallExpr extends Generated::CallExpr { - override string toString() { - exists(string callee | - ( - callee = this.getExpr().(PathExpr).toString() - or - not this.getExpr() instanceof PathExpr and callee = "..." - ) and - result = callee + "(...)" - ) - } + override string toString() { result = this.getExpr().toAbbreviatedString() + "(...)" } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/CastExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CastExprImpl.qll index 3d021e4955d..59cc960a67b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CastExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CastExprImpl.qll @@ -19,6 +19,8 @@ module Impl { * ``` */ class CastExpr extends Generated::CastExpr { - override string toString() { result = "... as " + this.getTy().toString() } + override string toString() { + result = this.getExpr().toAbbreviatedString() + " as " + this.getTy().toString() + } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ClosureExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ClosureExprImpl.qll index 861a258ec8e..17e373290b5 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ClosureExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ClosureExprImpl.qll @@ -25,6 +25,6 @@ module Impl { * ``` */ class ClosureExpr extends Generated::ClosureExpr { - override string toString() { result = "|...| ..." } + override string toString() { result = "|...| " + this.getBody().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll index 8c67382498c..957574d409a 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll @@ -49,15 +49,12 @@ module Impl { * ``` */ class ContinueExpr extends Generated::ContinueExpr { - override string toString() { - exists(string label | - ( - label = " " + this.getLifetime().getText() - or - not this.hasLifetime() and label = "" - ) and - result = "continue" + label - ) + override string toString() { result = concat(int i | | this.toStringPart(i), " " order by i) } + + private string toStringPart(int index) { + index = 0 and result = "continue" + or + index = 1 and result = this.getLifetime().toString() } /** @@ -66,7 +63,7 @@ module Impl { * The target is either a `LoopExpr`, a `ForExpr`, or a `WhileExpr`. */ pragma[nomagic] - Expr getTarget() { + LoopingExpr getTarget() { exists(string label | result = getAContinueAncestor(this, label) and BreakExprImpl::isLabelledLoop(result, label) diff --git a/rust/ql/lib/codeql/rust/elements/internal/ElementImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ElementImpl.qll index 6f342c00fd3..9307a567b6e 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ElementImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ElementImpl.qll @@ -14,6 +14,14 @@ module Impl { class Element extends Generated::Element { override string toString() { result = this.getAPrimaryQlClass() } + /** + * Returns a string suitable to be inserted into the name of the parent. Typically `"..."`, + * but may be overridden by subclasses. + * + * INTERNAL: Do not use. + */ + string toAbbreviatedString() { result = "..." } + predicate isUnknown() { none() } // compatibility with test generation, to be fixed } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/FieldExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/FieldExprImpl.qll index ccfcc4fd7b7..922de73c65d 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/FieldExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/FieldExprImpl.qll @@ -19,6 +19,12 @@ module Impl { * ``` */ class FieldExpr extends Generated::FieldExpr { - override string toString() { result = "... ." + this.getNameRef().toString() } + override string toString() { + exists(string abbr, string name | + abbr = this.getExpr().toAbbreviatedString() and + name = this.getNameRef().toString() and + if abbr = "..." then result = "... ." + name else result = abbr + "." + name + ) + } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ForExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ForExprImpl.qll index da62b58732b..b333702c941 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ForExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ForExprImpl.qll @@ -19,6 +19,8 @@ module Impl { * ``` */ class ForExpr extends Generated::ForExpr { - override string toString() { result = "for " + this.getPat().toString() + " in ... { ... }" } + override string toStringPrefix() { + result = "for " + this.getPat().toAbbreviatedString() + " in ..." + } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/IfExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/IfExprImpl.qll index 59c0638c42e..c90ee6ccdc0 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/IfExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/IfExprImpl.qll @@ -28,11 +28,16 @@ module Impl { * ``` */ class IfExpr extends Generated::IfExpr { - override string toString() { - exists(string elseString | - (if this.hasElse() then elseString = " else { ... }" else elseString = "") and - result = "if ... { ... }" + elseString - ) + override string toString() { result = concat(int i | | this.toStringPart(i), " " order by i) } + + private string toStringPart(int index) { + index = 0 and result = "if" + or + index = 1 and result = this.getCondition().toAbbreviatedString() + or + index = 2 and result = "{...}" + or + index = 3 and this.hasElse() and result = "else {...}" } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll index 28db84aa873..2ace04fe389 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll @@ -20,6 +20,9 @@ module Impl { * ``` */ class IndexExpr extends Generated::IndexExpr { - override string toString() { result = "...[...]" } + override string toString() { + result = + this.getBase().toAbbreviatedString() + "[" + this.getIndex().toAbbreviatedString() + "]" + } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LabelableExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LabelableExprImpl.qll new file mode 100644 index 00000000000..1b354658a2e --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/LabelableExprImpl.qll @@ -0,0 +1,30 @@ +/** + * This module provides a hand-modifiable wrapper around the generated class `LabelableExpr`. + * + * INTERNAL: Do not use. + */ + +private import codeql.rust.elements.internal.generated.LabelableExpr + +/** + * INTERNAL: This module contains the customizable definition of `LabelableExpr` and should not + * be referenced directly. + */ +module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file + /** + * The base class for expressions that can be labeled (`LoopExpr`, `ForExpr`, `WhileExpr` or `BlockExpr`). + */ + class LabelableExpr extends Generated::LabelableExpr { + override string toString() { + result = concat([this.getLabel().toString() + ":", this.toStringPrefix(), "{ ... }"], " ") + } + + /** + * Get the prefix for the string representation of this element. + * + * INTERNAL: Do not use. + */ + string toStringPrefix() { none() } + } +} diff --git a/rust/ql/lib/codeql/rust/elements/internal/LetExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LetExprImpl.qll index 8a54a005cf5..5b8bd7ec963 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LetExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LetExprImpl.qll @@ -21,11 +21,14 @@ module Impl { * ``` */ class LetExpr extends Generated::LetExpr { - override string toString() { - exists(string expr | - (if this.hasExpr() then expr = " = ..." else expr = "") and - result = "let " + this.getPat().toString() + expr - ) + override string toString() { result = concat(int i | | this.toStringPart(i), " " order by i) } + + private string toStringPart(int index) { + index = 0 and result = "let" + or + index = 1 and result = this.getPat().toAbbreviatedString() + or + index = 2 and result = "= " + this.getExpr().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LetStmtImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LetStmtImpl.qll index fce6aa3de44..1205836c230 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LetStmtImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LetStmtImpl.qll @@ -26,12 +26,16 @@ module Impl { * ``` */ class LetStmt extends Generated::LetStmt { - override string toString() { - exists(string expr, string elseStr | - (if this.hasInitializer() then expr = " = ..." else expr = "") and - (if this.hasLetElse() then elseStr = " else { ... }" else elseStr = "") and - result = "let " + this.getPat().toString() + expr + elseStr - ) + override string toString() { result = concat(int i | | this.toStringPart(i), " " order by i) } + + private string toStringPart(int index) { + index = 0 and result = "let" + or + index = 1 and result = this.getPat().toAbbreviatedString() + or + index = 2 and result = "= " + this.getInitializer().toAbbreviatedString() + or + index = 3 and result = this.getLetElse().toString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LiteralExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LiteralExprImpl.qll index 1b660b134c4..efcc4bf073e 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LiteralExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LiteralExprImpl.qll @@ -27,5 +27,7 @@ module Impl { */ class LiteralExpr extends Generated::LiteralExpr { override string toString() { result = this.getTextValue() } + + override string toAbbreviatedString() { result = this.getTextValue() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LiteralPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LiteralPatImpl.qll index 5bf0c13576a..65074603796 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LiteralPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LiteralPatImpl.qll @@ -22,6 +22,8 @@ module Impl { * ``` */ class LiteralPat extends Generated::LiteralPat { - override string toString() { result = this.getLiteral().toString() } + override string toString() { result = this.toAbbreviatedString() } + + override string toAbbreviatedString() { result = this.getLiteral().toString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LoopExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LoopExprImpl.qll index f91a14489c5..73214871705 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LoopExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LoopExprImpl.qll @@ -37,6 +37,6 @@ module Impl { * ``` */ class LoopExpr extends Generated::LoopExpr { - override string toString() { result = "loop {...}" } + override string toStringPrefix() { result = "loop" } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LoopingExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LoopingExprImpl.qll new file mode 100644 index 00000000000..45aa8f42e74 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/LoopingExprImpl.qll @@ -0,0 +1,19 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module provides a hand-modifiable wrapper around the generated class `LoopingExpr`. + * + * INTERNAL: Do not use. + */ + +private import codeql.rust.elements.internal.generated.LoopingExpr + +/** + * INTERNAL: This module contains the customizable definition of `LoopingExpr` and should not + * be referenced directly. + */ +module Impl { + /** + * The base class for expressions that loop (`LoopExpr`, `ForExpr` or `WhileExpr`). + */ + class LoopingExpr extends Generated::LoopingExpr { } +} diff --git a/rust/ql/lib/codeql/rust/elements/internal/MatchArmImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/MatchArmImpl.qll index 280eb4ea7c8..23ad2551bff 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/MatchArmImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/MatchArmImpl.qll @@ -28,11 +28,16 @@ module Impl { * ``` */ class MatchArm extends Generated::MatchArm { - override string toString() { - exists(string guard | - (if this.hasGuard() then guard = "if ... " else guard = "") and - result = this.getPat().toString() + guard + " => ..." - ) + override string toString() { result = concat(int i | | this.toStringPart(i), " " order by i) } + + private string toStringPart(int index) { + index = 0 and result = this.getPat().toAbbreviatedString() + or + index = 1 and result = "if " + this.getGuard().toAbbreviatedString() + or + index = 2 and result = "=>" + or + index = 3 and result = this.getExpr().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll index 530e9cc50a7..3ce9aa77310 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll @@ -28,7 +28,9 @@ module Impl { * ``` */ class MatchExpr extends Generated::MatchExpr { - override string toString() { result = "match ... { ... }" } + override string toString() { + result = "match " + this.getExpr().toAbbreviatedString() + " { ... }" + } /** * Gets the `index`th arm of this match expression. diff --git a/rust/ql/lib/codeql/rust/elements/internal/NeverTypeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/NeverTypeImpl.qll index 985ec81cdeb..c1858fc9421 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/NeverTypeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/NeverTypeImpl.qll @@ -19,6 +19,8 @@ module Impl { * ``` */ class NeverType extends Generated::NeverType { - override string toString() { result = "!" } + override string toString() { result = this.toAbbreviatedString() } + + override string toAbbreviatedString() { result = "!" } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/OrPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/OrPatImpl.qll index ffc3fb3d5b8..20ee0f68852 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/OrPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/OrPatImpl.qll @@ -21,7 +21,9 @@ module Impl { * ``` */ class OrPat extends Generated::OrPat { - override string toString() { result = "... | ..." } + override string toString() { + result = concat(int i | | this.getPat(i).toAbbreviatedString() order by i, " | ") + } /** Gets the last pattern in this or pattern. */ pragma[nomagic] diff --git a/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll index 5f135cc94ca..33e4f5fee59 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll @@ -19,15 +19,12 @@ module Impl { * ``` */ class Param extends Generated::Param { - override string toString() { - exists(string ty | - ( - ty = ": " + this.getTy().toString() - or - not this.hasTy() and ty = "" - ) and - result = this.getPat().toString() + ty - ) + override string toString() { result = concat(int i | | this.toStringPart(i) order by i) } + + private string toStringPart(int index) { + index = 0 and result = this.getPat().toAbbreviatedString() + or + index = 1 and result = ": " + this.getTy().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ParenExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ParenExprImpl.qll index 5dce4634340..db9d19f5650 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ParenExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ParenExprImpl.qll @@ -19,6 +19,6 @@ module Impl { * ``` */ class ParenExpr extends Generated::ParenExpr { - override string toString() { result = "(...)" } + override string toString() { result = "(" + this.getExpr().toAbbreviatedString() + ")" } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ParenPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ParenPatImpl.qll index 5eb8a486030..9d9016cff98 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ParenPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ParenPatImpl.qll @@ -19,6 +19,6 @@ module Impl { * ``` */ class ParenPat extends Generated::ParenPat { - override string toString() { result = "(...)" } + override string toString() { result = "(" + this.getPat().toAbbreviatedString() + ")" } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ParenTypeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ParenTypeImpl.qll index 95c022d651a..916758b9133 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ParenTypeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ParenTypeImpl.qll @@ -19,6 +19,6 @@ module Impl { * ``` */ class ParenType extends Generated::ParenType { - override string toString() { result = "(...)" } + override string toString() { result = "(" + this.getTy().toAbbreviatedString() + ")" } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/PathExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/PathExprImpl.qll index c8a2af3de33..19445493c88 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/PathExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/PathExprImpl.qll @@ -22,6 +22,8 @@ module Impl { * ``` */ class PathExpr extends Generated::PathExpr { - override string toString() { result = this.getPath().toString() } + override string toString() { result = this.toAbbreviatedString() } + + override string toAbbreviatedString() { result = this.getPath().toString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/PathImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/PathImpl.qll index b53c86559f0..8d0a2ab0ecf 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/PathImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/PathImpl.qll @@ -19,10 +19,14 @@ module Impl { * ``` */ class Path extends Generated::Path { - override string toString() { + override string toString() { result = this.toAbbreviatedString() } + + override string toAbbreviatedString() { if this.hasQualifier() - then result = this.getQualifier().toString() + "::" + this.getPart().toString() - else result = this.getPart().toString() + then + result = + this.getQualifier().toAbbreviatedString() + "::" + this.getPart().toAbbreviatedString() + else result = this.getPart().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/PathPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/PathPatImpl.qll index 2c6d94cbcce..a78d0dd7ab9 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/PathPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/PathPatImpl.qll @@ -22,6 +22,8 @@ module Impl { * ``` */ class PathPat extends Generated::PathPat { - override string toString() { result = this.getPath().toString() } + override string toString() { result = this.toAbbreviatedString() } + + override string toAbbreviatedString() { result = this.getPath().toString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/PathSegmentImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/PathSegmentImpl.qll index 300a6c7d4a0..90d7cee6639 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/PathSegmentImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/PathSegmentImpl.qll @@ -19,7 +19,9 @@ module Impl { * ``` */ class PathSegment extends Generated::PathSegment { - override string toString() { + override string toString() { result = this.toAbbreviatedString() } + + override string toAbbreviatedString() { // TODO: this does not cover everything if this.hasGenericArgList() then result = this.getNameRef().toString() + "::<...>" diff --git a/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll index 9c2f4e50052..3f88c50fa6a 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll @@ -19,6 +19,8 @@ module Impl { * ``` */ class PathType extends Generated::PathType { - override string toString() { result = this.getPath().toString() } + override string toString() { result = this.toAbbreviatedString() } + + override string toAbbreviatedString() { result = this.getPath().toString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/RangeExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RangeExprImpl.qll index 53dccb24fbd..3b8989af782 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RangeExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RangeExprImpl.qll @@ -24,6 +24,28 @@ module Impl { * ``` */ class RangeExpr extends Generated::RangeExpr { - override string toString() { result = "... " + this.getOperatorName().toString() + " ..." } + override string toString() { result = concat(int i | | this.toStringPart(i) order by i) } + + private string toStringPart(int index) { + index = 0 and result = this.getStartAbbreviation() + or + index = 1 and result = this.getOperatorName() + or + index = 2 and result = this.getEndAbbreviation() + } + + private string getStartAbbreviation() { + exists(string abbr | + abbr = this.getStart().toAbbreviatedString() and + if abbr = "..." then result = "... " else result = abbr + ) + } + + private string getEndAbbreviation() { + exists(string abbr | + abbr = this.getEnd().toAbbreviatedString() and + if abbr = "..." then result = " ..." else result = abbr + ) + } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/RecordExprFieldImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RecordExprFieldImpl.qll index f5462ab29c3..6e24c31d552 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RecordExprFieldImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RecordExprFieldImpl.qll @@ -19,11 +19,12 @@ module Impl { * ``` */ class RecordExprField extends Generated::RecordExprField { - override string toString() { - exists(string init | - (if this.hasExpr() then init = ": ..." else init = "") and - result = this.getNameRef().toString() + init - ) + override string toString() { result = concat(int i | | this.toStringPart(i) order by i) } + + private string toStringPart(int index) { + index = 0 and result = this.getNameRef().toString() + or + index = 1 and result = ": " + this.getExpr().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/RefExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RefExprImpl.qll index cf3ade0ad14..4ec593362d9 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RefExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RefExprImpl.qll @@ -23,12 +23,17 @@ module Impl { */ class RefExpr extends Generated::RefExpr { override string toString() { - exists(string raw, string const, string mut | - (if this.isRaw() then raw = "raw " else raw = "") and - (if this.isConst() then const = "const " else const = "") and - (if this.isMut() then mut = "mut " else mut = "") and - result = "&" + raw + const + mut + "..." - ) + result = "&" + concat(int i | | this.getSpecPart(i), " " order by i) + } + + private string getSpecPart(int index) { + index = 0 and this.isRaw() and result = "raw" + or + index = 1 and this.isConst() and result = "const" + or + index = 2 and this.isMut() and result = "mut" + or + index = 3 and result = this.getExpr().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/RefPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RefPatImpl.qll index a28574c1c07..d6b1f4c2709 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RefPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RefPatImpl.qll @@ -23,10 +23,13 @@ module Impl { */ class RefPat extends Generated::RefPat { override string toString() { - exists(string mut | - (if this.isMut() then mut = "mut " else mut = "") and - result = "&" + mut + "..." - ) + result = "&" + concat(int i | | this.getSpecPart(i), " " order by i) + } + + private string getSpecPart(int index) { + index = 0 and this.isMut() and result = "mut" + or + index = 1 and result = this.getPat().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/RestPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RestPatImpl.qll index a4ae812b72b..ec7d48a4d9d 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RestPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RestPatImpl.qll @@ -19,6 +19,8 @@ module Impl { * ``` */ class RestPat extends Generated::RestPat { - override string toString() { result = ".." } + override string toString() { result = this.toAbbreviatedString() } + + override string toAbbreviatedString() { result = ".." } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ReturnExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ReturnExprImpl.qll index 245f7e873ac..1b632587867 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ReturnExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ReturnExprImpl.qll @@ -26,8 +26,12 @@ module Impl { * ``` */ class ReturnExpr extends Generated::ReturnExpr { - override string toString() { - if this.hasExpr() then result = "return ..." else result = "return" + override string toString() { result = concat(int i | | this.toStringPart(i), " " order by i) } + + private string toStringPart(int index) { + index = 0 and result = "return" + or + index = 1 and result = this.getExpr().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/UnderscoreExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/UnderscoreExprImpl.qll index 26487fbfe4f..620a09e8c3d 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/UnderscoreExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/UnderscoreExprImpl.qll @@ -19,6 +19,8 @@ module Impl { * ``` */ class UnderscoreExpr extends Generated::UnderscoreExpr { - override string toString() { result = "_" } + override string toString() { result = this.toAbbreviatedString() } + + override string toAbbreviatedString() { result = "_" } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/WhileExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/WhileExprImpl.qll index 43f9510be1b..e41b6a684a1 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/WhileExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/WhileExprImpl.qll @@ -19,6 +19,8 @@ module Impl { * ``` */ class WhileExpr extends Generated::WhileExpr { - override string toString() { result = "while ... { ... }" } + override string toStringPrefix() { + result = "while " + this.getCondition().toAbbreviatedString() + } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/WildcardPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/WildcardPatImpl.qll index d7973866d91..f1a8fa1a72e 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/WildcardPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/WildcardPatImpl.qll @@ -19,6 +19,8 @@ module Impl { * ``` */ class WildcardPat extends Generated::WildcardPat { - override string toString() { result = "_" } + override string toString() { result = this.toAbbreviatedString() } + + override string toAbbreviatedString() { result = "_" } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/BlockExpr.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/BlockExpr.qll index c4f11fdd90c..6a01a0c4588 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/BlockExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/BlockExpr.qll @@ -7,8 +7,7 @@ private import codeql.rust.elements.internal.generated.Synth private import codeql.rust.elements.internal.generated.Raw import codeql.rust.elements.Attr -import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl -import codeql.rust.elements.Label +import codeql.rust.elements.internal.LabelableExprImpl::Impl as LabelableExprImpl import codeql.rust.elements.StmtList /** @@ -32,7 +31,7 @@ module Generated { * INTERNAL: Do not reference the `Generated::BlockExpr` class directly. * Use the subclass `BlockExpr`, where the following predicates are available. */ - class BlockExpr extends Synth::TBlockExpr, ExprImpl::Expr { + class BlockExpr extends Synth::TBlockExpr, LabelableExprImpl::LabelableExpr { override string getAPrimaryQlClass() { result = "BlockExpr" } /** @@ -83,19 +82,6 @@ module Generated { */ predicate isUnsafe() { Synth::convertBlockExprToRaw(this).(Raw::BlockExpr).isUnsafe() } - /** - * Gets the label of this block expression, if it exists. - */ - Label getLabel() { - result = - Synth::convertLabelFromRaw(Synth::convertBlockExprToRaw(this).(Raw::BlockExpr).getLabel()) - } - - /** - * Holds if `getLabel()` exists. - */ - final predicate hasLabel() { exists(this.getLabel()) } - /** * Gets the statement list of this block expression, if it exists. */ diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ForExpr.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ForExpr.qll index dc5f2d34d3e..202b1736fc4 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/ForExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ForExpr.qll @@ -7,10 +7,8 @@ private import codeql.rust.elements.internal.generated.Synth private import codeql.rust.elements.internal.generated.Raw import codeql.rust.elements.Attr -import codeql.rust.elements.BlockExpr import codeql.rust.elements.Expr -import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl -import codeql.rust.elements.Label +import codeql.rust.elements.internal.LoopingExprImpl::Impl as LoopingExprImpl import codeql.rust.elements.Pat /** @@ -26,7 +24,7 @@ module Generated { * INTERNAL: Do not reference the `Generated::ForExpr` class directly. * Use the subclass `ForExpr`, where the following predicates are available. */ - class ForExpr extends Synth::TForExpr, ExprImpl::Expr { + class ForExpr extends Synth::TForExpr, LoopingExprImpl::LoopingExpr { override string getAPrimaryQlClass() { result = "ForExpr" } /** @@ -60,32 +58,6 @@ module Generated { */ final predicate hasIterable() { exists(this.getIterable()) } - /** - * Gets the label of this for expression, if it exists. - */ - Label getLabel() { - result = - Synth::convertLabelFromRaw(Synth::convertForExprToRaw(this).(Raw::ForExpr).getLabel()) - } - - /** - * Holds if `getLabel()` exists. - */ - final predicate hasLabel() { exists(this.getLabel()) } - - /** - * Gets the loop body of this for expression, if it exists. - */ - BlockExpr getLoopBody() { - result = - Synth::convertBlockExprFromRaw(Synth::convertForExprToRaw(this).(Raw::ForExpr).getLoopBody()) - } - - /** - * Holds if `getLoopBody()` exists. - */ - final predicate hasLoopBody() { exists(this.getLoopBody()) } - /** * Gets the pat of this for expression, if it exists. */ diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/LabelableExpr.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/LabelableExpr.qll new file mode 100644 index 00000000000..a0dfd03fb40 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/LabelableExpr.qll @@ -0,0 +1,38 @@ +// generated by codegen, do not edit +/** + * This module provides the generated definition of `LabelableExpr`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.elements.internal.generated.Synth +private import codeql.rust.elements.internal.generated.Raw +import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl +import codeql.rust.elements.Label + +/** + * INTERNAL: This module contains the fully generated definition of `LabelableExpr` and should not + * be referenced directly. + */ +module Generated { + /** + * The base class for expressions that can be labeled (`LoopExpr`, `ForExpr`, `WhileExpr` or `BlockExpr`). + * INTERNAL: Do not reference the `Generated::LabelableExpr` class directly. + * Use the subclass `LabelableExpr`, where the following predicates are available. + */ + class LabelableExpr extends Synth::TLabelableExpr, ExprImpl::Expr { + /** + * Gets the label of this labelable expression, if it exists. + */ + Label getLabel() { + result = + Synth::convertLabelFromRaw(Synth::convertLabelableExprToRaw(this) + .(Raw::LabelableExpr) + .getLabel()) + } + + /** + * Holds if `getLabel()` exists. + */ + final predicate hasLabel() { exists(this.getLabel()) } + } +} diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/LoopExpr.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/LoopExpr.qll index eb943bf746a..510c3dedb68 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/LoopExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/LoopExpr.qll @@ -7,9 +7,7 @@ private import codeql.rust.elements.internal.generated.Synth private import codeql.rust.elements.internal.generated.Raw import codeql.rust.elements.Attr -import codeql.rust.elements.BlockExpr -import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl -import codeql.rust.elements.Label +import codeql.rust.elements.internal.LoopingExprImpl::Impl as LoopingExprImpl /** * INTERNAL: This module contains the fully generated definition of `LoopExpr` and should not @@ -42,7 +40,7 @@ module Generated { * INTERNAL: Do not reference the `Generated::LoopExpr` class directly. * Use the subclass `LoopExpr`, where the following predicates are available. */ - class LoopExpr extends Synth::TLoopExpr, ExprImpl::Expr { + class LoopExpr extends Synth::TLoopExpr, LoopingExprImpl::LoopingExpr { override string getAPrimaryQlClass() { result = "LoopExpr" } /** @@ -62,33 +60,5 @@ module Generated { * Gets the number of attrs of this loop expression. */ final int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } - - /** - * Gets the label of this loop expression, if it exists. - */ - Label getLabel() { - result = - Synth::convertLabelFromRaw(Synth::convertLoopExprToRaw(this).(Raw::LoopExpr).getLabel()) - } - - /** - * Holds if `getLabel()` exists. - */ - final predicate hasLabel() { exists(this.getLabel()) } - - /** - * Gets the loop body of this loop expression, if it exists. - */ - BlockExpr getLoopBody() { - result = - Synth::convertBlockExprFromRaw(Synth::convertLoopExprToRaw(this) - .(Raw::LoopExpr) - .getLoopBody()) - } - - /** - * Holds if `getLoopBody()` exists. - */ - final predicate hasLoopBody() { exists(this.getLoopBody()) } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/LoopingExpr.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/LoopingExpr.qll new file mode 100644 index 00000000000..427ef05c2ab --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/LoopingExpr.qll @@ -0,0 +1,38 @@ +// generated by codegen, do not edit +/** + * This module provides the generated definition of `LoopingExpr`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.elements.internal.generated.Synth +private import codeql.rust.elements.internal.generated.Raw +import codeql.rust.elements.BlockExpr +import codeql.rust.elements.internal.LabelableExprImpl::Impl as LabelableExprImpl + +/** + * INTERNAL: This module contains the fully generated definition of `LoopingExpr` and should not + * be referenced directly. + */ +module Generated { + /** + * The base class for expressions that loop (`LoopExpr`, `ForExpr` or `WhileExpr`). + * INTERNAL: Do not reference the `Generated::LoopingExpr` class directly. + * Use the subclass `LoopingExpr`, where the following predicates are available. + */ + class LoopingExpr extends Synth::TLoopingExpr, LabelableExprImpl::LabelableExpr { + /** + * Gets the loop body of this looping expression, if it exists. + */ + BlockExpr getLoopBody() { + result = + Synth::convertBlockExprFromRaw(Synth::convertLoopingExprToRaw(this) + .(Raw::LoopingExpr) + .getLoopBody()) + } + + /** + * Holds if `getLoopBody()` exists. + */ + final predicate hasLoopBody() { exists(this.getLoopBody()) } + } +} diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll index 470207683ae..6f005ee5a94 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll @@ -1397,29 +1397,6 @@ private module Impl { ) } - private Element getImmediateChildOfBlockExpr(BlockExpr e, int index, string partialPredicateCall) { - exists(int b, int bExpr, int n, int nAttr, int nLabel, int nStmtList | - b = 0 and - bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and - n = bExpr and - nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and - nLabel = nAttr + 1 and - nStmtList = nLabel + 1 and - ( - none() - or - result = getImmediateChildOfExpr(e, index - b, partialPredicateCall) - or - result = e.getAttr(index - n) and - partialPredicateCall = "Attr(" + (index - n).toString() + ")" - or - index = nAttr and result = e.getLabel() and partialPredicateCall = "Label()" - or - index = nLabel and result = e.getStmtList() and partialPredicateCall = "StmtList()" - ) - ) - } - private Element getImmediateChildOfBoxPat(BoxPat e, int index, string partialPredicateCall) { exists(int b, int bPat, int n, int nPat | b = 0 and @@ -1708,35 +1685,6 @@ private module Impl { ) } - private Element getImmediateChildOfForExpr(ForExpr e, int index, string partialPredicateCall) { - exists(int b, int bExpr, int n, int nAttr, int nIterable, int nLabel, int nLoopBody, int nPat | - b = 0 and - bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and - n = bExpr and - nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and - nIterable = nAttr + 1 and - nLabel = nIterable + 1 and - nLoopBody = nLabel + 1 and - nPat = nLoopBody + 1 and - ( - none() - or - result = getImmediateChildOfExpr(e, index - b, partialPredicateCall) - or - result = e.getAttr(index - n) and - partialPredicateCall = "Attr(" + (index - n).toString() + ")" - or - index = nAttr and result = e.getIterable() and partialPredicateCall = "Iterable()" - or - index = nIterable and result = e.getLabel() and partialPredicateCall = "Label()" - or - index = nLabel and result = e.getLoopBody() and partialPredicateCall = "LoopBody()" - or - index = nLoopBody and result = e.getPat() and partialPredicateCall = "Pat()" - ) - ) - } - private Element getImmediateChildOfForType(ForType e, int index, string partialPredicateCall) { exists(int b, int bTypeRef, int n, int nGenericParamList, int nTy | b = 0 and @@ -1900,6 +1848,24 @@ private module Impl { ) } + private Element getImmediateChildOfLabelableExpr( + LabelableExpr e, int index, string partialPredicateCall + ) { + exists(int b, int bExpr, int n, int nLabel | + b = 0 and + bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and + n = bExpr and + nLabel = n + 1 and + ( + none() + or + result = getImmediateChildOfExpr(e, index - b, partialPredicateCall) + or + index = n and result = e.getLabel() and partialPredicateCall = "Label()" + ) + ) + } + private Element getImmediateChildOfLetExpr(LetExpr e, int index, string partialPredicateCall) { exists(int b, int bExpr, int n, int nAttr, int nExpr, int nPat | b = 0 and @@ -2034,29 +2000,6 @@ private module Impl { ) } - private Element getImmediateChildOfLoopExpr(LoopExpr e, int index, string partialPredicateCall) { - exists(int b, int bExpr, int n, int nAttr, int nLabel, int nLoopBody | - b = 0 and - bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and - n = bExpr and - nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and - nLabel = nAttr + 1 and - nLoopBody = nLabel + 1 and - ( - none() - or - result = getImmediateChildOfExpr(e, index - b, partialPredicateCall) - or - result = e.getAttr(index - n) and - partialPredicateCall = "Attr(" + (index - n).toString() + ")" - or - index = nAttr and result = e.getLabel() and partialPredicateCall = "Label()" - or - index = nLabel and result = e.getLoopBody() and partialPredicateCall = "LoopBody()" - ) - ) - } - private Element getImmediateChildOfMacroExpr(MacroExpr e, int index, string partialPredicateCall) { exists(int b, int bExpr, int n, int nMacroCall | b = 0 and @@ -2748,32 +2691,6 @@ private module Impl { ) } - private Element getImmediateChildOfWhileExpr(WhileExpr e, int index, string partialPredicateCall) { - exists(int b, int bExpr, int n, int nAttr, int nCondition, int nLabel, int nLoopBody | - b = 0 and - bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and - n = bExpr and - nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and - nCondition = nAttr + 1 and - nLabel = nCondition + 1 and - nLoopBody = nLabel + 1 and - ( - none() - or - result = getImmediateChildOfExpr(e, index - b, partialPredicateCall) - or - result = e.getAttr(index - n) and - partialPredicateCall = "Attr(" + (index - n).toString() + ")" - or - index = nAttr and result = e.getCondition() and partialPredicateCall = "Condition()" - or - index = nCondition and result = e.getLabel() and partialPredicateCall = "Label()" - or - index = nLabel and result = e.getLoopBody() and partialPredicateCall = "LoopBody()" - ) - ) - } - private Element getImmediateChildOfWildcardPat( WildcardPat e, int index, string partialPredicateCall ) { @@ -2829,6 +2746,27 @@ private module Impl { ) } + private Element getImmediateChildOfBlockExpr(BlockExpr e, int index, string partialPredicateCall) { + exists(int b, int bLabelableExpr, int n, int nAttr, int nStmtList | + b = 0 and + bLabelableExpr = + b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLabelableExpr(e, i, _)) | i) and + n = bLabelableExpr and + nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and + nStmtList = nAttr + 1 and + ( + none() + or + result = getImmediateChildOfLabelableExpr(e, index - b, partialPredicateCall) + or + result = e.getAttr(index - n) and + partialPredicateCall = "Attr(" + (index - n).toString() + ")" + or + index = nAttr and result = e.getStmtList() and partialPredicateCall = "StmtList()" + ) + ) + } + private Element getImmediateChildOfCallExpr(CallExpr e, int index, string partialPredicateCall) { exists(int b, int bCallExprBase, int n, int nExpr | b = 0 and @@ -3087,6 +3025,25 @@ private module Impl { ) } + private Element getImmediateChildOfLoopingExpr( + LoopingExpr e, int index, string partialPredicateCall + ) { + exists(int b, int bLabelableExpr, int n, int nLoopBody | + b = 0 and + bLabelableExpr = + b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLabelableExpr(e, i, _)) | i) and + n = bLabelableExpr and + nLoopBody = n + 1 and + ( + none() + or + result = getImmediateChildOfLabelableExpr(e, index - b, partialPredicateCall) + or + index = n and result = e.getLoopBody() and partialPredicateCall = "LoopBody()" + ) + ) + } + private Element getImmediateChildOfMacroCall(MacroCall e, int index, string partialPredicateCall) { exists( int b, int bAssocItem, int bExternItem, int bItem, int n, int nAttr, int nPath, @@ -3535,6 +3492,69 @@ private module Impl { ) } + private Element getImmediateChildOfForExpr(ForExpr e, int index, string partialPredicateCall) { + exists(int b, int bLoopingExpr, int n, int nAttr, int nIterable, int nPat | + b = 0 and + bLoopingExpr = + b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLoopingExpr(e, i, _)) | i) and + n = bLoopingExpr and + nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and + nIterable = nAttr + 1 and + nPat = nIterable + 1 and + ( + none() + or + result = getImmediateChildOfLoopingExpr(e, index - b, partialPredicateCall) + or + result = e.getAttr(index - n) and + partialPredicateCall = "Attr(" + (index - n).toString() + ")" + or + index = nAttr and result = e.getIterable() and partialPredicateCall = "Iterable()" + or + index = nIterable and result = e.getPat() and partialPredicateCall = "Pat()" + ) + ) + } + + private Element getImmediateChildOfLoopExpr(LoopExpr e, int index, string partialPredicateCall) { + exists(int b, int bLoopingExpr, int n, int nAttr | + b = 0 and + bLoopingExpr = + b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLoopingExpr(e, i, _)) | i) and + n = bLoopingExpr and + nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and + ( + none() + or + result = getImmediateChildOfLoopingExpr(e, index - b, partialPredicateCall) + or + result = e.getAttr(index - n) and + partialPredicateCall = "Attr(" + (index - n).toString() + ")" + ) + ) + } + + private Element getImmediateChildOfWhileExpr(WhileExpr e, int index, string partialPredicateCall) { + exists(int b, int bLoopingExpr, int n, int nAttr, int nCondition | + b = 0 and + bLoopingExpr = + b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLoopingExpr(e, i, _)) | i) and + n = bLoopingExpr and + nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and + nCondition = nAttr + 1 and + ( + none() + or + result = getImmediateChildOfLoopingExpr(e, index - b, partialPredicateCall) + or + result = e.getAttr(index - n) and + partialPredicateCall = "Attr(" + (index - n).toString() + ")" + or + index = nAttr and result = e.getCondition() and partialPredicateCall = "Condition()" + ) + ) + } + cached Element getImmediateChild(Element e, int index, string partialAccessor) { // why does this look more complicated than it should? @@ -3655,8 +3675,6 @@ private module Impl { or result = getImmediateChildOfBinaryExpr(e, index, partialAccessor) or - result = getImmediateChildOfBlockExpr(e, index, partialAccessor) - or result = getImmediateChildOfBoxPat(e, index, partialAccessor) or result = getImmediateChildOfBreakExpr(e, index, partialAccessor) @@ -3683,8 +3701,6 @@ private module Impl { or result = getImmediateChildOfFnPtrType(e, index, partialAccessor) or - result = getImmediateChildOfForExpr(e, index, partialAccessor) - or result = getImmediateChildOfForType(e, index, partialAccessor) or result = getImmediateChildOfFormatArgsExpr(e, index, partialAccessor) @@ -3711,8 +3727,6 @@ private module Impl { or result = getImmediateChildOfLiteralPat(e, index, partialAccessor) or - result = getImmediateChildOfLoopExpr(e, index, partialAccessor) - or result = getImmediateChildOfMacroExpr(e, index, partialAccessor) or result = getImmediateChildOfMacroPat(e, index, partialAccessor) @@ -3785,14 +3799,14 @@ private module Impl { or result = getImmediateChildOfUnderscoreExpr(e, index, partialAccessor) or - result = getImmediateChildOfWhileExpr(e, index, partialAccessor) - or result = getImmediateChildOfWildcardPat(e, index, partialAccessor) or result = getImmediateChildOfYeetExpr(e, index, partialAccessor) or result = getImmediateChildOfYieldExpr(e, index, partialAccessor) or + result = getImmediateChildOfBlockExpr(e, index, partialAccessor) + or result = getImmediateChildOfCallExpr(e, index, partialAccessor) or result = getImmediateChildOfConst(e, index, partialAccessor) @@ -3834,6 +3848,12 @@ private module Impl { result = getImmediateChildOfUnion(e, index, partialAccessor) or result = getImmediateChildOfUse(e, index, partialAccessor) + or + result = getImmediateChildOfForExpr(e, index, partialAccessor) + or + result = getImmediateChildOfLoopExpr(e, index, partialAccessor) + or + result = getImmediateChildOfWhileExpr(e, index, partialAccessor) } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index 25af8ddac64..dc9f577bffc 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -1366,70 +1366,6 @@ module Raw { Expr getRhs() { binary_expr_rhs(this, result) } } - /** - * INTERNAL: Do not use. - * A block expression. For example: - * ```rust - * { - * let x = 42; - * } - * ``` - * ```rust - * 'label: { - * let x = 42; - * x - * } - * ``` - */ - class BlockExpr extends @block_expr, Expr { - override string toString() { result = "BlockExpr" } - - /** - * Gets the `index`th attr of this block expression (0-based). - */ - Attr getAttr(int index) { block_expr_attrs(this, index, result) } - - /** - * Holds if this block expression is async. - */ - predicate isAsync() { block_expr_is_async(this) } - - /** - * Holds if this block expression is const. - */ - predicate isConst() { block_expr_is_const(this) } - - /** - * Holds if this block expression is gen. - */ - predicate isGen() { block_expr_is_gen(this) } - - /** - * Holds if this block expression is move. - */ - predicate isMove() { block_expr_is_move(this) } - - /** - * Holds if this block expression is try. - */ - predicate isTry() { block_expr_is_try(this) } - - /** - * Holds if this block expression is unsafe. - */ - predicate isUnsafe() { block_expr_is_unsafe(this) } - - /** - * Gets the label of this block expression, if it exists. - */ - Label getLabel() { block_expr_labels(this, result) } - - /** - * Gets the statement list of this block expression, if it exists. - */ - StmtList getStmtList() { block_expr_stmt_lists(this, result) } - } - /** * INTERNAL: Do not use. * A box pattern. For example: @@ -1824,42 +1760,6 @@ module Raw { RetType getRetType() { fn_ptr_type_ret_types(this, result) } } - /** - * INTERNAL: Do not use. - * A ForExpr. For example: - * ```rust - * todo!() - * ``` - */ - class ForExpr extends @for_expr, Expr { - override string toString() { result = "ForExpr" } - - /** - * Gets the `index`th attr of this for expression (0-based). - */ - Attr getAttr(int index) { for_expr_attrs(this, index, result) } - - /** - * Gets the iterable of this for expression, if it exists. - */ - Expr getIterable() { for_expr_iterables(this, result) } - - /** - * Gets the label of this for expression, if it exists. - */ - Label getLabel() { for_expr_labels(this, result) } - - /** - * Gets the loop body of this for expression, if it exists. - */ - BlockExpr getLoopBody() { for_expr_loop_bodies(this, result) } - - /** - * Gets the pat of this for expression, if it exists. - */ - Pat getPat() { for_expr_pats(this, result) } - } - /** * INTERNAL: Do not use. * A ForType. For example: @@ -2071,6 +1971,17 @@ module Raw { string getCrateOrigin() { item_crate_origins(this, result) } } + /** + * INTERNAL: Do not use. + * The base class for expressions that can be labeled (`LoopExpr`, `ForExpr`, `WhileExpr` or `BlockExpr`). + */ + class LabelableExpr extends @labelable_expr, Expr { + /** + * Gets the label of this labelable expression, if it exists. + */ + Label getLabel() { labelable_expr_labels(this, result) } + } + /** * INTERNAL: Do not use. * A `let` expression. For example: @@ -2231,50 +2142,6 @@ module Raw { LiteralExpr getLiteral() { literal_pat_literals(this, result) } } - /** - * INTERNAL: Do not use. - * A loop expression. For example: - * ```rust - * loop { - * println!("Hello, world (again)!"); - * }; - * ``` - * ```rust - * 'label: loop { - * println!("Hello, world (once)!"); - * break 'label; - * }; - * ``` - * ```rust - * let mut x = 0; - * loop { - * if x < 10 { - * x += 1; - * } else { - * break; - * } - * }; - * ``` - */ - class LoopExpr extends @loop_expr, Expr { - override string toString() { result = "LoopExpr" } - - /** - * Gets the `index`th attr of this loop expression (0-based). - */ - Attr getAttr(int index) { loop_expr_attrs(this, index, result) } - - /** - * Gets the label of this loop expression, if it exists. - */ - Label getLabel() { loop_expr_labels(this, result) } - - /** - * Gets the loop body of this loop expression, if it exists. - */ - BlockExpr getLoopBody() { loop_expr_loop_bodies(this, result) } - } - /** * INTERNAL: Do not use. * A MacroExpr. For example: @@ -3063,37 +2930,6 @@ module Raw { Attr getAttr(int index) { underscore_expr_attrs(this, index, result) } } - /** - * INTERNAL: Do not use. - * A WhileExpr. For example: - * ```rust - * todo!() - * ``` - */ - class WhileExpr extends @while_expr, Expr { - override string toString() { result = "WhileExpr" } - - /** - * Gets the `index`th attr of this while expression (0-based). - */ - Attr getAttr(int index) { while_expr_attrs(this, index, result) } - - /** - * Gets the condition of this while expression, if it exists. - */ - Expr getCondition() { while_expr_conditions(this, result) } - - /** - * Gets the label of this while expression, if it exists. - */ - Label getLabel() { while_expr_labels(this, result) } - - /** - * Gets the loop body of this while expression, if it exists. - */ - BlockExpr getLoopBody() { while_expr_loop_bodies(this, result) } - } - /** * INTERNAL: Do not use. * A wildcard pattern. For example: @@ -3152,6 +2988,65 @@ module Raw { Expr getExpr() { yield_expr_exprs(this, result) } } + /** + * INTERNAL: Do not use. + * A block expression. For example: + * ```rust + * { + * let x = 42; + * } + * ``` + * ```rust + * 'label: { + * let x = 42; + * x + * } + * ``` + */ + class BlockExpr extends @block_expr, LabelableExpr { + override string toString() { result = "BlockExpr" } + + /** + * Gets the `index`th attr of this block expression (0-based). + */ + Attr getAttr(int index) { block_expr_attrs(this, index, result) } + + /** + * Holds if this block expression is async. + */ + predicate isAsync() { block_expr_is_async(this) } + + /** + * Holds if this block expression is const. + */ + predicate isConst() { block_expr_is_const(this) } + + /** + * Holds if this block expression is gen. + */ + predicate isGen() { block_expr_is_gen(this) } + + /** + * Holds if this block expression is move. + */ + predicate isMove() { block_expr_is_move(this) } + + /** + * Holds if this block expression is try. + */ + predicate isTry() { block_expr_is_try(this) } + + /** + * Holds if this block expression is unsafe. + */ + predicate isUnsafe() { block_expr_is_unsafe(this) } + + /** + * Gets the statement list of this block expression, if it exists. + */ + StmtList getStmtList() { block_expr_stmt_lists(this, result) } + } + /** * INTERNAL: Do not use. * A function call expression. For example: @@ -3458,6 +3353,17 @@ module Raw { WhereClause getWhereClause() { impl_where_clauses(this, result) } } + /** + * INTERNAL: Do not use. + * The base class for expressions that loop (`LoopExpr`, `ForExpr` or `WhileExpr`). + */ + class LoopingExpr extends @looping_expr, LabelableExpr { + /** + * Gets the loop body of this looping expression, if it exists. + */ + BlockExpr getLoopBody() { looping_expr_loop_bodies(this, result) } + } + /** * INTERNAL: Do not use. * A MacroCall. For example: @@ -3950,4 +3856,85 @@ module Raw { */ Visibility getVisibility() { use_visibilities(this, result) } } + + /** + * INTERNAL: Do not use. + * A ForExpr. For example: + * ```rust + * todo!() + * ``` + */ + class ForExpr extends @for_expr, LoopingExpr { + override string toString() { result = "ForExpr" } + + /** + * Gets the `index`th attr of this for expression (0-based). + */ + Attr getAttr(int index) { for_expr_attrs(this, index, result) } + + /** + * Gets the iterable of this for expression, if it exists. + */ + Expr getIterable() { for_expr_iterables(this, result) } + + /** + * Gets the pat of this for expression, if it exists. + */ + Pat getPat() { for_expr_pats(this, result) } + } + + /** + * INTERNAL: Do not use. + * A loop expression. For example: + * ```rust + * loop { + * println!("Hello, world (again)!"); + * }; + * ``` + * ```rust + * 'label: loop { + * println!("Hello, world (once)!"); + * break 'label; + * }; + * ``` + * ```rust + * let mut x = 0; + * loop { + * if x < 10 { + * x += 1; + * } else { + * break; + * } + * }; + * ``` + */ + class LoopExpr extends @loop_expr, LoopingExpr { + override string toString() { result = "LoopExpr" } + + /** + * Gets the `index`th attr of this loop expression (0-based). + */ + Attr getAttr(int index) { loop_expr_attrs(this, index, result) } + } + + /** + * INTERNAL: Do not use. + * A WhileExpr. For example: + * ```rust + * todo!() + * ``` + */ + class WhileExpr extends @while_expr, LoopingExpr { + override string toString() { result = "WhileExpr" } + + /** + * Gets the `index`th attr of this while expression (0-based). + */ + Attr getAttr(int index) { while_expr_attrs(this, index, result) } + + /** + * Gets the condition of this while expression, if it exists. + */ + Expr getCondition() { while_expr_conditions(this, result) } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll index 927ba1f238d..dda242ffdf9 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll @@ -645,12 +645,12 @@ module Synth { * INTERNAL: Do not use. */ class TExpr = - TArrayExpr or TAsmExpr or TAwaitExpr or TBecomeExpr or TBinaryExpr or TBlockExpr or - TBreakExpr or TCallExprBase or TCastExpr or TClosureExpr or TContinueExpr or TFieldExpr or - TForExpr or TFormatArgsExpr or TIfExpr or TIndexExpr or TLetExpr or TLiteralExpr or - TLoopExpr or TMacroExpr or TMatchExpr or TOffsetOfExpr or TParenExpr or TPathExprBase or - TPrefixExpr or TRangeExpr or TRecordExpr or TRefExpr or TReturnExpr or TTryExpr or - TTupleExpr or TUnderscoreExpr or TWhileExpr or TYeetExpr or TYieldExpr; + TArrayExpr or TAsmExpr or TAwaitExpr or TBecomeExpr or TBinaryExpr or TBreakExpr or + TCallExprBase or TCastExpr or TClosureExpr or TContinueExpr or TFieldExpr or + TFormatArgsExpr or TIfExpr or TIndexExpr or TLabelableExpr or TLetExpr or TLiteralExpr or + TMacroExpr or TMatchExpr or TOffsetOfExpr or TParenExpr or TPathExprBase or TPrefixExpr or + TRangeExpr or TRecordExpr or TRefExpr or TReturnExpr or TTryExpr or TTupleExpr or + TUnderscoreExpr or TYeetExpr or TYieldExpr; /** * INTERNAL: Do not use. @@ -680,11 +680,21 @@ module Synth { TMacroDef or TMacroRules or TModule or TStatic or TStruct or TTrait or TTraitAlias or TTypeAlias or TUnion or TUse; + /** + * INTERNAL: Do not use. + */ + class TLabelableExpr = TBlockExpr or TLoopingExpr; + /** * INTERNAL: Do not use. */ class TLocatable = TAstNode or TFormat or TFormatArgument; + /** + * INTERNAL: Do not use. + */ + class TLoopingExpr = TForExpr or TLoopExpr or TWhileExpr; + /** * INTERNAL: Do not use. */ @@ -1795,8 +1805,6 @@ module Synth { or result = convertBinaryExprFromRaw(e) or - result = convertBlockExprFromRaw(e) - or result = convertBreakExprFromRaw(e) or result = convertCallExprBaseFromRaw(e) @@ -1809,20 +1817,18 @@ module Synth { or result = convertFieldExprFromRaw(e) or - result = convertForExprFromRaw(e) - or result = convertFormatArgsExprFromRaw(e) or result = convertIfExprFromRaw(e) or result = convertIndexExprFromRaw(e) or + result = convertLabelableExprFromRaw(e) + or result = convertLetExprFromRaw(e) or result = convertLiteralExprFromRaw(e) or - result = convertLoopExprFromRaw(e) - or result = convertMacroExprFromRaw(e) or result = convertMatchExprFromRaw(e) @@ -1849,8 +1855,6 @@ module Synth { or result = convertUnderscoreExprFromRaw(e) or - result = convertWhileExprFromRaw(e) - or result = convertYeetExprFromRaw(e) or result = convertYieldExprFromRaw(e) @@ -1946,6 +1950,16 @@ module Synth { result = convertUseFromRaw(e) } + /** + * INTERNAL: Do not use. + * Converts a raw DB element to a synthesized `TLabelableExpr`, if possible. + */ + TLabelableExpr convertLabelableExprFromRaw(Raw::Element e) { + result = convertBlockExprFromRaw(e) + or + result = convertLoopingExprFromRaw(e) + } + /** * INTERNAL: Do not use. * Converts a raw DB element to a synthesized `TLocatable`, if possible. @@ -1958,6 +1972,18 @@ module Synth { result = convertFormatArgumentFromRaw(e) } + /** + * INTERNAL: Do not use. + * Converts a raw DB element to a synthesized `TLoopingExpr`, if possible. + */ + TLoopingExpr convertLoopingExprFromRaw(Raw::Element e) { + result = convertForExprFromRaw(e) + or + result = convertLoopExprFromRaw(e) + or + result = convertWhileExprFromRaw(e) + } + /** * INTERNAL: Do not use. * Converts a raw DB element to a synthesized `TPat`, if possible. @@ -3145,8 +3171,6 @@ module Synth { or result = convertBinaryExprToRaw(e) or - result = convertBlockExprToRaw(e) - or result = convertBreakExprToRaw(e) or result = convertCallExprBaseToRaw(e) @@ -3159,20 +3183,18 @@ module Synth { or result = convertFieldExprToRaw(e) or - result = convertForExprToRaw(e) - or result = convertFormatArgsExprToRaw(e) or result = convertIfExprToRaw(e) or result = convertIndexExprToRaw(e) or + result = convertLabelableExprToRaw(e) + or result = convertLetExprToRaw(e) or result = convertLiteralExprToRaw(e) or - result = convertLoopExprToRaw(e) - or result = convertMacroExprToRaw(e) or result = convertMatchExprToRaw(e) @@ -3199,8 +3221,6 @@ module Synth { or result = convertUnderscoreExprToRaw(e) or - result = convertWhileExprToRaw(e) - or result = convertYeetExprToRaw(e) or result = convertYieldExprToRaw(e) @@ -3296,6 +3316,16 @@ module Synth { result = convertUseToRaw(e) } + /** + * INTERNAL: Do not use. + * Converts a synthesized `TLabelableExpr` to a raw DB element, if possible. + */ + Raw::Element convertLabelableExprToRaw(TLabelableExpr e) { + result = convertBlockExprToRaw(e) + or + result = convertLoopingExprToRaw(e) + } + /** * INTERNAL: Do not use. * Converts a synthesized `TLocatable` to a raw DB element, if possible. @@ -3308,6 +3338,18 @@ module Synth { result = convertFormatArgumentToRaw(e) } + /** + * INTERNAL: Do not use. + * Converts a synthesized `TLoopingExpr` to a raw DB element, if possible. + */ + Raw::Element convertLoopingExprToRaw(TLoopingExpr e) { + result = convertForExprToRaw(e) + or + result = convertLoopExprToRaw(e) + or + result = convertWhileExprToRaw(e) + } + /** * INTERNAL: Do not use. * Converts a synthesized `TPat` to a raw DB element, if possible. diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/WhileExpr.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/WhileExpr.qll index 5cd48bb2506..fa4a4aee65c 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/WhileExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/WhileExpr.qll @@ -7,10 +7,8 @@ private import codeql.rust.elements.internal.generated.Synth private import codeql.rust.elements.internal.generated.Raw import codeql.rust.elements.Attr -import codeql.rust.elements.BlockExpr import codeql.rust.elements.Expr -import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl -import codeql.rust.elements.Label +import codeql.rust.elements.internal.LoopingExprImpl::Impl as LoopingExprImpl /** * INTERNAL: This module contains the fully generated definition of `WhileExpr` and should not @@ -25,7 +23,7 @@ module Generated { * INTERNAL: Do not reference the `Generated::WhileExpr` class directly. * Use the subclass `WhileExpr`, where the following predicates are available. */ - class WhileExpr extends Synth::TWhileExpr, ExprImpl::Expr { + class WhileExpr extends Synth::TWhileExpr, LoopingExprImpl::LoopingExpr { override string getAPrimaryQlClass() { result = "WhileExpr" } /** @@ -58,33 +56,5 @@ module Generated { * Holds if `getCondition()` exists. */ final predicate hasCondition() { exists(this.getCondition()) } - - /** - * Gets the label of this while expression, if it exists. - */ - Label getLabel() { - result = - Synth::convertLabelFromRaw(Synth::convertWhileExprToRaw(this).(Raw::WhileExpr).getLabel()) - } - - /** - * Holds if `getLabel()` exists. - */ - final predicate hasLabel() { exists(this.getLabel()) } - - /** - * Gets the loop body of this while expression, if it exists. - */ - BlockExpr getLoopBody() { - result = - Synth::convertBlockExprFromRaw(Synth::convertWhileExprToRaw(this) - .(Raw::WhileExpr) - .getLoopBody()) - } - - /** - * Holds if `getLoopBody()` exists. - */ - final predicate hasLoopBody() { exists(this.getLoopBody()) } } } diff --git a/rust/ql/lib/rust.dbscheme b/rust/ql/lib/rust.dbscheme index 666a1e2b0e1..c9933b5b5e3 100644 --- a/rust/ql/lib/rust.dbscheme +++ b/rust/ql/lib/rust.dbscheme @@ -292,20 +292,18 @@ closure_binder_generic_param_lists( | @await_expr | @become_expr | @binary_expr -| @block_expr | @break_expr | @call_expr_base | @cast_expr | @closure_expr | @continue_expr | @field_expr -| @for_expr | @format_args_expr | @if_expr | @index_expr +| @labelable_expr | @let_expr | @literal_expr -| @loop_expr | @macro_expr | @match_expr | @offset_of_expr @@ -319,7 +317,6 @@ closure_binder_generic_param_lists( | @try_expr | @tuple_expr | @underscore_expr -| @while_expr | @yeet_expr | @yield_expr ; @@ -1314,59 +1311,6 @@ binary_expr_rhs( int rhs: @expr ref ); -block_exprs( - unique int id: @block_expr -); - -#keyset[id, index] -block_expr_attrs( - int id: @block_expr ref, - int index: int ref, - int attr: @attr ref -); - -#keyset[id] -block_expr_is_async( - int id: @block_expr ref -); - -#keyset[id] -block_expr_is_const( - int id: @block_expr ref -); - -#keyset[id] -block_expr_is_gen( - int id: @block_expr ref -); - -#keyset[id] -block_expr_is_move( - int id: @block_expr ref -); - -#keyset[id] -block_expr_is_try( - int id: @block_expr ref -); - -#keyset[id] -block_expr_is_unsafe( - int id: @block_expr ref -); - -#keyset[id] -block_expr_labels( - int id: @block_expr ref, - int label: @label ref -); - -#keyset[id] -block_expr_stmt_lists( - int id: @block_expr ref, - int stmt_list: @stmt_list ref -); - box_pats( unique int id: @box_pat ); @@ -1650,41 +1594,6 @@ fn_ptr_type_ret_types( int ret_type: @ret_type ref ); -for_exprs( - unique int id: @for_expr -); - -#keyset[id, index] -for_expr_attrs( - int id: @for_expr ref, - int index: int ref, - int attr: @attr ref -); - -#keyset[id] -for_expr_iterables( - int id: @for_expr ref, - int iterable: @expr ref -); - -#keyset[id] -for_expr_labels( - int id: @for_expr ref, - int label: @label ref -); - -#keyset[id] -for_expr_loop_bodies( - int id: @for_expr ref, - int loop_body: @block_expr ref -); - -#keyset[id] -for_expr_pats( - int id: @for_expr ref, - int pat: @pat ref -); - for_types( unique int id: @for_type ); @@ -1856,6 +1765,17 @@ item_crate_origins( string crate_origin: string ref ); +@labelable_expr = + @block_expr +| @looping_expr +; + +#keyset[id] +labelable_expr_labels( + int id: @labelable_expr ref, + int label: @label ref +); + let_exprs( unique int id: @let_expr ); @@ -1974,29 +1894,6 @@ literal_pat_literals( int literal: @literal_expr ref ); -loop_exprs( - unique int id: @loop_expr -); - -#keyset[id, index] -loop_expr_attrs( - int id: @loop_expr ref, - int index: int ref, - int attr: @attr ref -); - -#keyset[id] -loop_expr_labels( - int id: @loop_expr ref, - int label: @label ref -); - -#keyset[id] -loop_expr_loop_bodies( - int id: @loop_expr ref, - int loop_body: @block_expr ref -); - macro_exprs( unique int id: @macro_expr ); @@ -2555,35 +2452,6 @@ underscore_expr_attrs( int attr: @attr ref ); -while_exprs( - unique int id: @while_expr -); - -#keyset[id, index] -while_expr_attrs( - int id: @while_expr ref, - int index: int ref, - int attr: @attr ref -); - -#keyset[id] -while_expr_conditions( - int id: @while_expr ref, - int condition: @expr ref -); - -#keyset[id] -while_expr_labels( - int id: @while_expr ref, - int label: @label ref -); - -#keyset[id] -while_expr_loop_bodies( - int id: @while_expr ref, - int loop_body: @block_expr ref -); - wildcard_pats( unique int id: @wildcard_pat ); @@ -2622,6 +2490,53 @@ yield_expr_exprs( int expr: @expr ref ); +block_exprs( + unique int id: @block_expr +); + +#keyset[id, index] +block_expr_attrs( + int id: @block_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +block_expr_is_async( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_const( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_gen( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_move( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_try( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_unsafe( + int id: @block_expr ref +); + +#keyset[id] +block_expr_stmt_lists( + int id: @block_expr ref, + int stmt_list: @stmt_list ref +); + call_exprs( unique int id: @call_expr ); @@ -2908,6 +2823,18 @@ impl_where_clauses( int where_clause: @where_clause ref ); +@looping_expr = + @for_expr +| @loop_expr +| @while_expr +; + +#keyset[id] +looping_expr_loop_bodies( + int id: @looping_expr ref, + int loop_body: @block_expr ref +); + macro_calls( unique int id: @macro_call ); @@ -3368,3 +3295,54 @@ use_visibilities( int id: @use ref, int visibility: @visibility ref ); + +for_exprs( + unique int id: @for_expr +); + +#keyset[id, index] +for_expr_attrs( + int id: @for_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +for_expr_iterables( + int id: @for_expr ref, + int iterable: @expr ref +); + +#keyset[id] +for_expr_pats( + int id: @for_expr ref, + int pat: @pat ref +); + +loop_exprs( + unique int id: @loop_expr +); + +#keyset[id, index] +loop_expr_attrs( + int id: @loop_expr ref, + int index: int ref, + int attr: @attr ref +); + +while_exprs( + unique int id: @while_expr +); + +#keyset[id, index] +while_expr_attrs( + int id: @while_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +while_expr_conditions( + int id: @while_expr ref, + int condition: @expr ref +); diff --git a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.ql b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.ql index 58107054515..992c06a605b 100644 --- a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.ql +++ b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.ql @@ -3,11 +3,12 @@ import codeql.rust.elements import TestUtils from - BlockExpr x, int getNumberOfAttrs, string isAsync, string isConst, string isGen, string isMove, - string isTry, string isUnsafe, string hasLabel, string hasStmtList + BlockExpr x, string hasLabel, int getNumberOfAttrs, string isAsync, string isConst, string isGen, + string isMove, string isTry, string isUnsafe, string hasStmtList where toBeTested(x) and not x.isUnknown() and + (if x.hasLabel() then hasLabel = "yes" else hasLabel = "no") and getNumberOfAttrs = x.getNumberOfAttrs() and (if x.isAsync() then isAsync = "yes" else isAsync = "no") and (if x.isConst() then isConst = "yes" else isConst = "no") and @@ -15,8 +16,7 @@ where (if x.isMove() then isMove = "yes" else isMove = "no") and (if x.isTry() then isTry = "yes" else isTry = "no") and (if x.isUnsafe() then isUnsafe = "yes" else isUnsafe = "no") and - (if x.hasLabel() then hasLabel = "yes" else hasLabel = "no") and if x.hasStmtList() then hasStmtList = "yes" else hasStmtList = "no" -select x, "getNumberOfAttrs:", getNumberOfAttrs, "isAsync:", isAsync, "isConst:", isConst, "isGen:", - isGen, "isMove:", isMove, "isTry:", isTry, "isUnsafe:", isUnsafe, "hasLabel:", hasLabel, +select x, "hasLabel:", hasLabel, "getNumberOfAttrs:", getNumberOfAttrs, "isAsync:", isAsync, + "isConst:", isConst, "isGen:", isGen, "isMove:", isMove, "isTry:", isTry, "isUnsafe:", isUnsafe, "hasStmtList:", hasStmtList diff --git a/rust/ql/test/extractor-tests/generated/ForExpr/ForExpr.ql b/rust/ql/test/extractor-tests/generated/ForExpr/ForExpr.ql index ef1999ff4a9..60f5ab1e080 100644 --- a/rust/ql/test/extractor-tests/generated/ForExpr/ForExpr.ql +++ b/rust/ql/test/extractor-tests/generated/ForExpr/ForExpr.ql @@ -3,15 +3,15 @@ import codeql.rust.elements import TestUtils from - ForExpr x, int getNumberOfAttrs, string hasIterable, string hasLabel, string hasLoopBody, + ForExpr x, string hasLabel, string hasLoopBody, int getNumberOfAttrs, string hasIterable, string hasPat where toBeTested(x) and not x.isUnknown() and - getNumberOfAttrs = x.getNumberOfAttrs() and - (if x.hasIterable() then hasIterable = "yes" else hasIterable = "no") and (if x.hasLabel() then hasLabel = "yes" else hasLabel = "no") and (if x.hasLoopBody() then hasLoopBody = "yes" else hasLoopBody = "no") and + getNumberOfAttrs = x.getNumberOfAttrs() and + (if x.hasIterable() then hasIterable = "yes" else hasIterable = "no") and if x.hasPat() then hasPat = "yes" else hasPat = "no" -select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasIterable:", hasIterable, "hasLabel:", hasLabel, - "hasLoopBody:", hasLoopBody, "hasPat:", hasPat +select x, "hasLabel:", hasLabel, "hasLoopBody:", hasLoopBody, "getNumberOfAttrs:", getNumberOfAttrs, + "hasIterable:", hasIterable, "hasPat:", hasPat diff --git a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.ql b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.ql index c627fb16771..92248ab5ec0 100644 --- a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.ql +++ b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.ql @@ -2,11 +2,11 @@ import codeql.rust.elements import TestUtils -from LoopExpr x, int getNumberOfAttrs, string hasLabel, string hasLoopBody +from LoopExpr x, string hasLabel, string hasLoopBody, int getNumberOfAttrs where toBeTested(x) and not x.isUnknown() and - getNumberOfAttrs = x.getNumberOfAttrs() and (if x.hasLabel() then hasLabel = "yes" else hasLabel = "no") and - if x.hasLoopBody() then hasLoopBody = "yes" else hasLoopBody = "no" -select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasLabel:", hasLabel, "hasLoopBody:", hasLoopBody + (if x.hasLoopBody() then hasLoopBody = "yes" else hasLoopBody = "no") and + getNumberOfAttrs = x.getNumberOfAttrs() +select x, "hasLabel:", hasLabel, "hasLoopBody:", hasLoopBody, "getNumberOfAttrs:", getNumberOfAttrs diff --git a/rust/ql/test/extractor-tests/generated/WhileExpr/WhileExpr.ql b/rust/ql/test/extractor-tests/generated/WhileExpr/WhileExpr.ql index ceb095e9d20..8544014e571 100644 --- a/rust/ql/test/extractor-tests/generated/WhileExpr/WhileExpr.ql +++ b/rust/ql/test/extractor-tests/generated/WhileExpr/WhileExpr.ql @@ -2,13 +2,13 @@ import codeql.rust.elements import TestUtils -from WhileExpr x, int getNumberOfAttrs, string hasCondition, string hasLabel, string hasLoopBody +from WhileExpr x, string hasLabel, string hasLoopBody, int getNumberOfAttrs, string hasCondition where toBeTested(x) and not x.isUnknown() and - getNumberOfAttrs = x.getNumberOfAttrs() and - (if x.hasCondition() then hasCondition = "yes" else hasCondition = "no") and (if x.hasLabel() then hasLabel = "yes" else hasLabel = "no") and - if x.hasLoopBody() then hasLoopBody = "yes" else hasLoopBody = "no" -select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasCondition:", hasCondition, "hasLabel:", - hasLabel, "hasLoopBody:", hasLoopBody + (if x.hasLoopBody() then hasLoopBody = "yes" else hasLoopBody = "no") and + getNumberOfAttrs = x.getNumberOfAttrs() and + if x.hasCondition() then hasCondition = "yes" else hasCondition = "no" +select x, "hasLabel:", hasLabel, "hasLoopBody:", hasLoopBody, "getNumberOfAttrs:", getNumberOfAttrs, + "hasCondition:", hasCondition diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 6260c2328a6..b7cb71bacfb 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -11,10 +11,10 @@ edges | test.rs:7:9:7:19 | method_call | test.rs:7:9:7:21 | method_call(...) | | | test.rs:7:9:7:21 | method_call(...) | test.rs:5:24:8:5 | { ... } | | | test.rs:7:9:7:22 | ExprStmt | test.rs:7:9:7:19 | method_call | | -| test.rs:10:5:13:5 | enter fn method_call | test.rs:11:9:11:37 | let map = ... | | +| test.rs:10:5:13:5 | enter fn method_call | test.rs:11:9:11:37 | let ... = ... | | | test.rs:10:5:13:5 | exit fn method_call (normal) | test.rs:10:5:13:5 | exit fn method_call | | | test.rs:10:22:13:5 | { ... } | test.rs:10:5:13:5 | exit fn method_call (normal) | | -| test.rs:11:9:11:37 | let map = ... | test.rs:11:23:11:34 | HashMap::new | | +| test.rs:11:9:11:37 | let ... = ... | test.rs:11:23:11:34 | HashMap::new | | | test.rs:11:13:11:19 | map | test.rs:12:9:12:28 | ExprStmt | match | | test.rs:11:23:11:34 | HashMap::new | test.rs:11:23:11:36 | HashMap::new(...) | | | test.rs:11:23:11:36 | HashMap::new(...) | test.rs:11:13:11:19 | map | | @@ -25,21 +25,21 @@ edges | test.rs:12:24:12:26 | "a" | test.rs:12:9:12:27 | ... .insert(...) | | | test.rs:18:5:24:5 | enter fn next | test.rs:18:13:18:13 | n | | | test.rs:18:5:24:5 | exit fn next (normal) | test.rs:18:5:24:5 | exit fn next | | -| test.rs:18:13:18:13 | n | test.rs:18:13:18:18 | n: i64 | match | -| test.rs:18:13:18:18 | n: i64 | test.rs:19:12:19:12 | n | | +| test.rs:18:13:18:13 | n | test.rs:18:13:18:18 | ...: i64 | match | +| test.rs:18:13:18:18 | ...: i64 | test.rs:19:12:19:12 | n | | | test.rs:18:28:24:5 | { ... } | test.rs:18:5:24:5 | exit fn next (normal) | | -| test.rs:19:9:23:9 | if ... { ... } else { ... } | test.rs:18:28:24:5 | { ... } | | +| test.rs:19:9:23:9 | if ... {...} else {...} | test.rs:18:28:24:5 | { ... } | | | test.rs:19:12:19:12 | n | test.rs:19:16:19:16 | 2 | | | test.rs:19:12:19:16 | ... % ... | test.rs:19:21:19:21 | 0 | | | test.rs:19:12:19:21 | ... == ... | test.rs:20:13:20:13 | n | true | | test.rs:19:12:19:21 | ... == ... | test.rs:22:13:22:13 | 3 | false | | test.rs:19:16:19:16 | 2 | test.rs:19:12:19:16 | ... % ... | | | test.rs:19:21:19:21 | 0 | test.rs:19:12:19:21 | ... == ... | | -| test.rs:19:23:21:9 | { ... } | test.rs:19:9:23:9 | if ... { ... } else { ... } | | +| test.rs:19:23:21:9 | { ... } | test.rs:19:9:23:9 | if ... {...} else {...} | | | test.rs:20:13:20:13 | n | test.rs:20:17:20:17 | 2 | | | test.rs:20:13:20:17 | ... / ... | test.rs:19:23:21:9 | { ... } | | | test.rs:20:17:20:17 | 2 | test.rs:20:13:20:17 | ... / ... | | -| test.rs:21:16:23:9 | { ... } | test.rs:19:9:23:9 | if ... { ... } else { ... } | | +| test.rs:21:16:23:9 | { ... } | test.rs:19:9:23:9 | if ... {...} else {...} | | | test.rs:22:13:22:13 | 3 | test.rs:22:17:22:17 | n | | | test.rs:22:13:22:17 | ... * ... | test.rs:22:21:22:21 | 1 | | | test.rs:22:13:22:21 | ... + ... | test.rs:21:16:23:9 | { ... } | | @@ -47,13 +47,13 @@ edges | test.rs:22:21:22:21 | 1 | test.rs:22:13:22:21 | ... + ... | | | test.rs:26:5:42:5 | enter fn test_break_and_continue | test.rs:26:32:26:32 | n | | | test.rs:26:5:42:5 | exit fn test_break_and_continue (normal) | test.rs:26:5:42:5 | exit fn test_break_and_continue | | -| test.rs:26:32:26:32 | n | test.rs:26:32:26:37 | n: i64 | match | -| test.rs:26:32:26:37 | n: i64 | test.rs:27:9:27:22 | let i = ... | | -| test.rs:27:9:27:22 | let i = ... | test.rs:27:21:27:21 | n | | +| test.rs:26:32:26:32 | n | test.rs:26:32:26:37 | ...: i64 | match | +| test.rs:26:32:26:37 | ...: i64 | test.rs:27:9:27:22 | let ... = n | | +| test.rs:27:9:27:22 | let ... = n | test.rs:27:21:27:21 | n | | | test.rs:27:13:27:17 | i | test.rs:28:9:40:9 | ExprStmt | match | | test.rs:27:21:27:21 | n | test.rs:27:13:27:17 | i | | | test.rs:28:9:40:9 | ExprStmt | test.rs:29:13:29:24 | ExprStmt | | -| test.rs:28:9:40:9 | loop {...} | test.rs:41:9:41:20 | ExprStmt | | +| test.rs:28:9:40:9 | loop { ... } | test.rs:41:9:41:20 | ExprStmt | | | test.rs:28:14:40:9 | { ... } | test.rs:29:13:29:24 | ExprStmt | | | test.rs:29:13:29:13 | i | test.rs:29:17:29:20 | next | | | test.rs:29:13:29:23 | ... = ... | test.rs:30:13:32:13 | ExprStmt | | @@ -62,27 +62,27 @@ edges | test.rs:29:17:29:23 | next(...) | test.rs:29:13:29:23 | ... = ... | | | test.rs:29:22:29:22 | i | test.rs:29:17:29:23 | next(...) | | | test.rs:30:13:32:13 | ExprStmt | test.rs:30:16:30:16 | i | | -| test.rs:30:13:32:13 | if ... { ... } | test.rs:33:13:35:13 | ExprStmt | | +| test.rs:30:13:32:13 | if ... {...} | test.rs:33:13:35:13 | ExprStmt | | | test.rs:30:16:30:16 | i | test.rs:30:20:30:24 | 10000 | | -| test.rs:30:16:30:24 | ... > ... | test.rs:30:13:32:13 | if ... { ... } | false | +| test.rs:30:16:30:24 | ... > ... | test.rs:30:13:32:13 | if ... {...} | false | | test.rs:30:16:30:24 | ... > ... | test.rs:31:17:31:29 | ExprStmt | true | | test.rs:30:20:30:24 | 10000 | test.rs:30:16:30:24 | ... > ... | | -| test.rs:31:17:31:28 | return ... | test.rs:26:5:42:5 | exit fn test_break_and_continue (normal) | return | +| test.rs:31:17:31:28 | return false | test.rs:26:5:42:5 | exit fn test_break_and_continue (normal) | return | | test.rs:31:17:31:29 | ExprStmt | test.rs:31:24:31:28 | false | | -| test.rs:31:24:31:28 | false | test.rs:31:17:31:28 | return ... | | +| test.rs:31:24:31:28 | false | test.rs:31:17:31:28 | return false | | | test.rs:33:13:35:13 | ExprStmt | test.rs:33:16:33:16 | i | | -| test.rs:33:13:35:13 | if ... { ... } | test.rs:36:13:38:13 | ExprStmt | | +| test.rs:33:13:35:13 | if ... {...} | test.rs:36:13:38:13 | ExprStmt | | | test.rs:33:16:33:16 | i | test.rs:33:21:33:21 | 1 | | -| test.rs:33:16:33:21 | ... == ... | test.rs:33:13:35:13 | if ... { ... } | false | +| test.rs:33:16:33:21 | ... == ... | test.rs:33:13:35:13 | if ... {...} | false | | test.rs:33:16:33:21 | ... == ... | test.rs:34:17:34:22 | ExprStmt | true | | test.rs:33:21:33:21 | 1 | test.rs:33:16:33:21 | ... == ... | | -| test.rs:34:17:34:21 | break | test.rs:28:9:40:9 | loop {...} | break | +| test.rs:34:17:34:21 | break | test.rs:28:9:40:9 | loop { ... } | break | | test.rs:34:17:34:22 | ExprStmt | test.rs:34:17:34:21 | break | | | test.rs:36:13:38:13 | ExprStmt | test.rs:36:16:36:16 | i | | -| test.rs:36:13:38:13 | if ... { ... } | test.rs:39:13:39:13 | i | | +| test.rs:36:13:38:13 | if ... {...} | test.rs:39:13:39:13 | i | | | test.rs:36:16:36:16 | i | test.rs:36:20:36:20 | 2 | | | test.rs:36:16:36:20 | ... % ... | test.rs:36:25:36:25 | 0 | | -| test.rs:36:16:36:25 | ... != ... | test.rs:36:13:38:13 | if ... { ... } | false | +| test.rs:36:16:36:25 | ... != ... | test.rs:36:13:38:13 | if ... {...} | false | | test.rs:36:16:36:25 | ... != ... | test.rs:37:17:37:25 | ExprStmt | true | | test.rs:36:20:36:20 | 2 | test.rs:36:16:36:20 | ... % ... | | | test.rs:36:25:36:25 | 0 | test.rs:36:16:36:25 | ... != ... | | @@ -93,156 +93,156 @@ edges | test.rs:39:17:39:17 | i | test.rs:39:21:39:21 | 2 | | | test.rs:39:17:39:21 | ... / ... | test.rs:39:13:39:21 | ... = ... | | | test.rs:39:21:39:21 | 2 | test.rs:39:17:39:21 | ... / ... | | -| test.rs:41:9:41:19 | return ... | test.rs:26:5:42:5 | exit fn test_break_and_continue (normal) | return | +| test.rs:41:9:41:19 | return true | test.rs:26:5:42:5 | exit fn test_break_and_continue (normal) | return | | test.rs:41:9:41:20 | ExprStmt | test.rs:41:16:41:19 | true | | -| test.rs:41:16:41:19 | true | test.rs:41:9:41:19 | return ... | | +| test.rs:41:16:41:19 | true | test.rs:41:9:41:19 | return true | | | test.rs:44:5:56:5 | enter fn test_break_with_labels | test.rs:44:31:44:31 | b | | | test.rs:44:5:56:5 | exit fn test_break_with_labels (normal) | test.rs:44:5:56:5 | exit fn test_break_with_labels | | -| test.rs:44:31:44:31 | b | test.rs:44:31:44:37 | b: bool | match | -| test.rs:44:31:44:37 | b: bool | test.rs:45:9:54:9 | ExprStmt | | +| test.rs:44:31:44:31 | b | test.rs:44:31:44:37 | ...: bool | match | +| test.rs:44:31:44:37 | ...: bool | test.rs:45:9:54:9 | ExprStmt | | | test.rs:44:48:56:5 | { ... } | test.rs:44:5:56:5 | exit fn test_break_with_labels (normal) | | +| test.rs:45:9:54:9 | ''outer: loop { ... } | test.rs:55:9:55:12 | true | | | test.rs:45:9:54:9 | ExprStmt | test.rs:47:17:51:17 | ExprStmt | | -| test.rs:45:9:54:9 | loop {...} | test.rs:55:9:55:12 | true | | | test.rs:45:22:54:9 | { ... } | test.rs:47:17:51:17 | ExprStmt | | -| test.rs:46:13:53:13 | loop {...} | test.rs:45:22:54:9 | { ... } | | +| test.rs:46:13:53:13 | ''inner: loop { ... } | test.rs:45:22:54:9 | { ... } | | | test.rs:47:17:51:17 | ExprStmt | test.rs:47:20:47:20 | b | | -| test.rs:47:17:51:17 | if ... { ... } else { ... } | test.rs:52:17:52:29 | ExprStmt | | +| test.rs:47:17:51:17 | if b {...} else {...} | test.rs:52:17:52:29 | ExprStmt | | | test.rs:47:20:47:20 | b | test.rs:48:21:48:26 | ExprStmt | true | | test.rs:47:20:47:20 | b | test.rs:49:27:49:27 | b | false | -| test.rs:48:21:48:25 | break | test.rs:46:13:53:13 | loop {...} | break | +| test.rs:48:21:48:25 | break | test.rs:46:13:53:13 | ''inner: loop { ... } | break | | test.rs:48:21:48:26 | ExprStmt | test.rs:48:21:48:25 | break | | -| test.rs:49:24:51:17 | if ... { ... } | test.rs:47:17:51:17 | if ... { ... } else { ... } | | -| test.rs:49:27:49:27 | b | test.rs:49:24:51:17 | if ... { ... } | false | +| test.rs:49:24:51:17 | if b {...} | test.rs:47:17:51:17 | if b {...} else {...} | | +| test.rs:49:27:49:27 | b | test.rs:49:24:51:17 | if b {...} | false | | test.rs:49:27:49:27 | b | test.rs:50:21:50:33 | ExprStmt | true | -| test.rs:50:21:50:32 | break ''outer | test.rs:45:9:54:9 | loop {...} | break | +| test.rs:50:21:50:32 | break ''outer | test.rs:45:9:54:9 | ''outer: loop { ... } | break | | test.rs:50:21:50:33 | ExprStmt | test.rs:50:21:50:32 | break ''outer | | -| test.rs:52:17:52:28 | break ''inner | test.rs:46:13:53:13 | loop {...} | break | +| test.rs:52:17:52:28 | break ''inner | test.rs:46:13:53:13 | ''inner: loop { ... } | break | | test.rs:52:17:52:29 | ExprStmt | test.rs:52:17:52:28 | break ''inner | | | test.rs:55:9:55:12 | true | test.rs:44:48:56:5 | { ... } | | | test.rs:58:5:70:5 | enter fn test_continue_with_labels | test.rs:58:34:58:34 | b | | -| test.rs:58:34:58:34 | b | test.rs:58:34:58:40 | b: bool | match | -| test.rs:58:34:58:40 | b: bool | test.rs:60:13:60:14 | ExprStmt | | +| test.rs:58:34:58:34 | b | test.rs:58:34:58:40 | ...: bool | match | +| test.rs:58:34:58:40 | ...: bool | test.rs:60:13:60:14 | ExprStmt | | | test.rs:60:13:60:13 | 1 | test.rs:62:17:66:17 | ExprStmt | | | test.rs:60:13:60:14 | ExprStmt | test.rs:60:13:60:13 | 1 | | | test.rs:62:17:66:17 | ExprStmt | test.rs:62:20:62:20 | b | | -| test.rs:62:17:66:17 | if ... { ... } else { ... } | test.rs:67:17:67:32 | ExprStmt | | +| test.rs:62:17:66:17 | if b {...} else {...} | test.rs:67:17:67:32 | ExprStmt | | | test.rs:62:20:62:20 | b | test.rs:63:21:63:29 | ExprStmt | true | | test.rs:62:20:62:20 | b | test.rs:64:27:64:27 | b | false | | test.rs:63:21:63:28 | continue | test.rs:62:17:66:17 | ExprStmt | continue | | test.rs:63:21:63:29 | ExprStmt | test.rs:63:21:63:28 | continue | | -| test.rs:64:24:66:17 | if ... { ... } | test.rs:62:17:66:17 | if ... { ... } else { ... } | | -| test.rs:64:27:64:27 | b | test.rs:64:24:66:17 | if ... { ... } | false | +| test.rs:64:24:66:17 | if b {...} | test.rs:62:17:66:17 | if b {...} else {...} | | +| test.rs:64:27:64:27 | b | test.rs:64:24:66:17 | if b {...} | false | | test.rs:64:27:64:27 | b | test.rs:65:21:65:36 | ExprStmt | true | -| test.rs:65:21:65:35 | continue 'outer | test.rs:60:13:60:14 | ExprStmt | continue | -| test.rs:65:21:65:36 | ExprStmt | test.rs:65:21:65:35 | continue 'outer | | -| test.rs:67:17:67:31 | continue 'inner | test.rs:62:17:66:17 | ExprStmt | continue | -| test.rs:67:17:67:32 | ExprStmt | test.rs:67:17:67:31 | continue 'inner | | +| test.rs:65:21:65:35 | continue ''outer | test.rs:60:13:60:14 | ExprStmt | continue | +| test.rs:65:21:65:36 | ExprStmt | test.rs:65:21:65:35 | continue ''outer | | +| test.rs:67:17:67:31 | continue ''inner | test.rs:62:17:66:17 | ExprStmt | continue | +| test.rs:67:17:67:32 | ExprStmt | test.rs:67:17:67:31 | continue ''inner | | | test.rs:72:5:84:5 | enter fn test_loop_label_shadowing | test.rs:72:34:72:34 | b | | -| test.rs:72:34:72:34 | b | test.rs:72:34:72:40 | b: bool | match | -| test.rs:72:34:72:40 | b: bool | test.rs:74:13:74:14 | ExprStmt | | +| test.rs:72:34:72:34 | b | test.rs:72:34:72:40 | ...: bool | match | +| test.rs:72:34:72:40 | ...: bool | test.rs:74:13:74:14 | ExprStmt | | | test.rs:74:13:74:13 | 1 | test.rs:76:17:80:17 | ExprStmt | | | test.rs:74:13:74:14 | ExprStmt | test.rs:74:13:74:13 | 1 | | | test.rs:76:17:80:17 | ExprStmt | test.rs:76:20:76:20 | b | | -| test.rs:76:17:80:17 | if ... { ... } else { ... } | test.rs:81:17:81:32 | ExprStmt | | +| test.rs:76:17:80:17 | if b {...} else {...} | test.rs:81:17:81:32 | ExprStmt | | | test.rs:76:20:76:20 | b | test.rs:77:21:77:29 | ExprStmt | true | | test.rs:76:20:76:20 | b | test.rs:78:27:78:27 | b | false | | test.rs:77:21:77:28 | continue | test.rs:76:17:80:17 | ExprStmt | continue | | test.rs:77:21:77:29 | ExprStmt | test.rs:77:21:77:28 | continue | | -| test.rs:78:24:80:17 | if ... { ... } | test.rs:76:17:80:17 | if ... { ... } else { ... } | | -| test.rs:78:27:78:27 | b | test.rs:78:24:80:17 | if ... { ... } | false | +| test.rs:78:24:80:17 | if b {...} | test.rs:76:17:80:17 | if b {...} else {...} | | +| test.rs:78:27:78:27 | b | test.rs:78:24:80:17 | if b {...} | false | | test.rs:78:27:78:27 | b | test.rs:79:21:79:36 | ExprStmt | true | -| test.rs:79:21:79:35 | continue 'label | test.rs:76:17:80:17 | ExprStmt | continue | -| test.rs:79:21:79:36 | ExprStmt | test.rs:79:21:79:35 | continue 'label | | -| test.rs:81:17:81:31 | continue 'label | test.rs:76:17:80:17 | ExprStmt | continue | -| test.rs:81:17:81:32 | ExprStmt | test.rs:81:17:81:31 | continue 'label | | +| test.rs:79:21:79:35 | continue ''label | test.rs:76:17:80:17 | ExprStmt | continue | +| test.rs:79:21:79:36 | ExprStmt | test.rs:79:21:79:35 | continue ''label | | +| test.rs:81:17:81:31 | continue ''label | test.rs:76:17:80:17 | ExprStmt | continue | +| test.rs:81:17:81:32 | ExprStmt | test.rs:81:17:81:31 | continue ''label | | | test.rs:86:5:95:5 | enter fn test_while | test.rs:86:19:86:19 | i | | | test.rs:86:5:95:5 | exit fn test_while (normal) | test.rs:86:5:95:5 | exit fn test_while | | -| test.rs:86:19:86:19 | i | test.rs:86:19:86:24 | i: i64 | match | -| test.rs:86:19:86:24 | i: i64 | test.rs:87:9:87:25 | let b = ... | | +| test.rs:86:19:86:19 | i | test.rs:86:19:86:24 | ...: i64 | match | +| test.rs:86:19:86:24 | ...: i64 | test.rs:87:9:87:25 | let ... = true | | | test.rs:86:27:95:5 | { ... } | test.rs:86:5:95:5 | exit fn test_while (normal) | | -| test.rs:87:9:87:25 | let b = ... | test.rs:87:21:87:24 | true | | +| test.rs:87:9:87:25 | let ... = true | test.rs:87:21:87:24 | true | | | test.rs:87:13:87:17 | b | test.rs:88:15:88:15 | b | match | | test.rs:87:21:87:24 | true | test.rs:87:13:87:17 | b | | -| test.rs:88:9:94:9 | while ... { ... } | test.rs:86:27:95:5 | { ... } | | -| test.rs:88:15:88:15 | b | test.rs:88:9:94:9 | while ... { ... } | false | +| test.rs:88:9:94:9 | while b { ... } | test.rs:86:27:95:5 | { ... } | | +| test.rs:88:15:88:15 | b | test.rs:88:9:94:9 | while b { ... } | false | | test.rs:88:15:88:15 | b | test.rs:89:13:89:14 | ExprStmt | true | | test.rs:88:17:94:9 | { ... } | test.rs:88:15:88:15 | b | | | test.rs:89:13:89:13 | 1 | test.rs:90:13:92:13 | ExprStmt | | | test.rs:89:13:89:14 | ExprStmt | test.rs:89:13:89:13 | 1 | | | test.rs:90:13:92:13 | ExprStmt | test.rs:90:17:90:17 | i | | -| test.rs:90:13:92:13 | if ... { ... } | test.rs:93:13:93:22 | ExprStmt | | +| test.rs:90:13:92:13 | if ... {...} | test.rs:93:13:93:22 | ExprStmt | | | test.rs:90:17:90:17 | i | test.rs:90:21:90:21 | 0 | | -| test.rs:90:17:90:21 | ... > ... | test.rs:90:13:92:13 | if ... { ... } | false | +| test.rs:90:17:90:21 | ... > ... | test.rs:90:13:92:13 | if ... {...} | false | | test.rs:90:17:90:21 | ... > ... | test.rs:91:17:91:22 | ExprStmt | true | | test.rs:90:21:90:21 | 0 | test.rs:90:17:90:21 | ... > ... | | -| test.rs:91:17:91:21 | break | test.rs:88:9:94:9 | while ... { ... } | break | +| test.rs:91:17:91:21 | break | test.rs:88:9:94:9 | while b { ... } | break | | test.rs:91:17:91:22 | ExprStmt | test.rs:91:17:91:21 | break | | | test.rs:93:13:93:13 | b | test.rs:93:17:93:21 | false | | | test.rs:93:13:93:21 | ... = ... | test.rs:88:17:94:9 | { ... } | | | test.rs:93:13:93:22 | ExprStmt | test.rs:93:13:93:13 | b | | | test.rs:93:17:93:21 | false | test.rs:93:13:93:21 | ... = ... | | -| test.rs:97:5:104:5 | enter fn test_while_let | test.rs:98:9:98:29 | let iter = ... | | +| test.rs:97:5:104:5 | enter fn test_while_let | test.rs:98:9:98:29 | let ... = ... | | | test.rs:97:5:104:5 | exit fn test_while_let (normal) | test.rs:97:5:104:5 | exit fn test_while_let | | | test.rs:97:25:104:5 | { ... } | test.rs:97:5:104:5 | exit fn test_while_let (normal) | | -| test.rs:98:9:98:29 | let iter = ... | test.rs:98:24:98:24 | 1 | | -| test.rs:98:13:98:20 | iter | test.rs:99:15:99:39 | let TupleStructPat = ... | match | +| test.rs:98:9:98:29 | let ... = ... | test.rs:98:24:98:24 | 1 | | +| test.rs:98:13:98:20 | iter | test.rs:99:15:99:39 | let ... = ... | match | | test.rs:98:24:98:24 | 1 | test.rs:98:27:98:28 | 10 | | -| test.rs:98:24:98:28 | ... .. ... | test.rs:98:13:98:20 | iter | | -| test.rs:98:27:98:28 | 10 | test.rs:98:24:98:28 | ... .. ... | | +| test.rs:98:24:98:28 | 1..10 | test.rs:98:13:98:20 | iter | | +| test.rs:98:27:98:28 | 10 | test.rs:98:24:98:28 | 1..10 | | | test.rs:99:9:103:9 | while ... { ... } | test.rs:97:25:104:5 | { ... } | | -| test.rs:99:15:99:39 | let TupleStructPat = ... | test.rs:99:29:99:32 | iter | | +| test.rs:99:15:99:39 | let ... = ... | test.rs:99:29:99:32 | iter | | | test.rs:99:19:99:25 | TupleStructPat | test.rs:99:9:103:9 | while ... { ... } | no-match | | test.rs:99:19:99:25 | TupleStructPat | test.rs:99:24:99:24 | x | match | | test.rs:99:24:99:24 | x | test.rs:100:17:100:17 | x | match | | test.rs:99:29:99:32 | iter | test.rs:99:29:99:39 | ... .next(...) | | | test.rs:99:29:99:39 | ... .next(...) | test.rs:99:19:99:25 | TupleStructPat | | -| test.rs:99:41:103:9 | { ... } | test.rs:99:15:99:39 | let TupleStructPat = ... | | -| test.rs:100:13:102:13 | if ... { ... } | test.rs:99:41:103:9 | { ... } | | +| test.rs:99:41:103:9 | { ... } | test.rs:99:15:99:39 | let ... = ... | | +| test.rs:100:13:102:13 | if ... {...} | test.rs:99:41:103:9 | { ... } | | | test.rs:100:17:100:17 | x | test.rs:100:22:100:22 | 5 | | -| test.rs:100:17:100:22 | ... == ... | test.rs:100:13:102:13 | if ... { ... } | false | +| test.rs:100:17:100:22 | ... == ... | test.rs:100:13:102:13 | if ... {...} | false | | test.rs:100:17:100:22 | ... == ... | test.rs:101:17:101:22 | ExprStmt | true | | test.rs:100:22:100:22 | 5 | test.rs:100:17:100:22 | ... == ... | | | test.rs:101:17:101:21 | break | test.rs:99:9:103:9 | while ... { ... } | break | | test.rs:101:17:101:22 | ExprStmt | test.rs:101:17:101:21 | break | | | test.rs:106:5:113:5 | enter fn test_for | test.rs:106:17:106:17 | j | | | test.rs:106:5:113:5 | exit fn test_for (normal) | test.rs:106:5:113:5 | exit fn test_for | | -| test.rs:106:17:106:17 | j | test.rs:106:17:106:22 | j: i64 | match | -| test.rs:106:17:106:22 | j: i64 | test.rs:107:18:107:18 | 0 | | +| test.rs:106:17:106:17 | j | test.rs:106:17:106:22 | ...: i64 | match | +| test.rs:106:17:106:22 | ...: i64 | test.rs:107:18:107:18 | 0 | | | test.rs:106:25:113:5 | { ... } | test.rs:106:5:113:5 | exit fn test_for (normal) | | -| test.rs:107:9:112:9 | for i in ... { ... } | test.rs:106:25:113:5 | { ... } | | -| test.rs:107:13:107:13 | i | test.rs:107:9:112:9 | for i in ... { ... } | no-match | +| test.rs:107:9:112:9 | for ... in ... { ... } | test.rs:106:25:113:5 | { ... } | | +| test.rs:107:13:107:13 | i | test.rs:107:9:112:9 | for ... in ... { ... } | no-match | | test.rs:107:13:107:13 | i | test.rs:108:13:110:13 | ExprStmt | match | | test.rs:107:18:107:18 | 0 | test.rs:107:21:107:22 | 10 | | -| test.rs:107:18:107:22 | ... .. ... | test.rs:107:13:107:13 | i | | -| test.rs:107:21:107:22 | 10 | test.rs:107:18:107:22 | ... .. ... | | +| test.rs:107:18:107:22 | 0..10 | test.rs:107:13:107:13 | i | | +| test.rs:107:21:107:22 | 10 | test.rs:107:18:107:22 | 0..10 | | | test.rs:107:24:112:9 | { ... } | test.rs:107:13:107:13 | i | | | test.rs:108:13:110:13 | ExprStmt | test.rs:108:17:108:17 | i | | -| test.rs:108:13:110:13 | if ... { ... } | test.rs:111:13:111:14 | ExprStmt | | +| test.rs:108:13:110:13 | if ... {...} | test.rs:111:13:111:14 | ExprStmt | | | test.rs:108:17:108:17 | i | test.rs:108:22:108:22 | j | | -| test.rs:108:17:108:22 | ... == ... | test.rs:108:13:110:13 | if ... { ... } | false | +| test.rs:108:17:108:22 | ... == ... | test.rs:108:13:110:13 | if ... {...} | false | | test.rs:108:17:108:22 | ... == ... | test.rs:109:17:109:22 | ExprStmt | true | | test.rs:108:22:108:22 | j | test.rs:108:17:108:22 | ... == ... | | -| test.rs:109:17:109:21 | break | test.rs:107:9:112:9 | for i in ... { ... } | break | +| test.rs:109:17:109:21 | break | test.rs:107:9:112:9 | for ... in ... { ... } | break | | test.rs:109:17:109:22 | ExprStmt | test.rs:109:17:109:21 | break | | | test.rs:111:13:111:13 | 1 | test.rs:107:24:112:9 | { ... } | | | test.rs:111:13:111:14 | ExprStmt | test.rs:111:13:111:13 | 1 | | | test.rs:115:5:119:5 | enter fn break_with_return | test.rs:117:13:117:27 | ExprStmt | | | test.rs:115:5:119:5 | exit fn break_with_return (normal) | test.rs:115:5:119:5 | exit fn break_with_return | | | test.rs:117:13:117:27 | ExprStmt | test.rs:117:26:117:26 | 1 | | -| test.rs:117:19:117:26 | return ... | test.rs:115:5:119:5 | exit fn break_with_return (normal) | return | -| test.rs:117:26:117:26 | 1 | test.rs:117:19:117:26 | return ... | | +| test.rs:117:19:117:26 | return 1 | test.rs:115:5:119:5 | exit fn break_with_return (normal) | return | +| test.rs:117:26:117:26 | 1 | test.rs:117:19:117:26 | return 1 | | | test.rs:122:1:125:1 | enter fn test_nested_function | test.rs:122:25:122:25 | n | | | test.rs:122:1:125:1 | exit fn test_nested_function (normal) | test.rs:122:1:125:1 | exit fn test_nested_function | | -| test.rs:122:25:122:25 | n | test.rs:122:25:122:30 | n: i64 | match | -| test.rs:122:25:122:30 | n: i64 | test.rs:123:5:123:28 | let add_one = ... | | +| test.rs:122:25:122:25 | n | test.rs:122:25:122:30 | ...: i64 | match | +| test.rs:122:25:122:30 | ...: i64 | test.rs:123:5:123:28 | let ... = ... | | | test.rs:122:40:125:1 | { ... } | test.rs:122:1:125:1 | exit fn test_nested_function (normal) | | -| test.rs:123:5:123:28 | let add_one = ... | test.rs:123:19:123:27 | \|...\| ... | | +| test.rs:123:5:123:28 | let ... = ... | test.rs:123:19:123:27 | \|...\| ... | | | test.rs:123:9:123:15 | add_one | test.rs:124:5:124:11 | add_one | match | | test.rs:123:19:123:27 | \|...\| ... | test.rs:123:9:123:15 | add_one | | | test.rs:123:19:123:27 | enter \|...\| ... | test.rs:123:20:123:20 | i | | | test.rs:123:19:123:27 | exit \|...\| ... (normal) | test.rs:123:19:123:27 | exit \|...\| ... | | -| test.rs:123:20:123:20 | i | test.rs:123:20:123:20 | i | match | -| test.rs:123:20:123:20 | i | test.rs:123:23:123:23 | i | | +| test.rs:123:20:123:20 | ... | test.rs:123:23:123:23 | i | | +| test.rs:123:20:123:20 | i | test.rs:123:20:123:20 | ... | match | | test.rs:123:23:123:23 | i | test.rs:123:27:123:27 | 1 | | | test.rs:123:23:123:27 | ... + ... | test.rs:123:19:123:27 | exit \|...\| ... (normal) | | | test.rs:123:27:123:27 | 1 | test.rs:123:23:123:27 | ... + ... | | @@ -253,105 +253,105 @@ edges | test.rs:124:21:124:21 | n | test.rs:124:13:124:22 | add_one(...) | | | test.rs:129:5:135:5 | enter fn test_if_else | test.rs:129:21:129:21 | n | | | test.rs:129:5:135:5 | exit fn test_if_else (normal) | test.rs:129:5:135:5 | exit fn test_if_else | | -| test.rs:129:21:129:21 | n | test.rs:129:21:129:26 | n: i64 | match | -| test.rs:129:21:129:26 | n: i64 | test.rs:130:12:130:12 | n | | +| test.rs:129:21:129:21 | n | test.rs:129:21:129:26 | ...: i64 | match | +| test.rs:129:21:129:26 | ...: i64 | test.rs:130:12:130:12 | n | | | test.rs:129:36:135:5 | { ... } | test.rs:129:5:135:5 | exit fn test_if_else (normal) | | -| test.rs:130:9:134:9 | if ... { ... } else { ... } | test.rs:129:36:135:5 | { ... } | | +| test.rs:130:9:134:9 | if ... {...} else {...} | test.rs:129:36:135:5 | { ... } | | | test.rs:130:12:130:12 | n | test.rs:130:17:130:17 | 0 | | | test.rs:130:12:130:17 | ... <= ... | test.rs:131:13:131:13 | 0 | true | | test.rs:130:12:130:17 | ... <= ... | test.rs:133:13:133:13 | n | false | | test.rs:130:17:130:17 | 0 | test.rs:130:12:130:17 | ... <= ... | | -| test.rs:130:19:132:9 | { ... } | test.rs:130:9:134:9 | if ... { ... } else { ... } | | +| test.rs:130:19:132:9 | { ... } | test.rs:130:9:134:9 | if ... {...} else {...} | | | test.rs:131:13:131:13 | 0 | test.rs:130:19:132:9 | { ... } | | -| test.rs:132:16:134:9 | { ... } | test.rs:130:9:134:9 | if ... { ... } else { ... } | | +| test.rs:132:16:134:9 | { ... } | test.rs:130:9:134:9 | if ... {...} else {...} | | | test.rs:133:13:133:13 | n | test.rs:133:17:133:17 | 1 | | | test.rs:133:13:133:17 | ... - ... | test.rs:132:16:134:9 | { ... } | | | test.rs:133:17:133:17 | 1 | test.rs:133:13:133:17 | ... - ... | | | test.rs:137:5:143:5 | enter fn test_if_let_else | test.rs:137:25:137:25 | a | | | test.rs:137:5:143:5 | exit fn test_if_let_else (normal) | test.rs:137:5:143:5 | exit fn test_if_let_else | | -| test.rs:137:25:137:25 | a | test.rs:137:25:137:38 | a: Option::<...> | match | -| test.rs:137:25:137:38 | a: Option::<...> | test.rs:138:12:138:26 | let TupleStructPat = ... | | +| test.rs:137:25:137:25 | a | test.rs:137:25:137:38 | ...: Option::<...> | match | +| test.rs:137:25:137:38 | ...: Option::<...> | test.rs:138:12:138:26 | let ... = a | | | test.rs:137:48:143:5 | { ... } | test.rs:137:5:143:5 | exit fn test_if_let_else (normal) | | -| test.rs:138:9:142:9 | if ... { ... } else { ... } | test.rs:137:48:143:5 | { ... } | | -| test.rs:138:12:138:26 | let TupleStructPat = ... | test.rs:138:26:138:26 | a | | +| test.rs:138:9:142:9 | if ... {...} else {...} | test.rs:137:48:143:5 | { ... } | | +| test.rs:138:12:138:26 | let ... = a | test.rs:138:26:138:26 | a | | | test.rs:138:16:138:22 | TupleStructPat | test.rs:138:21:138:21 | n | match | | test.rs:138:16:138:22 | TupleStructPat | test.rs:141:13:141:13 | 0 | no-match | | test.rs:138:21:138:21 | n | test.rs:139:13:139:13 | n | match | | test.rs:138:26:138:26 | a | test.rs:138:16:138:22 | TupleStructPat | | -| test.rs:138:28:140:9 | { ... } | test.rs:138:9:142:9 | if ... { ... } else { ... } | | +| test.rs:138:28:140:9 | { ... } | test.rs:138:9:142:9 | if ... {...} else {...} | | | test.rs:139:13:139:13 | n | test.rs:138:28:140:9 | { ... } | | -| test.rs:140:16:142:9 | { ... } | test.rs:138:9:142:9 | if ... { ... } else { ... } | | +| test.rs:140:16:142:9 | { ... } | test.rs:138:9:142:9 | if ... {...} else {...} | | | test.rs:141:13:141:13 | 0 | test.rs:140:16:142:9 | { ... } | | | test.rs:145:5:150:5 | enter fn test_if_let | test.rs:145:20:145:20 | a | | | test.rs:145:5:150:5 | exit fn test_if_let (normal) | test.rs:145:5:150:5 | exit fn test_if_let | | -| test.rs:145:20:145:20 | a | test.rs:145:20:145:33 | a: Option::<...> | match | -| test.rs:145:20:145:33 | a: Option::<...> | test.rs:146:9:148:9 | ExprStmt | | +| test.rs:145:20:145:20 | a | test.rs:145:20:145:33 | ...: Option::<...> | match | +| test.rs:145:20:145:33 | ...: Option::<...> | test.rs:146:9:148:9 | ExprStmt | | | test.rs:145:43:150:5 | { ... } | test.rs:145:5:150:5 | exit fn test_if_let (normal) | | -| test.rs:146:9:148:9 | ExprStmt | test.rs:146:12:146:26 | let TupleStructPat = ... | | -| test.rs:146:9:148:9 | if ... { ... } | test.rs:149:9:149:9 | 0 | | -| test.rs:146:12:146:26 | let TupleStructPat = ... | test.rs:146:26:146:26 | a | | -| test.rs:146:16:146:22 | TupleStructPat | test.rs:146:9:148:9 | if ... { ... } | no-match | +| test.rs:146:9:148:9 | ExprStmt | test.rs:146:12:146:26 | let ... = a | | +| test.rs:146:9:148:9 | if ... {...} | test.rs:149:9:149:9 | 0 | | +| test.rs:146:12:146:26 | let ... = a | test.rs:146:26:146:26 | a | | +| test.rs:146:16:146:22 | TupleStructPat | test.rs:146:9:148:9 | if ... {...} | no-match | | test.rs:146:16:146:22 | TupleStructPat | test.rs:146:21:146:21 | n | match | | test.rs:146:21:146:21 | n | test.rs:147:13:147:21 | ExprStmt | match | | test.rs:146:26:146:26 | a | test.rs:146:16:146:22 | TupleStructPat | | -| test.rs:147:13:147:20 | return ... | test.rs:145:5:150:5 | exit fn test_if_let (normal) | return | +| test.rs:147:13:147:20 | return n | test.rs:145:5:150:5 | exit fn test_if_let (normal) | return | | test.rs:147:13:147:21 | ExprStmt | test.rs:147:20:147:20 | n | | -| test.rs:147:20:147:20 | n | test.rs:147:13:147:20 | return ... | | +| test.rs:147:20:147:20 | n | test.rs:147:13:147:20 | return n | | | test.rs:149:9:149:9 | 0 | test.rs:145:43:150:5 | { ... } | | | test.rs:152:5:158:5 | enter fn test_nested_if | test.rs:152:23:152:23 | a | | | test.rs:152:5:158:5 | exit fn test_nested_if (normal) | test.rs:152:5:158:5 | exit fn test_nested_if | | -| test.rs:152:23:152:23 | a | test.rs:152:23:152:28 | a: i64 | match | -| test.rs:152:23:152:28 | a: i64 | test.rs:153:16:153:16 | a | | +| test.rs:152:23:152:23 | a | test.rs:152:23:152:28 | ...: i64 | match | +| test.rs:152:23:152:28 | ...: i64 | test.rs:153:16:153:16 | a | | | test.rs:152:38:158:5 | { ... } | test.rs:152:5:158:5 | exit fn test_nested_if (normal) | | -| test.rs:153:9:157:9 | if ... { ... } else { ... } | test.rs:152:38:158:5 | { ... } | | -| test.rs:153:13:153:48 | [boolean(false)] if ... { ... } else { ... } | test.rs:156:13:156:13 | 0 | false | -| test.rs:153:13:153:48 | [boolean(true)] if ... { ... } else { ... } | test.rs:154:13:154:13 | 1 | true | +| test.rs:153:9:157:9 | if ... {...} else {...} | test.rs:152:38:158:5 | { ... } | | +| test.rs:153:13:153:48 | [boolean(false)] if ... {...} else {...} | test.rs:156:13:156:13 | 0 | false | +| test.rs:153:13:153:48 | [boolean(true)] if ... {...} else {...} | test.rs:154:13:154:13 | 1 | true | | test.rs:153:16:153:16 | a | test.rs:153:20:153:20 | 0 | | | test.rs:153:16:153:20 | ... < ... | test.rs:153:24:153:24 | a | true | | test.rs:153:16:153:20 | ... < ... | test.rs:153:41:153:41 | a | false | | test.rs:153:20:153:20 | 0 | test.rs:153:16:153:20 | ... < ... | | -| test.rs:153:22:153:32 | [boolean(false)] { ... } | test.rs:153:13:153:48 | [boolean(false)] if ... { ... } else { ... } | false | -| test.rs:153:22:153:32 | [boolean(true)] { ... } | test.rs:153:13:153:48 | [boolean(true)] if ... { ... } else { ... } | true | +| test.rs:153:22:153:32 | [boolean(false)] { ... } | test.rs:153:13:153:48 | [boolean(false)] if ... {...} else {...} | false | +| test.rs:153:22:153:32 | [boolean(true)] { ... } | test.rs:153:13:153:48 | [boolean(true)] if ... {...} else {...} | true | | test.rs:153:24:153:24 | a | test.rs:153:29:153:30 | 10 | | | test.rs:153:24:153:30 | ... < ... | test.rs:153:22:153:32 | [boolean(false)] { ... } | false | | test.rs:153:24:153:30 | ... < ... | test.rs:153:22:153:32 | [boolean(true)] { ... } | true | | test.rs:153:28:153:30 | - ... | test.rs:153:24:153:30 | ... < ... | | | test.rs:153:29:153:30 | 10 | test.rs:153:28:153:30 | - ... | | -| test.rs:153:39:153:48 | [boolean(false)] { ... } | test.rs:153:13:153:48 | [boolean(false)] if ... { ... } else { ... } | false | -| test.rs:153:39:153:48 | [boolean(true)] { ... } | test.rs:153:13:153:48 | [boolean(true)] if ... { ... } else { ... } | true | +| test.rs:153:39:153:48 | [boolean(false)] { ... } | test.rs:153:13:153:48 | [boolean(false)] if ... {...} else {...} | false | +| test.rs:153:39:153:48 | [boolean(true)] { ... } | test.rs:153:13:153:48 | [boolean(true)] if ... {...} else {...} | true | | test.rs:153:41:153:41 | a | test.rs:153:45:153:46 | 10 | | | test.rs:153:41:153:46 | ... > ... | test.rs:153:39:153:48 | [boolean(false)] { ... } | false | | test.rs:153:41:153:46 | ... > ... | test.rs:153:39:153:48 | [boolean(true)] { ... } | true | | test.rs:153:45:153:46 | 10 | test.rs:153:41:153:46 | ... > ... | | -| test.rs:153:51:155:9 | { ... } | test.rs:153:9:157:9 | if ... { ... } else { ... } | | +| test.rs:153:51:155:9 | { ... } | test.rs:153:9:157:9 | if ... {...} else {...} | | | test.rs:154:13:154:13 | 1 | test.rs:153:51:155:9 | { ... } | | -| test.rs:155:16:157:9 | { ... } | test.rs:153:9:157:9 | if ... { ... } else { ... } | | +| test.rs:155:16:157:9 | { ... } | test.rs:153:9:157:9 | if ... {...} else {...} | | | test.rs:156:13:156:13 | 0 | test.rs:155:16:157:9 | { ... } | | | test.rs:160:5:169:5 | enter fn test_nested_if_match | test.rs:160:29:160:29 | a | | | test.rs:160:5:169:5 | exit fn test_nested_if_match (normal) | test.rs:160:5:169:5 | exit fn test_nested_if_match | | -| test.rs:160:29:160:29 | a | test.rs:160:29:160:34 | a: i64 | match | -| test.rs:160:29:160:34 | a: i64 | test.rs:161:19:161:19 | a | | +| test.rs:160:29:160:29 | a | test.rs:160:29:160:34 | ...: i64 | match | +| test.rs:160:29:160:34 | ...: i64 | test.rs:161:19:161:19 | a | | | test.rs:160:44:169:5 | { ... } | test.rs:160:5:169:5 | exit fn test_nested_if_match (normal) | | -| test.rs:161:9:168:9 | if ... { ... } else { ... } | test.rs:160:44:169:5 | { ... } | | -| test.rs:161:13:164:9 | [boolean(false)] match ... { ... } | test.rs:167:13:167:13 | 0 | false | -| test.rs:161:13:164:9 | [boolean(true)] match ... { ... } | test.rs:165:13:165:13 | 1 | true | +| test.rs:161:9:168:9 | if ... {...} else {...} | test.rs:160:44:169:5 | { ... } | | +| test.rs:161:13:164:9 | [boolean(false)] match a { ... } | test.rs:167:13:167:13 | 0 | false | +| test.rs:161:13:164:9 | [boolean(true)] match a { ... } | test.rs:165:13:165:13 | 1 | true | | test.rs:161:19:161:19 | a | test.rs:162:13:162:13 | 0 | | | test.rs:162:13:162:13 | 0 | test.rs:162:13:162:13 | 0 | | | test.rs:162:13:162:13 | 0 | test.rs:162:18:162:21 | true | match | | test.rs:162:13:162:13 | 0 | test.rs:163:13:163:13 | _ | no-match | -| test.rs:162:18:162:21 | true | test.rs:161:13:164:9 | [boolean(true)] match ... { ... } | true | +| test.rs:162:18:162:21 | true | test.rs:161:13:164:9 | [boolean(true)] match a { ... } | true | | test.rs:163:13:163:13 | _ | test.rs:163:18:163:22 | false | match | -| test.rs:163:18:163:22 | false | test.rs:161:13:164:9 | [boolean(false)] match ... { ... } | false | -| test.rs:164:12:166:9 | { ... } | test.rs:161:9:168:9 | if ... { ... } else { ... } | | +| test.rs:163:18:163:22 | false | test.rs:161:13:164:9 | [boolean(false)] match a { ... } | false | +| test.rs:164:12:166:9 | { ... } | test.rs:161:9:168:9 | if ... {...} else {...} | | | test.rs:165:13:165:13 | 1 | test.rs:164:12:166:9 | { ... } | | -| test.rs:166:16:168:9 | { ... } | test.rs:161:9:168:9 | if ... { ... } else { ... } | | +| test.rs:166:16:168:9 | { ... } | test.rs:161:9:168:9 | if ... {...} else {...} | | | test.rs:167:13:167:13 | 0 | test.rs:166:16:168:9 | { ... } | | | test.rs:171:5:180:5 | enter fn test_nested_if_block | test.rs:171:29:171:29 | a | | | test.rs:171:5:180:5 | exit fn test_nested_if_block (normal) | test.rs:171:5:180:5 | exit fn test_nested_if_block | | -| test.rs:171:29:171:29 | a | test.rs:171:29:171:34 | a: i64 | match | -| test.rs:171:29:171:34 | a: i64 | test.rs:173:13:173:15 | ExprStmt | | +| test.rs:171:29:171:29 | a | test.rs:171:29:171:34 | ...: i64 | match | +| test.rs:171:29:171:34 | ...: i64 | test.rs:173:13:173:15 | ExprStmt | | | test.rs:171:44:180:5 | { ... } | test.rs:171:5:180:5 | exit fn test_nested_if_block (normal) | | -| test.rs:172:9:179:9 | if ... { ... } else { ... } | test.rs:171:44:180:5 | { ... } | | +| test.rs:172:9:179:9 | if ... {...} else {...} | test.rs:171:44:180:5 | { ... } | | | test.rs:172:12:175:9 | [boolean(false)] { ... } | test.rs:178:13:178:13 | 0 | false | | test.rs:172:12:175:9 | [boolean(true)] { ... } | test.rs:176:13:176:13 | 1 | true | | test.rs:173:13:173:14 | TupleExpr | test.rs:174:13:174:13 | a | | @@ -360,19 +360,19 @@ edges | test.rs:174:13:174:17 | ... > ... | test.rs:172:12:175:9 | [boolean(false)] { ... } | false | | test.rs:174:13:174:17 | ... > ... | test.rs:172:12:175:9 | [boolean(true)] { ... } | true | | test.rs:174:17:174:17 | 0 | test.rs:174:13:174:17 | ... > ... | | -| test.rs:175:11:177:9 | { ... } | test.rs:172:9:179:9 | if ... { ... } else { ... } | | +| test.rs:175:11:177:9 | { ... } | test.rs:172:9:179:9 | if ... {...} else {...} | | | test.rs:176:13:176:13 | 1 | test.rs:175:11:177:9 | { ... } | | -| test.rs:177:16:179:9 | { ... } | test.rs:172:9:179:9 | if ... { ... } else { ... } | | +| test.rs:177:16:179:9 | { ... } | test.rs:172:9:179:9 | if ... {...} else {...} | | | test.rs:178:13:178:13 | 0 | test.rs:177:16:179:9 | { ... } | | | test.rs:182:5:192:5 | enter fn test_if_assignment | test.rs:182:27:182:27 | a | | | test.rs:182:5:192:5 | exit fn test_if_assignment (normal) | test.rs:182:5:192:5 | exit fn test_if_assignment | | -| test.rs:182:27:182:27 | a | test.rs:182:27:182:32 | a: i64 | match | -| test.rs:182:27:182:32 | a: i64 | test.rs:183:9:183:26 | let x = ... | | +| test.rs:182:27:182:27 | a | test.rs:182:27:182:32 | ...: i64 | match | +| test.rs:182:27:182:32 | ...: i64 | test.rs:183:9:183:26 | let ... = false | | | test.rs:182:42:192:5 | { ... } | test.rs:182:5:192:5 | exit fn test_if_assignment (normal) | | -| test.rs:183:9:183:26 | let x = ... | test.rs:183:21:183:25 | false | | +| test.rs:183:9:183:26 | let ... = false | test.rs:183:21:183:25 | false | | | test.rs:183:13:183:17 | x | test.rs:185:13:185:21 | ExprStmt | match | | test.rs:183:21:183:25 | false | test.rs:183:13:183:17 | x | | -| test.rs:184:9:191:9 | if ... { ... } else { ... } | test.rs:182:42:192:5 | { ... } | | +| test.rs:184:9:191:9 | if ... {...} else {...} | test.rs:182:42:192:5 | { ... } | | | test.rs:184:12:187:9 | [boolean(false)] { ... } | test.rs:190:13:190:13 | 0 | false | | test.rs:184:12:187:9 | [boolean(true)] { ... } | test.rs:188:13:188:13 | 1 | true | | test.rs:185:13:185:13 | x | test.rs:185:17:185:20 | true | | @@ -381,27 +381,27 @@ edges | test.rs:185:17:185:20 | true | test.rs:185:13:185:20 | ... = ... | | | test.rs:186:13:186:13 | x | test.rs:184:12:187:9 | [boolean(false)] { ... } | false | | test.rs:186:13:186:13 | x | test.rs:184:12:187:9 | [boolean(true)] { ... } | true | -| test.rs:187:11:189:9 | { ... } | test.rs:184:9:191:9 | if ... { ... } else { ... } | | +| test.rs:187:11:189:9 | { ... } | test.rs:184:9:191:9 | if ... {...} else {...} | | | test.rs:188:13:188:13 | 1 | test.rs:187:11:189:9 | { ... } | | -| test.rs:189:16:191:9 | { ... } | test.rs:184:9:191:9 | if ... { ... } else { ... } | | +| test.rs:189:16:191:9 | { ... } | test.rs:184:9:191:9 | if ... {...} else {...} | | | test.rs:190:13:190:13 | 0 | test.rs:189:16:191:9 | { ... } | | | test.rs:194:5:205:5 | enter fn test_if_loop1 | test.rs:194:22:194:22 | a | | | test.rs:194:5:205:5 | exit fn test_if_loop1 (normal) | test.rs:194:5:205:5 | exit fn test_if_loop1 | | -| test.rs:194:22:194:22 | a | test.rs:194:22:194:27 | a: i64 | match | -| test.rs:194:22:194:27 | a: i64 | test.rs:196:13:198:14 | ExprStmt | | +| test.rs:194:22:194:22 | a | test.rs:194:22:194:27 | ...: i64 | match | +| test.rs:194:22:194:27 | ...: i64 | test.rs:196:13:198:14 | ExprStmt | | | test.rs:194:37:205:5 | { ... } | test.rs:194:5:205:5 | exit fn test_if_loop1 (normal) | | -| test.rs:195:9:204:9 | if ... { ... } else { ... } | test.rs:194:37:205:5 | { ... } | | -| test.rs:195:13:200:9 | [boolean(false)] loop {...} | test.rs:203:13:203:13 | 0 | false | -| test.rs:195:13:200:9 | [boolean(true)] loop {...} | test.rs:201:13:201:13 | 1 | true | +| test.rs:195:9:204:9 | if ... {...} else {...} | test.rs:194:37:205:5 | { ... } | | +| test.rs:195:13:200:9 | [boolean(false)] loop { ... } | test.rs:203:13:203:13 | 0 | false | +| test.rs:195:13:200:9 | [boolean(true)] loop { ... } | test.rs:201:13:201:13 | 1 | true | | test.rs:195:18:200:9 | { ... } | test.rs:196:13:198:14 | ExprStmt | | -| test.rs:196:13:198:13 | if ... { ... } | test.rs:199:13:199:19 | ExprStmt | | +| test.rs:196:13:198:13 | if ... {...} | test.rs:199:13:199:19 | ExprStmt | | | test.rs:196:13:198:14 | ExprStmt | test.rs:196:16:196:16 | a | | | test.rs:196:16:196:16 | a | test.rs:196:20:196:20 | 0 | | -| test.rs:196:16:196:20 | ... > ... | test.rs:196:13:198:13 | if ... { ... } | false | +| test.rs:196:16:196:20 | ... > ... | test.rs:196:13:198:13 | if ... {...} | false | | test.rs:196:16:196:20 | ... > ... | test.rs:197:17:197:29 | ExprStmt | true | | test.rs:196:20:196:20 | 0 | test.rs:196:16:196:20 | ... > ... | | -| test.rs:197:17:197:28 | [boolean(false)] break ... | test.rs:195:13:200:9 | [boolean(false)] loop {...} | break | -| test.rs:197:17:197:28 | [boolean(true)] break ... | test.rs:195:13:200:9 | [boolean(true)] loop {...} | break | +| test.rs:197:17:197:28 | [boolean(false)] break ... | test.rs:195:13:200:9 | [boolean(false)] loop { ... } | break | +| test.rs:197:17:197:28 | [boolean(true)] break ... | test.rs:195:13:200:9 | [boolean(true)] loop { ... } | break | | test.rs:197:17:197:29 | ExprStmt | test.rs:197:23:197:23 | a | | | test.rs:197:23:197:23 | a | test.rs:197:27:197:28 | 10 | | | test.rs:197:23:197:28 | ... > ... | test.rs:197:17:197:28 | [boolean(false)] break ... | false | @@ -411,27 +411,27 @@ edges | test.rs:199:13:199:18 | ... < ... | test.rs:195:18:200:9 | { ... } | | | test.rs:199:13:199:19 | ExprStmt | test.rs:199:13:199:13 | a | | | test.rs:199:17:199:18 | 10 | test.rs:199:13:199:18 | ... < ... | | -| test.rs:200:12:202:9 | { ... } | test.rs:195:9:204:9 | if ... { ... } else { ... } | | +| test.rs:200:12:202:9 | { ... } | test.rs:195:9:204:9 | if ... {...} else {...} | | | test.rs:201:13:201:13 | 1 | test.rs:200:12:202:9 | { ... } | | -| test.rs:202:16:204:9 | { ... } | test.rs:195:9:204:9 | if ... { ... } else { ... } | | +| test.rs:202:16:204:9 | { ... } | test.rs:195:9:204:9 | if ... {...} else {...} | | | test.rs:203:13:203:13 | 0 | test.rs:202:16:204:9 | { ... } | | | test.rs:207:5:218:5 | enter fn test_if_loop2 | test.rs:207:22:207:22 | a | | | test.rs:207:5:218:5 | exit fn test_if_loop2 (normal) | test.rs:207:5:218:5 | exit fn test_if_loop2 | | -| test.rs:207:22:207:22 | a | test.rs:207:22:207:27 | a: i64 | match | -| test.rs:207:22:207:27 | a: i64 | test.rs:209:13:211:14 | ExprStmt | | +| test.rs:207:22:207:22 | a | test.rs:207:22:207:27 | ...: i64 | match | +| test.rs:207:22:207:27 | ...: i64 | test.rs:209:13:211:14 | ExprStmt | | | test.rs:207:37:218:5 | { ... } | test.rs:207:5:218:5 | exit fn test_if_loop2 (normal) | | -| test.rs:208:9:217:9 | if ... { ... } else { ... } | test.rs:207:37:218:5 | { ... } | | -| test.rs:208:13:213:9 | [boolean(false)] loop {...} | test.rs:216:13:216:13 | 0 | false | -| test.rs:208:13:213:9 | [boolean(true)] loop {...} | test.rs:214:13:214:13 | 1 | true | +| test.rs:208:9:217:9 | if ... {...} else {...} | test.rs:207:37:218:5 | { ... } | | +| test.rs:208:13:213:9 | [boolean(false)] ''label: loop { ... } | test.rs:216:13:216:13 | 0 | false | +| test.rs:208:13:213:9 | [boolean(true)] ''label: loop { ... } | test.rs:214:13:214:13 | 1 | true | | test.rs:208:26:213:9 | { ... } | test.rs:209:13:211:14 | ExprStmt | | -| test.rs:209:13:211:13 | if ... { ... } | test.rs:212:13:212:19 | ExprStmt | | +| test.rs:209:13:211:13 | if ... {...} | test.rs:212:13:212:19 | ExprStmt | | | test.rs:209:13:211:14 | ExprStmt | test.rs:209:16:209:16 | a | | | test.rs:209:16:209:16 | a | test.rs:209:20:209:20 | 0 | | -| test.rs:209:16:209:20 | ... > ... | test.rs:209:13:211:13 | if ... { ... } | false | +| test.rs:209:16:209:20 | ... > ... | test.rs:209:13:211:13 | if ... {...} | false | | test.rs:209:16:209:20 | ... > ... | test.rs:210:17:210:36 | ExprStmt | true | | test.rs:209:20:209:20 | 0 | test.rs:209:16:209:20 | ... > ... | | -| test.rs:210:17:210:35 | [boolean(false)] break ''label ... | test.rs:208:13:213:9 | [boolean(false)] loop {...} | break | -| test.rs:210:17:210:35 | [boolean(true)] break ''label ... | test.rs:208:13:213:9 | [boolean(true)] loop {...} | break | +| test.rs:210:17:210:35 | [boolean(false)] break ''label ... | test.rs:208:13:213:9 | [boolean(false)] ''label: loop { ... } | break | +| test.rs:210:17:210:35 | [boolean(true)] break ''label ... | test.rs:208:13:213:9 | [boolean(true)] ''label: loop { ... } | break | | test.rs:210:17:210:36 | ExprStmt | test.rs:210:30:210:30 | a | | | test.rs:210:30:210:30 | a | test.rs:210:34:210:35 | 10 | | | test.rs:210:30:210:35 | ... > ... | test.rs:210:17:210:35 | [boolean(false)] break ''label ... | false | @@ -441,39 +441,39 @@ edges | test.rs:212:13:212:18 | ... < ... | test.rs:208:26:213:9 | { ... } | | | test.rs:212:13:212:19 | ExprStmt | test.rs:212:13:212:13 | a | | | test.rs:212:17:212:18 | 10 | test.rs:212:13:212:18 | ... < ... | | -| test.rs:213:12:215:9 | { ... } | test.rs:208:9:217:9 | if ... { ... } else { ... } | | +| test.rs:213:12:215:9 | { ... } | test.rs:208:9:217:9 | if ... {...} else {...} | | | test.rs:214:13:214:13 | 1 | test.rs:213:12:215:9 | { ... } | | -| test.rs:215:16:217:9 | { ... } | test.rs:208:9:217:9 | if ... { ... } else { ... } | | +| test.rs:215:16:217:9 | { ... } | test.rs:208:9:217:9 | if ... {...} else {...} | | | test.rs:216:13:216:13 | 0 | test.rs:215:16:217:9 | { ... } | | | test.rs:220:5:228:5 | enter fn test_labelled_block | test.rs:220:28:220:28 | a | | | test.rs:220:5:228:5 | exit fn test_labelled_block (normal) | test.rs:220:5:228:5 | exit fn test_labelled_block | | -| test.rs:220:28:220:28 | a | test.rs:220:28:220:33 | a: i64 | match | -| test.rs:220:28:220:33 | a: i64 | test.rs:222:13:222:31 | ExprStmt | | +| test.rs:220:28:220:28 | a | test.rs:220:28:220:33 | ...: i64 | match | +| test.rs:220:28:220:33 | ...: i64 | test.rs:222:13:222:31 | ExprStmt | | | test.rs:220:43:228:5 | { ... } | test.rs:220:5:228:5 | exit fn test_labelled_block (normal) | | -| test.rs:221:9:227:9 | if ... { ... } else { ... } | test.rs:220:43:228:5 | { ... } | | -| test.rs:221:13:223:9 | [boolean(false)] { ... } | test.rs:226:13:226:13 | 0 | false | -| test.rs:221:13:223:9 | [boolean(true)] { ... } | test.rs:224:13:224:13 | 1 | true | -| test.rs:222:13:222:30 | [boolean(false)] break ''block ... | test.rs:221:13:223:9 | [boolean(false)] { ... } | break | -| test.rs:222:13:222:30 | [boolean(true)] break ''block ... | test.rs:221:13:223:9 | [boolean(true)] { ... } | break | +| test.rs:221:9:227:9 | if ... {...} else {...} | test.rs:220:43:228:5 | { ... } | | +| test.rs:221:13:223:9 | [boolean(false)] ''block: { ... } | test.rs:226:13:226:13 | 0 | false | +| test.rs:221:13:223:9 | [boolean(true)] ''block: { ... } | test.rs:224:13:224:13 | 1 | true | +| test.rs:222:13:222:30 | [boolean(false)] break ''block ... | test.rs:221:13:223:9 | [boolean(false)] ''block: { ... } | break | +| test.rs:222:13:222:30 | [boolean(true)] break ''block ... | test.rs:221:13:223:9 | [boolean(true)] ''block: { ... } | break | | test.rs:222:13:222:31 | ExprStmt | test.rs:222:26:222:26 | a | | | test.rs:222:26:222:26 | a | test.rs:222:30:222:30 | 0 | | | test.rs:222:26:222:30 | ... > ... | test.rs:222:13:222:30 | [boolean(false)] break ''block ... | false | | test.rs:222:26:222:30 | ... > ... | test.rs:222:13:222:30 | [boolean(true)] break ''block ... | true | | test.rs:222:30:222:30 | 0 | test.rs:222:26:222:30 | ... > ... | | -| test.rs:223:12:225:9 | { ... } | test.rs:221:9:227:9 | if ... { ... } else { ... } | | +| test.rs:223:12:225:9 | { ... } | test.rs:221:9:227:9 | if ... {...} else {...} | | | test.rs:224:13:224:13 | 1 | test.rs:223:12:225:9 | { ... } | | -| test.rs:225:16:227:9 | { ... } | test.rs:221:9:227:9 | if ... { ... } else { ... } | | +| test.rs:225:16:227:9 | { ... } | test.rs:221:9:227:9 | if ... {...} else {...} | | | test.rs:226:13:226:13 | 0 | test.rs:225:16:227:9 | { ... } | | | test.rs:233:5:236:5 | enter fn test_and_operator | test.rs:233:30:233:30 | a | | | test.rs:233:5:236:5 | exit fn test_and_operator (normal) | test.rs:233:5:236:5 | exit fn test_and_operator | | -| test.rs:233:30:233:30 | a | test.rs:233:30:233:36 | a: bool | match | -| test.rs:233:30:233:36 | a: bool | test.rs:233:39:233:39 | b | | -| test.rs:233:39:233:39 | b | test.rs:233:39:233:45 | b: bool | match | -| test.rs:233:39:233:45 | b: bool | test.rs:233:48:233:48 | c | | -| test.rs:233:48:233:48 | c | test.rs:233:48:233:54 | c: bool | match | -| test.rs:233:48:233:54 | c: bool | test.rs:234:9:234:28 | let d = ... | | +| test.rs:233:30:233:30 | a | test.rs:233:30:233:36 | ...: bool | match | +| test.rs:233:30:233:36 | ...: bool | test.rs:233:39:233:39 | b | | +| test.rs:233:39:233:39 | b | test.rs:233:39:233:45 | ...: bool | match | +| test.rs:233:39:233:45 | ...: bool | test.rs:233:48:233:48 | c | | +| test.rs:233:48:233:48 | c | test.rs:233:48:233:54 | ...: bool | match | +| test.rs:233:48:233:54 | ...: bool | test.rs:234:9:234:28 | let ... = ... | | | test.rs:233:65:236:5 | { ... } | test.rs:233:5:236:5 | exit fn test_and_operator (normal) | | -| test.rs:234:9:234:28 | let d = ... | test.rs:234:17:234:17 | a | | +| test.rs:234:9:234:28 | let ... = ... | test.rs:234:17:234:17 | a | | | test.rs:234:13:234:13 | d | test.rs:235:9:235:9 | d | match | | test.rs:234:17:234:17 | a | test.rs:234:17:234:22 | [boolean(false)] ... && ... | false | | test.rs:234:17:234:17 | a | test.rs:234:22:234:22 | b | true | @@ -486,14 +486,14 @@ edges | test.rs:235:9:235:9 | d | test.rs:233:65:236:5 | { ... } | | | test.rs:238:5:241:5 | enter fn test_or_operator | test.rs:238:25:238:25 | a | | | test.rs:238:5:241:5 | exit fn test_or_operator (normal) | test.rs:238:5:241:5 | exit fn test_or_operator | | -| test.rs:238:25:238:25 | a | test.rs:238:25:238:31 | a: bool | match | -| test.rs:238:25:238:31 | a: bool | test.rs:238:34:238:34 | b | | -| test.rs:238:34:238:34 | b | test.rs:238:34:238:40 | b: bool | match | -| test.rs:238:34:238:40 | b: bool | test.rs:238:43:238:43 | c | | -| test.rs:238:43:238:43 | c | test.rs:238:43:238:49 | c: bool | match | -| test.rs:238:43:238:49 | c: bool | test.rs:239:9:239:28 | let d = ... | | +| test.rs:238:25:238:25 | a | test.rs:238:25:238:31 | ...: bool | match | +| test.rs:238:25:238:31 | ...: bool | test.rs:238:34:238:34 | b | | +| test.rs:238:34:238:34 | b | test.rs:238:34:238:40 | ...: bool | match | +| test.rs:238:34:238:40 | ...: bool | test.rs:238:43:238:43 | c | | +| test.rs:238:43:238:43 | c | test.rs:238:43:238:49 | ...: bool | match | +| test.rs:238:43:238:49 | ...: bool | test.rs:239:9:239:28 | let ... = ... | | | test.rs:238:60:241:5 | { ... } | test.rs:238:5:241:5 | exit fn test_or_operator (normal) | | -| test.rs:239:9:239:28 | let d = ... | test.rs:239:17:239:17 | a | | +| test.rs:239:9:239:28 | let ... = ... | test.rs:239:17:239:17 | a | | | test.rs:239:13:239:13 | d | test.rs:240:9:240:9 | d | match | | test.rs:239:17:239:17 | a | test.rs:239:17:239:22 | [boolean(true)] ... \|\| ... | true | | test.rs:239:17:239:17 | a | test.rs:239:22:239:22 | b | false | @@ -506,14 +506,14 @@ edges | test.rs:240:9:240:9 | d | test.rs:238:60:241:5 | { ... } | | | test.rs:243:5:246:5 | enter fn test_or_operator_2 | test.rs:243:27:243:27 | a | | | test.rs:243:5:246:5 | exit fn test_or_operator_2 (normal) | test.rs:243:5:246:5 | exit fn test_or_operator_2 | | -| test.rs:243:27:243:27 | a | test.rs:243:27:243:33 | a: bool | match | -| test.rs:243:27:243:33 | a: bool | test.rs:243:36:243:36 | b | | -| test.rs:243:36:243:36 | b | test.rs:243:36:243:41 | b: i64 | match | -| test.rs:243:36:243:41 | b: i64 | test.rs:243:44:243:44 | c | | -| test.rs:243:44:243:44 | c | test.rs:243:44:243:50 | c: bool | match | -| test.rs:243:44:243:50 | c: bool | test.rs:244:9:244:36 | let d = ... | | +| test.rs:243:27:243:27 | a | test.rs:243:27:243:33 | ...: bool | match | +| test.rs:243:27:243:33 | ...: bool | test.rs:243:36:243:36 | b | | +| test.rs:243:36:243:36 | b | test.rs:243:36:243:41 | ...: i64 | match | +| test.rs:243:36:243:41 | ...: i64 | test.rs:243:44:243:44 | c | | +| test.rs:243:44:243:44 | c | test.rs:243:44:243:50 | ...: bool | match | +| test.rs:243:44:243:50 | ...: bool | test.rs:244:9:244:36 | let ... = ... | | | test.rs:243:61:246:5 | { ... } | test.rs:243:5:246:5 | exit fn test_or_operator_2 (normal) | | -| test.rs:244:9:244:36 | let d = ... | test.rs:244:17:244:17 | a | | +| test.rs:244:9:244:36 | let ... = ... | test.rs:244:17:244:17 | a | | | test.rs:244:13:244:13 | d | test.rs:245:9:245:9 | d | match | | test.rs:244:17:244:17 | a | test.rs:244:17:244:30 | [boolean(true)] ... \|\| ... | true | | test.rs:244:17:244:17 | a | test.rs:244:23:244:23 | b | false | @@ -528,24 +528,24 @@ edges | test.rs:245:9:245:9 | d | test.rs:243:61:246:5 | { ... } | | | test.rs:248:5:251:5 | enter fn test_not_operator | test.rs:248:26:248:26 | a | | | test.rs:248:5:251:5 | exit fn test_not_operator (normal) | test.rs:248:5:251:5 | exit fn test_not_operator | | -| test.rs:248:26:248:26 | a | test.rs:248:26:248:32 | a: bool | match | -| test.rs:248:26:248:32 | a: bool | test.rs:249:9:249:19 | let d = ... | | +| test.rs:248:26:248:26 | a | test.rs:248:26:248:32 | ...: bool | match | +| test.rs:248:26:248:32 | ...: bool | test.rs:249:9:249:19 | let ... = ... | | | test.rs:248:43:251:5 | { ... } | test.rs:248:5:251:5 | exit fn test_not_operator (normal) | | -| test.rs:249:9:249:19 | let d = ... | test.rs:249:18:249:18 | a | | +| test.rs:249:9:249:19 | let ... = ... | test.rs:249:18:249:18 | a | | | test.rs:249:13:249:13 | d | test.rs:250:9:250:9 | d | match | | test.rs:249:17:249:18 | ! ... | test.rs:249:13:249:13 | d | | | test.rs:249:18:249:18 | a | test.rs:249:17:249:18 | ! ... | | | test.rs:250:9:250:9 | d | test.rs:248:43:251:5 | { ... } | | | test.rs:253:5:259:5 | enter fn test_if_and_operator | test.rs:253:29:253:29 | a | | | test.rs:253:5:259:5 | exit fn test_if_and_operator (normal) | test.rs:253:5:259:5 | exit fn test_if_and_operator | | -| test.rs:253:29:253:29 | a | test.rs:253:29:253:35 | a: bool | match | -| test.rs:253:29:253:35 | a: bool | test.rs:253:38:253:38 | b | | -| test.rs:253:38:253:38 | b | test.rs:253:38:253:44 | b: bool | match | -| test.rs:253:38:253:44 | b: bool | test.rs:253:47:253:47 | c | | -| test.rs:253:47:253:47 | c | test.rs:253:47:253:53 | c: bool | match | -| test.rs:253:47:253:53 | c: bool | test.rs:254:12:254:12 | a | | +| test.rs:253:29:253:29 | a | test.rs:253:29:253:35 | ...: bool | match | +| test.rs:253:29:253:35 | ...: bool | test.rs:253:38:253:38 | b | | +| test.rs:253:38:253:38 | b | test.rs:253:38:253:44 | ...: bool | match | +| test.rs:253:38:253:44 | ...: bool | test.rs:253:47:253:47 | c | | +| test.rs:253:47:253:47 | c | test.rs:253:47:253:53 | ...: bool | match | +| test.rs:253:47:253:53 | ...: bool | test.rs:254:12:254:12 | a | | | test.rs:253:64:259:5 | { ... } | test.rs:253:5:259:5 | exit fn test_if_and_operator (normal) | | -| test.rs:254:9:258:9 | if ... { ... } else { ... } | test.rs:253:64:259:5 | { ... } | | +| test.rs:254:9:258:9 | if ... {...} else {...} | test.rs:253:64:259:5 | { ... } | | | test.rs:254:12:254:12 | a | test.rs:254:12:254:17 | [boolean(false)] ... && ... | false | | test.rs:254:12:254:12 | a | test.rs:254:17:254:17 | b | true | | test.rs:254:12:254:17 | [boolean(false)] ... && ... | test.rs:254:12:254:22 | [boolean(false)] ... && ... | false | @@ -556,20 +556,20 @@ edges | test.rs:254:17:254:17 | b | test.rs:254:12:254:17 | [boolean(true)] ... && ... | true | | test.rs:254:22:254:22 | c | test.rs:254:12:254:22 | [boolean(false)] ... && ... | false | | test.rs:254:22:254:22 | c | test.rs:254:12:254:22 | [boolean(true)] ... && ... | true | -| test.rs:254:24:256:9 | { ... } | test.rs:254:9:258:9 | if ... { ... } else { ... } | | +| test.rs:254:24:256:9 | { ... } | test.rs:254:9:258:9 | if ... {...} else {...} | | | test.rs:255:13:255:16 | true | test.rs:254:24:256:9 | { ... } | | -| test.rs:256:16:258:9 | { ... } | test.rs:254:9:258:9 | if ... { ... } else { ... } | | +| test.rs:256:16:258:9 | { ... } | test.rs:254:9:258:9 | if ... {...} else {...} | | | test.rs:257:13:257:17 | false | test.rs:256:16:258:9 | { ... } | | | test.rs:261:5:267:5 | enter fn test_if_or_operator | test.rs:261:28:261:28 | a | | | test.rs:261:5:267:5 | exit fn test_if_or_operator (normal) | test.rs:261:5:267:5 | exit fn test_if_or_operator | | -| test.rs:261:28:261:28 | a | test.rs:261:28:261:34 | a: bool | match | -| test.rs:261:28:261:34 | a: bool | test.rs:261:37:261:37 | b | | -| test.rs:261:37:261:37 | b | test.rs:261:37:261:43 | b: bool | match | -| test.rs:261:37:261:43 | b: bool | test.rs:261:46:261:46 | c | | -| test.rs:261:46:261:46 | c | test.rs:261:46:261:52 | c: bool | match | -| test.rs:261:46:261:52 | c: bool | test.rs:262:12:262:12 | a | | +| test.rs:261:28:261:28 | a | test.rs:261:28:261:34 | ...: bool | match | +| test.rs:261:28:261:34 | ...: bool | test.rs:261:37:261:37 | b | | +| test.rs:261:37:261:37 | b | test.rs:261:37:261:43 | ...: bool | match | +| test.rs:261:37:261:43 | ...: bool | test.rs:261:46:261:46 | c | | +| test.rs:261:46:261:46 | c | test.rs:261:46:261:52 | ...: bool | match | +| test.rs:261:46:261:52 | ...: bool | test.rs:262:12:262:12 | a | | | test.rs:261:63:267:5 | { ... } | test.rs:261:5:267:5 | exit fn test_if_or_operator (normal) | | -| test.rs:262:9:266:9 | if ... { ... } else { ... } | test.rs:261:63:267:5 | { ... } | | +| test.rs:262:9:266:9 | if ... {...} else {...} | test.rs:261:63:267:5 | { ... } | | | test.rs:262:12:262:12 | a | test.rs:262:12:262:17 | [boolean(true)] ... \|\| ... | true | | test.rs:262:12:262:12 | a | test.rs:262:17:262:17 | b | false | | test.rs:262:12:262:17 | [boolean(false)] ... \|\| ... | test.rs:262:22:262:22 | c | false | @@ -580,28 +580,28 @@ edges | test.rs:262:17:262:17 | b | test.rs:262:12:262:17 | [boolean(true)] ... \|\| ... | true | | test.rs:262:22:262:22 | c | test.rs:262:12:262:22 | [boolean(false)] ... \|\| ... | false | | test.rs:262:22:262:22 | c | test.rs:262:12:262:22 | [boolean(true)] ... \|\| ... | true | -| test.rs:262:24:264:9 | { ... } | test.rs:262:9:266:9 | if ... { ... } else { ... } | | +| test.rs:262:24:264:9 | { ... } | test.rs:262:9:266:9 | if ... {...} else {...} | | | test.rs:263:13:263:16 | true | test.rs:262:24:264:9 | { ... } | | -| test.rs:264:16:266:9 | { ... } | test.rs:262:9:266:9 | if ... { ... } else { ... } | | +| test.rs:264:16:266:9 | { ... } | test.rs:262:9:266:9 | if ... {...} else {...} | | | test.rs:265:13:265:17 | false | test.rs:264:16:266:9 | { ... } | | | test.rs:269:5:275:5 | enter fn test_if_not_operator | test.rs:269:29:269:29 | a | | | test.rs:269:5:275:5 | exit fn test_if_not_operator (normal) | test.rs:269:5:275:5 | exit fn test_if_not_operator | | -| test.rs:269:29:269:29 | a | test.rs:269:29:269:35 | a: bool | match | -| test.rs:269:29:269:35 | a: bool | test.rs:270:13:270:13 | a | | +| test.rs:269:29:269:29 | a | test.rs:269:29:269:35 | ...: bool | match | +| test.rs:269:29:269:35 | ...: bool | test.rs:270:13:270:13 | a | | | test.rs:269:46:275:5 | { ... } | test.rs:269:5:275:5 | exit fn test_if_not_operator (normal) | | -| test.rs:270:9:274:9 | if ... { ... } else { ... } | test.rs:269:46:275:5 | { ... } | | +| test.rs:270:9:274:9 | if ... {...} else {...} | test.rs:269:46:275:5 | { ... } | | | test.rs:270:12:270:13 | [boolean(false)] ! ... | test.rs:273:13:273:17 | false | false | | test.rs:270:12:270:13 | [boolean(true)] ! ... | test.rs:271:13:271:16 | true | true | | test.rs:270:13:270:13 | a | test.rs:270:12:270:13 | [boolean(false)] ! ... | true | | test.rs:270:13:270:13 | a | test.rs:270:12:270:13 | [boolean(true)] ! ... | false | -| test.rs:270:15:272:9 | { ... } | test.rs:270:9:274:9 | if ... { ... } else { ... } | | +| test.rs:270:15:272:9 | { ... } | test.rs:270:9:274:9 | if ... {...} else {...} | | | test.rs:271:13:271:16 | true | test.rs:270:15:272:9 | { ... } | | -| test.rs:272:16:274:9 | { ... } | test.rs:270:9:274:9 | if ... { ... } else { ... } | | +| test.rs:272:16:274:9 | { ... } | test.rs:270:9:274:9 | if ... {...} else {...} | | | test.rs:273:13:273:17 | false | test.rs:272:16:274:9 | { ... } | | | test.rs:277:5:279:5 | enter fn test_and_return | test.rs:277:24:277:24 | a | | | test.rs:277:5:279:5 | exit fn test_and_return (normal) | test.rs:277:5:279:5 | exit fn test_and_return | | -| test.rs:277:24:277:24 | a | test.rs:277:24:277:30 | a: bool | match | -| test.rs:277:24:277:30 | a: bool | test.rs:278:9:278:20 | ExprStmt | | +| test.rs:277:24:277:24 | a | test.rs:277:24:277:30 | ...: bool | match | +| test.rs:277:24:277:30 | ...: bool | test.rs:278:9:278:20 | ExprStmt | | | test.rs:277:33:279:5 | { ... } | test.rs:277:5:279:5 | exit fn test_and_return (normal) | | | test.rs:278:9:278:9 | a | test.rs:278:9:278:19 | ... && ... | false | | test.rs:278:9:278:9 | a | test.rs:278:14:278:19 | return | true | @@ -610,8 +610,8 @@ edges | test.rs:278:14:278:19 | return | test.rs:277:5:279:5 | exit fn test_and_return (normal) | return | | test.rs:285:5:287:5 | enter fn test_question_mark_operator_1 | test.rs:285:38:285:38 | s | | | test.rs:285:5:287:5 | exit fn test_question_mark_operator_1 (normal) | test.rs:285:5:287:5 | exit fn test_question_mark_operator_1 | | -| test.rs:285:38:285:38 | s | test.rs:285:38:285:44 | s: RefType | match | -| test.rs:285:38:285:44 | s: RefType | test.rs:286:9:286:10 | Ok | | +| test.rs:285:38:285:38 | s | test.rs:285:38:285:44 | ...: ... | match | +| test.rs:285:38:285:44 | ...: ... | test.rs:286:9:286:10 | Ok | | | test.rs:285:87:287:5 | { ... } | test.rs:285:5:287:5 | exit fn test_question_mark_operator_1 (normal) | | | test.rs:286:9:286:10 | Ok | test.rs:286:12:286:12 | s | | | test.rs:286:9:286:33 | Ok(...) | test.rs:285:87:287:5 | { ... } | | @@ -623,8 +623,8 @@ edges | test.rs:286:32:286:32 | 4 | test.rs:286:12:286:32 | ... + ... | | | test.rs:289:5:294:5 | enter fn test_question_mark_operator_2 | test.rs:289:38:289:38 | b | | | test.rs:289:5:294:5 | exit fn test_question_mark_operator_2 (normal) | test.rs:289:5:294:5 | exit fn test_question_mark_operator_2 | | -| test.rs:289:38:289:38 | b | test.rs:289:38:289:52 | b: Option::<...> | match | -| test.rs:289:38:289:52 | b: Option::<...> | test.rs:290:15:290:15 | b | | +| test.rs:289:38:289:38 | b | test.rs:289:38:289:52 | ...: Option::<...> | match | +| test.rs:289:38:289:52 | ...: Option::<...> | test.rs:290:15:290:15 | b | | | test.rs:289:71:294:5 | { ... } | test.rs:289:5:294:5 | exit fn test_question_mark_operator_2 (normal) | | | test.rs:290:9:293:9 | match ... { ... } | test.rs:289:71:294:5 | { ... } | | | test.rs:290:15:290:15 | b | test.rs:290:15:290:16 | TryExpr | | @@ -643,10 +643,10 @@ edges | test.rs:292:27:292:30 | true | test.rs:292:22:292:31 | Some(...) | | | test.rs:300:5:306:5 | enter fn test_match | test.rs:300:19:300:29 | maybe_digit | | | test.rs:300:5:306:5 | exit fn test_match (normal) | test.rs:300:5:306:5 | exit fn test_match | | -| test.rs:300:19:300:29 | maybe_digit | test.rs:300:19:300:42 | maybe_digit: Option::<...> | match | -| test.rs:300:19:300:42 | maybe_digit: Option::<...> | test.rs:301:15:301:25 | maybe_digit | | +| test.rs:300:19:300:29 | maybe_digit | test.rs:300:19:300:42 | ...: Option::<...> | match | +| test.rs:300:19:300:42 | ...: Option::<...> | test.rs:301:15:301:25 | maybe_digit | | | test.rs:300:52:306:5 | { ... } | test.rs:300:5:306:5 | exit fn test_match (normal) | | -| test.rs:301:9:305:9 | match ... { ... } | test.rs:300:52:306:5 | { ... } | | +| test.rs:301:9:305:9 | match maybe_digit { ... } | test.rs:300:52:306:5 | { ... } | | | test.rs:301:15:301:25 | maybe_digit | test.rs:302:13:302:27 | TupleStructPat | | | test.rs:302:13:302:27 | TupleStructPat | test.rs:302:26:302:26 | x | match | | test.rs:302:13:302:27 | TupleStructPat | test.rs:303:13:303:27 | TupleStructPat | no-match | @@ -656,31 +656,31 @@ edges | test.rs:302:32:302:37 | ... < ... | test.rs:303:13:303:27 | TupleStructPat | false | | test.rs:302:36:302:37 | 10 | test.rs:302:32:302:37 | ... < ... | | | test.rs:302:42:302:42 | x | test.rs:302:46:302:46 | 5 | | -| test.rs:302:42:302:46 | ... + ... | test.rs:301:9:305:9 | match ... { ... } | | +| test.rs:302:42:302:46 | ... + ... | test.rs:301:9:305:9 | match maybe_digit { ... } | | | test.rs:302:46:302:46 | 5 | test.rs:302:42:302:46 | ... + ... | | | test.rs:303:13:303:27 | TupleStructPat | test.rs:303:26:303:26 | x | match | | test.rs:303:13:303:27 | TupleStructPat | test.rs:304:13:304:24 | Option::None | no-match | | test.rs:303:26:303:26 | x | test.rs:303:32:303:32 | x | match | -| test.rs:303:32:303:32 | x | test.rs:301:9:305:9 | match ... { ... } | | +| test.rs:303:32:303:32 | x | test.rs:301:9:305:9 | match maybe_digit { ... } | | | test.rs:304:13:304:24 | Option::None | test.rs:304:29:304:29 | 5 | match | -| test.rs:304:29:304:29 | 5 | test.rs:301:9:305:9 | match ... { ... } | | +| test.rs:304:29:304:29 | 5 | test.rs:301:9:305:9 | match maybe_digit { ... } | | | test.rs:308:5:317:5 | enter fn test_match_with_return_in_scrutinee | test.rs:308:44:308:54 | maybe_digit | | | test.rs:308:5:317:5 | exit fn test_match_with_return_in_scrutinee (normal) | test.rs:308:5:317:5 | exit fn test_match_with_return_in_scrutinee | | -| test.rs:308:44:308:54 | maybe_digit | test.rs:308:44:308:67 | maybe_digit: Option::<...> | match | -| test.rs:308:44:308:67 | maybe_digit: Option::<...> | test.rs:309:19:309:29 | maybe_digit | | +| test.rs:308:44:308:54 | maybe_digit | test.rs:308:44:308:67 | ...: Option::<...> | match | +| test.rs:308:44:308:67 | ...: Option::<...> | test.rs:309:19:309:29 | maybe_digit | | | test.rs:308:77:317:5 | { ... } | test.rs:308:5:317:5 | exit fn test_match_with_return_in_scrutinee (normal) | | | test.rs:309:9:316:9 | match ... { ... } | test.rs:308:77:317:5 | { ... } | | -| test.rs:309:16:313:9 | if ... { ... } else { ... } | test.rs:314:13:314:27 | TupleStructPat | | +| test.rs:309:16:313:9 | if ... {...} else {...} | test.rs:314:13:314:27 | TupleStructPat | | | test.rs:309:19:309:29 | maybe_digit | test.rs:309:34:309:37 | Some | | | test.rs:309:19:309:40 | ... == ... | test.rs:310:13:310:21 | ExprStmt | true | | test.rs:309:19:309:40 | ... == ... | test.rs:312:13:312:23 | maybe_digit | false | | test.rs:309:34:309:37 | Some | test.rs:309:39:309:39 | 3 | | | test.rs:309:34:309:40 | Some(...) | test.rs:309:19:309:40 | ... == ... | | | test.rs:309:39:309:39 | 3 | test.rs:309:34:309:40 | Some(...) | | -| test.rs:310:13:310:20 | return ... | test.rs:308:5:317:5 | exit fn test_match_with_return_in_scrutinee (normal) | return | +| test.rs:310:13:310:20 | return 3 | test.rs:308:5:317:5 | exit fn test_match_with_return_in_scrutinee (normal) | return | | test.rs:310:13:310:21 | ExprStmt | test.rs:310:20:310:20 | 3 | | -| test.rs:310:20:310:20 | 3 | test.rs:310:13:310:20 | return ... | | -| test.rs:311:16:313:9 | { ... } | test.rs:309:16:313:9 | if ... { ... } else { ... } | | +| test.rs:310:20:310:20 | 3 | test.rs:310:13:310:20 | return 3 | | +| test.rs:311:16:313:9 | { ... } | test.rs:309:16:313:9 | if ... {...} else {...} | | | test.rs:312:13:312:23 | maybe_digit | test.rs:311:16:313:9 | { ... } | | | test.rs:314:13:314:27 | TupleStructPat | test.rs:314:26:314:26 | x | match | | test.rs:314:13:314:27 | TupleStructPat | test.rs:315:13:315:24 | Option::None | no-match | @@ -692,44 +692,44 @@ edges | test.rs:315:29:315:29 | 5 | test.rs:309:9:316:9 | match ... { ... } | | | test.rs:319:5:324:5 | enter fn test_match_and | test.rs:319:23:319:26 | cond | | | test.rs:319:5:324:5 | exit fn test_match_and (normal) | test.rs:319:5:324:5 | exit fn test_match_and | | -| test.rs:319:23:319:26 | cond | test.rs:319:23:319:32 | cond: bool | match | -| test.rs:319:23:319:32 | cond: bool | test.rs:319:35:319:35 | r | | -| test.rs:319:35:319:35 | r | test.rs:319:35:319:49 | r: Option::<...> | match | -| test.rs:319:35:319:49 | r: Option::<...> | test.rs:320:16:320:16 | r | | +| test.rs:319:23:319:26 | cond | test.rs:319:23:319:32 | ...: bool | match | +| test.rs:319:23:319:32 | ...: bool | test.rs:319:35:319:35 | r | | +| test.rs:319:35:319:35 | r | test.rs:319:35:319:49 | ...: Option::<...> | match | +| test.rs:319:35:319:49 | ...: Option::<...> | test.rs:320:16:320:16 | r | | | test.rs:319:60:324:5 | { ... } | test.rs:319:5:324:5 | exit fn test_match_and (normal) | | | test.rs:320:9:323:18 | ... && ... | test.rs:319:60:324:5 | { ... } | | -| test.rs:320:10:323:9 | [boolean(false)] match ... { ... } | test.rs:320:9:323:18 | ... && ... | false | -| test.rs:320:10:323:9 | [boolean(true)] match ... { ... } | test.rs:323:15:323:18 | cond | true | +| test.rs:320:10:323:9 | [boolean(false)] match r { ... } | test.rs:320:9:323:18 | ... && ... | false | +| test.rs:320:10:323:9 | [boolean(true)] match r { ... } | test.rs:323:15:323:18 | cond | true | | test.rs:320:16:320:16 | r | test.rs:321:13:321:19 | TupleStructPat | | | test.rs:321:13:321:19 | TupleStructPat | test.rs:321:18:321:18 | a | match | | test.rs:321:13:321:19 | TupleStructPat | test.rs:322:13:322:13 | _ | no-match | | test.rs:321:18:321:18 | a | test.rs:321:24:321:24 | a | match | -| test.rs:321:24:321:24 | a | test.rs:320:10:323:9 | [boolean(false)] match ... { ... } | false | -| test.rs:321:24:321:24 | a | test.rs:320:10:323:9 | [boolean(true)] match ... { ... } | true | +| test.rs:321:24:321:24 | a | test.rs:320:10:323:9 | [boolean(false)] match r { ... } | false | +| test.rs:321:24:321:24 | a | test.rs:320:10:323:9 | [boolean(true)] match r { ... } | true | | test.rs:322:13:322:13 | _ | test.rs:322:18:322:22 | false | match | -| test.rs:322:18:322:22 | false | test.rs:320:10:323:9 | [boolean(false)] match ... { ... } | false | +| test.rs:322:18:322:22 | false | test.rs:320:10:323:9 | [boolean(false)] match r { ... } | false | | test.rs:323:15:323:18 | cond | test.rs:320:9:323:18 | ... && ... | | | test.rs:326:5:331:5 | enter fn test_match_with_no_arms | test.rs:326:35:326:35 | r | | | test.rs:326:5:331:5 | exit fn test_match_with_no_arms (normal) | test.rs:326:5:331:5 | exit fn test_match_with_no_arms | | -| test.rs:326:35:326:35 | r | test.rs:326:35:326:58 | r: Result::<...> | match | -| test.rs:326:35:326:58 | r: Result::<...> | test.rs:327:15:327:15 | r | | +| test.rs:326:35:326:35 | r | test.rs:326:35:326:58 | ...: Result::<...> | match | +| test.rs:326:35:326:58 | ...: Result::<...> | test.rs:327:15:327:15 | r | | | test.rs:326:66:331:5 | { ... } | test.rs:326:5:331:5 | exit fn test_match_with_no_arms (normal) | | -| test.rs:327:9:330:9 | match ... { ... } | test.rs:326:66:331:5 | { ... } | | +| test.rs:327:9:330:9 | match r { ... } | test.rs:326:66:331:5 | { ... } | | | test.rs:327:15:327:15 | r | test.rs:328:13:328:21 | TupleStructPat | | | test.rs:328:13:328:21 | TupleStructPat | test.rs:328:16:328:20 | value | match | | test.rs:328:13:328:21 | TupleStructPat | test.rs:329:13:329:22 | TupleStructPat | no-match | | test.rs:328:16:328:20 | value | test.rs:328:26:328:30 | value | match | -| test.rs:328:26:328:30 | value | test.rs:327:9:330:9 | match ... { ... } | | +| test.rs:328:26:328:30 | value | test.rs:327:9:330:9 | match r { ... } | | | test.rs:329:13:329:22 | TupleStructPat | test.rs:329:17:329:21 | never | match | | test.rs:329:17:329:21 | never | test.rs:329:33:329:37 | never | match | -| test.rs:329:27:329:40 | match ... { ... } | test.rs:327:9:330:9 | match ... { ... } | | -| test.rs:329:33:329:37 | never | test.rs:329:27:329:40 | match ... { ... } | | +| test.rs:329:27:329:40 | match never { ... } | test.rs:327:9:330:9 | match r { ... } | | +| test.rs:329:33:329:37 | never | test.rs:329:27:329:40 | match never { ... } | | | test.rs:336:5:339:5 | enter fn test_let_match | test.rs:336:23:336:23 | a | | | test.rs:336:5:339:5 | exit fn test_let_match (normal) | test.rs:336:5:339:5 | exit fn test_let_match | | -| test.rs:336:23:336:23 | a | test.rs:336:23:336:36 | a: Option::<...> | match | -| test.rs:336:23:336:36 | a: Option::<...> | test.rs:337:9:337:57 | let TupleStructPat = ... else { ... } | | +| test.rs:336:23:336:23 | a | test.rs:336:23:336:36 | ...: Option::<...> | match | +| test.rs:336:23:336:36 | ...: Option::<...> | test.rs:337:9:337:57 | let ... = a else { ... } | | | test.rs:336:46:339:5 | { ... } | test.rs:336:5:339:5 | exit fn test_let_match (normal) | | -| test.rs:337:9:337:57 | let TupleStructPat = ... else { ... } | test.rs:337:23:337:23 | a | | +| test.rs:337:9:337:57 | let ... = a else { ... } | test.rs:337:23:337:23 | a | | | test.rs:337:13:337:19 | TupleStructPat | test.rs:337:18:337:18 | n | match | | test.rs:337:13:337:19 | TupleStructPat | test.rs:337:39:337:53 | MacroStmts | no-match | | test.rs:337:18:337:18 | n | test.rs:338:9:338:9 | n | match | @@ -748,51 +748,51 @@ edges | test.rs:338:9:338:9 | n | test.rs:336:46:339:5 | { ... } | | | test.rs:341:5:347:5 | enter fn test_let_with_return | test.rs:341:29:341:29 | m | | | test.rs:341:5:347:5 | exit fn test_let_with_return (normal) | test.rs:341:5:347:5 | exit fn test_let_with_return | | -| test.rs:341:29:341:29 | m | test.rs:341:29:341:42 | m: Option::<...> | match | -| test.rs:341:29:341:42 | m: Option::<...> | test.rs:342:9:345:10 | let ret = ... | | +| test.rs:341:29:341:29 | m | test.rs:341:29:341:42 | ...: Option::<...> | match | +| test.rs:341:29:341:42 | ...: Option::<...> | test.rs:342:9:345:10 | let ... = ... | | | test.rs:341:53:347:5 | { ... } | test.rs:341:5:347:5 | exit fn test_let_with_return (normal) | | -| test.rs:342:9:345:10 | let ret = ... | test.rs:342:25:342:25 | m | | +| test.rs:342:9:345:10 | let ... = ... | test.rs:342:25:342:25 | m | | | test.rs:342:13:342:15 | ret | test.rs:346:9:346:12 | true | match | -| test.rs:342:19:345:9 | match ... { ... } | test.rs:342:13:342:15 | ret | | +| test.rs:342:19:345:9 | match m { ... } | test.rs:342:13:342:15 | ret | | | test.rs:342:25:342:25 | m | test.rs:343:13:343:21 | TupleStructPat | | | test.rs:343:13:343:21 | TupleStructPat | test.rs:343:18:343:20 | ret | match | | test.rs:343:13:343:21 | TupleStructPat | test.rs:344:13:344:16 | None | no-match | | test.rs:343:18:343:20 | ret | test.rs:343:26:343:28 | ret | match | -| test.rs:343:26:343:28 | ret | test.rs:342:19:345:9 | match ... { ... } | | +| test.rs:343:26:343:28 | ret | test.rs:342:19:345:9 | match m { ... } | | | test.rs:344:13:344:16 | None | test.rs:344:28:344:32 | false | match | -| test.rs:344:21:344:32 | return ... | test.rs:341:5:347:5 | exit fn test_let_with_return (normal) | return | -| test.rs:344:28:344:32 | false | test.rs:344:21:344:32 | return ... | | +| test.rs:344:21:344:32 | return false | test.rs:341:5:347:5 | exit fn test_let_with_return (normal) | return | +| test.rs:344:28:344:32 | false | test.rs:344:21:344:32 | return false | | | test.rs:346:9:346:12 | true | test.rs:341:53:347:5 | { ... } | | | test.rs:352:5:355:5 | enter fn empty_tuple_pattern | test.rs:352:28:352:31 | unit | | | test.rs:352:5:355:5 | exit fn empty_tuple_pattern (normal) | test.rs:352:5:355:5 | exit fn empty_tuple_pattern | | -| test.rs:352:28:352:31 | unit | test.rs:352:28:352:35 | unit: TupleType | match | -| test.rs:352:28:352:35 | unit: TupleType | test.rs:353:9:353:22 | let TuplePat = ... | | -| test.rs:353:9:353:22 | let TuplePat = ... | test.rs:353:18:353:21 | unit | | +| test.rs:352:28:352:31 | unit | test.rs:352:28:352:35 | ...: ... | match | +| test.rs:352:28:352:35 | ...: ... | test.rs:353:9:353:22 | let ... = unit | | +| test.rs:353:9:353:22 | let ... = unit | test.rs:353:18:353:21 | unit | | | test.rs:353:13:353:14 | TuplePat | test.rs:354:9:354:15 | ExprStmt | match | | test.rs:353:18:353:21 | unit | test.rs:353:13:353:14 | TuplePat | | | test.rs:354:9:354:14 | return | test.rs:352:5:355:5 | exit fn empty_tuple_pattern (normal) | return | | test.rs:354:9:354:15 | ExprStmt | test.rs:354:9:354:14 | return | | | test.rs:359:5:363:5 | enter fn empty_struct_pattern | test.rs:359:29:359:30 | st | | | test.rs:359:5:363:5 | exit fn empty_struct_pattern (normal) | test.rs:359:5:363:5 | exit fn empty_struct_pattern | | -| test.rs:359:29:359:30 | st | test.rs:359:29:359:40 | st: MyStruct | match | -| test.rs:359:29:359:40 | st: MyStruct | test.rs:360:15:360:16 | st | | +| test.rs:359:29:359:30 | st | test.rs:359:29:359:40 | ...: MyStruct | match | +| test.rs:359:29:359:40 | ...: MyStruct | test.rs:360:15:360:16 | st | | | test.rs:359:50:363:5 | { ... } | test.rs:359:5:363:5 | exit fn empty_struct_pattern (normal) | | -| test.rs:360:9:362:9 | match ... { ... } | test.rs:359:50:363:5 | { ... } | | +| test.rs:360:9:362:9 | match st { ... } | test.rs:359:50:363:5 | { ... } | | | test.rs:360:15:360:16 | st | test.rs:361:13:361:27 | MyStruct {...} | | | test.rs:361:13:361:27 | MyStruct {...} | test.rs:361:24:361:25 | .. | match | | test.rs:361:24:361:25 | .. | test.rs:361:32:361:32 | 1 | match | -| test.rs:361:32:361:32 | 1 | test.rs:360:9:362:9 | match ... { ... } | | +| test.rs:361:32:361:32 | 1 | test.rs:360:9:362:9 | match st { ... } | | | test.rs:365:5:372:5 | enter fn range_pattern | test.rs:366:15:366:16 | 42 | | | test.rs:365:5:372:5 | exit fn range_pattern (normal) | test.rs:365:5:372:5 | exit fn range_pattern | | | test.rs:365:31:372:5 | { ... } | test.rs:365:5:372:5 | exit fn range_pattern (normal) | | -| test.rs:366:9:371:9 | match ... { ... } | test.rs:365:31:372:5 | { ... } | | +| test.rs:366:9:371:9 | match 42 { ... } | test.rs:365:31:372:5 | { ... } | | | test.rs:366:15:366:16 | 42 | test.rs:367:13:367:15 | RangePat | | | test.rs:367:13:367:15 | RangePat | test.rs:367:15:367:15 | 0 | match | | test.rs:367:13:367:15 | RangePat | test.rs:368:13:368:16 | RangePat | no-match | | test.rs:367:15:367:15 | 0 | test.rs:367:15:367:15 | 0 | | | test.rs:367:15:367:15 | 0 | test.rs:367:20:367:20 | 1 | match | | test.rs:367:15:367:15 | 0 | test.rs:368:13:368:16 | RangePat | no-match | -| test.rs:367:20:367:20 | 1 | test.rs:366:9:371:9 | match ... { ... } | | +| test.rs:367:20:367:20 | 1 | test.rs:366:9:371:9 | match 42 { ... } | | | test.rs:368:13:368:13 | 1 | test.rs:368:13:368:13 | 1 | | | test.rs:368:13:368:13 | 1 | test.rs:368:16:368:16 | 2 | match | | test.rs:368:13:368:13 | 1 | test.rs:369:13:369:15 | RangePat | no-match | @@ -801,15 +801,15 @@ edges | test.rs:368:16:368:16 | 2 | test.rs:368:16:368:16 | 2 | | | test.rs:368:16:368:16 | 2 | test.rs:368:21:368:21 | 2 | match | | test.rs:368:16:368:16 | 2 | test.rs:369:13:369:15 | RangePat | no-match | -| test.rs:368:21:368:21 | 2 | test.rs:366:9:371:9 | match ... { ... } | | +| test.rs:368:21:368:21 | 2 | test.rs:366:9:371:9 | match 42 { ... } | | | test.rs:369:13:369:13 | 5 | test.rs:369:13:369:13 | 5 | | | test.rs:369:13:369:13 | 5 | test.rs:369:20:369:20 | 3 | match | | test.rs:369:13:369:13 | 5 | test.rs:370:13:370:13 | _ | no-match | | test.rs:369:13:369:15 | RangePat | test.rs:369:13:369:13 | 5 | match | | test.rs:369:13:369:15 | RangePat | test.rs:370:13:370:13 | _ | no-match | -| test.rs:369:20:369:20 | 3 | test.rs:366:9:371:9 | match ... { ... } | | +| test.rs:369:20:369:20 | 3 | test.rs:366:9:371:9 | match 42 { ... } | | | test.rs:370:13:370:13 | _ | test.rs:370:18:370:18 | 4 | match | -| test.rs:370:18:370:18 | 4 | test.rs:366:9:371:9 | match ... { ... } | | +| test.rs:370:18:370:18 | 4 | test.rs:366:9:371:9 | match 42 { ... } | | | test.rs:376:5:381:5 | enter fn test_infinite_loop | test.rs:377:9:379:9 | ExprStmt | | | test.rs:377:9:379:9 | ExprStmt | test.rs:378:13:378:14 | TupleExpr | | | test.rs:377:14:379:9 | { ... } | test.rs:378:13:378:14 | TupleExpr | | @@ -829,11 +829,11 @@ edges | test.rs:386:18:386:32 | { ... } | test.rs:386:9:386:33 | MacroExpr | | | test.rs:389:5:408:5 | enter fn async_block | test.rs:389:26:389:26 | b | | | test.rs:389:5:408:5 | exit fn async_block (normal) | test.rs:389:5:408:5 | exit fn async_block | | -| test.rs:389:26:389:26 | b | test.rs:389:26:389:32 | b: bool | match | -| test.rs:389:26:389:32 | b: bool | test.rs:390:9:392:10 | let say_godbye = ... | | +| test.rs:389:26:389:26 | b | test.rs:389:26:389:32 | ...: bool | match | +| test.rs:389:26:389:32 | ...: bool | test.rs:390:9:392:10 | let ... = ... | | | test.rs:389:35:408:5 | { ... } | test.rs:389:5:408:5 | exit fn async_block (normal) | | -| test.rs:390:9:392:10 | let say_godbye = ... | test.rs:390:26:392:9 | { ... } | | -| test.rs:390:13:390:22 | say_godbye | test.rs:393:9:395:10 | let say_how_are_you = ... | match | +| test.rs:390:9:392:10 | let ... = ... | test.rs:390:26:392:9 | { ... } | | +| test.rs:390:13:390:22 | say_godbye | test.rs:393:9:395:10 | let ... = ... | match | | test.rs:390:26:392:9 | enter { ... } | test.rs:391:13:391:42 | ExprStmt | | | test.rs:390:26:392:9 | exit { ... } (normal) | test.rs:390:26:392:9 | exit { ... } | | | test.rs:390:26:392:9 | { ... } | test.rs:390:13:390:22 | say_godbye | | @@ -847,8 +847,8 @@ edges | test.rs:391:22:391:40 | MacroExpr | test.rs:391:22:391:40 | $crate::io::_print(...) | | | test.rs:391:22:391:40 | MacroStmts | test.rs:391:22:391:40 | ExprStmt | | | test.rs:391:22:391:40 | { ... } | test.rs:391:13:391:41 | MacroExpr | | -| test.rs:393:9:395:10 | let say_how_are_you = ... | test.rs:393:31:395:9 | { ... } | | -| test.rs:393:13:393:27 | say_how_are_you | test.rs:396:9:396:28 | let noop = ... | match | +| test.rs:393:9:395:10 | let ... = ... | test.rs:393:31:395:9 | { ... } | | +| test.rs:393:13:393:27 | say_how_are_you | test.rs:396:9:396:28 | let ... = ... | match | | test.rs:393:31:395:9 | enter { ... } | test.rs:394:13:394:37 | ExprStmt | | | test.rs:393:31:395:9 | exit { ... } (normal) | test.rs:393:31:395:9 | exit { ... } | | | test.rs:393:31:395:9 | { ... } | test.rs:393:13:393:27 | say_how_are_you | | @@ -862,35 +862,35 @@ edges | test.rs:394:22:394:35 | MacroExpr | test.rs:394:22:394:35 | $crate::io::_print(...) | | | test.rs:394:22:394:35 | MacroStmts | test.rs:394:22:394:35 | ExprStmt | | | test.rs:394:22:394:35 | { ... } | test.rs:394:13:394:36 | MacroExpr | | -| test.rs:396:9:396:28 | let noop = ... | test.rs:396:20:396:27 | { ... } | | +| test.rs:396:9:396:28 | let ... = ... | test.rs:396:20:396:27 | { ... } | | | test.rs:396:13:396:16 | noop | test.rs:397:9:397:26 | ExprStmt | match | | test.rs:396:20:396:27 | { ... } | test.rs:396:13:396:16 | noop | | | test.rs:397:9:397:17 | say_hello | test.rs:397:9:397:19 | say_hello(...) | | | test.rs:397:9:397:19 | say_hello(...) | test.rs:397:9:397:25 | await ... | | | test.rs:397:9:397:25 | await ... | test.rs:398:9:398:30 | ExprStmt | | | test.rs:397:9:397:26 | ExprStmt | test.rs:397:9:397:17 | say_hello | | -| test.rs:398:9:398:23 | say_how_are_you | test.rs:398:9:398:29 | await ... | | -| test.rs:398:9:398:29 | await ... | test.rs:399:9:399:25 | ExprStmt | | +| test.rs:398:9:398:23 | say_how_are_you | test.rs:398:9:398:29 | await say_how_are_you | | +| test.rs:398:9:398:29 | await say_how_are_you | test.rs:399:9:399:25 | ExprStmt | | | test.rs:398:9:398:30 | ExprStmt | test.rs:398:9:398:23 | say_how_are_you | | -| test.rs:399:9:399:18 | say_godbye | test.rs:399:9:399:24 | await ... | | -| test.rs:399:9:399:24 | await ... | test.rs:400:9:400:19 | ExprStmt | | +| test.rs:399:9:399:18 | say_godbye | test.rs:399:9:399:24 | await say_godbye | | +| test.rs:399:9:399:24 | await say_godbye | test.rs:400:9:400:19 | ExprStmt | | | test.rs:399:9:399:25 | ExprStmt | test.rs:399:9:399:18 | say_godbye | | -| test.rs:400:9:400:12 | noop | test.rs:400:9:400:18 | await ... | | -| test.rs:400:9:400:18 | await ... | test.rs:402:9:407:10 | let lambda = ... | | +| test.rs:400:9:400:12 | noop | test.rs:400:9:400:18 | await noop | | +| test.rs:400:9:400:18 | await noop | test.rs:402:9:407:10 | let ... = ... | | | test.rs:400:9:400:19 | ExprStmt | test.rs:400:9:400:12 | noop | | -| test.rs:402:9:407:10 | let lambda = ... | test.rs:402:22:407:9 | \|...\| ... | | +| test.rs:402:9:407:10 | let ... = ... | test.rs:402:22:407:9 | \|...\| ... | | | test.rs:402:13:402:18 | lambda | test.rs:389:35:408:5 | { ... } | match | | test.rs:402:22:407:9 | \|...\| ... | test.rs:402:13:402:18 | lambda | | | test.rs:402:22:407:9 | enter \|...\| ... | test.rs:402:23:402:25 | foo | | | test.rs:402:22:407:9 | exit \|...\| ... (normal) | test.rs:402:22:407:9 | exit \|...\| ... | | -| test.rs:402:23:402:25 | foo | test.rs:402:23:402:25 | foo | match | -| test.rs:402:23:402:25 | foo | test.rs:402:28:407:9 | { ... } | | +| test.rs:402:23:402:25 | ... | test.rs:402:28:407:9 | { ... } | | +| test.rs:402:23:402:25 | foo | test.rs:402:23:402:25 | ... | match | | test.rs:402:28:407:9 | enter { ... } | test.rs:403:13:405:14 | ExprStmt | | | test.rs:402:28:407:9 | exit { ... } (normal) | test.rs:402:28:407:9 | exit { ... } | | | test.rs:402:28:407:9 | { ... } | test.rs:402:22:407:9 | exit \|...\| ... (normal) | | -| test.rs:403:13:405:13 | if ... { ... } | test.rs:406:13:406:15 | foo | | +| test.rs:403:13:405:13 | if b {...} | test.rs:406:13:406:15 | foo | | | test.rs:403:13:405:14 | ExprStmt | test.rs:403:16:403:16 | b | | -| test.rs:403:16:403:16 | b | test.rs:403:13:405:13 | if ... { ... } | false | +| test.rs:403:16:403:16 | b | test.rs:403:13:405:13 | if b {...} | false | | test.rs:403:16:403:16 | b | test.rs:404:17:404:41 | ExprStmt | true | | test.rs:404:17:404:40 | return ... | test.rs:402:28:407:9 | exit { ... } (normal) | return | | test.rs:404:17:404:41 | ExprStmt | test.rs:404:24:404:34 | async_block | | @@ -900,8 +900,8 @@ edges | test.rs:406:13:406:15 | foo | test.rs:402:28:407:9 | exit { ... } (normal) | | | test.rs:414:5:416:5 | enter fn add_two | test.rs:414:22:414:22 | n | | | test.rs:414:5:416:5 | exit fn add_two (normal) | test.rs:414:5:416:5 | exit fn add_two | | -| test.rs:414:22:414:22 | n | test.rs:414:22:414:27 | n: i64 | match | -| test.rs:414:22:414:27 | n: i64 | test.rs:415:9:415:9 | n | | +| test.rs:414:22:414:22 | n | test.rs:414:22:414:27 | ...: i64 | match | +| test.rs:414:22:414:27 | ...: i64 | test.rs:415:9:415:9 | n | | | test.rs:414:37:416:5 | { ... } | test.rs:414:5:416:5 | exit fn add_two (normal) | | | test.rs:415:9:415:9 | n | test.rs:415:13:415:13 | 2 | | | test.rs:415:9:415:13 | ... + ... | test.rs:414:37:416:5 | { ... } | | @@ -925,16 +925,16 @@ edges | test.rs:424:13:424:49 | panic_cold_explicit(...) | test.rs:424:13:424:49 | { ... } | | | test.rs:424:13:424:49 | { ... } | test.rs:424:13:424:49 | MacroExpr | | | test.rs:424:13:424:49 | { ... } | test.rs:424:13:424:49 | exit fn panic_cold_explicit (normal) | | -| test.rs:424:13:424:49 | { ... } | test.rs:424:21:424:48 | if ... { ... } | | +| test.rs:424:13:424:49 | { ... } | test.rs:424:21:424:48 | if ... {...} | | | test.rs:424:13:424:50 | ExprStmt | test.rs:424:21:424:48 | MacroStmts | | | test.rs:424:21:424:42 | std::mem::size_of::<...> | test.rs:424:21:424:44 | std::mem::size_of::<...>(...) | | | test.rs:424:21:424:44 | std::mem::size_of::<...>(...) | test.rs:424:48:424:48 | 0 | | | test.rs:424:21:424:48 | ... > ... | test.rs:424:21:424:48 | [boolean(false)] ! ... | true | | test.rs:424:21:424:48 | ... > ... | test.rs:424:21:424:48 | [boolean(true)] ! ... | false | | test.rs:424:21:424:48 | MacroStmts | test.rs:424:21:424:42 | std::mem::size_of::<...> | | -| test.rs:424:21:424:48 | [boolean(false)] ! ... | test.rs:424:21:424:48 | if ... { ... } | false | +| test.rs:424:21:424:48 | [boolean(false)] ! ... | test.rs:424:21:424:48 | if ... {...} | false | | test.rs:424:21:424:48 | [boolean(true)] ! ... | test.rs:424:13:424:49 | ExprStmt | true | -| test.rs:424:21:424:48 | if ... { ... } | test.rs:424:21:424:48 | { ... } | | +| test.rs:424:21:424:48 | if ... {...} | test.rs:424:21:424:48 | { ... } | | | test.rs:424:21:424:48 | { ... } | test.rs:424:13:424:49 | MacroExpr | | | test.rs:424:48:424:48 | 0 | test.rs:424:21:424:48 | ... > ... | | | test.rs:427:9:427:10 | 42 | test.rs:420:41:428:5 | { ... } | | @@ -943,8 +943,8 @@ edges | test.rs:430:35:439:5 | { ... } | test.rs:430:5:439:5 | exit fn const_block_panic (normal) | | | test.rs:431:9:431:30 | Const | test.rs:432:9:437:9 | ExprStmt | | | test.rs:432:9:437:9 | ExprStmt | test.rs:432:12:432:16 | false | | -| test.rs:432:9:437:9 | if ... { ... } | test.rs:438:9:438:9 | N | | -| test.rs:432:12:432:16 | false | test.rs:432:9:437:9 | if ... { ... } | false | +| test.rs:432:9:437:9 | if false {...} | test.rs:438:9:438:9 | N | | +| test.rs:432:12:432:16 | false | test.rs:432:9:437:9 | if false {...} | false | | test.rs:435:17:435:24 | $crate::panicking::panic_explicit | test.rs:435:17:435:24 | $crate::panicking::panic_explicit(...) | | | test.rs:435:17:435:24 | $crate::panicking::panic_explicit(...) | test.rs:435:17:435:24 | { ... } | | | test.rs:435:17:435:24 | enter fn panic_cold_explicit | test.rs:435:17:435:24 | $crate::panicking::panic_explicit | | @@ -955,9 +955,9 @@ edges | test.rs:442:1:447:1 | exit fn dead_code (normal) | test.rs:442:1:447:1 | exit fn dead_code | | | test.rs:443:5:445:5 | ExprStmt | test.rs:443:9:443:12 | true | | | test.rs:443:9:443:12 | true | test.rs:444:9:444:17 | ExprStmt | true | -| test.rs:444:9:444:16 | return ... | test.rs:442:1:447:1 | exit fn dead_code (normal) | return | +| test.rs:444:9:444:16 | return 0 | test.rs:442:1:447:1 | exit fn dead_code (normal) | return | | test.rs:444:9:444:17 | ExprStmt | test.rs:444:16:444:16 | 0 | | -| test.rs:444:16:444:16 | 0 | test.rs:444:9:444:16 | return ... | | +| test.rs:444:16:444:16 | 0 | test.rs:444:9:444:16 | return 0 | | | test.rs:449:1:449:16 | enter fn do_thing | test.rs:449:15:449:16 | { ... } | | | test.rs:449:1:449:16 | exit fn do_thing (normal) | test.rs:449:1:449:16 | exit fn do_thing | | | test.rs:449:15:449:16 | { ... } | test.rs:449:1:449:16 | exit fn do_thing (normal) | | @@ -971,68 +971,68 @@ edges | test.rs:457:1:457:21 | enter fn do_last_thing | test.rs:457:20:457:21 | { ... } | | | test.rs:457:1:457:21 | exit fn do_last_thing (normal) | test.rs:457:1:457:21 | exit fn do_last_thing | | | test.rs:457:20:457:21 | { ... } | test.rs:457:1:457:21 | exit fn do_last_thing (normal) | | -| test.rs:459:1:473:1 | enter fn labelled_block1 | test.rs:460:5:471:6 | let result = ... | | +| test.rs:459:1:473:1 | enter fn labelled_block1 | test.rs:460:5:471:6 | let ... = ... | | | test.rs:459:1:473:1 | exit fn labelled_block1 (normal) | test.rs:459:1:473:1 | exit fn labelled_block1 | | | test.rs:459:29:473:1 | { ... } | test.rs:459:1:473:1 | exit fn labelled_block1 (normal) | | -| test.rs:460:5:471:6 | let result = ... | test.rs:461:9:461:19 | ExprStmt | | +| test.rs:460:5:471:6 | let ... = ... | test.rs:461:9:461:19 | ExprStmt | | | test.rs:460:9:460:14 | result | test.rs:472:5:472:10 | result | match | -| test.rs:460:18:471:5 | { ... } | test.rs:460:9:460:14 | result | | +| test.rs:460:18:471:5 | ''block: { ... } | test.rs:460:9:460:14 | result | | | test.rs:461:9:461:16 | do_thing | test.rs:461:9:461:18 | do_thing(...) | | | test.rs:461:9:461:18 | do_thing(...) | test.rs:462:9:464:9 | ExprStmt | | | test.rs:461:9:461:19 | ExprStmt | test.rs:461:9:461:16 | do_thing | | | test.rs:462:9:464:9 | ExprStmt | test.rs:462:12:462:28 | condition_not_met | | -| test.rs:462:9:464:9 | if ... { ... } | test.rs:465:9:465:24 | ExprStmt | | +| test.rs:462:9:464:9 | if ... {...} | test.rs:465:9:465:24 | ExprStmt | | | test.rs:462:12:462:28 | condition_not_met | test.rs:462:12:462:30 | condition_not_met(...) | | -| test.rs:462:12:462:30 | condition_not_met(...) | test.rs:462:9:464:9 | if ... { ... } | false | +| test.rs:462:12:462:30 | condition_not_met(...) | test.rs:462:9:464:9 | if ... {...} | false | | test.rs:462:12:462:30 | condition_not_met(...) | test.rs:463:13:463:27 | ExprStmt | true | -| test.rs:463:13:463:26 | break ''block ... | test.rs:460:18:471:5 | { ... } | break | +| test.rs:463:13:463:26 | break ''block 1 | test.rs:460:18:471:5 | ''block: { ... } | break | | test.rs:463:13:463:27 | ExprStmt | test.rs:463:26:463:26 | 1 | | -| test.rs:463:26:463:26 | 1 | test.rs:463:13:463:26 | break ''block ... | | +| test.rs:463:26:463:26 | 1 | test.rs:463:13:463:26 | break ''block 1 | | | test.rs:465:9:465:21 | do_next_thing | test.rs:465:9:465:23 | do_next_thing(...) | | | test.rs:465:9:465:23 | do_next_thing(...) | test.rs:466:9:468:9 | ExprStmt | | | test.rs:465:9:465:24 | ExprStmt | test.rs:465:9:465:21 | do_next_thing | | | test.rs:466:9:468:9 | ExprStmt | test.rs:466:12:466:28 | condition_not_met | | -| test.rs:466:9:468:9 | if ... { ... } | test.rs:469:9:469:24 | ExprStmt | | +| test.rs:466:9:468:9 | if ... {...} | test.rs:469:9:469:24 | ExprStmt | | | test.rs:466:12:466:28 | condition_not_met | test.rs:466:12:466:30 | condition_not_met(...) | | -| test.rs:466:12:466:30 | condition_not_met(...) | test.rs:466:9:468:9 | if ... { ... } | false | +| test.rs:466:12:466:30 | condition_not_met(...) | test.rs:466:9:468:9 | if ... {...} | false | | test.rs:466:12:466:30 | condition_not_met(...) | test.rs:467:13:467:27 | ExprStmt | true | -| test.rs:467:13:467:26 | break ''block ... | test.rs:460:18:471:5 | { ... } | break | +| test.rs:467:13:467:26 | break ''block 2 | test.rs:460:18:471:5 | ''block: { ... } | break | | test.rs:467:13:467:27 | ExprStmt | test.rs:467:26:467:26 | 2 | | -| test.rs:467:26:467:26 | 2 | test.rs:467:13:467:26 | break ''block ... | | +| test.rs:467:26:467:26 | 2 | test.rs:467:13:467:26 | break ''block 2 | | | test.rs:469:9:469:21 | do_last_thing | test.rs:469:9:469:23 | do_last_thing(...) | | | test.rs:469:9:469:23 | do_last_thing(...) | test.rs:470:9:470:9 | 3 | | | test.rs:469:9:469:24 | ExprStmt | test.rs:469:9:469:21 | do_last_thing | | -| test.rs:470:9:470:9 | 3 | test.rs:460:18:471:5 | { ... } | | +| test.rs:470:9:470:9 | 3 | test.rs:460:18:471:5 | ''block: { ... } | | | test.rs:472:5:472:10 | result | test.rs:459:29:473:1 | { ... } | | -| test.rs:475:1:483:1 | enter fn labelled_block2 | test.rs:476:5:482:6 | let result = ... | | +| test.rs:475:1:483:1 | enter fn labelled_block2 | test.rs:476:5:482:6 | let ... = ... | | | test.rs:475:1:483:1 | exit fn labelled_block2 (normal) | test.rs:475:1:483:1 | exit fn labelled_block2 | | | test.rs:475:22:483:1 | { ... } | test.rs:475:1:483:1 | exit fn labelled_block2 (normal) | | -| test.rs:476:5:482:6 | let result = ... | test.rs:477:9:477:34 | let x = ... | | +| test.rs:476:5:482:6 | let ... = ... | test.rs:477:9:477:34 | let ... = None | | | test.rs:476:9:476:14 | result | test.rs:475:22:483:1 | { ... } | match | -| test.rs:476:18:482:5 | { ... } | test.rs:476:9:476:14 | result | | -| test.rs:477:9:477:34 | let x = ... | test.rs:477:30:477:33 | None | | -| test.rs:477:13:477:13 | x | test.rs:478:9:480:10 | let TupleStructPat = ... else { ... } | match | +| test.rs:476:18:482:5 | ''block: { ... } | test.rs:476:9:476:14 | result | | +| test.rs:477:9:477:34 | let ... = None | test.rs:477:30:477:33 | None | | +| test.rs:477:13:477:13 | x | test.rs:478:9:480:10 | let ... = x else { ... } | match | | test.rs:477:30:477:33 | None | test.rs:477:13:477:13 | x | | -| test.rs:478:9:480:10 | let TupleStructPat = ... else { ... } | test.rs:478:23:478:23 | x | | +| test.rs:478:9:480:10 | let ... = x else { ... } | test.rs:478:23:478:23 | x | | | test.rs:478:13:478:19 | TupleStructPat | test.rs:478:18:478:18 | y | match | | test.rs:478:13:478:19 | TupleStructPat | test.rs:479:13:479:27 | ExprStmt | no-match | | test.rs:478:18:478:18 | y | test.rs:481:9:481:9 | 0 | match | | test.rs:478:23:478:23 | x | test.rs:478:13:478:19 | TupleStructPat | | -| test.rs:479:13:479:26 | break ''block ... | test.rs:476:18:482:5 | { ... } | break | +| test.rs:479:13:479:26 | break ''block 1 | test.rs:476:18:482:5 | ''block: { ... } | break | | test.rs:479:13:479:27 | ExprStmt | test.rs:479:26:479:26 | 1 | | -| test.rs:479:26:479:26 | 1 | test.rs:479:13:479:26 | break ''block ... | | -| test.rs:481:9:481:9 | 0 | test.rs:476:18:482:5 | { ... } | | -| test.rs:485:1:491:1 | enter fn test_nested_function2 | test.rs:486:5:486:18 | let x = ... | | +| test.rs:479:26:479:26 | 1 | test.rs:479:13:479:26 | break ''block 1 | | +| test.rs:481:9:481:9 | 0 | test.rs:476:18:482:5 | ''block: { ... } | | +| test.rs:485:1:491:1 | enter fn test_nested_function2 | test.rs:486:5:486:18 | let ... = 0 | | | test.rs:485:1:491:1 | exit fn test_nested_function2 (normal) | test.rs:485:1:491:1 | exit fn test_nested_function2 | | | test.rs:485:28:491:1 | { ... } | test.rs:485:1:491:1 | exit fn test_nested_function2 (normal) | | -| test.rs:486:5:486:18 | let x = ... | test.rs:486:17:486:17 | 0 | | +| test.rs:486:5:486:18 | let ... = 0 | test.rs:486:17:486:17 | 0 | | | test.rs:486:9:486:13 | x | test.rs:487:5:489:5 | fn nested | match | | test.rs:486:17:486:17 | 0 | test.rs:486:9:486:13 | x | | | test.rs:487:5:489:5 | enter fn nested | test.rs:487:15:487:15 | x | | | test.rs:487:5:489:5 | exit fn nested (normal) | test.rs:487:5:489:5 | exit fn nested | | | test.rs:487:5:489:5 | fn nested | test.rs:490:5:490:19 | ExprStmt | | -| test.rs:487:15:487:15 | x | test.rs:487:15:487:25 | x: RefType | match | -| test.rs:487:15:487:25 | x: RefType | test.rs:488:9:488:16 | ExprStmt | | +| test.rs:487:15:487:15 | x | test.rs:487:15:487:25 | ...: ... | match | +| test.rs:487:15:487:25 | ...: ... | test.rs:488:9:488:16 | ExprStmt | | | test.rs:487:28:489:5 | { ... } | test.rs:487:5:489:5 | exit fn nested (normal) | | | test.rs:488:9:488:10 | * ... | test.rs:488:15:488:15 | 1 | | | test.rs:488:9:488:15 | ... += ... | test.rs:487:28:489:5 | { ... } | | @@ -1042,28 +1042,28 @@ edges | test.rs:490:5:490:10 | nested | test.rs:490:17:490:17 | x | | | test.rs:490:5:490:18 | nested(...) | test.rs:485:28:491:1 | { ... } | | | test.rs:490:5:490:19 | ExprStmt | test.rs:490:5:490:10 | nested | | -| test.rs:490:12:490:17 | &mut ... | test.rs:490:5:490:18 | nested(...) | | -| test.rs:490:17:490:17 | x | test.rs:490:12:490:17 | &mut ... | | +| test.rs:490:12:490:17 | &mut x | test.rs:490:5:490:18 | nested(...) | | +| test.rs:490:17:490:17 | x | test.rs:490:12:490:17 | &mut x | | breakTarget -| test.rs:34:17:34:21 | break | test.rs:28:9:40:9 | loop {...} | -| test.rs:48:21:48:25 | break | test.rs:46:13:53:13 | loop {...} | -| test.rs:50:21:50:32 | break ''outer | test.rs:45:9:54:9 | loop {...} | -| test.rs:52:17:52:28 | break ''inner | test.rs:46:13:53:13 | loop {...} | -| test.rs:91:17:91:21 | break | test.rs:88:9:94:9 | while ... { ... } | +| test.rs:34:17:34:21 | break | test.rs:28:9:40:9 | loop { ... } | +| test.rs:48:21:48:25 | break | test.rs:46:13:53:13 | ''inner: loop { ... } | +| test.rs:50:21:50:32 | break ''outer | test.rs:45:9:54:9 | ''outer: loop { ... } | +| test.rs:52:17:52:28 | break ''inner | test.rs:46:13:53:13 | ''inner: loop { ... } | +| test.rs:91:17:91:21 | break | test.rs:88:9:94:9 | while b { ... } | | test.rs:101:17:101:21 | break | test.rs:99:9:103:9 | while ... { ... } | -| test.rs:109:17:109:21 | break | test.rs:107:9:112:9 | for i in ... { ... } | -| test.rs:117:13:117:26 | break ... | test.rs:116:9:118:9 | loop {...} | -| test.rs:197:17:197:28 | break ... | test.rs:195:13:200:9 | loop {...} | -| test.rs:210:17:210:35 | break ''label ... | test.rs:208:13:213:9 | loop {...} | -| test.rs:222:13:222:30 | break ''block ... | test.rs:221:13:223:9 | { ... } | -| test.rs:463:13:463:26 | break ''block ... | test.rs:460:18:471:5 | { ... } | -| test.rs:467:13:467:26 | break ''block ... | test.rs:460:18:471:5 | { ... } | -| test.rs:479:13:479:26 | break ''block ... | test.rs:476:18:482:5 | { ... } | +| test.rs:109:17:109:21 | break | test.rs:107:9:112:9 | for ... in ... { ... } | +| test.rs:117:13:117:26 | break ... | test.rs:116:9:118:9 | loop { ... } | +| test.rs:197:17:197:28 | break ... | test.rs:195:13:200:9 | loop { ... } | +| test.rs:210:17:210:35 | break ''label ... | test.rs:208:13:213:9 | ''label: loop { ... } | +| test.rs:222:13:222:30 | break ''block ... | test.rs:221:13:223:9 | ''block: { ... } | +| test.rs:463:13:463:26 | break ''block 1 | test.rs:460:18:471:5 | ''block: { ... } | +| test.rs:467:13:467:26 | break ''block 2 | test.rs:460:18:471:5 | ''block: { ... } | +| test.rs:479:13:479:26 | break ''block 1 | test.rs:476:18:482:5 | ''block: { ... } | continueTarget -| test.rs:37:17:37:24 | continue | test.rs:28:9:40:9 | loop {...} | -| test.rs:63:21:63:28 | continue | test.rs:61:13:68:13 | loop {...} | -| test.rs:65:21:65:35 | continue 'outer | test.rs:59:9:69:9 | loop {...} | -| test.rs:67:17:67:31 | continue 'inner | test.rs:61:13:68:13 | loop {...} | -| test.rs:77:21:77:28 | continue | test.rs:75:13:82:13 | loop {...} | -| test.rs:79:21:79:35 | continue 'label | test.rs:75:13:82:13 | loop {...} | -| test.rs:81:17:81:31 | continue 'label | test.rs:75:13:82:13 | loop {...} | +| test.rs:37:17:37:24 | continue | test.rs:28:9:40:9 | loop { ... } | +| test.rs:63:21:63:28 | continue | test.rs:61:13:68:13 | ''inner: loop { ... } | +| test.rs:65:21:65:35 | continue ''outer | test.rs:59:9:69:9 | ''outer: loop { ... } | +| test.rs:67:17:67:31 | continue ''inner | test.rs:61:13:68:13 | ''inner: loop { ... } | +| test.rs:77:21:77:28 | continue | test.rs:75:13:82:13 | ''label: loop { ... } | +| test.rs:79:21:79:35 | continue ''label | test.rs:75:13:82:13 | ''label: loop { ... } | +| test.rs:81:17:81:31 | continue ''label | test.rs:75:13:82:13 | ''label: loop { ... } | diff --git a/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected b/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected index c8d53f467e9..29d8b8e3b92 100644 --- a/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected @@ -1,16 +1,16 @@ models edges -| main.rs:21:13:21:21 | source(...) : unit | main.rs:22:10:22:10 | s | provenance | | -| main.rs:32:13:32:21 | source(...) : unit | main.rs:33:10:33:10 | s | provenance | | +| main.rs:21:13:21:21 | (...) ... : unit | main.rs:22:10:22:10 | s | provenance | | +| main.rs:32:13:32:21 | (...) ... : unit | main.rs:33:10:33:10 | s | provenance | | nodes -| main.rs:17:10:17:18 | source(...) | semmle.label | source(...) | -| main.rs:21:13:21:21 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:17:10:17:18 | (...) ... | semmle.label | (...) ... | +| main.rs:21:13:21:21 | (...) ... : unit | semmle.label | (...) ... : unit | | main.rs:22:10:22:10 | s | semmle.label | s | -| main.rs:32:13:32:21 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:32:13:32:21 | (...) ... : unit | semmle.label | (...) ... : unit | | main.rs:33:10:33:10 | s | semmle.label | s | subpaths testFailures #select -| main.rs:17:10:17:18 | source(...) | main.rs:17:10:17:18 | source(...) | main.rs:17:10:17:18 | source(...) | $@ | main.rs:17:10:17:18 | source(...) | source(...) | -| main.rs:22:10:22:10 | s | main.rs:21:13:21:21 | source(...) : unit | main.rs:22:10:22:10 | s | $@ | main.rs:21:13:21:21 | source(...) : unit | source(...) : unit | -| main.rs:33:10:33:10 | s | main.rs:32:13:32:21 | source(...) : unit | main.rs:33:10:33:10 | s | $@ | main.rs:32:13:32:21 | source(...) : unit | source(...) : unit | +| main.rs:17:10:17:18 | (...) ... | main.rs:17:10:17:18 | (...) ... | main.rs:17:10:17:18 | (...) ... | $@ | main.rs:17:10:17:18 | (...) ... | (...) ... | +| main.rs:22:10:22:10 | s | main.rs:21:13:21:21 | (...) ... : unit | main.rs:22:10:22:10 | s | $@ | main.rs:21:13:21:21 | (...) ... : unit | (...) ... : unit | +| main.rs:33:10:33:10 | s | main.rs:32:13:32:21 | (...) ... : unit | main.rs:33:10:33:10 | s | $@ | main.rs:32:13:32:21 | (...) ... : unit | (...) ... : unit | diff --git a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected index 28e43535c79..5fbf2fe41e1 100644 --- a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected +++ b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected @@ -1,24 +1,24 @@ -| main.rs:13:5:13:13 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:17:13:17:23 | get_data(...) | main.rs:12:1:14:1 | fn get_data | -| main.rs:18:5:18:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:22:5:22:15 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:26:13:26:21 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:27:5:27:14 | data_in(...) | main.rs:21:1:23:1 | fn data_in | -| main.rs:35:13:35:21 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:36:13:36:27 | pass_through(...) | main.rs:30:1:32:1 | fn pass_through | -| main.rs:37:5:37:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:49:9:49:15 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:55:13:55:21 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:13:5:13:13 | (...) ... | main.rs:1:1:3:1 | fn source | +| main.rs:17:13:17:23 | (...) ... | main.rs:12:1:14:1 | fn get_data | +| main.rs:18:5:18:11 | (...) ... | main.rs:5:1:7:1 | fn sink | +| main.rs:22:5:22:15 | (...) ... | main.rs:5:1:7:1 | fn sink | +| main.rs:26:13:26:21 | (...) ... | main.rs:1:1:3:1 | fn source | +| main.rs:27:5:27:14 | (...) ... | main.rs:21:1:23:1 | fn data_in | +| main.rs:35:13:35:21 | (...) ... | main.rs:1:1:3:1 | fn source | +| main.rs:36:13:36:27 | (...) ... | main.rs:30:1:32:1 | fn pass_through | +| main.rs:37:5:37:11 | (...) ... | main.rs:5:1:7:1 | fn sink | +| main.rs:49:9:49:15 | (...) ... | main.rs:5:1:7:1 | fn sink | +| main.rs:55:13:55:21 | (...) ... | main.rs:1:1:3:1 | fn source | | main.rs:69:13:69:25 | ... .get_data(...) | main.rs:51:5:57:5 | fn get_data | -| main.rs:70:5:70:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:75:13:75:21 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:70:5:70:11 | (...) ... | main.rs:5:1:7:1 | fn sink | +| main.rs:75:13:75:21 | (...) ... | main.rs:1:1:3:1 | fn source | | main.rs:76:5:76:17 | ... .data_in(...) | main.rs:48:5:50:5 | fn data_in | -| main.rs:81:13:81:21 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:81:13:81:21 | (...) ... | main.rs:1:1:3:1 | fn source | | main.rs:82:5:82:22 | ... .data_through(...) | main.rs:58:5:64:5 | fn data_through | -| main.rs:83:5:83:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:87:5:87:22 | data_out_of_call(...) | main.rs:16:1:19:1 | fn data_out_of_call | -| main.rs:88:5:88:21 | data_in_to_call(...) | main.rs:25:1:28:1 | fn data_in_to_call | -| main.rs:89:5:89:23 | data_through_call(...) | main.rs:34:1:38:1 | fn data_through_call | -| main.rs:91:5:91:24 | data_out_of_method(...) | main.rs:67:1:71:1 | fn data_out_of_method | -| main.rs:92:5:92:28 | data_in_to_method_call(...) | main.rs:73:1:77:1 | fn data_in_to_method_call | -| main.rs:93:5:93:25 | data_through_method(...) | main.rs:79:1:84:1 | fn data_through_method | +| main.rs:83:5:83:11 | (...) ... | main.rs:5:1:7:1 | fn sink | +| main.rs:87:5:87:22 | (...) ... | main.rs:16:1:19:1 | fn data_out_of_call | +| main.rs:88:5:88:21 | (...) ... | main.rs:25:1:28:1 | fn data_in_to_call | +| main.rs:89:5:89:23 | (...) ... | main.rs:34:1:38:1 | fn data_through_call | +| main.rs:91:5:91:24 | (...) ... | main.rs:67:1:71:1 | fn data_out_of_method | +| main.rs:92:5:92:28 | (...) ... | main.rs:73:1:77:1 | fn data_in_to_method_call | +| main.rs:93:5:93:25 | (...) ... | main.rs:79:1:84:1 | fn data_through_method | diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 3639294bd49..e0bab71ec1e 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -5,27 +5,27 @@ | main.rs:7:9:7:9 | s | main.rs:7:9:7:9 | [SSA] s | | main.rs:19:9:19:9 | [SSA] s | main.rs:20:10:20:10 | s | | main.rs:19:9:19:9 | s | main.rs:19:9:19:9 | [SSA] s | -| main.rs:19:13:19:21 | source(...) | main.rs:19:9:19:9 | s | +| main.rs:19:13:19:21 | (...) ... | main.rs:19:9:19:9 | s | | main.rs:23:18:23:21 | [SSA] cond | main.rs:26:16:26:19 | cond | | main.rs:23:18:23:21 | cond | main.rs:23:18:23:21 | [SSA] cond | | main.rs:24:9:24:9 | [SSA] a | main.rs:26:23:26:23 | a | | main.rs:24:9:24:9 | a | main.rs:24:9:24:9 | [SSA] a | -| main.rs:24:13:24:21 | source(...) | main.rs:24:9:24:9 | a | +| main.rs:24:13:24:21 | (...) ... | main.rs:24:9:24:9 | a | | main.rs:25:9:25:9 | [SSA] b | main.rs:26:34:26:34 | b | | main.rs:25:9:25:9 | b | main.rs:25:9:25:9 | [SSA] b | | main.rs:25:13:25:13 | 2 | main.rs:25:9:25:9 | b | | main.rs:26:9:26:9 | [SSA] c | main.rs:27:10:27:10 | c | | main.rs:26:9:26:9 | c | main.rs:26:9:26:9 | [SSA] c | -| main.rs:26:13:26:36 | if ... { ... } else { ... } | main.rs:26:9:26:9 | c | -| main.rs:26:21:26:25 | { ... } | main.rs:26:13:26:36 | if ... { ... } else { ... } | +| main.rs:26:13:26:36 | ... else { ... } if {...} | main.rs:26:9:26:9 | c | +| main.rs:26:21:26:25 | { ... } | main.rs:26:13:26:36 | ... else { ... } if {...} | | main.rs:26:23:26:23 | a | main.rs:26:21:26:25 | { ... } | -| main.rs:26:32:26:36 | { ... } | main.rs:26:13:26:36 | if ... { ... } else { ... } | +| main.rs:26:32:26:36 | { ... } | main.rs:26:13:26:36 | ... else { ... } if {...} | | main.rs:26:34:26:34 | b | main.rs:26:32:26:36 | { ... } | | main.rs:30:21:30:21 | [SSA] m | main.rs:32:19:32:19 | m | | main.rs:30:21:30:21 | m | main.rs:30:21:30:21 | [SSA] m | | main.rs:31:9:31:9 | [SSA] a | main.rs:33:20:33:20 | a | | main.rs:31:9:31:9 | a | main.rs:31:9:31:9 | [SSA] a | -| main.rs:31:13:31:21 | source(...) | main.rs:31:9:31:9 | a | +| main.rs:31:13:31:21 | (...) ... | main.rs:31:9:31:9 | a | | main.rs:32:9:32:9 | [SSA] b | main.rs:36:10:36:10 | b | | main.rs:32:9:32:9 | b | main.rs:32:9:32:9 | [SSA] b | | main.rs:32:13:35:5 | match ... { ... } | main.rs:32:9:32:9 | b | @@ -33,14 +33,14 @@ | main.rs:34:17:34:17 | 0 | main.rs:32:13:35:5 | match ... { ... } | | main.rs:40:9:40:9 | [SSA] a | main.rs:43:10:43:10 | a | | main.rs:40:9:40:9 | a | main.rs:40:9:40:9 | [SSA] a | -| main.rs:40:13:42:5 | loop {...} | main.rs:40:9:40:9 | a | -| main.rs:41:9:41:15 | break ... | main.rs:40:13:42:5 | loop {...} | -| main.rs:41:15:41:15 | 1 | main.rs:41:9:41:15 | break ... | +| main.rs:40:13:42:5 | loop { ... } | main.rs:40:9:40:9 | a | +| main.rs:41:9:41:15 | 1 break | main.rs:40:13:42:5 | loop { ... } | +| main.rs:41:15:41:15 | 1 | main.rs:41:9:41:15 | 1 break | | main.rs:44:9:44:9 | [SSA] b | main.rs:47:10:47:10 | b | | main.rs:44:9:44:9 | b | main.rs:44:9:44:9 | [SSA] b | -| main.rs:44:13:46:5 | loop {...} | main.rs:44:9:44:9 | b | -| main.rs:45:9:45:23 | break ... | main.rs:44:13:46:5 | loop {...} | -| main.rs:45:15:45:23 | source(...) | main.rs:45:9:45:23 | break ... | +| main.rs:44:13:46:5 | loop { ... } | main.rs:44:9:44:9 | b | +| main.rs:45:9:45:23 | ... break | main.rs:44:13:46:5 | loop { ... } | +| main.rs:45:15:45:23 | (...) ... | main.rs:45:9:45:23 | ... break | | main.rs:51:9:51:13 | [SSA] i | main.rs:52:10:52:10 | i | | main.rs:51:9:51:13 | i | main.rs:51:9:51:13 | [SSA] i | | main.rs:51:17:51:17 | 1 | main.rs:51:9:51:13 | i | @@ -48,7 +48,7 @@ | main.rs:53:5:53:5 | i | main.rs:53:5:53:5 | [SSA] i | | main.rs:61:9:61:9 | [SSA] i | main.rs:62:11:62:11 | i | | main.rs:61:9:61:9 | i | main.rs:61:9:61:9 | [SSA] i | -| main.rs:61:13:61:31 | Box::new(...) | main.rs:61:9:61:9 | i | +| main.rs:61:13:61:31 | (...) ... | main.rs:61:9:61:9 | i | | main.rs:66:9:66:9 | [SSA] a | main.rs:67:10:67:10 | a | | main.rs:66:9:66:9 | a | main.rs:66:9:66:9 | [SSA] a | | main.rs:66:13:66:26 | TupleExpr | main.rs:66:9:66:9 | a | @@ -70,16 +70,16 @@ | main.rs:97:38:97:38 | p | main.rs:97:9:97:34 | Point {...} | | main.rs:104:9:104:10 | [SSA] s1 | main.rs:106:11:106:12 | s1 | | main.rs:104:9:104:10 | s1 | main.rs:104:9:104:10 | [SSA] s1 | -| main.rs:104:14:104:28 | Some(...) | main.rs:104:9:104:10 | s1 | +| main.rs:104:14:104:28 | (...) ... | main.rs:104:9:104:10 | s1 | | main.rs:105:9:105:10 | [SSA] s2 | main.rs:110:11:110:12 | s2 | | main.rs:105:9:105:10 | s2 | main.rs:105:9:105:10 | [SSA] s2 | -| main.rs:105:14:105:20 | Some(...) | main.rs:105:9:105:10 | s2 | +| main.rs:105:14:105:20 | (...) ... | main.rs:105:9:105:10 | s2 | | main.rs:107:14:107:14 | [SSA] n | main.rs:107:25:107:25 | n | | main.rs:107:14:107:14 | n | main.rs:107:14:107:14 | [SSA] n | -| main.rs:107:20:107:26 | sink(...) | main.rs:106:5:109:5 | match ... { ... } | -| main.rs:108:17:108:23 | sink(...) | main.rs:106:5:109:5 | match ... { ... } | +| main.rs:107:20:107:26 | (...) ... | main.rs:106:5:109:5 | match ... { ... } | +| main.rs:108:17:108:23 | (...) ... | main.rs:106:5:109:5 | match ... { ... } | | main.rs:110:5:113:5 | match ... { ... } | main.rs:103:27:114:1 | { ... } | | main.rs:111:14:111:14 | [SSA] n | main.rs:111:25:111:25 | n | | main.rs:111:14:111:14 | n | main.rs:111:14:111:14 | [SSA] n | -| main.rs:111:20:111:26 | sink(...) | main.rs:110:5:113:5 | match ... { ... } | -| main.rs:112:17:112:23 | sink(...) | main.rs:110:5:113:5 | match ... { ... } | +| main.rs:111:20:111:26 | (...) ... | main.rs:110:5:113:5 | match ... { ... } | +| main.rs:112:17:112:23 | (...) ... | main.rs:110:5:113:5 | match ... { ... } | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index b4c292a93d9..315c3580f3d 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -1,24 +1,24 @@ models edges -| main.rs:19:13:19:21 | source(...) : unit | main.rs:20:10:20:10 | s | provenance | | -| main.rs:24:13:24:21 | source(...) : unit | main.rs:27:10:27:10 | c | provenance | | -| main.rs:31:13:31:21 | source(...) : unit | main.rs:36:10:36:10 | b | provenance | | -| main.rs:45:15:45:23 | source(...) : unit | main.rs:47:10:47:10 | b | provenance | | +| main.rs:19:13:19:21 | (...) ... : unit | main.rs:20:10:20:10 | s | provenance | | +| main.rs:24:13:24:21 | (...) ... : unit | main.rs:27:10:27:10 | c | provenance | | +| main.rs:31:13:31:21 | (...) ... : unit | main.rs:36:10:36:10 | b | provenance | | +| main.rs:45:15:45:23 | (...) ... : unit | main.rs:47:10:47:10 | b | provenance | | nodes -| main.rs:15:10:15:18 | source(...) | semmle.label | source(...) | -| main.rs:19:13:19:21 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:15:10:15:18 | (...) ... | semmle.label | (...) ... | +| main.rs:19:13:19:21 | (...) ... : unit | semmle.label | (...) ... : unit | | main.rs:20:10:20:10 | s | semmle.label | s | -| main.rs:24:13:24:21 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:24:13:24:21 | (...) ... : unit | semmle.label | (...) ... : unit | | main.rs:27:10:27:10 | c | semmle.label | c | -| main.rs:31:13:31:21 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:31:13:31:21 | (...) ... : unit | semmle.label | (...) ... : unit | | main.rs:36:10:36:10 | b | semmle.label | b | -| main.rs:45:15:45:23 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:45:15:45:23 | (...) ... : unit | semmle.label | (...) ... : unit | | main.rs:47:10:47:10 | b | semmle.label | b | subpaths testFailures #select -| main.rs:15:10:15:18 | source(...) | main.rs:15:10:15:18 | source(...) | main.rs:15:10:15:18 | source(...) | $@ | main.rs:15:10:15:18 | source(...) | source(...) | -| main.rs:20:10:20:10 | s | main.rs:19:13:19:21 | source(...) : unit | main.rs:20:10:20:10 | s | $@ | main.rs:19:13:19:21 | source(...) : unit | source(...) : unit | -| main.rs:27:10:27:10 | c | main.rs:24:13:24:21 | source(...) : unit | main.rs:27:10:27:10 | c | $@ | main.rs:24:13:24:21 | source(...) : unit | source(...) : unit | -| main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | source(...) : unit | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | source(...) : unit | source(...) : unit | -| main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | source(...) : unit | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | source(...) : unit | source(...) : unit | +| main.rs:15:10:15:18 | (...) ... | main.rs:15:10:15:18 | (...) ... | main.rs:15:10:15:18 | (...) ... | $@ | main.rs:15:10:15:18 | (...) ... | (...) ... | +| main.rs:20:10:20:10 | s | main.rs:19:13:19:21 | (...) ... : unit | main.rs:20:10:20:10 | s | $@ | main.rs:19:13:19:21 | (...) ... : unit | (...) ... : unit | +| main.rs:27:10:27:10 | c | main.rs:24:13:24:21 | (...) ... : unit | main.rs:27:10:27:10 | c | $@ | main.rs:24:13:24:21 | (...) ... : unit | (...) ... : unit | +| main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | (...) ... : unit | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | (...) ... : unit | (...) ... : unit | +| main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | (...) ... : unit | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | (...) ... : unit | (...) ... : unit | diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index d8e9835b16a..323e946e4f9 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -1,6 +1,19 @@ from misc.codegen.lib.schemadefs import * from .ast import * +class LabelableExpr(Expr): + """ + The base class for expressions that can be labeled (`LoopExpr`, `ForExpr`, `WhileExpr` or `BlockExpr`). + """ + label: optional[Label] | child + +class LoopingExpr(LabelableExpr): + """ + The base class for expressions that loop (`LoopExpr`, `ForExpr` or `WhileExpr`). + """ + loop_body: optional["BlockExpr"] | child + + @annotate(Module) @rust.doc_test_signature(None) @@ -151,7 +164,7 @@ class _: """ -@annotate(BlockExpr) +@annotate(BlockExpr, replace_bases={Expr: LabelableExpr}) class _: """ A block expression. For example: @@ -167,9 +180,10 @@ class _: } ``` """ + label: drop -@annotate(LoopExpr) +@annotate(LoopExpr, replace_bases={Expr: LoopingExpr}) class _: """ A loop expression. For example: @@ -195,6 +209,8 @@ class _: }; ``` """ + label: drop + loop_body: drop class CallExprBase(Expr): @@ -990,7 +1006,7 @@ class _: """ -@annotate(ForExpr) +@annotate(ForExpr, replace_bases={Expr: LoopingExpr}) class _: """ A ForExpr. For example: @@ -998,6 +1014,8 @@ class _: todo!() ``` """ + label: drop + loop_body: drop @annotate(ForType) @@ -1744,7 +1762,7 @@ class _: """ -@annotate(WhileExpr) +@annotate(WhileExpr, replace_bases={Expr: LoopingExpr}) class _: """ A WhileExpr. For example: @@ -1752,6 +1770,8 @@ class _: todo!() ``` """ + label: drop + loop_body: drop @annotate(Function, add_bases=[Callable]) From fd45e11f4bd781ae403378930a0d407c96326f3b Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 20 Nov 2024 16:49:20 +0100 Subject: [PATCH 133/470] Rust: accept test changes --- .../generated/BlockExpr/BlockExpr.expected | 6 +- .../BlockExpr/BlockExpr_getLabel.expected | 2 +- .../BlockExpr/BlockExpr_getStmtList.expected | 2 +- .../generated/BoxPat/BoxPat.expected | 2 +- .../generated/BoxPat/BoxPat_getPat.expected | 2 +- .../generated/BreakExpr/BreakExpr.expected | 4 +- .../BreakExpr/BreakExpr_getExpr.expected | 4 +- .../BreakExpr/BreakExpr_getLifetime.expected | 4 +- .../CallExpr/CallExpr_getExpr.expected | 2 +- .../generated/CastExpr/CastExpr.expected | 2 +- .../CastExpr/CastExpr_getExpr.expected | 2 +- .../CastExpr/CastExpr_getTy.expected | 2 +- .../generated/Comment/Comment.expected | 14 +- .../ContinueExpr/ContinueExpr.expected | 2 +- .../ContinueExpr_getLifetime.expected | 2 +- .../generated/FieldExpr/FieldExpr.expected | 2 +- .../FieldExpr/FieldExpr_getExpr.expected | 2 +- .../FieldExpr/FieldExpr_getNameRef.expected | 2 +- .../generated/IfExpr/IfExpr.expected | 4 +- .../IfExpr/IfExpr_getCondition.expected | 4 +- .../generated/IfExpr/IfExpr_getElse.expected | 2 +- .../generated/IfExpr/IfExpr_getThen.expected | 4 +- .../generated/IndexExpr/IndexExpr.expected | 4 +- .../IndexExpr/IndexExpr_getBase.expected | 4 +- .../IndexExpr/IndexExpr_getIndex.expected | 4 +- .../generated/LetExpr/LetExpr.expected | 2 +- .../LetExpr/LetExpr_getExpr.expected | 2 +- .../generated/LetExpr/LetExpr_getPat.expected | 2 +- .../generated/LetStmt/LetStmt.expected | 12 +- .../LetStmt/LetStmt_getInitializer.expected | 8 +- .../LetStmt/LetStmt_getLetElse.expected | 2 +- .../generated/LetStmt/LetStmt_getPat.expected | 12 +- .../generated/LetStmt/LetStmt_getTy.expected | 4 +- .../generated/LoopExpr/LoopExpr.expected | 6 +- .../LoopExpr/LoopExpr_getLabel.expected | 2 +- .../LoopExpr/LoopExpr_getLoopBody.expected | 6 +- .../CONSISTENCY/DataFlowConsistency.expected | 2 +- .../generated/MatchArm/MatchArm.expected | 8 +- .../MatchArm/MatchArm_getExpr.expected | 8 +- .../MatchArm/MatchArm_getGuard.expected | 2 +- .../MatchArm/MatchArm_getPat.expected | 8 +- .../generated/MatchExpr/MatchExpr.expected | 4 +- .../MatchExpr/MatchExpr_getExpr.expected | 4 +- .../MatchExpr_getMatchArmList.expected | 4 +- .../generated/OrPat/OrPat.expected | 2 +- .../generated/OrPat/OrPat_getPat.expected | 4 +- .../generated/RangeExpr/RangeExpr.expected | 12 +- .../RangeExpr/RangeExpr_getEnd.expected | 8 +- .../RangeExpr_getOperatorName.expected | 12 +- .../RangeExpr/RangeExpr_getStart.expected | 6 +- .../RecordExprField/RecordExprField.expected | 4 +- .../RecordExprField_getExpr.expected | 4 +- .../RecordExprField_getNameRef.expected | 4 +- .../generated/RefExpr/RefExpr.expected | 8 +- .../RefExpr/RefExpr_getExpr.expected | 8 +- .../generated/RefPat/RefPat.expected | 2 +- .../generated/RefPat/RefPat_getPat.expected | 2 +- .../generated/ReturnExpr/ReturnExpr.expected | 2 +- .../ReturnExpr/ReturnExpr_getExpr.expected | 2 +- .../ql/test/extractor-tests/utf8/ast.expected | 2 +- .../controlflow-unstable/Cfg.expected | 44 +- .../dataflow/barrier/inline-flow.expected | 16 +- .../dataflow/global/viableCallable.expected | 42 +- .../dataflow/local/DataFlowStep.expected | 42 +- .../dataflow/local/inline-flow.expected | 28 +- .../test/library-tests/variables/Cfg.expected | 530 +++++++++--------- .../test/library-tests/variables/Ssa.expected | 8 +- .../variables/variables.expected | 470 +++++++++++++++- .../ExtractionConsistency.expected | 1 - .../CONSISTENCY/DataFlowConsistency.expected | 14 - 70 files changed, 955 insertions(+), 504 deletions(-) diff --git a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.expected b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.expected index 3efd724a013..b832addc799 100644 --- a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.expected +++ b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.expected @@ -1,3 +1,3 @@ -| gen_block_expr.rs:3:28:12:1 | { ... } | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasLabel: | no | hasStmtList: | yes | -| gen_block_expr.rs:5:5:7:5 | { ... } | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasLabel: | no | hasStmtList: | yes | -| gen_block_expr.rs:8:5:11:5 | { ... } | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasLabel: | yes | hasStmtList: | yes | +| gen_block_expr.rs:3:28:12:1 | { ... } | hasLabel: | no | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasStmtList: | yes | +| gen_block_expr.rs:5:5:7:5 | { ... } | hasLabel: | no | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasStmtList: | yes | +| gen_block_expr.rs:8:5:11:5 | ''label: { ... } | hasLabel: | yes | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasStmtList: | yes | diff --git a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getLabel.expected b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getLabel.expected index 354199e9a07..289a157b0dc 100644 --- a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getLabel.expected +++ b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getLabel.expected @@ -1 +1 @@ -| gen_block_expr.rs:8:5:11:5 | { ... } | gen_block_expr.rs:8:5:8:11 | ''label | +| gen_block_expr.rs:8:5:11:5 | ''label: { ... } | gen_block_expr.rs:8:5:8:11 | ''label | diff --git a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getStmtList.expected b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getStmtList.expected index 226f5770392..582cff1a3cb 100644 --- a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getStmtList.expected +++ b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getStmtList.expected @@ -1,3 +1,3 @@ | gen_block_expr.rs:3:28:12:1 | { ... } | gen_block_expr.rs:3:28:12:1 | StmtList | | gen_block_expr.rs:5:5:7:5 | { ... } | gen_block_expr.rs:5:5:7:5 | StmtList | -| gen_block_expr.rs:8:5:11:5 | { ... } | gen_block_expr.rs:8:13:11:5 | StmtList | +| gen_block_expr.rs:8:5:11:5 | ''label: { ... } | gen_block_expr.rs:8:13:11:5 | StmtList | diff --git a/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat.expected b/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat.expected index 20bc2bf7cc1..810704f963e 100644 --- a/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat.expected +++ b/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat.expected @@ -1,2 +1,2 @@ | gen_box_pat.rs:6:9:6:27 | box ... | hasPat: | yes | -| gen_box_pat.rs:7:9:7:24 | box ... | hasPat: | yes | +| gen_box_pat.rs:7:9:7:24 | box Option::None | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat_getPat.expected b/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat_getPat.expected index d98d750d3a8..f30ce324802 100644 --- a/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat_getPat.expected @@ -1,2 +1,2 @@ | gen_box_pat.rs:6:9:6:27 | box ... | gen_box_pat.rs:6:13:6:27 | TupleStructPat | -| gen_box_pat.rs:7:9:7:24 | box ... | gen_box_pat.rs:7:13:7:24 | Option::None | +| gen_box_pat.rs:7:9:7:24 | box Option::None | gen_box_pat.rs:7:13:7:24 | Option::None | diff --git a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected index 2ffdacb6890..30c734fd682 100644 --- a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected +++ b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected @@ -1,3 +1,3 @@ | gen_break_expr.rs:7:13:7:17 | break | getNumberOfAttrs: | 0 | hasExpr: | no | hasLifetime: | no | -| gen_break_expr.rs:12:13:12:27 | break ''label ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | -| gen_break_expr.rs:17:13:17:27 | break ''label ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | +| gen_break_expr.rs:12:13:12:27 | break ''label 42 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | +| gen_break_expr.rs:17:13:17:27 | break ''label 42 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | diff --git a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected index 864069115df..20c5295354a 100644 --- a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected @@ -1,2 +1,2 @@ -| gen_break_expr.rs:12:13:12:27 | break ''label ... | gen_break_expr.rs:12:26:12:27 | 42 | -| gen_break_expr.rs:17:13:17:27 | break ''label ... | gen_break_expr.rs:17:26:17:27 | 42 | +| gen_break_expr.rs:12:13:12:27 | break ''label 42 | gen_break_expr.rs:12:26:12:27 | 42 | +| gen_break_expr.rs:17:13:17:27 | break ''label 42 | gen_break_expr.rs:17:26:17:27 | 42 | diff --git a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected index adbf9b15ff2..2e1a8801795 100644 --- a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected +++ b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected @@ -1,2 +1,2 @@ -| gen_break_expr.rs:12:13:12:27 | break ''label ... | gen_break_expr.rs:12:19:12:24 | ''label | -| gen_break_expr.rs:17:13:17:27 | break ''label ... | gen_break_expr.rs:17:19:17:24 | ''label | +| gen_break_expr.rs:12:13:12:27 | break ''label 42 | gen_break_expr.rs:12:19:12:24 | ''label | +| gen_break_expr.rs:17:13:17:27 | break ''label 42 | gen_break_expr.rs:17:19:17:24 | ''label | diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.expected index 68113cf5725..ecaaf15cebb 100644 --- a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.expected @@ -1,4 +1,4 @@ | gen_call_expr.rs:5:5:5:11 | foo(...) | gen_call_expr.rs:5:5:5:7 | foo | | gen_call_expr.rs:6:5:6:23 | foo::<...>(...) | gen_call_expr.rs:6:5:6:19 | foo::<...> | -| gen_call_expr.rs:7:5:7:14 | ...(...) | gen_call_expr.rs:7:5:7:10 | ...[...] | +| gen_call_expr.rs:7:5:7:14 | ...(...) | gen_call_expr.rs:7:5:7:10 | foo[0] | | gen_call_expr.rs:8:5:8:10 | foo(...) | gen_call_expr.rs:8:5:8:7 | foo | diff --git a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected index 157e06c3f2b..c85e4186631 100644 --- a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected @@ -1 +1 @@ -| gen_cast_expr.rs:5:5:5:16 | ... as u64 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasTy: | yes | +| gen_cast_expr.rs:5:5:5:16 | value as u64 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasTy: | yes | diff --git a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected index fda7db77d90..01a710bfb53 100644 --- a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected @@ -1 +1 @@ -| gen_cast_expr.rs:5:5:5:16 | ... as u64 | gen_cast_expr.rs:5:5:5:9 | value | +| gen_cast_expr.rs:5:5:5:16 | value as u64 | gen_cast_expr.rs:5:5:5:9 | value | diff --git a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected index 90fa37e4f97..87c07babb02 100644 --- a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected +++ b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected @@ -1 +1 @@ -| gen_cast_expr.rs:5:5:5:16 | ... as u64 | gen_cast_expr.rs:5:14:5:16 | u64 | +| gen_cast_expr.rs:5:5:5:16 | value as u64 | gen_cast_expr.rs:5:14:5:16 | u64 | diff --git a/rust/ql/test/extractor-tests/generated/Comment/Comment.expected b/rust/ql/test/extractor-tests/generated/Comment/Comment.expected index 21861bb40bf..24e95f123d8 100644 --- a/rust/ql/test/extractor-tests/generated/Comment/Comment.expected +++ b/rust/ql/test/extractor-tests/generated/Comment/Comment.expected @@ -1,7 +1,7 @@ -| comments.rs:1:1:3:2 | Comment | getParent: | comments.rs:1:1:9:1 | foo | getText: | /** \n* A doc comment\n*/ | -| comments.rs:6:17:6:34 | Comment | getParent: | comments.rs:6:17:8:16 | nested | getText: | // print some text | -| comments.rs:7:3:7:31 | Comment | getParent: | comments.rs:6:17:8:16 | nested | getText: | /// This is a nested function | -| gen_comment.rs:1:1:1:36 | Comment | getParent: | gen_comment.rs:1:1:7:2 | SourceFile | getText: | // generated by codegen, do not edit | -| gen_comment.rs:4:5:4:30 | Comment | getParent: | gen_comment.rs:3:25:7:1 | StmtList | getText: | // A comment. For example: | -| gen_comment.rs:5:5:5:24 | Comment | getParent: | gen_comment.rs:3:25:7:1 | StmtList | getText: | // this is a comment | -| gen_comment.rs:6:5:6:29 | Comment | getParent: | gen_comment.rs:3:25:7:1 | StmtList | getText: | /// This is a doc comment | +| comments.rs:1:1:3:2 | /**...*/ | getParent: | comments.rs:1:1:9:1 | fn foo | getText: | /** \n* A doc comment\n*/ | +| comments.rs:6:17:6:34 | //... | getParent: | comments.rs:6:17:8:16 | fn nested | getText: | // print some text | +| comments.rs:7:3:7:31 | ///... | getParent: | comments.rs:6:17:8:16 | fn nested | getText: | /// This is a nested function | +| gen_comment.rs:1:1:1:36 | //... | getParent: | gen_comment.rs:1:1:7:2 | SourceFile | getText: | // generated by codegen, do not edit | +| gen_comment.rs:4:5:4:30 | //... | getParent: | gen_comment.rs:3:25:7:1 | StmtList | getText: | // A comment. For example: | +| gen_comment.rs:5:5:5:24 | //... | getParent: | gen_comment.rs:3:25:7:1 | StmtList | getText: | // this is a comment | +| gen_comment.rs:6:5:6:29 | ///... | getParent: | gen_comment.rs:3:25:7:1 | StmtList | getText: | /// This is a doc comment | diff --git a/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr.expected b/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr.expected index a09556b9a3f..f2c4e28c337 100644 --- a/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr.expected +++ b/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr.expected @@ -1,2 +1,2 @@ | gen_continue_expr.rs:7:13:7:20 | continue | getNumberOfAttrs: | 0 | hasLifetime: | no | -| gen_continue_expr.rs:12:13:12:27 | continue 'label | getNumberOfAttrs: | 0 | hasLifetime: | yes | +| gen_continue_expr.rs:12:13:12:27 | continue ''label | getNumberOfAttrs: | 0 | hasLifetime: | yes | diff --git a/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected b/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected index d81d276ce0a..f4fa30ade3c 100644 --- a/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected +++ b/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected @@ -1 +1 @@ -| gen_continue_expr.rs:12:13:12:27 | continue 'label | gen_continue_expr.rs:12:22:12:27 | ''label | +| gen_continue_expr.rs:12:13:12:27 | continue ''label | gen_continue_expr.rs:12:22:12:27 | ''label | diff --git a/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr.expected b/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr.expected index 912f65f43e3..c25a0633e40 100644 --- a/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr.expected +++ b/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr.expected @@ -1 +1 @@ -| gen_field_expr.rs:5:5:5:9 | ... .foo | getNumberOfAttrs: | 0 | hasExpr: | yes | hasNameRef: | yes | +| gen_field_expr.rs:5:5:5:9 | x.foo | getNumberOfAttrs: | 0 | hasExpr: | yes | hasNameRef: | yes | diff --git a/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getExpr.expected index ac80547d5ca..7d21f7f7af8 100644 --- a/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getExpr.expected @@ -1 +1 @@ -| gen_field_expr.rs:5:5:5:9 | ... .foo | gen_field_expr.rs:5:5:5:5 | x | +| gen_field_expr.rs:5:5:5:9 | x.foo | gen_field_expr.rs:5:5:5:5 | x | diff --git a/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getNameRef.expected b/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getNameRef.expected index 743f58b5741..0722ca1aaf2 100644 --- a/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getNameRef.expected +++ b/rust/ql/test/extractor-tests/generated/FieldExpr/FieldExpr_getNameRef.expected @@ -1 +1 @@ -| gen_field_expr.rs:5:5:5:9 | ... .foo | gen_field_expr.rs:5:7:5:9 | foo | +| gen_field_expr.rs:5:5:5:9 | x.foo | gen_field_expr.rs:5:7:5:9 | foo | diff --git a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr.expected b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr.expected index 6c40caaae5c..d9a33ad74f7 100644 --- a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr.expected +++ b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr.expected @@ -1,2 +1,2 @@ -| gen_if_expr.rs:5:5:7:5 | if ... { ... } | getNumberOfAttrs: | 0 | hasCondition: | yes | hasElse: | no | hasThen: | yes | -| gen_if_expr.rs:8:13:12:5 | if ... { ... } else { ... } | getNumberOfAttrs: | 0 | hasCondition: | yes | hasElse: | yes | hasThen: | yes | +| gen_if_expr.rs:5:5:7:5 | if ... {...} | getNumberOfAttrs: | 0 | hasCondition: | yes | hasElse: | no | hasThen: | yes | +| gen_if_expr.rs:8:13:12:5 | if ... {...} else {...} | getNumberOfAttrs: | 0 | hasCondition: | yes | hasElse: | yes | hasThen: | yes | diff --git a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getCondition.expected b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getCondition.expected index 9dc91afd773..4990a47bc96 100644 --- a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getCondition.expected +++ b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getCondition.expected @@ -1,2 +1,2 @@ -| gen_if_expr.rs:5:5:7:5 | if ... { ... } | gen_if_expr.rs:5:8:5:14 | ... == ... | -| gen_if_expr.rs:8:13:12:5 | if ... { ... } else { ... } | gen_if_expr.rs:8:16:8:20 | ... > ... | +| gen_if_expr.rs:5:5:7:5 | if ... {...} | gen_if_expr.rs:5:8:5:14 | ... == ... | +| gen_if_expr.rs:8:13:12:5 | if ... {...} else {...} | gen_if_expr.rs:8:16:8:20 | ... > ... | diff --git a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getElse.expected b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getElse.expected index 4f8d79008e6..a03626f5e5d 100644 --- a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getElse.expected +++ b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getElse.expected @@ -1 +1 @@ -| gen_if_expr.rs:8:13:12:5 | if ... { ... } else { ... } | gen_if_expr.rs:10:12:12:5 | { ... } | +| gen_if_expr.rs:8:13:12:5 | if ... {...} else {...} | gen_if_expr.rs:10:12:12:5 | { ... } | diff --git a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getThen.expected b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getThen.expected index 961cb118409..6080b004f38 100644 --- a/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getThen.expected +++ b/rust/ql/test/extractor-tests/generated/IfExpr/IfExpr_getThen.expected @@ -1,2 +1,2 @@ -| gen_if_expr.rs:5:5:7:5 | if ... { ... } | gen_if_expr.rs:5:16:7:5 | { ... } | -| gen_if_expr.rs:8:13:12:5 | if ... { ... } else { ... } | gen_if_expr.rs:8:22:10:5 | { ... } | +| gen_if_expr.rs:5:5:7:5 | if ... {...} | gen_if_expr.rs:5:16:7:5 | { ... } | +| gen_if_expr.rs:8:13:12:5 | if ... {...} else {...} | gen_if_expr.rs:8:22:10:5 | { ... } | diff --git a/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr.expected b/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr.expected index e737827e89f..614afc3040f 100644 --- a/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr.expected +++ b/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr.expected @@ -1,2 +1,2 @@ -| gen_index_expr.rs:5:5:5:12 | ...[...] | getNumberOfAttrs: | 0 | hasBase: | yes | hasIndex: | yes | -| gen_index_expr.rs:6:5:6:12 | ...[...] | getNumberOfAttrs: | 0 | hasBase: | yes | hasIndex: | yes | +| gen_index_expr.rs:5:5:5:12 | list[42] | getNumberOfAttrs: | 0 | hasBase: | yes | hasIndex: | yes | +| gen_index_expr.rs:6:5:6:12 | list[42] | getNumberOfAttrs: | 0 | hasBase: | yes | hasIndex: | yes | diff --git a/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getBase.expected b/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getBase.expected index fc1e9720fab..13fb9a2c6a6 100644 --- a/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getBase.expected +++ b/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getBase.expected @@ -1,2 +1,2 @@ -| gen_index_expr.rs:5:5:5:12 | ...[...] | gen_index_expr.rs:5:5:5:8 | list | -| gen_index_expr.rs:6:5:6:12 | ...[...] | gen_index_expr.rs:6:5:6:8 | list | +| gen_index_expr.rs:5:5:5:12 | list[42] | gen_index_expr.rs:5:5:5:8 | list | +| gen_index_expr.rs:6:5:6:12 | list[42] | gen_index_expr.rs:6:5:6:8 | list | diff --git a/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getIndex.expected b/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getIndex.expected index 21c6228d5b9..dfca8204088 100644 --- a/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getIndex.expected +++ b/rust/ql/test/extractor-tests/generated/IndexExpr/IndexExpr_getIndex.expected @@ -1,2 +1,2 @@ -| gen_index_expr.rs:5:5:5:12 | ...[...] | gen_index_expr.rs:5:10:5:11 | 42 | -| gen_index_expr.rs:6:5:6:12 | ...[...] | gen_index_expr.rs:6:10:6:11 | 42 | +| gen_index_expr.rs:5:5:5:12 | list[42] | gen_index_expr.rs:5:10:5:11 | 42 | +| gen_index_expr.rs:6:5:6:12 | list[42] | gen_index_expr.rs:6:10:6:11 | 42 | diff --git a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.expected b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.expected index 6c6343e24d3..7ff5ad393e1 100644 --- a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.expected +++ b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.expected @@ -1 +1 @@ -| gen_let_expr.rs:5:8:5:31 | let TupleStructPat = ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasPat: | yes | +| gen_let_expr.rs:5:8:5:31 | let ... = maybe_some | getNumberOfAttrs: | 0 | hasExpr: | yes | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.expected index 9293ae80e1d..0080ab4ee6e 100644 --- a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.expected @@ -1 +1 @@ -| gen_let_expr.rs:5:8:5:31 | let TupleStructPat = ... | gen_let_expr.rs:5:22:5:31 | maybe_some | +| gen_let_expr.rs:5:8:5:31 | let ... = maybe_some | gen_let_expr.rs:5:22:5:31 | maybe_some | diff --git a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getPat.expected b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getPat.expected index 527a9fcc3a9..7c31e314128 100644 --- a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getPat.expected @@ -1 +1 @@ -| gen_let_expr.rs:5:8:5:31 | let TupleStructPat = ... | gen_let_expr.rs:5:12:5:18 | TupleStructPat | +| gen_let_expr.rs:5:8:5:31 | let ... = maybe_some | gen_let_expr.rs:5:12:5:18 | TupleStructPat | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt.expected index e433b420d4e..87c62a65a3a 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt.expected @@ -1,6 +1,6 @@ -| gen_let_stmt.rs:5:5:5:15 | let x = ... | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | no | hasPat: | yes | hasTy: | no | -| gen_let_stmt.rs:6:5:6:20 | let x = ... | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | no | hasPat: | yes | hasTy: | yes | -| gen_let_stmt.rs:7:5:7:15 | let x | getNumberOfAttrs: | 0 | hasInitializer: | no | hasLetElse: | no | hasPat: | yes | hasTy: | yes | -| gen_let_stmt.rs:8:5:8:10 | let x | getNumberOfAttrs: | 0 | hasInitializer: | no | hasLetElse: | no | hasPat: | yes | hasTy: | no | -| gen_let_stmt.rs:9:5:9:24 | let TuplePat = ... | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | no | hasPat: | yes | hasTy: | no | -| gen_let_stmt.rs:10:5:12:6 | let TupleStructPat = ... else { ... } | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | yes | hasPat: | yes | hasTy: | no | +| gen_let_stmt.rs:5:5:5:15 | let ... = 42 | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | no | hasPat: | yes | hasTy: | no | +| gen_let_stmt.rs:6:5:6:20 | let ... = 42 | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | no | hasPat: | yes | hasTy: | yes | +| gen_let_stmt.rs:7:5:7:15 | let ... | getNumberOfAttrs: | 0 | hasInitializer: | no | hasLetElse: | no | hasPat: | yes | hasTy: | yes | +| gen_let_stmt.rs:8:5:8:10 | let ... | getNumberOfAttrs: | 0 | hasInitializer: | no | hasLetElse: | no | hasPat: | yes | hasTy: | no | +| gen_let_stmt.rs:9:5:9:24 | let ... = ... | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | no | hasPat: | yes | hasTy: | no | +| gen_let_stmt.rs:10:5:12:6 | let ... = ... else { ... } | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | yes | hasPat: | yes | hasTy: | no | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected index a7323b834b3..a88557f9d70 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected @@ -1,4 +1,4 @@ -| gen_let_stmt.rs:5:5:5:15 | let x = ... | gen_let_stmt.rs:5:13:5:14 | 42 | -| gen_let_stmt.rs:6:5:6:20 | let x = ... | gen_let_stmt.rs:6:18:6:19 | 42 | -| gen_let_stmt.rs:9:5:9:24 | let TuplePat = ... | gen_let_stmt.rs:9:18:9:23 | TupleExpr | -| gen_let_stmt.rs:10:5:12:6 | let TupleStructPat = ... else { ... } | gen_let_stmt.rs:10:19:10:38 | std::env::var(...) | +| gen_let_stmt.rs:5:5:5:15 | let ... = 42 | gen_let_stmt.rs:5:13:5:14 | 42 | +| gen_let_stmt.rs:6:5:6:20 | let ... = 42 | gen_let_stmt.rs:6:18:6:19 | 42 | +| gen_let_stmt.rs:9:5:9:24 | let ... = ... | gen_let_stmt.rs:9:18:9:23 | TupleExpr | +| gen_let_stmt.rs:10:5:12:6 | let ... = ... else { ... } | gen_let_stmt.rs:10:19:10:38 | std::env::var(...) | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getLetElse.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getLetElse.expected index a0531cdba9e..84efa0be3b2 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getLetElse.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getLetElse.expected @@ -1 +1 @@ -| gen_let_stmt.rs:10:5:12:6 | let TupleStructPat = ... else { ... } | gen_let_stmt.rs:10:40:12:5 | else { ... } | +| gen_let_stmt.rs:10:5:12:6 | let ... = ... else { ... } | gen_let_stmt.rs:10:40:12:5 | else { ... } | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected index 09a185a51bd..e2aa2b9e957 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected @@ -1,6 +1,6 @@ -| gen_let_stmt.rs:5:5:5:15 | let x = ... | gen_let_stmt.rs:5:9:5:9 | x | -| gen_let_stmt.rs:6:5:6:20 | let x = ... | gen_let_stmt.rs:6:9:6:9 | x | -| gen_let_stmt.rs:7:5:7:15 | let x | gen_let_stmt.rs:7:9:7:9 | x | -| gen_let_stmt.rs:8:5:8:10 | let x | gen_let_stmt.rs:8:9:8:9 | x | -| gen_let_stmt.rs:9:5:9:24 | let TuplePat = ... | gen_let_stmt.rs:9:9:9:14 | TuplePat | -| gen_let_stmt.rs:10:5:12:6 | let TupleStructPat = ... else { ... } | gen_let_stmt.rs:10:9:10:15 | TupleStructPat | +| gen_let_stmt.rs:5:5:5:15 | let ... = 42 | gen_let_stmt.rs:5:9:5:9 | x | +| gen_let_stmt.rs:6:5:6:20 | let ... = 42 | gen_let_stmt.rs:6:9:6:9 | x | +| gen_let_stmt.rs:7:5:7:15 | let ... | gen_let_stmt.rs:7:9:7:9 | x | +| gen_let_stmt.rs:8:5:8:10 | let ... | gen_let_stmt.rs:8:9:8:9 | x | +| gen_let_stmt.rs:9:5:9:24 | let ... = ... | gen_let_stmt.rs:9:9:9:14 | TuplePat | +| gen_let_stmt.rs:10:5:12:6 | let ... = ... else { ... } | gen_let_stmt.rs:10:9:10:15 | TupleStructPat | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected index f00814567d3..489647f4793 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected @@ -1,2 +1,2 @@ -| gen_let_stmt.rs:6:5:6:20 | let x = ... | gen_let_stmt.rs:6:12:6:14 | i32 | -| gen_let_stmt.rs:7:5:7:15 | let x | gen_let_stmt.rs:7:12:7:14 | i32 | +| gen_let_stmt.rs:6:5:6:20 | let ... = 42 | gen_let_stmt.rs:6:12:6:14 | i32 | +| gen_let_stmt.rs:7:5:7:15 | let ... | gen_let_stmt.rs:7:12:7:14 | i32 | diff --git a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.expected b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.expected index 9cb3238c825..f7129b16385 100644 --- a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.expected +++ b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.expected @@ -1,3 +1,3 @@ -| gen_loop_expr.rs:5:5:7:5 | loop {...} | getNumberOfAttrs: | 0 | hasLabel: | no | hasLoopBody: | yes | -| gen_loop_expr.rs:8:5:11:5 | loop {...} | getNumberOfAttrs: | 0 | hasLabel: | yes | hasLoopBody: | yes | -| gen_loop_expr.rs:13:5:19:5 | loop {...} | getNumberOfAttrs: | 0 | hasLabel: | no | hasLoopBody: | yes | +| gen_loop_expr.rs:5:5:7:5 | loop { ... } | hasLabel: | no | hasLoopBody: | yes | getNumberOfAttrs: | 0 | +| gen_loop_expr.rs:8:5:11:5 | ''label: loop { ... } | hasLabel: | yes | hasLoopBody: | yes | getNumberOfAttrs: | 0 | +| gen_loop_expr.rs:13:5:19:5 | loop { ... } | hasLabel: | no | hasLoopBody: | yes | getNumberOfAttrs: | 0 | diff --git a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLabel.expected b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLabel.expected index 6a71a241413..167f84096fe 100644 --- a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLabel.expected +++ b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLabel.expected @@ -1 +1 @@ -| gen_loop_expr.rs:8:5:11:5 | loop {...} | gen_loop_expr.rs:8:5:8:11 | ''label | +| gen_loop_expr.rs:8:5:11:5 | ''label: loop { ... } | gen_loop_expr.rs:8:5:8:11 | ''label | diff --git a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.expected b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.expected index 18a1091d89a..952955da19d 100644 --- a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.expected +++ b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.expected @@ -1,3 +1,3 @@ -| gen_loop_expr.rs:5:5:7:5 | loop {...} | gen_loop_expr.rs:5:10:7:5 | { ... } | -| gen_loop_expr.rs:8:5:11:5 | loop {...} | gen_loop_expr.rs:8:18:11:5 | { ... } | -| gen_loop_expr.rs:13:5:19:5 | loop {...} | gen_loop_expr.rs:13:10:19:5 | { ... } | +| gen_loop_expr.rs:5:5:7:5 | loop { ... } | gen_loop_expr.rs:5:10:7:5 | { ... } | +| gen_loop_expr.rs:8:5:11:5 | ''label: loop { ... } | gen_loop_expr.rs:8:18:11:5 | { ... } | +| gen_loop_expr.rs:13:5:19:5 | loop { ... } | gen_loop_expr.rs:13:10:19:5 | { ... } | diff --git a/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected index b7a9f37a672..6f8a83cb913 100644 --- a/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected +++ b/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected @@ -1,9 +1,9 @@ uniqueNodeLocation | file://:0:0:0:0 | ... .parent(...) | Node should have one location but has 0. | | file://:0:0:0:0 | ... .unwrap(...) | Node should have one location but has 0. | +| file://:0:0:0:0 | ...: ... | Node should have one location but has 0. | | file://:0:0:0:0 | path | Node should have one location but has 0. | | file://:0:0:0:0 | path | Node should have one location but has 0. | -| file://:0:0:0:0 | path: RefType | Node should have one location but has 0. | | file://:0:0:0:0 | { ... } | Node should have one location but has 0. | missingLocation | Nodes without location: 6 | diff --git a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm.expected b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm.expected index 34033eeee08..d21faa7ff19 100644 --- a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm.expected +++ b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm.expected @@ -1,4 +1,4 @@ -| gen_match_arm.rs:6:9:6:29 | TupleStructPat => ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | -| gen_match_arm.rs:7:9:7:26 | Option::None => ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | -| gen_match_arm.rs:10:9:10:35 | TupleStructPatif ... => ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | yes | hasPat: | yes | -| gen_match_arm.rs:11:9:11:15 | _ => ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | +| gen_match_arm.rs:6:9:6:29 | ... => y | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | +| gen_match_arm.rs:7:9:7:26 | Option::None => 0 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | +| gen_match_arm.rs:10:9:10:35 | ... if ... => ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | yes | hasPat: | yes | +| gen_match_arm.rs:11:9:11:15 | _ => 0 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getExpr.expected b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getExpr.expected index 493ea8d9bb0..ecf8098fd78 100644 --- a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getExpr.expected @@ -1,4 +1,4 @@ -| gen_match_arm.rs:6:9:6:29 | MatchArm | gen_match_arm.rs:6:28:6:28 | y | -| gen_match_arm.rs:7:9:7:26 | MatchArm | gen_match_arm.rs:7:25:7:25 | 0 | -| gen_match_arm.rs:10:9:10:35 | MatchArm | gen_match_arm.rs:10:30:10:34 | ... / ... | -| gen_match_arm.rs:11:9:11:15 | MatchArm | gen_match_arm.rs:11:14:11:14 | 0 | +| gen_match_arm.rs:6:9:6:29 | ... => y | gen_match_arm.rs:6:28:6:28 | y | +| gen_match_arm.rs:7:9:7:26 | Option::None => 0 | gen_match_arm.rs:7:25:7:25 | 0 | +| gen_match_arm.rs:10:9:10:35 | ... if ... => ... | gen_match_arm.rs:10:30:10:34 | ... / ... | +| gen_match_arm.rs:11:9:11:15 | _ => 0 | gen_match_arm.rs:11:14:11:14 | 0 | diff --git a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getGuard.expected b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getGuard.expected index ad59397e84a..00291745547 100644 --- a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getGuard.expected +++ b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getGuard.expected @@ -1 +1 @@ -| gen_match_arm.rs:10:9:10:35 | TupleStructPatif ... => ... | gen_match_arm.rs:10:17:10:25 | MatchGuard | +| gen_match_arm.rs:10:9:10:35 | ... if ... => ... | gen_match_arm.rs:10:17:10:25 | MatchGuard | diff --git a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getPat.expected b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getPat.expected index 2d8cf38991d..010c7b50b06 100644 --- a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getPat.expected @@ -1,4 +1,4 @@ -| gen_match_arm.rs:6:9:6:29 | TupleStructPat => ... | gen_match_arm.rs:6:9:6:23 | TupleStructPat | -| gen_match_arm.rs:7:9:7:26 | Option::None => ... | gen_match_arm.rs:7:9:7:20 | Option::None | -| gen_match_arm.rs:10:9:10:35 | TupleStructPatif ... => ... | gen_match_arm.rs:10:9:10:15 | TupleStructPat | -| gen_match_arm.rs:11:9:11:15 | _ => ... | gen_match_arm.rs:11:9:11:9 | _ | +| gen_match_arm.rs:6:9:6:29 | ... => y | gen_match_arm.rs:6:9:6:23 | TupleStructPat | +| gen_match_arm.rs:7:9:7:26 | Option::None => 0 | gen_match_arm.rs:7:9:7:20 | Option::None | +| gen_match_arm.rs:10:9:10:35 | ... if ... => ... | gen_match_arm.rs:10:9:10:15 | TupleStructPat | +| gen_match_arm.rs:11:9:11:15 | _ => 0 | gen_match_arm.rs:11:9:11:9 | _ | diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected index ae8f3edb665..b98c3de696b 100644 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected @@ -1,2 +1,2 @@ -| gen_match_expr.rs:5:5:8:5 | match ... { ... } | getNumberOfAttrs: | 0 | hasExpr: | yes | hasMatchArmList: | yes | -| gen_match_expr.rs:9:5:12:5 | match ... { ... } | getNumberOfAttrs: | 0 | hasExpr: | yes | hasMatchArmList: | yes | +| gen_match_expr.rs:5:5:8:5 | match x { ... } | getNumberOfAttrs: | 0 | hasExpr: | yes | hasMatchArmList: | yes | +| gen_match_expr.rs:9:5:12:5 | match x { ... } | getNumberOfAttrs: | 0 | hasExpr: | yes | hasMatchArmList: | yes | diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.expected index ac1ec296029..427af7c6ed0 100644 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.expected @@ -1,2 +1,2 @@ -| gen_match_expr.rs:5:5:8:5 | match ... { ... } | gen_match_expr.rs:5:11:5:11 | x | -| gen_match_expr.rs:9:5:12:5 | match ... { ... } | gen_match_expr.rs:9:11:9:11 | x | +| gen_match_expr.rs:5:5:8:5 | match x { ... } | gen_match_expr.rs:5:11:5:11 | x | +| gen_match_expr.rs:9:5:12:5 | match x { ... } | gen_match_expr.rs:9:11:9:11 | x | diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchArmList.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchArmList.expected index 468fe9d14cf..f5e25db5b39 100644 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchArmList.expected +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchArmList.expected @@ -1,2 +1,2 @@ -| gen_match_expr.rs:5:5:8:5 | match ... { ... } | gen_match_expr.rs:5:13:8:5 | MatchArmList | -| gen_match_expr.rs:9:5:12:5 | match ... { ... } | gen_match_expr.rs:9:13:12:5 | MatchArmList | +| gen_match_expr.rs:5:5:8:5 | match x { ... } | gen_match_expr.rs:5:13:8:5 | MatchArmList | +| gen_match_expr.rs:9:5:12:5 | match x { ... } | gen_match_expr.rs:9:13:12:5 | MatchArmList | diff --git a/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected b/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected index 3574d6c1828..f4268aea84f 100644 --- a/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected +++ b/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected @@ -1 +1 @@ -| gen_or_pat.rs:6:9:6:38 | ... \| ... | getNumberOfPats: | 2 | +| gen_or_pat.rs:6:9:6:38 | ...Option::None | getNumberOfPats: | 2 | diff --git a/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected b/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected index ca76590a626..e04c09875b5 100644 --- a/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected @@ -1,2 +1,2 @@ -| gen_or_pat.rs:6:9:6:38 | ... \| ... | 0 | gen_or_pat.rs:6:9:6:23 | TupleStructPat | -| gen_or_pat.rs:6:9:6:38 | ... \| ... | 1 | gen_or_pat.rs:6:27:6:38 | Option::None | +| gen_or_pat.rs:6:9:6:38 | ...Option::None | 0 | gen_or_pat.rs:6:9:6:23 | TupleStructPat | +| gen_or_pat.rs:6:9:6:38 | ...Option::None | 1 | gen_or_pat.rs:6:27:6:38 | Option::None | diff --git a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr.expected b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr.expected index de7e26d5197..7d8aeff6dfa 100644 --- a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr.expected +++ b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr.expected @@ -1,6 +1,6 @@ -| gen_range_expr.rs:5:13:5:18 | ... ..= ... | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | yes | -| gen_range_expr.rs:6:13:6:17 | ... .. ... | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | yes | -| gen_range_expr.rs:7:13:7:16 | ... .. ... | getNumberOfAttrs: | 0 | hasEnd: | no | hasOperatorName: | yes | hasStart: | yes | -| gen_range_expr.rs:8:13:8:16 | ... .. ... | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | no | -| gen_range_expr.rs:9:13:9:17 | ... ..= ... | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | no | -| gen_range_expr.rs:10:13:10:14 | ... .. ... | getNumberOfAttrs: | 0 | hasEnd: | no | hasOperatorName: | yes | hasStart: | no | +| gen_range_expr.rs:5:13:5:18 | 1..=10 | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | yes | +| gen_range_expr.rs:6:13:6:17 | 1..10 | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | yes | +| gen_range_expr.rs:7:13:7:16 | 10.. | getNumberOfAttrs: | 0 | hasEnd: | no | hasOperatorName: | yes | hasStart: | yes | +| gen_range_expr.rs:8:13:8:16 | ..10 | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | no | +| gen_range_expr.rs:9:13:9:17 | ..=10 | getNumberOfAttrs: | 0 | hasEnd: | yes | hasOperatorName: | yes | hasStart: | no | +| gen_range_expr.rs:10:13:10:14 | .. | getNumberOfAttrs: | 0 | hasEnd: | no | hasOperatorName: | yes | hasStart: | no | diff --git a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getEnd.expected b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getEnd.expected index 85582cfd97f..46f5dba778c 100644 --- a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getEnd.expected +++ b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getEnd.expected @@ -1,4 +1,4 @@ -| gen_range_expr.rs:5:13:5:18 | ... ..= ... | gen_range_expr.rs:5:17:5:18 | 10 | -| gen_range_expr.rs:6:13:6:17 | ... .. ... | gen_range_expr.rs:6:16:6:17 | 10 | -| gen_range_expr.rs:8:13:8:16 | ... .. ... | gen_range_expr.rs:8:15:8:16 | 10 | -| gen_range_expr.rs:9:13:9:17 | ... ..= ... | gen_range_expr.rs:9:16:9:17 | 10 | +| gen_range_expr.rs:5:13:5:18 | 1..=10 | gen_range_expr.rs:5:17:5:18 | 10 | +| gen_range_expr.rs:6:13:6:17 | 1..10 | gen_range_expr.rs:6:16:6:17 | 10 | +| gen_range_expr.rs:8:13:8:16 | ..10 | gen_range_expr.rs:8:15:8:16 | 10 | +| gen_range_expr.rs:9:13:9:17 | ..=10 | gen_range_expr.rs:9:16:9:17 | 10 | diff --git a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getOperatorName.expected b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getOperatorName.expected index ff6f77424c7..ee9172ac1ce 100644 --- a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getOperatorName.expected +++ b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getOperatorName.expected @@ -1,6 +1,6 @@ -| gen_range_expr.rs:5:13:5:18 | ... ..= ... | ..= | -| gen_range_expr.rs:6:13:6:17 | ... .. ... | .. | -| gen_range_expr.rs:7:13:7:16 | ... .. ... | .. | -| gen_range_expr.rs:8:13:8:16 | ... .. ... | .. | -| gen_range_expr.rs:9:13:9:17 | ... ..= ... | ..= | -| gen_range_expr.rs:10:13:10:14 | ... .. ... | .. | +| gen_range_expr.rs:5:13:5:18 | 1..=10 | ..= | +| gen_range_expr.rs:6:13:6:17 | 1..10 | .. | +| gen_range_expr.rs:7:13:7:16 | 10.. | .. | +| gen_range_expr.rs:8:13:8:16 | ..10 | .. | +| gen_range_expr.rs:9:13:9:17 | ..=10 | ..= | +| gen_range_expr.rs:10:13:10:14 | .. | .. | diff --git a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getStart.expected b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getStart.expected index 0a012e5ecd5..7f58ee5299f 100644 --- a/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getStart.expected +++ b/rust/ql/test/extractor-tests/generated/RangeExpr/RangeExpr_getStart.expected @@ -1,3 +1,3 @@ -| gen_range_expr.rs:5:13:5:18 | ... ..= ... | gen_range_expr.rs:5:13:5:13 | 1 | -| gen_range_expr.rs:6:13:6:17 | ... .. ... | gen_range_expr.rs:6:13:6:13 | 1 | -| gen_range_expr.rs:7:13:7:16 | ... .. ... | gen_range_expr.rs:7:13:7:14 | 10 | +| gen_range_expr.rs:5:13:5:18 | 1..=10 | gen_range_expr.rs:5:13:5:13 | 1 | +| gen_range_expr.rs:6:13:6:17 | 1..10 | gen_range_expr.rs:6:13:6:13 | 1 | +| gen_range_expr.rs:7:13:7:16 | 10.. | gen_range_expr.rs:7:13:7:14 | 10 | diff --git a/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField.expected b/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField.expected index 7f3dd059b0a..46e7ce811bb 100644 --- a/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField.expected +++ b/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField.expected @@ -1,2 +1,2 @@ -| gen_record_expr_field.rs:5:11:5:14 | a: ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasNameRef: | yes | -| gen_record_expr_field.rs:5:17:5:20 | b: ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasNameRef: | yes | +| gen_record_expr_field.rs:5:11:5:14 | a: 1 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasNameRef: | yes | +| gen_record_expr_field.rs:5:17:5:20 | b: 2 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasNameRef: | yes | diff --git a/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getExpr.expected b/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getExpr.expected index 2af437f842b..cfb89242449 100644 --- a/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getExpr.expected @@ -1,2 +1,2 @@ -| gen_record_expr_field.rs:5:11:5:14 | a: ... | gen_record_expr_field.rs:5:14:5:14 | 1 | -| gen_record_expr_field.rs:5:17:5:20 | b: ... | gen_record_expr_field.rs:5:20:5:20 | 2 | +| gen_record_expr_field.rs:5:11:5:14 | a: 1 | gen_record_expr_field.rs:5:14:5:14 | 1 | +| gen_record_expr_field.rs:5:17:5:20 | b: 2 | gen_record_expr_field.rs:5:20:5:20 | 2 | diff --git a/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getNameRef.expected b/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getNameRef.expected index d0fcb3d0d44..d0a3f82cd9d 100644 --- a/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getNameRef.expected +++ b/rust/ql/test/extractor-tests/generated/RecordExprField/RecordExprField_getNameRef.expected @@ -1,2 +1,2 @@ -| gen_record_expr_field.rs:5:11:5:14 | a: ... | gen_record_expr_field.rs:5:11:5:11 | a | -| gen_record_expr_field.rs:5:17:5:20 | b: ... | gen_record_expr_field.rs:5:17:5:17 | b | +| gen_record_expr_field.rs:5:11:5:14 | a: 1 | gen_record_expr_field.rs:5:11:5:11 | a | +| gen_record_expr_field.rs:5:17:5:20 | b: 2 | gen_record_expr_field.rs:5:17:5:17 | b | diff --git a/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr.expected b/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr.expected index df32a2465db..412f8214206 100644 --- a/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr.expected +++ b/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr.expected @@ -1,4 +1,4 @@ -| gen_ref_expr.rs:5:25:5:28 | &... | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | no | isMut: | no | isRaw: | no | -| gen_ref_expr.rs:6:23:6:30 | &mut ... | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | no | isMut: | yes | isRaw: | no | -| gen_ref_expr.rs:7:35:7:48 | &raw const ... | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | yes | isMut: | no | isRaw: | yes | -| gen_ref_expr.rs:8:33:8:44 | &raw mut ... | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | no | isMut: | yes | isRaw: | yes | +| gen_ref_expr.rs:5:25:5:28 | &foo | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | no | isMut: | no | isRaw: | no | +| gen_ref_expr.rs:6:23:6:30 | &mut foo | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | no | isMut: | yes | isRaw: | no | +| gen_ref_expr.rs:7:35:7:48 | &raw const foo | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | yes | isMut: | no | isRaw: | yes | +| gen_ref_expr.rs:8:33:8:44 | &raw mut foo | getNumberOfAttrs: | 0 | hasExpr: | yes | isConst: | no | isMut: | yes | isRaw: | yes | diff --git a/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr_getExpr.expected index b350b30b6a1..7709668f6fd 100644 --- a/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/RefExpr/RefExpr_getExpr.expected @@ -1,4 +1,4 @@ -| gen_ref_expr.rs:5:25:5:28 | &... | gen_ref_expr.rs:5:26:5:28 | foo | -| gen_ref_expr.rs:6:23:6:30 | &mut ... | gen_ref_expr.rs:6:28:6:30 | foo | -| gen_ref_expr.rs:7:35:7:48 | &raw const ... | gen_ref_expr.rs:7:46:7:48 | foo | -| gen_ref_expr.rs:8:33:8:44 | &raw mut ... | gen_ref_expr.rs:8:42:8:44 | foo | +| gen_ref_expr.rs:5:25:5:28 | &foo | gen_ref_expr.rs:5:26:5:28 | foo | +| gen_ref_expr.rs:6:23:6:30 | &mut foo | gen_ref_expr.rs:6:28:6:30 | foo | +| gen_ref_expr.rs:7:35:7:48 | &raw const foo | gen_ref_expr.rs:7:46:7:48 | foo | +| gen_ref_expr.rs:8:33:8:44 | &raw mut foo | gen_ref_expr.rs:8:42:8:44 | foo | diff --git a/rust/ql/test/extractor-tests/generated/RefPat/RefPat.expected b/rust/ql/test/extractor-tests/generated/RefPat/RefPat.expected index b851902ff56..3e52c12807e 100644 --- a/rust/ql/test/extractor-tests/generated/RefPat/RefPat.expected +++ b/rust/ql/test/extractor-tests/generated/RefPat/RefPat.expected @@ -1,2 +1,2 @@ | gen_ref_pat.rs:6:9:6:28 | &mut ... | isMut: | yes | hasPat: | yes | -| gen_ref_pat.rs:7:9:7:21 | &... | isMut: | no | hasPat: | yes | +| gen_ref_pat.rs:7:9:7:21 | &Option::None | isMut: | no | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/RefPat/RefPat_getPat.expected b/rust/ql/test/extractor-tests/generated/RefPat/RefPat_getPat.expected index 6078837ceea..96b017a42ea 100644 --- a/rust/ql/test/extractor-tests/generated/RefPat/RefPat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/RefPat/RefPat_getPat.expected @@ -1,2 +1,2 @@ | gen_ref_pat.rs:6:9:6:28 | &mut ... | gen_ref_pat.rs:6:14:6:28 | TupleStructPat | -| gen_ref_pat.rs:7:9:7:21 | &... | gen_ref_pat.rs:7:10:7:21 | Option::None | +| gen_ref_pat.rs:7:9:7:21 | &Option::None | gen_ref_pat.rs:7:10:7:21 | Option::None | diff --git a/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr.expected b/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr.expected index c1d4bfbb626..83220773989 100644 --- a/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr.expected +++ b/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr.expected @@ -1,2 +1,2 @@ -| gen_return_expr.rs:5:5:5:13 | return ... | getNumberOfAttrs: | 0 | hasExpr: | yes | +| gen_return_expr.rs:5:5:5:13 | return 42 | getNumberOfAttrs: | 0 | hasExpr: | yes | | gen_return_expr.rs:8:5:8:10 | return | getNumberOfAttrs: | 0 | hasExpr: | no | diff --git a/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr_getExpr.expected index eb4b7a5f1aa..c75ecd0b23c 100644 --- a/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/ReturnExpr/ReturnExpr_getExpr.expected @@ -1 +1 @@ -| gen_return_expr.rs:5:5:5:13 | return ... | gen_return_expr.rs:5:12:5:13 | 42 | +| gen_return_expr.rs:5:5:5:13 | return 42 | gen_return_expr.rs:5:12:5:13 | 42 | diff --git a/rust/ql/test/extractor-tests/utf8/ast.expected b/rust/ql/test/extractor-tests/utf8/ast.expected index 17457550f79..560f834766e 100644 --- a/rust/ql/test/extractor-tests/utf8/ast.expected +++ b/rust/ql/test/extractor-tests/utf8/ast.expected @@ -27,7 +27,7 @@ | utf8_identifiers.rs:10:12:10:13 | ParamList | | utf8_identifiers.rs:10:15:12:1 | StmtList | | utf8_identifiers.rs:10:15:12:1 | { ... } | -| utf8_identifiers.rs:11:5:11:24 | let \u03b1 = ... | +| utf8_identifiers.rs:11:5:11:24 | let ... = 0.00001f64 | | utf8_identifiers.rs:11:9:11:9 | \u03b1 | | utf8_identifiers.rs:11:9:11:9 | \u03b1 | | utf8_identifiers.rs:11:14:11:23 | 0.00001f64 | diff --git a/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected b/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected index 28a436b1cce..4260e2384c8 100644 --- a/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected @@ -1,53 +1,53 @@ edges | test.rs:5:5:11:5 | enter fn test_and_if_let | test.rs:5:24:5:24 | a | | | test.rs:5:5:11:5 | exit fn test_and_if_let (normal) | test.rs:5:5:11:5 | exit fn test_and_if_let | | -| test.rs:5:24:5:24 | a | test.rs:5:24:5:30 | a: bool | match | -| test.rs:5:24:5:30 | a: bool | test.rs:5:33:5:33 | b | | -| test.rs:5:33:5:33 | b | test.rs:5:33:5:47 | b: Option::<...> | match | -| test.rs:5:33:5:47 | b: Option::<...> | test.rs:5:50:5:50 | c | | -| test.rs:5:50:5:50 | c | test.rs:5:50:5:56 | c: bool | match | -| test.rs:5:50:5:56 | c: bool | test.rs:6:12:6:12 | a | | +| test.rs:5:24:5:24 | a | test.rs:5:24:5:30 | ...: bool | match | +| test.rs:5:24:5:30 | ...: bool | test.rs:5:33:5:33 | b | | +| test.rs:5:33:5:33 | b | test.rs:5:33:5:47 | ...: Option::<...> | match | +| test.rs:5:33:5:47 | ...: Option::<...> | test.rs:5:50:5:50 | c | | +| test.rs:5:50:5:50 | c | test.rs:5:50:5:56 | ...: bool | match | +| test.rs:5:50:5:56 | ...: bool | test.rs:6:12:6:12 | a | | | test.rs:5:67:11:5 | { ... } | test.rs:5:5:11:5 | exit fn test_and_if_let (normal) | | -| test.rs:6:9:10:9 | if ... { ... } else { ... } | test.rs:5:67:11:5 | { ... } | | +| test.rs:6:9:10:9 | if ... {...} else {...} | test.rs:5:67:11:5 | { ... } | | | test.rs:6:12:6:12 | a | test.rs:6:12:6:31 | [boolean(false)] ... && ... | false | -| test.rs:6:12:6:12 | a | test.rs:6:17:6:31 | let TupleStructPat = ... | true | +| test.rs:6:12:6:12 | a | test.rs:6:17:6:31 | let ... = b | true | | test.rs:6:12:6:31 | [boolean(false)] ... && ... | test.rs:9:13:9:17 | false | false | | test.rs:6:12:6:31 | [boolean(true)] ... && ... | test.rs:7:13:7:13 | d | true | -| test.rs:6:17:6:31 | let TupleStructPat = ... | test.rs:6:31:6:31 | b | | +| test.rs:6:17:6:31 | let ... = b | test.rs:6:31:6:31 | b | | | test.rs:6:21:6:27 | TupleStructPat | test.rs:6:12:6:31 | [boolean(false)] ... && ... | no-match | | test.rs:6:21:6:27 | TupleStructPat | test.rs:6:26:6:26 | d | match | | test.rs:6:26:6:26 | d | test.rs:6:12:6:31 | [boolean(true)] ... && ... | match | | test.rs:6:31:6:31 | b | test.rs:6:21:6:27 | TupleStructPat | | -| test.rs:6:33:8:9 | { ... } | test.rs:6:9:10:9 | if ... { ... } else { ... } | | +| test.rs:6:33:8:9 | { ... } | test.rs:6:9:10:9 | if ... {...} else {...} | | | test.rs:7:13:7:13 | d | test.rs:6:33:8:9 | { ... } | | -| test.rs:8:16:10:9 | { ... } | test.rs:6:9:10:9 | if ... { ... } else { ... } | | +| test.rs:8:16:10:9 | { ... } | test.rs:6:9:10:9 | if ... {...} else {...} | | | test.rs:9:13:9:17 | false | test.rs:8:16:10:9 | { ... } | | | test.rs:13:5:21:5 | enter fn test_and_if_let2 | test.rs:13:25:13:25 | a | | | test.rs:13:5:21:5 | exit fn test_and_if_let2 (normal) | test.rs:13:5:21:5 | exit fn test_and_if_let2 | | -| test.rs:13:25:13:25 | a | test.rs:13:25:13:31 | a: bool | match | -| test.rs:13:25:13:31 | a: bool | test.rs:13:34:13:34 | b | | -| test.rs:13:34:13:34 | b | test.rs:13:34:13:39 | b: i64 | match | -| test.rs:13:34:13:39 | b: i64 | test.rs:13:42:13:42 | c | | -| test.rs:13:42:13:42 | c | test.rs:13:42:13:48 | c: bool | match | -| test.rs:13:42:13:48 | c: bool | test.rs:14:12:14:12 | a | | +| test.rs:13:25:13:25 | a | test.rs:13:25:13:31 | ...: bool | match | +| test.rs:13:25:13:31 | ...: bool | test.rs:13:34:13:34 | b | | +| test.rs:13:34:13:34 | b | test.rs:13:34:13:39 | ...: i64 | match | +| test.rs:13:34:13:39 | ...: i64 | test.rs:13:42:13:42 | c | | +| test.rs:13:42:13:42 | c | test.rs:13:42:13:48 | ...: bool | match | +| test.rs:13:42:13:48 | ...: bool | test.rs:14:12:14:12 | a | | | test.rs:13:59:21:5 | { ... } | test.rs:13:5:21:5 | exit fn test_and_if_let2 (normal) | | -| test.rs:14:9:20:9 | if ... { ... } else { ... } | test.rs:13:59:21:5 | { ... } | | +| test.rs:14:9:20:9 | if ... {...} else {...} | test.rs:13:59:21:5 | { ... } | | | test.rs:14:12:14:12 | a | test.rs:14:12:14:25 | [boolean(false)] ... && ... | false | -| test.rs:14:12:14:12 | a | test.rs:14:17:14:25 | let d = ... | true | +| test.rs:14:12:14:12 | a | test.rs:14:17:14:25 | let ... = b | true | | test.rs:14:12:14:25 | [boolean(false)] ... && ... | test.rs:14:12:15:16 | [boolean(false)] ... && ... | false | | test.rs:14:12:14:25 | [boolean(true)] ... && ... | test.rs:15:16:15:16 | c | true | | test.rs:14:12:15:16 | [boolean(false)] ... && ... | test.rs:19:13:19:17 | false | false | | test.rs:14:12:15:16 | [boolean(true)] ... && ... | test.rs:17:13:17:13 | d | true | -| test.rs:14:17:14:25 | let d = ... | test.rs:14:25:14:25 | b | | +| test.rs:14:17:14:25 | let ... = b | test.rs:14:25:14:25 | b | | | test.rs:14:21:14:21 | d | test.rs:14:12:14:25 | [boolean(true)] ... && ... | match | | test.rs:14:25:14:25 | b | test.rs:14:21:14:21 | d | | | test.rs:15:16:15:16 | c | test.rs:14:12:15:16 | [boolean(false)] ... && ... | false | | test.rs:15:16:15:16 | c | test.rs:14:12:15:16 | [boolean(true)] ... && ... | true | -| test.rs:16:9:18:9 | { ... } | test.rs:14:9:20:9 | if ... { ... } else { ... } | | +| test.rs:16:9:18:9 | { ... } | test.rs:14:9:20:9 | if ... {...} else {...} | | | test.rs:17:13:17:13 | d | test.rs:17:17:17:17 | 0 | | | test.rs:17:13:17:17 | ... > ... | test.rs:16:9:18:9 | { ... } | | | test.rs:17:17:17:17 | 0 | test.rs:17:13:17:17 | ... > ... | | -| test.rs:18:16:20:9 | { ... } | test.rs:14:9:20:9 | if ... { ... } else { ... } | | +| test.rs:18:16:20:9 | { ... } | test.rs:14:9:20:9 | if ... {...} else {...} | | | test.rs:19:13:19:17 | false | test.rs:18:16:20:9 | { ... } | | breakTarget continueTarget diff --git a/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected b/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected index 29d8b8e3b92..c8d53f467e9 100644 --- a/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected @@ -1,16 +1,16 @@ models edges -| main.rs:21:13:21:21 | (...) ... : unit | main.rs:22:10:22:10 | s | provenance | | -| main.rs:32:13:32:21 | (...) ... : unit | main.rs:33:10:33:10 | s | provenance | | +| main.rs:21:13:21:21 | source(...) : unit | main.rs:22:10:22:10 | s | provenance | | +| main.rs:32:13:32:21 | source(...) : unit | main.rs:33:10:33:10 | s | provenance | | nodes -| main.rs:17:10:17:18 | (...) ... | semmle.label | (...) ... | -| main.rs:21:13:21:21 | (...) ... : unit | semmle.label | (...) ... : unit | +| main.rs:17:10:17:18 | source(...) | semmle.label | source(...) | +| main.rs:21:13:21:21 | source(...) : unit | semmle.label | source(...) : unit | | main.rs:22:10:22:10 | s | semmle.label | s | -| main.rs:32:13:32:21 | (...) ... : unit | semmle.label | (...) ... : unit | +| main.rs:32:13:32:21 | source(...) : unit | semmle.label | source(...) : unit | | main.rs:33:10:33:10 | s | semmle.label | s | subpaths testFailures #select -| main.rs:17:10:17:18 | (...) ... | main.rs:17:10:17:18 | (...) ... | main.rs:17:10:17:18 | (...) ... | $@ | main.rs:17:10:17:18 | (...) ... | (...) ... | -| main.rs:22:10:22:10 | s | main.rs:21:13:21:21 | (...) ... : unit | main.rs:22:10:22:10 | s | $@ | main.rs:21:13:21:21 | (...) ... : unit | (...) ... : unit | -| main.rs:33:10:33:10 | s | main.rs:32:13:32:21 | (...) ... : unit | main.rs:33:10:33:10 | s | $@ | main.rs:32:13:32:21 | (...) ... : unit | (...) ... : unit | +| main.rs:17:10:17:18 | source(...) | main.rs:17:10:17:18 | source(...) | main.rs:17:10:17:18 | source(...) | $@ | main.rs:17:10:17:18 | source(...) | source(...) | +| main.rs:22:10:22:10 | s | main.rs:21:13:21:21 | source(...) : unit | main.rs:22:10:22:10 | s | $@ | main.rs:21:13:21:21 | source(...) : unit | source(...) : unit | +| main.rs:33:10:33:10 | s | main.rs:32:13:32:21 | source(...) : unit | main.rs:33:10:33:10 | s | $@ | main.rs:32:13:32:21 | source(...) : unit | source(...) : unit | diff --git a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected index 5fbf2fe41e1..28e43535c79 100644 --- a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected +++ b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected @@ -1,24 +1,24 @@ -| main.rs:13:5:13:13 | (...) ... | main.rs:1:1:3:1 | fn source | -| main.rs:17:13:17:23 | (...) ... | main.rs:12:1:14:1 | fn get_data | -| main.rs:18:5:18:11 | (...) ... | main.rs:5:1:7:1 | fn sink | -| main.rs:22:5:22:15 | (...) ... | main.rs:5:1:7:1 | fn sink | -| main.rs:26:13:26:21 | (...) ... | main.rs:1:1:3:1 | fn source | -| main.rs:27:5:27:14 | (...) ... | main.rs:21:1:23:1 | fn data_in | -| main.rs:35:13:35:21 | (...) ... | main.rs:1:1:3:1 | fn source | -| main.rs:36:13:36:27 | (...) ... | main.rs:30:1:32:1 | fn pass_through | -| main.rs:37:5:37:11 | (...) ... | main.rs:5:1:7:1 | fn sink | -| main.rs:49:9:49:15 | (...) ... | main.rs:5:1:7:1 | fn sink | -| main.rs:55:13:55:21 | (...) ... | main.rs:1:1:3:1 | fn source | +| main.rs:13:5:13:13 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:17:13:17:23 | get_data(...) | main.rs:12:1:14:1 | fn get_data | +| main.rs:18:5:18:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:22:5:22:15 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:26:13:26:21 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:27:5:27:14 | data_in(...) | main.rs:21:1:23:1 | fn data_in | +| main.rs:35:13:35:21 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:36:13:36:27 | pass_through(...) | main.rs:30:1:32:1 | fn pass_through | +| main.rs:37:5:37:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:49:9:49:15 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:55:13:55:21 | source(...) | main.rs:1:1:3:1 | fn source | | main.rs:69:13:69:25 | ... .get_data(...) | main.rs:51:5:57:5 | fn get_data | -| main.rs:70:5:70:11 | (...) ... | main.rs:5:1:7:1 | fn sink | -| main.rs:75:13:75:21 | (...) ... | main.rs:1:1:3:1 | fn source | +| main.rs:70:5:70:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:75:13:75:21 | source(...) | main.rs:1:1:3:1 | fn source | | main.rs:76:5:76:17 | ... .data_in(...) | main.rs:48:5:50:5 | fn data_in | -| main.rs:81:13:81:21 | (...) ... | main.rs:1:1:3:1 | fn source | +| main.rs:81:13:81:21 | source(...) | main.rs:1:1:3:1 | fn source | | main.rs:82:5:82:22 | ... .data_through(...) | main.rs:58:5:64:5 | fn data_through | -| main.rs:83:5:83:11 | (...) ... | main.rs:5:1:7:1 | fn sink | -| main.rs:87:5:87:22 | (...) ... | main.rs:16:1:19:1 | fn data_out_of_call | -| main.rs:88:5:88:21 | (...) ... | main.rs:25:1:28:1 | fn data_in_to_call | -| main.rs:89:5:89:23 | (...) ... | main.rs:34:1:38:1 | fn data_through_call | -| main.rs:91:5:91:24 | (...) ... | main.rs:67:1:71:1 | fn data_out_of_method | -| main.rs:92:5:92:28 | (...) ... | main.rs:73:1:77:1 | fn data_in_to_method_call | -| main.rs:93:5:93:25 | (...) ... | main.rs:79:1:84:1 | fn data_through_method | +| main.rs:83:5:83:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:87:5:87:22 | data_out_of_call(...) | main.rs:16:1:19:1 | fn data_out_of_call | +| main.rs:88:5:88:21 | data_in_to_call(...) | main.rs:25:1:28:1 | fn data_in_to_call | +| main.rs:89:5:89:23 | data_through_call(...) | main.rs:34:1:38:1 | fn data_through_call | +| main.rs:91:5:91:24 | data_out_of_method(...) | main.rs:67:1:71:1 | fn data_out_of_method | +| main.rs:92:5:92:28 | data_in_to_method_call(...) | main.rs:73:1:77:1 | fn data_in_to_method_call | +| main.rs:93:5:93:25 | data_through_method(...) | main.rs:79:1:84:1 | fn data_through_method | diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index e0bab71ec1e..1e342ba93e5 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -5,42 +5,42 @@ | main.rs:7:9:7:9 | s | main.rs:7:9:7:9 | [SSA] s | | main.rs:19:9:19:9 | [SSA] s | main.rs:20:10:20:10 | s | | main.rs:19:9:19:9 | s | main.rs:19:9:19:9 | [SSA] s | -| main.rs:19:13:19:21 | (...) ... | main.rs:19:9:19:9 | s | +| main.rs:19:13:19:21 | source(...) | main.rs:19:9:19:9 | s | | main.rs:23:18:23:21 | [SSA] cond | main.rs:26:16:26:19 | cond | | main.rs:23:18:23:21 | cond | main.rs:23:18:23:21 | [SSA] cond | | main.rs:24:9:24:9 | [SSA] a | main.rs:26:23:26:23 | a | | main.rs:24:9:24:9 | a | main.rs:24:9:24:9 | [SSA] a | -| main.rs:24:13:24:21 | (...) ... | main.rs:24:9:24:9 | a | +| main.rs:24:13:24:21 | source(...) | main.rs:24:9:24:9 | a | | main.rs:25:9:25:9 | [SSA] b | main.rs:26:34:26:34 | b | | main.rs:25:9:25:9 | b | main.rs:25:9:25:9 | [SSA] b | | main.rs:25:13:25:13 | 2 | main.rs:25:9:25:9 | b | | main.rs:26:9:26:9 | [SSA] c | main.rs:27:10:27:10 | c | | main.rs:26:9:26:9 | c | main.rs:26:9:26:9 | [SSA] c | -| main.rs:26:13:26:36 | ... else { ... } if {...} | main.rs:26:9:26:9 | c | -| main.rs:26:21:26:25 | { ... } | main.rs:26:13:26:36 | ... else { ... } if {...} | +| main.rs:26:13:26:36 | if cond {...} else {...} | main.rs:26:9:26:9 | c | +| main.rs:26:21:26:25 | { ... } | main.rs:26:13:26:36 | if cond {...} else {...} | | main.rs:26:23:26:23 | a | main.rs:26:21:26:25 | { ... } | -| main.rs:26:32:26:36 | { ... } | main.rs:26:13:26:36 | ... else { ... } if {...} | +| main.rs:26:32:26:36 | { ... } | main.rs:26:13:26:36 | if cond {...} else {...} | | main.rs:26:34:26:34 | b | main.rs:26:32:26:36 | { ... } | | main.rs:30:21:30:21 | [SSA] m | main.rs:32:19:32:19 | m | | main.rs:30:21:30:21 | m | main.rs:30:21:30:21 | [SSA] m | | main.rs:31:9:31:9 | [SSA] a | main.rs:33:20:33:20 | a | | main.rs:31:9:31:9 | a | main.rs:31:9:31:9 | [SSA] a | -| main.rs:31:13:31:21 | (...) ... | main.rs:31:9:31:9 | a | +| main.rs:31:13:31:21 | source(...) | main.rs:31:9:31:9 | a | | main.rs:32:9:32:9 | [SSA] b | main.rs:36:10:36:10 | b | | main.rs:32:9:32:9 | b | main.rs:32:9:32:9 | [SSA] b | -| main.rs:32:13:35:5 | match ... { ... } | main.rs:32:9:32:9 | b | -| main.rs:33:20:33:20 | a | main.rs:32:13:35:5 | match ... { ... } | -| main.rs:34:17:34:17 | 0 | main.rs:32:13:35:5 | match ... { ... } | +| main.rs:32:13:35:5 | match m { ... } | main.rs:32:9:32:9 | b | +| main.rs:33:20:33:20 | a | main.rs:32:13:35:5 | match m { ... } | +| main.rs:34:17:34:17 | 0 | main.rs:32:13:35:5 | match m { ... } | | main.rs:40:9:40:9 | [SSA] a | main.rs:43:10:43:10 | a | | main.rs:40:9:40:9 | a | main.rs:40:9:40:9 | [SSA] a | | main.rs:40:13:42:5 | loop { ... } | main.rs:40:9:40:9 | a | -| main.rs:41:9:41:15 | 1 break | main.rs:40:13:42:5 | loop { ... } | -| main.rs:41:15:41:15 | 1 | main.rs:41:9:41:15 | 1 break | +| main.rs:41:9:41:15 | break 1 | main.rs:40:13:42:5 | loop { ... } | +| main.rs:41:15:41:15 | 1 | main.rs:41:9:41:15 | break 1 | | main.rs:44:9:44:9 | [SSA] b | main.rs:47:10:47:10 | b | | main.rs:44:9:44:9 | b | main.rs:44:9:44:9 | [SSA] b | | main.rs:44:13:46:5 | loop { ... } | main.rs:44:9:44:9 | b | -| main.rs:45:9:45:23 | ... break | main.rs:44:13:46:5 | loop { ... } | -| main.rs:45:15:45:23 | (...) ... | main.rs:45:9:45:23 | ... break | +| main.rs:45:9:45:23 | break ... | main.rs:44:13:46:5 | loop { ... } | +| main.rs:45:15:45:23 | source(...) | main.rs:45:9:45:23 | break ... | | main.rs:51:9:51:13 | [SSA] i | main.rs:52:10:52:10 | i | | main.rs:51:9:51:13 | i | main.rs:51:9:51:13 | [SSA] i | | main.rs:51:17:51:17 | 1 | main.rs:51:9:51:13 | i | @@ -48,7 +48,7 @@ | main.rs:53:5:53:5 | i | main.rs:53:5:53:5 | [SSA] i | | main.rs:61:9:61:9 | [SSA] i | main.rs:62:11:62:11 | i | | main.rs:61:9:61:9 | i | main.rs:61:9:61:9 | [SSA] i | -| main.rs:61:13:61:31 | (...) ... | main.rs:61:9:61:9 | i | +| main.rs:61:13:61:31 | Box::new(...) | main.rs:61:9:61:9 | i | | main.rs:66:9:66:9 | [SSA] a | main.rs:67:10:67:10 | a | | main.rs:66:9:66:9 | a | main.rs:66:9:66:9 | [SSA] a | | main.rs:66:13:66:26 | TupleExpr | main.rs:66:9:66:9 | a | @@ -70,16 +70,16 @@ | main.rs:97:38:97:38 | p | main.rs:97:9:97:34 | Point {...} | | main.rs:104:9:104:10 | [SSA] s1 | main.rs:106:11:106:12 | s1 | | main.rs:104:9:104:10 | s1 | main.rs:104:9:104:10 | [SSA] s1 | -| main.rs:104:14:104:28 | (...) ... | main.rs:104:9:104:10 | s1 | +| main.rs:104:14:104:28 | Some(...) | main.rs:104:9:104:10 | s1 | | main.rs:105:9:105:10 | [SSA] s2 | main.rs:110:11:110:12 | s2 | | main.rs:105:9:105:10 | s2 | main.rs:105:9:105:10 | [SSA] s2 | -| main.rs:105:14:105:20 | (...) ... | main.rs:105:9:105:10 | s2 | +| main.rs:105:14:105:20 | Some(...) | main.rs:105:9:105:10 | s2 | | main.rs:107:14:107:14 | [SSA] n | main.rs:107:25:107:25 | n | | main.rs:107:14:107:14 | n | main.rs:107:14:107:14 | [SSA] n | -| main.rs:107:20:107:26 | (...) ... | main.rs:106:5:109:5 | match ... { ... } | -| main.rs:108:17:108:23 | (...) ... | main.rs:106:5:109:5 | match ... { ... } | -| main.rs:110:5:113:5 | match ... { ... } | main.rs:103:27:114:1 | { ... } | +| main.rs:107:20:107:26 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } | +| main.rs:108:17:108:23 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } | +| main.rs:110:5:113:5 | match s2 { ... } | main.rs:103:27:114:1 | { ... } | | main.rs:111:14:111:14 | [SSA] n | main.rs:111:25:111:25 | n | | main.rs:111:14:111:14 | n | main.rs:111:14:111:14 | [SSA] n | -| main.rs:111:20:111:26 | (...) ... | main.rs:110:5:113:5 | match ... { ... } | -| main.rs:112:17:112:23 | (...) ... | main.rs:110:5:113:5 | match ... { ... } | +| main.rs:111:20:111:26 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } | +| main.rs:112:17:112:23 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index 315c3580f3d..b4c292a93d9 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -1,24 +1,24 @@ models edges -| main.rs:19:13:19:21 | (...) ... : unit | main.rs:20:10:20:10 | s | provenance | | -| main.rs:24:13:24:21 | (...) ... : unit | main.rs:27:10:27:10 | c | provenance | | -| main.rs:31:13:31:21 | (...) ... : unit | main.rs:36:10:36:10 | b | provenance | | -| main.rs:45:15:45:23 | (...) ... : unit | main.rs:47:10:47:10 | b | provenance | | +| main.rs:19:13:19:21 | source(...) : unit | main.rs:20:10:20:10 | s | provenance | | +| main.rs:24:13:24:21 | source(...) : unit | main.rs:27:10:27:10 | c | provenance | | +| main.rs:31:13:31:21 | source(...) : unit | main.rs:36:10:36:10 | b | provenance | | +| main.rs:45:15:45:23 | source(...) : unit | main.rs:47:10:47:10 | b | provenance | | nodes -| main.rs:15:10:15:18 | (...) ... | semmle.label | (...) ... | -| main.rs:19:13:19:21 | (...) ... : unit | semmle.label | (...) ... : unit | +| main.rs:15:10:15:18 | source(...) | semmle.label | source(...) | +| main.rs:19:13:19:21 | source(...) : unit | semmle.label | source(...) : unit | | main.rs:20:10:20:10 | s | semmle.label | s | -| main.rs:24:13:24:21 | (...) ... : unit | semmle.label | (...) ... : unit | +| main.rs:24:13:24:21 | source(...) : unit | semmle.label | source(...) : unit | | main.rs:27:10:27:10 | c | semmle.label | c | -| main.rs:31:13:31:21 | (...) ... : unit | semmle.label | (...) ... : unit | +| main.rs:31:13:31:21 | source(...) : unit | semmle.label | source(...) : unit | | main.rs:36:10:36:10 | b | semmle.label | b | -| main.rs:45:15:45:23 | (...) ... : unit | semmle.label | (...) ... : unit | +| main.rs:45:15:45:23 | source(...) : unit | semmle.label | source(...) : unit | | main.rs:47:10:47:10 | b | semmle.label | b | subpaths testFailures #select -| main.rs:15:10:15:18 | (...) ... | main.rs:15:10:15:18 | (...) ... | main.rs:15:10:15:18 | (...) ... | $@ | main.rs:15:10:15:18 | (...) ... | (...) ... | -| main.rs:20:10:20:10 | s | main.rs:19:13:19:21 | (...) ... : unit | main.rs:20:10:20:10 | s | $@ | main.rs:19:13:19:21 | (...) ... : unit | (...) ... : unit | -| main.rs:27:10:27:10 | c | main.rs:24:13:24:21 | (...) ... : unit | main.rs:27:10:27:10 | c | $@ | main.rs:24:13:24:21 | (...) ... : unit | (...) ... : unit | -| main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | (...) ... : unit | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | (...) ... : unit | (...) ... : unit | -| main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | (...) ... : unit | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | (...) ... : unit | (...) ... : unit | +| main.rs:15:10:15:18 | source(...) | main.rs:15:10:15:18 | source(...) | main.rs:15:10:15:18 | source(...) | $@ | main.rs:15:10:15:18 | source(...) | source(...) | +| main.rs:20:10:20:10 | s | main.rs:19:13:19:21 | source(...) : unit | main.rs:20:10:20:10 | s | $@ | main.rs:19:13:19:21 | source(...) : unit | source(...) : unit | +| main.rs:27:10:27:10 | c | main.rs:24:13:24:21 | source(...) : unit | main.rs:27:10:27:10 | c | $@ | main.rs:24:13:24:21 | source(...) : unit | source(...) : unit | +| main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | source(...) : unit | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | source(...) : unit | source(...) : unit | +| main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | source(...) : unit | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | source(...) : unit | source(...) : unit | diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected index 338af96a7c4..3a7e72f0349 100644 --- a/rust/ql/test/library-tests/variables/Cfg.expected +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -1,8 +1,8 @@ edges | variables.rs:3:1:5:1 | enter fn print_str | variables.rs:3:14:3:14 | s | | | variables.rs:3:1:5:1 | exit fn print_str (normal) | variables.rs:3:1:5:1 | exit fn print_str | | -| variables.rs:3:14:3:14 | s | variables.rs:3:14:3:20 | s: RefType | match | -| variables.rs:3:14:3:20 | s: RefType | variables.rs:4:5:4:22 | ExprStmt | | +| variables.rs:3:14:3:14 | s | variables.rs:3:14:3:20 | ...: ... | match | +| variables.rs:3:14:3:20 | ...: ... | variables.rs:4:5:4:22 | ExprStmt | | | variables.rs:3:23:5:1 | { ... } | variables.rs:3:1:5:1 | exit fn print_str (normal) | | | variables.rs:4:5:4:21 | $crate::io::_print | variables.rs:4:14:4:17 | "{}\\n" | | | variables.rs:4:5:4:21 | MacroExpr | variables.rs:3:23:5:1 | { ... } | | @@ -17,8 +17,8 @@ edges | variables.rs:4:20:4:20 | s | variables.rs:4:14:4:20 | FormatArgsExpr | | | variables.rs:7:1:9:1 | enter fn print_i64 | variables.rs:7:14:7:14 | i | | | variables.rs:7:1:9:1 | exit fn print_i64 (normal) | variables.rs:7:1:9:1 | exit fn print_i64 | | -| variables.rs:7:14:7:14 | i | variables.rs:7:14:7:19 | i: i64 | match | -| variables.rs:7:14:7:19 | i: i64 | variables.rs:8:5:8:22 | ExprStmt | | +| variables.rs:7:14:7:14 | i | variables.rs:7:14:7:19 | ...: i64 | match | +| variables.rs:7:14:7:19 | ...: i64 | variables.rs:8:5:8:22 | ExprStmt | | | variables.rs:7:22:9:1 | { ... } | variables.rs:7:1:9:1 | exit fn print_i64 (normal) | | | variables.rs:8:5:8:21 | $crate::io::_print | variables.rs:8:14:8:17 | "{}\\n" | | | variables.rs:8:5:8:21 | MacroExpr | variables.rs:7:22:9:1 | { ... } | | @@ -33,27 +33,27 @@ edges | variables.rs:8:20:8:20 | i | variables.rs:8:14:8:20 | FormatArgsExpr | | | variables.rs:11:1:13:1 | enter fn print_i64_ref | variables.rs:11:18:11:18 | i | | | variables.rs:11:1:13:1 | exit fn print_i64_ref (normal) | variables.rs:11:1:13:1 | exit fn print_i64_ref | | -| variables.rs:11:18:11:18 | i | variables.rs:11:18:11:24 | i: RefType | match | -| variables.rs:11:18:11:24 | i: RefType | variables.rs:12:5:12:13 | print_i64 | | +| variables.rs:11:18:11:18 | i | variables.rs:11:18:11:24 | ...: ... | match | +| variables.rs:11:18:11:24 | ...: ... | variables.rs:12:5:12:13 | print_i64 | | | variables.rs:11:27:13:1 | { ... } | variables.rs:11:1:13:1 | exit fn print_i64_ref (normal) | | | variables.rs:12:5:12:13 | print_i64 | variables.rs:12:16:12:16 | i | | | variables.rs:12:5:12:17 | print_i64(...) | variables.rs:11:27:13:1 | { ... } | | | variables.rs:12:15:12:16 | * ... | variables.rs:12:5:12:17 | print_i64(...) | | | variables.rs:12:16:12:16 | i | variables.rs:12:15:12:16 | * ... | | -| variables.rs:15:1:18:1 | enter fn immutable_variable | variables.rs:16:5:16:17 | let x1 = ... | | +| variables.rs:15:1:18:1 | enter fn immutable_variable | variables.rs:16:5:16:17 | let ... = "a" | | | variables.rs:15:1:18:1 | exit fn immutable_variable (normal) | variables.rs:15:1:18:1 | exit fn immutable_variable | | | variables.rs:15:25:18:1 | { ... } | variables.rs:15:1:18:1 | exit fn immutable_variable (normal) | | -| variables.rs:16:5:16:17 | let x1 = ... | variables.rs:16:14:16:16 | "a" | | +| variables.rs:16:5:16:17 | let ... = "a" | variables.rs:16:14:16:16 | "a" | | | variables.rs:16:9:16:10 | x1 | variables.rs:17:5:17:18 | ExprStmt | match | | variables.rs:16:14:16:16 | "a" | variables.rs:16:9:16:10 | x1 | | | variables.rs:17:5:17:13 | print_str | variables.rs:17:15:17:16 | x1 | | | variables.rs:17:5:17:17 | print_str(...) | variables.rs:15:25:18:1 | { ... } | | | variables.rs:17:5:17:18 | ExprStmt | variables.rs:17:5:17:13 | print_str | | | variables.rs:17:15:17:16 | x1 | variables.rs:17:5:17:17 | print_str(...) | | -| variables.rs:20:1:25:1 | enter fn mutable_variable | variables.rs:21:5:21:19 | let x2 = ... | | +| variables.rs:20:1:25:1 | enter fn mutable_variable | variables.rs:21:5:21:19 | let ... = 4 | | | variables.rs:20:1:25:1 | exit fn mutable_variable (normal) | variables.rs:20:1:25:1 | exit fn mutable_variable | | | variables.rs:20:23:25:1 | { ... } | variables.rs:20:1:25:1 | exit fn mutable_variable (normal) | | -| variables.rs:21:5:21:19 | let x2 = ... | variables.rs:21:18:21:18 | 4 | | +| variables.rs:21:5:21:19 | let ... = 4 | variables.rs:21:18:21:18 | 4 | | | variables.rs:21:9:21:14 | x2 | variables.rs:22:5:22:18 | ExprStmt | match | | variables.rs:21:18:21:18 | 4 | variables.rs:21:9:21:14 | x2 | | | variables.rs:22:5:22:13 | print_i64 | variables.rs:22:15:22:16 | x2 | | @@ -68,17 +68,17 @@ edges | variables.rs:24:5:24:17 | print_i64(...) | variables.rs:20:23:25:1 | { ... } | | | variables.rs:24:5:24:18 | ExprStmt | variables.rs:24:5:24:13 | print_i64 | | | variables.rs:24:15:24:16 | x2 | variables.rs:24:5:24:17 | print_i64(...) | | -| variables.rs:27:1:32:1 | enter fn mutable_variable_immutable_borrow | variables.rs:28:5:28:18 | let x = ... | | +| variables.rs:27:1:32:1 | enter fn mutable_variable_immutable_borrow | variables.rs:28:5:28:18 | let ... = 1 | | | variables.rs:27:1:32:1 | exit fn mutable_variable_immutable_borrow (normal) | variables.rs:27:1:32:1 | exit fn mutable_variable_immutable_borrow | | | variables.rs:27:40:32:1 | { ... } | variables.rs:27:1:32:1 | exit fn mutable_variable_immutable_borrow (normal) | | -| variables.rs:28:5:28:18 | let x = ... | variables.rs:28:17:28:17 | 1 | | +| variables.rs:28:5:28:18 | let ... = 1 | variables.rs:28:17:28:17 | 1 | | | variables.rs:28:9:28:13 | x | variables.rs:29:5:29:22 | ExprStmt | match | | variables.rs:28:17:28:17 | 1 | variables.rs:28:9:28:13 | x | | | variables.rs:29:5:29:17 | print_i64_ref | variables.rs:29:20:29:20 | x | | | variables.rs:29:5:29:21 | print_i64_ref(...) | variables.rs:30:5:30:10 | ExprStmt | | | variables.rs:29:5:29:22 | ExprStmt | variables.rs:29:5:29:17 | print_i64_ref | | -| variables.rs:29:19:29:20 | &... | variables.rs:29:5:29:21 | print_i64_ref(...) | | -| variables.rs:29:20:29:20 | x | variables.rs:29:19:29:20 | &... | | +| variables.rs:29:19:29:20 | &x | variables.rs:29:5:29:21 | print_i64_ref(...) | | +| variables.rs:29:20:29:20 | x | variables.rs:29:19:29:20 | &x | | | variables.rs:30:5:30:5 | x | variables.rs:30:9:30:9 | 2 | | | variables.rs:30:5:30:9 | ... = ... | variables.rs:31:5:31:22 | ExprStmt | | | variables.rs:30:5:30:10 | ExprStmt | variables.rs:30:5:30:5 | x | | @@ -86,19 +86,19 @@ edges | variables.rs:31:5:31:17 | print_i64_ref | variables.rs:31:20:31:20 | x | | | variables.rs:31:5:31:21 | print_i64_ref(...) | variables.rs:27:40:32:1 | { ... } | | | variables.rs:31:5:31:22 | ExprStmt | variables.rs:31:5:31:17 | print_i64_ref | | -| variables.rs:31:19:31:20 | &... | variables.rs:31:5:31:21 | print_i64_ref(...) | | -| variables.rs:31:20:31:20 | x | variables.rs:31:19:31:20 | &... | | -| variables.rs:34:1:40:1 | enter fn variable_shadow1 | variables.rs:35:5:35:15 | let x3 = ... | | +| variables.rs:31:19:31:20 | &x | variables.rs:31:5:31:21 | print_i64_ref(...) | | +| variables.rs:31:20:31:20 | x | variables.rs:31:19:31:20 | &x | | +| variables.rs:34:1:40:1 | enter fn variable_shadow1 | variables.rs:35:5:35:15 | let ... = 1 | | | variables.rs:34:1:40:1 | exit fn variable_shadow1 (normal) | variables.rs:34:1:40:1 | exit fn variable_shadow1 | | | variables.rs:34:23:40:1 | { ... } | variables.rs:34:1:40:1 | exit fn variable_shadow1 (normal) | | -| variables.rs:35:5:35:15 | let x3 = ... | variables.rs:35:14:35:14 | 1 | | +| variables.rs:35:5:35:15 | let ... = 1 | variables.rs:35:14:35:14 | 1 | | | variables.rs:35:9:35:10 | x3 | variables.rs:36:5:36:18 | ExprStmt | match | | variables.rs:35:14:35:14 | 1 | variables.rs:35:9:35:10 | x3 | | | variables.rs:36:5:36:13 | print_i64 | variables.rs:36:15:36:16 | x3 | | -| variables.rs:36:5:36:17 | print_i64(...) | variables.rs:37:5:38:15 | let x3 = ... | | +| variables.rs:36:5:36:17 | print_i64(...) | variables.rs:37:5:38:15 | let ... = ... | | | variables.rs:36:5:36:18 | ExprStmt | variables.rs:36:5:36:13 | print_i64 | | | variables.rs:36:15:36:16 | x3 | variables.rs:36:5:36:17 | print_i64(...) | | -| variables.rs:37:5:38:15 | let x3 = ... | variables.rs:38:9:38:10 | x3 | | +| variables.rs:37:5:38:15 | let ... = ... | variables.rs:38:9:38:10 | x3 | | | variables.rs:37:9:37:10 | x3 | variables.rs:39:5:39:18 | ExprStmt | match | | variables.rs:38:9:38:10 | x3 | variables.rs:38:14:38:14 | 1 | | | variables.rs:38:9:38:14 | ... + ... | variables.rs:37:9:37:10 | x3 | | @@ -107,19 +107,19 @@ edges | variables.rs:39:5:39:17 | print_i64(...) | variables.rs:34:23:40:1 | { ... } | | | variables.rs:39:5:39:18 | ExprStmt | variables.rs:39:5:39:13 | print_i64 | | | variables.rs:39:15:39:16 | x3 | variables.rs:39:5:39:17 | print_i64(...) | | -| variables.rs:42:1:50:1 | enter fn variable_shadow2 | variables.rs:43:5:43:17 | let x4 = ... | | +| variables.rs:42:1:50:1 | enter fn variable_shadow2 | variables.rs:43:5:43:17 | let ... = "a" | | | variables.rs:42:1:50:1 | exit fn variable_shadow2 (normal) | variables.rs:42:1:50:1 | exit fn variable_shadow2 | | | variables.rs:42:23:50:1 | { ... } | variables.rs:42:1:50:1 | exit fn variable_shadow2 (normal) | | -| variables.rs:43:5:43:17 | let x4 = ... | variables.rs:43:14:43:16 | "a" | | +| variables.rs:43:5:43:17 | let ... = "a" | variables.rs:43:14:43:16 | "a" | | | variables.rs:43:9:43:10 | x4 | variables.rs:44:5:44:18 | ExprStmt | match | | variables.rs:43:14:43:16 | "a" | variables.rs:43:9:43:10 | x4 | | | variables.rs:44:5:44:13 | print_str | variables.rs:44:15:44:16 | x4 | | | variables.rs:44:5:44:17 | print_str(...) | variables.rs:45:5:48:5 | ExprStmt | | | variables.rs:44:5:44:18 | ExprStmt | variables.rs:44:5:44:13 | print_str | | | variables.rs:44:15:44:16 | x4 | variables.rs:44:5:44:17 | print_str(...) | | -| variables.rs:45:5:48:5 | ExprStmt | variables.rs:46:9:46:21 | let x4 = ... | | +| variables.rs:45:5:48:5 | ExprStmt | variables.rs:46:9:46:21 | let ... = "b" | | | variables.rs:45:5:48:5 | { ... } | variables.rs:49:5:49:18 | ExprStmt | | -| variables.rs:46:9:46:21 | let x4 = ... | variables.rs:46:18:46:20 | "b" | | +| variables.rs:46:9:46:21 | let ... = "b" | variables.rs:46:18:46:20 | "b" | | | variables.rs:46:13:46:14 | x4 | variables.rs:47:9:47:22 | ExprStmt | match | | variables.rs:46:18:46:20 | "b" | variables.rs:46:13:46:14 | x4 | | | variables.rs:47:9:47:17 | print_str | variables.rs:47:19:47:20 | x4 | | @@ -130,10 +130,10 @@ edges | variables.rs:49:5:49:17 | print_str(...) | variables.rs:42:23:50:1 | { ... } | | | variables.rs:49:5:49:18 | ExprStmt | variables.rs:49:5:49:13 | print_str | | | variables.rs:49:15:49:16 | x4 | variables.rs:49:5:49:17 | print_str(...) | | -| variables.rs:57:1:72:1 | enter fn let_pattern1 | variables.rs:58:5:67:47 | let TuplePat = ... | | +| variables.rs:57:1:72:1 | enter fn let_pattern1 | variables.rs:58:5:67:47 | let ... = ... | | | variables.rs:57:1:72:1 | exit fn let_pattern1 (normal) | variables.rs:57:1:72:1 | exit fn let_pattern1 | | | variables.rs:57:19:72:1 | { ... } | variables.rs:57:1:72:1 | exit fn let_pattern1 (normal) | | -| variables.rs:58:5:67:47 | let TuplePat = ... | variables.rs:67:11:67:13 | "a" | | +| variables.rs:58:5:67:47 | let ... = ... | variables.rs:67:11:67:13 | "a" | | | variables.rs:58:9:67:5 | TuplePat | variables.rs:59:9:62:9 | TuplePat | match | | variables.rs:59:9:62:9 | TuplePat | variables.rs:60:13:60:14 | a1 | match | | variables.rs:60:13:60:14 | a1 | variables.rs:61:13:61:14 | b1 | match | @@ -164,15 +164,15 @@ edges | variables.rs:71:5:71:16 | print_str(...) | variables.rs:57:19:72:1 | { ... } | | | variables.rs:71:5:71:17 | ExprStmt | variables.rs:71:5:71:13 | print_str | | | variables.rs:71:15:71:15 | y | variables.rs:71:5:71:16 | print_str(...) | | -| variables.rs:74:1:82:1 | enter fn let_pattern2 | variables.rs:75:5:75:38 | let p1 = ... | | +| variables.rs:74:1:82:1 | enter fn let_pattern2 | variables.rs:75:5:75:38 | let ... = ... | | | variables.rs:74:1:82:1 | exit fn let_pattern2 (normal) | variables.rs:74:1:82:1 | exit fn let_pattern2 | | | variables.rs:74:19:82:1 | { ... } | variables.rs:74:1:82:1 | exit fn let_pattern2 (normal) | | -| variables.rs:75:5:75:38 | let p1 = ... | variables.rs:75:25:75:27 | "a" | | -| variables.rs:75:9:75:10 | p1 | variables.rs:76:5:79:11 | let Point {...} = ... | match | +| variables.rs:75:5:75:38 | let ... = ... | variables.rs:75:25:75:27 | "a" | | +| variables.rs:75:9:75:10 | p1 | variables.rs:76:5:79:11 | let ... = p1 | match | | variables.rs:75:14:75:37 | Point {...} | variables.rs:75:9:75:10 | p1 | | | variables.rs:75:25:75:27 | "a" | variables.rs:75:33:75:35 | "b" | | | variables.rs:75:33:75:35 | "b" | variables.rs:75:14:75:37 | Point {...} | | -| variables.rs:76:5:79:11 | let Point {...} = ... | variables.rs:79:9:79:10 | p1 | | +| variables.rs:76:5:79:11 | let ... = p1 | variables.rs:79:9:79:10 | p1 | | | variables.rs:76:9:79:5 | Point {...} | variables.rs:77:12:77:13 | a2 | match | | variables.rs:77:12:77:13 | a2 | variables.rs:78:12:78:13 | b2 | match | | variables.rs:78:12:78:13 | b2 | variables.rs:80:5:80:18 | ExprStmt | match | @@ -185,31 +185,31 @@ edges | variables.rs:81:5:81:17 | print_str(...) | variables.rs:74:19:82:1 | { ... } | | | variables.rs:81:5:81:18 | ExprStmt | variables.rs:81:5:81:13 | print_str | | | variables.rs:81:15:81:16 | b2 | variables.rs:81:5:81:17 | print_str(...) | | -| variables.rs:84:1:91:1 | enter fn let_pattern3 | variables.rs:85:5:85:42 | let s1 = ... | | +| variables.rs:84:1:91:1 | enter fn let_pattern3 | variables.rs:85:5:85:42 | let ... = ... | | | variables.rs:84:1:91:1 | exit fn let_pattern3 (normal) | variables.rs:84:1:91:1 | exit fn let_pattern3 | | | variables.rs:84:19:91:1 | { ... } | variables.rs:84:1:91:1 | exit fn let_pattern3 (normal) | | -| variables.rs:85:5:85:42 | let s1 = ... | variables.rs:85:14:85:17 | Some | | -| variables.rs:85:9:85:10 | s1 | variables.rs:87:8:88:12 | let TupleStructPat = ... | match | +| variables.rs:85:5:85:42 | let ... = ... | variables.rs:85:14:85:17 | Some | | +| variables.rs:85:9:85:10 | s1 | variables.rs:87:8:88:12 | let ... = s1 | match | | variables.rs:85:14:85:17 | Some | variables.rs:85:19:85:30 | String::from | | | variables.rs:85:14:85:41 | Some(...) | variables.rs:85:9:85:10 | s1 | | | variables.rs:85:19:85:30 | String::from | variables.rs:85:32:85:39 | "Hello!" | | | variables.rs:85:19:85:40 | String::from(...) | variables.rs:85:14:85:41 | Some(...) | | | variables.rs:85:32:85:39 | "Hello!" | variables.rs:85:19:85:40 | String::from(...) | | -| variables.rs:87:5:90:5 | if ... { ... } | variables.rs:84:19:91:1 | { ... } | | -| variables.rs:87:8:88:12 | let TupleStructPat = ... | variables.rs:88:11:88:12 | s1 | | -| variables.rs:87:12:87:23 | TupleStructPat | variables.rs:87:5:90:5 | if ... { ... } | no-match | +| variables.rs:87:5:90:5 | if ... {...} | variables.rs:84:19:91:1 | { ... } | | +| variables.rs:87:8:88:12 | let ... = s1 | variables.rs:88:11:88:12 | s1 | | +| variables.rs:87:12:87:23 | TupleStructPat | variables.rs:87:5:90:5 | if ... {...} | no-match | | variables.rs:87:12:87:23 | TupleStructPat | variables.rs:87:17:87:22 | s2 | match | | variables.rs:87:17:87:22 | s2 | variables.rs:89:9:89:22 | ExprStmt | match | | variables.rs:88:11:88:12 | s1 | variables.rs:87:12:87:23 | TupleStructPat | | -| variables.rs:88:14:90:5 | { ... } | variables.rs:87:5:90:5 | if ... { ... } | | +| variables.rs:88:14:90:5 | { ... } | variables.rs:87:5:90:5 | if ... {...} | | | variables.rs:89:9:89:17 | print_str | variables.rs:89:19:89:20 | s2 | | | variables.rs:89:9:89:21 | print_str(...) | variables.rs:88:14:90:5 | { ... } | | | variables.rs:89:9:89:22 | ExprStmt | variables.rs:89:9:89:17 | print_str | | | variables.rs:89:19:89:20 | s2 | variables.rs:89:9:89:21 | print_str(...) | | -| variables.rs:93:1:99:1 | enter fn let_pattern4 | variables.rs:94:5:97:10 | let TupleStructPat = ... else { ... } | | +| variables.rs:93:1:99:1 | enter fn let_pattern4 | variables.rs:94:5:97:10 | let ... = ... else { ... } | | | variables.rs:93:1:99:1 | exit fn let_pattern4 (normal) | variables.rs:93:1:99:1 | exit fn let_pattern4 | | | variables.rs:93:19:99:1 | { ... } | variables.rs:93:1:99:1 | exit fn let_pattern4 (normal) | | -| variables.rs:94:5:97:10 | let TupleStructPat = ... else { ... } | variables.rs:94:34:94:37 | Some | | +| variables.rs:94:5:97:10 | let ... = ... else { ... } | variables.rs:94:34:94:37 | Some | | | variables.rs:94:9:94:16 | TupleStructPat | variables.rs:94:14:94:15 | x5 | match | | variables.rs:94:9:94:16 | TupleStructPat | variables.rs:96:13:96:19 | MacroStmts | no-match | | variables.rs:94:14:94:15 | x5 | variables.rs:98:5:98:18 | ExprStmt | match | @@ -225,40 +225,40 @@ edges | variables.rs:98:5:98:17 | print_str(...) | variables.rs:93:19:99:1 | { ... } | | | variables.rs:98:5:98:18 | ExprStmt | variables.rs:98:5:98:13 | print_str | | | variables.rs:98:15:98:16 | x5 | variables.rs:98:5:98:17 | print_str(...) | | -| variables.rs:101:1:108:1 | enter fn let_pattern5 | variables.rs:102:5:102:42 | let s1 = ... | | +| variables.rs:101:1:108:1 | enter fn let_pattern5 | variables.rs:102:5:102:42 | let ... = ... | | | variables.rs:101:1:108:1 | exit fn let_pattern5 (normal) | variables.rs:101:1:108:1 | exit fn let_pattern5 | | | variables.rs:101:19:108:1 | { ... } | variables.rs:101:1:108:1 | exit fn let_pattern5 (normal) | | -| variables.rs:102:5:102:42 | let s1 = ... | variables.rs:102:14:102:17 | Some | | -| variables.rs:102:9:102:10 | s1 | variables.rs:104:11:105:12 | let TupleStructPat = ... | match | +| variables.rs:102:5:102:42 | let ... = ... | variables.rs:102:14:102:17 | Some | | +| variables.rs:102:9:102:10 | s1 | variables.rs:104:11:105:12 | let ... = s1 | match | | variables.rs:102:14:102:17 | Some | variables.rs:102:19:102:30 | String::from | | | variables.rs:102:14:102:41 | Some(...) | variables.rs:102:9:102:10 | s1 | | | variables.rs:102:19:102:30 | String::from | variables.rs:102:32:102:39 | "Hello!" | | | variables.rs:102:19:102:40 | String::from(...) | variables.rs:102:14:102:41 | Some(...) | | | variables.rs:102:32:102:39 | "Hello!" | variables.rs:102:19:102:40 | String::from(...) | | | variables.rs:104:5:107:5 | while ... { ... } | variables.rs:101:19:108:1 | { ... } | | -| variables.rs:104:11:105:12 | let TupleStructPat = ... | variables.rs:105:11:105:12 | s1 | | +| variables.rs:104:11:105:12 | let ... = s1 | variables.rs:105:11:105:12 | s1 | | | variables.rs:104:15:104:26 | TupleStructPat | variables.rs:104:5:107:5 | while ... { ... } | no-match | | variables.rs:104:15:104:26 | TupleStructPat | variables.rs:104:20:104:25 | s2 | match | | variables.rs:104:20:104:25 | s2 | variables.rs:106:9:106:22 | ExprStmt | match | | variables.rs:105:11:105:12 | s1 | variables.rs:104:15:104:26 | TupleStructPat | | -| variables.rs:105:14:107:5 | { ... } | variables.rs:104:11:105:12 | let TupleStructPat = ... | | +| variables.rs:105:14:107:5 | { ... } | variables.rs:104:11:105:12 | let ... = s1 | | | variables.rs:106:9:106:17 | print_str | variables.rs:106:19:106:20 | s2 | | | variables.rs:106:9:106:21 | print_str(...) | variables.rs:105:14:107:5 | { ... } | | | variables.rs:106:9:106:22 | ExprStmt | variables.rs:106:9:106:17 | print_str | | | variables.rs:106:19:106:20 | s2 | variables.rs:106:9:106:21 | print_str(...) | | -| variables.rs:110:1:125:1 | enter fn match_pattern1 | variables.rs:111:5:111:21 | let x6 = ... | | +| variables.rs:110:1:125:1 | enter fn match_pattern1 | variables.rs:111:5:111:21 | let ... = ... | | | variables.rs:110:1:125:1 | exit fn match_pattern1 (normal) | variables.rs:110:1:125:1 | exit fn match_pattern1 | | | variables.rs:110:21:125:1 | { ... } | variables.rs:110:1:125:1 | exit fn match_pattern1 (normal) | | -| variables.rs:111:5:111:21 | let x6 = ... | variables.rs:111:14:111:17 | Some | | -| variables.rs:111:9:111:10 | x6 | variables.rs:112:5:112:16 | let y1 = ... | match | +| variables.rs:111:5:111:21 | let ... = ... | variables.rs:111:14:111:17 | Some | | +| variables.rs:111:9:111:10 | x6 | variables.rs:112:5:112:16 | let ... = 10 | match | | variables.rs:111:14:111:17 | Some | variables.rs:111:19:111:19 | 5 | | | variables.rs:111:14:111:20 | Some(...) | variables.rs:111:9:111:10 | x6 | | | variables.rs:111:19:111:19 | 5 | variables.rs:111:14:111:20 | Some(...) | | -| variables.rs:112:5:112:16 | let y1 = ... | variables.rs:112:14:112:15 | 10 | | +| variables.rs:112:5:112:16 | let ... = 10 | variables.rs:112:14:112:15 | 10 | | | variables.rs:112:9:112:10 | y1 | variables.rs:114:5:122:5 | ExprStmt | match | | variables.rs:112:14:112:15 | 10 | variables.rs:112:9:112:10 | y1 | | | variables.rs:114:5:122:5 | ExprStmt | variables.rs:114:11:114:12 | x6 | | -| variables.rs:114:5:122:5 | match ... { ... } | variables.rs:124:5:124:18 | ExprStmt | | +| variables.rs:114:5:122:5 | match x6 { ... } | variables.rs:124:5:124:18 | ExprStmt | | | variables.rs:114:11:114:12 | x6 | variables.rs:115:9:115:16 | TupleStructPat | | | variables.rs:115:9:115:16 | TupleStructPat | variables.rs:115:14:115:15 | 50 | match | | variables.rs:115:9:115:16 | TupleStructPat | variables.rs:116:9:116:16 | TupleStructPat | no-match | @@ -266,27 +266,27 @@ edges | variables.rs:115:14:115:15 | 50 | variables.rs:115:21:115:29 | print_str | match | | variables.rs:115:14:115:15 | 50 | variables.rs:116:9:116:16 | TupleStructPat | no-match | | variables.rs:115:21:115:29 | print_str | variables.rs:115:31:115:38 | "Got 50" | | -| variables.rs:115:21:115:39 | print_str(...) | variables.rs:114:5:122:5 | match ... { ... } | | +| variables.rs:115:21:115:39 | print_str(...) | variables.rs:114:5:122:5 | match x6 { ... } | | | variables.rs:115:31:115:38 | "Got 50" | variables.rs:115:21:115:39 | print_str(...) | | | variables.rs:116:9:116:16 | TupleStructPat | variables.rs:116:14:116:15 | y1 | match | | variables.rs:116:9:116:16 | TupleStructPat | variables.rs:121:9:121:12 | None | no-match | | variables.rs:116:14:116:15 | y1 | variables.rs:119:13:119:21 | print_i64 | match | -| variables.rs:118:9:120:9 | { ... } | variables.rs:114:5:122:5 | match ... { ... } | | +| variables.rs:118:9:120:9 | { ... } | variables.rs:114:5:122:5 | match x6 { ... } | | | variables.rs:119:13:119:21 | print_i64 | variables.rs:119:23:119:24 | y1 | | | variables.rs:119:13:119:25 | print_i64(...) | variables.rs:118:9:120:9 | { ... } | | | variables.rs:119:23:119:24 | y1 | variables.rs:119:13:119:25 | print_i64(...) | | | variables.rs:121:9:121:12 | None | variables.rs:121:17:121:25 | print_str | match | | variables.rs:121:17:121:25 | print_str | variables.rs:121:27:121:32 | "NONE" | | -| variables.rs:121:17:121:33 | print_str(...) | variables.rs:114:5:122:5 | match ... { ... } | | +| variables.rs:121:17:121:33 | print_str(...) | variables.rs:114:5:122:5 | match x6 { ... } | | | variables.rs:121:27:121:32 | "NONE" | variables.rs:121:17:121:33 | print_str(...) | | | variables.rs:124:5:124:13 | print_i64 | variables.rs:124:15:124:16 | y1 | | | variables.rs:124:5:124:17 | print_i64(...) | variables.rs:110:21:125:1 | { ... } | | | variables.rs:124:5:124:18 | ExprStmt | variables.rs:124:5:124:13 | print_i64 | | | variables.rs:124:15:124:16 | y1 | variables.rs:124:5:124:17 | print_i64(...) | | -| variables.rs:127:1:152:1 | enter fn match_pattern2 | variables.rs:128:5:128:36 | let numbers = ... | | +| variables.rs:127:1:152:1 | enter fn match_pattern2 | variables.rs:128:5:128:36 | let ... = ... | | | variables.rs:127:1:152:1 | exit fn match_pattern2 (normal) | variables.rs:127:1:152:1 | exit fn match_pattern2 | | | variables.rs:127:21:152:1 | { ... } | variables.rs:127:1:152:1 | exit fn match_pattern2 (normal) | | -| variables.rs:128:5:128:36 | let numbers = ... | variables.rs:128:20:128:20 | 2 | | +| variables.rs:128:5:128:36 | let ... = ... | variables.rs:128:20:128:20 | 2 | | | variables.rs:128:9:128:15 | numbers | variables.rs:130:5:140:5 | ExprStmt | match | | variables.rs:128:19:128:35 | TupleExpr | variables.rs:128:9:128:15 | numbers | | | variables.rs:128:20:128:20 | 2 | variables.rs:128:23:128:23 | 4 | | @@ -295,7 +295,7 @@ edges | variables.rs:128:29:128:30 | 16 | variables.rs:128:33:128:34 | 32 | | | variables.rs:128:33:128:34 | 32 | variables.rs:128:19:128:35 | TupleExpr | | | variables.rs:130:5:140:5 | ExprStmt | variables.rs:130:11:130:17 | numbers | | -| variables.rs:130:5:140:5 | match ... { ... } | variables.rs:142:11:142:17 | numbers | | +| variables.rs:130:5:140:5 | match numbers { ... } | variables.rs:142:11:142:17 | numbers | | | variables.rs:130:11:130:17 | numbers | variables.rs:131:9:135:9 | TuplePat | | | variables.rs:131:9:135:9 | TuplePat | variables.rs:132:13:132:17 | first | match | | variables.rs:132:13:132:17 | first | variables.rs:132:20:132:20 | _ | match | @@ -303,7 +303,7 @@ edges | variables.rs:133:13:133:17 | third | variables.rs:133:20:133:20 | _ | match | | variables.rs:133:20:133:20 | _ | variables.rs:134:13:134:17 | fifth | match | | variables.rs:134:13:134:17 | fifth | variables.rs:136:13:136:29 | ExprStmt | match | -| variables.rs:135:14:139:9 | { ... } | variables.rs:130:5:140:5 | match ... { ... } | | +| variables.rs:135:14:139:9 | { ... } | variables.rs:130:5:140:5 | match numbers { ... } | | | variables.rs:136:13:136:21 | print_i64 | variables.rs:136:23:136:27 | first | | | variables.rs:136:13:136:28 | print_i64(...) | variables.rs:137:13:137:29 | ExprStmt | | | variables.rs:136:13:136:29 | ExprStmt | variables.rs:136:13:136:21 | print_i64 | | @@ -316,13 +316,13 @@ edges | variables.rs:138:13:138:28 | print_i64(...) | variables.rs:135:14:139:9 | { ... } | | | variables.rs:138:13:138:29 | ExprStmt | variables.rs:138:13:138:21 | print_i64 | | | variables.rs:138:23:138:27 | fifth | variables.rs:138:13:138:28 | print_i64(...) | | -| variables.rs:142:5:151:5 | match ... { ... } | variables.rs:127:21:152:1 | { ... } | | +| variables.rs:142:5:151:5 | match numbers { ... } | variables.rs:127:21:152:1 | { ... } | | | variables.rs:142:11:142:17 | numbers | variables.rs:143:9:147:9 | TuplePat | | | variables.rs:143:9:147:9 | TuplePat | variables.rs:144:13:144:17 | first | match | | variables.rs:144:13:144:17 | first | variables.rs:145:13:145:14 | .. | match | | variables.rs:145:13:145:14 | .. | variables.rs:146:13:146:16 | last | match | | variables.rs:146:13:146:16 | last | variables.rs:148:13:148:29 | ExprStmt | match | -| variables.rs:147:14:150:9 | { ... } | variables.rs:142:5:151:5 | match ... { ... } | | +| variables.rs:147:14:150:9 | { ... } | variables.rs:142:5:151:5 | match numbers { ... } | | | variables.rs:148:13:148:21 | print_i64 | variables.rs:148:23:148:27 | first | | | variables.rs:148:13:148:28 | print_i64(...) | variables.rs:149:13:149:28 | ExprStmt | | | variables.rs:148:13:148:29 | ExprStmt | variables.rs:148:13:148:21 | print_i64 | | @@ -331,30 +331,30 @@ edges | variables.rs:149:13:149:27 | print_i64(...) | variables.rs:147:14:150:9 | { ... } | | | variables.rs:149:13:149:28 | ExprStmt | variables.rs:149:13:149:21 | print_i64 | | | variables.rs:149:23:149:26 | last | variables.rs:149:13:149:27 | print_i64(...) | | -| variables.rs:154:1:162:1 | enter fn match_pattern3 | variables.rs:155:5:155:38 | let p2 = ... | | +| variables.rs:154:1:162:1 | enter fn match_pattern3 | variables.rs:155:5:155:38 | let ... = ... | | | variables.rs:154:1:162:1 | exit fn match_pattern3 (normal) | variables.rs:154:1:162:1 | exit fn match_pattern3 | | | variables.rs:154:21:162:1 | { ... } | variables.rs:154:1:162:1 | exit fn match_pattern3 (normal) | | -| variables.rs:155:5:155:38 | let p2 = ... | variables.rs:155:25:155:27 | "x" | | +| variables.rs:155:5:155:38 | let ... = ... | variables.rs:155:25:155:27 | "x" | | | variables.rs:155:9:155:10 | p2 | variables.rs:157:11:157:12 | p2 | match | | variables.rs:155:14:155:37 | Point {...} | variables.rs:155:9:155:10 | p2 | | | variables.rs:155:25:155:27 | "x" | variables.rs:155:33:155:35 | "y" | | | variables.rs:155:33:155:35 | "y" | variables.rs:155:14:155:37 | Point {...} | | -| variables.rs:157:5:161:5 | match ... { ... } | variables.rs:154:21:162:1 | { ... } | | +| variables.rs:157:5:161:5 | match p2 { ... } | variables.rs:154:21:162:1 | { ... } | | | variables.rs:157:11:157:12 | p2 | variables.rs:158:9:160:9 | Point {...} | | | variables.rs:158:9:160:9 | Point {...} | variables.rs:159:16:159:17 | x7 | match | | variables.rs:159:16:159:17 | x7 | variables.rs:159:20:159:21 | .. | match | | variables.rs:159:20:159:21 | .. | variables.rs:160:14:160:22 | print_str | match | | variables.rs:160:14:160:22 | print_str | variables.rs:160:24:160:25 | x7 | | -| variables.rs:160:14:160:26 | print_str(...) | variables.rs:157:5:161:5 | match ... { ... } | | +| variables.rs:160:14:160:26 | print_str(...) | variables.rs:157:5:161:5 | match p2 { ... } | | | variables.rs:160:24:160:25 | x7 | variables.rs:160:14:160:26 | print_str(...) | | -| variables.rs:168:1:181:1 | enter fn match_pattern4 | variables.rs:169:5:169:39 | let msg = ... | | +| variables.rs:168:1:181:1 | enter fn match_pattern4 | variables.rs:169:5:169:39 | let ... = ... | | | variables.rs:168:1:181:1 | exit fn match_pattern4 (normal) | variables.rs:168:1:181:1 | exit fn match_pattern4 | | | variables.rs:168:21:181:1 | { ... } | variables.rs:168:1:181:1 | exit fn match_pattern4 (normal) | | -| variables.rs:169:5:169:39 | let msg = ... | variables.rs:169:36:169:36 | 0 | | +| variables.rs:169:5:169:39 | let ... = ... | variables.rs:169:36:169:36 | 0 | | | variables.rs:169:9:169:11 | msg | variables.rs:171:11:171:13 | msg | match | | variables.rs:169:15:169:38 | Message::Hello {...} | variables.rs:169:9:169:11 | msg | | | variables.rs:169:36:169:36 | 0 | variables.rs:169:15:169:38 | Message::Hello {...} | | -| variables.rs:171:5:180:5 | match ... { ... } | variables.rs:168:21:181:1 | { ... } | | +| variables.rs:171:5:180:5 | match msg { ... } | variables.rs:168:21:181:1 | { ... } | | | variables.rs:171:11:171:13 | msg | variables.rs:172:9:174:9 | Message::Hello {...} | | | variables.rs:172:9:174:9 | Message::Hello {...} | variables.rs:173:31:173:35 | RangePat | match | | variables.rs:172:9:174:9 | Message::Hello {...} | variables.rs:175:9:175:38 | Message::Hello {...} | no-match | @@ -368,7 +368,7 @@ edges | variables.rs:173:35:173:35 | 7 | variables.rs:173:35:173:35 | 7 | | | variables.rs:173:35:173:35 | 7 | variables.rs:175:9:175:38 | Message::Hello {...} | no-match | | variables.rs:174:14:174:22 | print_i64 | variables.rs:174:24:174:34 | id_variable | | -| variables.rs:174:14:174:35 | print_i64(...) | variables.rs:171:5:180:5 | match ... { ... } | | +| variables.rs:174:14:174:35 | print_i64(...) | variables.rs:171:5:180:5 | match msg { ... } | | | variables.rs:174:24:174:34 | id_variable | variables.rs:174:14:174:35 | print_i64(...) | | | variables.rs:175:9:175:38 | Message::Hello {...} | variables.rs:175:30:175:36 | RangePat | match | | variables.rs:175:9:175:38 | Message::Hello {...} | variables.rs:178:9:178:29 | Message::Hello {...} | no-match | @@ -380,7 +380,7 @@ edges | variables.rs:175:35:175:36 | 12 | variables.rs:175:35:175:36 | 12 | | | variables.rs:175:35:175:36 | 12 | variables.rs:176:22:176:51 | MacroStmts | match | | variables.rs:175:35:175:36 | 12 | variables.rs:178:9:178:29 | Message::Hello {...} | no-match | -| variables.rs:175:43:177:9 | { ... } | variables.rs:171:5:180:5 | match ... { ... } | | +| variables.rs:175:43:177:9 | { ... } | variables.rs:171:5:180:5 | match msg { ... } | | | variables.rs:176:13:176:52 | $crate::io::_print | variables.rs:176:22:176:51 | "Found an id in another range\\n" | | | variables.rs:176:13:176:52 | MacroExpr | variables.rs:175:43:177:9 | { ... } | | | variables.rs:176:22:176:51 | "Found an id in another range\\n" | variables.rs:176:22:176:51 | FormatArgsExpr | | @@ -393,182 +393,182 @@ edges | variables.rs:178:9:178:29 | Message::Hello {...} | variables.rs:178:26:178:27 | id | match | | variables.rs:178:26:178:27 | id | variables.rs:179:13:179:21 | print_i64 | match | | variables.rs:179:13:179:21 | print_i64 | variables.rs:179:23:179:24 | id | | -| variables.rs:179:13:179:25 | print_i64(...) | variables.rs:171:5:180:5 | match ... { ... } | | +| variables.rs:179:13:179:25 | print_i64(...) | variables.rs:171:5:180:5 | match msg { ... } | | | variables.rs:179:23:179:24 | id | variables.rs:179:13:179:25 | print_i64(...) | | -| variables.rs:188:1:194:1 | enter fn match_pattern5 | variables.rs:189:5:189:34 | let either = ... | | +| variables.rs:188:1:194:1 | enter fn match_pattern5 | variables.rs:189:5:189:34 | let ... = ... | | | variables.rs:188:1:194:1 | exit fn match_pattern5 (normal) | variables.rs:188:1:194:1 | exit fn match_pattern5 | | | variables.rs:188:21:194:1 | { ... } | variables.rs:188:1:194:1 | exit fn match_pattern5 (normal) | | -| variables.rs:189:5:189:34 | let either = ... | variables.rs:189:18:189:29 | Either::Left | | +| variables.rs:189:5:189:34 | let ... = ... | variables.rs:189:18:189:29 | Either::Left | | | variables.rs:189:9:189:14 | either | variables.rs:190:11:190:16 | either | match | | variables.rs:189:18:189:29 | Either::Left | variables.rs:189:31:189:32 | 32 | | | variables.rs:189:18:189:33 | Either::Left(...) | variables.rs:189:9:189:14 | either | | | variables.rs:189:31:189:32 | 32 | variables.rs:189:18:189:33 | Either::Left(...) | | -| variables.rs:190:5:193:5 | match ... { ... } | variables.rs:188:21:194:1 | { ... } | | +| variables.rs:190:5:193:5 | match either { ... } | variables.rs:188:21:194:1 | { ... } | | | variables.rs:190:11:190:16 | either | variables.rs:191:9:191:24 | TupleStructPat | | | variables.rs:191:9:191:24 | TupleStructPat | variables.rs:191:22:191:23 | a3 | match | | variables.rs:191:9:191:24 | TupleStructPat | variables.rs:191:28:191:44 | TupleStructPat | no-match | -| variables.rs:191:9:191:44 | [match(true)] ... \| ... | variables.rs:192:16:192:24 | print_i64 | match | -| variables.rs:191:22:191:23 | a3 | variables.rs:191:9:191:44 | [match(true)] ... \| ... | match | +| variables.rs:191:9:191:44 | [match(true)] ...... | variables.rs:192:16:192:24 | print_i64 | match | +| variables.rs:191:22:191:23 | a3 | variables.rs:191:9:191:44 | [match(true)] ...... | match | | variables.rs:191:28:191:44 | TupleStructPat | variables.rs:191:42:191:43 | a3 | match | -| variables.rs:191:42:191:43 | a3 | variables.rs:191:9:191:44 | [match(true)] ... \| ... | match | +| variables.rs:191:42:191:43 | a3 | variables.rs:191:9:191:44 | [match(true)] ...... | match | | variables.rs:192:16:192:24 | print_i64 | variables.rs:192:26:192:27 | a3 | | -| variables.rs:192:16:192:28 | print_i64(...) | variables.rs:190:5:193:5 | match ... { ... } | | +| variables.rs:192:16:192:28 | print_i64(...) | variables.rs:190:5:193:5 | match either { ... } | | | variables.rs:192:26:192:27 | a3 | variables.rs:192:16:192:28 | print_i64(...) | | -| variables.rs:202:1:216:1 | enter fn match_pattern6 | variables.rs:203:5:203:37 | let tv = ... | | +| variables.rs:202:1:216:1 | enter fn match_pattern6 | variables.rs:203:5:203:37 | let ... = ... | | | variables.rs:202:1:216:1 | exit fn match_pattern6 (normal) | variables.rs:202:1:216:1 | exit fn match_pattern6 | | | variables.rs:202:21:216:1 | { ... } | variables.rs:202:1:216:1 | exit fn match_pattern6 (normal) | | -| variables.rs:203:5:203:37 | let tv = ... | variables.rs:203:14:203:32 | ThreeValued::Second | | +| variables.rs:203:5:203:37 | let ... = ... | variables.rs:203:14:203:32 | ThreeValued::Second | | | variables.rs:203:9:203:10 | tv | variables.rs:204:5:207:5 | ExprStmt | match | | variables.rs:203:14:203:32 | ThreeValued::Second | variables.rs:203:34:203:35 | 62 | | | variables.rs:203:14:203:36 | ThreeValued::Second(...) | variables.rs:203:9:203:10 | tv | | | variables.rs:203:34:203:35 | 62 | variables.rs:203:14:203:36 | ThreeValued::Second(...) | | | variables.rs:204:5:207:5 | ExprStmt | variables.rs:204:11:204:12 | tv | | -| variables.rs:204:5:207:5 | match ... { ... } | variables.rs:208:5:211:5 | ExprStmt | | +| variables.rs:204:5:207:5 | match tv { ... } | variables.rs:208:5:211:5 | ExprStmt | | | variables.rs:204:11:204:12 | tv | variables.rs:205:9:205:30 | TupleStructPat | | | variables.rs:205:9:205:30 | TupleStructPat | variables.rs:205:28:205:29 | a4 | match | | variables.rs:205:9:205:30 | TupleStructPat | variables.rs:205:34:205:56 | TupleStructPat | no-match | -| variables.rs:205:9:205:81 | [match(true)] ... \| ... | variables.rs:206:16:206:24 | print_i64 | match | -| variables.rs:205:28:205:29 | a4 | variables.rs:205:9:205:81 | [match(true)] ... \| ... | match | +| variables.rs:205:9:205:81 | [match(true)] ......... | variables.rs:206:16:206:24 | print_i64 | match | +| variables.rs:205:28:205:29 | a4 | variables.rs:205:9:205:81 | [match(true)] ......... | match | | variables.rs:205:34:205:56 | TupleStructPat | variables.rs:205:54:205:55 | a4 | match | | variables.rs:205:34:205:56 | TupleStructPat | variables.rs:205:60:205:81 | TupleStructPat | no-match | -| variables.rs:205:54:205:55 | a4 | variables.rs:205:9:205:81 | [match(true)] ... \| ... | match | +| variables.rs:205:54:205:55 | a4 | variables.rs:205:9:205:81 | [match(true)] ......... | match | | variables.rs:205:60:205:81 | TupleStructPat | variables.rs:205:79:205:80 | a4 | match | -| variables.rs:205:79:205:80 | a4 | variables.rs:205:9:205:81 | [match(true)] ... \| ... | match | +| variables.rs:205:79:205:80 | a4 | variables.rs:205:9:205:81 | [match(true)] ......... | match | | variables.rs:206:16:206:24 | print_i64 | variables.rs:206:26:206:27 | a4 | | -| variables.rs:206:16:206:28 | print_i64(...) | variables.rs:204:5:207:5 | match ... { ... } | | +| variables.rs:206:16:206:28 | print_i64(...) | variables.rs:204:5:207:5 | match tv { ... } | | | variables.rs:206:26:206:27 | a4 | variables.rs:206:16:206:28 | print_i64(...) | | | variables.rs:208:5:211:5 | ExprStmt | variables.rs:208:11:208:12 | tv | | -| variables.rs:208:5:211:5 | match ... { ... } | variables.rs:212:11:212:12 | tv | | +| variables.rs:208:5:211:5 | match tv { ... } | variables.rs:212:11:212:12 | tv | | | variables.rs:208:11:208:12 | tv | variables.rs:209:10:209:31 | TupleStructPat | | -| variables.rs:209:9:209:83 | [match(true)] ... \| ... | variables.rs:210:16:210:24 | print_i64 | match | +| variables.rs:209:9:209:83 | [match(true)] ...... | variables.rs:210:16:210:24 | print_i64 | match | | variables.rs:209:10:209:31 | TupleStructPat | variables.rs:209:29:209:30 | a5 | match | | variables.rs:209:10:209:31 | TupleStructPat | variables.rs:209:35:209:57 | TupleStructPat | no-match | -| variables.rs:209:10:209:57 | [match(false)] ... \| ... | variables.rs:209:62:209:83 | TupleStructPat | no-match | -| variables.rs:209:10:209:57 | [match(true)] ... \| ... | variables.rs:209:9:209:83 | [match(true)] ... \| ... | match | -| variables.rs:209:29:209:30 | a5 | variables.rs:209:10:209:57 | [match(true)] ... \| ... | match | -| variables.rs:209:35:209:57 | TupleStructPat | variables.rs:209:10:209:57 | [match(false)] ... \| ... | no-match | +| variables.rs:209:10:209:57 | [match(false)] ...... | variables.rs:209:62:209:83 | TupleStructPat | no-match | +| variables.rs:209:10:209:57 | [match(true)] ...... | variables.rs:209:9:209:83 | [match(true)] ...... | match | +| variables.rs:209:29:209:30 | a5 | variables.rs:209:10:209:57 | [match(true)] ...... | match | +| variables.rs:209:35:209:57 | TupleStructPat | variables.rs:209:10:209:57 | [match(false)] ...... | no-match | | variables.rs:209:35:209:57 | TupleStructPat | variables.rs:209:55:209:56 | a5 | match | -| variables.rs:209:55:209:56 | a5 | variables.rs:209:10:209:57 | [match(true)] ... \| ... | match | +| variables.rs:209:55:209:56 | a5 | variables.rs:209:10:209:57 | [match(true)] ...... | match | | variables.rs:209:62:209:83 | TupleStructPat | variables.rs:209:81:209:82 | a5 | match | -| variables.rs:209:81:209:82 | a5 | variables.rs:209:9:209:83 | [match(true)] ... \| ... | match | +| variables.rs:209:81:209:82 | a5 | variables.rs:209:9:209:83 | [match(true)] ...... | match | | variables.rs:210:16:210:24 | print_i64 | variables.rs:210:26:210:27 | a5 | | -| variables.rs:210:16:210:28 | print_i64(...) | variables.rs:208:5:211:5 | match ... { ... } | | +| variables.rs:210:16:210:28 | print_i64(...) | variables.rs:208:5:211:5 | match tv { ... } | | | variables.rs:210:26:210:27 | a5 | variables.rs:210:16:210:28 | print_i64(...) | | -| variables.rs:212:5:215:5 | match ... { ... } | variables.rs:202:21:216:1 | { ... } | | +| variables.rs:212:5:215:5 | match tv { ... } | variables.rs:202:21:216:1 | { ... } | | | variables.rs:212:11:212:12 | tv | variables.rs:213:9:213:30 | TupleStructPat | | | variables.rs:213:9:213:30 | TupleStructPat | variables.rs:213:28:213:29 | a6 | match | | variables.rs:213:9:213:30 | TupleStructPat | variables.rs:213:35:213:57 | TupleStructPat | no-match | -| variables.rs:213:9:213:83 | [match(true)] ... \| ... | variables.rs:214:16:214:24 | print_i64 | match | -| variables.rs:213:28:213:29 | a6 | variables.rs:213:9:213:83 | [match(true)] ... \| ... | match | +| variables.rs:213:9:213:83 | [match(true)] ...... | variables.rs:214:16:214:24 | print_i64 | match | +| variables.rs:213:28:213:29 | a6 | variables.rs:213:9:213:83 | [match(true)] ...... | match | | variables.rs:213:35:213:57 | TupleStructPat | variables.rs:213:55:213:56 | a6 | match | | variables.rs:213:35:213:57 | TupleStructPat | variables.rs:213:61:213:82 | TupleStructPat | no-match | -| variables.rs:213:35:213:82 | [match(true)] ... \| ... | variables.rs:213:9:213:83 | [match(true)] ... \| ... | match | -| variables.rs:213:55:213:56 | a6 | variables.rs:213:35:213:82 | [match(true)] ... \| ... | match | +| variables.rs:213:35:213:82 | [match(true)] ...... | variables.rs:213:9:213:83 | [match(true)] ...... | match | +| variables.rs:213:55:213:56 | a6 | variables.rs:213:35:213:82 | [match(true)] ...... | match | | variables.rs:213:61:213:82 | TupleStructPat | variables.rs:213:80:213:81 | a6 | match | -| variables.rs:213:80:213:81 | a6 | variables.rs:213:35:213:82 | [match(true)] ... \| ... | match | +| variables.rs:213:80:213:81 | a6 | variables.rs:213:35:213:82 | [match(true)] ...... | match | | variables.rs:214:16:214:24 | print_i64 | variables.rs:214:26:214:27 | a6 | | -| variables.rs:214:16:214:28 | print_i64(...) | variables.rs:212:5:215:5 | match ... { ... } | | +| variables.rs:214:16:214:28 | print_i64(...) | variables.rs:212:5:215:5 | match tv { ... } | | | variables.rs:214:26:214:27 | a6 | variables.rs:214:16:214:28 | print_i64(...) | | -| variables.rs:218:1:226:1 | enter fn match_pattern7 | variables.rs:219:5:219:34 | let either = ... | | +| variables.rs:218:1:226:1 | enter fn match_pattern7 | variables.rs:219:5:219:34 | let ... = ... | | | variables.rs:218:1:226:1 | exit fn match_pattern7 (normal) | variables.rs:218:1:226:1 | exit fn match_pattern7 | | | variables.rs:218:21:226:1 | { ... } | variables.rs:218:1:226:1 | exit fn match_pattern7 (normal) | | -| variables.rs:219:5:219:34 | let either = ... | variables.rs:219:18:219:29 | Either::Left | | +| variables.rs:219:5:219:34 | let ... = ... | variables.rs:219:18:219:29 | Either::Left | | | variables.rs:219:9:219:14 | either | variables.rs:220:11:220:16 | either | match | | variables.rs:219:18:219:29 | Either::Left | variables.rs:219:31:219:32 | 32 | | | variables.rs:219:18:219:33 | Either::Left(...) | variables.rs:219:9:219:14 | either | | | variables.rs:219:31:219:32 | 32 | variables.rs:219:18:219:33 | Either::Left(...) | | -| variables.rs:220:5:225:5 | match ... { ... } | variables.rs:218:21:226:1 | { ... } | | +| variables.rs:220:5:225:5 | match either { ... } | variables.rs:218:21:226:1 | { ... } | | | variables.rs:220:11:220:16 | either | variables.rs:221:9:221:24 | TupleStructPat | | | variables.rs:221:9:221:24 | TupleStructPat | variables.rs:221:22:221:23 | a7 | match | | variables.rs:221:9:221:24 | TupleStructPat | variables.rs:221:28:221:44 | TupleStructPat | no-match | -| variables.rs:221:9:221:44 | [match(false)] ... \| ... | variables.rs:224:9:224:9 | _ | no-match | -| variables.rs:221:9:221:44 | [match(true)] ... \| ... | variables.rs:222:16:222:17 | a7 | match | -| variables.rs:221:22:221:23 | a7 | variables.rs:221:9:221:44 | [match(true)] ... \| ... | match | -| variables.rs:221:28:221:44 | TupleStructPat | variables.rs:221:9:221:44 | [match(false)] ... \| ... | no-match | +| variables.rs:221:9:221:44 | [match(false)] ...... | variables.rs:224:9:224:9 | _ | no-match | +| variables.rs:221:9:221:44 | [match(true)] ...... | variables.rs:222:16:222:17 | a7 | match | +| variables.rs:221:22:221:23 | a7 | variables.rs:221:9:221:44 | [match(true)] ...... | match | +| variables.rs:221:28:221:44 | TupleStructPat | variables.rs:221:9:221:44 | [match(false)] ...... | no-match | | variables.rs:221:28:221:44 | TupleStructPat | variables.rs:221:42:221:43 | a7 | match | -| variables.rs:221:42:221:43 | a7 | variables.rs:221:9:221:44 | [match(true)] ... \| ... | match | +| variables.rs:221:42:221:43 | a7 | variables.rs:221:9:221:44 | [match(true)] ...... | match | | variables.rs:222:16:222:17 | a7 | variables.rs:222:21:222:21 | 0 | | | variables.rs:222:16:222:21 | ... > ... | variables.rs:223:16:223:24 | print_i64 | true | | variables.rs:222:16:222:21 | ... > ... | variables.rs:224:9:224:9 | _ | false | | variables.rs:222:21:222:21 | 0 | variables.rs:222:16:222:21 | ... > ... | | | variables.rs:223:16:223:24 | print_i64 | variables.rs:223:26:223:27 | a7 | | -| variables.rs:223:16:223:28 | print_i64(...) | variables.rs:220:5:225:5 | match ... { ... } | | +| variables.rs:223:16:223:28 | print_i64(...) | variables.rs:220:5:225:5 | match either { ... } | | | variables.rs:223:26:223:27 | a7 | variables.rs:223:16:223:28 | print_i64(...) | | | variables.rs:224:9:224:9 | _ | variables.rs:224:14:224:15 | TupleExpr | match | -| variables.rs:224:14:224:15 | TupleExpr | variables.rs:220:5:225:5 | match ... { ... } | | -| variables.rs:228:1:243:1 | enter fn match_pattern8 | variables.rs:229:5:229:34 | let either = ... | | +| variables.rs:224:14:224:15 | TupleExpr | variables.rs:220:5:225:5 | match either { ... } | | +| variables.rs:228:1:243:1 | enter fn match_pattern8 | variables.rs:229:5:229:34 | let ... = ... | | | variables.rs:228:1:243:1 | exit fn match_pattern8 (normal) | variables.rs:228:1:243:1 | exit fn match_pattern8 | | | variables.rs:228:21:243:1 | { ... } | variables.rs:228:1:243:1 | exit fn match_pattern8 (normal) | | -| variables.rs:229:5:229:34 | let either = ... | variables.rs:229:18:229:29 | Either::Left | | +| variables.rs:229:5:229:34 | let ... = ... | variables.rs:229:18:229:29 | Either::Left | | | variables.rs:229:9:229:14 | either | variables.rs:231:11:231:16 | either | match | | variables.rs:229:18:229:29 | Either::Left | variables.rs:229:31:229:32 | 32 | | | variables.rs:229:18:229:33 | Either::Left(...) | variables.rs:229:9:229:14 | either | | | variables.rs:229:31:229:32 | 32 | variables.rs:229:18:229:33 | Either::Left(...) | | -| variables.rs:231:5:242:5 | match ... { ... } | variables.rs:228:21:243:1 | { ... } | | +| variables.rs:231:5:242:5 | match either { ... } | variables.rs:228:21:243:1 | { ... } | | | variables.rs:231:11:231:16 | either | variables.rs:233:14:233:30 | TupleStructPat | | | variables.rs:232:9:233:52 | [match(true)] e | variables.rs:235:13:235:27 | ExprStmt | match | | variables.rs:233:14:233:30 | TupleStructPat | variables.rs:233:27:233:29 | a11 | match | | variables.rs:233:14:233:30 | TupleStructPat | variables.rs:233:34:233:51 | TupleStructPat | no-match | -| variables.rs:233:14:233:51 | [match(false)] ... \| ... | variables.rs:241:9:241:9 | _ | no-match | -| variables.rs:233:14:233:51 | [match(true)] ... \| ... | variables.rs:232:9:233:52 | [match(true)] e | match | -| variables.rs:233:27:233:29 | a11 | variables.rs:233:14:233:51 | [match(true)] ... \| ... | match | -| variables.rs:233:34:233:51 | TupleStructPat | variables.rs:233:14:233:51 | [match(false)] ... \| ... | no-match | +| variables.rs:233:14:233:51 | [match(false)] ...... | variables.rs:241:9:241:9 | _ | no-match | +| variables.rs:233:14:233:51 | [match(true)] ...... | variables.rs:232:9:233:52 | [match(true)] e | match | +| variables.rs:233:27:233:29 | a11 | variables.rs:233:14:233:51 | [match(true)] ...... | match | +| variables.rs:233:34:233:51 | TupleStructPat | variables.rs:233:14:233:51 | [match(false)] ...... | no-match | | variables.rs:233:34:233:51 | TupleStructPat | variables.rs:233:48:233:50 | a11 | match | -| variables.rs:233:48:233:50 | a11 | variables.rs:233:14:233:51 | [match(true)] ... \| ... | match | -| variables.rs:234:12:240:9 | { ... } | variables.rs:231:5:242:5 | match ... { ... } | | +| variables.rs:233:48:233:50 | a11 | variables.rs:233:14:233:51 | [match(true)] ...... | match | +| variables.rs:234:12:240:9 | { ... } | variables.rs:231:5:242:5 | match either { ... } | | | variables.rs:235:13:235:21 | print_i64 | variables.rs:235:23:235:25 | a11 | | -| variables.rs:235:13:235:26 | print_i64(...) | variables.rs:236:16:237:15 | let TupleStructPat = ... | | +| variables.rs:235:13:235:26 | print_i64(...) | variables.rs:236:16:237:15 | let ... = e | | | variables.rs:235:13:235:27 | ExprStmt | variables.rs:235:13:235:21 | print_i64 | | | variables.rs:235:23:235:25 | a11 | variables.rs:235:13:235:26 | print_i64(...) | | -| variables.rs:236:13:239:13 | if ... { ... } | variables.rs:234:12:240:9 | { ... } | | -| variables.rs:236:16:237:15 | let TupleStructPat = ... | variables.rs:237:15:237:15 | e | | -| variables.rs:236:20:236:36 | TupleStructPat | variables.rs:236:13:239:13 | if ... { ... } | no-match | +| variables.rs:236:13:239:13 | if ... {...} | variables.rs:234:12:240:9 | { ... } | | +| variables.rs:236:16:237:15 | let ... = e | variables.rs:237:15:237:15 | e | | +| variables.rs:236:20:236:36 | TupleStructPat | variables.rs:236:13:239:13 | if ... {...} | no-match | | variables.rs:236:20:236:36 | TupleStructPat | variables.rs:236:33:236:35 | a12 | match | | variables.rs:236:33:236:35 | a12 | variables.rs:238:17:238:32 | ExprStmt | match | | variables.rs:237:15:237:15 | e | variables.rs:236:20:236:36 | TupleStructPat | | -| variables.rs:237:17:239:13 | { ... } | variables.rs:236:13:239:13 | if ... { ... } | | +| variables.rs:237:17:239:13 | { ... } | variables.rs:236:13:239:13 | if ... {...} | | | variables.rs:238:17:238:25 | print_i64 | variables.rs:238:28:238:30 | a12 | | | variables.rs:238:17:238:31 | print_i64(...) | variables.rs:237:17:239:13 | { ... } | | | variables.rs:238:17:238:32 | ExprStmt | variables.rs:238:17:238:25 | print_i64 | | | variables.rs:238:27:238:30 | * ... | variables.rs:238:17:238:31 | print_i64(...) | | | variables.rs:238:28:238:30 | a12 | variables.rs:238:27:238:30 | * ... | | | variables.rs:241:9:241:9 | _ | variables.rs:241:14:241:15 | TupleExpr | match | -| variables.rs:241:14:241:15 | TupleExpr | variables.rs:231:5:242:5 | match ... { ... } | | -| variables.rs:252:1:258:1 | enter fn match_pattern9 | variables.rs:253:5:253:36 | let fv = ... | | +| variables.rs:241:14:241:15 | TupleExpr | variables.rs:231:5:242:5 | match either { ... } | | +| variables.rs:252:1:258:1 | enter fn match_pattern9 | variables.rs:253:5:253:36 | let ... = ... | | | variables.rs:252:1:258:1 | exit fn match_pattern9 (normal) | variables.rs:252:1:258:1 | exit fn match_pattern9 | | | variables.rs:252:21:258:1 | { ... } | variables.rs:252:1:258:1 | exit fn match_pattern9 (normal) | | -| variables.rs:253:5:253:36 | let fv = ... | variables.rs:253:14:253:31 | FourValued::Second | | +| variables.rs:253:5:253:36 | let ... = ... | variables.rs:253:14:253:31 | FourValued::Second | | | variables.rs:253:9:253:10 | fv | variables.rs:254:11:254:12 | fv | match | | variables.rs:253:14:253:31 | FourValued::Second | variables.rs:253:33:253:34 | 62 | | | variables.rs:253:14:253:35 | FourValued::Second(...) | variables.rs:253:9:253:10 | fv | | | variables.rs:253:33:253:34 | 62 | variables.rs:253:14:253:35 | FourValued::Second(...) | | -| variables.rs:254:5:257:5 | match ... { ... } | variables.rs:252:21:258:1 | { ... } | | +| variables.rs:254:5:257:5 | match fv { ... } | variables.rs:252:21:258:1 | { ... } | | | variables.rs:254:11:254:12 | fv | variables.rs:255:9:255:30 | TupleStructPat | | | variables.rs:255:9:255:30 | TupleStructPat | variables.rs:255:27:255:29 | a13 | match | | variables.rs:255:9:255:30 | TupleStructPat | variables.rs:255:35:255:57 | TupleStructPat | no-match | -| variables.rs:255:9:255:109 | [match(true)] ... \| ... | variables.rs:256:16:256:24 | print_i64 | match | -| variables.rs:255:27:255:29 | a13 | variables.rs:255:9:255:109 | [match(true)] ... \| ... | match | +| variables.rs:255:9:255:109 | [match(true)] ......... | variables.rs:256:16:256:24 | print_i64 | match | +| variables.rs:255:27:255:29 | a13 | variables.rs:255:9:255:109 | [match(true)] ......... | match | | variables.rs:255:35:255:57 | TupleStructPat | variables.rs:255:54:255:56 | a13 | match | | variables.rs:255:35:255:57 | TupleStructPat | variables.rs:255:61:255:82 | TupleStructPat | no-match | -| variables.rs:255:35:255:82 | [match(false)] ... \| ... | variables.rs:255:87:255:109 | TupleStructPat | no-match | -| variables.rs:255:35:255:82 | [match(true)] ... \| ... | variables.rs:255:9:255:109 | [match(true)] ... \| ... | match | -| variables.rs:255:54:255:56 | a13 | variables.rs:255:35:255:82 | [match(true)] ... \| ... | match | -| variables.rs:255:61:255:82 | TupleStructPat | variables.rs:255:35:255:82 | [match(false)] ... \| ... | no-match | +| variables.rs:255:35:255:82 | [match(false)] ...... | variables.rs:255:87:255:109 | TupleStructPat | no-match | +| variables.rs:255:35:255:82 | [match(true)] ...... | variables.rs:255:9:255:109 | [match(true)] ......... | match | +| variables.rs:255:54:255:56 | a13 | variables.rs:255:35:255:82 | [match(true)] ...... | match | +| variables.rs:255:61:255:82 | TupleStructPat | variables.rs:255:35:255:82 | [match(false)] ...... | no-match | | variables.rs:255:61:255:82 | TupleStructPat | variables.rs:255:79:255:81 | a13 | match | -| variables.rs:255:79:255:81 | a13 | variables.rs:255:35:255:82 | [match(true)] ... \| ... | match | +| variables.rs:255:79:255:81 | a13 | variables.rs:255:35:255:82 | [match(true)] ...... | match | | variables.rs:255:87:255:109 | TupleStructPat | variables.rs:255:106:255:108 | a13 | match | -| variables.rs:255:106:255:108 | a13 | variables.rs:255:9:255:109 | [match(true)] ... \| ... | match | +| variables.rs:255:106:255:108 | a13 | variables.rs:255:9:255:109 | [match(true)] ......... | match | | variables.rs:256:16:256:24 | print_i64 | variables.rs:256:26:256:28 | a13 | | -| variables.rs:256:16:256:29 | print_i64(...) | variables.rs:254:5:257:5 | match ... { ... } | | +| variables.rs:256:16:256:29 | print_i64(...) | variables.rs:254:5:257:5 | match fv { ... } | | | variables.rs:256:26:256:28 | a13 | variables.rs:256:16:256:29 | print_i64(...) | | | variables.rs:260:1:269:1 | enter fn param_pattern1 | variables.rs:261:5:261:6 | a8 | | | variables.rs:260:1:269:1 | exit fn param_pattern1 (normal) | variables.rs:260:1:269:1 | exit fn param_pattern1 | | -| variables.rs:261:5:261:6 | a8 | variables.rs:261:5:261:12 | a8: RefType | match | -| variables.rs:261:5:261:12 | a8: RefType | variables.rs:262:5:265:5 | TuplePat | | +| variables.rs:261:5:261:6 | a8 | variables.rs:261:5:261:12 | ...: ... | match | +| variables.rs:261:5:261:12 | ...: ... | variables.rs:262:5:265:5 | TuplePat | | | variables.rs:262:5:265:5 | TuplePat | variables.rs:263:9:263:10 | b3 | match | -| variables.rs:262:5:265:19 | TuplePat: TupleType | variables.rs:266:5:266:18 | ExprStmt | | +| variables.rs:262:5:265:19 | ...: ... | variables.rs:266:5:266:18 | ExprStmt | | | variables.rs:263:9:263:10 | b3 | variables.rs:264:9:264:10 | c1 | match | -| variables.rs:264:9:264:10 | c1 | variables.rs:262:5:265:19 | TuplePat: TupleType | match | +| variables.rs:264:9:264:10 | c1 | variables.rs:262:5:265:19 | ...: ... | match | | variables.rs:265:28:269:1 | { ... } | variables.rs:260:1:269:1 | exit fn param_pattern1 (normal) | | | variables.rs:266:5:266:13 | print_str | variables.rs:266:15:266:16 | a8 | | | variables.rs:266:5:266:17 | print_str(...) | variables.rs:267:5:267:18 | ExprStmt | | @@ -584,22 +584,22 @@ edges | variables.rs:268:15:268:16 | c1 | variables.rs:268:5:268:17 | print_str(...) | | | variables.rs:271:1:275:1 | enter fn param_pattern2 | variables.rs:272:6:272:21 | TupleStructPat | | | variables.rs:271:1:275:1 | exit fn param_pattern2 (normal) | variables.rs:271:1:275:1 | exit fn param_pattern2 | | -| variables.rs:272:5:272:50 | (...): Either | variables.rs:274:5:274:18 | ExprStmt | | +| variables.rs:272:5:272:50 | ...: Either | variables.rs:274:5:274:18 | ExprStmt | | | variables.rs:272:6:272:21 | TupleStructPat | variables.rs:272:19:272:20 | a9 | match | | variables.rs:272:6:272:21 | TupleStructPat | variables.rs:272:25:272:41 | TupleStructPat | no-match | -| variables.rs:272:6:272:41 | [match(true)] ... \| ... | variables.rs:272:5:272:50 | (...): Either | match | -| variables.rs:272:19:272:20 | a9 | variables.rs:272:6:272:41 | [match(true)] ... \| ... | match | +| variables.rs:272:6:272:41 | [match(true)] ...... | variables.rs:272:5:272:50 | ...: Either | match | +| variables.rs:272:19:272:20 | a9 | variables.rs:272:6:272:41 | [match(true)] ...... | match | | variables.rs:272:25:272:41 | TupleStructPat | variables.rs:272:39:272:40 | a9 | match | -| variables.rs:272:39:272:40 | a9 | variables.rs:272:6:272:41 | [match(true)] ... \| ... | match | +| variables.rs:272:39:272:40 | a9 | variables.rs:272:6:272:41 | [match(true)] ...... | match | | variables.rs:273:9:275:1 | { ... } | variables.rs:271:1:275:1 | exit fn param_pattern2 (normal) | | | variables.rs:274:5:274:13 | print_i64 | variables.rs:274:15:274:16 | a9 | | | variables.rs:274:5:274:17 | print_i64(...) | variables.rs:273:9:275:1 | { ... } | | | variables.rs:274:5:274:18 | ExprStmt | variables.rs:274:5:274:13 | print_i64 | | | variables.rs:274:15:274:16 | a9 | variables.rs:274:5:274:17 | print_i64(...) | | -| variables.rs:277:1:312:1 | enter fn destruct_assignment | variables.rs:278:5:282:18 | let TuplePat = ... | | +| variables.rs:277:1:312:1 | enter fn destruct_assignment | variables.rs:278:5:282:18 | let ... = ... | | | variables.rs:277:1:312:1 | exit fn destruct_assignment (normal) | variables.rs:277:1:312:1 | exit fn destruct_assignment | | | variables.rs:277:26:312:1 | { ... } | variables.rs:277:1:312:1 | exit fn destruct_assignment (normal) | | -| variables.rs:278:5:282:18 | let TuplePat = ... | variables.rs:282:10:282:10 | 1 | | +| variables.rs:278:5:282:18 | let ... = ... | variables.rs:282:10:282:10 | 1 | | | variables.rs:278:9:282:5 | TuplePat | variables.rs:279:9:279:15 | a10 | match | | variables.rs:279:9:279:15 | a10 | variables.rs:280:9:280:14 | b4 | match | | variables.rs:280:9:280:14 | b4 | variables.rs:281:9:281:14 | c2 | match | @@ -667,18 +667,18 @@ edges | variables.rs:311:5:311:17 | print_i64(...) | variables.rs:277:26:312:1 | { ... } | | | variables.rs:311:5:311:18 | ExprStmt | variables.rs:311:5:311:13 | print_i64 | | | variables.rs:311:15:311:16 | b4 | variables.rs:311:5:311:17 | print_i64(...) | | -| variables.rs:314:1:329:1 | enter fn closure_variable | variables.rs:315:5:317:10 | let example_closure = ... | | +| variables.rs:314:1:329:1 | enter fn closure_variable | variables.rs:315:5:317:10 | let ... = ... | | | variables.rs:314:1:329:1 | exit fn closure_variable (normal) | variables.rs:314:1:329:1 | exit fn closure_variable | | | variables.rs:314:23:329:1 | { ... } | variables.rs:314:1:329:1 | exit fn closure_variable (normal) | | -| variables.rs:315:5:317:10 | let example_closure = ... | variables.rs:316:9:317:9 | \|...\| ... | | -| variables.rs:315:9:315:23 | example_closure | variables.rs:318:5:319:27 | let n1 = ... | match | -| variables.rs:316:9:317:9 | \|...\| ... | variables.rs:315:9:315:23 | example_closure | | -| variables.rs:316:9:317:9 | enter \|...\| ... | variables.rs:316:10:316:10 | x | | -| variables.rs:316:9:317:9 | exit \|...\| ... (normal) | variables.rs:316:9:317:9 | exit \|...\| ... | | -| variables.rs:316:10:316:10 | x | variables.rs:316:10:316:15 | x: i64 | match | -| variables.rs:316:10:316:15 | x: i64 | variables.rs:317:9:317:9 | x | | -| variables.rs:317:9:317:9 | x | variables.rs:316:9:317:9 | exit \|...\| ... (normal) | | -| variables.rs:318:5:319:27 | let n1 = ... | variables.rs:319:9:319:23 | example_closure | | +| variables.rs:315:5:317:10 | let ... = ... | variables.rs:316:9:317:9 | \|...\| x | | +| variables.rs:315:9:315:23 | example_closure | variables.rs:318:5:319:27 | let ... = ... | match | +| variables.rs:316:9:317:9 | \|...\| x | variables.rs:315:9:315:23 | example_closure | | +| variables.rs:316:9:317:9 | enter \|...\| x | variables.rs:316:10:316:10 | x | | +| variables.rs:316:9:317:9 | exit \|...\| x (normal) | variables.rs:316:9:317:9 | exit \|...\| x | | +| variables.rs:316:10:316:10 | x | variables.rs:316:10:316:15 | ...: i64 | match | +| variables.rs:316:10:316:15 | ...: i64 | variables.rs:317:9:317:9 | x | | +| variables.rs:317:9:317:9 | x | variables.rs:316:9:317:9 | exit \|...\| x (normal) | | +| variables.rs:318:5:319:27 | let ... = ... | variables.rs:319:9:319:23 | example_closure | | | variables.rs:318:9:318:10 | n1 | variables.rs:320:5:320:18 | ExprStmt | match | | variables.rs:319:9:319:23 | example_closure | variables.rs:319:25:319:25 | 5 | | | variables.rs:319:9:319:26 | example_closure(...) | variables.rs:318:9:318:10 | n1 | | @@ -688,17 +688,17 @@ edges | variables.rs:320:5:320:18 | ExprStmt | variables.rs:320:5:320:13 | print_i64 | | | variables.rs:320:15:320:16 | n1 | variables.rs:320:5:320:17 | print_i64(...) | | | variables.rs:322:5:322:22 | immutable_variable | variables.rs:322:5:322:24 | immutable_variable(...) | | -| variables.rs:322:5:322:24 | immutable_variable(...) | variables.rs:323:5:325:10 | let immutable_variable = ... | | +| variables.rs:322:5:322:24 | immutable_variable(...) | variables.rs:323:5:325:10 | let ... = ... | | | variables.rs:322:5:322:25 | ExprStmt | variables.rs:322:5:322:22 | immutable_variable | | -| variables.rs:323:5:325:10 | let immutable_variable = ... | variables.rs:324:9:325:9 | \|...\| ... | | -| variables.rs:323:9:323:26 | immutable_variable | variables.rs:326:5:327:30 | let n2 = ... | match | -| variables.rs:324:9:325:9 | \|...\| ... | variables.rs:323:9:323:26 | immutable_variable | | -| variables.rs:324:9:325:9 | enter \|...\| ... | variables.rs:324:10:324:10 | x | | -| variables.rs:324:9:325:9 | exit \|...\| ... (normal) | variables.rs:324:9:325:9 | exit \|...\| ... | | -| variables.rs:324:10:324:10 | x | variables.rs:324:10:324:15 | x: i64 | match | -| variables.rs:324:10:324:15 | x: i64 | variables.rs:325:9:325:9 | x | | -| variables.rs:325:9:325:9 | x | variables.rs:324:9:325:9 | exit \|...\| ... (normal) | | -| variables.rs:326:5:327:30 | let n2 = ... | variables.rs:327:9:327:26 | immutable_variable | | +| variables.rs:323:5:325:10 | let ... = ... | variables.rs:324:9:325:9 | \|...\| x | | +| variables.rs:323:9:323:26 | immutable_variable | variables.rs:326:5:327:30 | let ... = ... | match | +| variables.rs:324:9:325:9 | \|...\| x | variables.rs:323:9:323:26 | immutable_variable | | +| variables.rs:324:9:325:9 | enter \|...\| x | variables.rs:324:10:324:10 | x | | +| variables.rs:324:9:325:9 | exit \|...\| x (normal) | variables.rs:324:9:325:9 | exit \|...\| x | | +| variables.rs:324:10:324:10 | x | variables.rs:324:10:324:15 | ...: i64 | match | +| variables.rs:324:10:324:15 | ...: i64 | variables.rs:325:9:325:9 | x | | +| variables.rs:325:9:325:9 | x | variables.rs:324:9:325:9 | exit \|...\| x (normal) | | +| variables.rs:326:5:327:30 | let ... = ... | variables.rs:327:9:327:26 | immutable_variable | | | variables.rs:326:9:326:10 | n2 | variables.rs:328:5:328:18 | ExprStmt | match | | variables.rs:327:9:327:26 | immutable_variable | variables.rs:327:28:327:28 | 6 | | | variables.rs:327:9:327:29 | immutable_variable(...) | variables.rs:326:9:326:10 | n2 | | @@ -707,18 +707,18 @@ edges | variables.rs:328:5:328:17 | print_i64(...) | variables.rs:314:23:329:1 | { ... } | | | variables.rs:328:5:328:18 | ExprStmt | variables.rs:328:5:328:13 | print_i64 | | | variables.rs:328:15:328:16 | n2 | variables.rs:328:5:328:17 | print_i64(...) | | -| variables.rs:331:1:338:1 | enter fn for_variable | variables.rs:332:5:332:42 | let v = ... | | +| variables.rs:331:1:338:1 | enter fn for_variable | variables.rs:332:5:332:42 | let ... = ... | | | variables.rs:331:1:338:1 | exit fn for_variable (normal) | variables.rs:331:1:338:1 | exit fn for_variable | | | variables.rs:331:19:338:1 | { ... } | variables.rs:331:1:338:1 | exit fn for_variable (normal) | | -| variables.rs:332:5:332:42 | let v = ... | variables.rs:332:15:332:22 | "apples" | | +| variables.rs:332:5:332:42 | let ... = ... | variables.rs:332:15:332:22 | "apples" | | | variables.rs:332:9:332:9 | v | variables.rs:335:12:335:12 | v | match | | variables.rs:332:13:332:41 | &... | variables.rs:332:9:332:9 | v | | | variables.rs:332:14:332:41 | [...] | variables.rs:332:13:332:41 | &... | | | variables.rs:332:15:332:22 | "apples" | variables.rs:332:25:332:30 | "cake" | | | variables.rs:332:25:332:30 | "cake" | variables.rs:332:33:332:40 | "coffee" | | | variables.rs:332:33:332:40 | "coffee" | variables.rs:332:14:332:41 | [...] | | -| variables.rs:334:5:337:5 | ForExpr | variables.rs:331:19:338:1 | { ... } | | -| variables.rs:334:9:334:12 | text | variables.rs:334:5:337:5 | ForExpr | no-match | +| variables.rs:334:5:337:5 | for ... in ... { ... } | variables.rs:331:19:338:1 | { ... } | | +| variables.rs:334:9:334:12 | text | variables.rs:334:5:337:5 | for ... in ... { ... } | no-match | | variables.rs:334:9:334:12 | text | variables.rs:336:9:336:24 | ExprStmt | match | | variables.rs:335:12:335:12 | v | variables.rs:334:9:334:12 | text | | | variables.rs:335:14:337:5 | { ... } | variables.rs:334:9:334:12 | text | | @@ -726,10 +726,10 @@ edges | variables.rs:336:9:336:23 | print_str(...) | variables.rs:335:14:337:5 | { ... } | | | variables.rs:336:9:336:24 | ExprStmt | variables.rs:336:9:336:17 | print_str | | | variables.rs:336:19:336:22 | text | variables.rs:336:9:336:23 | print_str(...) | | -| variables.rs:340:1:346:1 | enter fn add_assign | variables.rs:341:5:341:18 | let a = ... | | +| variables.rs:340:1:346:1 | enter fn add_assign | variables.rs:341:5:341:18 | let ... = 0 | | | variables.rs:340:1:346:1 | exit fn add_assign (normal) | variables.rs:340:1:346:1 | exit fn add_assign | | | variables.rs:340:17:346:1 | { ... } | variables.rs:340:1:346:1 | exit fn add_assign (normal) | | -| variables.rs:341:5:341:18 | let a = ... | variables.rs:341:17:341:17 | 0 | | +| variables.rs:341:5:341:18 | let ... = 0 | variables.rs:341:17:341:17 | 0 | | | variables.rs:341:9:341:13 | a | variables.rs:342:5:342:11 | ExprStmt | match | | variables.rs:341:17:341:17 | 0 | variables.rs:341:9:341:13 | a | | | variables.rs:342:5:342:5 | a | variables.rs:342:10:342:10 | 1 | | @@ -742,23 +742,23 @@ edges | variables.rs:343:15:343:15 | a | variables.rs:343:5:343:16 | print_i64(...) | | | variables.rs:344:5:344:27 | ... .add_assign(...) | variables.rs:345:5:345:17 | ExprStmt | | | variables.rs:344:5:344:28 | ExprStmt | variables.rs:344:11:344:11 | a | | -| variables.rs:344:6:344:11 | &mut ... | variables.rs:344:25:344:26 | 10 | | -| variables.rs:344:11:344:11 | a | variables.rs:344:6:344:11 | &mut ... | | +| variables.rs:344:6:344:11 | &mut a | variables.rs:344:25:344:26 | 10 | | +| variables.rs:344:11:344:11 | a | variables.rs:344:6:344:11 | &mut a | | | variables.rs:344:25:344:26 | 10 | variables.rs:344:5:344:27 | ... .add_assign(...) | | | variables.rs:345:5:345:13 | print_i64 | variables.rs:345:15:345:15 | a | | | variables.rs:345:5:345:16 | print_i64(...) | variables.rs:340:17:346:1 | { ... } | | | variables.rs:345:5:345:17 | ExprStmt | variables.rs:345:5:345:13 | print_i64 | | | variables.rs:345:15:345:15 | a | variables.rs:345:5:345:16 | print_i64(...) | | -| variables.rs:348:1:354:1 | enter fn mutate | variables.rs:349:5:349:18 | let i = ... | | +| variables.rs:348:1:354:1 | enter fn mutate | variables.rs:349:5:349:18 | let ... = 1 | | | variables.rs:348:1:354:1 | exit fn mutate (normal) | variables.rs:348:1:354:1 | exit fn mutate | | | variables.rs:348:13:354:1 | { ... } | variables.rs:348:1:354:1 | exit fn mutate (normal) | | -| variables.rs:349:5:349:18 | let i = ... | variables.rs:349:17:349:17 | 1 | | -| variables.rs:349:9:349:13 | i | variables.rs:350:5:351:15 | let ref_i = ... | match | +| variables.rs:349:5:349:18 | let ... = 1 | variables.rs:349:17:349:17 | 1 | | +| variables.rs:349:9:349:13 | i | variables.rs:350:5:351:15 | let ... = ... | match | | variables.rs:349:17:349:17 | 1 | variables.rs:349:9:349:13 | i | | -| variables.rs:350:5:351:15 | let ref_i = ... | variables.rs:351:14:351:14 | i | | +| variables.rs:350:5:351:15 | let ... = ... | variables.rs:351:14:351:14 | i | | | variables.rs:350:9:350:13 | ref_i | variables.rs:352:5:352:15 | ExprStmt | match | -| variables.rs:351:9:351:14 | &mut ... | variables.rs:350:9:350:13 | ref_i | | -| variables.rs:351:14:351:14 | i | variables.rs:351:9:351:14 | &mut ... | | +| variables.rs:351:9:351:14 | &mut i | variables.rs:350:9:350:13 | ref_i | | +| variables.rs:351:14:351:14 | i | variables.rs:351:9:351:14 | &mut i | | | variables.rs:352:5:352:10 | * ... | variables.rs:352:14:352:14 | 2 | | | variables.rs:352:5:352:14 | ... = ... | variables.rs:353:5:353:17 | ExprStmt | | | variables.rs:352:5:352:15 | ExprStmt | variables.rs:352:6:352:10 | ref_i | | @@ -770,8 +770,8 @@ edges | variables.rs:353:15:353:15 | i | variables.rs:353:5:353:16 | print_i64(...) | | | variables.rs:356:1:361:1 | enter fn mutate_param | variables.rs:356:17:356:17 | x | | | variables.rs:356:1:361:1 | exit fn mutate_param (normal) | variables.rs:356:1:361:1 | exit fn mutate_param | | -| variables.rs:356:17:356:17 | x | variables.rs:356:17:356:28 | x: RefType | match | -| variables.rs:356:17:356:28 | x: RefType | variables.rs:357:5:359:11 | ExprStmt | | +| variables.rs:356:17:356:17 | x | variables.rs:356:17:356:28 | ...: ... | match | +| variables.rs:356:17:356:28 | ...: ... | variables.rs:357:5:359:11 | ExprStmt | | | variables.rs:357:5:357:6 | * ... | variables.rs:358:10:358:10 | x | | | variables.rs:357:5:359:10 | ... = ... | variables.rs:360:5:360:13 | ExprStmt | | | variables.rs:357:5:359:11 | ExprStmt | variables.rs:357:6:357:6 | x | | @@ -781,15 +781,15 @@ edges | variables.rs:358:10:358:10 | x | variables.rs:358:9:358:10 | * ... | | | variables.rs:359:9:359:10 | * ... | variables.rs:358:9:359:10 | ... + ... | | | variables.rs:359:10:359:10 | x | variables.rs:359:9:359:10 | * ... | | -| variables.rs:360:5:360:12 | return ... | variables.rs:356:1:361:1 | exit fn mutate_param (normal) | return | +| variables.rs:360:5:360:12 | return x | variables.rs:356:1:361:1 | exit fn mutate_param (normal) | return | | variables.rs:360:5:360:13 | ExprStmt | variables.rs:360:12:360:12 | x | | -| variables.rs:360:12:360:12 | x | variables.rs:360:5:360:12 | return ... | | +| variables.rs:360:12:360:12 | x | variables.rs:360:5:360:12 | return x | | | variables.rs:363:1:369:1 | enter fn mutate_param2 | variables.rs:363:22:363:22 | x | | | variables.rs:363:1:369:1 | exit fn mutate_param2 (normal) | variables.rs:363:1:369:1 | exit fn mutate_param2 | | -| variables.rs:363:22:363:22 | x | variables.rs:363:22:363:36 | x: RefType | match | -| variables.rs:363:22:363:36 | x: RefType | variables.rs:363:39:363:39 | y | | -| variables.rs:363:39:363:39 | y | variables.rs:363:39:363:57 | y: RefType | match | -| variables.rs:363:39:363:57 | y: RefType | variables.rs:364:5:366:11 | ExprStmt | | +| variables.rs:363:22:363:22 | x | variables.rs:363:22:363:36 | ...: ... | match | +| variables.rs:363:22:363:36 | ...: ... | variables.rs:363:39:363:39 | y | | +| variables.rs:363:39:363:39 | y | variables.rs:363:39:363:57 | ...: ... | match | +| variables.rs:363:39:363:57 | ...: ... | variables.rs:364:5:366:11 | ExprStmt | | | variables.rs:363:60:369:1 | { ... } | variables.rs:363:1:369:1 | exit fn mutate_param2 (normal) | | | variables.rs:364:5:364:6 | * ... | variables.rs:365:10:365:10 | x | | | variables.rs:364:5:366:10 | ... = ... | variables.rs:367:5:368:10 | ExprStmt | | @@ -805,40 +805,40 @@ edges | variables.rs:367:5:368:10 | ExprStmt | variables.rs:367:6:367:6 | y | | | variables.rs:367:6:367:6 | y | variables.rs:367:5:367:6 | * ... | | | variables.rs:368:9:368:9 | x | variables.rs:367:5:368:9 | ... = ... | | -| variables.rs:371:1:389:1 | enter fn mutate_arg | variables.rs:372:5:372:18 | let x = ... | | +| variables.rs:371:1:389:1 | enter fn mutate_arg | variables.rs:372:5:372:18 | let ... = 2 | | | variables.rs:371:1:389:1 | exit fn mutate_arg (normal) | variables.rs:371:1:389:1 | exit fn mutate_arg | | | variables.rs:371:17:389:1 | { ... } | variables.rs:371:1:389:1 | exit fn mutate_arg (normal) | | -| variables.rs:372:5:372:18 | let x = ... | variables.rs:372:17:372:17 | 2 | | -| variables.rs:372:9:372:13 | x | variables.rs:373:5:374:29 | let y = ... | match | +| variables.rs:372:5:372:18 | let ... = 2 | variables.rs:372:17:372:17 | 2 | | +| variables.rs:372:9:372:13 | x | variables.rs:373:5:374:29 | let ... = ... | match | | variables.rs:372:17:372:17 | 2 | variables.rs:372:9:372:13 | x | | -| variables.rs:373:5:374:29 | let y = ... | variables.rs:374:9:374:20 | mutate_param | | +| variables.rs:373:5:374:29 | let ... = ... | variables.rs:374:9:374:20 | mutate_param | | | variables.rs:373:9:373:9 | y | variables.rs:375:5:375:12 | ExprStmt | match | | variables.rs:374:9:374:20 | mutate_param | variables.rs:374:27:374:27 | x | | | variables.rs:374:9:374:28 | mutate_param(...) | variables.rs:373:9:373:9 | y | | -| variables.rs:374:22:374:27 | &mut ... | variables.rs:374:9:374:28 | mutate_param(...) | | -| variables.rs:374:27:374:27 | x | variables.rs:374:22:374:27 | &mut ... | | +| variables.rs:374:22:374:27 | &mut x | variables.rs:374:9:374:28 | mutate_param(...) | | +| variables.rs:374:27:374:27 | x | variables.rs:374:22:374:27 | &mut x | | | variables.rs:375:5:375:6 | * ... | variables.rs:375:10:375:11 | 10 | | | variables.rs:375:5:375:11 | ... = ... | variables.rs:377:5:377:17 | ExprStmt | | | variables.rs:375:5:375:12 | ExprStmt | variables.rs:375:6:375:6 | y | | | variables.rs:375:6:375:6 | y | variables.rs:375:5:375:6 | * ... | | | variables.rs:375:10:375:11 | 10 | variables.rs:375:5:375:11 | ... = ... | | | variables.rs:377:5:377:13 | print_i64 | variables.rs:377:15:377:15 | x | | -| variables.rs:377:5:377:16 | print_i64(...) | variables.rs:379:5:379:18 | let z = ... | | +| variables.rs:377:5:377:16 | print_i64(...) | variables.rs:379:5:379:18 | let ... = 4 | | | variables.rs:377:5:377:17 | ExprStmt | variables.rs:377:5:377:13 | print_i64 | | | variables.rs:377:15:377:15 | x | variables.rs:377:5:377:16 | print_i64(...) | | -| variables.rs:379:5:379:18 | let z = ... | variables.rs:379:17:379:17 | 4 | | -| variables.rs:379:9:379:13 | z | variables.rs:380:5:381:20 | let w = ... | match | +| variables.rs:379:5:379:18 | let ... = 4 | variables.rs:379:17:379:17 | 4 | | +| variables.rs:379:9:379:13 | z | variables.rs:380:5:381:20 | let ... = ... | match | | variables.rs:379:17:379:17 | 4 | variables.rs:379:9:379:13 | z | | -| variables.rs:380:5:381:20 | let w = ... | variables.rs:381:19:381:19 | x | | +| variables.rs:380:5:381:20 | let ... = ... | variables.rs:381:19:381:19 | x | | | variables.rs:380:9:380:9 | w | variables.rs:382:5:385:6 | ExprStmt | match | | variables.rs:381:9:381:19 | &mut ... | variables.rs:380:9:380:9 | w | | -| variables.rs:381:14:381:19 | &mut ... | variables.rs:381:9:381:19 | &mut ... | | -| variables.rs:381:19:381:19 | x | variables.rs:381:14:381:19 | &mut ... | | +| variables.rs:381:14:381:19 | &mut x | variables.rs:381:9:381:19 | &mut ... | | +| variables.rs:381:19:381:19 | x | variables.rs:381:14:381:19 | &mut x | | | variables.rs:382:5:382:17 | mutate_param2 | variables.rs:383:14:383:14 | z | | | variables.rs:382:5:385:5 | mutate_param2(...) | variables.rs:386:5:386:13 | ExprStmt | | | variables.rs:382:5:385:6 | ExprStmt | variables.rs:382:5:382:17 | mutate_param2 | | -| variables.rs:383:9:383:14 | &mut ... | variables.rs:384:9:384:9 | w | | -| variables.rs:383:14:383:14 | z | variables.rs:383:9:383:14 | &mut ... | | +| variables.rs:383:9:383:14 | &mut z | variables.rs:384:9:384:9 | w | | +| variables.rs:383:14:383:14 | z | variables.rs:383:9:383:14 | &mut z | | | variables.rs:384:9:384:9 | w | variables.rs:382:5:385:5 | mutate_param2(...) | | | variables.rs:386:5:386:7 | * ... | variables.rs:386:11:386:12 | 11 | | | variables.rs:386:5:386:12 | ... = ... | variables.rs:388:5:388:17 | ExprStmt | | @@ -850,16 +850,16 @@ edges | variables.rs:388:5:388:16 | print_i64(...) | variables.rs:371:17:389:1 | { ... } | | | variables.rs:388:5:388:17 | ExprStmt | variables.rs:388:5:388:13 | print_i64 | | | variables.rs:388:15:388:15 | z | variables.rs:388:5:388:16 | print_i64(...) | | -| variables.rs:391:1:397:1 | enter fn alias | variables.rs:392:5:392:18 | let x = ... | | +| variables.rs:391:1:397:1 | enter fn alias | variables.rs:392:5:392:18 | let ... = 1 | | | variables.rs:391:1:397:1 | exit fn alias (normal) | variables.rs:391:1:397:1 | exit fn alias | | | variables.rs:391:12:397:1 | { ... } | variables.rs:391:1:397:1 | exit fn alias (normal) | | -| variables.rs:392:5:392:18 | let x = ... | variables.rs:392:17:392:17 | 1 | | -| variables.rs:392:9:392:13 | x | variables.rs:393:5:394:15 | let y = ... | match | +| variables.rs:392:5:392:18 | let ... = 1 | variables.rs:392:17:392:17 | 1 | | +| variables.rs:392:9:392:13 | x | variables.rs:393:5:394:15 | let ... = ... | match | | variables.rs:392:17:392:17 | 1 | variables.rs:392:9:392:13 | x | | -| variables.rs:393:5:394:15 | let y = ... | variables.rs:394:14:394:14 | x | | +| variables.rs:393:5:394:15 | let ... = ... | variables.rs:394:14:394:14 | x | | | variables.rs:393:9:393:9 | y | variables.rs:395:5:395:11 | ExprStmt | match | -| variables.rs:394:9:394:14 | &mut ... | variables.rs:393:9:393:9 | y | | -| variables.rs:394:14:394:14 | x | variables.rs:394:9:394:14 | &mut ... | | +| variables.rs:394:9:394:14 | &mut x | variables.rs:393:9:393:9 | y | | +| variables.rs:394:14:394:14 | x | variables.rs:394:9:394:14 | &mut x | | | variables.rs:395:5:395:6 | * ... | variables.rs:395:10:395:10 | 2 | | | variables.rs:395:5:395:10 | ... = ... | variables.rs:396:5:396:17 | ExprStmt | | | variables.rs:395:5:395:11 | ExprStmt | variables.rs:395:6:395:6 | y | | @@ -869,13 +869,13 @@ edges | variables.rs:396:5:396:16 | print_i64(...) | variables.rs:391:12:397:1 | { ... } | | | variables.rs:396:5:396:17 | ExprStmt | variables.rs:396:5:396:13 | print_i64 | | | variables.rs:396:15:396:15 | x | variables.rs:396:5:396:16 | print_i64(...) | | -| variables.rs:399:1:407:1 | enter fn capture_immut | variables.rs:400:5:400:16 | let x = ... | | +| variables.rs:399:1:407:1 | enter fn capture_immut | variables.rs:400:5:400:16 | let ... = 100 | | | variables.rs:399:1:407:1 | exit fn capture_immut (normal) | variables.rs:399:1:407:1 | exit fn capture_immut | | | variables.rs:399:20:407:1 | { ... } | variables.rs:399:1:407:1 | exit fn capture_immut (normal) | | -| variables.rs:400:5:400:16 | let x = ... | variables.rs:400:13:400:15 | 100 | | -| variables.rs:400:9:400:9 | x | variables.rs:402:5:404:6 | let cap = ... | match | +| variables.rs:400:5:400:16 | let ... = 100 | variables.rs:400:13:400:15 | 100 | | +| variables.rs:400:9:400:9 | x | variables.rs:402:5:404:6 | let ... = ... | match | | variables.rs:400:13:400:15 | 100 | variables.rs:400:9:400:9 | x | | -| variables.rs:402:5:404:6 | let cap = ... | variables.rs:402:15:404:5 | \|...\| ... | | +| variables.rs:402:5:404:6 | let ... = ... | variables.rs:402:15:404:5 | \|...\| ... | | | variables.rs:402:9:402:11 | cap | variables.rs:405:5:405:10 | ExprStmt | match | | variables.rs:402:15:404:5 | \|...\| ... | variables.rs:402:9:402:11 | cap | | | variables.rs:402:15:404:5 | enter \|...\| ... | variables.rs:403:9:403:21 | ExprStmt | | @@ -892,13 +892,13 @@ edges | variables.rs:406:5:406:16 | print_i64(...) | variables.rs:399:20:407:1 | { ... } | | | variables.rs:406:5:406:17 | ExprStmt | variables.rs:406:5:406:13 | print_i64 | | | variables.rs:406:15:406:15 | x | variables.rs:406:5:406:16 | print_i64(...) | | -| variables.rs:409:1:433:1 | enter fn capture_mut | variables.rs:410:5:410:18 | let x = ... | | +| variables.rs:409:1:433:1 | enter fn capture_mut | variables.rs:410:5:410:18 | let ... = 1 | | | variables.rs:409:1:433:1 | exit fn capture_mut (normal) | variables.rs:409:1:433:1 | exit fn capture_mut | | | variables.rs:409:18:433:1 | { ... } | variables.rs:409:1:433:1 | exit fn capture_mut (normal) | | -| variables.rs:410:5:410:18 | let x = ... | variables.rs:410:17:410:17 | 1 | | -| variables.rs:410:9:410:13 | x | variables.rs:412:5:414:6 | let closure1 = ... | match | +| variables.rs:410:5:410:18 | let ... = 1 | variables.rs:410:17:410:17 | 1 | | +| variables.rs:410:9:410:13 | x | variables.rs:412:5:414:6 | let ... = ... | match | | variables.rs:410:17:410:17 | 1 | variables.rs:410:9:410:13 | x | | -| variables.rs:412:5:414:6 | let closure1 = ... | variables.rs:412:20:414:5 | \|...\| ... | | +| variables.rs:412:5:414:6 | let ... = ... | variables.rs:412:20:414:5 | \|...\| ... | | | variables.rs:412:9:412:16 | closure1 | variables.rs:415:5:415:15 | ExprStmt | match | | variables.rs:412:20:414:5 | \|...\| ... | variables.rs:412:9:412:16 | closure1 | | | variables.rs:412:20:414:5 | enter \|...\| ... | variables.rs:413:9:413:21 | ExprStmt | | @@ -912,13 +912,13 @@ edges | variables.rs:415:5:415:14 | closure1(...) | variables.rs:416:5:416:17 | ExprStmt | | | variables.rs:415:5:415:15 | ExprStmt | variables.rs:415:5:415:12 | closure1 | | | variables.rs:416:5:416:13 | print_i64 | variables.rs:416:15:416:15 | x | | -| variables.rs:416:5:416:16 | print_i64(...) | variables.rs:418:5:418:18 | let y = ... | | +| variables.rs:416:5:416:16 | print_i64(...) | variables.rs:418:5:418:18 | let ... = 2 | | | variables.rs:416:5:416:17 | ExprStmt | variables.rs:416:5:416:13 | print_i64 | | | variables.rs:416:15:416:15 | x | variables.rs:416:5:416:16 | print_i64(...) | | -| variables.rs:418:5:418:18 | let y = ... | variables.rs:418:17:418:17 | 2 | | -| variables.rs:418:9:418:13 | y | variables.rs:420:5:422:6 | let closure2 = ... | match | +| variables.rs:418:5:418:18 | let ... = 2 | variables.rs:418:17:418:17 | 2 | | +| variables.rs:418:9:418:13 | y | variables.rs:420:5:422:6 | let ... = ... | match | | variables.rs:418:17:418:17 | 2 | variables.rs:418:9:418:13 | y | | -| variables.rs:420:5:422:6 | let closure2 = ... | variables.rs:420:24:422:5 | \|...\| ... | | +| variables.rs:420:5:422:6 | let ... = ... | variables.rs:420:24:422:5 | \|...\| ... | | | variables.rs:420:9:420:20 | closure2 | variables.rs:423:5:423:15 | ExprStmt | match | | variables.rs:420:24:422:5 | \|...\| ... | variables.rs:420:9:420:20 | closure2 | | | variables.rs:420:24:422:5 | enter \|...\| ... | variables.rs:421:9:421:14 | ExprStmt | | @@ -932,13 +932,13 @@ edges | variables.rs:423:5:423:14 | closure2(...) | variables.rs:424:5:424:17 | ExprStmt | | | variables.rs:423:5:423:15 | ExprStmt | variables.rs:423:5:423:12 | closure2 | | | variables.rs:424:5:424:13 | print_i64 | variables.rs:424:15:424:15 | y | | -| variables.rs:424:5:424:16 | print_i64(...) | variables.rs:426:5:426:18 | let z = ... | | +| variables.rs:424:5:424:16 | print_i64(...) | variables.rs:426:5:426:18 | let ... = 2 | | | variables.rs:424:5:424:17 | ExprStmt | variables.rs:424:5:424:13 | print_i64 | | | variables.rs:424:15:424:15 | y | variables.rs:424:5:424:16 | print_i64(...) | | -| variables.rs:426:5:426:18 | let z = ... | variables.rs:426:17:426:17 | 2 | | -| variables.rs:426:9:426:13 | z | variables.rs:428:5:430:6 | let closure3 = ... | match | +| variables.rs:426:5:426:18 | let ... = 2 | variables.rs:426:17:426:17 | 2 | | +| variables.rs:426:9:426:13 | z | variables.rs:428:5:430:6 | let ... = ... | match | | variables.rs:426:17:426:17 | 2 | variables.rs:426:9:426:13 | z | | -| variables.rs:428:5:430:6 | let closure3 = ... | variables.rs:428:24:430:5 | \|...\| ... | | +| variables.rs:428:5:430:6 | let ... = ... | variables.rs:428:24:430:5 | \|...\| ... | | | variables.rs:428:9:428:20 | closure3 | variables.rs:431:5:431:15 | ExprStmt | match | | variables.rs:428:24:430:5 | \|...\| ... | variables.rs:428:9:428:20 | closure3 | | | variables.rs:428:24:430:5 | enter \|...\| ... | variables.rs:429:9:429:24 | ExprStmt | | @@ -955,13 +955,13 @@ edges | variables.rs:432:5:432:16 | print_i64(...) | variables.rs:409:18:433:1 | { ... } | | | variables.rs:432:5:432:17 | ExprStmt | variables.rs:432:5:432:13 | print_i64 | | | variables.rs:432:15:432:15 | z | variables.rs:432:5:432:16 | print_i64(...) | | -| variables.rs:435:1:443:1 | enter fn async_block_capture | variables.rs:436:5:436:23 | let i = ... | | +| variables.rs:435:1:443:1 | enter fn async_block_capture | variables.rs:436:5:436:23 | let ... = 0 | | | variables.rs:435:1:443:1 | exit fn async_block_capture (normal) | variables.rs:435:1:443:1 | exit fn async_block_capture | | | variables.rs:435:32:443:1 | { ... } | variables.rs:435:1:443:1 | exit fn async_block_capture (normal) | | -| variables.rs:436:5:436:23 | let i = ... | variables.rs:436:22:436:22 | 0 | | -| variables.rs:436:9:436:13 | i | variables.rs:437:5:439:6 | let block = ... | match | +| variables.rs:436:5:436:23 | let ... = 0 | variables.rs:436:22:436:22 | 0 | | +| variables.rs:436:9:436:13 | i | variables.rs:437:5:439:6 | let ... = ... | match | | variables.rs:436:22:436:22 | 0 | variables.rs:436:9:436:13 | i | | -| variables.rs:437:5:439:6 | let block = ... | variables.rs:437:17:439:5 | { ... } | | +| variables.rs:437:5:439:6 | let ... = ... | variables.rs:437:17:439:5 | { ... } | | | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:16 | ExprStmt | match | | variables.rs:437:17:439:5 | enter { ... } | variables.rs:438:9:438:14 | ExprStmt | | | variables.rs:437:17:439:5 | exit { ... } (normal) | variables.rs:437:17:439:5 | exit { ... } | | @@ -970,8 +970,8 @@ edges | variables.rs:438:9:438:13 | ... = ... | variables.rs:437:17:439:5 | exit { ... } (normal) | | | variables.rs:438:9:438:14 | ExprStmt | variables.rs:438:9:438:9 | i | | | variables.rs:438:13:438:13 | 1 | variables.rs:438:9:438:13 | ... = ... | | -| variables.rs:441:5:441:9 | block | variables.rs:441:5:441:15 | await ... | | -| variables.rs:441:5:441:15 | await ... | variables.rs:442:5:442:17 | ExprStmt | | +| variables.rs:441:5:441:9 | block | variables.rs:441:5:441:15 | await block | | +| variables.rs:441:5:441:15 | await block | variables.rs:442:5:442:17 | ExprStmt | | | variables.rs:441:5:441:16 | ExprStmt | variables.rs:441:5:441:9 | block | | | variables.rs:442:5:442:13 | print_i64 | variables.rs:442:15:442:15 | i | | | variables.rs:442:5:442:16 | print_i64(...) | variables.rs:435:32:443:1 | { ... } | | @@ -979,10 +979,10 @@ edges | variables.rs:442:15:442:15 | i | variables.rs:442:5:442:16 | print_i64(...) | | | variables.rs:445:1:459:1 | enter fn phi | variables.rs:445:8:445:8 | b | | | variables.rs:445:1:459:1 | exit fn phi (normal) | variables.rs:445:1:459:1 | exit fn phi | | -| variables.rs:445:8:445:8 | b | variables.rs:445:8:445:15 | b: bool | match | -| variables.rs:445:8:445:15 | b: bool | variables.rs:446:5:446:18 | let x = ... | | +| variables.rs:445:8:445:8 | b | variables.rs:445:8:445:15 | ...: bool | match | +| variables.rs:445:8:445:15 | ...: bool | variables.rs:446:5:446:18 | let ... = 1 | | | variables.rs:445:18:459:1 | { ... } | variables.rs:445:1:459:1 | exit fn phi (normal) | | -| variables.rs:446:5:446:18 | let x = ... | variables.rs:446:17:446:17 | 1 | | +| variables.rs:446:5:446:18 | let ... = 1 | variables.rs:446:17:446:17 | 1 | | | variables.rs:446:9:446:13 | x | variables.rs:447:5:447:17 | ExprStmt | match | | variables.rs:446:17:446:17 | 1 | variables.rs:446:9:446:13 | x | | | variables.rs:447:5:447:13 | print_i64 | variables.rs:447:15:447:15 | x | | @@ -996,10 +996,10 @@ edges | variables.rs:448:15:448:19 | ... + ... | variables.rs:448:5:448:20 | print_i64(...) | | | variables.rs:448:19:448:19 | 1 | variables.rs:448:15:448:19 | ... + ... | | | variables.rs:449:5:457:5 | ExprStmt | variables.rs:449:8:449:8 | b | | -| variables.rs:449:5:457:5 | if ... { ... } else { ... } | variables.rs:458:5:458:17 | ExprStmt | | +| variables.rs:449:5:457:5 | if b {...} else {...} | variables.rs:458:5:458:17 | ExprStmt | | | variables.rs:449:8:449:8 | b | variables.rs:450:9:450:14 | ExprStmt | true | | variables.rs:449:8:449:8 | b | variables.rs:454:9:454:14 | ExprStmt | false | -| variables.rs:449:10:453:5 | { ... } | variables.rs:449:5:457:5 | if ... { ... } else { ... } | | +| variables.rs:449:10:453:5 | { ... } | variables.rs:449:5:457:5 | if b {...} else {...} | | | variables.rs:450:9:450:9 | x | variables.rs:450:13:450:13 | 2 | | | variables.rs:450:9:450:13 | ... = ... | variables.rs:451:9:451:21 | ExprStmt | | | variables.rs:450:9:450:14 | ExprStmt | variables.rs:450:9:450:9 | x | | @@ -1014,7 +1014,7 @@ edges | variables.rs:452:19:452:19 | x | variables.rs:452:23:452:23 | 1 | | | variables.rs:452:19:452:23 | ... + ... | variables.rs:452:9:452:24 | print_i64(...) | | | variables.rs:452:23:452:23 | 1 | variables.rs:452:19:452:23 | ... + ... | | -| variables.rs:453:12:457:5 | { ... } | variables.rs:449:5:457:5 | if ... { ... } else { ... } | | +| variables.rs:453:12:457:5 | { ... } | variables.rs:449:5:457:5 | if b {...} else {...} | | | variables.rs:454:9:454:9 | x | variables.rs:454:13:454:13 | 3 | | | variables.rs:454:9:454:13 | ... = ... | variables.rs:455:9:455:21 | ExprStmt | | | variables.rs:454:9:454:14 | ExprStmt | variables.rs:454:9:454:9 | x | | @@ -1035,37 +1035,37 @@ edges | variables.rs:458:15:458:15 | x | variables.rs:458:5:458:16 | print_i64(...) | | | variables.rs:461:1:474:1 | enter fn phi_read | variables.rs:461:13:461:14 | b1 | | | variables.rs:461:1:474:1 | exit fn phi_read (normal) | variables.rs:461:1:474:1 | exit fn phi_read | | -| variables.rs:461:13:461:14 | b1 | variables.rs:461:13:461:21 | b1: bool | match | -| variables.rs:461:13:461:21 | b1: bool | variables.rs:461:24:461:25 | b2 | | -| variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:32 | b2: bool | match | -| variables.rs:461:24:461:32 | b2: bool | variables.rs:462:5:462:14 | let x = ... | | +| variables.rs:461:13:461:14 | b1 | variables.rs:461:13:461:21 | ...: bool | match | +| variables.rs:461:13:461:21 | ...: bool | variables.rs:461:24:461:25 | b2 | | +| variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:32 | ...: bool | match | +| variables.rs:461:24:461:32 | ...: bool | variables.rs:462:5:462:14 | let ... = 1 | | | variables.rs:461:35:474:1 | { ... } | variables.rs:461:1:474:1 | exit fn phi_read (normal) | | -| variables.rs:462:5:462:14 | let x = ... | variables.rs:462:13:462:13 | 1 | | +| variables.rs:462:5:462:14 | let ... = 1 | variables.rs:462:13:462:13 | 1 | | | variables.rs:462:9:462:9 | x | variables.rs:463:5:467:5 | ExprStmt | match | | variables.rs:462:13:462:13 | 1 | variables.rs:462:9:462:9 | x | | | variables.rs:463:5:467:5 | ExprStmt | variables.rs:463:8:463:9 | b1 | | -| variables.rs:463:5:467:5 | if ... { ... } else { ... } | variables.rs:469:8:469:9 | b2 | | +| variables.rs:463:5:467:5 | if b1 {...} else {...} | variables.rs:469:8:469:9 | b2 | | | variables.rs:463:8:463:9 | b1 | variables.rs:464:9:464:21 | ExprStmt | true | | variables.rs:463:8:463:9 | b1 | variables.rs:466:9:466:21 | ExprStmt | false | -| variables.rs:463:11:465:5 | { ... } | variables.rs:463:5:467:5 | if ... { ... } else { ... } | | +| variables.rs:463:11:465:5 | { ... } | variables.rs:463:5:467:5 | if b1 {...} else {...} | | | variables.rs:464:9:464:17 | print_i64 | variables.rs:464:19:464:19 | x | | | variables.rs:464:9:464:20 | print_i64(...) | variables.rs:463:11:465:5 | { ... } | | | variables.rs:464:9:464:21 | ExprStmt | variables.rs:464:9:464:17 | print_i64 | | | variables.rs:464:19:464:19 | x | variables.rs:464:9:464:20 | print_i64(...) | | -| variables.rs:465:12:467:5 | { ... } | variables.rs:463:5:467:5 | if ... { ... } else { ... } | | +| variables.rs:465:12:467:5 | { ... } | variables.rs:463:5:467:5 | if b1 {...} else {...} | | | variables.rs:466:9:466:17 | print_i64 | variables.rs:466:19:466:19 | x | | | variables.rs:466:9:466:20 | print_i64(...) | variables.rs:465:12:467:5 | { ... } | | | variables.rs:466:9:466:21 | ExprStmt | variables.rs:466:9:466:17 | print_i64 | | | variables.rs:466:19:466:19 | x | variables.rs:466:9:466:20 | print_i64(...) | | -| variables.rs:469:5:473:5 | if ... { ... } else { ... } | variables.rs:461:35:474:1 | { ... } | | +| variables.rs:469:5:473:5 | if b2 {...} else {...} | variables.rs:461:35:474:1 | { ... } | | | variables.rs:469:8:469:9 | b2 | variables.rs:470:9:470:21 | ExprStmt | true | | variables.rs:469:8:469:9 | b2 | variables.rs:472:9:472:21 | ExprStmt | false | -| variables.rs:469:11:471:5 | { ... } | variables.rs:469:5:473:5 | if ... { ... } else { ... } | | +| variables.rs:469:11:471:5 | { ... } | variables.rs:469:5:473:5 | if b2 {...} else {...} | | | variables.rs:470:9:470:17 | print_i64 | variables.rs:470:19:470:19 | x | | | variables.rs:470:9:470:20 | print_i64(...) | variables.rs:469:11:471:5 | { ... } | | | variables.rs:470:9:470:21 | ExprStmt | variables.rs:470:9:470:17 | print_i64 | | | variables.rs:470:19:470:19 | x | variables.rs:470:9:470:20 | print_i64(...) | | -| variables.rs:471:12:473:5 | { ... } | variables.rs:469:5:473:5 | if ... { ... } else { ... } | | +| variables.rs:471:12:473:5 | { ... } | variables.rs:469:5:473:5 | if b2 {...} else {...} | | | variables.rs:472:9:472:17 | print_i64 | variables.rs:472:19:472:19 | x | | | variables.rs:472:9:472:20 | print_i64(...) | variables.rs:471:12:473:5 | { ... } | | | variables.rs:472:9:472:21 | ExprStmt | variables.rs:472:9:472:17 | print_i64 | | @@ -1074,12 +1074,12 @@ edges | variables.rs:482:5:484:5 | exit fn my_get (normal) | variables.rs:482:5:484:5 | exit fn my_get | | | variables.rs:483:9:483:23 | return ... | variables.rs:482:5:484:5 | exit fn my_get (normal) | return | | variables.rs:483:9:483:24 | ExprStmt | variables.rs:483:16:483:19 | self | | -| variables.rs:483:16:483:19 | self | variables.rs:483:16:483:23 | ... .val | | -| variables.rs:483:16:483:23 | ... .val | variables.rs:483:9:483:23 | return ... | | -| variables.rs:487:1:494:1 | enter fn structs | variables.rs:488:5:488:36 | let a = ... | | +| variables.rs:483:16:483:19 | self | variables.rs:483:16:483:23 | self.val | | +| variables.rs:483:16:483:23 | self.val | variables.rs:483:9:483:23 | return ... | | +| variables.rs:487:1:494:1 | enter fn structs | variables.rs:488:5:488:36 | let ... = ... | | | variables.rs:487:1:494:1 | exit fn structs (normal) | variables.rs:487:1:494:1 | exit fn structs | | | variables.rs:487:14:494:1 | { ... } | variables.rs:487:1:494:1 | exit fn structs (normal) | | -| variables.rs:488:5:488:36 | let a = ... | variables.rs:488:33:488:33 | 1 | | +| variables.rs:488:5:488:36 | let ... = ... | variables.rs:488:33:488:33 | 1 | | | variables.rs:488:9:488:13 | a | variables.rs:489:5:489:26 | ExprStmt | match | | variables.rs:488:17:488:35 | MyStruct {...} | variables.rs:488:9:488:13 | a | | | variables.rs:488:33:488:33 | 1 | variables.rs:488:17:488:35 | MyStruct {...} | | @@ -1088,8 +1088,8 @@ edges | variables.rs:489:5:489:26 | ExprStmt | variables.rs:489:5:489:13 | print_i64 | | | variables.rs:489:15:489:15 | a | variables.rs:489:15:489:24 | ... .my_get(...) | | | variables.rs:489:15:489:24 | ... .my_get(...) | variables.rs:489:5:489:25 | print_i64(...) | | -| variables.rs:490:5:490:5 | a | variables.rs:490:5:490:9 | ... .val | | -| variables.rs:490:5:490:9 | ... .val | variables.rs:490:13:490:13 | 5 | | +| variables.rs:490:5:490:5 | a | variables.rs:490:5:490:9 | a.val | | +| variables.rs:490:5:490:9 | a.val | variables.rs:490:13:490:13 | 5 | | | variables.rs:490:5:490:13 | ... = ... | variables.rs:491:5:491:26 | ExprStmt | | | variables.rs:490:5:490:14 | ExprStmt | variables.rs:490:5:490:5 | a | | | variables.rs:490:13:490:13 | 5 | variables.rs:490:5:490:13 | ... = ... | | @@ -1108,29 +1108,29 @@ edges | variables.rs:493:5:493:26 | ExprStmt | variables.rs:493:5:493:13 | print_i64 | | | variables.rs:493:15:493:15 | a | variables.rs:493:15:493:24 | ... .my_get(...) | | | variables.rs:493:15:493:24 | ... .my_get(...) | variables.rs:493:5:493:25 | print_i64(...) | | -| variables.rs:496:1:503:1 | enter fn ref_arg | variables.rs:497:5:497:15 | let x = ... | | +| variables.rs:496:1:503:1 | enter fn ref_arg | variables.rs:497:5:497:15 | let ... = 16 | | | variables.rs:496:1:503:1 | exit fn ref_arg (normal) | variables.rs:496:1:503:1 | exit fn ref_arg | | | variables.rs:496:14:503:1 | { ... } | variables.rs:496:1:503:1 | exit fn ref_arg (normal) | | -| variables.rs:497:5:497:15 | let x = ... | variables.rs:497:13:497:14 | 16 | | +| variables.rs:497:5:497:15 | let ... = 16 | variables.rs:497:13:497:14 | 16 | | | variables.rs:497:9:497:9 | x | variables.rs:498:5:498:22 | ExprStmt | match | | variables.rs:497:13:497:14 | 16 | variables.rs:497:9:497:9 | x | | | variables.rs:498:5:498:17 | print_i64_ref | variables.rs:498:20:498:20 | x | | | variables.rs:498:5:498:21 | print_i64_ref(...) | variables.rs:499:5:499:17 | ExprStmt | | | variables.rs:498:5:498:22 | ExprStmt | variables.rs:498:5:498:17 | print_i64_ref | | -| variables.rs:498:19:498:20 | &... | variables.rs:498:5:498:21 | print_i64_ref(...) | | -| variables.rs:498:20:498:20 | x | variables.rs:498:19:498:20 | &... | | +| variables.rs:498:19:498:20 | &x | variables.rs:498:5:498:21 | print_i64_ref(...) | | +| variables.rs:498:20:498:20 | x | variables.rs:498:19:498:20 | &x | | | variables.rs:499:5:499:13 | print_i64 | variables.rs:499:15:499:15 | x | | -| variables.rs:499:5:499:16 | print_i64(...) | variables.rs:501:5:501:15 | let z = ... | | +| variables.rs:499:5:499:16 | print_i64(...) | variables.rs:501:5:501:15 | let ... = 17 | | | variables.rs:499:5:499:17 | ExprStmt | variables.rs:499:5:499:13 | print_i64 | | | variables.rs:499:15:499:15 | x | variables.rs:499:5:499:16 | print_i64(...) | | -| variables.rs:501:5:501:15 | let z = ... | variables.rs:501:13:501:14 | 17 | | +| variables.rs:501:5:501:15 | let ... = 17 | variables.rs:501:13:501:14 | 17 | | | variables.rs:501:9:501:9 | z | variables.rs:502:5:502:22 | ExprStmt | match | | variables.rs:501:13:501:14 | 17 | variables.rs:501:9:501:9 | z | | | variables.rs:502:5:502:17 | print_i64_ref | variables.rs:502:20:502:20 | z | | | variables.rs:502:5:502:21 | print_i64_ref(...) | variables.rs:496:14:503:1 | { ... } | | | variables.rs:502:5:502:22 | ExprStmt | variables.rs:502:5:502:17 | print_i64_ref | | -| variables.rs:502:19:502:20 | &... | variables.rs:502:5:502:21 | print_i64_ref(...) | | -| variables.rs:502:20:502:20 | z | variables.rs:502:19:502:20 | &... | | +| variables.rs:502:19:502:20 | &z | variables.rs:502:5:502:21 | print_i64_ref(...) | | +| variables.rs:502:20:502:20 | z | variables.rs:502:19:502:20 | &z | | | variables.rs:510:3:512:3 | enter fn bar | variables.rs:511:5:511:32 | ExprStmt | | | variables.rs:510:3:512:3 | exit fn bar (normal) | variables.rs:510:3:512:3 | exit fn bar | | | variables.rs:510:21:512:3 | { ... } | variables.rs:510:3:512:3 | exit fn bar (normal) | | @@ -1140,10 +1140,10 @@ edges | variables.rs:511:6:511:9 | self | variables.rs:511:5:511:9 | * ... | | | variables.rs:511:13:511:31 | MyStruct {...} | variables.rs:511:5:511:31 | ... = ... | | | variables.rs:511:29:511:29 | 3 | variables.rs:511:13:511:31 | MyStruct {...} | | -| variables.rs:515:1:520:1 | enter fn ref_methodcall_receiver | variables.rs:516:3:516:34 | let a = ... | | +| variables.rs:515:1:520:1 | enter fn ref_methodcall_receiver | variables.rs:516:3:516:34 | let ... = ... | | | variables.rs:515:1:520:1 | exit fn ref_methodcall_receiver (normal) | variables.rs:515:1:520:1 | exit fn ref_methodcall_receiver | | | variables.rs:515:30:520:1 | { ... } | variables.rs:515:1:520:1 | exit fn ref_methodcall_receiver (normal) | | -| variables.rs:516:3:516:34 | let a = ... | variables.rs:516:31:516:31 | 1 | | +| variables.rs:516:3:516:34 | let ... = ... | variables.rs:516:31:516:31 | 1 | | | variables.rs:516:7:516:11 | a | variables.rs:517:3:517:10 | ExprStmt | match | | variables.rs:516:15:516:33 | MyStruct {...} | variables.rs:516:7:516:11 | a | | | variables.rs:516:31:516:31 | 1 | variables.rs:516:15:516:33 | MyStruct {...} | | @@ -1153,8 +1153,8 @@ edges | variables.rs:519:3:519:11 | print_i64 | variables.rs:519:13:519:13 | a | | | variables.rs:519:3:519:18 | print_i64(...) | variables.rs:515:30:520:1 | { ... } | | | variables.rs:519:3:519:19 | ExprStmt | variables.rs:519:3:519:11 | print_i64 | | -| variables.rs:519:13:519:13 | a | variables.rs:519:13:519:17 | ... .val | | -| variables.rs:519:13:519:17 | ... .val | variables.rs:519:3:519:18 | print_i64(...) | | +| variables.rs:519:13:519:13 | a | variables.rs:519:13:519:17 | a.val | | +| variables.rs:519:13:519:17 | a.val | variables.rs:519:3:519:18 | print_i64(...) | | | variables.rs:522:1:556:1 | enter fn main | variables.rs:523:5:523:25 | ExprStmt | | | variables.rs:522:1:556:1 | exit fn main (normal) | variables.rs:522:1:556:1 | exit fn main | | | variables.rs:522:11:556:1 | { ... } | variables.rs:522:1:556:1 | exit fn main (normal) | | diff --git a/rust/ql/test/library-tests/variables/Ssa.expected b/rust/ql/test/library-tests/variables/Ssa.expected index 8eb885d77d3..af3c96d9503 100644 --- a/rust/ql/test/library-tests/variables/Ssa.expected +++ b/rust/ql/test/library-tests/variables/Ssa.expected @@ -125,7 +125,7 @@ definition | variables.rs:436:9:436:13 | i | variables.rs:436:13:436:13 | i | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | | variables.rs:438:9:438:9 | i | variables.rs:436:13:436:13 | i | -| variables.rs:441:5:441:15 | await ... | variables.rs:436:13:436:13 | i | +| variables.rs:441:5:441:15 | await block | variables.rs:436:13:436:13 | i | | variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | | variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | @@ -242,7 +242,7 @@ read | variables.rs:423:5:423:14 | closure2(...) | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | -| variables.rs:441:5:441:15 | await ... | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | +| variables.rs:441:5:441:15 | await block | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | | variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | variables.rs:449:8:449:8 | b | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:447:15:447:15 | x | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:448:15:448:15 | x | @@ -346,7 +346,7 @@ firstRead | variables.rs:423:5:423:14 | closure2(...) | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | -| variables.rs:441:5:441:15 | await ... | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | +| variables.rs:441:5:441:15 | await block | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | | variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | variables.rs:449:8:449:8 | b | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:447:15:447:15 | x | | variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | variables.rs:458:15:458:15 | x | @@ -446,7 +446,7 @@ lastRead | variables.rs:423:5:423:14 | closure2(...) | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | -| variables.rs:441:5:441:15 | await ... | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | +| variables.rs:441:5:441:15 | await block | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | | variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | variables.rs:449:8:449:8 | b | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:448:15:448:15 | x | | variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | variables.rs:458:15:458:15 | x | diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index ea439e78d5b..5ce79f25801 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -1,2 +1,468 @@ -ERROR: empty recursive call: dispatch predicate for CommentImpl::Impl::Comment::getCommentMarker (CommentImpl.qll:23,47-63) -ERROR: empty recursive call: dispatch predicate for CommentImpl::Impl::Comment::getText (CommentImpl.qll:36,34-41) +testFailures +failures +variable +| variables.rs:3:14:3:14 | s | +| variables.rs:7:14:7:14 | i | +| variables.rs:11:18:11:18 | i | +| variables.rs:16:9:16:10 | x1 | +| variables.rs:21:13:21:14 | x2 | +| variables.rs:28:13:28:13 | x | +| variables.rs:35:9:35:10 | x3 | +| variables.rs:37:9:37:10 | x3 | +| variables.rs:43:9:43:10 | x4 | +| variables.rs:46:13:46:14 | x4 | +| variables.rs:60:13:60:14 | a1 | +| variables.rs:61:13:61:14 | b1 | +| variables.rs:64:13:64:13 | x | +| variables.rs:65:13:65:13 | y | +| variables.rs:75:9:75:10 | p1 | +| variables.rs:77:12:77:13 | a2 | +| variables.rs:78:12:78:13 | b2 | +| variables.rs:85:9:85:10 | s1 | +| variables.rs:87:21:87:22 | s2 | +| variables.rs:94:14:94:15 | x5 | +| variables.rs:102:9:102:10 | s1 | +| variables.rs:104:24:104:25 | s2 | +| variables.rs:111:9:111:10 | x6 | +| variables.rs:112:9:112:10 | y1 | +| variables.rs:116:14:116:15 | y1 | +| variables.rs:128:9:128:15 | numbers | +| variables.rs:132:13:132:17 | first | +| variables.rs:133:13:133:17 | third | +| variables.rs:134:13:134:17 | fifth | +| variables.rs:144:13:144:17 | first | +| variables.rs:146:13:146:16 | last | +| variables.rs:155:9:155:10 | p2 | +| variables.rs:159:16:159:17 | x7 | +| variables.rs:169:9:169:11 | msg | +| variables.rs:173:17:173:27 | id_variable | +| variables.rs:178:26:178:27 | id | +| variables.rs:189:9:189:14 | either | +| variables.rs:191:9:191:44 | a3 | +| variables.rs:203:9:203:10 | tv | +| variables.rs:205:9:205:81 | a4 | +| variables.rs:209:9:209:83 | a5 | +| variables.rs:213:9:213:83 | a6 | +| variables.rs:219:9:219:14 | either | +| variables.rs:221:9:221:44 | a7 | +| variables.rs:229:9:229:14 | either | +| variables.rs:232:13:232:13 | e | +| variables.rs:233:14:233:51 | a11 | +| variables.rs:236:33:236:35 | a12 | +| variables.rs:253:9:253:10 | fv | +| variables.rs:255:9:255:109 | a13 | +| variables.rs:261:5:261:6 | a8 | +| variables.rs:263:9:263:10 | b3 | +| variables.rs:264:9:264:10 | c1 | +| variables.rs:272:6:272:41 | a9 | +| variables.rs:279:13:279:15 | a10 | +| variables.rs:280:13:280:14 | b4 | +| variables.rs:281:13:281:14 | c2 | +| variables.rs:302:13:302:15 | a10 | +| variables.rs:303:13:303:14 | b4 | +| variables.rs:315:9:315:23 | example_closure | +| variables.rs:316:10:316:10 | x | +| variables.rs:318:9:318:10 | n1 | +| variables.rs:323:9:323:26 | immutable_variable | +| variables.rs:324:10:324:10 | x | +| variables.rs:326:9:326:10 | n2 | +| variables.rs:332:9:332:9 | v | +| variables.rs:334:9:334:12 | text | +| variables.rs:341:13:341:13 | a | +| variables.rs:349:13:349:13 | i | +| variables.rs:350:9:350:13 | ref_i | +| variables.rs:356:17:356:17 | x | +| variables.rs:363:22:363:22 | x | +| variables.rs:363:39:363:39 | y | +| variables.rs:372:13:372:13 | x | +| variables.rs:373:9:373:9 | y | +| variables.rs:379:13:379:13 | z | +| variables.rs:380:9:380:9 | w | +| variables.rs:392:13:392:13 | x | +| variables.rs:393:9:393:9 | y | +| variables.rs:400:9:400:9 | x | +| variables.rs:402:9:402:11 | cap | +| variables.rs:410:13:410:13 | x | +| variables.rs:412:9:412:16 | closure1 | +| variables.rs:418:13:418:13 | y | +| variables.rs:420:13:420:20 | closure2 | +| variables.rs:426:13:426:13 | z | +| variables.rs:428:13:428:20 | closure3 | +| variables.rs:436:13:436:13 | i | +| variables.rs:437:9:437:13 | block | +| variables.rs:445:8:445:8 | b | +| variables.rs:446:13:446:13 | x | +| variables.rs:461:13:461:14 | b1 | +| variables.rs:461:24:461:25 | b2 | +| variables.rs:462:9:462:9 | x | +| variables.rs:488:13:488:13 | a | +| variables.rs:497:9:497:9 | x | +| variables.rs:501:9:501:9 | z | +| variables.rs:516:11:516:11 | a | +variableAccess +| variables.rs:4:20:4:20 | s | variables.rs:3:14:3:14 | s | +| variables.rs:8:20:8:20 | i | variables.rs:7:14:7:14 | i | +| variables.rs:12:16:12:16 | i | variables.rs:11:18:11:18 | i | +| variables.rs:17:15:17:16 | x1 | variables.rs:16:9:16:10 | x1 | +| variables.rs:22:15:22:16 | x2 | variables.rs:21:13:21:14 | x2 | +| variables.rs:23:5:23:6 | x2 | variables.rs:21:13:21:14 | x2 | +| variables.rs:24:15:24:16 | x2 | variables.rs:21:13:21:14 | x2 | +| variables.rs:29:20:29:20 | x | variables.rs:28:13:28:13 | x | +| variables.rs:30:5:30:5 | x | variables.rs:28:13:28:13 | x | +| variables.rs:31:20:31:20 | x | variables.rs:28:13:28:13 | x | +| variables.rs:36:15:36:16 | x3 | variables.rs:35:9:35:10 | x3 | +| variables.rs:38:9:38:10 | x3 | variables.rs:35:9:35:10 | x3 | +| variables.rs:39:15:39:16 | x3 | variables.rs:37:9:37:10 | x3 | +| variables.rs:44:15:44:16 | x4 | variables.rs:43:9:43:10 | x4 | +| variables.rs:47:19:47:20 | x4 | variables.rs:46:13:46:14 | x4 | +| variables.rs:49:15:49:16 | x4 | variables.rs:43:9:43:10 | x4 | +| variables.rs:68:15:68:16 | a1 | variables.rs:60:13:60:14 | a1 | +| variables.rs:69:15:69:16 | b1 | variables.rs:61:13:61:14 | b1 | +| variables.rs:70:15:70:15 | x | variables.rs:64:13:64:13 | x | +| variables.rs:71:15:71:15 | y | variables.rs:65:13:65:13 | y | +| variables.rs:79:9:79:10 | p1 | variables.rs:75:9:75:10 | p1 | +| variables.rs:80:15:80:16 | a2 | variables.rs:77:12:77:13 | a2 | +| variables.rs:81:15:81:16 | b2 | variables.rs:78:12:78:13 | b2 | +| variables.rs:88:11:88:12 | s1 | variables.rs:85:9:85:10 | s1 | +| variables.rs:89:19:89:20 | s2 | variables.rs:87:21:87:22 | s2 | +| variables.rs:98:15:98:16 | x5 | variables.rs:94:14:94:15 | x5 | +| variables.rs:105:11:105:12 | s1 | variables.rs:102:9:102:10 | s1 | +| variables.rs:106:19:106:20 | s2 | variables.rs:104:24:104:25 | s2 | +| variables.rs:114:11:114:12 | x6 | variables.rs:111:9:111:10 | x6 | +| variables.rs:119:23:119:24 | y1 | variables.rs:116:14:116:15 | y1 | +| variables.rs:124:15:124:16 | y1 | variables.rs:112:9:112:10 | y1 | +| variables.rs:130:11:130:17 | numbers | variables.rs:128:9:128:15 | numbers | +| variables.rs:136:23:136:27 | first | variables.rs:132:13:132:17 | first | +| variables.rs:137:23:137:27 | third | variables.rs:133:13:133:17 | third | +| variables.rs:138:23:138:27 | fifth | variables.rs:134:13:134:17 | fifth | +| variables.rs:142:11:142:17 | numbers | variables.rs:128:9:128:15 | numbers | +| variables.rs:148:23:148:27 | first | variables.rs:144:13:144:17 | first | +| variables.rs:149:23:149:26 | last | variables.rs:146:13:146:16 | last | +| variables.rs:157:11:157:12 | p2 | variables.rs:155:9:155:10 | p2 | +| variables.rs:160:24:160:25 | x7 | variables.rs:159:16:159:17 | x7 | +| variables.rs:171:11:171:13 | msg | variables.rs:169:9:169:11 | msg | +| variables.rs:174:24:174:34 | id_variable | variables.rs:173:17:173:27 | id_variable | +| variables.rs:179:23:179:24 | id | variables.rs:178:26:178:27 | id | +| variables.rs:190:11:190:16 | either | variables.rs:189:9:189:14 | either | +| variables.rs:192:26:192:27 | a3 | variables.rs:191:9:191:44 | a3 | +| variables.rs:204:11:204:12 | tv | variables.rs:203:9:203:10 | tv | +| variables.rs:206:26:206:27 | a4 | variables.rs:205:9:205:81 | a4 | +| variables.rs:208:11:208:12 | tv | variables.rs:203:9:203:10 | tv | +| variables.rs:210:26:210:27 | a5 | variables.rs:209:9:209:83 | a5 | +| variables.rs:212:11:212:12 | tv | variables.rs:203:9:203:10 | tv | +| variables.rs:214:26:214:27 | a6 | variables.rs:213:9:213:83 | a6 | +| variables.rs:220:11:220:16 | either | variables.rs:219:9:219:14 | either | +| variables.rs:222:16:222:17 | a7 | variables.rs:221:9:221:44 | a7 | +| variables.rs:223:26:223:27 | a7 | variables.rs:221:9:221:44 | a7 | +| variables.rs:231:11:231:16 | either | variables.rs:229:9:229:14 | either | +| variables.rs:235:23:235:25 | a11 | variables.rs:233:14:233:51 | a11 | +| variables.rs:237:15:237:15 | e | variables.rs:232:13:232:13 | e | +| variables.rs:238:28:238:30 | a12 | variables.rs:236:33:236:35 | a12 | +| variables.rs:254:11:254:12 | fv | variables.rs:253:9:253:10 | fv | +| variables.rs:256:26:256:28 | a13 | variables.rs:255:9:255:109 | a13 | +| variables.rs:266:15:266:16 | a8 | variables.rs:261:5:261:6 | a8 | +| variables.rs:267:15:267:16 | b3 | variables.rs:263:9:263:10 | b3 | +| variables.rs:268:15:268:16 | c1 | variables.rs:264:9:264:10 | c1 | +| variables.rs:274:15:274:16 | a9 | variables.rs:272:6:272:41 | a9 | +| variables.rs:283:15:283:17 | a10 | variables.rs:279:13:279:15 | a10 | +| variables.rs:284:15:284:16 | b4 | variables.rs:280:13:280:14 | b4 | +| variables.rs:285:15:285:16 | c2 | variables.rs:281:13:281:14 | c2 | +| variables.rs:288:9:288:10 | c2 | variables.rs:281:13:281:14 | c2 | +| variables.rs:289:9:289:10 | b4 | variables.rs:280:13:280:14 | b4 | +| variables.rs:290:9:290:11 | a10 | variables.rs:279:13:279:15 | a10 | +| variables.rs:292:9:292:11 | a10 | variables.rs:279:13:279:15 | a10 | +| variables.rs:293:9:293:10 | b4 | variables.rs:280:13:280:14 | b4 | +| variables.rs:294:9:294:10 | c2 | variables.rs:281:13:281:14 | c2 | +| variables.rs:296:15:296:17 | a10 | variables.rs:279:13:279:15 | a10 | +| variables.rs:297:15:297:16 | b4 | variables.rs:280:13:280:14 | b4 | +| variables.rs:298:15:298:16 | c2 | variables.rs:281:13:281:14 | c2 | +| variables.rs:305:23:305:25 | a10 | variables.rs:302:13:302:15 | a10 | +| variables.rs:306:23:306:24 | b4 | variables.rs:303:13:303:14 | b4 | +| variables.rs:310:15:310:17 | a10 | variables.rs:279:13:279:15 | a10 | +| variables.rs:311:15:311:16 | b4 | variables.rs:280:13:280:14 | b4 | +| variables.rs:317:9:317:9 | x | variables.rs:316:10:316:10 | x | +| variables.rs:319:9:319:23 | example_closure | variables.rs:315:9:315:23 | example_closure | +| variables.rs:320:15:320:16 | n1 | variables.rs:318:9:318:10 | n1 | +| variables.rs:325:9:325:9 | x | variables.rs:324:10:324:10 | x | +| variables.rs:327:9:327:26 | immutable_variable | variables.rs:323:9:323:26 | immutable_variable | +| variables.rs:328:15:328:16 | n2 | variables.rs:326:9:326:10 | n2 | +| variables.rs:335:12:335:12 | v | variables.rs:332:9:332:9 | v | +| variables.rs:336:19:336:22 | text | variables.rs:334:9:334:12 | text | +| variables.rs:342:5:342:5 | a | variables.rs:341:13:341:13 | a | +| variables.rs:343:15:343:15 | a | variables.rs:341:13:341:13 | a | +| variables.rs:344:11:344:11 | a | variables.rs:341:13:341:13 | a | +| variables.rs:345:15:345:15 | a | variables.rs:341:13:341:13 | a | +| variables.rs:351:14:351:14 | i | variables.rs:349:13:349:13 | i | +| variables.rs:352:6:352:10 | ref_i | variables.rs:350:9:350:13 | ref_i | +| variables.rs:353:15:353:15 | i | variables.rs:349:13:349:13 | i | +| variables.rs:357:6:357:6 | x | variables.rs:356:17:356:17 | x | +| variables.rs:358:10:358:10 | x | variables.rs:356:17:356:17 | x | +| variables.rs:359:10:359:10 | x | variables.rs:356:17:356:17 | x | +| variables.rs:360:12:360:12 | x | variables.rs:356:17:356:17 | x | +| variables.rs:364:6:364:6 | x | variables.rs:363:22:363:22 | x | +| variables.rs:365:10:365:10 | x | variables.rs:363:22:363:22 | x | +| variables.rs:366:10:366:10 | x | variables.rs:363:22:363:22 | x | +| variables.rs:367:6:367:6 | y | variables.rs:363:39:363:39 | y | +| variables.rs:368:9:368:9 | x | variables.rs:363:22:363:22 | x | +| variables.rs:374:27:374:27 | x | variables.rs:372:13:372:13 | x | +| variables.rs:375:6:375:6 | y | variables.rs:373:9:373:9 | y | +| variables.rs:377:15:377:15 | x | variables.rs:372:13:372:13 | x | +| variables.rs:381:19:381:19 | x | variables.rs:372:13:372:13 | x | +| variables.rs:383:14:383:14 | z | variables.rs:379:13:379:13 | z | +| variables.rs:384:9:384:9 | w | variables.rs:380:9:380:9 | w | +| variables.rs:386:7:386:7 | w | variables.rs:380:9:380:9 | w | +| variables.rs:388:15:388:15 | z | variables.rs:379:13:379:13 | z | +| variables.rs:394:14:394:14 | x | variables.rs:392:13:392:13 | x | +| variables.rs:395:6:395:6 | y | variables.rs:393:9:393:9 | y | +| variables.rs:396:15:396:15 | x | variables.rs:392:13:392:13 | x | +| variables.rs:403:19:403:19 | x | variables.rs:400:9:400:9 | x | +| variables.rs:405:5:405:7 | cap | variables.rs:402:9:402:11 | cap | +| variables.rs:406:15:406:15 | x | variables.rs:400:9:400:9 | x | +| variables.rs:413:19:413:19 | x | variables.rs:410:13:410:13 | x | +| variables.rs:415:5:415:12 | closure1 | variables.rs:412:9:412:16 | closure1 | +| variables.rs:416:15:416:15 | x | variables.rs:410:13:410:13 | x | +| variables.rs:421:9:421:9 | y | variables.rs:418:13:418:13 | y | +| variables.rs:423:5:423:12 | closure2 | variables.rs:420:13:420:20 | closure2 | +| variables.rs:424:15:424:15 | y | variables.rs:418:13:418:13 | y | +| variables.rs:429:9:429:9 | z | variables.rs:426:13:426:13 | z | +| variables.rs:431:5:431:12 | closure3 | variables.rs:428:13:428:20 | closure3 | +| variables.rs:432:15:432:15 | z | variables.rs:426:13:426:13 | z | +| variables.rs:438:9:438:9 | i | variables.rs:436:13:436:13 | i | +| variables.rs:441:5:441:9 | block | variables.rs:437:9:437:13 | block | +| variables.rs:442:15:442:15 | i | variables.rs:436:13:436:13 | i | +| variables.rs:447:15:447:15 | x | variables.rs:446:13:446:13 | x | +| variables.rs:448:15:448:15 | x | variables.rs:446:13:446:13 | x | +| variables.rs:449:8:449:8 | b | variables.rs:445:8:445:8 | b | +| variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x | +| variables.rs:451:19:451:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:452:19:452:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x | +| variables.rs:455:19:455:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:456:19:456:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:458:15:458:15 | x | variables.rs:446:13:446:13 | x | +| variables.rs:463:8:463:9 | b1 | variables.rs:461:13:461:14 | b1 | +| variables.rs:464:19:464:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:466:19:466:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:469:8:469:9 | b2 | variables.rs:461:24:461:25 | b2 | +| variables.rs:470:19:470:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:472:19:472:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:489:15:489:15 | a | variables.rs:488:13:488:13 | a | +| variables.rs:490:5:490:5 | a | variables.rs:488:13:488:13 | a | +| variables.rs:491:15:491:15 | a | variables.rs:488:13:488:13 | a | +| variables.rs:492:5:492:5 | a | variables.rs:488:13:488:13 | a | +| variables.rs:493:15:493:15 | a | variables.rs:488:13:488:13 | a | +| variables.rs:498:20:498:20 | x | variables.rs:497:9:497:9 | x | +| variables.rs:499:15:499:15 | x | variables.rs:497:9:497:9 | x | +| variables.rs:502:20:502:20 | z | variables.rs:501:9:501:9 | z | +| variables.rs:517:3:517:3 | a | variables.rs:516:11:516:11 | a | +| variables.rs:519:13:519:13 | a | variables.rs:516:11:516:11 | a | +variableWriteAccess +| variables.rs:23:5:23:6 | x2 | variables.rs:21:13:21:14 | x2 | +| variables.rs:30:5:30:5 | x | variables.rs:28:13:28:13 | x | +| variables.rs:288:9:288:10 | c2 | variables.rs:281:13:281:14 | c2 | +| variables.rs:289:9:289:10 | b4 | variables.rs:280:13:280:14 | b4 | +| variables.rs:290:9:290:11 | a10 | variables.rs:279:13:279:15 | a10 | +| variables.rs:421:9:421:9 | y | variables.rs:418:13:418:13 | y | +| variables.rs:438:9:438:9 | i | variables.rs:436:13:436:13 | i | +| variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x | +| variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x | +| variables.rs:492:5:492:5 | a | variables.rs:488:13:488:13 | a | +variableReadAccess +| variables.rs:4:20:4:20 | s | variables.rs:3:14:3:14 | s | +| variables.rs:8:20:8:20 | i | variables.rs:7:14:7:14 | i | +| variables.rs:12:16:12:16 | i | variables.rs:11:18:11:18 | i | +| variables.rs:17:15:17:16 | x1 | variables.rs:16:9:16:10 | x1 | +| variables.rs:22:15:22:16 | x2 | variables.rs:21:13:21:14 | x2 | +| variables.rs:24:15:24:16 | x2 | variables.rs:21:13:21:14 | x2 | +| variables.rs:36:15:36:16 | x3 | variables.rs:35:9:35:10 | x3 | +| variables.rs:38:9:38:10 | x3 | variables.rs:35:9:35:10 | x3 | +| variables.rs:39:15:39:16 | x3 | variables.rs:37:9:37:10 | x3 | +| variables.rs:44:15:44:16 | x4 | variables.rs:43:9:43:10 | x4 | +| variables.rs:47:19:47:20 | x4 | variables.rs:46:13:46:14 | x4 | +| variables.rs:49:15:49:16 | x4 | variables.rs:43:9:43:10 | x4 | +| variables.rs:68:15:68:16 | a1 | variables.rs:60:13:60:14 | a1 | +| variables.rs:69:15:69:16 | b1 | variables.rs:61:13:61:14 | b1 | +| variables.rs:70:15:70:15 | x | variables.rs:64:13:64:13 | x | +| variables.rs:71:15:71:15 | y | variables.rs:65:13:65:13 | y | +| variables.rs:79:9:79:10 | p1 | variables.rs:75:9:75:10 | p1 | +| variables.rs:80:15:80:16 | a2 | variables.rs:77:12:77:13 | a2 | +| variables.rs:81:15:81:16 | b2 | variables.rs:78:12:78:13 | b2 | +| variables.rs:88:11:88:12 | s1 | variables.rs:85:9:85:10 | s1 | +| variables.rs:89:19:89:20 | s2 | variables.rs:87:21:87:22 | s2 | +| variables.rs:98:15:98:16 | x5 | variables.rs:94:14:94:15 | x5 | +| variables.rs:105:11:105:12 | s1 | variables.rs:102:9:102:10 | s1 | +| variables.rs:106:19:106:20 | s2 | variables.rs:104:24:104:25 | s2 | +| variables.rs:114:11:114:12 | x6 | variables.rs:111:9:111:10 | x6 | +| variables.rs:119:23:119:24 | y1 | variables.rs:116:14:116:15 | y1 | +| variables.rs:124:15:124:16 | y1 | variables.rs:112:9:112:10 | y1 | +| variables.rs:130:11:130:17 | numbers | variables.rs:128:9:128:15 | numbers | +| variables.rs:136:23:136:27 | first | variables.rs:132:13:132:17 | first | +| variables.rs:137:23:137:27 | third | variables.rs:133:13:133:17 | third | +| variables.rs:138:23:138:27 | fifth | variables.rs:134:13:134:17 | fifth | +| variables.rs:142:11:142:17 | numbers | variables.rs:128:9:128:15 | numbers | +| variables.rs:148:23:148:27 | first | variables.rs:144:13:144:17 | first | +| variables.rs:149:23:149:26 | last | variables.rs:146:13:146:16 | last | +| variables.rs:157:11:157:12 | p2 | variables.rs:155:9:155:10 | p2 | +| variables.rs:160:24:160:25 | x7 | variables.rs:159:16:159:17 | x7 | +| variables.rs:171:11:171:13 | msg | variables.rs:169:9:169:11 | msg | +| variables.rs:174:24:174:34 | id_variable | variables.rs:173:17:173:27 | id_variable | +| variables.rs:179:23:179:24 | id | variables.rs:178:26:178:27 | id | +| variables.rs:190:11:190:16 | either | variables.rs:189:9:189:14 | either | +| variables.rs:192:26:192:27 | a3 | variables.rs:191:9:191:44 | a3 | +| variables.rs:204:11:204:12 | tv | variables.rs:203:9:203:10 | tv | +| variables.rs:206:26:206:27 | a4 | variables.rs:205:9:205:81 | a4 | +| variables.rs:208:11:208:12 | tv | variables.rs:203:9:203:10 | tv | +| variables.rs:210:26:210:27 | a5 | variables.rs:209:9:209:83 | a5 | +| variables.rs:212:11:212:12 | tv | variables.rs:203:9:203:10 | tv | +| variables.rs:214:26:214:27 | a6 | variables.rs:213:9:213:83 | a6 | +| variables.rs:220:11:220:16 | either | variables.rs:219:9:219:14 | either | +| variables.rs:222:16:222:17 | a7 | variables.rs:221:9:221:44 | a7 | +| variables.rs:223:26:223:27 | a7 | variables.rs:221:9:221:44 | a7 | +| variables.rs:231:11:231:16 | either | variables.rs:229:9:229:14 | either | +| variables.rs:235:23:235:25 | a11 | variables.rs:233:14:233:51 | a11 | +| variables.rs:237:15:237:15 | e | variables.rs:232:13:232:13 | e | +| variables.rs:238:28:238:30 | a12 | variables.rs:236:33:236:35 | a12 | +| variables.rs:254:11:254:12 | fv | variables.rs:253:9:253:10 | fv | +| variables.rs:256:26:256:28 | a13 | variables.rs:255:9:255:109 | a13 | +| variables.rs:266:15:266:16 | a8 | variables.rs:261:5:261:6 | a8 | +| variables.rs:267:15:267:16 | b3 | variables.rs:263:9:263:10 | b3 | +| variables.rs:268:15:268:16 | c1 | variables.rs:264:9:264:10 | c1 | +| variables.rs:274:15:274:16 | a9 | variables.rs:272:6:272:41 | a9 | +| variables.rs:283:15:283:17 | a10 | variables.rs:279:13:279:15 | a10 | +| variables.rs:284:15:284:16 | b4 | variables.rs:280:13:280:14 | b4 | +| variables.rs:285:15:285:16 | c2 | variables.rs:281:13:281:14 | c2 | +| variables.rs:292:9:292:11 | a10 | variables.rs:279:13:279:15 | a10 | +| variables.rs:293:9:293:10 | b4 | variables.rs:280:13:280:14 | b4 | +| variables.rs:294:9:294:10 | c2 | variables.rs:281:13:281:14 | c2 | +| variables.rs:296:15:296:17 | a10 | variables.rs:279:13:279:15 | a10 | +| variables.rs:297:15:297:16 | b4 | variables.rs:280:13:280:14 | b4 | +| variables.rs:298:15:298:16 | c2 | variables.rs:281:13:281:14 | c2 | +| variables.rs:305:23:305:25 | a10 | variables.rs:302:13:302:15 | a10 | +| variables.rs:306:23:306:24 | b4 | variables.rs:303:13:303:14 | b4 | +| variables.rs:310:15:310:17 | a10 | variables.rs:279:13:279:15 | a10 | +| variables.rs:311:15:311:16 | b4 | variables.rs:280:13:280:14 | b4 | +| variables.rs:317:9:317:9 | x | variables.rs:316:10:316:10 | x | +| variables.rs:319:9:319:23 | example_closure | variables.rs:315:9:315:23 | example_closure | +| variables.rs:320:15:320:16 | n1 | variables.rs:318:9:318:10 | n1 | +| variables.rs:325:9:325:9 | x | variables.rs:324:10:324:10 | x | +| variables.rs:327:9:327:26 | immutable_variable | variables.rs:323:9:323:26 | immutable_variable | +| variables.rs:328:15:328:16 | n2 | variables.rs:326:9:326:10 | n2 | +| variables.rs:335:12:335:12 | v | variables.rs:332:9:332:9 | v | +| variables.rs:336:19:336:22 | text | variables.rs:334:9:334:12 | text | +| variables.rs:343:15:343:15 | a | variables.rs:341:13:341:13 | a | +| variables.rs:345:15:345:15 | a | variables.rs:341:13:341:13 | a | +| variables.rs:352:6:352:10 | ref_i | variables.rs:350:9:350:13 | ref_i | +| variables.rs:353:15:353:15 | i | variables.rs:349:13:349:13 | i | +| variables.rs:357:6:357:6 | x | variables.rs:356:17:356:17 | x | +| variables.rs:358:10:358:10 | x | variables.rs:356:17:356:17 | x | +| variables.rs:359:10:359:10 | x | variables.rs:356:17:356:17 | x | +| variables.rs:360:12:360:12 | x | variables.rs:356:17:356:17 | x | +| variables.rs:364:6:364:6 | x | variables.rs:363:22:363:22 | x | +| variables.rs:365:10:365:10 | x | variables.rs:363:22:363:22 | x | +| variables.rs:366:10:366:10 | x | variables.rs:363:22:363:22 | x | +| variables.rs:367:6:367:6 | y | variables.rs:363:39:363:39 | y | +| variables.rs:368:9:368:9 | x | variables.rs:363:22:363:22 | x | +| variables.rs:375:6:375:6 | y | variables.rs:373:9:373:9 | y | +| variables.rs:377:15:377:15 | x | variables.rs:372:13:372:13 | x | +| variables.rs:384:9:384:9 | w | variables.rs:380:9:380:9 | w | +| variables.rs:386:7:386:7 | w | variables.rs:380:9:380:9 | w | +| variables.rs:388:15:388:15 | z | variables.rs:379:13:379:13 | z | +| variables.rs:395:6:395:6 | y | variables.rs:393:9:393:9 | y | +| variables.rs:396:15:396:15 | x | variables.rs:392:13:392:13 | x | +| variables.rs:403:19:403:19 | x | variables.rs:400:9:400:9 | x | +| variables.rs:405:5:405:7 | cap | variables.rs:402:9:402:11 | cap | +| variables.rs:406:15:406:15 | x | variables.rs:400:9:400:9 | x | +| variables.rs:413:19:413:19 | x | variables.rs:410:13:410:13 | x | +| variables.rs:415:5:415:12 | closure1 | variables.rs:412:9:412:16 | closure1 | +| variables.rs:416:15:416:15 | x | variables.rs:410:13:410:13 | x | +| variables.rs:423:5:423:12 | closure2 | variables.rs:420:13:420:20 | closure2 | +| variables.rs:424:15:424:15 | y | variables.rs:418:13:418:13 | y | +| variables.rs:429:9:429:9 | z | variables.rs:426:13:426:13 | z | +| variables.rs:431:5:431:12 | closure3 | variables.rs:428:13:428:20 | closure3 | +| variables.rs:432:15:432:15 | z | variables.rs:426:13:426:13 | z | +| variables.rs:441:5:441:9 | block | variables.rs:437:9:437:13 | block | +| variables.rs:442:15:442:15 | i | variables.rs:436:13:436:13 | i | +| variables.rs:447:15:447:15 | x | variables.rs:446:13:446:13 | x | +| variables.rs:448:15:448:15 | x | variables.rs:446:13:446:13 | x | +| variables.rs:449:8:449:8 | b | variables.rs:445:8:445:8 | b | +| variables.rs:451:19:451:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:452:19:452:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:455:19:455:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:456:19:456:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:458:15:458:15 | x | variables.rs:446:13:446:13 | x | +| variables.rs:463:8:463:9 | b1 | variables.rs:461:13:461:14 | b1 | +| variables.rs:464:19:464:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:466:19:466:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:469:8:469:9 | b2 | variables.rs:461:24:461:25 | b2 | +| variables.rs:470:19:470:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:472:19:472:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:489:15:489:15 | a | variables.rs:488:13:488:13 | a | +| variables.rs:490:5:490:5 | a | variables.rs:488:13:488:13 | a | +| variables.rs:491:15:491:15 | a | variables.rs:488:13:488:13 | a | +| variables.rs:493:15:493:15 | a | variables.rs:488:13:488:13 | a | +| variables.rs:499:15:499:15 | x | variables.rs:497:9:497:9 | x | +| variables.rs:517:3:517:3 | a | variables.rs:516:11:516:11 | a | +| variables.rs:519:13:519:13 | a | variables.rs:516:11:516:11 | a | +variableInitializer +| variables.rs:16:9:16:10 | x1 | variables.rs:16:14:16:16 | "a" | +| variables.rs:21:13:21:14 | x2 | variables.rs:21:18:21:18 | 4 | +| variables.rs:28:13:28:13 | x | variables.rs:28:17:28:17 | 1 | +| variables.rs:35:9:35:10 | x3 | variables.rs:35:14:35:14 | 1 | +| variables.rs:37:9:37:10 | x3 | variables.rs:38:9:38:14 | ... + ... | +| variables.rs:43:9:43:10 | x4 | variables.rs:43:14:43:16 | "a" | +| variables.rs:46:13:46:14 | x4 | variables.rs:46:18:46:20 | "b" | +| variables.rs:75:9:75:10 | p1 | variables.rs:75:14:75:37 | Point {...} | +| variables.rs:85:9:85:10 | s1 | variables.rs:85:14:85:41 | Some(...) | +| variables.rs:102:9:102:10 | s1 | variables.rs:102:14:102:41 | Some(...) | +| variables.rs:111:9:111:10 | x6 | variables.rs:111:14:111:20 | Some(...) | +| variables.rs:112:9:112:10 | y1 | variables.rs:112:14:112:15 | 10 | +| variables.rs:128:9:128:15 | numbers | variables.rs:128:19:128:35 | TupleExpr | +| variables.rs:155:9:155:10 | p2 | variables.rs:155:14:155:37 | Point {...} | +| variables.rs:169:9:169:11 | msg | variables.rs:169:15:169:38 | Message::Hello {...} | +| variables.rs:189:9:189:14 | either | variables.rs:189:18:189:33 | Either::Left(...) | +| variables.rs:203:9:203:10 | tv | variables.rs:203:14:203:36 | ThreeValued::Second(...) | +| variables.rs:219:9:219:14 | either | variables.rs:219:18:219:33 | Either::Left(...) | +| variables.rs:229:9:229:14 | either | variables.rs:229:18:229:33 | Either::Left(...) | +| variables.rs:253:9:253:10 | fv | variables.rs:253:14:253:35 | FourValued::Second(...) | +| variables.rs:315:9:315:23 | example_closure | variables.rs:316:9:317:9 | \|...\| x | +| variables.rs:318:9:318:10 | n1 | variables.rs:319:9:319:26 | example_closure(...) | +| variables.rs:323:9:323:26 | immutable_variable | variables.rs:324:9:325:9 | \|...\| x | +| variables.rs:326:9:326:10 | n2 | variables.rs:327:9:327:29 | immutable_variable(...) | +| variables.rs:332:9:332:9 | v | variables.rs:332:13:332:41 | &... | +| variables.rs:341:13:341:13 | a | variables.rs:341:17:341:17 | 0 | +| variables.rs:349:13:349:13 | i | variables.rs:349:17:349:17 | 1 | +| variables.rs:350:9:350:13 | ref_i | variables.rs:351:9:351:14 | &mut i | +| variables.rs:372:13:372:13 | x | variables.rs:372:17:372:17 | 2 | +| variables.rs:373:9:373:9 | y | variables.rs:374:9:374:28 | mutate_param(...) | +| variables.rs:379:13:379:13 | z | variables.rs:379:17:379:17 | 4 | +| variables.rs:380:9:380:9 | w | variables.rs:381:9:381:19 | &mut ... | +| variables.rs:392:13:392:13 | x | variables.rs:392:17:392:17 | 1 | +| variables.rs:393:9:393:9 | y | variables.rs:394:9:394:14 | &mut x | +| variables.rs:400:9:400:9 | x | variables.rs:400:13:400:15 | 100 | +| variables.rs:402:9:402:11 | cap | variables.rs:402:15:404:5 | \|...\| ... | +| variables.rs:410:13:410:13 | x | variables.rs:410:17:410:17 | 1 | +| variables.rs:412:9:412:16 | closure1 | variables.rs:412:20:414:5 | \|...\| ... | +| variables.rs:418:13:418:13 | y | variables.rs:418:17:418:17 | 2 | +| variables.rs:420:13:420:20 | closure2 | variables.rs:420:24:422:5 | \|...\| ... | +| variables.rs:426:13:426:13 | z | variables.rs:426:17:426:17 | 2 | +| variables.rs:428:13:428:20 | closure3 | variables.rs:428:24:430:5 | \|...\| ... | +| variables.rs:436:13:436:13 | i | variables.rs:436:22:436:22 | 0 | +| variables.rs:437:9:437:13 | block | variables.rs:437:17:439:5 | { ... } | +| variables.rs:446:13:446:13 | x | variables.rs:446:17:446:17 | 1 | +| variables.rs:462:9:462:9 | x | variables.rs:462:13:462:13 | 1 | +| variables.rs:488:13:488:13 | a | variables.rs:488:17:488:35 | MyStruct {...} | +| variables.rs:497:9:497:9 | x | variables.rs:497:13:497:14 | 16 | +| variables.rs:501:9:501:9 | z | variables.rs:501:13:501:14 | 17 | +| variables.rs:516:11:516:11 | a | variables.rs:516:15:516:33 | MyStruct {...} | +capturedVariable +| variables.rs:400:9:400:9 | x | +| variables.rs:410:13:410:13 | x | +| variables.rs:418:13:418:13 | y | +| variables.rs:426:13:426:13 | z | +| variables.rs:436:13:436:13 | i | +capturedAccess +| variables.rs:403:19:403:19 | x | +| variables.rs:413:19:413:19 | x | +| variables.rs:421:9:421:9 | y | +| variables.rs:429:9:429:9 | z | +| variables.rs:438:9:438:9 | i | diff --git a/rust/ql/test/query-tests/diagnostics/CONSISTENCY/ExtractionConsistency.expected b/rust/ql/test/query-tests/diagnostics/CONSISTENCY/ExtractionConsistency.expected index bdfa4a9792d..5b4796faa8c 100644 --- a/rust/ql/test/query-tests/diagnostics/CONSISTENCY/ExtractionConsistency.expected +++ b/rust/ql/test/query-tests/diagnostics/CONSISTENCY/ExtractionConsistency.expected @@ -4,5 +4,4 @@ extractionWarning | does_not_compile.rs:2:13:2:12 | expected SEMICOLON | | does_not_compile.rs:2:21:2:20 | expected SEMICOLON | | does_not_compile.rs:2:26:2:25 | expected SEMICOLON | -| does_not_compile.rs:2:32:2:31 | expected field name or number | | error.rs:2:5:2:17 | An error! | diff --git a/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected index f4a07cc45c2..0a61a151c20 100644 --- a/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected +++ b/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected @@ -3,17 +3,3 @@ uniqueEnclosingCallable | main.rs:198:28:198:28 | x | Node should have one enclosing callable but has 0. | | main.rs:202:28:202:28 | x | Node should have one enclosing callable but has 0. | | main.rs:206:28:206:28 | x | Node should have one enclosing callable but has 0. | -uniqueNodeToString -| main.rs:205:32:205:32 | (no string representation) | Node should have one toString but has 0. | -| main.rs:219:9:219:13 | (no string representation) | Node should have one toString but has 0. | -| main.rs:224:9:224:13 | (no string representation) | Node should have one toString but has 0. | -| main.rs:424:21:424:23 | (no string representation) | Node should have one toString but has 0. | -| main.rs:424:26:424:28 | (no string representation) | Node should have one toString but has 0. | -| main.rs:427:21:427:23 | (no string representation) | Node should have one toString but has 0. | -| main.rs:427:26:427:28 | (no string representation) | Node should have one toString but has 0. | -| main.rs:430:21:430:23 | (no string representation) | Node should have one toString but has 0. | -| main.rs:430:26:430:28 | (no string representation) | Node should have one toString but has 0. | -| main.rs:434:21:434:23 | (no string representation) | Node should have one toString but has 0. | -| main.rs:434:26:434:28 | (no string representation) | Node should have one toString but has 0. | -| unreachable.rs:10:34:10:34 | (no string representation) | Node should have one toString but has 0. | -| unreachable.rs:230:13:230:17 | (no string representation) | Node should have one toString but has 0. | From d609c1b7e65da0c4e3d45334a7766be83d4555b8 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 20 Nov 2024 17:00:13 +0100 Subject: [PATCH 134/470] Rust: fix `OrPat.toString` --- .../rust/elements/internal/OrPatImpl.qll | 2 +- .../generated/OrPat/OrPat.expected | 2 +- .../generated/OrPat/OrPat_getPat.expected | 4 +- .../test/library-tests/variables/Cfg.expected | 80 +++++++++---------- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/OrPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/OrPatImpl.qll index 20ee0f68852..07cc59f0dde 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/OrPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/OrPatImpl.qll @@ -22,7 +22,7 @@ module Impl { */ class OrPat extends Generated::OrPat { override string toString() { - result = concat(int i | | this.getPat(i).toAbbreviatedString() order by i, " | ") + result = concat(int i | | this.getPat(i).toAbbreviatedString(), " | " order by i) } /** Gets the last pattern in this or pattern. */ diff --git a/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected b/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected index f4268aea84f..26426d2c5aa 100644 --- a/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected +++ b/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected @@ -1 +1 @@ -| gen_or_pat.rs:6:9:6:38 | ...Option::None | getNumberOfPats: | 2 | +| gen_or_pat.rs:6:9:6:38 | ... \| Option::None | getNumberOfPats: | 2 | diff --git a/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected b/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected index e04c09875b5..80326c82f0d 100644 --- a/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected @@ -1,2 +1,2 @@ -| gen_or_pat.rs:6:9:6:38 | ...Option::None | 0 | gen_or_pat.rs:6:9:6:23 | TupleStructPat | -| gen_or_pat.rs:6:9:6:38 | ...Option::None | 1 | gen_or_pat.rs:6:27:6:38 | Option::None | +| gen_or_pat.rs:6:9:6:38 | ... \| Option::None | 0 | gen_or_pat.rs:6:9:6:23 | TupleStructPat | +| gen_or_pat.rs:6:9:6:38 | ... \| Option::None | 1 | gen_or_pat.rs:6:27:6:38 | Option::None | diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected index 3a7e72f0349..93356b89408 100644 --- a/rust/ql/test/library-tests/variables/Cfg.expected +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -407,10 +407,10 @@ edges | variables.rs:190:11:190:16 | either | variables.rs:191:9:191:24 | TupleStructPat | | | variables.rs:191:9:191:24 | TupleStructPat | variables.rs:191:22:191:23 | a3 | match | | variables.rs:191:9:191:24 | TupleStructPat | variables.rs:191:28:191:44 | TupleStructPat | no-match | -| variables.rs:191:9:191:44 | [match(true)] ...... | variables.rs:192:16:192:24 | print_i64 | match | -| variables.rs:191:22:191:23 | a3 | variables.rs:191:9:191:44 | [match(true)] ...... | match | +| variables.rs:191:9:191:44 | [match(true)] ... \| ... | variables.rs:192:16:192:24 | print_i64 | match | +| variables.rs:191:22:191:23 | a3 | variables.rs:191:9:191:44 | [match(true)] ... \| ... | match | | variables.rs:191:28:191:44 | TupleStructPat | variables.rs:191:42:191:43 | a3 | match | -| variables.rs:191:42:191:43 | a3 | variables.rs:191:9:191:44 | [match(true)] ...... | match | +| variables.rs:191:42:191:43 | a3 | variables.rs:191:9:191:44 | [match(true)] ... \| ... | match | | variables.rs:192:16:192:24 | print_i64 | variables.rs:192:26:192:27 | a3 | | | variables.rs:192:16:192:28 | print_i64(...) | variables.rs:190:5:193:5 | match either { ... } | | | variables.rs:192:26:192:27 | a3 | variables.rs:192:16:192:28 | print_i64(...) | | @@ -427,30 +427,30 @@ edges | variables.rs:204:11:204:12 | tv | variables.rs:205:9:205:30 | TupleStructPat | | | variables.rs:205:9:205:30 | TupleStructPat | variables.rs:205:28:205:29 | a4 | match | | variables.rs:205:9:205:30 | TupleStructPat | variables.rs:205:34:205:56 | TupleStructPat | no-match | -| variables.rs:205:9:205:81 | [match(true)] ......... | variables.rs:206:16:206:24 | print_i64 | match | -| variables.rs:205:28:205:29 | a4 | variables.rs:205:9:205:81 | [match(true)] ......... | match | +| variables.rs:205:9:205:81 | [match(true)] ... \| ... \| ... | variables.rs:206:16:206:24 | print_i64 | match | +| variables.rs:205:28:205:29 | a4 | variables.rs:205:9:205:81 | [match(true)] ... \| ... \| ... | match | | variables.rs:205:34:205:56 | TupleStructPat | variables.rs:205:54:205:55 | a4 | match | | variables.rs:205:34:205:56 | TupleStructPat | variables.rs:205:60:205:81 | TupleStructPat | no-match | -| variables.rs:205:54:205:55 | a4 | variables.rs:205:9:205:81 | [match(true)] ......... | match | +| variables.rs:205:54:205:55 | a4 | variables.rs:205:9:205:81 | [match(true)] ... \| ... \| ... | match | | variables.rs:205:60:205:81 | TupleStructPat | variables.rs:205:79:205:80 | a4 | match | -| variables.rs:205:79:205:80 | a4 | variables.rs:205:9:205:81 | [match(true)] ......... | match | +| variables.rs:205:79:205:80 | a4 | variables.rs:205:9:205:81 | [match(true)] ... \| ... \| ... | match | | variables.rs:206:16:206:24 | print_i64 | variables.rs:206:26:206:27 | a4 | | | variables.rs:206:16:206:28 | print_i64(...) | variables.rs:204:5:207:5 | match tv { ... } | | | variables.rs:206:26:206:27 | a4 | variables.rs:206:16:206:28 | print_i64(...) | | | variables.rs:208:5:211:5 | ExprStmt | variables.rs:208:11:208:12 | tv | | | variables.rs:208:5:211:5 | match tv { ... } | variables.rs:212:11:212:12 | tv | | | variables.rs:208:11:208:12 | tv | variables.rs:209:10:209:31 | TupleStructPat | | -| variables.rs:209:9:209:83 | [match(true)] ...... | variables.rs:210:16:210:24 | print_i64 | match | +| variables.rs:209:9:209:83 | [match(true)] ... \| ... | variables.rs:210:16:210:24 | print_i64 | match | | variables.rs:209:10:209:31 | TupleStructPat | variables.rs:209:29:209:30 | a5 | match | | variables.rs:209:10:209:31 | TupleStructPat | variables.rs:209:35:209:57 | TupleStructPat | no-match | -| variables.rs:209:10:209:57 | [match(false)] ...... | variables.rs:209:62:209:83 | TupleStructPat | no-match | -| variables.rs:209:10:209:57 | [match(true)] ...... | variables.rs:209:9:209:83 | [match(true)] ...... | match | -| variables.rs:209:29:209:30 | a5 | variables.rs:209:10:209:57 | [match(true)] ...... | match | -| variables.rs:209:35:209:57 | TupleStructPat | variables.rs:209:10:209:57 | [match(false)] ...... | no-match | +| variables.rs:209:10:209:57 | [match(false)] ... \| ... | variables.rs:209:62:209:83 | TupleStructPat | no-match | +| variables.rs:209:10:209:57 | [match(true)] ... \| ... | variables.rs:209:9:209:83 | [match(true)] ... \| ... | match | +| variables.rs:209:29:209:30 | a5 | variables.rs:209:10:209:57 | [match(true)] ... \| ... | match | +| variables.rs:209:35:209:57 | TupleStructPat | variables.rs:209:10:209:57 | [match(false)] ... \| ... | no-match | | variables.rs:209:35:209:57 | TupleStructPat | variables.rs:209:55:209:56 | a5 | match | -| variables.rs:209:55:209:56 | a5 | variables.rs:209:10:209:57 | [match(true)] ...... | match | +| variables.rs:209:55:209:56 | a5 | variables.rs:209:10:209:57 | [match(true)] ... \| ... | match | | variables.rs:209:62:209:83 | TupleStructPat | variables.rs:209:81:209:82 | a5 | match | -| variables.rs:209:81:209:82 | a5 | variables.rs:209:9:209:83 | [match(true)] ...... | match | +| variables.rs:209:81:209:82 | a5 | variables.rs:209:9:209:83 | [match(true)] ... \| ... | match | | variables.rs:210:16:210:24 | print_i64 | variables.rs:210:26:210:27 | a5 | | | variables.rs:210:16:210:28 | print_i64(...) | variables.rs:208:5:211:5 | match tv { ... } | | | variables.rs:210:26:210:27 | a5 | variables.rs:210:16:210:28 | print_i64(...) | | @@ -458,14 +458,14 @@ edges | variables.rs:212:11:212:12 | tv | variables.rs:213:9:213:30 | TupleStructPat | | | variables.rs:213:9:213:30 | TupleStructPat | variables.rs:213:28:213:29 | a6 | match | | variables.rs:213:9:213:30 | TupleStructPat | variables.rs:213:35:213:57 | TupleStructPat | no-match | -| variables.rs:213:9:213:83 | [match(true)] ...... | variables.rs:214:16:214:24 | print_i64 | match | -| variables.rs:213:28:213:29 | a6 | variables.rs:213:9:213:83 | [match(true)] ...... | match | +| variables.rs:213:9:213:83 | [match(true)] ... \| ... | variables.rs:214:16:214:24 | print_i64 | match | +| variables.rs:213:28:213:29 | a6 | variables.rs:213:9:213:83 | [match(true)] ... \| ... | match | | variables.rs:213:35:213:57 | TupleStructPat | variables.rs:213:55:213:56 | a6 | match | | variables.rs:213:35:213:57 | TupleStructPat | variables.rs:213:61:213:82 | TupleStructPat | no-match | -| variables.rs:213:35:213:82 | [match(true)] ...... | variables.rs:213:9:213:83 | [match(true)] ...... | match | -| variables.rs:213:55:213:56 | a6 | variables.rs:213:35:213:82 | [match(true)] ...... | match | +| variables.rs:213:35:213:82 | [match(true)] ... \| ... | variables.rs:213:9:213:83 | [match(true)] ... \| ... | match | +| variables.rs:213:55:213:56 | a6 | variables.rs:213:35:213:82 | [match(true)] ... \| ... | match | | variables.rs:213:61:213:82 | TupleStructPat | variables.rs:213:80:213:81 | a6 | match | -| variables.rs:213:80:213:81 | a6 | variables.rs:213:35:213:82 | [match(true)] ...... | match | +| variables.rs:213:80:213:81 | a6 | variables.rs:213:35:213:82 | [match(true)] ... \| ... | match | | variables.rs:214:16:214:24 | print_i64 | variables.rs:214:26:214:27 | a6 | | | variables.rs:214:16:214:28 | print_i64(...) | variables.rs:212:5:215:5 | match tv { ... } | | | variables.rs:214:26:214:27 | a6 | variables.rs:214:16:214:28 | print_i64(...) | | @@ -481,12 +481,12 @@ edges | variables.rs:220:11:220:16 | either | variables.rs:221:9:221:24 | TupleStructPat | | | variables.rs:221:9:221:24 | TupleStructPat | variables.rs:221:22:221:23 | a7 | match | | variables.rs:221:9:221:24 | TupleStructPat | variables.rs:221:28:221:44 | TupleStructPat | no-match | -| variables.rs:221:9:221:44 | [match(false)] ...... | variables.rs:224:9:224:9 | _ | no-match | -| variables.rs:221:9:221:44 | [match(true)] ...... | variables.rs:222:16:222:17 | a7 | match | -| variables.rs:221:22:221:23 | a7 | variables.rs:221:9:221:44 | [match(true)] ...... | match | -| variables.rs:221:28:221:44 | TupleStructPat | variables.rs:221:9:221:44 | [match(false)] ...... | no-match | +| variables.rs:221:9:221:44 | [match(false)] ... \| ... | variables.rs:224:9:224:9 | _ | no-match | +| variables.rs:221:9:221:44 | [match(true)] ... \| ... | variables.rs:222:16:222:17 | a7 | match | +| variables.rs:221:22:221:23 | a7 | variables.rs:221:9:221:44 | [match(true)] ... \| ... | match | +| variables.rs:221:28:221:44 | TupleStructPat | variables.rs:221:9:221:44 | [match(false)] ... \| ... | no-match | | variables.rs:221:28:221:44 | TupleStructPat | variables.rs:221:42:221:43 | a7 | match | -| variables.rs:221:42:221:43 | a7 | variables.rs:221:9:221:44 | [match(true)] ...... | match | +| variables.rs:221:42:221:43 | a7 | variables.rs:221:9:221:44 | [match(true)] ... \| ... | match | | variables.rs:222:16:222:17 | a7 | variables.rs:222:21:222:21 | 0 | | | variables.rs:222:16:222:21 | ... > ... | variables.rs:223:16:223:24 | print_i64 | true | | variables.rs:222:16:222:21 | ... > ... | variables.rs:224:9:224:9 | _ | false | @@ -509,12 +509,12 @@ edges | variables.rs:232:9:233:52 | [match(true)] e | variables.rs:235:13:235:27 | ExprStmt | match | | variables.rs:233:14:233:30 | TupleStructPat | variables.rs:233:27:233:29 | a11 | match | | variables.rs:233:14:233:30 | TupleStructPat | variables.rs:233:34:233:51 | TupleStructPat | no-match | -| variables.rs:233:14:233:51 | [match(false)] ...... | variables.rs:241:9:241:9 | _ | no-match | -| variables.rs:233:14:233:51 | [match(true)] ...... | variables.rs:232:9:233:52 | [match(true)] e | match | -| variables.rs:233:27:233:29 | a11 | variables.rs:233:14:233:51 | [match(true)] ...... | match | -| variables.rs:233:34:233:51 | TupleStructPat | variables.rs:233:14:233:51 | [match(false)] ...... | no-match | +| variables.rs:233:14:233:51 | [match(false)] ... \| ... | variables.rs:241:9:241:9 | _ | no-match | +| variables.rs:233:14:233:51 | [match(true)] ... \| ... | variables.rs:232:9:233:52 | [match(true)] e | match | +| variables.rs:233:27:233:29 | a11 | variables.rs:233:14:233:51 | [match(true)] ... \| ... | match | +| variables.rs:233:34:233:51 | TupleStructPat | variables.rs:233:14:233:51 | [match(false)] ... \| ... | no-match | | variables.rs:233:34:233:51 | TupleStructPat | variables.rs:233:48:233:50 | a11 | match | -| variables.rs:233:48:233:50 | a11 | variables.rs:233:14:233:51 | [match(true)] ...... | match | +| variables.rs:233:48:233:50 | a11 | variables.rs:233:14:233:51 | [match(true)] ... \| ... | match | | variables.rs:234:12:240:9 | { ... } | variables.rs:231:5:242:5 | match either { ... } | | | variables.rs:235:13:235:21 | print_i64 | variables.rs:235:23:235:25 | a11 | | | variables.rs:235:13:235:26 | print_i64(...) | variables.rs:236:16:237:15 | let ... = e | | @@ -546,18 +546,18 @@ edges | variables.rs:254:11:254:12 | fv | variables.rs:255:9:255:30 | TupleStructPat | | | variables.rs:255:9:255:30 | TupleStructPat | variables.rs:255:27:255:29 | a13 | match | | variables.rs:255:9:255:30 | TupleStructPat | variables.rs:255:35:255:57 | TupleStructPat | no-match | -| variables.rs:255:9:255:109 | [match(true)] ......... | variables.rs:256:16:256:24 | print_i64 | match | -| variables.rs:255:27:255:29 | a13 | variables.rs:255:9:255:109 | [match(true)] ......... | match | +| variables.rs:255:9:255:109 | [match(true)] ... \| ... \| ... | variables.rs:256:16:256:24 | print_i64 | match | +| variables.rs:255:27:255:29 | a13 | variables.rs:255:9:255:109 | [match(true)] ... \| ... \| ... | match | | variables.rs:255:35:255:57 | TupleStructPat | variables.rs:255:54:255:56 | a13 | match | | variables.rs:255:35:255:57 | TupleStructPat | variables.rs:255:61:255:82 | TupleStructPat | no-match | -| variables.rs:255:35:255:82 | [match(false)] ...... | variables.rs:255:87:255:109 | TupleStructPat | no-match | -| variables.rs:255:35:255:82 | [match(true)] ...... | variables.rs:255:9:255:109 | [match(true)] ......... | match | -| variables.rs:255:54:255:56 | a13 | variables.rs:255:35:255:82 | [match(true)] ...... | match | -| variables.rs:255:61:255:82 | TupleStructPat | variables.rs:255:35:255:82 | [match(false)] ...... | no-match | +| variables.rs:255:35:255:82 | [match(false)] ... \| ... | variables.rs:255:87:255:109 | TupleStructPat | no-match | +| variables.rs:255:35:255:82 | [match(true)] ... \| ... | variables.rs:255:9:255:109 | [match(true)] ... \| ... \| ... | match | +| variables.rs:255:54:255:56 | a13 | variables.rs:255:35:255:82 | [match(true)] ... \| ... | match | +| variables.rs:255:61:255:82 | TupleStructPat | variables.rs:255:35:255:82 | [match(false)] ... \| ... | no-match | | variables.rs:255:61:255:82 | TupleStructPat | variables.rs:255:79:255:81 | a13 | match | -| variables.rs:255:79:255:81 | a13 | variables.rs:255:35:255:82 | [match(true)] ...... | match | +| variables.rs:255:79:255:81 | a13 | variables.rs:255:35:255:82 | [match(true)] ... \| ... | match | | variables.rs:255:87:255:109 | TupleStructPat | variables.rs:255:106:255:108 | a13 | match | -| variables.rs:255:106:255:108 | a13 | variables.rs:255:9:255:109 | [match(true)] ......... | match | +| variables.rs:255:106:255:108 | a13 | variables.rs:255:9:255:109 | [match(true)] ... \| ... \| ... | match | | variables.rs:256:16:256:24 | print_i64 | variables.rs:256:26:256:28 | a13 | | | variables.rs:256:16:256:29 | print_i64(...) | variables.rs:254:5:257:5 | match fv { ... } | | | variables.rs:256:26:256:28 | a13 | variables.rs:256:16:256:29 | print_i64(...) | | @@ -587,10 +587,10 @@ edges | variables.rs:272:5:272:50 | ...: Either | variables.rs:274:5:274:18 | ExprStmt | | | variables.rs:272:6:272:21 | TupleStructPat | variables.rs:272:19:272:20 | a9 | match | | variables.rs:272:6:272:21 | TupleStructPat | variables.rs:272:25:272:41 | TupleStructPat | no-match | -| variables.rs:272:6:272:41 | [match(true)] ...... | variables.rs:272:5:272:50 | ...: Either | match | -| variables.rs:272:19:272:20 | a9 | variables.rs:272:6:272:41 | [match(true)] ...... | match | +| variables.rs:272:6:272:41 | [match(true)] ... \| ... | variables.rs:272:5:272:50 | ...: Either | match | +| variables.rs:272:19:272:20 | a9 | variables.rs:272:6:272:41 | [match(true)] ... \| ... | match | | variables.rs:272:25:272:41 | TupleStructPat | variables.rs:272:39:272:40 | a9 | match | -| variables.rs:272:39:272:40 | a9 | variables.rs:272:6:272:41 | [match(true)] ...... | match | +| variables.rs:272:39:272:40 | a9 | variables.rs:272:6:272:41 | [match(true)] ... \| ... | match | | variables.rs:273:9:275:1 | { ... } | variables.rs:271:1:275:1 | exit fn param_pattern2 (normal) | | | variables.rs:274:5:274:13 | print_i64 | variables.rs:274:15:274:16 | a9 | | | variables.rs:274:5:274:17 | print_i64(...) | variables.rs:273:9:275:1 | { ... } | | From 09f73d8d6f359f5681046bc5805e667d23228bdc Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 20 Nov 2024 17:36:43 +0100 Subject: [PATCH 135/470] JS: Add: test cases for toWellFormed --- .../TaintTracking/string-immutable-operations.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 javascript/ql/test/library-tests/TaintTracking/string-immutable-operations.js diff --git a/javascript/ql/test/library-tests/TaintTracking/string-immutable-operations.js b/javascript/ql/test/library-tests/TaintTracking/string-immutable-operations.js new file mode 100644 index 00000000000..60f6c44088c --- /dev/null +++ b/javascript/ql/test/library-tests/TaintTracking/string-immutable-operations.js @@ -0,0 +1,12 @@ +function test() { + let x = source(); + sink(x.toWellFormed()); // NOT OK -- Currently not tainted, but should be + + const wellFormedX = x.toWellFormed(); + sink(wellFormedX); // NOT OK -- Currently not tainted, but should be + + const concatWellFormedX = "/" + wellFormedX + "!"; + sink(concatWellFormedX); // NOT OK -- Currently not tainted, but should be + + sink(source().toWellFormed()); // NOT OK -- Currently not tainted, but should be +} From afc2d3e6d25f24d6111072b555357151b3684222 Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 20 Nov 2024 17:42:25 +0100 Subject: [PATCH 136/470] JS: Add: String.protytpe.toWellFormed to StringManipulationTaintStep --- .../ql/lib/semmle/javascript/dataflow/TaintTracking.qll | 2 +- .../TaintTracking/BasicTaintTracking.expected | 4 ++++ .../TaintTracking/string-immutable-operations.js | 8 ++++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index a19691e9448..6b6fc9c4b07 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -612,7 +612,7 @@ module TaintTracking { "italics", "link", "padEnd", "padStart", "repeat", "replace", "replaceAll", "slice", "small", "split", "strike", "sub", "substr", "substring", "sup", "toLocaleLowerCase", "toLocaleUpperCase", "toLowerCase", "toUpperCase", "trim", - "trimLeft", "trimRight" + "trimLeft", "trimRight", "toWellFormed" ] or // sorted, interesting, properties of Object.prototype diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index f81405a32a2..3d4fd0b67f8 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -209,6 +209,10 @@ typeInferenceMismatch | static-capture-groups.js:2:17:2:24 | source() | static-capture-groups.js:27:14:27:22 | RegExp.$1 | | static-capture-groups.js:32:17:32:24 | source() | static-capture-groups.js:38:10:38:18 | RegExp.$1 | | static-capture-groups.js:42:12:42:19 | source() | static-capture-groups.js:43:14:43:22 | RegExp.$1 | +| string-immutable-operations.js:2:13:2:20 | source() | string-immutable-operations.js:3:10:3:25 | x.toWellFormed() | +| string-immutable-operations.js:2:13:2:20 | source() | string-immutable-operations.js:6:10:6:20 | wellFormedX | +| string-immutable-operations.js:2:13:2:20 | source() | string-immutable-operations.js:9:10:9:26 | concatWellFormedX | +| string-immutable-operations.js:11:10:11:17 | source() | string-immutable-operations.js:11:10:11:32 | source( ... ormed() | | string-replace.js:3:13:3:20 | source() | string-replace.js:14:10:14:13 | data | | string-replace.js:3:13:3:20 | source() | string-replace.js:18:10:18:13 | data | | string-replace.js:3:13:3:20 | source() | string-replace.js:21:6:21:41 | safe(). ... taint) | diff --git a/javascript/ql/test/library-tests/TaintTracking/string-immutable-operations.js b/javascript/ql/test/library-tests/TaintTracking/string-immutable-operations.js index 60f6c44088c..79e93fab002 100644 --- a/javascript/ql/test/library-tests/TaintTracking/string-immutable-operations.js +++ b/javascript/ql/test/library-tests/TaintTracking/string-immutable-operations.js @@ -1,12 +1,12 @@ function test() { let x = source(); - sink(x.toWellFormed()); // NOT OK -- Currently not tainted, but should be + sink(x.toWellFormed()); // NOT OK const wellFormedX = x.toWellFormed(); - sink(wellFormedX); // NOT OK -- Currently not tainted, but should be + sink(wellFormedX); // NOT OK const concatWellFormedX = "/" + wellFormedX + "!"; - sink(concatWellFormedX); // NOT OK -- Currently not tainted, but should be + sink(concatWellFormedX); // NOT OK - sink(source().toWellFormed()); // NOT OK -- Currently not tainted, but should be + sink(source().toWellFormed()); // NOT OK } From 43eda58f83d4e81ecba1505a67b68e4a33e4b061 Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 20 Nov 2024 17:44:36 +0100 Subject: [PATCH 137/470] Added change notes --- .../2024-11-20-ES2023-string-protytpe-toWellFormed.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 javascript/ql/lib/change-notes/2024-11-20-ES2023-string-protytpe-toWellFormed.md diff --git a/javascript/ql/lib/change-notes/2024-11-20-ES2023-string-protytpe-toWellFormed.md b/javascript/ql/lib/change-notes/2024-11-20-ES2023-string-protytpe-toWellFormed.md new file mode 100644 index 00000000000..dda4d878760 --- /dev/null +++ b/javascript/ql/lib/change-notes/2024-11-20-ES2023-string-protytpe-toWellFormed.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added taint-steps for `String.prototype.toWellFormed`. From d828941b7c026df222df78f02832b44e9613bad3 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 20 Nov 2024 22:37:46 +0000 Subject: [PATCH 138/470] Rust: Address review comments. --- rust/ql/src/queries/security/CWE-089/SqlInjection.ql | 3 --- rust/ql/src/queries/security/CWE-089/SqlInjectionBad.rs | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-089/SqlInjection.ql b/rust/ql/src/queries/security/CWE-089/SqlInjection.ql index c8db4569e59..cf1ea5534aa 100644 --- a/rust/ql/src/queries/security/CWE-089/SqlInjection.ql +++ b/rust/ql/src/queries/security/CWE-089/SqlInjection.ql @@ -27,9 +27,6 @@ module SqlInjectionConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node barrier) { barrier instanceof SqlInjection::Barrier } } -/** - * Detect taint flow of tainted data that reaches a SQL sink. - */ module SqlInjectionFlow = TaintTracking::Global; from SqlInjectionFlow::PathNode sourceNode, SqlInjectionFlow::PathNode sinkNode diff --git a/rust/ql/src/queries/security/CWE-089/SqlInjectionBad.rs b/rust/ql/src/queries/security/CWE-089/SqlInjectionBad.rs index cd0086b7eb2..4184399a4f1 100644 --- a/rust/ql/src/queries/security/CWE-089/SqlInjectionBad.rs +++ b/rust/ql/src/queries/security/CWE-089/SqlInjectionBad.rs @@ -4,4 +4,4 @@ let unsafe_query = format!("SELECT * FROM people WHERE firstname='{remote_contro let _ = conn.execute(unsafe_query.as_str()).await?; // BAD (arbitrary SQL injection is possible) -let _ = sqlx::query(unsafe_query.as_str()).fetch_all(&mut conn).await?; // $ BAD (arbitrary SQL injection is possible) +let _ = sqlx::query(unsafe_query.as_str()).fetch_all(&mut conn).await?; // BAD (arbitrary SQL injection is possible) From f25c16245c1ac0d52578b3549d91f9b8d8917c99 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 00:21:44 +0000 Subject: [PATCH 139/470] Add changed framework coverage reports --- .../library-coverage/coverage.csv | 262 ++++++++++-------- .../library-coverage/coverage.rst | 22 +- 2 files changed, 152 insertions(+), 132 deletions(-) diff --git a/go/documentation/library-coverage/coverage.csv b/go/documentation/library-coverage/coverage.csv index 547f0aa79ac..21127e396a2 100644 --- a/go/documentation/library-coverage/coverage.csv +++ b/go/documentation/library-coverage/coverage.csv @@ -1,121 +1,141 @@ -package,sink,source,summary,sink:command-injection,sink:credentials-key,sink:jwt,sink:path-injection,sink:regex-use[0],sink:regex-use[1],sink:regex-use[c],sink:request-forgery,sink:request-forgery[TCP Addr + Port],sink:url-redirection,sink:url-redirection[0],sink:url-redirection[receiver],sink:xpath-injection,source:environment,source:file,source:remote,source:stdin,summary:taint,summary:value -,,,8,,,,,,,,,,,,,,,,,,3,5 -archive/tar,,,5,,,,,,,,,,,,,,,,,,5, -archive/zip,,,6,,,,,,,,,,,,,,,,,,6, -bufio,,,17,,,,,,,,,,,,,,,,,,17, -bytes,,,43,,,,,,,,,,,,,,,,,,43, -clevergo.tech/clevergo,1,,,,,,,,,,,,,,1,,,,,,, -compress/bzip2,,,1,,,,,,,,,,,,,,,,,,1, -compress/flate,,,4,,,,,,,,,,,,,,,,,,4, -compress/gzip,,,3,,,,,,,,,,,,,,,,,,3, -compress/lzw,,,1,,,,,,,,,,,,,,,,,,1, -compress/zlib,,,4,,,,,,,,,,,,,,,,,,4, -container/heap,,,5,,,,,,,,,,,,,,,,,,5, -container/list,,,20,,,,,,,,,,,,,,,,,,20, -container/ring,,,5,,,,,,,,,,,,,,,,,,5, -context,,,5,,,,,,,,,,,,,,,,,,5, -crypto,,,10,,,,,,,,,,,,,,,,,,10, -database/sql,,,11,,,,,,,,,,,,,,,,,,11, -encoding,,,77,,,,,,,,,,,,,,,,,,77, -errors,,,3,,,,,,,,,,,,,,,,,,3, -expvar,,,6,,,,,,,,,,,,,,,,,,6, -fmt,,,16,,,,,,,,,,,,,,,,,,16, -github.com/ChrisTrenkamp/goxpath,3,,,,,,,,,,,,,,,3,,,,,, -github.com/antchfx/htmlquery,4,,,,,,,,,,,,,,,4,,,,,, -github.com/antchfx/jsonquery,4,,,,,,,,,,,,,,,4,,,,,, -github.com/antchfx/xmlquery,8,,,,,,,,,,,,,,,8,,,,,, -github.com/antchfx/xpath,4,,,,,,,,,,,,,,,4,,,,,, -github.com/appleboy/gin-jwt,1,,,,1,,,,,,,,,,,,,,,,, -github.com/astaxie/beego,7,21,21,,,,5,,,,,,2,,,,,,21,,21, -github.com/beego/beego,14,42,42,,,,10,,,,,,4,,,,,,42,,42, -github.com/caarlos0/env,,5,2,,,,,,,,,,,,,,5,,,,1,1 -github.com/clevergo/clevergo,1,,,,,,,,,,,,,,1,,,,,,, -github.com/codeskyblue/go-sh,4,,,4,,,,,,,,,,,,,,,,,, -github.com/couchbase/gocb,,,18,,,,,,,,,,,,,,,,,,18, -github.com/couchbaselabs/gocb,,,18,,,,,,,,,,,,,,,,,,18, -github.com/crankycoder/xmlpath,2,,,,,,,,,,,,,,,2,,,,,, -github.com/cristalhq/jwt,1,,,,1,,,,,,,,,,,,,,,,, -github.com/dgrijalva/jwt-go,3,,9,,2,1,,,,,,,,,,,,,,,9, -github.com/elazarl/goproxy,,2,2,,,,,,,,,,,,,,,,2,,2, -github.com/emicklei/go-restful,,7,,,,,,,,,,,,,,,,,7,,, -github.com/evanphx/json-patch,,,12,,,,,,,,,,,,,,,,,,12, -github.com/form3tech-oss/jwt-go,2,,,,2,,,,,,,,,,,,,,,,, -github.com/gin-gonic/gin,3,46,2,,,,3,,,,,,,,,,,,46,,2, -github.com/go-chi/chi,,3,,,,,,,,,,,,,,,,,3,,, -github.com/go-chi/jwtauth,1,,,,1,,,,,,,,,,,,,,,,, -github.com/go-jose/go-jose,3,,4,,2,1,,,,,,,,,,,,,,,4, -github.com/go-kit/kit/auth/jwt,1,,,,1,,,,,,,,,,,,,,,,, -github.com/go-pg/pg/orm,,,6,,,,,,,,,,,,,,,,,,6, -github.com/go-xmlpath/xmlpath,2,,,,,,,,,,,,,,,2,,,,,, -github.com/gobuffalo/envy,,7,,,,,,,,,,,,,,,7,,,,, -github.com/gobwas/ws,,2,,,,,,,,,,,,,,,,,2,,, -github.com/gofiber/fiber,5,,,,,,4,,,,,,,,1,,,,,,, -github.com/gogf/gf-jwt,1,,,,1,,,,,,,,,,,,,,,,, -github.com/going/toolkit/xmlpath,2,,,,,,,,,,,,,,,2,,,,,, -github.com/golang-jwt/jwt,3,,11,,2,1,,,,,,,,,,,,,,,11, -github.com/golang/protobuf/proto,,,4,,,,,,,,,,,,,,,,,,4, -github.com/gorilla/mux,,1,,,,,,,,,,,,,,,,,1,,, -github.com/gorilla/websocket,,3,,,,,,,,,,,,,,,,,3,,, -github.com/hashicorp/go-envparse,,1,,,,,,,,,,,,,,,1,,,,, -github.com/jbowtie/gokogiri/xml,4,,,,,,,,,,,,,,,4,,,,,, -github.com/jbowtie/gokogiri/xpath,1,,,,,,,,,,,,,,,1,,,,,, -github.com/joho/godotenv,,4,,,,,,,,,,,,,,,4,,,,, -github.com/json-iterator/go,,,4,,,,,,,,,,,,,,,,,,4, -github.com/kataras/iris/context,6,,,,,,6,,,,,,,,,,,,,,, -github.com/kataras/iris/middleware/jwt,2,,,,2,,,,,,,,,,,,,,,,, -github.com/kataras/iris/server/web/context,6,,,,,,6,,,,,,,,,,,,,,, -github.com/kataras/jwt,5,,,,5,,,,,,,,,,,,,,,,, -github.com/kelseyhightower/envconfig,,6,,,,,,,,,,,,,,,6,,,,, -github.com/labstack/echo,3,12,2,,,,2,,,,,,1,,,,,,12,,2, -github.com/lestrrat-go/jwx,2,,,,2,,,,,,,,,,,,,,,,, -github.com/lestrrat-go/libxml2/parser,3,,,,,,,,,,,,,,,3,,,,,, -github.com/lestrrat/go-jwx/jwk,1,,,,1,,,,,,,,,,,,,,,,, -github.com/masterzen/xmlpath,2,,,,,,,,,,,,,,,2,,,,,, -github.com/moovweb/gokogiri/xml,4,,,,,,,,,,,,,,,4,,,,,, -github.com/moovweb/gokogiri/xpath,1,,,,,,,,,,,,,,,1,,,,,, -github.com/ory/fosite/token/jwt,2,,,,2,,,,,,,,,,,,,,,,, -github.com/revel/revel,2,23,10,,,,1,,,,,,1,,,,,,23,,10, -github.com/robfig/revel,2,23,10,,,,1,,,,,,1,,,,,,23,,10, -github.com/santhosh-tekuri/xpathparser,2,,,,,,,,,,,,,,,2,,,,,, -github.com/sendgrid/sendgrid-go/helpers/mail,,,1,,,,,,,,,,,,,,,,,,1, -github.com/spf13/afero,34,,,,,,34,,,,,,,,,,,,,,, -github.com/square/go-jose,3,,4,,2,1,,,,,,,,,,,,,,,4, -github.com/valyala/fasthttp,35,50,5,,,,8,,,,17,8,2,,,,,,50,,5, -go.uber.org/zap,,,11,,,,,,,,,,,,,,,,,,11, -golang.org/x/crypto/ssh,4,,,4,,,,,,,,,,,,,,,,,, -golang.org/x/net/context,,,5,,,,,,,,,,,,,,,,,,5, -golang.org/x/net/html,,,16,,,,,,,,,,,,,,,,,,16, -golang.org/x/net/websocket,,2,,,,,,,,,,,,,,,,,2,,, -google.golang.org/protobuf/internal/encoding/text,,,1,,,,,,,,,,,,,,,,,,1, -google.golang.org/protobuf/internal/impl,,,2,,,,,,,,,,,,,,,,,,2, -google.golang.org/protobuf/proto,,,8,,,,,,,,,,,,,,,,,,8, -google.golang.org/protobuf/reflect/protoreflect,,,1,,,,,,,,,,,,,,,,,,1, -gopkg.in/couchbase/gocb,,,18,,,,,,,,,,,,,,,,,,18, -gopkg.in/go-jose/go-jose,3,,4,,2,1,,,,,,,,,,,,,,,4, -gopkg.in/go-xmlpath/xmlpath,2,,,,,,,,,,,,,,,2,,,,,, -gopkg.in/macaron,1,12,1,,,,,,,,,,,,1,,,,12,,1, -gopkg.in/square/go-jose,3,,4,,2,1,,,,,,,,,,,,,,,4, -gopkg.in/xmlpath,2,,,,,,,,,,,,,,,2,,,,,, -gopkg.in/yaml,,,9,,,,,,,,,,,,,,,,,,9, -html,,,8,,,,,,,,,,,,,,,,,,8, -io,5,4,34,,,,5,,,,,,,,,,,4,,,34, -k8s.io/api/core,,,10,,,,,,,,,,,,,,,,,,10, -k8s.io/apimachinery/pkg/runtime,,,47,,,,,,,,,,,,,,,,,,47, -launchpad.net/xmlpath,2,,,,,,,,,,,,,,,2,,,,,, -log,,,3,,,,,,,,,,,,,,,,,,3, -math/big,,,1,,,,,,,,,,,,,,,,,,1, -mime,,,14,,,,,,,,,,,,,,,,,,14, -net,2,16,100,,,,1,,,,,,,1,,,,,16,,100, -nhooyr.io/websocket,,2,,,,,,,,,,,,,,,,,2,,, -os,29,11,6,3,,,26,,,,,,,,,,7,3,,1,6, -path,,,18,,,,,,,,,,,,,,,,,,18, -reflect,,,37,,,,,,,,,,,,,,,,,,37, -regexp,10,,20,,,,,3,3,4,,,,,,,,,,,20, -sort,,,1,,,,,,,,,,,,,,,,,,1, -strconv,,,9,,,,,,,,,,,,,,,,,,9, -strings,,,34,,,,,,,,,,,,,,,,,,34, -sync,,,34,,,,,,,,,,,,,,,,,,34, -syscall,5,2,8,5,,,,,,,,,,,,,2,,,,8, -text/scanner,,,3,,,,,,,,,,,,,,,,,,3, -text/tabwriter,,,1,,,,,,,,,,,,,,,,,,1, -text/template,,,6,,,,,,,,,,,,,,,,,,6, +package,sink,source,summary,sink:command-injection,sink:credentials-key,sink:jwt,sink:log-injection,sink:nosql-injection,sink:path-injection,sink:regex-use[0],sink:regex-use[1],sink:regex-use[c],sink:request-forgery,sink:request-forgery[TCP Addr + Port],sink:sql-injection,sink:url-redirection,sink:url-redirection[0],sink:url-redirection[receiver],sink:xpath-injection,source:environment,source:file,source:remote,source:stdin,summary:taint,summary:value +,,,8,,,,,,,,,,,,,,,,,,,,,3,5 +archive/tar,,,5,,,,,,,,,,,,,,,,,,,,,5, +archive/zip,,,6,,,,,,,,,,,,,,,,,,,,,6, +bufio,,,17,,,,,,,,,,,,,,,,,,,,,17, +bytes,,,43,,,,,,,,,,,,,,,,,,,,,43, +clevergo.tech/clevergo,1,,,,,,,,,,,,,,,,,1,,,,,,, +compress/bzip2,,,1,,,,,,,,,,,,,,,,,,,,,1, +compress/flate,,,4,,,,,,,,,,,,,,,,,,,,,4, +compress/gzip,,,3,,,,,,,,,,,,,,,,,,,,,3, +compress/lzw,,,1,,,,,,,,,,,,,,,,,,,,,1, +compress/zlib,,,4,,,,,,,,,,,,,,,,,,,,,4, +container/heap,,,5,,,,,,,,,,,,,,,,,,,,,5, +container/list,,,20,,,,,,,,,,,,,,,,,,,,,20, +container/ring,,,5,,,,,,,,,,,,,,,,,,,,,5, +context,,,5,,,,,,,,,,,,,,,,,,,,,5, +crypto,,,10,,,,,,,,,,,,,,,,,,,,,10, +database/sql,30,,11,,,,,,,,,,,,30,,,,,,,,,11, +encoding,,,77,,,,,,,,,,,,,,,,,,,,,77, +errors,,,3,,,,,,,,,,,,,,,,,,,,,3, +expvar,,,6,,,,,,,,,,,,,,,,,,,,,6, +fmt,3,,16,,,,3,,,,,,,,,,,,,,,,,16, +github.com/ChrisTrenkamp/goxpath,3,,,,,,,,,,,,,,,,,,3,,,,,, +github.com/Masterminds/squirrel,32,,,,,,,,,,,,,,32,,,,,,,,,, +github.com/Sirupsen/logrus,145,,,,,,145,,,,,,,,,,,,,,,,,, +github.com/antchfx/htmlquery,4,,,,,,,,,,,,,,,,,,4,,,,,, +github.com/antchfx/jsonquery,4,,,,,,,,,,,,,,,,,,4,,,,,, +github.com/antchfx/xmlquery,8,,,,,,,,,,,,,,,,,,8,,,,,, +github.com/antchfx/xpath,4,,,,,,,,,,,,,,,,,,4,,,,,, +github.com/appleboy/gin-jwt,1,,,,1,,,,,,,,,,,,,,,,,,,, +github.com/astaxie/beego,71,21,21,,,,34,,5,,,,,,30,2,,,,,,21,,21, +github.com/beego/beego,142,42,42,,,,68,,10,,,,,,60,4,,,,,,42,,42, +github.com/caarlos0/env,,5,2,,,,,,,,,,,,,,,,,5,,,,1,1 +github.com/clevergo/clevergo,1,,,,,,,,,,,,,,,,,1,,,,,,, +github.com/codeskyblue/go-sh,4,,,4,,,,,,,,,,,,,,,,,,,,, +github.com/couchbase/gocb,8,,18,,,,,8,,,,,,,,,,,,,,,,18, +github.com/couchbaselabs/gocb,8,,18,,,,,8,,,,,,,,,,,,,,,,18, +github.com/crankycoder/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,, +github.com/cristalhq/jwt,1,,,,1,,,,,,,,,,,,,,,,,,,, +github.com/davecgh/go-spew/spew,9,,,,,,9,,,,,,,,,,,,,,,,,, +github.com/dgrijalva/jwt-go,3,,9,,2,1,,,,,,,,,,,,,,,,,,9, +github.com/elazarl/goproxy,2,2,2,,,,2,,,,,,,,,,,,,,,2,,2, +github.com/emicklei/go-restful,,7,,,,,,,,,,,,,,,,,,,,7,,, +github.com/evanphx/json-patch,,,12,,,,,,,,,,,,,,,,,,,,,12, +github.com/form3tech-oss/jwt-go,2,,,,2,,,,,,,,,,,,,,,,,,,, +github.com/gin-gonic/gin,3,46,2,,,,,,3,,,,,,,,,,,,,46,,2, +github.com/go-chi/chi,,3,,,,,,,,,,,,,,,,,,,,3,,, +github.com/go-chi/jwtauth,1,,,,1,,,,,,,,,,,,,,,,,,,, +github.com/go-gorm/gorm,13,,,,,,,,,,,,,,13,,,,,,,,,, +github.com/go-jose/go-jose,3,,4,,2,1,,,,,,,,,,,,,,,,,,4, +github.com/go-kit/kit/auth/jwt,1,,,,1,,,,,,,,,,,,,,,,,,,, +github.com/go-pg/pg/orm,,,6,,,,,,,,,,,,,,,,,,,,,6, +github.com/go-xmlpath/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,, +github.com/go-xorm/xorm,34,,,,,,,,,,,,,,34,,,,,,,,,, +github.com/gobuffalo/envy,,7,,,,,,,,,,,,,,,,,,7,,,,, +github.com/gobwas/ws,,2,,,,,,,,,,,,,,,,,,,,2,,, +github.com/gofiber/fiber,5,,,,,,,,4,,,,,,,,,1,,,,,,, +github.com/gogf/gf-jwt,1,,,,1,,,,,,,,,,,,,,,,,,,, +github.com/gogf/gf/database/gdb,51,,,,,,,,,,,,,,51,,,,,,,,,, +github.com/going/toolkit/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,, +github.com/golang-jwt/jwt,3,,11,,2,1,,,,,,,,,,,,,,,,,,11, +github.com/golang/glog,90,,,,,,90,,,,,,,,,,,,,,,,,, +github.com/golang/protobuf/proto,,,4,,,,,,,,,,,,,,,,,,,,,4, +github.com/gorilla/mux,,1,,,,,,,,,,,,,,,,,,,,1,,, +github.com/gorilla/websocket,,3,,,,,,,,,,,,,,,,,,,,3,,, +github.com/hashicorp/go-envparse,,1,,,,,,,,,,,,,,,,,,1,,,,, +github.com/jbowtie/gokogiri/xml,4,,,,,,,,,,,,,,,,,,4,,,,,, +github.com/jbowtie/gokogiri/xpath,1,,,,,,,,,,,,,,,,,,1,,,,,, +github.com/jinzhu/gorm,13,,,,,,,,,,,,,,13,,,,,,,,,, +github.com/jmoiron/sqlx,12,,,,,,,,,,,,,,12,,,,,,,,,, +github.com/joho/godotenv,,4,,,,,,,,,,,,,,,,,,4,,,,, +github.com/json-iterator/go,,,4,,,,,,,,,,,,,,,,,,,,,4, +github.com/kataras/iris/context,6,,,,,,,,6,,,,,,,,,,,,,,,, +github.com/kataras/iris/middleware/jwt,2,,,,2,,,,,,,,,,,,,,,,,,,, +github.com/kataras/iris/server/web/context,6,,,,,,,,6,,,,,,,,,,,,,,,, +github.com/kataras/jwt,5,,,,5,,,,,,,,,,,,,,,,,,,, +github.com/kelseyhightower/envconfig,,6,,,,,,,,,,,,,,,,,,6,,,,, +github.com/labstack/echo,3,12,2,,,,,,2,,,,,,,1,,,,,,12,,2, +github.com/lann/squirrel,32,,,,,,,,,,,,,,32,,,,,,,,,, +github.com/lestrrat-go/jwx,2,,,,2,,,,,,,,,,,,,,,,,,,, +github.com/lestrrat-go/libxml2/parser,3,,,,,,,,,,,,,,,,,,3,,,,,, +github.com/lestrrat/go-jwx/jwk,1,,,,1,,,,,,,,,,,,,,,,,,,, +github.com/masterzen/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,, +github.com/moovweb/gokogiri/xml,4,,,,,,,,,,,,,,,,,,4,,,,,, +github.com/moovweb/gokogiri/xpath,1,,,,,,,,,,,,,,,,,,1,,,,,, +github.com/ory/fosite/token/jwt,2,,,,2,,,,,,,,,,,,,,,,,,,, +github.com/raindog308/gorqlite,24,,,,,,,,,,,,,,24,,,,,,,,,, +github.com/revel/revel,2,23,10,,,,,,1,,,,,,,1,,,,,,23,,10, +github.com/robfig/revel,2,23,10,,,,,,1,,,,,,,1,,,,,,23,,10, +github.com/rqlite/gorqlite,24,,,,,,,,,,,,,,24,,,,,,,,,, +github.com/santhosh-tekuri/xpathparser,2,,,,,,,,,,,,,,,,,,2,,,,,, +github.com/sendgrid/sendgrid-go/helpers/mail,,,1,,,,,,,,,,,,,,,,,,,,,1, +github.com/sirupsen/logrus,145,,,,,,145,,,,,,,,,,,,,,,,,, +github.com/spf13/afero,34,,,,,,,,34,,,,,,,,,,,,,,,, +github.com/square/go-jose,3,,4,,2,1,,,,,,,,,,,,,,,,,,4, +github.com/uptrace/bun,63,,,,,,,,,,,,,,63,,,,,,,,,, +github.com/valyala/fasthttp,35,50,5,,,,,,8,,,,17,8,,2,,,,,,50,,5, +go.mongodb.org/mongo-driver/mongo,14,,,,,,,14,,,,,,,,,,,,,,,,, +go.uber.org/zap,33,,11,,,,33,,,,,,,,,,,,,,,,,11, +golang.org/x/crypto/ssh,4,,,4,,,,,,,,,,,,,,,,,,,,, +golang.org/x/net/context,,,5,,,,,,,,,,,,,,,,,,,,,5, +golang.org/x/net/html,,,16,,,,,,,,,,,,,,,,,,,,,16, +golang.org/x/net/websocket,,2,,,,,,,,,,,,,,,,,,,,2,,, +google.golang.org/protobuf/internal/encoding/text,,,1,,,,,,,,,,,,,,,,,,,,,1, +google.golang.org/protobuf/internal/impl,,,2,,,,,,,,,,,,,,,,,,,,,2, +google.golang.org/protobuf/proto,,,8,,,,,,,,,,,,,,,,,,,,,8, +google.golang.org/protobuf/reflect/protoreflect,,,1,,,,,,,,,,,,,,,,,,,,,1, +gopkg.in/Masterminds/squirrel,32,,,,,,,,,,,,,,32,,,,,,,,,, +gopkg.in/couchbase/gocb,8,,18,,,,,8,,,,,,,,,,,,,,,,18, +gopkg.in/glog,90,,,,,,90,,,,,,,,,,,,,,,,,, +gopkg.in/go-jose/go-jose,3,,4,,2,1,,,,,,,,,,,,,,,,,,4, +gopkg.in/go-xmlpath/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,, +gopkg.in/macaron,1,12,1,,,,,,,,,,,,,,,1,,,,12,,1, +gopkg.in/square/go-jose,3,,4,,2,1,,,,,,,,,,,,,,,,,,4, +gopkg.in/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,, +gopkg.in/yaml,,,9,,,,,,,,,,,,,,,,,,,,,9, +gorm.io/gorm,13,,,,,,,,,,,,,,13,,,,,,,,,, +html,,,8,,,,,,,,,,,,,,,,,,,,,8, +io,5,4,34,,,,,,5,,,,,,,,,,,,4,,,34, +k8s.io/api/core,,,10,,,,,,,,,,,,,,,,,,,,,10, +k8s.io/apimachinery/pkg/runtime,,,47,,,,,,,,,,,,,,,,,,,,,47, +k8s.io/klog,90,,,,,,90,,,,,,,,,,,,,,,,,, +launchpad.net/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,, +log,20,,3,,,,20,,,,,,,,,,,,,,,,,3, +math/big,,,1,,,,,,,,,,,,,,,,,,,,,1, +mime,,,14,,,,,,,,,,,,,,,,,,,,,14, +net,2,16,100,,,,,,1,,,,,,,,1,,,,,16,,100, +nhooyr.io/websocket,,2,,,,,,,,,,,,,,,,,,,,2,,, +os,29,11,6,3,,,,,26,,,,,,,,,,,7,3,,1,6, +path,,,18,,,,,,,,,,,,,,,,,,,,,18, +reflect,,,37,,,,,,,,,,,,,,,,,,,,,37, +regexp,10,,20,,,,,,,3,3,4,,,,,,,,,,,,20, +sort,,,1,,,,,,,,,,,,,,,,,,,,,1, +strconv,,,9,,,,,,,,,,,,,,,,,,,,,9, +strings,,,34,,,,,,,,,,,,,,,,,,,,,34, +sync,,,34,,,,,,,,,,,,,,,,,,,,,34, +syscall,5,2,8,5,,,,,,,,,,,,,,,,2,,,,8, +text/scanner,,,3,,,,,,,,,,,,,,,,,,,,,3, +text/tabwriter,,,1,,,,,,,,,,,,,,,,,,,,,1, +text/template,,,6,,,,,,,,,,,,,,,,,,,,,6, +xorm.io/xorm,34,,,,,,,,,,,,,,34,,,,,,,,,, diff --git a/go/documentation/library-coverage/coverage.rst b/go/documentation/library-coverage/coverage.rst index 09c44b8aa80..87ac3e6f1cc 100644 --- a/go/documentation/library-coverage/coverage.rst +++ b/go/documentation/library-coverage/coverage.rst @@ -9,27 +9,27 @@ Go framework & library support Framework / library,Package,Flow sources,Taint & value steps,Sinks (total) `Afero `_,``github.com/spf13/afero*``,,,34 `CleverGo `_,"``clevergo.tech/clevergo*``, ``github.com/clevergo/clevergo*``",,,2 - `Couchbase official client(gocb) `_,"``github.com/couchbase/gocb*``, ``gopkg.in/couchbase/gocb*``",,36, - `Couchbase unofficial client `_,``github.com/couchbaselabs/gocb*``,,18, + `Couchbase official client(gocb) `_,"``github.com/couchbase/gocb*``, ``gopkg.in/couchbase/gocb*``",,36,16 + `Couchbase unofficial client `_,``github.com/couchbaselabs/gocb*``,,18,8 `Echo `_,``github.com/labstack/echo*``,12,2,3 `Fiber `_,``github.com/gofiber/fiber*``,,,5 `Fosite `_,``github.com/ory/fosite*``,,,2 `Gin `_,``github.com/gin-gonic/gin*``,46,2,3 - `Glog `_,"``github.com/golang/glog*``, ``gopkg.in/glog*``, ``k8s.io/klog*``",,, + `Glog `_,"``github.com/golang/glog*``, ``gopkg.in/glog*``, ``k8s.io/klog*``",,,270 `Go JOSE `_,"``github.com/go-jose/go-jose*``, ``github.com/square/go-jose*``, ``gopkg.in/square/go-jose*``, ``gopkg.in/go-jose/go-jose*``",,16,12 `Go kit `_,``github.com/go-kit/kit*``,,,1 - `Go-spew `_,``github.com/davecgh/go-spew/spew*``,,, + `Go-spew `_,``github.com/davecgh/go-spew/spew*``,,,9 `Gokogiri `_,"``github.com/jbowtie/gokogiri*``, ``github.com/moovweb/gokogiri*``",,,10 `Iris `_,``github.com/kataras/iris*``,,,14 `Kubernetes `_,"``k8s.io/api*``, ``k8s.io/apimachinery*``",,57, - `Logrus `_,"``github.com/Sirupsen/logrus*``, ``github.com/sirupsen/logrus*``",,, + `Logrus `_,"``github.com/Sirupsen/logrus*``, ``github.com/sirupsen/logrus*``",,,290 `Macaron `_,``gopkg.in/macaron*``,12,1,1 `Revel `_,"``github.com/revel/revel*``, ``github.com/robfig/revel*``",46,20,4 `SendGrid `_,``github.com/sendgrid/sendgrid-go*``,,1, - `Standard library `_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``",33,587,51 + `Standard library `_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``",33,587,104 `XPath `_,``github.com/antchfx/xpath*``,,,4 `appleboy/gin-jwt `_,``github.com/appleboy/gin-jwt*``,,,1 - `beego `_,"``github.com/astaxie/beego*``, ``github.com/beego/beego*``",63,63,21 + `beego `_,"``github.com/astaxie/beego*``, ``github.com/beego/beego*``",63,63,213 `chi `_,``github.com/go-chi/chi*``,3,, `cristalhq/jwt `_,``github.com/cristalhq/jwt*``,,,1 `fasthttp `_,``github.com/valyala/fasthttp*``,50,5,35 @@ -39,7 +39,7 @@ Go framework & library support `go-sh `_,``github.com/codeskyblue/go-sh*``,,,4 `golang.org/x/crypto/ssh `_,``golang.org/x/crypto/ssh*``,,,4 `golang.org/x/net `_,``golang.org/x/net*``,2,21, - `goproxy `_,``github.com/elazarl/goproxy*``,2,2, + `goproxy `_,``github.com/elazarl/goproxy*``,2,2,2 `gorilla/mux `_,``github.com/gorilla/mux*``,1,, `gorilla/websocket `_,``github.com/gorilla/websocket*``,3,, `goxpath `_,``github.com/ChrisTrenkamp/goxpath*``,,,3 @@ -59,7 +59,7 @@ Go framework & library support `xmlquery `_,``github.com/antchfx/xmlquery*``,,,8 `xpathparser `_,``github.com/santhosh-tekuri/xpathparser*``,,,2 `yaml `_,``gopkg.in/yaml*``,,9, - `zap `_,``go.uber.org/zap*``,,11, - Others,"``github.com/caarlos0/env``, ``github.com/gobuffalo/envy``, ``github.com/hashicorp/go-envparse``, ``github.com/joho/godotenv``, ``github.com/kelseyhightower/envconfig``",23,2, - Totals,,307,911,268 + `zap `_,``go.uber.org/zap*``,,11,33 + Others,"``github.com/Masterminds/squirrel``, ``github.com/caarlos0/env``, ``github.com/go-gorm/gorm``, ``github.com/go-xorm/xorm``, ``github.com/gobuffalo/envy``, ``github.com/gogf/gf/database/gdb``, ``github.com/hashicorp/go-envparse``, ``github.com/jinzhu/gorm``, ``github.com/jmoiron/sqlx``, ``github.com/joho/godotenv``, ``github.com/kelseyhightower/envconfig``, ``github.com/lann/squirrel``, ``github.com/raindog308/gorqlite``, ``github.com/rqlite/gorqlite``, ``github.com/uptrace/bun``, ``go.mongodb.org/mongo-driver/mongo``, ``gopkg.in/Masterminds/squirrel``, ``gorm.io/gorm``, ``xorm.io/xorm``",23,2,391 + Totals,,307,911,1532 From d6ceb893249552921e53ad71382fe33eca7f0000 Mon Sep 17 00:00:00 2001 From: ewillonermsft <129988051+ewillonermsft@users.noreply.github.com> Date: Wed, 20 Nov 2024 21:01:20 -0800 Subject: [PATCH 140/470] Add Deserialize() and Deserialize to System.Web.Serialization stub.s --- csharp/ql/test/resources/stubs/System.Web.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/csharp/ql/test/resources/stubs/System.Web.cs b/csharp/ql/test/resources/stubs/System.Web.cs index d876a83e318..d1942c07dc1 100644 --- a/csharp/ql/test/resources/stubs/System.Web.cs +++ b/csharp/ql/test/resources/stubs/System.Web.cs @@ -390,6 +390,8 @@ namespace System.Web.Script.Serialization public JavaScriptSerializer() => throw null; public JavaScriptSerializer(System.Web.Script.Serialization.JavaScriptTypeResolver resolver) => throw null; public object DeserializeObject(string input) => throw null; + public T Deserialize (string input) => throw null; + public object Deserialize(string input, Type targetType) => throw null; } // Generated from `System.Web.Script.Serialization.JavaScriptTypeResolver` in `System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35` From fab29361cb371356a4d4a61fffb83f7e066e454f Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 19 Nov 2024 14:55:19 +0100 Subject: [PATCH 141/470] Rust: Add more CFG tests --- .../library-tests/controlflow/Cfg.expected | 962 +++++++++--------- .../ql/test/library-tests/controlflow/test.rs | 7 + 2 files changed, 496 insertions(+), 473 deletions(-) diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 8fd71a451b8..93022fe371d 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -608,476 +608,492 @@ edges | test.rs:278:9:278:19 | ... && ... | test.rs:277:33:279:5 | BlockExpr | | | test.rs:278:9:278:20 | ExprStmt | test.rs:278:9:278:9 | a | | | test.rs:278:14:278:19 | ReturnExpr | test.rs:277:5:279:5 | exit test_and_return (normal) | return | -| test.rs:285:5:287:5 | enter test_question_mark_operator_1 | test.rs:285:38:285:38 | s | | -| test.rs:285:5:287:5 | exit test_question_mark_operator_1 (normal) | test.rs:285:5:287:5 | exit test_question_mark_operator_1 | | -| test.rs:285:38:285:38 | s | test.rs:285:38:285:44 | Param | match | -| test.rs:285:38:285:44 | Param | test.rs:286:9:286:10 | Ok | | -| test.rs:285:87:287:5 | BlockExpr | test.rs:285:5:287:5 | exit test_question_mark_operator_1 (normal) | | -| test.rs:286:9:286:10 | Ok | test.rs:286:12:286:12 | s | | -| test.rs:286:9:286:33 | CallExpr | test.rs:285:87:287:5 | BlockExpr | | -| test.rs:286:12:286:12 | s | test.rs:286:12:286:27 | ... .parse(...) | | -| test.rs:286:12:286:27 | ... .parse(...) | test.rs:286:12:286:28 | TryExpr | | -| test.rs:286:12:286:28 | TryExpr | test.rs:285:5:287:5 | exit test_question_mark_operator_1 (normal) | return | -| test.rs:286:12:286:28 | TryExpr | test.rs:286:32:286:32 | 4 | match | -| test.rs:286:12:286:32 | ... + ... | test.rs:286:9:286:33 | CallExpr | | -| test.rs:286:32:286:32 | 4 | test.rs:286:12:286:32 | ... + ... | | -| test.rs:289:5:294:5 | enter test_question_mark_operator_2 | test.rs:289:38:289:38 | b | | -| test.rs:289:5:294:5 | exit test_question_mark_operator_2 (normal) | test.rs:289:5:294:5 | exit test_question_mark_operator_2 | | -| test.rs:289:38:289:38 | b | test.rs:289:38:289:52 | Param | match | -| test.rs:289:38:289:52 | Param | test.rs:290:15:290:15 | b | | -| test.rs:289:71:294:5 | BlockExpr | test.rs:289:5:294:5 | exit test_question_mark_operator_2 (normal) | | -| test.rs:290:9:293:9 | MatchExpr | test.rs:289:71:294:5 | BlockExpr | | -| test.rs:290:15:290:15 | b | test.rs:290:15:290:16 | TryExpr | | -| test.rs:290:15:290:16 | TryExpr | test.rs:289:5:294:5 | exit test_question_mark_operator_2 (normal) | return | -| test.rs:290:15:290:16 | TryExpr | test.rs:291:13:291:16 | true | match | -| test.rs:291:13:291:16 | LiteralPat | test.rs:291:21:291:24 | Some | match | -| test.rs:291:13:291:16 | LiteralPat | test.rs:292:13:292:17 | false | no-match | -| test.rs:291:13:291:16 | true | test.rs:291:13:291:16 | LiteralPat | | -| test.rs:291:21:291:24 | Some | test.rs:291:26:291:30 | false | | -| test.rs:291:21:291:31 | CallExpr | test.rs:290:9:293:9 | MatchExpr | | -| test.rs:291:26:291:30 | false | test.rs:291:21:291:31 | CallExpr | | -| test.rs:292:13:292:17 | LiteralPat | test.rs:292:22:292:25 | Some | match | -| test.rs:292:13:292:17 | false | test.rs:292:13:292:17 | LiteralPat | | -| test.rs:292:22:292:25 | Some | test.rs:292:27:292:30 | true | | -| test.rs:292:22:292:31 | CallExpr | test.rs:290:9:293:9 | MatchExpr | | -| test.rs:292:27:292:30 | true | test.rs:292:22:292:31 | CallExpr | | -| test.rs:300:5:306:5 | enter test_match | test.rs:300:19:300:29 | maybe_digit | | -| test.rs:300:5:306:5 | exit test_match (normal) | test.rs:300:5:306:5 | exit test_match | | -| test.rs:300:19:300:29 | maybe_digit | test.rs:300:19:300:42 | Param | match | -| test.rs:300:19:300:42 | Param | test.rs:301:15:301:25 | maybe_digit | | -| test.rs:300:52:306:5 | BlockExpr | test.rs:300:5:306:5 | exit test_match (normal) | | -| test.rs:301:9:305:9 | MatchExpr | test.rs:300:52:306:5 | BlockExpr | | -| test.rs:301:15:301:25 | maybe_digit | test.rs:302:13:302:27 | TupleStructPat | | -| test.rs:302:13:302:27 | TupleStructPat | test.rs:302:26:302:26 | x | match | -| test.rs:302:13:302:27 | TupleStructPat | test.rs:303:13:303:27 | TupleStructPat | no-match | -| test.rs:302:26:302:26 | x | test.rs:302:32:302:32 | x | match | -| test.rs:302:32:302:32 | x | test.rs:302:36:302:37 | 10 | | -| test.rs:302:32:302:37 | ... < ... | test.rs:302:42:302:42 | x | true | -| test.rs:302:32:302:37 | ... < ... | test.rs:303:13:303:27 | TupleStructPat | false | -| test.rs:302:36:302:37 | 10 | test.rs:302:32:302:37 | ... < ... | | -| test.rs:302:42:302:42 | x | test.rs:302:46:302:46 | 5 | | -| test.rs:302:42:302:46 | ... + ... | test.rs:301:9:305:9 | MatchExpr | | -| test.rs:302:46:302:46 | 5 | test.rs:302:42:302:46 | ... + ... | | -| test.rs:303:13:303:27 | TupleStructPat | test.rs:303:26:303:26 | x | match | -| test.rs:303:13:303:27 | TupleStructPat | test.rs:304:13:304:24 | PathPat | no-match | -| test.rs:303:26:303:26 | x | test.rs:303:32:303:32 | x | match | -| test.rs:303:32:303:32 | x | test.rs:301:9:305:9 | MatchExpr | | -| test.rs:304:13:304:24 | PathPat | test.rs:304:29:304:29 | 5 | match | -| test.rs:304:29:304:29 | 5 | test.rs:301:9:305:9 | MatchExpr | | -| test.rs:308:5:317:5 | enter test_match_with_return_in_scrutinee | test.rs:308:44:308:54 | maybe_digit | | -| test.rs:308:5:317:5 | exit test_match_with_return_in_scrutinee (normal) | test.rs:308:5:317:5 | exit test_match_with_return_in_scrutinee | | -| test.rs:308:44:308:54 | maybe_digit | test.rs:308:44:308:67 | Param | match | -| test.rs:308:44:308:67 | Param | test.rs:309:19:309:29 | maybe_digit | | -| test.rs:308:77:317:5 | BlockExpr | test.rs:308:5:317:5 | exit test_match_with_return_in_scrutinee (normal) | | -| test.rs:309:9:316:9 | MatchExpr | test.rs:308:77:317:5 | BlockExpr | | -| test.rs:309:16:313:9 | IfExpr | test.rs:314:13:314:27 | TupleStructPat | | -| test.rs:309:19:309:29 | maybe_digit | test.rs:309:34:309:37 | Some | | -| test.rs:309:19:309:40 | ... == ... | test.rs:310:13:310:21 | ExprStmt | true | -| test.rs:309:19:309:40 | ... == ... | test.rs:312:13:312:23 | maybe_digit | false | -| test.rs:309:34:309:37 | Some | test.rs:309:39:309:39 | 3 | | -| test.rs:309:34:309:40 | CallExpr | test.rs:309:19:309:40 | ... == ... | | -| test.rs:309:39:309:39 | 3 | test.rs:309:34:309:40 | CallExpr | | -| test.rs:310:13:310:20 | ReturnExpr | test.rs:308:5:317:5 | exit test_match_with_return_in_scrutinee (normal) | return | -| test.rs:310:13:310:21 | ExprStmt | test.rs:310:20:310:20 | 3 | | -| test.rs:310:20:310:20 | 3 | test.rs:310:13:310:20 | ReturnExpr | | -| test.rs:311:16:313:9 | BlockExpr | test.rs:309:16:313:9 | IfExpr | | -| test.rs:312:13:312:23 | maybe_digit | test.rs:311:16:313:9 | BlockExpr | | -| test.rs:314:13:314:27 | TupleStructPat | test.rs:314:26:314:26 | x | match | -| test.rs:314:13:314:27 | TupleStructPat | test.rs:315:13:315:24 | PathPat | no-match | -| test.rs:314:26:314:26 | x | test.rs:314:32:314:32 | x | match | -| test.rs:314:32:314:32 | x | test.rs:314:36:314:36 | 5 | | -| test.rs:314:32:314:36 | ... + ... | test.rs:309:9:316:9 | MatchExpr | | -| test.rs:314:36:314:36 | 5 | test.rs:314:32:314:36 | ... + ... | | -| test.rs:315:13:315:24 | PathPat | test.rs:315:29:315:29 | 5 | match | -| test.rs:315:29:315:29 | 5 | test.rs:309:9:316:9 | MatchExpr | | -| test.rs:319:5:324:5 | enter test_match_and | test.rs:319:23:319:26 | cond | | -| test.rs:319:5:324:5 | exit test_match_and (normal) | test.rs:319:5:324:5 | exit test_match_and | | -| test.rs:319:23:319:26 | cond | test.rs:319:23:319:32 | Param | match | -| test.rs:319:23:319:32 | Param | test.rs:319:35:319:35 | r | | -| test.rs:319:35:319:35 | r | test.rs:319:35:319:49 | Param | match | -| test.rs:319:35:319:49 | Param | test.rs:320:16:320:16 | r | | -| test.rs:319:60:324:5 | BlockExpr | test.rs:319:5:324:5 | exit test_match_and (normal) | | -| test.rs:320:9:323:18 | ... && ... | test.rs:319:60:324:5 | BlockExpr | | -| test.rs:320:10:323:9 | [boolean(false)] MatchExpr | test.rs:320:9:323:18 | ... && ... | false | -| test.rs:320:10:323:9 | [boolean(true)] MatchExpr | test.rs:323:15:323:18 | cond | true | -| test.rs:320:16:320:16 | r | test.rs:321:13:321:19 | TupleStructPat | | -| test.rs:321:13:321:19 | TupleStructPat | test.rs:321:18:321:18 | a | match | -| test.rs:321:13:321:19 | TupleStructPat | test.rs:322:13:322:13 | WildcardPat | no-match | -| test.rs:321:18:321:18 | a | test.rs:321:24:321:24 | a | match | -| test.rs:321:24:321:24 | a | test.rs:320:10:323:9 | [boolean(false)] MatchExpr | false | -| test.rs:321:24:321:24 | a | test.rs:320:10:323:9 | [boolean(true)] MatchExpr | true | -| test.rs:322:13:322:13 | WildcardPat | test.rs:322:18:322:22 | false | match | -| test.rs:322:18:322:22 | false | test.rs:320:10:323:9 | [boolean(false)] MatchExpr | false | -| test.rs:323:15:323:18 | cond | test.rs:320:9:323:18 | ... && ... | | -| test.rs:326:5:331:5 | enter test_match_with_no_arms | test.rs:326:35:326:35 | r | | -| test.rs:326:5:331:5 | exit test_match_with_no_arms (normal) | test.rs:326:5:331:5 | exit test_match_with_no_arms | | -| test.rs:326:35:326:35 | r | test.rs:326:35:326:58 | Param | match | -| test.rs:326:35:326:58 | Param | test.rs:327:15:327:15 | r | | -| test.rs:326:66:331:5 | BlockExpr | test.rs:326:5:331:5 | exit test_match_with_no_arms (normal) | | -| test.rs:327:9:330:9 | MatchExpr | test.rs:326:66:331:5 | BlockExpr | | -| test.rs:327:15:327:15 | r | test.rs:328:13:328:21 | TupleStructPat | | -| test.rs:328:13:328:21 | TupleStructPat | test.rs:328:16:328:20 | value | match | -| test.rs:328:13:328:21 | TupleStructPat | test.rs:329:13:329:22 | TupleStructPat | no-match | -| test.rs:328:16:328:20 | value | test.rs:328:26:328:30 | value | match | -| test.rs:328:26:328:30 | value | test.rs:327:9:330:9 | MatchExpr | | -| test.rs:329:13:329:22 | TupleStructPat | test.rs:329:17:329:21 | never | match | -| test.rs:329:17:329:21 | never | test.rs:329:33:329:37 | never | match | -| test.rs:329:27:329:40 | MatchExpr | test.rs:327:9:330:9 | MatchExpr | | -| test.rs:329:33:329:37 | never | test.rs:329:27:329:40 | MatchExpr | | -| test.rs:336:5:339:5 | enter test_let_match | test.rs:336:23:336:23 | a | | -| test.rs:336:5:339:5 | exit test_let_match (normal) | test.rs:336:5:339:5 | exit test_let_match | | -| test.rs:336:23:336:23 | a | test.rs:336:23:336:36 | Param | match | -| test.rs:336:23:336:36 | Param | test.rs:337:9:337:57 | LetStmt | | -| test.rs:336:46:339:5 | BlockExpr | test.rs:336:5:339:5 | exit test_let_match (normal) | | -| test.rs:337:9:337:57 | LetStmt | test.rs:337:23:337:23 | a | | -| test.rs:337:13:337:19 | TupleStructPat | test.rs:337:18:337:18 | n | match | -| test.rs:337:13:337:19 | TupleStructPat | test.rs:337:39:337:53 | MacroStmts | no-match | -| test.rs:337:18:337:18 | n | test.rs:338:9:338:9 | n | match | -| test.rs:337:23:337:23 | a | test.rs:337:13:337:19 | TupleStructPat | | -| test.rs:337:32:337:54 | $crate::panicking::panic_fmt | test.rs:337:39:337:53 | "Expected some" | | -| test.rs:337:32:337:54 | MacroExpr | test.rs:337:30:337:56 | BlockExpr | | -| test.rs:337:39:337:53 | "Expected some" | test.rs:337:39:337:53 | FormatArgsExpr | | -| test.rs:337:39:337:53 | BlockExpr | test.rs:337:39:337:53 | MacroExpr | | -| test.rs:337:39:337:53 | CallExpr | test.rs:337:39:337:53 | BlockExpr | | -| test.rs:337:39:337:53 | ExprStmt | test.rs:337:32:337:54 | $crate::panicking::panic_fmt | | -| test.rs:337:39:337:53 | FormatArgsExpr | test.rs:337:39:337:53 | MacroExpr | | -| test.rs:337:39:337:53 | MacroExpr | test.rs:337:32:337:54 | MacroExpr | | -| test.rs:337:39:337:53 | MacroExpr | test.rs:337:39:337:53 | CallExpr | | -| test.rs:337:39:337:53 | MacroStmts | test.rs:337:39:337:53 | ExprStmt | | -| test.rs:337:39:337:53 | MacroStmts | test.rs:337:39:337:53 | MacroStmts | | -| test.rs:338:9:338:9 | n | test.rs:336:46:339:5 | BlockExpr | | -| test.rs:341:5:347:5 | enter test_let_with_return | test.rs:341:29:341:29 | m | | -| test.rs:341:5:347:5 | exit test_let_with_return (normal) | test.rs:341:5:347:5 | exit test_let_with_return | | -| test.rs:341:29:341:29 | m | test.rs:341:29:341:42 | Param | match | -| test.rs:341:29:341:42 | Param | test.rs:342:9:345:10 | LetStmt | | -| test.rs:341:53:347:5 | BlockExpr | test.rs:341:5:347:5 | exit test_let_with_return (normal) | | -| test.rs:342:9:345:10 | LetStmt | test.rs:342:25:342:25 | m | | -| test.rs:342:13:342:15 | ret | test.rs:346:9:346:12 | true | match | -| test.rs:342:19:345:9 | MatchExpr | test.rs:342:13:342:15 | ret | | -| test.rs:342:25:342:25 | m | test.rs:343:13:343:21 | TupleStructPat | | -| test.rs:343:13:343:21 | TupleStructPat | test.rs:343:18:343:20 | ret | match | -| test.rs:343:13:343:21 | TupleStructPat | test.rs:344:13:344:16 | None | no-match | -| test.rs:343:18:343:20 | ret | test.rs:343:26:343:28 | ret | match | -| test.rs:343:26:343:28 | ret | test.rs:342:19:345:9 | MatchExpr | | -| test.rs:344:13:344:16 | None | test.rs:344:28:344:32 | false | match | -| test.rs:344:21:344:32 | ReturnExpr | test.rs:341:5:347:5 | exit test_let_with_return (normal) | return | -| test.rs:344:28:344:32 | false | test.rs:344:21:344:32 | ReturnExpr | | -| test.rs:346:9:346:12 | true | test.rs:341:53:347:5 | BlockExpr | | -| test.rs:352:5:355:5 | enter empty_tuple_pattern | test.rs:352:28:352:31 | unit | | -| test.rs:352:5:355:5 | exit empty_tuple_pattern (normal) | test.rs:352:5:355:5 | exit empty_tuple_pattern | | -| test.rs:352:28:352:31 | unit | test.rs:352:28:352:35 | Param | match | -| test.rs:352:28:352:35 | Param | test.rs:353:9:353:22 | LetStmt | | -| test.rs:353:9:353:22 | LetStmt | test.rs:353:18:353:21 | unit | | -| test.rs:353:13:353:14 | TuplePat | test.rs:354:9:354:15 | ExprStmt | match | -| test.rs:353:18:353:21 | unit | test.rs:353:13:353:14 | TuplePat | | -| test.rs:354:9:354:14 | ReturnExpr | test.rs:352:5:355:5 | exit empty_tuple_pattern (normal) | return | -| test.rs:354:9:354:15 | ExprStmt | test.rs:354:9:354:14 | ReturnExpr | | -| test.rs:359:5:363:5 | enter empty_struct_pattern | test.rs:359:29:359:30 | st | | -| test.rs:359:5:363:5 | exit empty_struct_pattern (normal) | test.rs:359:5:363:5 | exit empty_struct_pattern | | -| test.rs:359:29:359:30 | st | test.rs:359:29:359:40 | Param | match | -| test.rs:359:29:359:40 | Param | test.rs:360:15:360:16 | st | | -| test.rs:359:50:363:5 | BlockExpr | test.rs:359:5:363:5 | exit empty_struct_pattern (normal) | | -| test.rs:360:9:362:9 | MatchExpr | test.rs:359:50:363:5 | BlockExpr | | -| test.rs:360:15:360:16 | st | test.rs:361:13:361:27 | RecordPat | | -| test.rs:361:13:361:27 | RecordPat | test.rs:361:24:361:25 | RestPat | match | -| test.rs:361:24:361:25 | RestPat | test.rs:361:32:361:32 | 1 | match | -| test.rs:361:32:361:32 | 1 | test.rs:360:9:362:9 | MatchExpr | | -| test.rs:365:5:372:5 | enter range_pattern | test.rs:366:15:366:16 | 42 | | -| test.rs:365:5:372:5 | exit range_pattern (normal) | test.rs:365:5:372:5 | exit range_pattern | | -| test.rs:365:31:372:5 | BlockExpr | test.rs:365:5:372:5 | exit range_pattern (normal) | | -| test.rs:366:9:371:9 | MatchExpr | test.rs:365:31:372:5 | BlockExpr | | -| test.rs:366:15:366:16 | 42 | test.rs:367:13:367:15 | RangePat | | -| test.rs:367:13:367:15 | RangePat | test.rs:367:15:367:15 | 0 | match | -| test.rs:367:13:367:15 | RangePat | test.rs:368:13:368:16 | RangePat | no-match | -| test.rs:367:15:367:15 | 0 | test.rs:367:15:367:15 | LiteralPat | | -| test.rs:367:15:367:15 | LiteralPat | test.rs:367:20:367:20 | 1 | match | -| test.rs:367:15:367:15 | LiteralPat | test.rs:368:13:368:16 | RangePat | no-match | -| test.rs:367:20:367:20 | 1 | test.rs:366:9:371:9 | MatchExpr | | -| test.rs:368:13:368:13 | 1 | test.rs:368:13:368:13 | LiteralPat | | -| test.rs:368:13:368:13 | LiteralPat | test.rs:368:16:368:16 | 2 | match | -| test.rs:368:13:368:13 | LiteralPat | test.rs:369:13:369:15 | RangePat | no-match | -| test.rs:368:13:368:16 | RangePat | test.rs:368:13:368:13 | 1 | match | -| test.rs:368:13:368:16 | RangePat | test.rs:369:13:369:15 | RangePat | no-match | -| test.rs:368:16:368:16 | 2 | test.rs:368:16:368:16 | LiteralPat | | -| test.rs:368:16:368:16 | LiteralPat | test.rs:368:21:368:21 | 2 | match | -| test.rs:368:16:368:16 | LiteralPat | test.rs:369:13:369:15 | RangePat | no-match | -| test.rs:368:21:368:21 | 2 | test.rs:366:9:371:9 | MatchExpr | | -| test.rs:369:13:369:13 | 5 | test.rs:369:13:369:13 | LiteralPat | | -| test.rs:369:13:369:13 | LiteralPat | test.rs:369:20:369:20 | 3 | match | -| test.rs:369:13:369:13 | LiteralPat | test.rs:370:13:370:13 | WildcardPat | no-match | -| test.rs:369:13:369:15 | RangePat | test.rs:369:13:369:13 | 5 | match | -| test.rs:369:13:369:15 | RangePat | test.rs:370:13:370:13 | WildcardPat | no-match | -| test.rs:369:20:369:20 | 3 | test.rs:366:9:371:9 | MatchExpr | | -| test.rs:370:13:370:13 | WildcardPat | test.rs:370:18:370:18 | 4 | match | -| test.rs:370:18:370:18 | 4 | test.rs:366:9:371:9 | MatchExpr | | -| test.rs:376:5:381:5 | enter test_infinite_loop | test.rs:377:9:379:9 | ExprStmt | | -| test.rs:377:9:379:9 | ExprStmt | test.rs:378:13:378:14 | TupleExpr | | -| test.rs:377:14:379:9 | BlockExpr | test.rs:378:13:378:14 | TupleExpr | | -| test.rs:378:13:378:14 | TupleExpr | test.rs:377:14:379:9 | BlockExpr | | -| test.rs:385:5:387:5 | enter say_hello | test.rs:386:9:386:34 | ExprStmt | | -| test.rs:385:5:387:5 | exit say_hello (normal) | test.rs:385:5:387:5 | exit say_hello | | -| test.rs:385:26:387:5 | BlockExpr | test.rs:385:5:387:5 | exit say_hello (normal) | | -| test.rs:386:9:386:33 | $crate::io::_print | test.rs:386:18:386:32 | "hello, world!\\n" | | -| test.rs:386:9:386:33 | MacroExpr | test.rs:385:26:387:5 | BlockExpr | | -| test.rs:386:9:386:34 | ExprStmt | test.rs:386:18:386:32 | MacroStmts | | -| test.rs:386:18:386:32 | "hello, world!\\n" | test.rs:386:18:386:32 | FormatArgsExpr | | -| test.rs:386:18:386:32 | BlockExpr | test.rs:386:9:386:33 | MacroExpr | | -| test.rs:386:18:386:32 | CallExpr | test.rs:386:18:386:32 | BlockExpr | | -| test.rs:386:18:386:32 | ExprStmt | test.rs:386:9:386:33 | $crate::io::_print | | -| test.rs:386:18:386:32 | FormatArgsExpr | test.rs:386:18:386:32 | MacroExpr | | -| test.rs:386:18:386:32 | MacroExpr | test.rs:386:18:386:32 | CallExpr | | -| test.rs:386:18:386:32 | MacroStmts | test.rs:386:18:386:32 | ExprStmt | | -| test.rs:389:5:408:5 | enter async_block | test.rs:389:26:389:26 | b | | -| test.rs:389:5:408:5 | exit async_block (normal) | test.rs:389:5:408:5 | exit async_block | | -| test.rs:389:26:389:26 | b | test.rs:389:26:389:32 | Param | match | -| test.rs:389:26:389:32 | Param | test.rs:390:9:392:10 | LetStmt | | -| test.rs:389:35:408:5 | BlockExpr | test.rs:389:5:408:5 | exit async_block (normal) | | -| test.rs:390:9:392:10 | LetStmt | test.rs:390:26:392:9 | BlockExpr | | -| test.rs:390:13:390:22 | say_godbye | test.rs:393:9:395:10 | LetStmt | match | -| test.rs:390:26:392:9 | BlockExpr | test.rs:390:13:390:22 | say_godbye | | -| test.rs:390:26:392:9 | enter BlockExpr | test.rs:391:13:391:42 | ExprStmt | | -| test.rs:390:26:392:9 | exit BlockExpr (normal) | test.rs:390:26:392:9 | exit BlockExpr | | -| test.rs:391:13:391:41 | $crate::io::_print | test.rs:391:22:391:40 | "godbye, everyone!\\n" | | -| test.rs:391:13:391:41 | MacroExpr | test.rs:390:26:392:9 | exit BlockExpr (normal) | | -| test.rs:391:13:391:42 | ExprStmt | test.rs:391:22:391:40 | MacroStmts | | -| test.rs:391:22:391:40 | "godbye, everyone!\\n" | test.rs:391:22:391:40 | FormatArgsExpr | | -| test.rs:391:22:391:40 | BlockExpr | test.rs:391:13:391:41 | MacroExpr | | -| test.rs:391:22:391:40 | CallExpr | test.rs:391:22:391:40 | BlockExpr | | -| test.rs:391:22:391:40 | ExprStmt | test.rs:391:13:391:41 | $crate::io::_print | | -| test.rs:391:22:391:40 | FormatArgsExpr | test.rs:391:22:391:40 | MacroExpr | | -| test.rs:391:22:391:40 | MacroExpr | test.rs:391:22:391:40 | CallExpr | | -| test.rs:391:22:391:40 | MacroStmts | test.rs:391:22:391:40 | ExprStmt | | -| test.rs:393:9:395:10 | LetStmt | test.rs:393:31:395:9 | BlockExpr | | -| test.rs:393:13:393:27 | say_how_are_you | test.rs:396:9:396:28 | LetStmt | match | -| test.rs:393:31:395:9 | BlockExpr | test.rs:393:13:393:27 | say_how_are_you | | -| test.rs:393:31:395:9 | enter BlockExpr | test.rs:394:13:394:37 | ExprStmt | | -| test.rs:393:31:395:9 | exit BlockExpr (normal) | test.rs:393:31:395:9 | exit BlockExpr | | -| test.rs:394:13:394:36 | $crate::io::_print | test.rs:394:22:394:35 | "how are you?\\n" | | -| test.rs:394:13:394:36 | MacroExpr | test.rs:393:31:395:9 | exit BlockExpr (normal) | | -| test.rs:394:13:394:37 | ExprStmt | test.rs:394:22:394:35 | MacroStmts | | -| test.rs:394:22:394:35 | "how are you?\\n" | test.rs:394:22:394:35 | FormatArgsExpr | | -| test.rs:394:22:394:35 | BlockExpr | test.rs:394:13:394:36 | MacroExpr | | -| test.rs:394:22:394:35 | CallExpr | test.rs:394:22:394:35 | BlockExpr | | -| test.rs:394:22:394:35 | ExprStmt | test.rs:394:13:394:36 | $crate::io::_print | | -| test.rs:394:22:394:35 | FormatArgsExpr | test.rs:394:22:394:35 | MacroExpr | | -| test.rs:394:22:394:35 | MacroExpr | test.rs:394:22:394:35 | CallExpr | | -| test.rs:394:22:394:35 | MacroStmts | test.rs:394:22:394:35 | ExprStmt | | -| test.rs:396:9:396:28 | LetStmt | test.rs:396:20:396:27 | BlockExpr | | -| test.rs:396:13:396:16 | noop | test.rs:397:9:397:26 | ExprStmt | match | -| test.rs:396:20:396:27 | BlockExpr | test.rs:396:13:396:16 | noop | | -| test.rs:397:9:397:17 | say_hello | test.rs:397:9:397:19 | CallExpr | | -| test.rs:397:9:397:19 | CallExpr | test.rs:397:9:397:25 | AwaitExpr | | -| test.rs:397:9:397:25 | AwaitExpr | test.rs:398:9:398:30 | ExprStmt | | -| test.rs:397:9:397:26 | ExprStmt | test.rs:397:9:397:17 | say_hello | | -| test.rs:398:9:398:23 | say_how_are_you | test.rs:398:9:398:29 | AwaitExpr | | -| test.rs:398:9:398:29 | AwaitExpr | test.rs:399:9:399:25 | ExprStmt | | -| test.rs:398:9:398:30 | ExprStmt | test.rs:398:9:398:23 | say_how_are_you | | -| test.rs:399:9:399:18 | say_godbye | test.rs:399:9:399:24 | AwaitExpr | | -| test.rs:399:9:399:24 | AwaitExpr | test.rs:400:9:400:19 | ExprStmt | | -| test.rs:399:9:399:25 | ExprStmt | test.rs:399:9:399:18 | say_godbye | | -| test.rs:400:9:400:12 | noop | test.rs:400:9:400:18 | AwaitExpr | | -| test.rs:400:9:400:18 | AwaitExpr | test.rs:402:9:407:10 | LetStmt | | -| test.rs:400:9:400:19 | ExprStmt | test.rs:400:9:400:12 | noop | | -| test.rs:402:9:407:10 | LetStmt | test.rs:402:22:407:9 | ClosureExpr | | -| test.rs:402:13:402:18 | lambda | test.rs:389:35:408:5 | BlockExpr | match | -| test.rs:402:22:407:9 | ClosureExpr | test.rs:402:13:402:18 | lambda | | -| test.rs:402:22:407:9 | enter ClosureExpr | test.rs:402:23:402:25 | foo | | -| test.rs:402:22:407:9 | exit ClosureExpr (normal) | test.rs:402:22:407:9 | exit ClosureExpr | | -| test.rs:402:23:402:25 | Param | test.rs:402:28:407:9 | BlockExpr | | -| test.rs:402:23:402:25 | foo | test.rs:402:23:402:25 | Param | match | -| test.rs:402:28:407:9 | BlockExpr | test.rs:402:22:407:9 | exit ClosureExpr (normal) | | -| test.rs:402:28:407:9 | enter BlockExpr | test.rs:403:13:405:14 | ExprStmt | | -| test.rs:402:28:407:9 | exit BlockExpr (normal) | test.rs:402:28:407:9 | exit BlockExpr | | -| test.rs:403:13:405:13 | IfExpr | test.rs:406:13:406:15 | foo | | -| test.rs:403:13:405:14 | ExprStmt | test.rs:403:16:403:16 | b | | -| test.rs:403:16:403:16 | b | test.rs:403:13:405:13 | IfExpr | false | -| test.rs:403:16:403:16 | b | test.rs:404:17:404:41 | ExprStmt | true | -| test.rs:404:17:404:40 | ReturnExpr | test.rs:402:28:407:9 | exit BlockExpr (normal) | return | -| test.rs:404:17:404:41 | ExprStmt | test.rs:404:24:404:34 | async_block | | -| test.rs:404:24:404:34 | async_block | test.rs:404:36:404:39 | true | | -| test.rs:404:24:404:40 | CallExpr | test.rs:404:17:404:40 | ReturnExpr | | -| test.rs:404:36:404:39 | true | test.rs:404:24:404:40 | CallExpr | | -| test.rs:406:13:406:15 | foo | test.rs:402:28:407:9 | exit BlockExpr (normal) | | -| test.rs:414:5:416:5 | enter add_two | test.rs:414:22:414:22 | n | | -| test.rs:414:5:416:5 | exit add_two (normal) | test.rs:414:5:416:5 | exit add_two | | -| test.rs:414:22:414:22 | n | test.rs:414:22:414:27 | Param | match | -| test.rs:414:22:414:27 | Param | test.rs:415:9:415:9 | n | | -| test.rs:414:37:416:5 | BlockExpr | test.rs:414:5:416:5 | exit add_two (normal) | | -| test.rs:415:9:415:9 | n | test.rs:415:13:415:13 | 2 | | -| test.rs:415:9:415:13 | ... + ... | test.rs:414:37:416:5 | BlockExpr | | -| test.rs:415:13:415:13 | 2 | test.rs:415:9:415:13 | ... + ... | | -| test.rs:420:5:428:5 | enter const_block_assert | test.rs:423:9:425:9 | ExprStmt | | -| test.rs:420:5:428:5 | exit const_block_assert (normal) | test.rs:420:5:428:5 | exit const_block_assert | | -| test.rs:420:41:428:5 | BlockExpr | test.rs:420:5:428:5 | exit const_block_assert (normal) | | -| test.rs:423:9:425:9 | BlockExpr | test.rs:427:9:427:10 | 42 | | -| test.rs:423:9:425:9 | ExprStmt | test.rs:424:13:424:50 | ExprStmt | | -| test.rs:424:13:424:49 | $crate::panicking::panic_explicit | test.rs:424:13:424:49 | CallExpr | | -| test.rs:424:13:424:49 | BlockExpr | test.rs:424:13:424:49 | MacroExpr | | -| test.rs:424:13:424:49 | BlockExpr | test.rs:424:13:424:49 | exit panic_cold_explicit (normal) | | -| test.rs:424:13:424:49 | BlockExpr | test.rs:424:21:424:48 | IfExpr | | -| test.rs:424:13:424:49 | CallExpr | test.rs:424:13:424:49 | BlockExpr | | -| test.rs:424:13:424:49 | CallExpr | test.rs:424:13:424:49 | BlockExpr | | -| test.rs:424:13:424:49 | ExprStmt | test.rs:424:13:424:49 | MacroStmts | | -| test.rs:424:13:424:49 | ExprStmt | test.rs:424:13:424:49 | panic_cold_explicit | | -| test.rs:424:13:424:49 | MacroExpr | test.rs:423:9:425:9 | BlockExpr | | -| test.rs:424:13:424:49 | MacroExpr | test.rs:424:13:424:49 | BlockExpr | | -| test.rs:424:13:424:49 | MacroStmts | test.rs:424:13:424:49 | panic_cold_explicit | | -| test.rs:424:13:424:49 | enter panic_cold_explicit | test.rs:424:13:424:49 | $crate::panicking::panic_explicit | | -| test.rs:424:13:424:49 | exit panic_cold_explicit (normal) | test.rs:424:13:424:49 | exit panic_cold_explicit | | -| test.rs:424:13:424:49 | panic_cold_explicit | test.rs:424:13:424:49 | CallExpr | | -| test.rs:424:13:424:49 | panic_cold_explicit | test.rs:424:13:424:49 | ExprStmt | | -| test.rs:424:13:424:50 | ExprStmt | test.rs:424:21:424:48 | MacroStmts | | -| test.rs:424:21:424:42 | std::mem::size_of::<...> | test.rs:424:21:424:44 | CallExpr | | -| test.rs:424:21:424:44 | CallExpr | test.rs:424:48:424:48 | 0 | | -| test.rs:424:21:424:48 | ... > ... | test.rs:424:21:424:48 | [boolean(false)] ! ... | true | -| test.rs:424:21:424:48 | ... > ... | test.rs:424:21:424:48 | [boolean(true)] ! ... | false | -| test.rs:424:21:424:48 | BlockExpr | test.rs:424:13:424:49 | MacroExpr | | -| test.rs:424:21:424:48 | IfExpr | test.rs:424:21:424:48 | BlockExpr | | -| test.rs:424:21:424:48 | MacroStmts | test.rs:424:21:424:42 | std::mem::size_of::<...> | | -| test.rs:424:21:424:48 | [boolean(false)] ! ... | test.rs:424:21:424:48 | IfExpr | false | -| test.rs:424:21:424:48 | [boolean(true)] ! ... | test.rs:424:13:424:49 | ExprStmt | true | -| test.rs:424:48:424:48 | 0 | test.rs:424:21:424:48 | ... > ... | | -| test.rs:427:9:427:10 | 42 | test.rs:420:41:428:5 | BlockExpr | | -| test.rs:430:5:439:5 | enter const_block_panic | test.rs:431:9:431:30 | Const | | -| test.rs:430:5:439:5 | exit const_block_panic (normal) | test.rs:430:5:439:5 | exit const_block_panic | | -| test.rs:430:35:439:5 | BlockExpr | test.rs:430:5:439:5 | exit const_block_panic (normal) | | -| test.rs:431:9:431:30 | Const | test.rs:432:9:437:9 | ExprStmt | | -| test.rs:432:9:437:9 | ExprStmt | test.rs:432:12:432:16 | false | | -| test.rs:432:9:437:9 | IfExpr | test.rs:438:9:438:9 | N | | -| test.rs:432:12:432:16 | false | test.rs:432:9:437:9 | IfExpr | false | -| test.rs:435:17:435:24 | $crate::panicking::panic_explicit | test.rs:435:17:435:24 | CallExpr | | -| test.rs:435:17:435:24 | BlockExpr | test.rs:435:17:435:24 | exit panic_cold_explicit (normal) | | -| test.rs:435:17:435:24 | CallExpr | test.rs:435:17:435:24 | BlockExpr | | -| test.rs:435:17:435:24 | enter panic_cold_explicit | test.rs:435:17:435:24 | $crate::panicking::panic_explicit | | -| test.rs:435:17:435:24 | exit panic_cold_explicit (normal) | test.rs:435:17:435:24 | exit panic_cold_explicit | | -| test.rs:438:9:438:9 | N | test.rs:430:35:439:5 | BlockExpr | | -| test.rs:442:1:447:1 | enter dead_code | test.rs:443:5:445:5 | ExprStmt | | -| test.rs:442:1:447:1 | exit dead_code (normal) | test.rs:442:1:447:1 | exit dead_code | | -| test.rs:443:5:445:5 | ExprStmt | test.rs:443:9:443:12 | true | | -| test.rs:443:9:443:12 | true | test.rs:444:9:444:17 | ExprStmt | true | -| test.rs:444:9:444:16 | ReturnExpr | test.rs:442:1:447:1 | exit dead_code (normal) | return | -| test.rs:444:9:444:17 | ExprStmt | test.rs:444:16:444:16 | 0 | | -| test.rs:444:16:444:16 | 0 | test.rs:444:9:444:16 | ReturnExpr | | -| test.rs:449:1:449:16 | enter do_thing | test.rs:449:15:449:16 | BlockExpr | | -| test.rs:449:1:449:16 | exit do_thing (normal) | test.rs:449:1:449:16 | exit do_thing | | -| test.rs:449:15:449:16 | BlockExpr | test.rs:449:1:449:16 | exit do_thing (normal) | | -| test.rs:451:1:453:1 | enter condition_not_met | test.rs:452:5:452:9 | false | | -| test.rs:451:1:453:1 | exit condition_not_met (normal) | test.rs:451:1:453:1 | exit condition_not_met | | -| test.rs:451:32:453:1 | BlockExpr | test.rs:451:1:453:1 | exit condition_not_met (normal) | | -| test.rs:452:5:452:9 | false | test.rs:451:32:453:1 | BlockExpr | | -| test.rs:455:1:455:21 | enter do_next_thing | test.rs:455:20:455:21 | BlockExpr | | -| test.rs:455:1:455:21 | exit do_next_thing (normal) | test.rs:455:1:455:21 | exit do_next_thing | | -| test.rs:455:20:455:21 | BlockExpr | test.rs:455:1:455:21 | exit do_next_thing (normal) | | -| test.rs:457:1:457:21 | enter do_last_thing | test.rs:457:20:457:21 | BlockExpr | | -| test.rs:457:1:457:21 | exit do_last_thing (normal) | test.rs:457:1:457:21 | exit do_last_thing | | -| test.rs:457:20:457:21 | BlockExpr | test.rs:457:1:457:21 | exit do_last_thing (normal) | | -| test.rs:459:1:473:1 | enter labelled_block1 | test.rs:460:5:471:6 | LetStmt | | -| test.rs:459:1:473:1 | exit labelled_block1 (normal) | test.rs:459:1:473:1 | exit labelled_block1 | | -| test.rs:459:29:473:1 | BlockExpr | test.rs:459:1:473:1 | exit labelled_block1 (normal) | | -| test.rs:460:5:471:6 | LetStmt | test.rs:461:9:461:19 | ExprStmt | | -| test.rs:460:9:460:14 | result | test.rs:472:5:472:10 | result | match | -| test.rs:460:18:471:5 | BlockExpr | test.rs:460:9:460:14 | result | | -| test.rs:461:9:461:16 | do_thing | test.rs:461:9:461:18 | CallExpr | | -| test.rs:461:9:461:18 | CallExpr | test.rs:462:9:464:9 | ExprStmt | | -| test.rs:461:9:461:19 | ExprStmt | test.rs:461:9:461:16 | do_thing | | -| test.rs:462:9:464:9 | ExprStmt | test.rs:462:12:462:28 | condition_not_met | | -| test.rs:462:9:464:9 | IfExpr | test.rs:465:9:465:24 | ExprStmt | | -| test.rs:462:12:462:28 | condition_not_met | test.rs:462:12:462:30 | CallExpr | | -| test.rs:462:12:462:30 | CallExpr | test.rs:462:9:464:9 | IfExpr | false | -| test.rs:462:12:462:30 | CallExpr | test.rs:463:13:463:27 | ExprStmt | true | -| test.rs:463:13:463:26 | BreakExpr | test.rs:460:18:471:5 | BlockExpr | break | -| test.rs:463:13:463:27 | ExprStmt | test.rs:463:26:463:26 | 1 | | -| test.rs:463:26:463:26 | 1 | test.rs:463:13:463:26 | BreakExpr | | -| test.rs:465:9:465:21 | do_next_thing | test.rs:465:9:465:23 | CallExpr | | -| test.rs:465:9:465:23 | CallExpr | test.rs:466:9:468:9 | ExprStmt | | -| test.rs:465:9:465:24 | ExprStmt | test.rs:465:9:465:21 | do_next_thing | | -| test.rs:466:9:468:9 | ExprStmt | test.rs:466:12:466:28 | condition_not_met | | -| test.rs:466:9:468:9 | IfExpr | test.rs:469:9:469:24 | ExprStmt | | -| test.rs:466:12:466:28 | condition_not_met | test.rs:466:12:466:30 | CallExpr | | -| test.rs:466:12:466:30 | CallExpr | test.rs:466:9:468:9 | IfExpr | false | -| test.rs:466:12:466:30 | CallExpr | test.rs:467:13:467:27 | ExprStmt | true | -| test.rs:467:13:467:26 | BreakExpr | test.rs:460:18:471:5 | BlockExpr | break | -| test.rs:467:13:467:27 | ExprStmt | test.rs:467:26:467:26 | 2 | | -| test.rs:467:26:467:26 | 2 | test.rs:467:13:467:26 | BreakExpr | | -| test.rs:469:9:469:21 | do_last_thing | test.rs:469:9:469:23 | CallExpr | | -| test.rs:469:9:469:23 | CallExpr | test.rs:470:9:470:9 | 3 | | -| test.rs:469:9:469:24 | ExprStmt | test.rs:469:9:469:21 | do_last_thing | | -| test.rs:470:9:470:9 | 3 | test.rs:460:18:471:5 | BlockExpr | | -| test.rs:472:5:472:10 | result | test.rs:459:29:473:1 | BlockExpr | | -| test.rs:475:1:483:1 | enter labelled_block2 | test.rs:476:5:482:6 | LetStmt | | -| test.rs:475:1:483:1 | exit labelled_block2 (normal) | test.rs:475:1:483:1 | exit labelled_block2 | | -| test.rs:475:22:483:1 | BlockExpr | test.rs:475:1:483:1 | exit labelled_block2 (normal) | | -| test.rs:476:5:482:6 | LetStmt | test.rs:477:9:477:34 | LetStmt | | -| test.rs:476:9:476:14 | result | test.rs:475:22:483:1 | BlockExpr | match | -| test.rs:476:18:482:5 | BlockExpr | test.rs:476:9:476:14 | result | | -| test.rs:477:9:477:34 | LetStmt | test.rs:477:30:477:33 | None | | -| test.rs:477:13:477:13 | x | test.rs:478:9:480:10 | LetStmt | match | -| test.rs:477:30:477:33 | None | test.rs:477:13:477:13 | x | | -| test.rs:478:9:480:10 | LetStmt | test.rs:478:23:478:23 | x | | -| test.rs:478:13:478:19 | TupleStructPat | test.rs:478:18:478:18 | y | match | -| test.rs:478:13:478:19 | TupleStructPat | test.rs:479:13:479:27 | ExprStmt | no-match | -| test.rs:478:18:478:18 | y | test.rs:481:9:481:9 | 0 | match | -| test.rs:478:23:478:23 | x | test.rs:478:13:478:19 | TupleStructPat | | -| test.rs:479:13:479:26 | BreakExpr | test.rs:476:18:482:5 | BlockExpr | break | -| test.rs:479:13:479:27 | ExprStmt | test.rs:479:26:479:26 | 1 | | -| test.rs:479:26:479:26 | 1 | test.rs:479:13:479:26 | BreakExpr | | -| test.rs:481:9:481:9 | 0 | test.rs:476:18:482:5 | BlockExpr | | -| test.rs:485:1:491:1 | enter test_nested_function2 | test.rs:486:5:486:18 | LetStmt | | -| test.rs:485:1:491:1 | exit test_nested_function2 (normal) | test.rs:485:1:491:1 | exit test_nested_function2 | | -| test.rs:485:28:491:1 | BlockExpr | test.rs:485:1:491:1 | exit test_nested_function2 (normal) | | -| test.rs:486:5:486:18 | LetStmt | test.rs:486:17:486:17 | 0 | | -| test.rs:486:9:486:13 | x | test.rs:487:5:489:5 | nested | match | -| test.rs:486:17:486:17 | 0 | test.rs:486:9:486:13 | x | | -| test.rs:487:5:489:5 | enter nested | test.rs:487:15:487:15 | x | | -| test.rs:487:5:489:5 | exit nested (normal) | test.rs:487:5:489:5 | exit nested | | -| test.rs:487:5:489:5 | nested | test.rs:490:5:490:19 | ExprStmt | | -| test.rs:487:15:487:15 | x | test.rs:487:15:487:25 | Param | match | -| test.rs:487:15:487:25 | Param | test.rs:488:9:488:16 | ExprStmt | | -| test.rs:487:28:489:5 | BlockExpr | test.rs:487:5:489:5 | exit nested (normal) | | -| test.rs:488:9:488:10 | * ... | test.rs:488:15:488:15 | 1 | | -| test.rs:488:9:488:15 | ... += ... | test.rs:487:28:489:5 | BlockExpr | | -| test.rs:488:9:488:16 | ExprStmt | test.rs:488:10:488:10 | x | | -| test.rs:488:10:488:10 | x | test.rs:488:9:488:10 | * ... | | -| test.rs:488:15:488:15 | 1 | test.rs:488:9:488:15 | ... += ... | | -| test.rs:490:5:490:10 | nested | test.rs:490:17:490:17 | x | | -| test.rs:490:5:490:18 | CallExpr | test.rs:485:28:491:1 | BlockExpr | | -| test.rs:490:5:490:19 | ExprStmt | test.rs:490:5:490:10 | nested | | -| test.rs:490:12:490:17 | RefExpr | test.rs:490:5:490:18 | CallExpr | | -| test.rs:490:17:490:17 | x | test.rs:490:12:490:17 | RefExpr | | -| test.rs:502:5:504:5 | enter new | test.rs:502:12:502:12 | a | | -| test.rs:502:5:504:5 | exit new (normal) | test.rs:502:5:504:5 | exit new | | -| test.rs:502:12:502:12 | a | test.rs:502:12:502:17 | Param | match | -| test.rs:502:12:502:17 | Param | test.rs:503:23:503:23 | a | | -| test.rs:502:28:504:5 | BlockExpr | test.rs:502:5:504:5 | exit new (normal) | | -| test.rs:503:9:503:25 | RecordExpr | test.rs:502:28:504:5 | BlockExpr | | -| test.rs:503:23:503:23 | a | test.rs:503:9:503:25 | RecordExpr | | -| test.rs:506:5:508:5 | enter negated | test.rs:506:16:506:19 | self | | -| test.rs:506:5:508:5 | exit negated (normal) | test.rs:506:5:508:5 | exit negated | | -| test.rs:506:16:506:19 | SelfParam | test.rs:507:23:507:26 | self | | -| test.rs:506:16:506:19 | self | test.rs:506:16:506:19 | SelfParam | | -| test.rs:506:30:508:5 | BlockExpr | test.rs:506:5:508:5 | exit negated (normal) | | -| test.rs:507:9:507:30 | RecordExpr | test.rs:506:30:508:5 | BlockExpr | | -| test.rs:507:23:507:26 | self | test.rs:507:23:507:28 | FieldExpr | | -| test.rs:507:23:507:28 | FieldExpr | test.rs:507:9:507:30 | RecordExpr | | -| test.rs:510:5:512:5 | enter multifly_add | test.rs:510:26:510:29 | self | | -| test.rs:510:5:512:5 | exit multifly_add (normal) | test.rs:510:5:512:5 | exit multifly_add | | -| test.rs:510:21:510:29 | SelfParam | test.rs:510:32:510:32 | a | | -| test.rs:510:26:510:29 | self | test.rs:510:21:510:29 | SelfParam | | -| test.rs:510:32:510:32 | a | test.rs:510:32:510:37 | Param | match | -| test.rs:510:32:510:37 | Param | test.rs:510:40:510:40 | b | | -| test.rs:510:40:510:40 | b | test.rs:510:40:510:45 | Param | match | -| test.rs:510:40:510:45 | Param | test.rs:511:9:511:34 | ExprStmt | | -| test.rs:510:48:512:5 | BlockExpr | test.rs:510:5:512:5 | exit multifly_add (normal) | | -| test.rs:511:9:511:12 | self | test.rs:511:9:511:14 | FieldExpr | | -| test.rs:511:9:511:14 | FieldExpr | test.rs:511:19:511:22 | self | | -| test.rs:511:9:511:33 | ... = ... | test.rs:510:48:512:5 | BlockExpr | | -| test.rs:511:9:511:34 | ExprStmt | test.rs:511:9:511:12 | self | | -| test.rs:511:18:511:33 | ... + ... | test.rs:511:9:511:33 | ... = ... | | -| test.rs:511:19:511:22 | self | test.rs:511:19:511:24 | FieldExpr | | -| test.rs:511:19:511:24 | FieldExpr | test.rs:511:28:511:28 | a | | -| test.rs:511:19:511:28 | ... * ... | test.rs:511:33:511:33 | b | | -| test.rs:511:28:511:28 | a | test.rs:511:19:511:28 | ... * ... | | -| test.rs:511:33:511:33 | b | test.rs:511:18:511:33 | ... + ... | | +| test.rs:281:5:286:5 | enter test_and_true | test.rs:281:22:281:22 | a | | +| test.rs:281:5:286:5 | exit test_and_true (normal) | test.rs:281:5:286:5 | exit test_and_true | | +| test.rs:281:22:281:22 | a | test.rs:281:22:281:28 | Param | match | +| test.rs:281:22:281:28 | Param | test.rs:282:9:284:9 | ExprStmt | | +| test.rs:281:38:286:5 | BlockExpr | test.rs:281:5:286:5 | exit test_and_true (normal) | | +| test.rs:282:9:284:9 | ExprStmt | test.rs:282:13:282:13 | a | | +| test.rs:282:9:284:9 | IfExpr | test.rs:285:9:285:9 | 0 | | +| test.rs:282:13:282:13 | a | test.rs:282:13:282:21 | [boolean(false)] ... && ... | false | +| test.rs:282:13:282:13 | a | test.rs:282:18:282:21 | true | true | +| test.rs:282:13:282:21 | [boolean(false)] ... && ... | test.rs:282:9:284:9 | IfExpr | false | +| test.rs:282:13:282:21 | [boolean(true)] ... && ... | test.rs:283:13:283:21 | ExprStmt | true | +| test.rs:282:18:282:21 | true | test.rs:282:13:282:21 | [boolean(true)] ... && ... | true | +| test.rs:283:13:283:20 | ReturnExpr | test.rs:281:5:286:5 | exit test_and_true (normal) | return | +| test.rs:283:13:283:21 | ExprStmt | test.rs:283:20:283:20 | 1 | | +| test.rs:283:20:283:20 | 1 | test.rs:283:13:283:20 | ReturnExpr | | +| test.rs:285:9:285:9 | 0 | test.rs:281:38:286:5 | BlockExpr | | +| test.rs:292:5:294:5 | enter test_question_mark_operator_1 | test.rs:292:38:292:38 | s | | +| test.rs:292:5:294:5 | exit test_question_mark_operator_1 (normal) | test.rs:292:5:294:5 | exit test_question_mark_operator_1 | | +| test.rs:292:38:292:38 | s | test.rs:292:38:292:44 | Param | match | +| test.rs:292:38:292:44 | Param | test.rs:293:9:293:10 | Ok | | +| test.rs:292:87:294:5 | BlockExpr | test.rs:292:5:294:5 | exit test_question_mark_operator_1 (normal) | | +| test.rs:293:9:293:10 | Ok | test.rs:293:12:293:12 | s | | +| test.rs:293:9:293:33 | CallExpr | test.rs:292:87:294:5 | BlockExpr | | +| test.rs:293:12:293:12 | s | test.rs:293:12:293:27 | ... .parse(...) | | +| test.rs:293:12:293:27 | ... .parse(...) | test.rs:293:12:293:28 | TryExpr | | +| test.rs:293:12:293:28 | TryExpr | test.rs:292:5:294:5 | exit test_question_mark_operator_1 (normal) | return | +| test.rs:293:12:293:28 | TryExpr | test.rs:293:32:293:32 | 4 | match | +| test.rs:293:12:293:32 | ... + ... | test.rs:293:9:293:33 | CallExpr | | +| test.rs:293:32:293:32 | 4 | test.rs:293:12:293:32 | ... + ... | | +| test.rs:296:5:301:5 | enter test_question_mark_operator_2 | test.rs:296:38:296:38 | b | | +| test.rs:296:5:301:5 | exit test_question_mark_operator_2 (normal) | test.rs:296:5:301:5 | exit test_question_mark_operator_2 | | +| test.rs:296:38:296:38 | b | test.rs:296:38:296:52 | Param | match | +| test.rs:296:38:296:52 | Param | test.rs:297:15:297:15 | b | | +| test.rs:296:71:301:5 | BlockExpr | test.rs:296:5:301:5 | exit test_question_mark_operator_2 (normal) | | +| test.rs:297:9:300:9 | MatchExpr | test.rs:296:71:301:5 | BlockExpr | | +| test.rs:297:15:297:15 | b | test.rs:297:15:297:16 | TryExpr | | +| test.rs:297:15:297:16 | TryExpr | test.rs:296:5:301:5 | exit test_question_mark_operator_2 (normal) | return | +| test.rs:297:15:297:16 | TryExpr | test.rs:298:13:298:16 | true | match | +| test.rs:298:13:298:16 | LiteralPat | test.rs:298:21:298:24 | Some | match | +| test.rs:298:13:298:16 | LiteralPat | test.rs:299:13:299:17 | false | no-match | +| test.rs:298:13:298:16 | true | test.rs:298:13:298:16 | LiteralPat | | +| test.rs:298:21:298:24 | Some | test.rs:298:26:298:30 | false | | +| test.rs:298:21:298:31 | CallExpr | test.rs:297:9:300:9 | MatchExpr | | +| test.rs:298:26:298:30 | false | test.rs:298:21:298:31 | CallExpr | | +| test.rs:299:13:299:17 | LiteralPat | test.rs:299:22:299:25 | Some | match | +| test.rs:299:13:299:17 | false | test.rs:299:13:299:17 | LiteralPat | | +| test.rs:299:22:299:25 | Some | test.rs:299:27:299:30 | true | | +| test.rs:299:22:299:31 | CallExpr | test.rs:297:9:300:9 | MatchExpr | | +| test.rs:299:27:299:30 | true | test.rs:299:22:299:31 | CallExpr | | +| test.rs:307:5:313:5 | enter test_match | test.rs:307:19:307:29 | maybe_digit | | +| test.rs:307:5:313:5 | exit test_match (normal) | test.rs:307:5:313:5 | exit test_match | | +| test.rs:307:19:307:29 | maybe_digit | test.rs:307:19:307:42 | Param | match | +| test.rs:307:19:307:42 | Param | test.rs:308:15:308:25 | maybe_digit | | +| test.rs:307:52:313:5 | BlockExpr | test.rs:307:5:313:5 | exit test_match (normal) | | +| test.rs:308:9:312:9 | MatchExpr | test.rs:307:52:313:5 | BlockExpr | | +| test.rs:308:15:308:25 | maybe_digit | test.rs:309:13:309:27 | TupleStructPat | | +| test.rs:309:13:309:27 | TupleStructPat | test.rs:309:26:309:26 | x | match | +| test.rs:309:13:309:27 | TupleStructPat | test.rs:310:13:310:27 | TupleStructPat | no-match | +| test.rs:309:26:309:26 | x | test.rs:309:32:309:32 | x | match | +| test.rs:309:32:309:32 | x | test.rs:309:36:309:37 | 10 | | +| test.rs:309:32:309:37 | ... < ... | test.rs:309:42:309:42 | x | true | +| test.rs:309:32:309:37 | ... < ... | test.rs:310:13:310:27 | TupleStructPat | false | +| test.rs:309:36:309:37 | 10 | test.rs:309:32:309:37 | ... < ... | | +| test.rs:309:42:309:42 | x | test.rs:309:46:309:46 | 5 | | +| test.rs:309:42:309:46 | ... + ... | test.rs:308:9:312:9 | MatchExpr | | +| test.rs:309:46:309:46 | 5 | test.rs:309:42:309:46 | ... + ... | | +| test.rs:310:13:310:27 | TupleStructPat | test.rs:310:26:310:26 | x | match | +| test.rs:310:13:310:27 | TupleStructPat | test.rs:311:13:311:24 | PathPat | no-match | +| test.rs:310:26:310:26 | x | test.rs:310:32:310:32 | x | match | +| test.rs:310:32:310:32 | x | test.rs:308:9:312:9 | MatchExpr | | +| test.rs:311:13:311:24 | PathPat | test.rs:311:29:311:29 | 5 | match | +| test.rs:311:29:311:29 | 5 | test.rs:308:9:312:9 | MatchExpr | | +| test.rs:315:5:324:5 | enter test_match_with_return_in_scrutinee | test.rs:315:44:315:54 | maybe_digit | | +| test.rs:315:5:324:5 | exit test_match_with_return_in_scrutinee (normal) | test.rs:315:5:324:5 | exit test_match_with_return_in_scrutinee | | +| test.rs:315:44:315:54 | maybe_digit | test.rs:315:44:315:67 | Param | match | +| test.rs:315:44:315:67 | Param | test.rs:316:19:316:29 | maybe_digit | | +| test.rs:315:77:324:5 | BlockExpr | test.rs:315:5:324:5 | exit test_match_with_return_in_scrutinee (normal) | | +| test.rs:316:9:323:9 | MatchExpr | test.rs:315:77:324:5 | BlockExpr | | +| test.rs:316:16:320:9 | IfExpr | test.rs:321:13:321:27 | TupleStructPat | | +| test.rs:316:19:316:29 | maybe_digit | test.rs:316:34:316:37 | Some | | +| test.rs:316:19:316:40 | ... == ... | test.rs:317:13:317:21 | ExprStmt | true | +| test.rs:316:19:316:40 | ... == ... | test.rs:319:13:319:23 | maybe_digit | false | +| test.rs:316:34:316:37 | Some | test.rs:316:39:316:39 | 3 | | +| test.rs:316:34:316:40 | CallExpr | test.rs:316:19:316:40 | ... == ... | | +| test.rs:316:39:316:39 | 3 | test.rs:316:34:316:40 | CallExpr | | +| test.rs:317:13:317:20 | ReturnExpr | test.rs:315:5:324:5 | exit test_match_with_return_in_scrutinee (normal) | return | +| test.rs:317:13:317:21 | ExprStmt | test.rs:317:20:317:20 | 3 | | +| test.rs:317:20:317:20 | 3 | test.rs:317:13:317:20 | ReturnExpr | | +| test.rs:318:16:320:9 | BlockExpr | test.rs:316:16:320:9 | IfExpr | | +| test.rs:319:13:319:23 | maybe_digit | test.rs:318:16:320:9 | BlockExpr | | +| test.rs:321:13:321:27 | TupleStructPat | test.rs:321:26:321:26 | x | match | +| test.rs:321:13:321:27 | TupleStructPat | test.rs:322:13:322:24 | PathPat | no-match | +| test.rs:321:26:321:26 | x | test.rs:321:32:321:32 | x | match | +| test.rs:321:32:321:32 | x | test.rs:321:36:321:36 | 5 | | +| test.rs:321:32:321:36 | ... + ... | test.rs:316:9:323:9 | MatchExpr | | +| test.rs:321:36:321:36 | 5 | test.rs:321:32:321:36 | ... + ... | | +| test.rs:322:13:322:24 | PathPat | test.rs:322:29:322:29 | 5 | match | +| test.rs:322:29:322:29 | 5 | test.rs:316:9:323:9 | MatchExpr | | +| test.rs:326:5:331:5 | enter test_match_and | test.rs:326:23:326:26 | cond | | +| test.rs:326:5:331:5 | exit test_match_and (normal) | test.rs:326:5:331:5 | exit test_match_and | | +| test.rs:326:23:326:26 | cond | test.rs:326:23:326:32 | Param | match | +| test.rs:326:23:326:32 | Param | test.rs:326:35:326:35 | r | | +| test.rs:326:35:326:35 | r | test.rs:326:35:326:49 | Param | match | +| test.rs:326:35:326:49 | Param | test.rs:327:16:327:16 | r | | +| test.rs:326:60:331:5 | BlockExpr | test.rs:326:5:331:5 | exit test_match_and (normal) | | +| test.rs:327:9:330:18 | ... && ... | test.rs:326:60:331:5 | BlockExpr | | +| test.rs:327:10:330:9 | [boolean(false)] MatchExpr | test.rs:327:9:330:18 | ... && ... | false | +| test.rs:327:10:330:9 | [boolean(true)] MatchExpr | test.rs:330:15:330:18 | cond | true | +| test.rs:327:16:327:16 | r | test.rs:328:13:328:19 | TupleStructPat | | +| test.rs:328:13:328:19 | TupleStructPat | test.rs:328:18:328:18 | a | match | +| test.rs:328:13:328:19 | TupleStructPat | test.rs:329:13:329:13 | WildcardPat | no-match | +| test.rs:328:18:328:18 | a | test.rs:328:24:328:24 | a | match | +| test.rs:328:24:328:24 | a | test.rs:327:10:330:9 | [boolean(false)] MatchExpr | false | +| test.rs:328:24:328:24 | a | test.rs:327:10:330:9 | [boolean(true)] MatchExpr | true | +| test.rs:329:13:329:13 | WildcardPat | test.rs:329:18:329:22 | false | match | +| test.rs:329:18:329:22 | false | test.rs:327:10:330:9 | [boolean(false)] MatchExpr | false | +| test.rs:330:15:330:18 | cond | test.rs:327:9:330:18 | ... && ... | | +| test.rs:333:5:338:5 | enter test_match_with_no_arms | test.rs:333:35:333:35 | r | | +| test.rs:333:5:338:5 | exit test_match_with_no_arms (normal) | test.rs:333:5:338:5 | exit test_match_with_no_arms | | +| test.rs:333:35:333:35 | r | test.rs:333:35:333:58 | Param | match | +| test.rs:333:35:333:58 | Param | test.rs:334:15:334:15 | r | | +| test.rs:333:66:338:5 | BlockExpr | test.rs:333:5:338:5 | exit test_match_with_no_arms (normal) | | +| test.rs:334:9:337:9 | MatchExpr | test.rs:333:66:338:5 | BlockExpr | | +| test.rs:334:15:334:15 | r | test.rs:335:13:335:21 | TupleStructPat | | +| test.rs:335:13:335:21 | TupleStructPat | test.rs:335:16:335:20 | value | match | +| test.rs:335:13:335:21 | TupleStructPat | test.rs:336:13:336:22 | TupleStructPat | no-match | +| test.rs:335:16:335:20 | value | test.rs:335:26:335:30 | value | match | +| test.rs:335:26:335:30 | value | test.rs:334:9:337:9 | MatchExpr | | +| test.rs:336:13:336:22 | TupleStructPat | test.rs:336:17:336:21 | never | match | +| test.rs:336:17:336:21 | never | test.rs:336:33:336:37 | never | match | +| test.rs:336:27:336:40 | MatchExpr | test.rs:334:9:337:9 | MatchExpr | | +| test.rs:336:33:336:37 | never | test.rs:336:27:336:40 | MatchExpr | | +| test.rs:343:5:346:5 | enter test_let_match | test.rs:343:23:343:23 | a | | +| test.rs:343:5:346:5 | exit test_let_match (normal) | test.rs:343:5:346:5 | exit test_let_match | | +| test.rs:343:23:343:23 | a | test.rs:343:23:343:36 | Param | match | +| test.rs:343:23:343:36 | Param | test.rs:344:9:344:57 | LetStmt | | +| test.rs:343:46:346:5 | BlockExpr | test.rs:343:5:346:5 | exit test_let_match (normal) | | +| test.rs:344:9:344:57 | LetStmt | test.rs:344:23:344:23 | a | | +| test.rs:344:13:344:19 | TupleStructPat | test.rs:344:18:344:18 | n | match | +| test.rs:344:13:344:19 | TupleStructPat | test.rs:344:39:344:53 | MacroStmts | no-match | +| test.rs:344:18:344:18 | n | test.rs:345:9:345:9 | n | match | +| test.rs:344:23:344:23 | a | test.rs:344:13:344:19 | TupleStructPat | | +| test.rs:344:32:344:54 | $crate::panicking::panic_fmt | test.rs:344:39:344:53 | "Expected some" | | +| test.rs:344:32:344:54 | MacroExpr | test.rs:344:30:344:56 | BlockExpr | | +| test.rs:344:39:344:53 | "Expected some" | test.rs:344:39:344:53 | FormatArgsExpr | | +| test.rs:344:39:344:53 | BlockExpr | test.rs:344:39:344:53 | MacroExpr | | +| test.rs:344:39:344:53 | CallExpr | test.rs:344:39:344:53 | BlockExpr | | +| test.rs:344:39:344:53 | ExprStmt | test.rs:344:32:344:54 | $crate::panicking::panic_fmt | | +| test.rs:344:39:344:53 | FormatArgsExpr | test.rs:344:39:344:53 | MacroExpr | | +| test.rs:344:39:344:53 | MacroExpr | test.rs:344:32:344:54 | MacroExpr | | +| test.rs:344:39:344:53 | MacroExpr | test.rs:344:39:344:53 | CallExpr | | +| test.rs:344:39:344:53 | MacroStmts | test.rs:344:39:344:53 | ExprStmt | | +| test.rs:344:39:344:53 | MacroStmts | test.rs:344:39:344:53 | MacroStmts | | +| test.rs:345:9:345:9 | n | test.rs:343:46:346:5 | BlockExpr | | +| test.rs:348:5:354:5 | enter test_let_with_return | test.rs:348:29:348:29 | m | | +| test.rs:348:5:354:5 | exit test_let_with_return (normal) | test.rs:348:5:354:5 | exit test_let_with_return | | +| test.rs:348:29:348:29 | m | test.rs:348:29:348:42 | Param | match | +| test.rs:348:29:348:42 | Param | test.rs:349:9:352:10 | LetStmt | | +| test.rs:348:53:354:5 | BlockExpr | test.rs:348:5:354:5 | exit test_let_with_return (normal) | | +| test.rs:349:9:352:10 | LetStmt | test.rs:349:25:349:25 | m | | +| test.rs:349:13:349:15 | ret | test.rs:353:9:353:12 | true | match | +| test.rs:349:19:352:9 | MatchExpr | test.rs:349:13:349:15 | ret | | +| test.rs:349:25:349:25 | m | test.rs:350:13:350:21 | TupleStructPat | | +| test.rs:350:13:350:21 | TupleStructPat | test.rs:350:18:350:20 | ret | match | +| test.rs:350:13:350:21 | TupleStructPat | test.rs:351:13:351:16 | None | no-match | +| test.rs:350:18:350:20 | ret | test.rs:350:26:350:28 | ret | match | +| test.rs:350:26:350:28 | ret | test.rs:349:19:352:9 | MatchExpr | | +| test.rs:351:13:351:16 | None | test.rs:351:28:351:32 | false | match | +| test.rs:351:21:351:32 | ReturnExpr | test.rs:348:5:354:5 | exit test_let_with_return (normal) | return | +| test.rs:351:28:351:32 | false | test.rs:351:21:351:32 | ReturnExpr | | +| test.rs:353:9:353:12 | true | test.rs:348:53:354:5 | BlockExpr | | +| test.rs:359:5:362:5 | enter empty_tuple_pattern | test.rs:359:28:359:31 | unit | | +| test.rs:359:5:362:5 | exit empty_tuple_pattern (normal) | test.rs:359:5:362:5 | exit empty_tuple_pattern | | +| test.rs:359:28:359:31 | unit | test.rs:359:28:359:35 | Param | match | +| test.rs:359:28:359:35 | Param | test.rs:360:9:360:22 | LetStmt | | +| test.rs:360:9:360:22 | LetStmt | test.rs:360:18:360:21 | unit | | +| test.rs:360:13:360:14 | TuplePat | test.rs:361:9:361:15 | ExprStmt | match | +| test.rs:360:18:360:21 | unit | test.rs:360:13:360:14 | TuplePat | | +| test.rs:361:9:361:14 | ReturnExpr | test.rs:359:5:362:5 | exit empty_tuple_pattern (normal) | return | +| test.rs:361:9:361:15 | ExprStmt | test.rs:361:9:361:14 | ReturnExpr | | +| test.rs:366:5:370:5 | enter empty_struct_pattern | test.rs:366:29:366:30 | st | | +| test.rs:366:5:370:5 | exit empty_struct_pattern (normal) | test.rs:366:5:370:5 | exit empty_struct_pattern | | +| test.rs:366:29:366:30 | st | test.rs:366:29:366:40 | Param | match | +| test.rs:366:29:366:40 | Param | test.rs:367:15:367:16 | st | | +| test.rs:366:50:370:5 | BlockExpr | test.rs:366:5:370:5 | exit empty_struct_pattern (normal) | | +| test.rs:367:9:369:9 | MatchExpr | test.rs:366:50:370:5 | BlockExpr | | +| test.rs:367:15:367:16 | st | test.rs:368:13:368:27 | RecordPat | | +| test.rs:368:13:368:27 | RecordPat | test.rs:368:24:368:25 | RestPat | match | +| test.rs:368:24:368:25 | RestPat | test.rs:368:32:368:32 | 1 | match | +| test.rs:368:32:368:32 | 1 | test.rs:367:9:369:9 | MatchExpr | | +| test.rs:372:5:379:5 | enter range_pattern | test.rs:373:15:373:16 | 42 | | +| test.rs:372:5:379:5 | exit range_pattern (normal) | test.rs:372:5:379:5 | exit range_pattern | | +| test.rs:372:31:379:5 | BlockExpr | test.rs:372:5:379:5 | exit range_pattern (normal) | | +| test.rs:373:9:378:9 | MatchExpr | test.rs:372:31:379:5 | BlockExpr | | +| test.rs:373:15:373:16 | 42 | test.rs:374:13:374:15 | RangePat | | +| test.rs:374:13:374:15 | RangePat | test.rs:374:15:374:15 | 0 | match | +| test.rs:374:13:374:15 | RangePat | test.rs:375:13:375:16 | RangePat | no-match | +| test.rs:374:15:374:15 | 0 | test.rs:374:15:374:15 | LiteralPat | | +| test.rs:374:15:374:15 | LiteralPat | test.rs:374:20:374:20 | 1 | match | +| test.rs:374:15:374:15 | LiteralPat | test.rs:375:13:375:16 | RangePat | no-match | +| test.rs:374:20:374:20 | 1 | test.rs:373:9:378:9 | MatchExpr | | +| test.rs:375:13:375:13 | 1 | test.rs:375:13:375:13 | LiteralPat | | +| test.rs:375:13:375:13 | LiteralPat | test.rs:375:16:375:16 | 2 | match | +| test.rs:375:13:375:13 | LiteralPat | test.rs:376:13:376:15 | RangePat | no-match | +| test.rs:375:13:375:16 | RangePat | test.rs:375:13:375:13 | 1 | match | +| test.rs:375:13:375:16 | RangePat | test.rs:376:13:376:15 | RangePat | no-match | +| test.rs:375:16:375:16 | 2 | test.rs:375:16:375:16 | LiteralPat | | +| test.rs:375:16:375:16 | LiteralPat | test.rs:375:21:375:21 | 2 | match | +| test.rs:375:16:375:16 | LiteralPat | test.rs:376:13:376:15 | RangePat | no-match | +| test.rs:375:21:375:21 | 2 | test.rs:373:9:378:9 | MatchExpr | | +| test.rs:376:13:376:13 | 5 | test.rs:376:13:376:13 | LiteralPat | | +| test.rs:376:13:376:13 | LiteralPat | test.rs:376:20:376:20 | 3 | match | +| test.rs:376:13:376:13 | LiteralPat | test.rs:377:13:377:13 | WildcardPat | no-match | +| test.rs:376:13:376:15 | RangePat | test.rs:376:13:376:13 | 5 | match | +| test.rs:376:13:376:15 | RangePat | test.rs:377:13:377:13 | WildcardPat | no-match | +| test.rs:376:20:376:20 | 3 | test.rs:373:9:378:9 | MatchExpr | | +| test.rs:377:13:377:13 | WildcardPat | test.rs:377:18:377:18 | 4 | match | +| test.rs:377:18:377:18 | 4 | test.rs:373:9:378:9 | MatchExpr | | +| test.rs:383:5:388:5 | enter test_infinite_loop | test.rs:384:9:386:9 | ExprStmt | | +| test.rs:384:9:386:9 | ExprStmt | test.rs:385:13:385:14 | TupleExpr | | +| test.rs:384:14:386:9 | BlockExpr | test.rs:385:13:385:14 | TupleExpr | | +| test.rs:385:13:385:14 | TupleExpr | test.rs:384:14:386:9 | BlockExpr | | +| test.rs:392:5:394:5 | enter say_hello | test.rs:393:9:393:34 | ExprStmt | | +| test.rs:392:5:394:5 | exit say_hello (normal) | test.rs:392:5:394:5 | exit say_hello | | +| test.rs:392:26:394:5 | BlockExpr | test.rs:392:5:394:5 | exit say_hello (normal) | | +| test.rs:393:9:393:33 | $crate::io::_print | test.rs:393:18:393:32 | "hello, world!\\n" | | +| test.rs:393:9:393:33 | MacroExpr | test.rs:392:26:394:5 | BlockExpr | | +| test.rs:393:9:393:34 | ExprStmt | test.rs:393:18:393:32 | MacroStmts | | +| test.rs:393:18:393:32 | "hello, world!\\n" | test.rs:393:18:393:32 | FormatArgsExpr | | +| test.rs:393:18:393:32 | BlockExpr | test.rs:393:9:393:33 | MacroExpr | | +| test.rs:393:18:393:32 | CallExpr | test.rs:393:18:393:32 | BlockExpr | | +| test.rs:393:18:393:32 | ExprStmt | test.rs:393:9:393:33 | $crate::io::_print | | +| test.rs:393:18:393:32 | FormatArgsExpr | test.rs:393:18:393:32 | MacroExpr | | +| test.rs:393:18:393:32 | MacroExpr | test.rs:393:18:393:32 | CallExpr | | +| test.rs:393:18:393:32 | MacroStmts | test.rs:393:18:393:32 | ExprStmt | | +| test.rs:396:5:415:5 | enter async_block | test.rs:396:26:396:26 | b | | +| test.rs:396:5:415:5 | exit async_block (normal) | test.rs:396:5:415:5 | exit async_block | | +| test.rs:396:26:396:26 | b | test.rs:396:26:396:32 | Param | match | +| test.rs:396:26:396:32 | Param | test.rs:397:9:399:10 | LetStmt | | +| test.rs:396:35:415:5 | BlockExpr | test.rs:396:5:415:5 | exit async_block (normal) | | +| test.rs:397:9:399:10 | LetStmt | test.rs:397:26:399:9 | BlockExpr | | +| test.rs:397:13:397:22 | say_godbye | test.rs:400:9:402:10 | LetStmt | match | +| test.rs:397:26:399:9 | BlockExpr | test.rs:397:13:397:22 | say_godbye | | +| test.rs:397:26:399:9 | enter BlockExpr | test.rs:398:13:398:42 | ExprStmt | | +| test.rs:397:26:399:9 | exit BlockExpr (normal) | test.rs:397:26:399:9 | exit BlockExpr | | +| test.rs:398:13:398:41 | $crate::io::_print | test.rs:398:22:398:40 | "godbye, everyone!\\n" | | +| test.rs:398:13:398:41 | MacroExpr | test.rs:397:26:399:9 | exit BlockExpr (normal) | | +| test.rs:398:13:398:42 | ExprStmt | test.rs:398:22:398:40 | MacroStmts | | +| test.rs:398:22:398:40 | "godbye, everyone!\\n" | test.rs:398:22:398:40 | FormatArgsExpr | | +| test.rs:398:22:398:40 | BlockExpr | test.rs:398:13:398:41 | MacroExpr | | +| test.rs:398:22:398:40 | CallExpr | test.rs:398:22:398:40 | BlockExpr | | +| test.rs:398:22:398:40 | ExprStmt | test.rs:398:13:398:41 | $crate::io::_print | | +| test.rs:398:22:398:40 | FormatArgsExpr | test.rs:398:22:398:40 | MacroExpr | | +| test.rs:398:22:398:40 | MacroExpr | test.rs:398:22:398:40 | CallExpr | | +| test.rs:398:22:398:40 | MacroStmts | test.rs:398:22:398:40 | ExprStmt | | +| test.rs:400:9:402:10 | LetStmt | test.rs:400:31:402:9 | BlockExpr | | +| test.rs:400:13:400:27 | say_how_are_you | test.rs:403:9:403:28 | LetStmt | match | +| test.rs:400:31:402:9 | BlockExpr | test.rs:400:13:400:27 | say_how_are_you | | +| test.rs:400:31:402:9 | enter BlockExpr | test.rs:401:13:401:37 | ExprStmt | | +| test.rs:400:31:402:9 | exit BlockExpr (normal) | test.rs:400:31:402:9 | exit BlockExpr | | +| test.rs:401:13:401:36 | $crate::io::_print | test.rs:401:22:401:35 | "how are you?\\n" | | +| test.rs:401:13:401:36 | MacroExpr | test.rs:400:31:402:9 | exit BlockExpr (normal) | | +| test.rs:401:13:401:37 | ExprStmt | test.rs:401:22:401:35 | MacroStmts | | +| test.rs:401:22:401:35 | "how are you?\\n" | test.rs:401:22:401:35 | FormatArgsExpr | | +| test.rs:401:22:401:35 | BlockExpr | test.rs:401:13:401:36 | MacroExpr | | +| test.rs:401:22:401:35 | CallExpr | test.rs:401:22:401:35 | BlockExpr | | +| test.rs:401:22:401:35 | ExprStmt | test.rs:401:13:401:36 | $crate::io::_print | | +| test.rs:401:22:401:35 | FormatArgsExpr | test.rs:401:22:401:35 | MacroExpr | | +| test.rs:401:22:401:35 | MacroExpr | test.rs:401:22:401:35 | CallExpr | | +| test.rs:401:22:401:35 | MacroStmts | test.rs:401:22:401:35 | ExprStmt | | +| test.rs:403:9:403:28 | LetStmt | test.rs:403:20:403:27 | BlockExpr | | +| test.rs:403:13:403:16 | noop | test.rs:404:9:404:26 | ExprStmt | match | +| test.rs:403:20:403:27 | BlockExpr | test.rs:403:13:403:16 | noop | | +| test.rs:404:9:404:17 | say_hello | test.rs:404:9:404:19 | CallExpr | | +| test.rs:404:9:404:19 | CallExpr | test.rs:404:9:404:25 | AwaitExpr | | +| test.rs:404:9:404:25 | AwaitExpr | test.rs:405:9:405:30 | ExprStmt | | +| test.rs:404:9:404:26 | ExprStmt | test.rs:404:9:404:17 | say_hello | | +| test.rs:405:9:405:23 | say_how_are_you | test.rs:405:9:405:29 | AwaitExpr | | +| test.rs:405:9:405:29 | AwaitExpr | test.rs:406:9:406:25 | ExprStmt | | +| test.rs:405:9:405:30 | ExprStmt | test.rs:405:9:405:23 | say_how_are_you | | +| test.rs:406:9:406:18 | say_godbye | test.rs:406:9:406:24 | AwaitExpr | | +| test.rs:406:9:406:24 | AwaitExpr | test.rs:407:9:407:19 | ExprStmt | | +| test.rs:406:9:406:25 | ExprStmt | test.rs:406:9:406:18 | say_godbye | | +| test.rs:407:9:407:12 | noop | test.rs:407:9:407:18 | AwaitExpr | | +| test.rs:407:9:407:18 | AwaitExpr | test.rs:409:9:414:10 | LetStmt | | +| test.rs:407:9:407:19 | ExprStmt | test.rs:407:9:407:12 | noop | | +| test.rs:409:9:414:10 | LetStmt | test.rs:409:22:414:9 | ClosureExpr | | +| test.rs:409:13:409:18 | lambda | test.rs:396:35:415:5 | BlockExpr | match | +| test.rs:409:22:414:9 | ClosureExpr | test.rs:409:13:409:18 | lambda | | +| test.rs:409:22:414:9 | enter ClosureExpr | test.rs:409:23:409:25 | foo | | +| test.rs:409:22:414:9 | exit ClosureExpr (normal) | test.rs:409:22:414:9 | exit ClosureExpr | | +| test.rs:409:23:409:25 | Param | test.rs:409:28:414:9 | BlockExpr | | +| test.rs:409:23:409:25 | foo | test.rs:409:23:409:25 | Param | match | +| test.rs:409:28:414:9 | BlockExpr | test.rs:409:22:414:9 | exit ClosureExpr (normal) | | +| test.rs:409:28:414:9 | enter BlockExpr | test.rs:410:13:412:14 | ExprStmt | | +| test.rs:409:28:414:9 | exit BlockExpr (normal) | test.rs:409:28:414:9 | exit BlockExpr | | +| test.rs:410:13:412:13 | IfExpr | test.rs:413:13:413:15 | foo | | +| test.rs:410:13:412:14 | ExprStmt | test.rs:410:16:410:16 | b | | +| test.rs:410:16:410:16 | b | test.rs:410:13:412:13 | IfExpr | false | +| test.rs:410:16:410:16 | b | test.rs:411:17:411:41 | ExprStmt | true | +| test.rs:411:17:411:40 | ReturnExpr | test.rs:409:28:414:9 | exit BlockExpr (normal) | return | +| test.rs:411:17:411:41 | ExprStmt | test.rs:411:24:411:34 | async_block | | +| test.rs:411:24:411:34 | async_block | test.rs:411:36:411:39 | true | | +| test.rs:411:24:411:40 | CallExpr | test.rs:411:17:411:40 | ReturnExpr | | +| test.rs:411:36:411:39 | true | test.rs:411:24:411:40 | CallExpr | | +| test.rs:413:13:413:15 | foo | test.rs:409:28:414:9 | exit BlockExpr (normal) | | +| test.rs:421:5:423:5 | enter add_two | test.rs:421:22:421:22 | n | | +| test.rs:421:5:423:5 | exit add_two (normal) | test.rs:421:5:423:5 | exit add_two | | +| test.rs:421:22:421:22 | n | test.rs:421:22:421:27 | Param | match | +| test.rs:421:22:421:27 | Param | test.rs:422:9:422:9 | n | | +| test.rs:421:37:423:5 | BlockExpr | test.rs:421:5:423:5 | exit add_two (normal) | | +| test.rs:422:9:422:9 | n | test.rs:422:13:422:13 | 2 | | +| test.rs:422:9:422:13 | ... + ... | test.rs:421:37:423:5 | BlockExpr | | +| test.rs:422:13:422:13 | 2 | test.rs:422:9:422:13 | ... + ... | | +| test.rs:427:5:435:5 | enter const_block_assert | test.rs:430:9:432:9 | ExprStmt | | +| test.rs:427:5:435:5 | exit const_block_assert (normal) | test.rs:427:5:435:5 | exit const_block_assert | | +| test.rs:427:41:435:5 | BlockExpr | test.rs:427:5:435:5 | exit const_block_assert (normal) | | +| test.rs:430:9:432:9 | BlockExpr | test.rs:434:9:434:10 | 42 | | +| test.rs:430:9:432:9 | ExprStmt | test.rs:431:13:431:50 | ExprStmt | | +| test.rs:431:13:431:49 | $crate::panicking::panic_explicit | test.rs:431:13:431:49 | CallExpr | | +| test.rs:431:13:431:49 | BlockExpr | test.rs:431:13:431:49 | MacroExpr | | +| test.rs:431:13:431:49 | BlockExpr | test.rs:431:13:431:49 | exit panic_cold_explicit (normal) | | +| test.rs:431:13:431:49 | BlockExpr | test.rs:431:21:431:48 | IfExpr | | +| test.rs:431:13:431:49 | CallExpr | test.rs:431:13:431:49 | BlockExpr | | +| test.rs:431:13:431:49 | CallExpr | test.rs:431:13:431:49 | BlockExpr | | +| test.rs:431:13:431:49 | ExprStmt | test.rs:431:13:431:49 | MacroStmts | | +| test.rs:431:13:431:49 | ExprStmt | test.rs:431:13:431:49 | panic_cold_explicit | | +| test.rs:431:13:431:49 | MacroExpr | test.rs:430:9:432:9 | BlockExpr | | +| test.rs:431:13:431:49 | MacroExpr | test.rs:431:13:431:49 | BlockExpr | | +| test.rs:431:13:431:49 | MacroStmts | test.rs:431:13:431:49 | panic_cold_explicit | | +| test.rs:431:13:431:49 | enter panic_cold_explicit | test.rs:431:13:431:49 | $crate::panicking::panic_explicit | | +| test.rs:431:13:431:49 | exit panic_cold_explicit (normal) | test.rs:431:13:431:49 | exit panic_cold_explicit | | +| test.rs:431:13:431:49 | panic_cold_explicit | test.rs:431:13:431:49 | CallExpr | | +| test.rs:431:13:431:49 | panic_cold_explicit | test.rs:431:13:431:49 | ExprStmt | | +| test.rs:431:13:431:50 | ExprStmt | test.rs:431:21:431:48 | MacroStmts | | +| test.rs:431:21:431:42 | std::mem::size_of::<...> | test.rs:431:21:431:44 | CallExpr | | +| test.rs:431:21:431:44 | CallExpr | test.rs:431:48:431:48 | 0 | | +| test.rs:431:21:431:48 | ... > ... | test.rs:431:21:431:48 | [boolean(false)] ! ... | true | +| test.rs:431:21:431:48 | ... > ... | test.rs:431:21:431:48 | [boolean(true)] ! ... | false | +| test.rs:431:21:431:48 | BlockExpr | test.rs:431:13:431:49 | MacroExpr | | +| test.rs:431:21:431:48 | IfExpr | test.rs:431:21:431:48 | BlockExpr | | +| test.rs:431:21:431:48 | MacroStmts | test.rs:431:21:431:42 | std::mem::size_of::<...> | | +| test.rs:431:21:431:48 | [boolean(false)] ! ... | test.rs:431:21:431:48 | IfExpr | false | +| test.rs:431:21:431:48 | [boolean(true)] ! ... | test.rs:431:13:431:49 | ExprStmt | true | +| test.rs:431:48:431:48 | 0 | test.rs:431:21:431:48 | ... > ... | | +| test.rs:434:9:434:10 | 42 | test.rs:427:41:435:5 | BlockExpr | | +| test.rs:437:5:446:5 | enter const_block_panic | test.rs:438:9:438:30 | Const | | +| test.rs:437:5:446:5 | exit const_block_panic (normal) | test.rs:437:5:446:5 | exit const_block_panic | | +| test.rs:437:35:446:5 | BlockExpr | test.rs:437:5:446:5 | exit const_block_panic (normal) | | +| test.rs:438:9:438:30 | Const | test.rs:439:9:444:9 | ExprStmt | | +| test.rs:439:9:444:9 | ExprStmt | test.rs:439:12:439:16 | false | | +| test.rs:439:9:444:9 | IfExpr | test.rs:445:9:445:9 | N | | +| test.rs:439:12:439:16 | false | test.rs:439:9:444:9 | IfExpr | false | +| test.rs:442:17:442:24 | $crate::panicking::panic_explicit | test.rs:442:17:442:24 | CallExpr | | +| test.rs:442:17:442:24 | BlockExpr | test.rs:442:17:442:24 | exit panic_cold_explicit (normal) | | +| test.rs:442:17:442:24 | CallExpr | test.rs:442:17:442:24 | BlockExpr | | +| test.rs:442:17:442:24 | enter panic_cold_explicit | test.rs:442:17:442:24 | $crate::panicking::panic_explicit | | +| test.rs:442:17:442:24 | exit panic_cold_explicit (normal) | test.rs:442:17:442:24 | exit panic_cold_explicit | | +| test.rs:445:9:445:9 | N | test.rs:437:35:446:5 | BlockExpr | | +| test.rs:449:1:454:1 | enter dead_code | test.rs:450:5:452:5 | ExprStmt | | +| test.rs:449:1:454:1 | exit dead_code (normal) | test.rs:449:1:454:1 | exit dead_code | | +| test.rs:450:5:452:5 | ExprStmt | test.rs:450:9:450:12 | true | | +| test.rs:450:9:450:12 | true | test.rs:451:9:451:17 | ExprStmt | true | +| test.rs:451:9:451:16 | ReturnExpr | test.rs:449:1:454:1 | exit dead_code (normal) | return | +| test.rs:451:9:451:17 | ExprStmt | test.rs:451:16:451:16 | 0 | | +| test.rs:451:16:451:16 | 0 | test.rs:451:9:451:16 | ReturnExpr | | +| test.rs:456:1:456:16 | enter do_thing | test.rs:456:15:456:16 | BlockExpr | | +| test.rs:456:1:456:16 | exit do_thing (normal) | test.rs:456:1:456:16 | exit do_thing | | +| test.rs:456:15:456:16 | BlockExpr | test.rs:456:1:456:16 | exit do_thing (normal) | | +| test.rs:458:1:460:1 | enter condition_not_met | test.rs:459:5:459:9 | false | | +| test.rs:458:1:460:1 | exit condition_not_met (normal) | test.rs:458:1:460:1 | exit condition_not_met | | +| test.rs:458:32:460:1 | BlockExpr | test.rs:458:1:460:1 | exit condition_not_met (normal) | | +| test.rs:459:5:459:9 | false | test.rs:458:32:460:1 | BlockExpr | | +| test.rs:462:1:462:21 | enter do_next_thing | test.rs:462:20:462:21 | BlockExpr | | +| test.rs:462:1:462:21 | exit do_next_thing (normal) | test.rs:462:1:462:21 | exit do_next_thing | | +| test.rs:462:20:462:21 | BlockExpr | test.rs:462:1:462:21 | exit do_next_thing (normal) | | +| test.rs:464:1:464:21 | enter do_last_thing | test.rs:464:20:464:21 | BlockExpr | | +| test.rs:464:1:464:21 | exit do_last_thing (normal) | test.rs:464:1:464:21 | exit do_last_thing | | +| test.rs:464:20:464:21 | BlockExpr | test.rs:464:1:464:21 | exit do_last_thing (normal) | | +| test.rs:466:1:480:1 | enter labelled_block1 | test.rs:467:5:478:6 | LetStmt | | +| test.rs:466:1:480:1 | exit labelled_block1 (normal) | test.rs:466:1:480:1 | exit labelled_block1 | | +| test.rs:466:29:480:1 | BlockExpr | test.rs:466:1:480:1 | exit labelled_block1 (normal) | | +| test.rs:467:5:478:6 | LetStmt | test.rs:468:9:468:19 | ExprStmt | | +| test.rs:467:9:467:14 | result | test.rs:479:5:479:10 | result | match | +| test.rs:467:18:478:5 | BlockExpr | test.rs:467:9:467:14 | result | | +| test.rs:468:9:468:16 | do_thing | test.rs:468:9:468:18 | CallExpr | | +| test.rs:468:9:468:18 | CallExpr | test.rs:469:9:471:9 | ExprStmt | | +| test.rs:468:9:468:19 | ExprStmt | test.rs:468:9:468:16 | do_thing | | +| test.rs:469:9:471:9 | ExprStmt | test.rs:469:12:469:28 | condition_not_met | | +| test.rs:469:9:471:9 | IfExpr | test.rs:472:9:472:24 | ExprStmt | | +| test.rs:469:12:469:28 | condition_not_met | test.rs:469:12:469:30 | CallExpr | | +| test.rs:469:12:469:30 | CallExpr | test.rs:469:9:471:9 | IfExpr | false | +| test.rs:469:12:469:30 | CallExpr | test.rs:470:13:470:27 | ExprStmt | true | +| test.rs:470:13:470:26 | BreakExpr | test.rs:467:18:478:5 | BlockExpr | break | +| test.rs:470:13:470:27 | ExprStmt | test.rs:470:26:470:26 | 1 | | +| test.rs:470:26:470:26 | 1 | test.rs:470:13:470:26 | BreakExpr | | +| test.rs:472:9:472:21 | do_next_thing | test.rs:472:9:472:23 | CallExpr | | +| test.rs:472:9:472:23 | CallExpr | test.rs:473:9:475:9 | ExprStmt | | +| test.rs:472:9:472:24 | ExprStmt | test.rs:472:9:472:21 | do_next_thing | | +| test.rs:473:9:475:9 | ExprStmt | test.rs:473:12:473:28 | condition_not_met | | +| test.rs:473:9:475:9 | IfExpr | test.rs:476:9:476:24 | ExprStmt | | +| test.rs:473:12:473:28 | condition_not_met | test.rs:473:12:473:30 | CallExpr | | +| test.rs:473:12:473:30 | CallExpr | test.rs:473:9:475:9 | IfExpr | false | +| test.rs:473:12:473:30 | CallExpr | test.rs:474:13:474:27 | ExprStmt | true | +| test.rs:474:13:474:26 | BreakExpr | test.rs:467:18:478:5 | BlockExpr | break | +| test.rs:474:13:474:27 | ExprStmt | test.rs:474:26:474:26 | 2 | | +| test.rs:474:26:474:26 | 2 | test.rs:474:13:474:26 | BreakExpr | | +| test.rs:476:9:476:21 | do_last_thing | test.rs:476:9:476:23 | CallExpr | | +| test.rs:476:9:476:23 | CallExpr | test.rs:477:9:477:9 | 3 | | +| test.rs:476:9:476:24 | ExprStmt | test.rs:476:9:476:21 | do_last_thing | | +| test.rs:477:9:477:9 | 3 | test.rs:467:18:478:5 | BlockExpr | | +| test.rs:479:5:479:10 | result | test.rs:466:29:480:1 | BlockExpr | | +| test.rs:482:1:490:1 | enter labelled_block2 | test.rs:483:5:489:6 | LetStmt | | +| test.rs:482:1:490:1 | exit labelled_block2 (normal) | test.rs:482:1:490:1 | exit labelled_block2 | | +| test.rs:482:22:490:1 | BlockExpr | test.rs:482:1:490:1 | exit labelled_block2 (normal) | | +| test.rs:483:5:489:6 | LetStmt | test.rs:484:9:484:34 | LetStmt | | +| test.rs:483:9:483:14 | result | test.rs:482:22:490:1 | BlockExpr | match | +| test.rs:483:18:489:5 | BlockExpr | test.rs:483:9:483:14 | result | | +| test.rs:484:9:484:34 | LetStmt | test.rs:484:30:484:33 | None | | +| test.rs:484:13:484:13 | x | test.rs:485:9:487:10 | LetStmt | match | +| test.rs:484:30:484:33 | None | test.rs:484:13:484:13 | x | | +| test.rs:485:9:487:10 | LetStmt | test.rs:485:23:485:23 | x | | +| test.rs:485:13:485:19 | TupleStructPat | test.rs:485:18:485:18 | y | match | +| test.rs:485:13:485:19 | TupleStructPat | test.rs:486:13:486:27 | ExprStmt | no-match | +| test.rs:485:18:485:18 | y | test.rs:488:9:488:9 | 0 | match | +| test.rs:485:23:485:23 | x | test.rs:485:13:485:19 | TupleStructPat | | +| test.rs:486:13:486:26 | BreakExpr | test.rs:483:18:489:5 | BlockExpr | break | +| test.rs:486:13:486:27 | ExprStmt | test.rs:486:26:486:26 | 1 | | +| test.rs:486:26:486:26 | 1 | test.rs:486:13:486:26 | BreakExpr | | +| test.rs:488:9:488:9 | 0 | test.rs:483:18:489:5 | BlockExpr | | +| test.rs:492:1:498:1 | enter test_nested_function2 | test.rs:493:5:493:18 | LetStmt | | +| test.rs:492:1:498:1 | exit test_nested_function2 (normal) | test.rs:492:1:498:1 | exit test_nested_function2 | | +| test.rs:492:28:498:1 | BlockExpr | test.rs:492:1:498:1 | exit test_nested_function2 (normal) | | +| test.rs:493:5:493:18 | LetStmt | test.rs:493:17:493:17 | 0 | | +| test.rs:493:9:493:13 | x | test.rs:494:5:496:5 | nested | match | +| test.rs:493:17:493:17 | 0 | test.rs:493:9:493:13 | x | | +| test.rs:494:5:496:5 | enter nested | test.rs:494:15:494:15 | x | | +| test.rs:494:5:496:5 | exit nested (normal) | test.rs:494:5:496:5 | exit nested | | +| test.rs:494:5:496:5 | nested | test.rs:497:5:497:19 | ExprStmt | | +| test.rs:494:15:494:15 | x | test.rs:494:15:494:25 | Param | match | +| test.rs:494:15:494:25 | Param | test.rs:495:9:495:16 | ExprStmt | | +| test.rs:494:28:496:5 | BlockExpr | test.rs:494:5:496:5 | exit nested (normal) | | +| test.rs:495:9:495:10 | * ... | test.rs:495:15:495:15 | 1 | | +| test.rs:495:9:495:15 | ... += ... | test.rs:494:28:496:5 | BlockExpr | | +| test.rs:495:9:495:16 | ExprStmt | test.rs:495:10:495:10 | x | | +| test.rs:495:10:495:10 | x | test.rs:495:9:495:10 | * ... | | +| test.rs:495:15:495:15 | 1 | test.rs:495:9:495:15 | ... += ... | | +| test.rs:497:5:497:10 | nested | test.rs:497:17:497:17 | x | | +| test.rs:497:5:497:18 | CallExpr | test.rs:492:28:498:1 | BlockExpr | | +| test.rs:497:5:497:19 | ExprStmt | test.rs:497:5:497:10 | nested | | +| test.rs:497:12:497:17 | RefExpr | test.rs:497:5:497:18 | CallExpr | | +| test.rs:497:17:497:17 | x | test.rs:497:12:497:17 | RefExpr | | +| test.rs:509:5:511:5 | enter new | test.rs:509:12:509:12 | a | | +| test.rs:509:5:511:5 | exit new (normal) | test.rs:509:5:511:5 | exit new | | +| test.rs:509:12:509:12 | a | test.rs:509:12:509:17 | Param | match | +| test.rs:509:12:509:17 | Param | test.rs:510:23:510:23 | a | | +| test.rs:509:28:511:5 | BlockExpr | test.rs:509:5:511:5 | exit new (normal) | | +| test.rs:510:9:510:25 | RecordExpr | test.rs:509:28:511:5 | BlockExpr | | +| test.rs:510:23:510:23 | a | test.rs:510:9:510:25 | RecordExpr | | +| test.rs:513:5:515:5 | enter negated | test.rs:513:16:513:19 | self | | +| test.rs:513:5:515:5 | exit negated (normal) | test.rs:513:5:515:5 | exit negated | | +| test.rs:513:16:513:19 | SelfParam | test.rs:514:23:514:26 | self | | +| test.rs:513:16:513:19 | self | test.rs:513:16:513:19 | SelfParam | | +| test.rs:513:30:515:5 | BlockExpr | test.rs:513:5:515:5 | exit negated (normal) | | +| test.rs:514:9:514:30 | RecordExpr | test.rs:513:30:515:5 | BlockExpr | | +| test.rs:514:23:514:26 | self | test.rs:514:23:514:28 | FieldExpr | | +| test.rs:514:23:514:28 | FieldExpr | test.rs:514:9:514:30 | RecordExpr | | +| test.rs:517:5:519:5 | enter multifly_add | test.rs:517:26:517:29 | self | | +| test.rs:517:5:519:5 | exit multifly_add (normal) | test.rs:517:5:519:5 | exit multifly_add | | +| test.rs:517:21:517:29 | SelfParam | test.rs:517:32:517:32 | a | | +| test.rs:517:26:517:29 | self | test.rs:517:21:517:29 | SelfParam | | +| test.rs:517:32:517:32 | a | test.rs:517:32:517:37 | Param | match | +| test.rs:517:32:517:37 | Param | test.rs:517:40:517:40 | b | | +| test.rs:517:40:517:40 | b | test.rs:517:40:517:45 | Param | match | +| test.rs:517:40:517:45 | Param | test.rs:518:9:518:34 | ExprStmt | | +| test.rs:517:48:519:5 | BlockExpr | test.rs:517:5:519:5 | exit multifly_add (normal) | | +| test.rs:518:9:518:12 | self | test.rs:518:9:518:14 | FieldExpr | | +| test.rs:518:9:518:14 | FieldExpr | test.rs:518:19:518:22 | self | | +| test.rs:518:9:518:33 | ... = ... | test.rs:517:48:519:5 | BlockExpr | | +| test.rs:518:9:518:34 | ExprStmt | test.rs:518:9:518:12 | self | | +| test.rs:518:18:518:33 | ... + ... | test.rs:518:9:518:33 | ... = ... | | +| test.rs:518:19:518:22 | self | test.rs:518:19:518:24 | FieldExpr | | +| test.rs:518:19:518:24 | FieldExpr | test.rs:518:28:518:28 | a | | +| test.rs:518:19:518:28 | ... * ... | test.rs:518:33:518:33 | b | | +| test.rs:518:28:518:28 | a | test.rs:518:19:518:28 | ... * ... | | +| test.rs:518:33:518:33 | b | test.rs:518:18:518:33 | ... + ... | | breakTarget | test.rs:34:17:34:21 | BreakExpr | test.rs:28:9:40:9 | LoopExpr | | test.rs:48:21:48:25 | BreakExpr | test.rs:46:13:53:13 | LoopExpr | @@ -1090,9 +1106,9 @@ breakTarget | test.rs:197:17:197:28 | BreakExpr | test.rs:195:13:200:9 | LoopExpr | | test.rs:210:17:210:35 | BreakExpr | test.rs:208:13:213:9 | LoopExpr | | test.rs:222:13:222:30 | BreakExpr | test.rs:221:13:223:9 | BlockExpr | -| test.rs:463:13:463:26 | BreakExpr | test.rs:460:18:471:5 | BlockExpr | -| test.rs:467:13:467:26 | BreakExpr | test.rs:460:18:471:5 | BlockExpr | -| test.rs:479:13:479:26 | BreakExpr | test.rs:476:18:482:5 | BlockExpr | +| test.rs:470:13:470:26 | BreakExpr | test.rs:467:18:478:5 | BlockExpr | +| test.rs:474:13:474:26 | BreakExpr | test.rs:467:18:478:5 | BlockExpr | +| test.rs:486:13:486:26 | BreakExpr | test.rs:483:18:489:5 | BlockExpr | continueTarget | test.rs:37:17:37:24 | ContinueExpr | test.rs:28:9:40:9 | LoopExpr | | test.rs:63:21:63:28 | ContinueExpr | test.rs:61:13:68:13 | LoopExpr | diff --git a/rust/ql/test/library-tests/controlflow/test.rs b/rust/ql/test/library-tests/controlflow/test.rs index 42094c5432e..42285f42b71 100644 --- a/rust/ql/test/library-tests/controlflow/test.rs +++ b/rust/ql/test/library-tests/controlflow/test.rs @@ -277,6 +277,13 @@ mod logical_operators { fn test_and_return(a: bool) { a && return; } + + fn test_and_true(a: bool) -> i64 { + if (a && true) { + return 1; + } + 0 + } } mod question_mark_operator { From 1c2fdc29a333ef6ff258fa8d4c7dc5ede1c1ffd1 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 19 Nov 2024 15:19:08 +0100 Subject: [PATCH 142/470] Rust: Add more local data flow tests --- .../dataflow/local/DataFlowStep.expected | 24 ++++++++++++++++ .../test/library-tests/dataflow/local/main.rs | 28 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 8cc12598f62..d52e9609600 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -83,3 +83,27 @@ | main.rs:111:14:111:14 | n | main.rs:111:14:111:14 | [SSA] n | | main.rs:111:20:111:26 | CallExpr | main.rs:110:5:113:5 | MatchExpr | | main.rs:112:17:112:23 | CallExpr | main.rs:110:5:113:5 | MatchExpr | +| main.rs:117:9:117:9 | [SSA] a | main.rs:118:5:118:5 | a | +| main.rs:117:9:117:9 | a | main.rs:117:9:117:9 | [SSA] a | +| main.rs:117:13:117:17 | BlockExpr | main.rs:117:9:117:9 | a | +| main.rs:117:15:117:15 | 0 | main.rs:117:13:117:17 | BlockExpr | +| main.rs:118:5:118:5 | a | main.rs:116:31:119:1 | BlockExpr | +| main.rs:121:22:121:22 | [SSA] b | main.rs:123:12:123:12 | b | +| main.rs:121:22:121:22 | b | main.rs:121:22:121:22 | [SSA] b | +| main.rs:122:9:122:9 | [SSA] a | main.rs:128:5:128:5 | a | +| main.rs:122:9:122:9 | a | main.rs:122:9:122:9 | [SSA] a | +| main.rs:122:13:127:5 | BlockExpr | main.rs:122:9:122:9 | a | +| main.rs:123:12:123:12 | b | main.rs:123:9:125:9 | IfExpr | +| main.rs:124:13:124:26 | BreakExpr | main.rs:122:13:127:5 | BlockExpr | +| main.rs:124:26:124:26 | 1 | main.rs:124:13:124:26 | BreakExpr | +| main.rs:126:9:126:9 | 2 | main.rs:122:13:127:5 | BlockExpr | +| main.rs:128:5:128:5 | a | main.rs:121:38:129:1 | BlockExpr | +| main.rs:131:22:131:22 | [SSA] b | main.rs:133:12:133:12 | b | +| main.rs:131:22:131:22 | b | main.rs:131:22:131:22 | [SSA] b | +| main.rs:132:9:132:9 | [SSA] a | main.rs:138:5:138:5 | a | +| main.rs:132:9:132:9 | a | main.rs:132:9:132:9 | [SSA] a | +| main.rs:132:13:137:5 | BlockExpr | main.rs:132:9:132:9 | a | +| main.rs:133:12:133:12 | b | main.rs:133:9:135:9 | IfExpr | +| main.rs:134:26:134:26 | 1 | main.rs:134:13:134:26 | BreakExpr | +| main.rs:136:22:136:22 | 2 | main.rs:136:9:136:22 | BreakExpr | +| main.rs:138:5:138:5 | a | main.rs:131:38:139:1 | BlockExpr | diff --git a/rust/ql/test/library-tests/dataflow/local/main.rs b/rust/ql/test/library-tests/dataflow/local/main.rs index fb79baa70bd..dea41118b1d 100644 --- a/rust/ql/test/library-tests/dataflow/local/main.rs +++ b/rust/ql/test/library-tests/dataflow/local/main.rs @@ -113,6 +113,31 @@ fn option_pattern_match() { } } +fn block_expression1() -> i64 { + let a = { 0 }; + a +} + +fn block_expression2(b: bool) -> i64 { + let a = 'block: { + if b { + break 'block 1; + }; + 2 + }; + a +} + +fn block_expression3(b: bool) -> i64 { + let a = 'block: { + if b { + break 'block 1; + } + break 'block 2; + }; + a +} + fn main() { direct(); variable_usage(); @@ -125,4 +150,7 @@ fn main() { struct_field(); struct_pattern_match(); option_pattern_match(); + block_expression1(); + block_expression2(true); + block_expression3(true); } From c8736e8a3da54a65adaf8e837e18b025c65da608 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 4 Nov 2024 08:45:54 +0100 Subject: [PATCH 143/470] Rust: Auto-generate `CfgNodes.qll` --- misc/codegen/codegen.py | 2 + misc/codegen/generators/qlgen.py | 24 + misc/codegen/lib/ql.py | 17 + misc/codegen/lib/schema.py | 1 + misc/codegen/lib/schemadefs.py | 3 +- misc/codegen/loaders/schemaloader.py | 1 + misc/codegen/templates/ql_cfg_nodes.mustache | 199 + rust/codegen.conf | 1 + rust/ql/.generated.list | 1 + rust/ql/.gitattributes | 1 + .../lib/codeql/rust/controlflow/CfgNodes.qll | 6 +- .../controlflow/internal/CfgConsistency.qll | 23 + .../rust/controlflow/internal/CfgNodes.qll | 116 + .../internal/generated/CfgNodes.qll | 3657 +++++++++++++++++ .../rust/elements/internal/AstNodeImpl.qll | 33 + .../lib/codeql/rust/internal/CachedStages.qll | 3 + .../diagnostics/CfgConsistencyCounts.expected | 1 + rust/schema/annotations.py | 106 +- 18 files changed, 4139 insertions(+), 56 deletions(-) create mode 100644 misc/codegen/templates/ql_cfg_nodes.mustache create mode 100644 rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll create mode 100644 rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll diff --git a/misc/codegen/codegen.py b/misc/codegen/codegen.py index acc8e59bba5..ce991b6f0d4 100755 --- a/misc/codegen/codegen.py +++ b/misc/codegen/codegen.py @@ -64,6 +64,8 @@ def _parse_args() -> argparse.Namespace: help="registry file containing information about checked-in generated code. A .gitattributes" "file is generated besides it to mark those files with linguist-generated=true. Must" "be in a directory containing all generated code."), + p.add_argument("--ql-cfg-output", + help="output directory for QL CFG layer (optional)."), ] p.add_argument("--script-name", help="script name to put in header comments of generated files. By default, the path of this " diff --git a/misc/codegen/generators/qlgen.py b/misc/codegen/generators/qlgen.py index c5e7153489b..f1a68f6bc01 100755 --- a/misc/codegen/generators/qlgen.py +++ b/misc/codegen/generators/qlgen.py @@ -160,6 +160,8 @@ def get_ql_class(cls: schema.Class, lookup: typing.Dict[str, schema.Class]) -> q prop = get_ql_property(cls, p, lookup, prev_child) if prop.is_child: prev_child = prop.singular + if prop.type in lookup and lookup[prop.type].cfg: + prop.cfg = True properties.append(prop) return ql.Class( name=cls.name, @@ -171,6 +173,16 @@ def get_ql_class(cls: schema.Class, lookup: typing.Dict[str, schema.Class]) -> q doc=cls.doc, hideable="ql_hideable" in cls.pragmas, internal="ql_internal" in cls.pragmas, + cfg=cls.cfg, + ) + + +def get_ql_cfg_class(cls: schema.Class, lookup: typing.Dict[str, ql.Class]) -> ql.CfgClass: + return ql.CfgClass( + name=cls.name, + bases=[base for base in cls.bases if lookup[base.base].cfg], + properties=cls.properties, + doc=cls.doc ) @@ -361,6 +373,7 @@ def generate(opts, renderer): input = opts.schema out = opts.ql_output stub_out = opts.ql_stub_output + cfg_out = opts.ql_cfg_output test_out = opts.ql_test_output missing_test_source_filename = "MISSING_SOURCE.txt" include_file = stub_out.with_suffix(".qll") @@ -385,6 +398,7 @@ def generate(opts, renderer): imports = {} imports_impl = {} classes_used_by = {} + cfg_classes = [] generated_import_prefix = get_import(out, opts.root_dir) registry = opts.generated_registry or pathlib.Path( os.path.commonpath((out, stub_out, test_out)), ".generated.list") @@ -402,6 +416,8 @@ def generate(opts, renderer): imports[c.name] = path path_impl = get_import(stub_out / c.dir / "internal" / c.name, opts.root_dir) imports_impl[c.name + "Impl"] = path_impl + "Impl" + if c.cfg: + cfg_classes.append(get_ql_cfg_class(c, classes)) for c in classes.values(): qll = out / c.path.with_suffix(".qll") @@ -411,6 +427,14 @@ def generate(opts, renderer): c.import_prefix = generated_import_prefix renderer.render(c, qll) + if cfg_out: + cfg_classes_val = ql.CfgClasses( + include_file_import=get_import(include_file, opts.root_dir), + classes=cfg_classes + ) + cfg_qll = cfg_out / "CfgNodes.qll" + renderer.render(cfg_classes_val, cfg_qll) + for c in data.classes.values(): path = _get_path(c) path_impl = _get_path_impl(c) diff --git a/misc/codegen/lib/ql.py b/misc/codegen/lib/ql.py index 1920a813e20..1182c7f5dc1 100644 --- a/misc/codegen/lib/ql.py +++ b/misc/codegen/lib/ql.py @@ -45,6 +45,7 @@ class Property: synth: bool = False type_is_hideable: bool = False internal: bool = False + cfg: bool = False def __post_init__(self): if self.tableparams: @@ -110,6 +111,7 @@ class Class: internal: bool = False doc: List[str] = field(default_factory=list) hideable: bool = False + cfg: bool = False def __post_init__(self): def get_bases(bases): return [Base(str(b), str(prev)) for b, prev in zip(bases, itertools.chain([""], bases))] @@ -333,3 +335,18 @@ class Synth: cls: "Synth.FinalClass" import_prefix: str + + +@dataclass +class CfgClass: + name: str + bases: List[Base] = field(default_factory=list) + properties: List[Property] = field(default_factory=list) + doc: List[str] = field(default_factory=list) + + +@dataclass +class CfgClasses: + template: ClassVar = 'ql_cfg_nodes' + include_file_import: Optional[str] = None + classes: List[CfgClass] = field(default_factory=list) diff --git a/misc/codegen/lib/schema.py b/misc/codegen/lib/schema.py index c5c3dc810b6..23f1aea2ba4 100644 --- a/misc/codegen/lib/schema.py +++ b/misc/codegen/lib/schema.py @@ -94,6 +94,7 @@ class Class: properties: List[Property] = field(default_factory=list) pragmas: List[str] | Dict[str, object] = field(default_factory=dict) doc: List[str] = field(default_factory=list) + cfg: bool = False def __post_init__(self): if not isinstance(self.pragmas, dict): diff --git a/misc/codegen/lib/schemadefs.py b/misc/codegen/lib/schemadefs.py index 997b85b4ca6..32d3a6b85ae 100644 --- a/misc/codegen/lib/schemadefs.py +++ b/misc/codegen/lib/schemadefs.py @@ -279,7 +279,7 @@ _ = _PropertyAnnotation() drop = object() -def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, replace_bases: _Dict[type, type] | None = None) -> _Callable[[type], _PropertyAnnotation]: +def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, replace_bases: _Dict[type, type] | None = None, cfg: bool = False) -> _Callable[[type], _PropertyAnnotation]: """ Add or modify schema annotations after a class has been defined previously. @@ -298,6 +298,7 @@ def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, repl annotated_cls.__bases__ = tuple(replace_bases.get(b, b) for b in annotated_cls.__bases__) if add_bases: annotated_cls.__bases__ += tuple(add_bases) + annotated_cls.__cfg__ = cfg for a in dir(cls): if a.startswith(_schema.inheritable_pragma_prefix): setattr(annotated_cls, a, getattr(cls, a)) diff --git a/misc/codegen/loaders/schemaloader.py b/misc/codegen/loaders/schemaloader.py index 069e3b65474..dd1edee1de0 100644 --- a/misc/codegen/loaders/schemaloader.py +++ b/misc/codegen/loaders/schemaloader.py @@ -53,6 +53,7 @@ def _get_class(cls: type) -> schema.Class: bases=[b.__name__ for b in cls.__bases__ if b is not object], derived=derived, pragmas=pragmas, + cfg=cls.__cfg__ if hasattr(cls, "__cfg__") else False, # in the following we don't use `getattr` to avoid inheriting properties=[ a | _PropertyNamer(n) diff --git a/misc/codegen/templates/ql_cfg_nodes.mustache b/misc/codegen/templates/ql_cfg_nodes.mustache new file mode 100644 index 00000000000..fd969b1c59b --- /dev/null +++ b/misc/codegen/templates/ql_cfg_nodes.mustache @@ -0,0 +1,199 @@ +// generated by {{generator}}, do not edit +/** + * This module provides generated wrappers around the `CfgNode` type. + * + * INTERNAL: Do not import directly. + */ + +private import codeql.util.Location +private import codeql.util.Unit +private import {{include_file_import}} + +/** Provides the input to `MakeCfgNodes` */ +signature module InputSig { + class CfgNode { + AstNode getAstNode(); + + string toString(); + + Loc getLocation(); + } + + AstNode getDesugared(AstNode n); +} + +/** + * Given a `CfgNode` implementation, provides the module `Nodes` that + * contains wrappers around `CfgNode` for relevant classes. + */ +module MakeCfgNodes Input> { + private import Input + + final private class AstNodeFinal = AstNode; + + final private class CfgNodeFinal = CfgNode; + + /** + * INTERNAL: Do not expose. + */ + abstract class ParentAstNode extends AstNodeFinal { + /** + * Holds if `child` is a (possibly nested) child of this AST node + * for which we would like to find a matching CFG child. + */ + abstract predicate relevantChild(AstNode child); + } + + /** + * INTERNAL: Do not expose. + */ + abstract class ChildMapping extends Unit { + /** + * Holds if `child` is a (possibly nested) child of AST node `parent` + * for which we would like to find a matching CFG child. + */ + final predicate relevantChild(AstNode parent, AstNode child) { + parent.(ParentAstNode).relevantChild(child) + } + + /** + * Holds if there is a control-flow path from `cfn` to `cfnChild`, where `cfn` + * is a control-flow node for this AST node, and `cfnChild` is a control-flow + * node for `child`. + * + * This predicate should be implemented at the place where `MakeCfgNodes` is + * invoked. Ideally, `MakeCfgNodes` should be a higher-order parameterized + * module, but since that is currently not supported, we achieve the "callback" + * effect using this `abstract` class instead. + */ + cached + abstract predicate hasCfgChild(AstNode parent, AstNode child, CfgNode cfn, CfgNode cfnChild); + } + + /** Provides sub classes of `CfgNode`. */ + module Nodes { + {{#classes}} + private final class Parent{{name}} extends ParentAstNode, {{name}} { + override predicate relevantChild(AstNode child) { + none() + {{#properties}} + {{#cfg}} + or + child = this.{{getter}}({{#is_indexed}}_{{/is_indexed}}) + {{/cfg}} + {{/properties}} + } + } + + /** + {{#doc}} + * {{.}} + {{/doc}} + */ + final class {{name}}CfgNode extends CfgNodeFinal{{#bases}}, {{.}}CfgNode{{/bases}} { + private {{name}} node; + + {{name}}CfgNode() { + node = this.getAstNode() + } + + /** Gets the underlying `{{name}}`. */ + {{name}} get{{name}}() { result = node } + + {{#properties}} + /** + * {{>ql_property_doc}} * + {{#description}} + * {{.}} + {{/description}} + {{#internal}} + * INTERNAL: Do not use. + {{/internal}} + */ + {{type}}{{#cfg}}CfgNode{{/cfg}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) { + {{#cfg}} + any(ChildMapping mapping).hasCfgChild(node, node.{{getter}}({{#is_indexed}}index{{/is_indexed}}), this, result) + {{/cfg}} + {{^cfg}} + {{^is_predicate}}result = {{/is_predicate}}node.{{getter}}({{#is_indexed}}index{{/is_indexed}}) + {{/cfg}} + } + + {{#is_optional}} + /** + * Holds if `{{getter}}({{#is_repeated}}index{{/is_repeated}})` exists. + {{#internal}} + * INTERNAL: Do not use. + {{/internal}} + */ + predicate has{{singular}}({{#is_repeated}}int index{{/is_repeated}}) { + exists(this.{{getter}}({{#is_repeated}}index{{/is_repeated}})) + } + {{/is_optional}} + {{#is_indexed}} + + /** + * Gets any of the {{doc_plural}}. + {{#internal}} + * INTERNAL: Do not use. + {{/internal}} + */ + {{type}}{{#cfg}}CfgNode{{/cfg}} {{indefinite_getter}}() { + result = this.{{getter}}(_) + } + {{^is_optional}} + + /** + * Gets the number of {{doc_plural}}. + {{#internal}} + * INTERNAL: Do not use. + {{/internal}} + */ + int getNumberOf{{plural}}() { + result = count(int i | exists(this.{{getter}}(i))) + } + {{/is_optional}} + {{/is_indexed}} + {{#is_unordered}} + /** + * Gets the number of {{doc_plural}}. + {{#internal}} + * INTERNAL: Do not use. + {{/internal}} + */ + int getNumberOf{{plural}}() { + result = count(this.{{getter}}()) + } + {{/is_unordered}} + {{/properties}} + } + {{/classes}} + } + + module Consistency { + private predicate hasCfgNode(AstNode astNode) { + astNode = any(CfgNode cfgNode).getAstNode() + } + + query predicate missingCfgChild(CfgNode parent, string pred, int i, AstNode child) { + none() + {{#classes}} + {{#properties}} + {{#cfg}} + or + pred = "{{getter}}" and + parent = any(Nodes::{{name}}CfgNode cfgNode, {{name}} astNode | + astNode = cfgNode.get{{name}}() and + child = getDesugared(astNode.{{getter}}({{#is_indexed}}i{{/is_indexed}})) + {{^is_indexed}}and i = -1{{/is_indexed}} and + hasCfgNode(child) and + not child = cfgNode.{{getter}}({{#is_indexed}}i{{/is_indexed}}).getAstNode() + | + cfgNode + ) + {{/cfg}} + {{/properties}} + {{/classes}} + } + } +} \ No newline at end of file diff --git a/rust/codegen.conf b/rust/codegen.conf index 29b6edc8985..d40fada446b 100644 --- a/rust/codegen.conf +++ b/rust/codegen.conf @@ -4,6 +4,7 @@ --dbscheme=ql/lib/rust.dbscheme --ql-output=ql/lib/codeql/rust/elements/internal/generated --ql-stub-output=ql/lib/codeql/rust/elements +--ql-cfg-output=ql/lib/codeql/rust/controlflow/internal/generated --ql-test-output=ql/test/extractor-tests/generated --rust-output=extractor/src/generated --script-name=codegen diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index ca25e0533fc..11980eb55df 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -1,3 +1,4 @@ +lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll 55c20303ad50f17ddea728eb840304e0a634821adb7b13471a9ce55b71ed3886 13509512ffb59a9634ed2dc3c4969af26d5ba2d1502d98dc0c107a99392ce892 lib/codeql/rust/elements/Abi.qll 4c973d28b6d628f5959d1f1cc793704572fd0acaae9a97dfce82ff9d73f73476 250f68350180af080f904cd34cb2af481c5c688dc93edf7365fd0ae99855e893 lib/codeql/rust/elements/ArgList.qll 661f5100f5d3ef8351452d9058b663a2a5c720eea8cf11bedd628969741486a2 28e424aac01a90fb58cd6f9f83c7e4cf379eea39e636bc0ba07efc818be71c71 lib/codeql/rust/elements/ArrayExpr.qll a3e6e122632f4011644ec31b37f88b32fe3f2b7e388e7e878a6883309937049f 12ccb5873d95c433da5606fd371d182ef2f71b78d0c53c2d6dec10fa45852bdc diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index a532f142ec9..68b893ba9c7 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -1,5 +1,6 @@ /.generated.list linguist-generated /.gitattributes linguist-generated +/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll linguist-generated /lib/codeql/rust/elements/Abi.qll linguist-generated /lib/codeql/rust/elements/ArgList.qll linguist-generated /lib/codeql/rust/elements/ArrayExpr.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll index 4a51506dbc0..1a7c7e212b9 100644 --- a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll @@ -5,7 +5,9 @@ private import rust private import ControlFlowGraph -private import internal.ControlFlowGraphImpl +private import internal.ControlFlowGraphImpl as CfgImpl +private import internal.CfgNodes +import Nodes /** A CFG node that corresponds to an element in the AST. */ class AstCfgNode extends CfgNode { @@ -57,4 +59,4 @@ class MethodCallExprCfgNode extends ExprCfgNode { MethodCallExpr getMethodCallExpr() { result = node } } -final class ExitCfgNode = ExitNode; +final class ExitCfgNode = CfgImpl::ExitNode; diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll b/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll index 2722661494d..0f178726ad8 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll @@ -8,6 +8,8 @@ import Consistency private import codeql.rust.controlflow.ControlFlowGraph private import codeql.rust.controlflow.internal.ControlFlowGraphImpl as CfgImpl private import codeql.rust.controlflow.internal.Completion +private import codeql.rust.controlflow.internal.CfgNodes::Consistency as CfgNodes +private import codeql.rust.Diagnostics private predicate nonPostOrderExpr(Expr e) { not e instanceof LetExpr and @@ -54,6 +56,24 @@ query predicate deadEnd(CfgImpl::Node node) { not letElsePanic(node.getAstNode()) } +pragma[nomagic] +private predicate successfullyExtractedFile(File f) { + not exists(ExtractionWarning ee | ee.getLocation().getFile() = f) +} + +query predicate missingCfgChild(CfgNode parent, string pred, int i, AstNode child) { + CfgNodes::missingCfgChild(parent, pred, i, child) and + successfullyExtractedFile(child.getLocation().getFile()) and + not exists(AstNode last, CfgImpl::Completion c | CfgImpl::last(child, last, c) | + // In for example `if (a && true) ...` there is no RHS CFG node going into the + // `[false] a && true` operation + strictcount(ConditionalSuccessor cs | exists(last.getACfgNode().getASuccessor(cs)) | cs) = 1 + or + // In for example `x && return`, there is no RHS CFG node going into the `&&` operation + not c instanceof CfgImpl::NormalCompletion + ) +} + /** * Gets counts of control flow graph inconsistencies of each type. */ @@ -99,4 +119,7 @@ int getCfgInconsistencyCounts(string type) { or type = "Non-PostOrderTree Expr node" and result = count(Expr e | nonPostOrderExpr(e) | e) + or + type = "Missing CFG child" and + result = count(CfgNode parent, string pred, int child | missingCfgChild(parent, pred, child, _)) } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll new file mode 100644 index 00000000000..3f5b3c0e483 --- /dev/null +++ b/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll @@ -0,0 +1,116 @@ +private import rust +private import codeql.rust.controlflow.internal.generated.CfgNodes +private import codeql.rust.controlflow.internal.ControlFlowGraphImpl as CfgImpl +private import codeql.rust.controlflow.ControlFlowGraph +private import codeql.rust.controlflow.BasicBlocks +private import codeql.rust.controlflow.CfgNodes +private import codeql.rust.internal.CachedStages + +private predicate isPostOrder(AstNode n) { + n instanceof Expr and + not n instanceof LetExpr + or + n instanceof OrPat + or + n instanceof IdentPat + or + n instanceof LiteralPat + or + n instanceof Param +} + +private module CfgNodesInput implements InputSig { + private import codeql.rust.controlflow.ControlFlowGraph as Cfg + + class CfgNode = AstCfgNode; + + private AstNode desugar(AstNode n) { + result = n.(ParenPat).getPat() + or + result = n.(ParenExpr).getExpr() + } + + AstNode getDesugared(AstNode n) { + result = getDesugared(desugar(n)) + or + not exists(desugar(n)) and + result = n + } +} + +import MakeCfgNodes + +private class ChildMappingImpl extends ChildMapping { + /** Gets a CFG node for `child`, where `child` is a relevant child node of `parent`. */ + private CfgNode getRelevantChildCfgNode(AstNode parent, AstNode child) { + this.relevantChild(parent, child) and + result = CfgNodesInput::getDesugared(child).getACfgNode() + } + + pragma[nomagic] + private BasicBlock getARelevantBasicBlock(AstNode parent) { + result.getANode().getAstNode() = parent or + result.getANode() = this.getRelevantChildCfgNode(parent, _) + } + + /** + * Holds if CFG node `cfnChild` can reach basic block `bb`, without going + * through an intermediate block that contains a CFG node for `parent` or + * any other relevant child of `parent`. + */ + pragma[nomagic] + predicate childNodeReachesBasicBlock( + AstNode parent, AstNode child, CfgNode cfnChild, BasicBlock bb + ) { + exists(BasicBlock bb0 | + cfnChild = this.getRelevantChildCfgNode(parent, child) and + bb0.getANode() = cfnChild + | + bb = bb0 + or + not bb0.getANode().getAstNode() = parent and + if isPostOrder(parent) then bb = bb0.getASuccessor() else bb = bb0.getAPredecessor() + ) + or + exists(BasicBlock mid | + this.childNodeReachesBasicBlock(parent, child, cfnChild, mid) and + not mid = this.getARelevantBasicBlock(parent) and + if isPostOrder(parent) then bb = mid.getASuccessor() else bb = mid.getAPredecessor() + ) + } + + /** + * Holds if CFG node `cfnChild` can reach CFG node `cfnParent`, without going + * through an intermediate block that contains a CFG node for `parent`. + */ + pragma[nomagic] + predicate childNodeReachesParentNode( + AstNode parent, CfgNode cfnParent, AstNode child, CfgNode cfnChild + ) { + // `cfnChild` can reach `cfnParent` directly + exists(BasicBlock bb | + this.childNodeReachesBasicBlock(parent, child, cfnChild, bb) and + cfnParent.getAstNode() = parent + | + cfnParent = bb.getANode() + or + if isPostOrder(parent) + then cfnParent = bb.getASuccessor().getANode() + else cfnParent = bb.getAPredecessor().getANode() + ) + or + // `cfnChild` can reach `cfnParent` by going via another relevant child + exists(CfgNode cfnOtherChild | + this.childNodeReachesParentNode(parent, cfnParent, _, cfnOtherChild) and + exists(BasicBlock bb | + this.childNodeReachesBasicBlock(parent, child, cfnChild, bb) and + bb.getANode() = cfnOtherChild + ) + ) + } + + override predicate hasCfgChild(AstNode parent, AstNode child, AstCfgNode cfn, AstCfgNode cfnChild) { + Stages::CfgStage::ref() and + this.childNodeReachesParentNode(parent, cfn, child, cfnChild) + } +} diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll new file mode 100644 index 00000000000..1cd67ef2cd1 --- /dev/null +++ b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll @@ -0,0 +1,3657 @@ +// generated by codegen, do not edit +/** + * This module provides generated wrappers around the `CfgNode` type. + * + * INTERNAL: Do not import directly. + */ + +private import codeql.util.Location +private import codeql.util.Unit +private import codeql.rust.elements + +/** Provides the input to `MakeCfgNodes` */ +signature module InputSig { + class CfgNode { + AstNode getAstNode(); + + string toString(); + + Loc getLocation(); + } + + AstNode getDesugared(AstNode n); +} + +/** + * Given a `CfgNode` implementation, provides the module `Nodes` that + * contains wrappers around `CfgNode` for relevant classes. + */ +module MakeCfgNodes Input> { + private import Input + + final private class AstNodeFinal = AstNode; + + final private class CfgNodeFinal = CfgNode; + + /** + * INTERNAL: Do not expose. + */ + abstract class ParentAstNode extends AstNodeFinal { + /** + * Holds if `child` is a (possibly nested) child of this AST node + * for which we would like to find a matching CFG child. + */ + abstract predicate relevantChild(AstNode child); + } + + /** + * INTERNAL: Do not expose. + */ + abstract class ChildMapping extends Unit { + /** + * Holds if `child` is a (possibly nested) child of AST node `parent` + * for which we would like to find a matching CFG child. + */ + final predicate relevantChild(AstNode parent, AstNode child) { + parent.(ParentAstNode).relevantChild(child) + } + + /** + * Holds if there is a control-flow path from `cfn` to `cfnChild`, where `cfn` + * is a control-flow node for this AST node, and `cfnChild` is a control-flow + * node for `child`. + * + * This predicate should be implemented at the place where `MakeCfgNodes` is + * invoked. Ideally, `MakeCfgNodes` should be a higher-order parameterized + * module, but since that is currently not supported, we achieve the "callback" + * effect using this `abstract` class instead. + */ + cached + abstract predicate hasCfgChild(AstNode parent, AstNode child, CfgNode cfn, CfgNode cfnChild); + } + + /** Provides sub classes of `CfgNode`. */ + module Nodes { + final private class ParentArrayExpr extends ParentAstNode, ArrayExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr(_) + } + } + + /** + * An array expression. For example: + * ```rust + * [1, 2, 3]; + * [1; 10]; + * ``` + */ + final class ArrayExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private ArrayExpr node; + + ArrayExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `ArrayExpr`. */ + ArrayExpr getArrayExpr() { result = node } + + /** + * Gets the `index`th attr of this array expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this array expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this array expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the `index`th expression of this array expression (0-based). + */ + ExprCfgNode getExpr(int index) { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(index), this, result) + } + + /** + * Gets any of the expressions of this array expression. + */ + ExprCfgNode getAnExpr() { result = this.getExpr(_) } + + /** + * Gets the number of expressions of this array expression. + */ + int getNumberOfExprs() { result = count(int i | exists(this.getExpr(i))) } + } + + final private class ParentAsmExpr extends ParentAstNode, AsmExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr() + } + } + + /** + * An inline assembly expression. For example: + * ```rust + * unsafe { + * builtin # asm(_); + * } + * ``` + */ + final class AsmExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private AsmExpr node; + + AsmExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `AsmExpr`. */ + AsmExpr getAsmExpr() { result = node } + + /** + * Gets the `index`th attr of this asm expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this asm expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this asm expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the expression of this asm expression, if it exists. + */ + ExprCfgNode getExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + } + + /** + * Holds if `getExpr()` exists. + */ + predicate hasExpr() { exists(this.getExpr()) } + } + + final private class ParentAwaitExpr extends ParentAstNode, AwaitExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr() + } + } + + /** + * An `await` expression. For example: + * ```rust + * async { + * let x = foo().await; + * x + * } + * ``` + */ + final class AwaitExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private AwaitExpr node; + + AwaitExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `AwaitExpr`. */ + AwaitExpr getAwaitExpr() { result = node } + + /** + * Gets the `index`th attr of this await expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this await expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this await expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the expression of this await expression, if it exists. + */ + ExprCfgNode getExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + } + + /** + * Holds if `getExpr()` exists. + */ + predicate hasExpr() { exists(this.getExpr()) } + } + + final private class ParentBecomeExpr extends ParentAstNode, BecomeExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr() + } + } + + /** + * A `become` expression. For example: + * ```rust + * fn fact_a(n: i32, a: i32) -> i32 { + * if n == 0 { + * a + * } else { + * become fact_a(n - 1, n * a) + * } + * } + * ``` + */ + final class BecomeExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private BecomeExpr node; + + BecomeExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `BecomeExpr`. */ + BecomeExpr getBecomeExpr() { result = node } + + /** + * Gets the `index`th attr of this become expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this become expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this become expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the expression of this become expression, if it exists. + */ + ExprCfgNode getExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + } + + /** + * Holds if `getExpr()` exists. + */ + predicate hasExpr() { exists(this.getExpr()) } + } + + final private class ParentBinaryExpr extends ParentAstNode, BinaryExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getLhs() + or + child = this.getRhs() + } + } + + /** + * A binary operation expression. For example: + * ```rust + * x + y; + * x && y; + * x <= y; + * x = y; + * x += y; + * ``` + */ + final class BinaryExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private BinaryExpr node; + + BinaryExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `BinaryExpr`. */ + BinaryExpr getBinaryExpr() { result = node } + + /** + * Gets the `index`th attr of this binary expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this binary expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this binary expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the lhs of this binary expression, if it exists. + */ + ExprCfgNode getLhs() { + any(ChildMapping mapping).hasCfgChild(node, node.getLhs(), this, result) + } + + /** + * Holds if `getLhs()` exists. + */ + predicate hasLhs() { exists(this.getLhs()) } + + /** + * Gets the operator name of this binary expression, if it exists. + */ + string getOperatorName() { result = node.getOperatorName() } + + /** + * Holds if `getOperatorName()` exists. + */ + predicate hasOperatorName() { exists(this.getOperatorName()) } + + /** + * Gets the rhs of this binary expression, if it exists. + */ + ExprCfgNode getRhs() { + any(ChildMapping mapping).hasCfgChild(node, node.getRhs(), this, result) + } + + /** + * Holds if `getRhs()` exists. + */ + predicate hasRhs() { exists(this.getRhs()) } + } + + final private class ParentBlockExpr extends ParentAstNode, BlockExpr { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * A block expression. For example: + * ```rust + * { + * let x = 42; + * } + * ``` + * ```rust + * 'label: { + * let x = 42; + * x + * } + * ``` + */ + final class BlockExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private BlockExpr node; + + BlockExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `BlockExpr`. */ + BlockExpr getBlockExpr() { result = node } + + /** + * Gets the `index`th attr of this block expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this block expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this block expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Holds if this block expression is async. + */ + predicate isAsync() { node.isAsync() } + + /** + * Holds if this block expression is const. + */ + predicate isConst() { node.isConst() } + + /** + * Holds if this block expression is gen. + */ + predicate isGen() { node.isGen() } + + /** + * Holds if this block expression is move. + */ + predicate isMove() { node.isMove() } + + /** + * Holds if this block expression is try. + */ + predicate isTry() { node.isTry() } + + /** + * Holds if this block expression is unsafe. + */ + predicate isUnsafe() { node.isUnsafe() } + + /** + * Gets the label of this block expression, if it exists. + */ + Label getLabel() { result = node.getLabel() } + + /** + * Holds if `getLabel()` exists. + */ + predicate hasLabel() { exists(this.getLabel()) } + + /** + * Gets the statement list of this block expression, if it exists. + */ + StmtList getStmtList() { result = node.getStmtList() } + + /** + * Holds if `getStmtList()` exists. + */ + predicate hasStmtList() { exists(this.getStmtList()) } + } + + final private class ParentBoxPat extends ParentAstNode, BoxPat { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getPat() + } + } + + /** + * A box pattern. For example: + * ```rust + * match x { + * box Option::Some(y) => y, + * box Option::None => 0, + * }; + * ``` + */ + final class BoxPatCfgNode extends CfgNodeFinal, PatCfgNode { + private BoxPat node; + + BoxPatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `BoxPat`. */ + BoxPat getBoxPat() { result = node } + + /** + * Gets the pat of this box pat, if it exists. + */ + PatCfgNode getPat() { + any(ChildMapping mapping).hasCfgChild(node, node.getPat(), this, result) + } + + /** + * Holds if `getPat()` exists. + */ + predicate hasPat() { exists(this.getPat()) } + } + + final private class ParentBreakExpr extends ParentAstNode, BreakExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr() + } + } + + /** + * A break expression. For example: + * ```rust + * loop { + * if not_ready() { + * break; + * } + * } + * ``` + * ```rust + * let x = 'label: loop { + * if done() { + * break 'label 42; + * } + * }; + * ``` + * ```rust + * let x = 'label: { + * if exit() { + * break 'label 42; + * } + * 0; + * }; + * ``` + */ + final class BreakExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private BreakExpr node; + + BreakExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `BreakExpr`. */ + BreakExpr getBreakExpr() { result = node } + + /** + * Gets the `index`th attr of this break expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this break expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this break expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the expression of this break expression, if it exists. + */ + ExprCfgNode getExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + } + + /** + * Holds if `getExpr()` exists. + */ + predicate hasExpr() { exists(this.getExpr()) } + + /** + * Gets the lifetime of this break expression, if it exists. + */ + Lifetime getLifetime() { result = node.getLifetime() } + + /** + * Holds if `getLifetime()` exists. + */ + predicate hasLifetime() { exists(this.getLifetime()) } + } + + final private class ParentCallExpr extends ParentAstNode, CallExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr() + } + } + + /** + * A function call expression. For example: + * ```rust + * foo(42); + * foo::(42); + * foo[0](42); + * foo(1) = 4; + * ``` + */ + final class CallExprCfgNode extends CfgNodeFinal, CallExprBaseCfgNode { + private CallExpr node; + + CallExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `CallExpr`. */ + CallExpr getCallExpr() { result = node } + + /** + * Gets the expression of this call expression, if it exists. + */ + ExprCfgNode getExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + } + + /** + * Holds if `getExpr()` exists. + */ + predicate hasExpr() { exists(this.getExpr()) } + } + + final private class ParentCallExprBase extends ParentAstNode, CallExprBase { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * A function or method call expression. See `CallExpr` and `MethodCallExpr` for further details. + */ + final class CallExprBaseCfgNode extends CfgNodeFinal, ExprCfgNode { + private CallExprBase node; + + CallExprBaseCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `CallExprBase`. */ + CallExprBase getCallExprBase() { result = node } + + /** + * Gets the argument list of this call expression base, if it exists. + */ + ArgList getArgList() { result = node.getArgList() } + + /** + * Holds if `getArgList()` exists. + */ + predicate hasArgList() { exists(this.getArgList()) } + + /** + * Gets the `index`th attr of this call expression base (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this call expression base. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this call expression base. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + } + + final private class ParentConstBlockPat extends ParentAstNode, ConstBlockPat { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getBlockExpr() + } + } + + /** + * A const block pattern. For example: + * ```rust + * match x { + * const { 1 + 2 + 3 } => "ok", + * _ => "fail", + * }; + * ``` + */ + final class ConstBlockPatCfgNode extends CfgNodeFinal, PatCfgNode { + private ConstBlockPat node; + + ConstBlockPatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `ConstBlockPat`. */ + ConstBlockPat getConstBlockPat() { result = node } + + /** + * Gets the block expression of this const block pat, if it exists. + */ + BlockExprCfgNode getBlockExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getBlockExpr(), this, result) + } + + /** + * Holds if `getBlockExpr()` exists. + */ + predicate hasBlockExpr() { exists(this.getBlockExpr()) } + + /** + * Holds if this const block pat is const. + */ + predicate isConst() { node.isConst() } + } + + final private class ParentContinueExpr extends ParentAstNode, ContinueExpr { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * A continue expression. For example: + * ```rust + * loop { + * if not_ready() { + * continue; + * } + * } + * ``` + * ```rust + * 'label: loop { + * if not_ready() { + * continue 'label; + * } + * } + * ``` + */ + final class ContinueExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private ContinueExpr node; + + ContinueExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `ContinueExpr`. */ + ContinueExpr getContinueExpr() { result = node } + + /** + * Gets the `index`th attr of this continue expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this continue expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this continue expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the lifetime of this continue expression, if it exists. + */ + Lifetime getLifetime() { result = node.getLifetime() } + + /** + * Holds if `getLifetime()` exists. + */ + predicate hasLifetime() { exists(this.getLifetime()) } + } + + final private class ParentExpr extends ParentAstNode, Expr { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * The base class for expressions. + */ + final class ExprCfgNode extends CfgNodeFinal { + private Expr node; + + ExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `Expr`. */ + Expr getExpr() { result = node } + } + + final private class ParentFieldExpr extends ParentAstNode, FieldExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr() + } + } + + /** + * A field access expression. For example: + * ```rust + * x.foo + * ``` + */ + final class FieldExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private FieldExpr node; + + FieldExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `FieldExpr`. */ + FieldExpr getFieldExpr() { result = node } + + /** + * Gets the `index`th attr of this field expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this field expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this field expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the expression of this field expression, if it exists. + */ + ExprCfgNode getExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + } + + /** + * Holds if `getExpr()` exists. + */ + predicate hasExpr() { exists(this.getExpr()) } + + /** + * Gets the name reference of this field expression, if it exists. + */ + NameRef getNameRef() { result = node.getNameRef() } + + /** + * Holds if `getNameRef()` exists. + */ + predicate hasNameRef() { exists(this.getNameRef()) } + } + + final private class ParentForExpr extends ParentAstNode, ForExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getIterable() + or + child = this.getLoopBody() + or + child = this.getPat() + } + } + + /** + * A ForExpr. For example: + * ```rust + * todo!() + * ``` + */ + final class ForExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private ForExpr node; + + ForExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `ForExpr`. */ + ForExpr getForExpr() { result = node } + + /** + * Gets the `index`th attr of this for expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this for expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this for expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the iterable of this for expression, if it exists. + */ + ExprCfgNode getIterable() { + any(ChildMapping mapping).hasCfgChild(node, node.getIterable(), this, result) + } + + /** + * Holds if `getIterable()` exists. + */ + predicate hasIterable() { exists(this.getIterable()) } + + /** + * Gets the label of this for expression, if it exists. + */ + Label getLabel() { result = node.getLabel() } + + /** + * Holds if `getLabel()` exists. + */ + predicate hasLabel() { exists(this.getLabel()) } + + /** + * Gets the loop body of this for expression, if it exists. + */ + BlockExprCfgNode getLoopBody() { + any(ChildMapping mapping).hasCfgChild(node, node.getLoopBody(), this, result) + } + + /** + * Holds if `getLoopBody()` exists. + */ + predicate hasLoopBody() { exists(this.getLoopBody()) } + + /** + * Gets the pat of this for expression, if it exists. + */ + PatCfgNode getPat() { + any(ChildMapping mapping).hasCfgChild(node, node.getPat(), this, result) + } + + /** + * Holds if `getPat()` exists. + */ + predicate hasPat() { exists(this.getPat()) } + } + + final private class ParentFormatArgsExpr extends ParentAstNode, FormatArgsExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getTemplate() + } + } + + /** + * A FormatArgsExpr. For example: + * ```rust + * todo!() + * ``` + */ + final class FormatArgsExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private FormatArgsExpr node; + + FormatArgsExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `FormatArgsExpr`. */ + FormatArgsExpr getFormatArgsExpr() { result = node } + + /** + * Gets the `index`th argument of this format arguments expression (0-based). + */ + FormatArgsArg getArg(int index) { result = node.getArg(index) } + + /** + * Gets any of the arguments of this format arguments expression. + */ + FormatArgsArg getAnArg() { result = this.getArg(_) } + + /** + * Gets the number of arguments of this format arguments expression. + */ + int getNumberOfArgs() { result = count(int i | exists(this.getArg(i))) } + + /** + * Gets the `index`th attr of this format arguments expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this format arguments expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this format arguments expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the template of this format arguments expression, if it exists. + */ + ExprCfgNode getTemplate() { + any(ChildMapping mapping).hasCfgChild(node, node.getTemplate(), this, result) + } + + /** + * Holds if `getTemplate()` exists. + */ + predicate hasTemplate() { exists(this.getTemplate()) } + } + + final private class ParentFormatTemplateVariableAccess extends ParentAstNode, + FormatTemplateVariableAccess + { + override predicate relevantChild(AstNode child) { none() } + } + + /** + */ + final class FormatTemplateVariableAccessCfgNode extends CfgNodeFinal, PathExprBaseCfgNode { + private FormatTemplateVariableAccess node; + + FormatTemplateVariableAccessCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `FormatTemplateVariableAccess`. */ + FormatTemplateVariableAccess getFormatTemplateVariableAccess() { result = node } + } + + final private class ParentIdentPat extends ParentAstNode, IdentPat { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getPat() + } + } + + /** + * A binding pattern. For example: + * ```rust + * match x { + * Option::Some(y) => y, + * Option::None => 0, + * }; + * ``` + * ```rust + * match x { + * y@Option::Some(_) => y, + * Option::None => 0, + * }; + * ``` + */ + final class IdentPatCfgNode extends CfgNodeFinal, PatCfgNode { + private IdentPat node; + + IdentPatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `IdentPat`. */ + IdentPat getIdentPat() { result = node } + + /** + * Gets the `index`th attr of this ident pat (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this ident pat. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this ident pat. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Holds if this ident pat is mut. + */ + predicate isMut() { node.isMut() } + + /** + * Holds if this ident pat is reference. + */ + predicate isRef() { node.isRef() } + + /** + * Gets the name of this ident pat, if it exists. + */ + Name getName() { result = node.getName() } + + /** + * Holds if `getName()` exists. + */ + predicate hasName() { exists(this.getName()) } + + /** + * Gets the pat of this ident pat, if it exists. + */ + PatCfgNode getPat() { + any(ChildMapping mapping).hasCfgChild(node, node.getPat(), this, result) + } + + /** + * Holds if `getPat()` exists. + */ + predicate hasPat() { exists(this.getPat()) } + } + + final private class ParentIfExpr extends ParentAstNode, IfExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getCondition() + or + child = this.getElse() + or + child = this.getThen() + } + } + + /** + * An `if` expression. For example: + * ```rust + * if x == 42 { + * println!("that's the answer"); + * } + * ``` + * ```rust + * let y = if x > 0 { + * 1 + * } else { + * 0 + * }; + * ``` + */ + final class IfExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private IfExpr node; + + IfExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `IfExpr`. */ + IfExpr getIfExpr() { result = node } + + /** + * Gets the `index`th attr of this if expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this if expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this if expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the condition of this if expression, if it exists. + */ + ExprCfgNode getCondition() { + any(ChildMapping mapping).hasCfgChild(node, node.getCondition(), this, result) + } + + /** + * Holds if `getCondition()` exists. + */ + predicate hasCondition() { exists(this.getCondition()) } + + /** + * Gets the else of this if expression, if it exists. + */ + ExprCfgNode getElse() { + any(ChildMapping mapping).hasCfgChild(node, node.getElse(), this, result) + } + + /** + * Holds if `getElse()` exists. + */ + predicate hasElse() { exists(this.getElse()) } + + /** + * Gets the then of this if expression, if it exists. + */ + BlockExprCfgNode getThen() { + any(ChildMapping mapping).hasCfgChild(node, node.getThen(), this, result) + } + + /** + * Holds if `getThen()` exists. + */ + predicate hasThen() { exists(this.getThen()) } + } + + final private class ParentIndexExpr extends ParentAstNode, IndexExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getBase() + or + child = this.getIndex() + } + } + + /** + * An index expression. For example: + * ```rust + * list[42]; + * list[42] = 1; + * ``` + */ + final class IndexExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private IndexExpr node; + + IndexExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `IndexExpr`. */ + IndexExpr getIndexExpr() { result = node } + + /** + * Gets the `index`th attr of this index expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this index expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this index expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the base of this index expression, if it exists. + */ + ExprCfgNode getBase() { + any(ChildMapping mapping).hasCfgChild(node, node.getBase(), this, result) + } + + /** + * Holds if `getBase()` exists. + */ + predicate hasBase() { exists(this.getBase()) } + + /** + * Gets the index of this index expression, if it exists. + */ + ExprCfgNode getIndex() { + any(ChildMapping mapping).hasCfgChild(node, node.getIndex(), this, result) + } + + /** + * Holds if `getIndex()` exists. + */ + predicate hasIndex() { exists(this.getIndex()) } + } + + final private class ParentLetExpr extends ParentAstNode, LetExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr() + or + child = this.getPat() + } + } + + /** + * A `let` expression. For example: + * ```rust + * if let Some(x) = maybe_some { + * println!("{}", x); + * } + * ``` + */ + final class LetExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private LetExpr node; + + LetExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `LetExpr`. */ + LetExpr getLetExpr() { result = node } + + /** + * Gets the `index`th attr of this let expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this let expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this let expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the expression of this let expression, if it exists. + */ + ExprCfgNode getExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + } + + /** + * Holds if `getExpr()` exists. + */ + predicate hasExpr() { exists(this.getExpr()) } + + /** + * Gets the pat of this let expression, if it exists. + */ + PatCfgNode getPat() { + any(ChildMapping mapping).hasCfgChild(node, node.getPat(), this, result) + } + + /** + * Holds if `getPat()` exists. + */ + predicate hasPat() { exists(this.getPat()) } + } + + final private class ParentLetStmt extends ParentAstNode, LetStmt { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getInitializer() + or + child = this.getPat() + } + } + + /** + * A let statement. For example: + * ```rust + * let x = 42; + * let x: i32 = 42; + * let x: i32; + * let x; + * let (x, y) = (1, 2); + * let Some(x) = std::env::var("FOO") else { + * return; + * }; + * ``` + */ + final class LetStmtCfgNode extends CfgNodeFinal { + private LetStmt node; + + LetStmtCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `LetStmt`. */ + LetStmt getLetStmt() { result = node } + + /** + * Gets the `index`th attr of this let statement (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this let statement. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this let statement. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the initializer of this let statement, if it exists. + */ + ExprCfgNode getInitializer() { + any(ChildMapping mapping).hasCfgChild(node, node.getInitializer(), this, result) + } + + /** + * Holds if `getInitializer()` exists. + */ + predicate hasInitializer() { exists(this.getInitializer()) } + + /** + * Gets the let else of this let statement, if it exists. + */ + LetElse getLetElse() { result = node.getLetElse() } + + /** + * Holds if `getLetElse()` exists. + */ + predicate hasLetElse() { exists(this.getLetElse()) } + + /** + * Gets the pat of this let statement, if it exists. + */ + PatCfgNode getPat() { + any(ChildMapping mapping).hasCfgChild(node, node.getPat(), this, result) + } + + /** + * Holds if `getPat()` exists. + */ + predicate hasPat() { exists(this.getPat()) } + + /** + * Gets the ty of this let statement, if it exists. + */ + TypeRef getTy() { result = node.getTy() } + + /** + * Holds if `getTy()` exists. + */ + predicate hasTy() { exists(this.getTy()) } + } + + final private class ParentLiteralExpr extends ParentAstNode, LiteralExpr { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * A literal expression. For example: + * ```rust + * 42; + * 42.0; + * "Hello, world!"; + * b"Hello, world!"; + * 'x'; + * b'x'; + * r"Hello, world!"; + * true; + * ``` + */ + final class LiteralExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private LiteralExpr node; + + LiteralExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `LiteralExpr`. */ + LiteralExpr getLiteralExpr() { result = node } + + /** + * Gets the `index`th attr of this literal expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this literal expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this literal expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the text value of this literal expression, if it exists. + */ + string getTextValue() { result = node.getTextValue() } + + /** + * Holds if `getTextValue()` exists. + */ + predicate hasTextValue() { exists(this.getTextValue()) } + } + + final private class ParentLiteralPat extends ParentAstNode, LiteralPat { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getLiteral() + } + } + + /** + * A literal pattern. For example: + * ```rust + * match x { + * 42 => "ok", + * _ => "fail", + * } + * ``` + */ + final class LiteralPatCfgNode extends CfgNodeFinal, PatCfgNode { + private LiteralPat node; + + LiteralPatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `LiteralPat`. */ + LiteralPat getLiteralPat() { result = node } + + /** + * Gets the literal of this literal pat, if it exists. + */ + LiteralExprCfgNode getLiteral() { + any(ChildMapping mapping).hasCfgChild(node, node.getLiteral(), this, result) + } + + /** + * Holds if `getLiteral()` exists. + */ + predicate hasLiteral() { exists(this.getLiteral()) } + } + + final private class ParentLoopExpr extends ParentAstNode, LoopExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getLoopBody() + } + } + + /** + * A loop expression. For example: + * ```rust + * loop { + * println!("Hello, world (again)!"); + * }; + * ``` + * ```rust + * 'label: loop { + * println!("Hello, world (once)!"); + * break 'label; + * }; + * ``` + * ```rust + * let mut x = 0; + * loop { + * if x < 10 { + * x += 1; + * } else { + * break; + * } + * }; + * ``` + */ + final class LoopExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private LoopExpr node; + + LoopExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `LoopExpr`. */ + LoopExpr getLoopExpr() { result = node } + + /** + * Gets the `index`th attr of this loop expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this loop expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this loop expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the label of this loop expression, if it exists. + */ + Label getLabel() { result = node.getLabel() } + + /** + * Holds if `getLabel()` exists. + */ + predicate hasLabel() { exists(this.getLabel()) } + + /** + * Gets the loop body of this loop expression, if it exists. + */ + BlockExprCfgNode getLoopBody() { + any(ChildMapping mapping).hasCfgChild(node, node.getLoopBody(), this, result) + } + + /** + * Holds if `getLoopBody()` exists. + */ + predicate hasLoopBody() { exists(this.getLoopBody()) } + } + + final private class ParentMacroCall extends ParentAstNode, MacroCall { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * A MacroCall. For example: + * ```rust + * todo!() + * ``` + */ + final class MacroCallCfgNode extends CfgNodeFinal { + private MacroCall node; + + MacroCallCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `MacroCall`. */ + MacroCall getMacroCall() { result = node } + + /** + * Gets the `index`th attr of this macro call (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this macro call. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this macro call. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the path of this macro call, if it exists. + */ + Path getPath() { result = node.getPath() } + + /** + * Holds if `getPath()` exists. + */ + predicate hasPath() { exists(this.getPath()) } + + /** + * Gets the token tree of this macro call, if it exists. + */ + TokenTree getTokenTree() { result = node.getTokenTree() } + + /** + * Holds if `getTokenTree()` exists. + */ + predicate hasTokenTree() { exists(this.getTokenTree()) } + + /** + * Gets the expanded of this macro call, if it exists. + */ + AstNode getExpanded() { result = node.getExpanded() } + + /** + * Holds if `getExpanded()` exists. + */ + predicate hasExpanded() { exists(this.getExpanded()) } + } + + final private class ParentMacroExpr extends ParentAstNode, MacroExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getMacroCall() + } + } + + /** + * A MacroExpr. For example: + * ```rust + * todo!() + * ``` + */ + final class MacroExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private MacroExpr node; + + MacroExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `MacroExpr`. */ + MacroExpr getMacroExpr() { result = node } + + /** + * Gets the macro call of this macro expression, if it exists. + */ + MacroCallCfgNode getMacroCall() { + any(ChildMapping mapping).hasCfgChild(node, node.getMacroCall(), this, result) + } + + /** + * Holds if `getMacroCall()` exists. + */ + predicate hasMacroCall() { exists(this.getMacroCall()) } + } + + final private class ParentMacroPat extends ParentAstNode, MacroPat { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getMacroCall() + } + } + + /** + * A MacroPat. For example: + * ```rust + * todo!() + * ``` + */ + final class MacroPatCfgNode extends CfgNodeFinal, PatCfgNode { + private MacroPat node; + + MacroPatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `MacroPat`. */ + MacroPat getMacroPat() { result = node } + + /** + * Gets the macro call of this macro pat, if it exists. + */ + MacroCallCfgNode getMacroCall() { + any(ChildMapping mapping).hasCfgChild(node, node.getMacroCall(), this, result) + } + + /** + * Holds if `getMacroCall()` exists. + */ + predicate hasMacroCall() { exists(this.getMacroCall()) } + } + + final private class ParentMatchExpr extends ParentAstNode, MatchExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr() + } + } + + /** + * A match expression. For example: + * ```rust + * match x { + * Option::Some(y) => y, + * Option::None => 0, + * } + * ``` + * ```rust + * match x { + * Some(y) if y != 0 => 1 / y, + * _ => 0, + * } + * ``` + */ + final class MatchExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private MatchExpr node; + + MatchExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `MatchExpr`. */ + MatchExpr getMatchExpr() { result = node } + + /** + * Gets the `index`th attr of this match expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this match expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this match expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the expression of this match expression, if it exists. + */ + ExprCfgNode getExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + } + + /** + * Holds if `getExpr()` exists. + */ + predicate hasExpr() { exists(this.getExpr()) } + + /** + * Gets the match arm list of this match expression, if it exists. + */ + MatchArmList getMatchArmList() { result = node.getMatchArmList() } + + /** + * Holds if `getMatchArmList()` exists. + */ + predicate hasMatchArmList() { exists(this.getMatchArmList()) } + } + + final private class ParentMethodCallExpr extends ParentAstNode, MethodCallExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getReceiver() + } + } + + /** + * A method call expression. For example: + * ```rust + * x.foo(42); + * x.foo::(42); + * ``` + */ + final class MethodCallExprCfgNode extends CfgNodeFinal, CallExprBaseCfgNode { + private MethodCallExpr node; + + MethodCallExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `MethodCallExpr`. */ + MethodCallExpr getMethodCallExpr() { result = node } + + /** + * Gets the generic argument list of this method call expression, if it exists. + */ + GenericArgList getGenericArgList() { result = node.getGenericArgList() } + + /** + * Holds if `getGenericArgList()` exists. + */ + predicate hasGenericArgList() { exists(this.getGenericArgList()) } + + /** + * Gets the name reference of this method call expression, if it exists. + */ + NameRef getNameRef() { result = node.getNameRef() } + + /** + * Holds if `getNameRef()` exists. + */ + predicate hasNameRef() { exists(this.getNameRef()) } + + /** + * Gets the receiver of this method call expression, if it exists. + */ + ExprCfgNode getReceiver() { + any(ChildMapping mapping).hasCfgChild(node, node.getReceiver(), this, result) + } + + /** + * Holds if `getReceiver()` exists. + */ + predicate hasReceiver() { exists(this.getReceiver()) } + } + + final private class ParentOffsetOfExpr extends ParentAstNode, OffsetOfExpr { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * An `offset_of` expression. For example: + * ```rust + * builtin # offset_of(Struct, field); + * ``` + */ + final class OffsetOfExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private OffsetOfExpr node; + + OffsetOfExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `OffsetOfExpr`. */ + OffsetOfExpr getOffsetOfExpr() { result = node } + + /** + * Gets the `index`th attr of this offset of expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this offset of expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this offset of expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the `index`th field of this offset of expression (0-based). + */ + NameRef getField(int index) { result = node.getField(index) } + + /** + * Gets any of the fields of this offset of expression. + */ + NameRef getAField() { result = this.getField(_) } + + /** + * Gets the number of fields of this offset of expression. + */ + int getNumberOfFields() { result = count(int i | exists(this.getField(i))) } + + /** + * Gets the ty of this offset of expression, if it exists. + */ + TypeRef getTy() { result = node.getTy() } + + /** + * Holds if `getTy()` exists. + */ + predicate hasTy() { exists(this.getTy()) } + } + + final private class ParentOrPat extends ParentAstNode, OrPat { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getPat(_) + } + } + + /** + * An or pattern. For example: + * ```rust + * match x { + * Option::Some(y) | Option::None => 0, + * } + * ``` + */ + final class OrPatCfgNode extends CfgNodeFinal, PatCfgNode { + private OrPat node; + + OrPatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `OrPat`. */ + OrPat getOrPat() { result = node } + + /** + * Gets the `index`th pat of this or pat (0-based). + */ + PatCfgNode getPat(int index) { + any(ChildMapping mapping).hasCfgChild(node, node.getPat(index), this, result) + } + + /** + * Gets any of the pats of this or pat. + */ + PatCfgNode getAPat() { result = this.getPat(_) } + + /** + * Gets the number of pats of this or pat. + */ + int getNumberOfPats() { result = count(int i | exists(this.getPat(i))) } + } + + final private class ParentParam extends ParentAstNode, Param { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getPat() + } + } + + /** + * A Param. For example: + * ```rust + * todo!() + * ``` + */ + final class ParamCfgNode extends CfgNodeFinal { + private Param node; + + ParamCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `Param`. */ + Param getParam() { result = node } + + /** + * Gets the `index`th attr of this parameter (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this parameter. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this parameter. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the pat of this parameter, if it exists. + */ + PatCfgNode getPat() { + any(ChildMapping mapping).hasCfgChild(node, node.getPat(), this, result) + } + + /** + * Holds if `getPat()` exists. + */ + predicate hasPat() { exists(this.getPat()) } + + /** + * Gets the ty of this parameter, if it exists. + */ + TypeRef getTy() { result = node.getTy() } + + /** + * Holds if `getTy()` exists. + */ + predicate hasTy() { exists(this.getTy()) } + } + + final private class ParentPat extends ParentAstNode, Pat { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * The base class for patterns. + */ + final class PatCfgNode extends CfgNodeFinal { + private Pat node; + + PatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `Pat`. */ + Pat getPat() { result = node } + } + + final private class ParentPathExpr extends ParentAstNode, PathExpr { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * A path expression. For example: + * ```rust + * let x = variable; + * let x = foo::bar; + * let y = ::foo; + * let z = ::foo; + * ``` + */ + final class PathExprCfgNode extends CfgNodeFinal, PathExprBaseCfgNode { + private PathExpr node; + + PathExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `PathExpr`. */ + PathExpr getPathExpr() { result = node } + + /** + * Gets the `index`th attr of this path expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this path expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this path expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the path of this path expression, if it exists. + */ + Path getPath() { result = node.getPath() } + + /** + * Holds if `getPath()` exists. + */ + predicate hasPath() { exists(this.getPath()) } + } + + final private class ParentPathExprBase extends ParentAstNode, PathExprBase { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * A path expression or a variable access in a formatting template. See `PathExpr` and `FormatTemplateVariableAccess` for further details. + */ + final class PathExprBaseCfgNode extends CfgNodeFinal, ExprCfgNode { + private PathExprBase node; + + PathExprBaseCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `PathExprBase`. */ + PathExprBase getPathExprBase() { result = node } + } + + final private class ParentPathPat extends ParentAstNode, PathPat { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * A path pattern. For example: + * ```rust + * match x { + * Foo::Bar => "ok", + * _ => "fail", + * } + * ``` + */ + final class PathPatCfgNode extends CfgNodeFinal, PatCfgNode { + private PathPat node; + + PathPatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `PathPat`. */ + PathPat getPathPat() { result = node } + + /** + * Gets the path of this path pat, if it exists. + */ + Path getPath() { result = node.getPath() } + + /** + * Holds if `getPath()` exists. + */ + predicate hasPath() { exists(this.getPath()) } + } + + final private class ParentPrefixExpr extends ParentAstNode, PrefixExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr() + } + } + + /** + * A unary operation expression. For example: + * ```rust + * let x = -42; + * let y = !true; + * let z = *ptr; + * ``` + */ + final class PrefixExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private PrefixExpr node; + + PrefixExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `PrefixExpr`. */ + PrefixExpr getPrefixExpr() { result = node } + + /** + * Gets the `index`th attr of this prefix expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this prefix expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this prefix expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the expression of this prefix expression, if it exists. + */ + ExprCfgNode getExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + } + + /** + * Holds if `getExpr()` exists. + */ + predicate hasExpr() { exists(this.getExpr()) } + + /** + * Gets the operator name of this prefix expression, if it exists. + */ + string getOperatorName() { result = node.getOperatorName() } + + /** + * Holds if `getOperatorName()` exists. + */ + predicate hasOperatorName() { exists(this.getOperatorName()) } + } + + final private class ParentRangeExpr extends ParentAstNode, RangeExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getEnd() + or + child = this.getStart() + } + } + + /** + * A range expression. For example: + * ```rust + * let x = 1..=10; + * let x = 1..10; + * let x = 10..; + * let x = ..10; + * let x = ..=10; + * let x = ..; + * ``` + */ + final class RangeExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private RangeExpr node; + + RangeExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `RangeExpr`. */ + RangeExpr getRangeExpr() { result = node } + + /** + * Gets the `index`th attr of this range expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this range expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this range expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the end of this range expression, if it exists. + */ + ExprCfgNode getEnd() { + any(ChildMapping mapping).hasCfgChild(node, node.getEnd(), this, result) + } + + /** + * Holds if `getEnd()` exists. + */ + predicate hasEnd() { exists(this.getEnd()) } + + /** + * Gets the operator name of this range expression, if it exists. + */ + string getOperatorName() { result = node.getOperatorName() } + + /** + * Holds if `getOperatorName()` exists. + */ + predicate hasOperatorName() { exists(this.getOperatorName()) } + + /** + * Gets the start of this range expression, if it exists. + */ + ExprCfgNode getStart() { + any(ChildMapping mapping).hasCfgChild(node, node.getStart(), this, result) + } + + /** + * Holds if `getStart()` exists. + */ + predicate hasStart() { exists(this.getStart()) } + } + + final private class ParentRangePat extends ParentAstNode, RangePat { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getEnd() + or + child = this.getStart() + } + } + + /** + * A range pattern. For example: + * ```rust + * match x { + * ..15 => "too cold", + * 16..=25 => "just right", + * 26.. => "too hot", + * } + * ``` + */ + final class RangePatCfgNode extends CfgNodeFinal, PatCfgNode { + private RangePat node; + + RangePatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `RangePat`. */ + RangePat getRangePat() { result = node } + + /** + * Gets the end of this range pat, if it exists. + */ + PatCfgNode getEnd() { + any(ChildMapping mapping).hasCfgChild(node, node.getEnd(), this, result) + } + + /** + * Holds if `getEnd()` exists. + */ + predicate hasEnd() { exists(this.getEnd()) } + + /** + * Gets the operator name of this range pat, if it exists. + */ + string getOperatorName() { result = node.getOperatorName() } + + /** + * Holds if `getOperatorName()` exists. + */ + predicate hasOperatorName() { exists(this.getOperatorName()) } + + /** + * Gets the start of this range pat, if it exists. + */ + PatCfgNode getStart() { + any(ChildMapping mapping).hasCfgChild(node, node.getStart(), this, result) + } + + /** + * Holds if `getStart()` exists. + */ + predicate hasStart() { exists(this.getStart()) } + } + + final private class ParentRecordExpr extends ParentAstNode, RecordExpr { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * A record expression. For example: + * ```rust + * let first = Foo { a: 1, b: 2 }; + * let second = Foo { a: 2, ..first }; + * Foo { a: 1, b: 2 }[2] = 10; + * Foo { .. } = second; + * ``` + */ + final class RecordExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private RecordExpr node; + + RecordExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `RecordExpr`. */ + RecordExpr getRecordExpr() { result = node } + + /** + * Gets the path of this record expression, if it exists. + */ + Path getPath() { result = node.getPath() } + + /** + * Holds if `getPath()` exists. + */ + predicate hasPath() { exists(this.getPath()) } + + /** + * Gets the record expression field list of this record expression, if it exists. + */ + RecordExprFieldList getRecordExprFieldList() { result = node.getRecordExprFieldList() } + + /** + * Holds if `getRecordExprFieldList()` exists. + */ + predicate hasRecordExprFieldList() { exists(this.getRecordExprFieldList()) } + } + + final private class ParentRecordPat extends ParentAstNode, RecordPat { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * A record pattern. For example: + * ```rust + * match x { + * Foo { a: 1, b: 2 } => "ok", + * Foo { .. } => "fail", + * } + * ``` + */ + final class RecordPatCfgNode extends CfgNodeFinal, PatCfgNode { + private RecordPat node; + + RecordPatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `RecordPat`. */ + RecordPat getRecordPat() { result = node } + + /** + * Gets the path of this record pat, if it exists. + */ + Path getPath() { result = node.getPath() } + + /** + * Holds if `getPath()` exists. + */ + predicate hasPath() { exists(this.getPath()) } + + /** + * Gets the record pat field list of this record pat, if it exists. + */ + RecordPatFieldList getRecordPatFieldList() { result = node.getRecordPatFieldList() } + + /** + * Holds if `getRecordPatFieldList()` exists. + */ + predicate hasRecordPatFieldList() { exists(this.getRecordPatFieldList()) } + } + + final private class ParentRefExpr extends ParentAstNode, RefExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr() + } + } + + /** + * A reference expression. For example: + * ```rust + * let ref_const = &foo; + * let ref_mut = &mut foo; + * let raw_const: &mut i32 = &raw const foo; + * let raw_mut: &mut i32 = &raw mut foo; + * ``` + */ + final class RefExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private RefExpr node; + + RefExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `RefExpr`. */ + RefExpr getRefExpr() { result = node } + + /** + * Gets the `index`th attr of this reference expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this reference expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this reference expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the expression of this reference expression, if it exists. + */ + ExprCfgNode getExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + } + + /** + * Holds if `getExpr()` exists. + */ + predicate hasExpr() { exists(this.getExpr()) } + + /** + * Holds if this reference expression is const. + */ + predicate isConst() { node.isConst() } + + /** + * Holds if this reference expression is mut. + */ + predicate isMut() { node.isMut() } + + /** + * Holds if this reference expression is raw. + */ + predicate isRaw() { node.isRaw() } + } + + final private class ParentRefPat extends ParentAstNode, RefPat { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getPat() + } + } + + /** + * A reference pattern. For example: + * ```rust + * match x { + * &mut Option::Some(y) => y, + * &Option::None => 0, + * }; + * ``` + */ + final class RefPatCfgNode extends CfgNodeFinal, PatCfgNode { + private RefPat node; + + RefPatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `RefPat`. */ + RefPat getRefPat() { result = node } + + /** + * Holds if this reference pat is mut. + */ + predicate isMut() { node.isMut() } + + /** + * Gets the pat of this reference pat, if it exists. + */ + PatCfgNode getPat() { + any(ChildMapping mapping).hasCfgChild(node, node.getPat(), this, result) + } + + /** + * Holds if `getPat()` exists. + */ + predicate hasPat() { exists(this.getPat()) } + } + + final private class ParentRestPat extends ParentAstNode, RestPat { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * A RestPat. For example: + * ```rust + * todo!() + * ``` + */ + final class RestPatCfgNode extends CfgNodeFinal, PatCfgNode { + private RestPat node; + + RestPatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `RestPat`. */ + RestPat getRestPat() { result = node } + + /** + * Gets the `index`th attr of this rest pat (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this rest pat. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this rest pat. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + } + + final private class ParentReturnExpr extends ParentAstNode, ReturnExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr() + } + } + + /** + * A return expression. For example: + * ```rust + * fn some_value() -> i32 { + * return 42; + * } + * ``` + * ```rust + * fn no_value() -> () { + * return; + * } + * ``` + */ + final class ReturnExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private ReturnExpr node; + + ReturnExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `ReturnExpr`. */ + ReturnExpr getReturnExpr() { result = node } + + /** + * Gets the `index`th attr of this return expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this return expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this return expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the expression of this return expression, if it exists. + */ + ExprCfgNode getExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + } + + /** + * Holds if `getExpr()` exists. + */ + predicate hasExpr() { exists(this.getExpr()) } + } + + final private class ParentSlicePat extends ParentAstNode, SlicePat { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getPat(_) + } + } + + /** + * A slice pattern. For example: + * ```rust + * match x { + * [1, 2, 3, 4, 5] => "ok", + * [1, 2, ..] => "fail", + * [x, y, .., z, 7] => "fail", + * } + * ``` + */ + final class SlicePatCfgNode extends CfgNodeFinal, PatCfgNode { + private SlicePat node; + + SlicePatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `SlicePat`. */ + SlicePat getSlicePat() { result = node } + + /** + * Gets the `index`th pat of this slice pat (0-based). + */ + PatCfgNode getPat(int index) { + any(ChildMapping mapping).hasCfgChild(node, node.getPat(index), this, result) + } + + /** + * Gets any of the pats of this slice pat. + */ + PatCfgNode getAPat() { result = this.getPat(_) } + + /** + * Gets the number of pats of this slice pat. + */ + int getNumberOfPats() { result = count(int i | exists(this.getPat(i))) } + } + + final private class ParentTryExpr extends ParentAstNode, TryExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr() + } + } + + /** + * A TryExpr. For example: + * ```rust + * todo!() + * ``` + */ + final class TryExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private TryExpr node; + + TryExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `TryExpr`. */ + TryExpr getTryExpr() { result = node } + + /** + * Gets the `index`th attr of this try expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this try expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this try expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the expression of this try expression, if it exists. + */ + ExprCfgNode getExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + } + + /** + * Holds if `getExpr()` exists. + */ + predicate hasExpr() { exists(this.getExpr()) } + } + + final private class ParentTupleExpr extends ParentAstNode, TupleExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getField(_) + } + } + + /** + * A tuple expression. For example: + * ```rust + * (1, "one"); + * (2, "two")[0] = 3; + * ``` + */ + final class TupleExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private TupleExpr node; + + TupleExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `TupleExpr`. */ + TupleExpr getTupleExpr() { result = node } + + /** + * Gets the `index`th attr of this tuple expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this tuple expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this tuple expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the `index`th field of this tuple expression (0-based). + */ + ExprCfgNode getField(int index) { + any(ChildMapping mapping).hasCfgChild(node, node.getField(index), this, result) + } + + /** + * Gets any of the fields of this tuple expression. + */ + ExprCfgNode getAField() { result = this.getField(_) } + + /** + * Gets the number of fields of this tuple expression. + */ + int getNumberOfFields() { result = count(int i | exists(this.getField(i))) } + } + + final private class ParentTuplePat extends ParentAstNode, TuplePat { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getField(_) + } + } + + /** + * A tuple pattern. For example: + * ```rust + * let (x, y) = (1, 2); + * let (a, b, .., z) = (1, 2, 3, 4, 5); + * ``` + */ + final class TuplePatCfgNode extends CfgNodeFinal, PatCfgNode { + private TuplePat node; + + TuplePatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `TuplePat`. */ + TuplePat getTuplePat() { result = node } + + /** + * Gets the `index`th field of this tuple pat (0-based). + */ + PatCfgNode getField(int index) { + any(ChildMapping mapping).hasCfgChild(node, node.getField(index), this, result) + } + + /** + * Gets any of the fields of this tuple pat. + */ + PatCfgNode getAField() { result = this.getField(_) } + + /** + * Gets the number of fields of this tuple pat. + */ + int getNumberOfFields() { result = count(int i | exists(this.getField(i))) } + } + + final private class ParentTupleStructPat extends ParentAstNode, TupleStructPat { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getField(_) + } + } + + /** + * A tuple struct pattern. For example: + * ```rust + * match x { + * Tuple("a", 1, 2, 3) => "great", + * Tuple(.., 3) => "fine", + * Tuple(..) => "fail", + * }; + * ``` + */ + final class TupleStructPatCfgNode extends CfgNodeFinal, PatCfgNode { + private TupleStructPat node; + + TupleStructPatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `TupleStructPat`. */ + TupleStructPat getTupleStructPat() { result = node } + + /** + * Gets the `index`th field of this tuple struct pat (0-based). + */ + PatCfgNode getField(int index) { + any(ChildMapping mapping).hasCfgChild(node, node.getField(index), this, result) + } + + /** + * Gets any of the fields of this tuple struct pat. + */ + PatCfgNode getAField() { result = this.getField(_) } + + /** + * Gets the number of fields of this tuple struct pat. + */ + int getNumberOfFields() { result = count(int i | exists(this.getField(i))) } + + /** + * Gets the path of this tuple struct pat, if it exists. + */ + Path getPath() { result = node.getPath() } + + /** + * Holds if `getPath()` exists. + */ + predicate hasPath() { exists(this.getPath()) } + } + + final private class ParentUnderscoreExpr extends ParentAstNode, UnderscoreExpr { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * An underscore expression. For example: + * ```rust + * _ = 42; + * ``` + */ + final class UnderscoreExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private UnderscoreExpr node; + + UnderscoreExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `UnderscoreExpr`. */ + UnderscoreExpr getUnderscoreExpr() { result = node } + + /** + * Gets the `index`th attr of this underscore expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this underscore expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this underscore expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + } + + final private class ParentWhileExpr extends ParentAstNode, WhileExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getCondition() + or + child = this.getLoopBody() + } + } + + /** + * A WhileExpr. For example: + * ```rust + * todo!() + * ``` + */ + final class WhileExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private WhileExpr node; + + WhileExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `WhileExpr`. */ + WhileExpr getWhileExpr() { result = node } + + /** + * Gets the `index`th attr of this while expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this while expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this while expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the condition of this while expression, if it exists. + */ + ExprCfgNode getCondition() { + any(ChildMapping mapping).hasCfgChild(node, node.getCondition(), this, result) + } + + /** + * Holds if `getCondition()` exists. + */ + predicate hasCondition() { exists(this.getCondition()) } + + /** + * Gets the label of this while expression, if it exists. + */ + Label getLabel() { result = node.getLabel() } + + /** + * Holds if `getLabel()` exists. + */ + predicate hasLabel() { exists(this.getLabel()) } + + /** + * Gets the loop body of this while expression, if it exists. + */ + BlockExprCfgNode getLoopBody() { + any(ChildMapping mapping).hasCfgChild(node, node.getLoopBody(), this, result) + } + + /** + * Holds if `getLoopBody()` exists. + */ + predicate hasLoopBody() { exists(this.getLoopBody()) } + } + + final private class ParentWildcardPat extends ParentAstNode, WildcardPat { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * A wildcard pattern. For example: + * ```rust + * let _ = 42; + * ``` + */ + final class WildcardPatCfgNode extends CfgNodeFinal, PatCfgNode { + private WildcardPat node; + + WildcardPatCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `WildcardPat`. */ + WildcardPat getWildcardPat() { result = node } + } + + final private class ParentYeetExpr extends ParentAstNode, YeetExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr() + } + } + + /** + * A `yeet` expression. For example: + * ```rust + * if x < size { + * do yeet "index out of bounds"; + * } + * ``` + */ + final class YeetExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private YeetExpr node; + + YeetExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `YeetExpr`. */ + YeetExpr getYeetExpr() { result = node } + + /** + * Gets the `index`th attr of this yeet expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this yeet expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this yeet expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the expression of this yeet expression, if it exists. + */ + ExprCfgNode getExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + } + + /** + * Holds if `getExpr()` exists. + */ + predicate hasExpr() { exists(this.getExpr()) } + } + + final private class ParentYieldExpr extends ParentAstNode, YieldExpr { + override predicate relevantChild(AstNode child) { + none() + or + child = this.getExpr() + } + } + + /** + * A `yield` expression. For example: + * ```rust + * let one = #[coroutine] + * || { + * yield 1; + * }; + * ``` + */ + final class YieldExprCfgNode extends CfgNodeFinal, ExprCfgNode { + private YieldExpr node; + + YieldExprCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `YieldExpr`. */ + YieldExpr getYieldExpr() { result = node } + + /** + * Gets the `index`th attr of this yield expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this yield expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this yield expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the expression of this yield expression, if it exists. + */ + ExprCfgNode getExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + } + + /** + * Holds if `getExpr()` exists. + */ + predicate hasExpr() { exists(this.getExpr()) } + } + } + + module Consistency { + private predicate hasCfgNode(AstNode astNode) { astNode = any(CfgNode cfgNode).getAstNode() } + + query predicate missingCfgChild(CfgNode parent, string pred, int i, AstNode child) { + none() + or + pred = "getExpr" and + parent = + any(Nodes::ArrayExprCfgNode cfgNode, ArrayExpr astNode | + astNode = cfgNode.getArrayExpr() and + child = getDesugared(astNode.getExpr(i)) and + hasCfgNode(child) and + not child = cfgNode.getExpr(i).getAstNode() + | + cfgNode + ) + or + pred = "getExpr" and + parent = + any(Nodes::AsmExprCfgNode cfgNode, AsmExpr astNode | + astNode = cfgNode.getAsmExpr() and + child = getDesugared(astNode.getExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getExpr().getAstNode() + | + cfgNode + ) + or + pred = "getExpr" and + parent = + any(Nodes::AwaitExprCfgNode cfgNode, AwaitExpr astNode | + astNode = cfgNode.getAwaitExpr() and + child = getDesugared(astNode.getExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getExpr().getAstNode() + | + cfgNode + ) + or + pred = "getExpr" and + parent = + any(Nodes::BecomeExprCfgNode cfgNode, BecomeExpr astNode | + astNode = cfgNode.getBecomeExpr() and + child = getDesugared(astNode.getExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getExpr().getAstNode() + | + cfgNode + ) + or + pred = "getLhs" and + parent = + any(Nodes::BinaryExprCfgNode cfgNode, BinaryExpr astNode | + astNode = cfgNode.getBinaryExpr() and + child = getDesugared(astNode.getLhs()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getLhs().getAstNode() + | + cfgNode + ) + or + pred = "getRhs" and + parent = + any(Nodes::BinaryExprCfgNode cfgNode, BinaryExpr astNode | + astNode = cfgNode.getBinaryExpr() and + child = getDesugared(astNode.getRhs()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getRhs().getAstNode() + | + cfgNode + ) + or + pred = "getPat" and + parent = + any(Nodes::BoxPatCfgNode cfgNode, BoxPat astNode | + astNode = cfgNode.getBoxPat() and + child = getDesugared(astNode.getPat()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getPat().getAstNode() + | + cfgNode + ) + or + pred = "getExpr" and + parent = + any(Nodes::BreakExprCfgNode cfgNode, BreakExpr astNode | + astNode = cfgNode.getBreakExpr() and + child = getDesugared(astNode.getExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getExpr().getAstNode() + | + cfgNode + ) + or + pred = "getExpr" and + parent = + any(Nodes::CallExprCfgNode cfgNode, CallExpr astNode | + astNode = cfgNode.getCallExpr() and + child = getDesugared(astNode.getExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getExpr().getAstNode() + | + cfgNode + ) + or + pred = "getBlockExpr" and + parent = + any(Nodes::ConstBlockPatCfgNode cfgNode, ConstBlockPat astNode | + astNode = cfgNode.getConstBlockPat() and + child = getDesugared(astNode.getBlockExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getBlockExpr().getAstNode() + | + cfgNode + ) + or + pred = "getExpr" and + parent = + any(Nodes::FieldExprCfgNode cfgNode, FieldExpr astNode | + astNode = cfgNode.getFieldExpr() and + child = getDesugared(astNode.getExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getExpr().getAstNode() + | + cfgNode + ) + or + pred = "getIterable" and + parent = + any(Nodes::ForExprCfgNode cfgNode, ForExpr astNode | + astNode = cfgNode.getForExpr() and + child = getDesugared(astNode.getIterable()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getIterable().getAstNode() + | + cfgNode + ) + or + pred = "getLoopBody" and + parent = + any(Nodes::ForExprCfgNode cfgNode, ForExpr astNode | + astNode = cfgNode.getForExpr() and + child = getDesugared(astNode.getLoopBody()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getLoopBody().getAstNode() + | + cfgNode + ) + or + pred = "getPat" and + parent = + any(Nodes::ForExprCfgNode cfgNode, ForExpr astNode | + astNode = cfgNode.getForExpr() and + child = getDesugared(astNode.getPat()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getPat().getAstNode() + | + cfgNode + ) + or + pred = "getTemplate" and + parent = + any(Nodes::FormatArgsExprCfgNode cfgNode, FormatArgsExpr astNode | + astNode = cfgNode.getFormatArgsExpr() and + child = getDesugared(astNode.getTemplate()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getTemplate().getAstNode() + | + cfgNode + ) + or + pred = "getPat" and + parent = + any(Nodes::IdentPatCfgNode cfgNode, IdentPat astNode | + astNode = cfgNode.getIdentPat() and + child = getDesugared(astNode.getPat()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getPat().getAstNode() + | + cfgNode + ) + or + pred = "getCondition" and + parent = + any(Nodes::IfExprCfgNode cfgNode, IfExpr astNode | + astNode = cfgNode.getIfExpr() and + child = getDesugared(astNode.getCondition()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getCondition().getAstNode() + | + cfgNode + ) + or + pred = "getElse" and + parent = + any(Nodes::IfExprCfgNode cfgNode, IfExpr astNode | + astNode = cfgNode.getIfExpr() and + child = getDesugared(astNode.getElse()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getElse().getAstNode() + | + cfgNode + ) + or + pred = "getThen" and + parent = + any(Nodes::IfExprCfgNode cfgNode, IfExpr astNode | + astNode = cfgNode.getIfExpr() and + child = getDesugared(astNode.getThen()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getThen().getAstNode() + | + cfgNode + ) + or + pred = "getBase" and + parent = + any(Nodes::IndexExprCfgNode cfgNode, IndexExpr astNode | + astNode = cfgNode.getIndexExpr() and + child = getDesugared(astNode.getBase()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getBase().getAstNode() + | + cfgNode + ) + or + pred = "getIndex" and + parent = + any(Nodes::IndexExprCfgNode cfgNode, IndexExpr astNode | + astNode = cfgNode.getIndexExpr() and + child = getDesugared(astNode.getIndex()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getIndex().getAstNode() + | + cfgNode + ) + or + pred = "getExpr" and + parent = + any(Nodes::LetExprCfgNode cfgNode, LetExpr astNode | + astNode = cfgNode.getLetExpr() and + child = getDesugared(astNode.getExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getExpr().getAstNode() + | + cfgNode + ) + or + pred = "getPat" and + parent = + any(Nodes::LetExprCfgNode cfgNode, LetExpr astNode | + astNode = cfgNode.getLetExpr() and + child = getDesugared(astNode.getPat()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getPat().getAstNode() + | + cfgNode + ) + or + pred = "getInitializer" and + parent = + any(Nodes::LetStmtCfgNode cfgNode, LetStmt astNode | + astNode = cfgNode.getLetStmt() and + child = getDesugared(astNode.getInitializer()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getInitializer().getAstNode() + | + cfgNode + ) + or + pred = "getPat" and + parent = + any(Nodes::LetStmtCfgNode cfgNode, LetStmt astNode | + astNode = cfgNode.getLetStmt() and + child = getDesugared(astNode.getPat()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getPat().getAstNode() + | + cfgNode + ) + or + pred = "getLiteral" and + parent = + any(Nodes::LiteralPatCfgNode cfgNode, LiteralPat astNode | + astNode = cfgNode.getLiteralPat() and + child = getDesugared(astNode.getLiteral()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getLiteral().getAstNode() + | + cfgNode + ) + or + pred = "getLoopBody" and + parent = + any(Nodes::LoopExprCfgNode cfgNode, LoopExpr astNode | + astNode = cfgNode.getLoopExpr() and + child = getDesugared(astNode.getLoopBody()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getLoopBody().getAstNode() + | + cfgNode + ) + or + pred = "getMacroCall" and + parent = + any(Nodes::MacroExprCfgNode cfgNode, MacroExpr astNode | + astNode = cfgNode.getMacroExpr() and + child = getDesugared(astNode.getMacroCall()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getMacroCall().getAstNode() + | + cfgNode + ) + or + pred = "getMacroCall" and + parent = + any(Nodes::MacroPatCfgNode cfgNode, MacroPat astNode | + astNode = cfgNode.getMacroPat() and + child = getDesugared(astNode.getMacroCall()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getMacroCall().getAstNode() + | + cfgNode + ) + or + pred = "getExpr" and + parent = + any(Nodes::MatchExprCfgNode cfgNode, MatchExpr astNode | + astNode = cfgNode.getMatchExpr() and + child = getDesugared(astNode.getExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getExpr().getAstNode() + | + cfgNode + ) + or + pred = "getReceiver" and + parent = + any(Nodes::MethodCallExprCfgNode cfgNode, MethodCallExpr astNode | + astNode = cfgNode.getMethodCallExpr() and + child = getDesugared(astNode.getReceiver()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getReceiver().getAstNode() + | + cfgNode + ) + or + pred = "getPat" and + parent = + any(Nodes::OrPatCfgNode cfgNode, OrPat astNode | + astNode = cfgNode.getOrPat() and + child = getDesugared(astNode.getPat(i)) and + hasCfgNode(child) and + not child = cfgNode.getPat(i).getAstNode() + | + cfgNode + ) + or + pred = "getPat" and + parent = + any(Nodes::ParamCfgNode cfgNode, Param astNode | + astNode = cfgNode.getParam() and + child = getDesugared(astNode.getPat()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getPat().getAstNode() + | + cfgNode + ) + or + pred = "getExpr" and + parent = + any(Nodes::PrefixExprCfgNode cfgNode, PrefixExpr astNode | + astNode = cfgNode.getPrefixExpr() and + child = getDesugared(astNode.getExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getExpr().getAstNode() + | + cfgNode + ) + or + pred = "getEnd" and + parent = + any(Nodes::RangeExprCfgNode cfgNode, RangeExpr astNode | + astNode = cfgNode.getRangeExpr() and + child = getDesugared(astNode.getEnd()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getEnd().getAstNode() + | + cfgNode + ) + or + pred = "getStart" and + parent = + any(Nodes::RangeExprCfgNode cfgNode, RangeExpr astNode | + astNode = cfgNode.getRangeExpr() and + child = getDesugared(astNode.getStart()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getStart().getAstNode() + | + cfgNode + ) + or + pred = "getEnd" and + parent = + any(Nodes::RangePatCfgNode cfgNode, RangePat astNode | + astNode = cfgNode.getRangePat() and + child = getDesugared(astNode.getEnd()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getEnd().getAstNode() + | + cfgNode + ) + or + pred = "getStart" and + parent = + any(Nodes::RangePatCfgNode cfgNode, RangePat astNode | + astNode = cfgNode.getRangePat() and + child = getDesugared(astNode.getStart()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getStart().getAstNode() + | + cfgNode + ) + or + pred = "getExpr" and + parent = + any(Nodes::RefExprCfgNode cfgNode, RefExpr astNode | + astNode = cfgNode.getRefExpr() and + child = getDesugared(astNode.getExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getExpr().getAstNode() + | + cfgNode + ) + or + pred = "getPat" and + parent = + any(Nodes::RefPatCfgNode cfgNode, RefPat astNode | + astNode = cfgNode.getRefPat() and + child = getDesugared(astNode.getPat()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getPat().getAstNode() + | + cfgNode + ) + or + pred = "getExpr" and + parent = + any(Nodes::ReturnExprCfgNode cfgNode, ReturnExpr astNode | + astNode = cfgNode.getReturnExpr() and + child = getDesugared(astNode.getExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getExpr().getAstNode() + | + cfgNode + ) + or + pred = "getPat" and + parent = + any(Nodes::SlicePatCfgNode cfgNode, SlicePat astNode | + astNode = cfgNode.getSlicePat() and + child = getDesugared(astNode.getPat(i)) and + hasCfgNode(child) and + not child = cfgNode.getPat(i).getAstNode() + | + cfgNode + ) + or + pred = "getExpr" and + parent = + any(Nodes::TryExprCfgNode cfgNode, TryExpr astNode | + astNode = cfgNode.getTryExpr() and + child = getDesugared(astNode.getExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getExpr().getAstNode() + | + cfgNode + ) + or + pred = "getField" and + parent = + any(Nodes::TupleExprCfgNode cfgNode, TupleExpr astNode | + astNode = cfgNode.getTupleExpr() and + child = getDesugared(astNode.getField(i)) and + hasCfgNode(child) and + not child = cfgNode.getField(i).getAstNode() + | + cfgNode + ) + or + pred = "getField" and + parent = + any(Nodes::TuplePatCfgNode cfgNode, TuplePat astNode | + astNode = cfgNode.getTuplePat() and + child = getDesugared(astNode.getField(i)) and + hasCfgNode(child) and + not child = cfgNode.getField(i).getAstNode() + | + cfgNode + ) + or + pred = "getField" and + parent = + any(Nodes::TupleStructPatCfgNode cfgNode, TupleStructPat astNode | + astNode = cfgNode.getTupleStructPat() and + child = getDesugared(astNode.getField(i)) and + hasCfgNode(child) and + not child = cfgNode.getField(i).getAstNode() + | + cfgNode + ) + or + pred = "getCondition" and + parent = + any(Nodes::WhileExprCfgNode cfgNode, WhileExpr astNode | + astNode = cfgNode.getWhileExpr() and + child = getDesugared(astNode.getCondition()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getCondition().getAstNode() + | + cfgNode + ) + or + pred = "getLoopBody" and + parent = + any(Nodes::WhileExprCfgNode cfgNode, WhileExpr astNode | + astNode = cfgNode.getWhileExpr() and + child = getDesugared(astNode.getLoopBody()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getLoopBody().getAstNode() + | + cfgNode + ) + or + pred = "getExpr" and + parent = + any(Nodes::YeetExprCfgNode cfgNode, YeetExpr astNode | + astNode = cfgNode.getYeetExpr() and + child = getDesugared(astNode.getExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getExpr().getAstNode() + | + cfgNode + ) + or + pred = "getExpr" and + parent = + any(Nodes::YieldExprCfgNode cfgNode, YieldExpr astNode | + astNode = cfgNode.getYieldExpr() and + child = getDesugared(astNode.getExpr()) and + i = -1 and + hasCfgNode(child) and + not child = cfgNode.getExpr().getAstNode() + | + cfgNode + ) + } + } +} diff --git a/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll index f2784d058ae..cbe9653e493 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll @@ -14,6 +14,7 @@ private import codeql.rust.controlflow.ControlFlowGraph module Impl { private import rust private import codeql.rust.elements.internal.generated.ParentChild + private import codeql.rust.controlflow.ControlFlowGraph /** * Gets the immediate parent of a non-`AstNode` element `e`. @@ -62,5 +63,37 @@ module Impl { or this.getParentNode().isInMacroExpansion() } + + /** + * Gets a control-flow node for this AST node, if any. + * + * Note that because of _control-flow splitting_, one `AstNode` node may correspond + * to multiple `CfgNode`s. Example: + * + * ```rust + * if a && b { + * // ... + * } + * ``` + * + * The CFG for the condition above looks like + * + * ```mermaid + * flowchart TD + * 1["a"] + * 2["b"] + * 3["[false] a && b"] + * 4["[true] a && b"] + * + * 1 -- false --> 3 + * 1 -- true --> 2 + * 2 -- false --> 3 + * 2 -- true --> 4 + * ``` + * + * That is, the AST node for `a && b` corresponds to _two_ CFG nodes (it is + * split into two). + */ + CfgNode getACfgNode() { this = result.getAstNode() } } } diff --git a/rust/ql/lib/codeql/rust/internal/CachedStages.qll b/rust/ql/lib/codeql/rust/internal/CachedStages.qll index 162853846f2..3defe0b8168 100644 --- a/rust/ql/lib/codeql/rust/internal/CachedStages.qll +++ b/rust/ql/lib/codeql/rust/internal/CachedStages.qll @@ -71,6 +71,7 @@ module Stages { private import codeql.rust.controlflow.internal.Splitting private import codeql.rust.controlflow.internal.SuccessorType private import codeql.rust.controlflow.internal.ControlFlowGraphImpl + private import codeql.rust.controlflow.CfgNodes /** * Always holds. @@ -93,6 +94,8 @@ module Stages { exists(TNormalSuccessor()) or exists(AstCfgNode n) + or + exists(CallExprCfgNode n | exists(n.getExpr())) } } } diff --git a/rust/ql/test/query-tests/diagnostics/CfgConsistencyCounts.expected b/rust/ql/test/query-tests/diagnostics/CfgConsistencyCounts.expected index 7df2863da9e..7056936908c 100644 --- a/rust/ql/test/query-tests/diagnostics/CfgConsistencyCounts.expected +++ b/rust/ql/test/query-tests/diagnostics/CfgConsistencyCounts.expected @@ -1,5 +1,6 @@ | CFG scope lacks initial AST node | 0 | | Dead end | 0 | +| Missing CFG child | 0 | | Multiple successors of the same type | 0 | | Multiple toStrings | 0 | | Non-PostOrderTree Expr node | 0 | diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index d8e9835b16a..e84648ca662 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -18,14 +18,14 @@ class _: """ -@annotate(Expr) +@annotate(Expr, cfg = True) class _: """ The base class for expressions. """ -@annotate(Pat) +@annotate(Pat, cfg = True) class _: """ The base class for patterns. @@ -106,7 +106,7 @@ class PathExprBase(Expr): """ -@annotate(PathExpr, replace_bases={Expr: PathExprBase}) +@annotate(PathExpr, replace_bases={Expr: PathExprBase}, cfg = True) class _: """ A path expression. For example: @@ -119,7 +119,7 @@ class _: """ -@annotate(IfExpr) +@annotate(IfExpr, cfg = True) class _: """ An `if` expression. For example: @@ -138,7 +138,7 @@ class _: """ -@annotate(LetExpr) +@annotate(LetExpr, cfg = True) @rust.doc_test_signature("(maybe_some: Option) -> ()") class _: """ @@ -151,7 +151,7 @@ class _: """ -@annotate(BlockExpr) +@annotate(BlockExpr, cfg = True) class _: """ A block expression. For example: @@ -169,7 +169,7 @@ class _: """ -@annotate(LoopExpr) +@annotate(LoopExpr, cfg = True) class _: """ A loop expression. For example: @@ -205,7 +205,7 @@ class CallExprBase(Expr): attrs: list["Attr"] | child -@annotate(CallExpr, replace_bases={Expr: CallExprBase}) +@annotate(CallExpr, replace_bases={Expr: CallExprBase}, cfg = True) class _: """ A function call expression. For example: @@ -220,7 +220,7 @@ class _: attrs: drop -@annotate(MethodCallExpr, replace_bases={Expr: CallExprBase}, add_bases=(Resolvable,)) +@annotate(MethodCallExpr, replace_bases={Expr: CallExprBase}, add_bases=(Resolvable,), cfg = True) class _: """ A method call expression. For example: @@ -253,7 +253,7 @@ class _: """ -@annotate(MatchExpr) +@annotate(MatchExpr, cfg = True) @rust.doc_test_signature("(x: i32) -> i32") class _: """ @@ -273,7 +273,7 @@ class _: """ -@annotate(ContinueExpr) +@annotate(ContinueExpr, cfg = True) class _: """ A continue expression. For example: @@ -294,7 +294,7 @@ class _: """ -@annotate(BreakExpr) +@annotate(BreakExpr, cfg = True) class _: """ A break expression. For example: @@ -323,7 +323,7 @@ class _: """ -@annotate(ReturnExpr) +@annotate(ReturnExpr, cfg = True) @rust.doc_test_signature(None) class _: """ @@ -341,7 +341,7 @@ class _: """ -@annotate(BecomeExpr) +@annotate(BecomeExpr, cfg = True) @rust.doc_test_signature(None) class _: """ @@ -358,7 +358,7 @@ class _: """ -@annotate(YieldExpr) +@annotate(YieldExpr, cfg = True) class _: """ A `yield` expression. For example: @@ -371,7 +371,7 @@ class _: """ -@annotate(YeetExpr) +@annotate(YeetExpr, cfg = True) class _: """ A `yeet` expression. For example: @@ -393,7 +393,7 @@ class _: """ -@annotate(RecordExpr) +@annotate(RecordExpr, cfg = True) class _: """ A record expression. For example: @@ -406,7 +406,7 @@ class _: """ -@annotate(FieldExpr) +@annotate(FieldExpr, cfg = True) class _: """ A field access expression. For example: @@ -416,7 +416,7 @@ class _: """ -@annotate(AwaitExpr) +@annotate(AwaitExpr, cfg = True) class _: """ An `await` expression. For example: @@ -439,7 +439,7 @@ class _: """ -@annotate(RefExpr) +@annotate(RefExpr, cfg = True) class _: """ A reference expression. For example: @@ -452,7 +452,7 @@ class _: """ -@annotate(PrefixExpr) +@annotate(PrefixExpr, cfg = True) class _: """ A unary operation expression. For example: @@ -464,7 +464,7 @@ class _: """ -@annotate(BinaryExpr) +@annotate(BinaryExpr, cfg = True) class _: """ A binary operation expression. For example: @@ -478,7 +478,7 @@ class _: """ -@annotate(RangeExpr) +@annotate(RangeExpr, cfg = True) class _: """ A range expression. For example: @@ -493,7 +493,7 @@ class _: """ -@annotate(IndexExpr) +@annotate(IndexExpr, cfg = True) class _: """ An index expression. For example: @@ -520,7 +520,7 @@ class _: """ -@annotate(TupleExpr) +@annotate(TupleExpr, cfg = True) class _: """ A tuple expression. For example: @@ -531,7 +531,7 @@ class _: """ -@annotate(ArrayExpr) +@annotate(ArrayExpr, cfg = True) class _: """ An array expression. For example: @@ -542,7 +542,7 @@ class _: """ -@annotate(LiteralExpr) +@annotate(LiteralExpr, cfg = True) class _: """ A literal expression. For example: @@ -559,7 +559,7 @@ class _: """ -@annotate(UnderscoreExpr) +@annotate(UnderscoreExpr, cfg = True) class _: """ An underscore expression. For example: @@ -569,7 +569,7 @@ class _: """ -@annotate(OffsetOfExpr) +@annotate(OffsetOfExpr, cfg = True) class _: """ An `offset_of` expression. For example: @@ -579,7 +579,7 @@ class _: """ -@annotate(AsmExpr) +@annotate(AsmExpr, cfg = True) class _: """ An inline assembly expression. For example: @@ -591,7 +591,7 @@ class _: """ -@annotate(LetStmt) +@annotate(LetStmt, cfg = True) class _: """ A let statement. For example: @@ -620,7 +620,7 @@ class _: """ -@annotate(WildcardPat) +@annotate(WildcardPat, cfg = True) class _: """ A wildcard pattern. For example: @@ -630,7 +630,7 @@ class _: """ -@annotate(TuplePat) +@annotate(TuplePat, cfg = True) class _: """ A tuple pattern. For example: @@ -641,7 +641,7 @@ class _: """ -@annotate(OrPat) +@annotate(OrPat, cfg = True) class _: """ An or pattern. For example: @@ -663,7 +663,7 @@ class _: """ -@annotate(RecordPat) +@annotate(RecordPat, cfg = True) class _: """ A record pattern. For example: @@ -676,7 +676,7 @@ class _: """ -@annotate(RangePat) +@annotate(RangePat, cfg = True) class _: """ A range pattern. For example: @@ -690,7 +690,7 @@ class _: """ -@annotate(SlicePat) +@annotate(SlicePat, cfg = True) class _: """ A slice pattern. For example: @@ -704,7 +704,7 @@ class _: """ -@annotate(PathPat) +@annotate(PathPat, cfg = True) class _: """ A path pattern. For example: @@ -717,7 +717,7 @@ class _: """ -@annotate(LiteralPat) +@annotate(LiteralPat, cfg = True) class _: """ A literal pattern. For example: @@ -730,7 +730,7 @@ class _: """ -@annotate(IdentPat) +@annotate(IdentPat, cfg = True) class _: """ A binding pattern. For example: @@ -749,7 +749,7 @@ class _: """ -@annotate(TupleStructPat) +@annotate(TupleStructPat, cfg = True) class _: """ A tuple struct pattern. For example: @@ -763,7 +763,7 @@ class _: """ -@annotate(RefPat) +@annotate(RefPat, cfg = True) class _: """ A reference pattern. For example: @@ -776,7 +776,7 @@ class _: """ -@annotate(BoxPat) +@annotate(BoxPat, cfg = True) class _: """ A box pattern. For example: @@ -789,7 +789,7 @@ class _: """ -@annotate(ConstBlockPat) +@annotate(ConstBlockPat, cfg = True) class _: """ A const block pattern. For example: @@ -990,7 +990,7 @@ class _: """ -@annotate(ForExpr) +@annotate(ForExpr, cfg = True) class _: """ A ForExpr. For example: @@ -1020,7 +1020,7 @@ class _: """ -@annotate(FormatArgsExpr) +@annotate(FormatArgsExpr, cfg = True) class _: """ A FormatArgsExpr. For example: @@ -1150,7 +1150,7 @@ class _: """ -@annotate(MacroCall) +@annotate(MacroCall, cfg = True) class _: """ A MacroCall. For example: @@ -1171,7 +1171,7 @@ class _: """ -@annotate(MacroExpr) +@annotate(MacroExpr, cfg = True) class _: """ A MacroExpr. For example: @@ -1194,7 +1194,7 @@ class _: """ -@annotate(MacroPat) +@annotate(MacroPat, cfg = True) class _: """ A MacroPat. For example: @@ -1297,7 +1297,7 @@ class _: """ -@annotate(Param) +@annotate(Param, cfg = True) class _: """ A Param. For example: @@ -1437,7 +1437,7 @@ class _: """ -@annotate(RestPat) +@annotate(RestPat, cfg = True) class _: """ A RestPat. For example: @@ -1564,7 +1564,7 @@ class _: """ -@annotate(TryExpr) +@annotate(TryExpr, cfg = True) class _: """ A TryExpr. For example: @@ -1744,7 +1744,7 @@ class _: """ -@annotate(WhileExpr) +@annotate(WhileExpr, cfg = True) class _: """ A WhileExpr. For example: From ca18005e44a3127e3094c3d59dbd7a1d3fb0f1a0 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 19 Nov 2024 15:01:14 +0100 Subject: [PATCH 144/470] Rust: Add some manual classes to `CfgNodes.qll` --- .../lib/codeql/rust/controlflow/CfgNodes.qll | 199 +++++++++++++++--- .../rust/controlflow/internal/CfgNodes.qll | 32 +++ 2 files changed, 197 insertions(+), 34 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll index 1a7c7e212b9..b60a6b857b2 100644 --- a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll @@ -9,54 +9,185 @@ private import internal.ControlFlowGraphImpl as CfgImpl private import internal.CfgNodes import Nodes -/** A CFG node that corresponds to an element in the AST. */ -class AstCfgNode extends CfgNode { - AstNode node; +class AstCfgNode = CfgImpl::AstCfgNode; - AstCfgNode() { node = this.getAstNode() } +class ExitCfgNode = CfgImpl::ExitNode; - /** Gets the underlying ast node. */ - AstNode getAstNode() { result = node } +/** + * An assignment expression, for example + * + * ```rust + * x = y; + * ``` + */ +final class AssignmentExprCfgNode extends BinaryExprCfgNode { + AssignmentExpr a; + + AssignmentExprCfgNode() { a = this.getBinaryExpr() } + + /** Gets the underlying `AssignmentExpr`. */ + AssignmentExpr getAssignmentExpr() { result = a } } -/** A CFG node that corresponds to a parameter in the AST. */ -class ParamCfgNode extends AstCfgNode { - override Param node; +/** + * A match expression. For example: + * ```rust + * match x { + * Option::Some(y) => y, + * Option::None => 0, + * } + * ``` + * ```rust + * match x { + * Some(y) if y != 0 => 1 / y, + * _ => 0, + * } + * ``` + */ +final class MatchExprCfgNode extends Nodes::MatchExprCfgNode { + private MatchExpr node; - /** Gets the underlying parameter. */ - Param getParam() { result = node } + MatchExprCfgNode() { node = this.getMatchExpr() } + + /** + * Gets the pattern of the `i`th match arm, if it exists. + */ + PatCfgNode getArmPat(int i) { + any(ChildMapping mapping).hasCfgChild(node, node.getArm(i).getPat(), this, result) + } + + /** + * Gets the guard of the `i`th match arm, if it exists. + */ + ExprCfgNode getArmGuard(int i) { + any(ChildMapping mapping) + .hasCfgChild(node, node.getArm(i).getGuard().getCondition(), this, result) + } + + /** + * Gets the expression of the `i`th match arm, if it exists. + */ + ExprCfgNode getArmExpr(int i) { + any(ChildMapping mapping).hasCfgChild(node, node.getArm(i).getExpr(), this, result) + } } -/** A CFG node that corresponds to a parameter in the AST. */ -class PatCfgNode extends AstCfgNode { - override Pat node; +/** + * A block expression. For example: + * ```rust + * { + * let x = 42; + * } + * ``` + * ```rust + * 'label: { + * let x = 42; + * x + * } + * ``` + */ +final class BlockExprCfgNode extends Nodes::BlockExprCfgNode { + private BlockExprChildMapping node; - /** Gets the underlying pattern. */ - Pat getPat() { result = node } + BlockExprCfgNode() { node = this.getAstNode() } + + /** + * Gets the tail expression of this block, if it exists. + */ + ExprCfgNode getTailExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getStmtList().getTailExpr(), this, result) + } } -/** A CFG node that corresponds to an expression in the AST. */ -class ExprCfgNode extends AstCfgNode { - override Expr node; - - /** Gets the underlying expression. */ - Expr getExpr() { result = node } +/** + * A break expression. For example: + * ```rust + * loop { + * if not_ready() { + * break; + * } + * } + * ``` + * ```rust + * let x = 'label: loop { + * if done() { + * break 'label 42; + * } + * }; + * ``` + * ```rust + * let x = 'label: { + * if exit() { + * break 'label 42; + * } + * 0; + * }; + * ``` + */ +final class BreakExprCfgNode extends Nodes::BreakExprCfgNode { + /** + * Gets the target of this `break` expression. + * + * The target is either a `LoopExpr`, a `ForExpr`, a `WhileExpr`, or a + * `BlockExpr`. + */ + ExprCfgNode getTarget() { + any(ChildMapping mapping) + .hasCfgChild(this.getBreakExpr().getTarget(), this.getBreakExpr(), result, this) + } } -/** A CFG node that corresponds to a call in the AST. */ -class CallExprCfgNode extends ExprCfgNode { - override CallExpr node; +/** + * A function or method call expression. See `CallExpr` and `MethodCallExpr` for further details. + */ +final class CallExprBaseCfgNode extends Nodes::CallExprBaseCfgNode { + private CallExprBaseChildMapping node; - /** Gets the underlying `CallExpr`. */ - CallExpr getCallExpr() { result = node } + CallExprBaseCfgNode() { node = this.getAstNode() } + + /** Gets the `i`th argument of this call. */ + ExprCfgNode getArgument(int i) { + any(ChildMapping mapping).hasCfgChild(node, node.getArgList().getArg(i), this, result) + } } -/** A CFG node that corresponds to a call in the AST. */ -class MethodCallExprCfgNode extends ExprCfgNode { - override MethodCallExpr node; +/** + * A method call expression. For example: + * ```rust + * x.foo(42); + * x.foo::(42); + * ``` + */ +final class MethodCallExprCfgNode extends CallExprBaseCfgNode, Nodes::MethodCallExprCfgNode { } - /** Gets the underlying `MethodCallExpr`. */ - MethodCallExpr getMethodCallExpr() { result = node } +/** + * A function call expression. For example: + * ```rust + * foo(42); + * foo::(42); + * foo[0](42); + * foo(1) = 4; + * ``` + */ +final class CallExprCfgNode extends CallExprBaseCfgNode, Nodes::CallExprCfgNode { } + +/** + * A record expression. For example: + * ```rust + * let first = Foo { a: 1, b: 2 }; + * let second = Foo { a: 2, ..first }; + * Foo { a: 1, b: 2 }[2] = 10; + * Foo { .. } = second; + * ``` + */ +final class RecordExprCfgNode extends Nodes::RecordExprCfgNode { + private RecordExprChildMapping node; + + RecordExprCfgNode() { node = this.getRecordExpr() } + + /** Gets the `i`th record expression. */ + ExprCfgNode getExpr(int i) { + any(ChildMapping mapping) + .hasCfgChild(node, node.getRecordExprFieldList().getField(i).getExpr(), this, result) + } } - -final class ExitCfgNode = CfgImpl::ExitNode; diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll index 3f5b3c0e483..fc0df95f24a 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll @@ -40,6 +40,38 @@ private module CfgNodesInput implements InputSig { import MakeCfgNodes +class MatchExprChildMapping extends ParentAstNode, MatchExpr { + override predicate relevantChild(AstNode child) { + child = this.getAnArm().getPat() + or + child = this.getAnArm().getGuard().getCondition() + or + child = this.getAnArm().getExpr() + } +} + +class BlockExprChildMapping extends ParentAstNode, BlockExpr { + override predicate relevantChild(AstNode child) { child = this.getStmtList().getTailExpr() } +} + +class BreakExprTargetChildMapping extends ParentAstNode, Expr { + override predicate relevantChild(AstNode child) { child.(BreakExpr).getTarget() = this } +} + +class CallExprBaseChildMapping extends ParentAstNode, CallExprBase { + override predicate relevantChild(AstNode child) { child = this.getArgList().getAnArg() } +} + +class RecordExprChildMapping extends ParentAstNode, RecordExpr { + override predicate relevantChild(AstNode child) { + child = this.getRecordExprFieldList().getAField().getExpr() + } +} + +class FormatArgsExprChildMapping extends ParentAstNode, CfgImpl::ExprTrees::FormatArgsExprTree { + override predicate relevantChild(AstNode child) { child = this.getChildNode(_) } +} + private class ChildMappingImpl extends ChildMapping { /** Gets a CFG node for `child`, where `child` is a relevant child node of `parent`. */ private CfgNode getRelevantChildCfgNode(AstNode parent, AstNode child) { From e6887f982eb8d71a55ce61ce24d0f2bb2b26b752 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 19 Nov 2024 15:01:32 +0100 Subject: [PATCH 145/470] Rust: Use nodes from `CfgNodes.qll` in `DataFlowImpl.qll` --- rust/ql/lib/codeql/rust/dataflow/Ssa.qll | 9 +-- .../rust/dataflow/internal/DataFlowImpl.qll | 62 +++++++++---------- .../codeql/rust/dataflow/internal/SsaImpl.qll | 6 +- .../dataflow/local/DataFlowStep.expected | 5 +- .../dataflow/local/inline-flow.expected | 4 ++ .../test/library-tests/dataflow/local/main.rs | 2 +- rust/ql/test/utils/InlineFlowTest.qll | 9 +-- 7 files changed, 49 insertions(+), 48 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/Ssa.qll b/rust/ql/lib/codeql/rust/dataflow/Ssa.qll index ff1aae058aa..158128a12a9 100644 --- a/rust/ql/lib/codeql/rust/dataflow/Ssa.qll +++ b/rust/ql/lib/codeql/rust/dataflow/Ssa.qll @@ -9,6 +9,7 @@ module Ssa { private import rust private import codeql.rust.controlflow.BasicBlocks private import codeql.rust.controlflow.ControlFlowGraph + private import codeql.rust.controlflow.CfgNodes private import codeql.rust.controlflow.internal.ControlFlowGraphImpl as CfgImpl private import internal.SsaImpl as SsaImpl @@ -221,11 +222,11 @@ module Ssa { * end * ``` */ - predicate assigns(CfgNode value) { - exists(AssignmentExpr ae, BasicBlock bb, int i | + predicate assigns(ExprCfgNode value) { + exists(AssignmentExprCfgNode ae, BasicBlock bb, int i | this.definesAt(_, bb, i) and - ae.getLhs() = bb.getNode(i).getAstNode() and - value.getAstNode() = ae.getRhs() + ae.getLhs() = bb.getNode(i) and + value = ae.getRhs() ) } diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index c31ef9e8107..98024731257 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -48,7 +48,7 @@ final class DataFlowCall extends TDataFlowCall { MethodCallExprCfgNode asMethodCallExprCfgNode() { this = TMethodCall(result) } - ExprCfgNode asExprCfgNode() { + CallExprBaseCfgNode asExprCfgNode() { result = this.asCallExprCfgNode() or result = this.asMethodCallExprCfgNode() } @@ -76,7 +76,7 @@ module Node { /** * Gets the expression that corresponds to this node, if any. */ - Expr asExpr() { none() } + ExprCfgNode asExpr() { none() } /** Gets the enclosing callable. */ DataFlowCallable getEnclosingCallable() { result = TCfgScope(this.getCfgScope()) } @@ -115,13 +115,13 @@ module Node { abstract class AstCfgFlowNode extends Node { AstCfgNode n; - override CfgNode getCfgNode() { result = n } + final override CfgNode getCfgNode() { result = n } - override CfgScope getCfgScope() { result = n.getAstNode().getEnclosingCfgScope() } + final override CfgScope getCfgScope() { result = n.getAstNode().getEnclosingCfgScope() } - override Location getLocation() { result = n.getAstNode().getLocation() } + final override Location getLocation() { result = n.getAstNode().getLocation() } - override string toString() { result = n.getAstNode().toString() } + final override string toString() { result = n.getAstNode().toString() } } /** @@ -137,7 +137,7 @@ module Node { ExprNode() { this = TExprNode(n) } - override Expr asExpr() { result = n.getExpr() } + override ExprCfgNode asExpr() { result = n } } final class PatNode extends AstCfgFlowNode, TPatNode { @@ -159,7 +159,7 @@ module Node { ParameterNode() { this = TParameterNode(n) } /** Gets the parameter in the AST that this node corresponds to. */ - Param getParameter() { result = n.getParam() } + ParamCfgNode getParameter() { result = n } } final class ArgumentNode = NaNode; @@ -197,7 +197,7 @@ module Node { } final private class ExprOutNode extends ExprNode, OutNode { - ExprOutNode() { this.asExpr() instanceof CallExpr } + ExprOutNode() { this.asExpr() instanceof CallExprCfgNode } /** Gets the underlying call CFG node that includes this out node. */ override DataFlowCall getCall() { result.asExprCfgNode() = this.getCfgNode() } @@ -228,13 +228,13 @@ final class Node = Node::Node; module SsaFlow { private module Impl = SsaImpl::DataFlowIntegration; - private Node::ParameterNode toParameterNode(Param p) { result.getParameter() = p } + private Node::ParameterNode toParameterNode(ParamCfgNode p) { result.getParameter() = p } /** Converts a control flow node into an SSA control flow node. */ Impl::Node asNode(Node n) { n = TSsaNode(result) or - result.(Impl::ExprNode).getExpr() = n.(Node::ExprNode).getCfgNode() + result.(Impl::ExprNode).getExpr() = n.asExpr() or n = toParameterNode(result.(Impl::ParameterNode).getParameter()) } @@ -248,29 +248,18 @@ module SsaFlow { } } -/** - * Holds for expressions `e` that evaluate to the value of any last (in - * evaluation order) subexpressions within it. E.g., expressions that propagate - * a values from a subexpression. - * - * For instance, the predicate holds for if expressions as `if b { e1 } else { - * e2 }` evalates to the value of one of the subexpressions `e1` or `e2`. - */ -private predicate propagatesValue(Expr e) { - e instanceof IfExpr or - e instanceof LoopExpr or - e instanceof ReturnExpr or - e instanceof BreakExpr or - e.(BlockExpr).getStmtList().hasTailExpr() or - e instanceof MatchExpr -} - /** * Gets a node that may execute last in `n`, and which, when it executes last, * will be the value of `n`. */ -private ExprCfgNode getALastEvalNode(ExprCfgNode n) { - propagatesValue(n.getExpr()) and result.getASuccessor() = n +private ExprCfgNode getALastEvalNode(ExprCfgNode e) { + e = any(IfExprCfgNode n | result = [n.getThen(), n.getElse()]) or + result = e.(LoopExprCfgNode).getLoopBody() or + result = e.(ReturnExprCfgNode).getExpr() or + result = e.(BreakExprCfgNode).getExpr() or + result = e.(BlockExprCfgNode).getTailExpr() or + result = e.(MatchExprCfgNode).getArmExpr(_) or + result.(BreakExprCfgNode).getTarget() = e } module LocalFlow { @@ -278,9 +267,9 @@ module LocalFlow { predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) { nodeFrom.getCfgNode() = getALastEvalNode(nodeTo.getCfgNode()) or - exists(LetStmt s | - nodeFrom.getCfgNode().getAstNode() = s.getInitializer() and - nodeTo.getCfgNode().getAstNode() = s.getPat() + exists(LetStmtCfgNode s | + nodeFrom.getCfgNode() = s.getInitializer() and + nodeTo.getCfgNode() = s.getPat() ) or // An edge from a pattern/expression to its corresponding SSA definition. @@ -288,6 +277,11 @@ module LocalFlow { nodeTo.(Node::SsaNode).getDefinitionExt().(Ssa::WriteDefinition).getControlFlowNode() or SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _) + or + exists(AssignmentExprCfgNode a | + a.getRhs() = nodeFrom.getCfgNode() and + a.getLhs() = nodeTo.getCfgNode() + ) } } @@ -329,7 +323,7 @@ module RustDataFlow implements InputSig { class DataFlowExpr = ExprCfgNode; /** Gets the node corresponding to `e`. */ - Node exprNode(DataFlowExpr e) { result.getCfgNode() = e } + Node exprNode(DataFlowExpr e) { result.asExpr() = e } final class DataFlowCall = DataFlowCallAlias; diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll index d5263fca810..6e9032f1dc4 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll @@ -474,14 +474,14 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu /** Holds if SSA definition `def` assigns `value` to the underlying variable. */ predicate ssaDefAssigns(WriteDefinition def, Expr value) { - exists(BasicBlock bb, int i | def.definesAt(_, bb, i) and value = bb.getNode(i)) + none() // handled in `DataFlowImpl.qll` instead } - class Parameter = Param; + class Parameter = CfgNodes::ParamCfgNode; /** Holds if SSA definition `def` initializes parameter `p` at function entry. */ predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) { - exists(BasicBlock bb, int i | bb.getNode(i).getAstNode() = p and def.definesAt(_, bb, i)) + none() // handled in `DataFlowImpl.qll` instead } class Guard extends CfgNodes::AstCfgNode { diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index d52e9609600..1ccc9c219c3 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -46,6 +46,7 @@ | main.rs:51:17:51:17 | 1 | main.rs:51:9:51:13 | i | | main.rs:53:5:53:5 | [SSA] i | main.rs:54:10:54:10 | i | | main.rs:53:5:53:5 | i | main.rs:53:5:53:5 | [SSA] i | +| main.rs:53:9:53:17 | CallExpr | main.rs:53:5:53:5 | i | | main.rs:61:9:61:9 | [SSA] i | main.rs:62:11:62:11 | i | | main.rs:61:9:61:9 | i | main.rs:61:9:61:9 | [SSA] i | | main.rs:61:13:61:31 | CallExpr | main.rs:61:9:61:9 | i | @@ -93,7 +94,6 @@ | main.rs:122:9:122:9 | [SSA] a | main.rs:128:5:128:5 | a | | main.rs:122:9:122:9 | a | main.rs:122:9:122:9 | [SSA] a | | main.rs:122:13:127:5 | BlockExpr | main.rs:122:9:122:9 | a | -| main.rs:123:12:123:12 | b | main.rs:123:9:125:9 | IfExpr | | main.rs:124:13:124:26 | BreakExpr | main.rs:122:13:127:5 | BlockExpr | | main.rs:124:26:124:26 | 1 | main.rs:124:13:124:26 | BreakExpr | | main.rs:126:9:126:9 | 2 | main.rs:122:13:127:5 | BlockExpr | @@ -103,7 +103,8 @@ | main.rs:132:9:132:9 | [SSA] a | main.rs:138:5:138:5 | a | | main.rs:132:9:132:9 | a | main.rs:132:9:132:9 | [SSA] a | | main.rs:132:13:137:5 | BlockExpr | main.rs:132:9:132:9 | a | -| main.rs:133:12:133:12 | b | main.rs:133:9:135:9 | IfExpr | +| main.rs:134:13:134:26 | BreakExpr | main.rs:132:13:137:5 | BlockExpr | | main.rs:134:26:134:26 | 1 | main.rs:134:13:134:26 | BreakExpr | +| main.rs:136:9:136:22 | BreakExpr | main.rs:132:13:137:5 | BlockExpr | | main.rs:136:22:136:22 | 2 | main.rs:136:9:136:22 | BreakExpr | | main.rs:138:5:138:5 | a | main.rs:131:38:139:1 | BlockExpr | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index 72273334c6f..3cb35a1079f 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -4,6 +4,7 @@ edges | main.rs:24:13:24:21 | CallExpr : unit | main.rs:27:10:27:10 | c | provenance | | | main.rs:31:13:31:21 | CallExpr : unit | main.rs:36:10:36:10 | b | provenance | | | main.rs:45:15:45:23 | CallExpr : unit | main.rs:47:10:47:10 | b | provenance | | +| main.rs:53:9:53:17 | CallExpr : unit | main.rs:54:10:54:10 | i | provenance | | nodes | main.rs:15:10:15:18 | CallExpr | semmle.label | CallExpr | | main.rs:19:13:19:21 | CallExpr : unit | semmle.label | CallExpr : unit | @@ -14,6 +15,8 @@ nodes | main.rs:36:10:36:10 | b | semmle.label | b | | main.rs:45:15:45:23 | CallExpr : unit | semmle.label | CallExpr : unit | | main.rs:47:10:47:10 | b | semmle.label | b | +| main.rs:53:9:53:17 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:54:10:54:10 | i | semmle.label | i | subpaths testFailures #select @@ -22,3 +25,4 @@ testFailures | main.rs:27:10:27:10 | c | main.rs:24:13:24:21 | CallExpr : unit | main.rs:27:10:27:10 | c | $@ | main.rs:24:13:24:21 | CallExpr : unit | CallExpr : unit | | main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | CallExpr : unit | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | CallExpr : unit | CallExpr : unit | | main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | CallExpr : unit | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | CallExpr : unit | CallExpr : unit | +| main.rs:54:10:54:10 | i | main.rs:53:9:53:17 | CallExpr : unit | main.rs:54:10:54:10 | i | $@ | main.rs:53:9:53:17 | CallExpr : unit | CallExpr : unit | diff --git a/rust/ql/test/library-tests/dataflow/local/main.rs b/rust/ql/test/library-tests/dataflow/local/main.rs index dea41118b1d..50aa4fdb965 100644 --- a/rust/ql/test/library-tests/dataflow/local/main.rs +++ b/rust/ql/test/library-tests/dataflow/local/main.rs @@ -51,7 +51,7 @@ fn assignment() { let mut i = 1; sink(i); i = source(2); - sink(i); // $ MISSING: hasValueFlow=2 + sink(i); // $ hasValueFlow=2 } // ----------------------------------------------------------------------------- diff --git a/rust/ql/test/utils/InlineFlowTest.qll b/rust/ql/test/utils/InlineFlowTest.qll index b4960a055ee..ad196871273 100644 --- a/rust/ql/test/utils/InlineFlowTest.qll +++ b/rust/ql/test/utils/InlineFlowTest.qll @@ -5,26 +5,27 @@ import rust private import codeql.dataflow.test.InlineFlowTest +private import codeql.rust.controlflow.CfgNodes private import codeql.rust.dataflow.DataFlow private import codeql.rust.dataflow.internal.DataFlowImpl private import codeql.rust.dataflow.internal.TaintTrackingImpl private import internal.InlineExpectationsTestImpl as InlineExpectationsTestImpl // Holds if the target expression of `call` is a path and the string representation of the path is `name`. -private predicate callTargetName(CallExpr call, string name) { - call.getExpr().(PathExpr).toString() = name +private predicate callTargetName(CallExprCfgNode call, string name) { + call.getExpr().(PathExprCfgNode).toString() = name } private module FlowTestImpl implements InputSig { predicate defaultSource(DataFlow::Node source) { callTargetName(source.asExpr(), "source") } predicate defaultSink(DataFlow::Node sink) { - any(CallExpr call | callTargetName(call, "sink")).getArgList().getAnArg() = sink.asExpr() + any(CallExprCfgNode call | callTargetName(call, "sink")).getArgument(_) = sink.asExpr() } private string getSourceArgString(DataFlow::Node src) { defaultSource(src) and - result = src.asExpr().(CallExpr).getArgList().getArg(0).toString() + result = src.asExpr().(CallExprCfgNode).getArgument(0).toString() } bindingset[src, sink] From be7aca9780cab7e1f8d571c5ad93a518f67ddc3c Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 21 Nov 2024 10:32:06 +0100 Subject: [PATCH 146/470] Address review comments --- misc/codegen/codegen.py | 4 +- rust/ql/.generated.list | 2 +- .../controlflow/internal/CfgConsistency.qll | 7 +- .../internal/generated/CfgNodes.qll | 69 +++++++++++++++++++ .../rust/dataflow/internal/DataFlowImpl.qll | 2 +- rust/schema/annotations.py | 2 +- 6 files changed, 78 insertions(+), 8 deletions(-) diff --git a/misc/codegen/codegen.py b/misc/codegen/codegen.py index ce991b6f0d4..ae3a67d3fba 100755 --- a/misc/codegen/codegen.py +++ b/misc/codegen/codegen.py @@ -54,6 +54,8 @@ def _parse_args() -> argparse.Namespace: "generated qll file importing every class file"), p.add_argument("--ql-test-output", help="output directory for QL generated extractor test files"), + p.add_argument("--ql-cfg-output", + help="output directory for QL CFG layer (optional)."), p.add_argument("--cpp-output", help="output directory for generated C++ files, required if trap or cpp is provided to " "--generate"), @@ -64,8 +66,6 @@ def _parse_args() -> argparse.Namespace: help="registry file containing information about checked-in generated code. A .gitattributes" "file is generated besides it to mark those files with linguist-generated=true. Must" "be in a directory containing all generated code."), - p.add_argument("--ql-cfg-output", - help="output directory for QL CFG layer (optional)."), ] p.add_argument("--script-name", help="script name to put in header comments of generated files. By default, the path of this " diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 11980eb55df..f033f1982c7 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -1,4 +1,4 @@ -lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll 55c20303ad50f17ddea728eb840304e0a634821adb7b13471a9ce55b71ed3886 13509512ffb59a9634ed2dc3c4969af26d5ba2d1502d98dc0c107a99392ce892 +lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll 438e0b2d6e2dd5f137c1d5791c2f9bc97876acacadc09d56876567c8e6b197ce 8b967df7a91ec767faa2daf142db3bb0e276270789f81d1d887db9fcfd05ad88 lib/codeql/rust/elements/Abi.qll 4c973d28b6d628f5959d1f1cc793704572fd0acaae9a97dfce82ff9d73f73476 250f68350180af080f904cd34cb2af481c5c688dc93edf7365fd0ae99855e893 lib/codeql/rust/elements/ArgList.qll 661f5100f5d3ef8351452d9058b663a2a5c720eea8cf11bedd628969741486a2 28e424aac01a90fb58cd6f9f83c7e4cf379eea39e636bc0ba07efc818be71c71 lib/codeql/rust/elements/ArrayExpr.qll a3e6e122632f4011644ec31b37f88b32fe3f2b7e388e7e878a6883309937049f 12ccb5873d95c433da5606fd371d182ef2f71b78d0c53c2d6dec10fa45852bdc diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll b/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll index 0f178726ad8..62ac5822dbb 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll @@ -65,11 +65,12 @@ query predicate missingCfgChild(CfgNode parent, string pred, int i, AstNode chil CfgNodes::missingCfgChild(parent, pred, i, child) and successfullyExtractedFile(child.getLocation().getFile()) and not exists(AstNode last, CfgImpl::Completion c | CfgImpl::last(child, last, c) | - // In for example `if (a && true) ...` there is no RHS CFG node going into the - // `[false] a && true` operation + // In for example `if (a && true) ...`, there is no edge from the CFG node + // for `true` into the `[false] a && true` node. strictcount(ConditionalSuccessor cs | exists(last.getACfgNode().getASuccessor(cs)) | cs) = 1 or - // In for example `x && return`, there is no RHS CFG node going into the `&&` operation + // In for example `x && return`, there is no edge from the node for + // `return` into the `&&` node. not c instanceof CfgImpl::NormalCompletion ) } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll index 1cd67ef2cd1..4200c743a2f 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll @@ -2575,6 +2575,75 @@ module MakeCfgNodes Input> { predicate hasExpr() { exists(this.getExpr()) } } + final private class ParentSelfParam extends ParentAstNode, SelfParam { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * A SelfParam. For example: + * ```rust + * todo!() + * ``` + */ + final class SelfParamCfgNode extends CfgNodeFinal { + private SelfParam node; + + SelfParamCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `SelfParam`. */ + SelfParam getSelfParam() { result = node } + + /** + * Gets the `index`th attr of this self parameter (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this self parameter. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this self parameter. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Holds if this self parameter is mut. + */ + predicate isMut() { node.isMut() } + + /** + * Gets the lifetime of this self parameter, if it exists. + */ + Lifetime getLifetime() { result = node.getLifetime() } + + /** + * Holds if `getLifetime()` exists. + */ + predicate hasLifetime() { exists(this.getLifetime()) } + + /** + * Gets the name of this self parameter, if it exists. + */ + Name getName() { result = node.getName() } + + /** + * Holds if `getName()` exists. + */ + predicate hasName() { exists(this.getName()) } + + /** + * Gets the ty of this self parameter, if it exists. + */ + TypeRef getTy() { result = node.getTy() } + + /** + * Holds if `getTy()` exists. + */ + predicate hasTy() { exists(this.getTy()) } + } + final private class ParentSlicePat extends ParentAstNode, SlicePat { override predicate relevantChild(AstNode child) { none() diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 98024731257..1f205fc6949 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -158,7 +158,7 @@ module Node { ParameterNode() { this = TParameterNode(n) } - /** Gets the parameter in the AST that this node corresponds to. */ + /** Gets the parameter in the CFG that this node corresponds to. */ ParamCfgNode getParameter() { result = n } } diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index e84648ca662..ae94b0604e7 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -1467,7 +1467,7 @@ class _: """ -@annotate(SelfParam) +@annotate(SelfParam, cfg = True) class _: """ A SelfParam. For example: From 86a7c486f95b408dcaf5087f17b227be915bd5de Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 21 Nov 2024 10:42:11 +0100 Subject: [PATCH 147/470] Rust: "control-flow" -> "control flow" --- misc/codegen/templates/ql_cfg_nodes.mustache | 4 ++-- rust/ql/.generated.list | 2 +- .../rust/controlflow/internal/ControlFlowGraphImpl.qll | 2 +- rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll | 2 +- .../codeql/rust/controlflow/internal/generated/CfgNodes.qll | 4 ++-- rust/ql/lib/codeql/rust/dataflow/Ssa.qll | 6 +++--- rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll | 2 +- rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll | 4 ++-- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/misc/codegen/templates/ql_cfg_nodes.mustache b/misc/codegen/templates/ql_cfg_nodes.mustache index fd969b1c59b..a2edf4410be 100644 --- a/misc/codegen/templates/ql_cfg_nodes.mustache +++ b/misc/codegen/templates/ql_cfg_nodes.mustache @@ -57,8 +57,8 @@ module MakeCfgNodes Input> { } /** - * Holds if there is a control-flow path from `cfn` to `cfnChild`, where `cfn` - * is a control-flow node for this AST node, and `cfnChild` is a control-flow + * Holds if there is a control flow path from `cfn` to `cfnChild`, where `cfn` + * is a control flow node for this AST node, and `cfnChild` is a control flow * node for `child`. * * This predicate should be implemented at the place where `MakeCfgNodes` is diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index f033f1982c7..e3fe15f3e5b 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -1,4 +1,4 @@ -lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll 438e0b2d6e2dd5f137c1d5791c2f9bc97876acacadc09d56876567c8e6b197ce 8b967df7a91ec767faa2daf142db3bb0e276270789f81d1d887db9fcfd05ad88 +lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll e7bcae1016e1853d46d9c91dc5f9b81e81d207fdf91fdaa6eadb3bf185879674 541d386db1f0b662d0cbe1aface1bc6e4b1bc484d1230b95523f35ca63c08875 lib/codeql/rust/elements/Abi.qll 4c973d28b6d628f5959d1f1cc793704572fd0acaae9a97dfce82ff9d73f73476 250f68350180af080f904cd34cb2af481c5c688dc93edf7365fd0ae99855e893 lib/codeql/rust/elements/ArgList.qll 661f5100f5d3ef8351452d9058b663a2a5c720eea8cf11bedd628969741486a2 28e424aac01a90fb58cd6f9f83c7e4cf379eea39e636bc0ba07efc818be71c71 lib/codeql/rust/elements/ArrayExpr.qll a3e6e122632f4011644ec31b37f88b32fe3f2b7e388e7e878a6883309937049f 12ccb5873d95c433da5606fd371d182ef2f71b78d0c53c2d6dec10fa45852bdc diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 938b933cba0..df43d450a50 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -19,7 +19,7 @@ private module CfgInput implements InputSig { predicate completionIsValidFor = C::completionIsValidFor/2; - /** An AST node with an associated control-flow graph. */ + /** An AST node with an associated control flow graph. */ class CfgScope = Scope::CfgScope; CfgScope getCfgScope(AstNode n) { diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll index 7b3367690ec..cf779ed152f 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll @@ -4,7 +4,7 @@ private import ControlFlowGraphImpl private import codeql.rust.elements.internal.generated.ParentChild /** - * A control-flow graph (CFG) scope. + * A control flow graph (CFG) scope. */ abstract private class CfgScopeImpl extends AstNode { /** Holds if `first` is executed first when entering `scope`. */ diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll index 4200c743a2f..b42a00bf551 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll @@ -57,8 +57,8 @@ module MakeCfgNodes Input> { } /** - * Holds if there is a control-flow path from `cfn` to `cfnChild`, where `cfn` - * is a control-flow node for this AST node, and `cfnChild` is a control-flow + * Holds if there is a control flow path from `cfn` to `cfnChild`, where `cfn` + * is a control flow node for this AST node, and `cfnChild` is a control flow * node for `child`. * * This predicate should be implemented at the place where `MakeCfgNodes` is diff --git a/rust/ql/lib/codeql/rust/dataflow/Ssa.qll b/rust/ql/lib/codeql/rust/dataflow/Ssa.qll index 158128a12a9..5b452a329fa 100644 --- a/rust/ql/lib/codeql/rust/dataflow/Ssa.qll +++ b/rust/ql/lib/codeql/rust/dataflow/Ssa.qll @@ -27,7 +27,7 @@ module Ssa { } /** - * Gets a control-flow node that reads the value of this SSA definition. + * Gets a control flow node that reads the value of this SSA definition. * * Example: * @@ -54,7 +54,7 @@ module Ssa { final CfgNode getARead() { result = SsaImpl::getARead(this) } /** - * Gets a first control-flow node that reads the value of this SSA definition. + * Gets a first control flow node that reads the value of this SSA definition. * That is, a read that can be reached from this definition without passing * through other reads. * @@ -83,7 +83,7 @@ module Ssa { final CfgNode getAFirstRead() { SsaImpl::firstRead(this, result) } /** - * Gets a last control-flow node that reads the value of this SSA definition. + * Gets a last control flow node that reads the value of this SSA definition. * That is, a read that can reach the end of the enclosing CFG scope, or another * SSA definition for the source variable, without passing through any other read. * diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 1f205fc6949..210f12825cf 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -128,7 +128,7 @@ module Node { * A node in the data flow graph that corresponds to an expression in the * AST. * - * Note that because of control-flow splitting, one `Expr` may correspond + * Note that because of control flow splitting, one `Expr` may correspond * to multiple `ExprNode`s, just like it may correspond to multiple * `ControlFlow::Node`s. */ diff --git a/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll index cbe9653e493..c33b1f3dd6e 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll @@ -65,9 +65,9 @@ module Impl { } /** - * Gets a control-flow node for this AST node, if any. + * Gets a control flow node for this AST node, if any. * - * Note that because of _control-flow splitting_, one `AstNode` node may correspond + * Note that because of _control flow splitting_, one `AstNode` node may correspond * to multiple `CfgNode`s. Example: * * ```rust From 5012332bb28a3002ed12b196d7795f7b2ab032e9 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Nov 2024 11:12:29 +0100 Subject: [PATCH 148/470] Rust: fix `Path.toString` and address some review comments --- rust/ql/.generated.list | 40 +++++++++---------- rust/ql/.gitattributes | 30 +++++++------- rust/ql/lib/codeql/rust/elements/Path.qll | 1 + .../lib/codeql/rust/elements/PathSegment.qll | 5 +-- .../rust/elements/internal/BreakExprImpl.qll | 4 +- .../rust/elements/internal/CastExprImpl.qll | 2 +- .../elements/internal/ContinueExprImpl.qll | 6 ++- .../rust/elements/internal/EnumImpl.qll | 2 +- .../rust/elements/internal/FieldExprImpl.qll | 2 +- .../rust/elements/internal/ImplImpl.qll | 4 +- .../rust/elements/internal/LabelImpl.qll | 9 ++++- .../elements/internal/LabelableExprImpl.qll | 12 +++++- .../rust/elements/internal/LetElseImpl.qll | 4 +- .../rust/elements/internal/LetStmtImpl.qll | 6 ++- .../elements/internal/LiteralExprImpl.qll | 16 +++++++- .../rust/elements/internal/LiteralPatImpl.qll | 2 +- .../rust/elements/internal/MacroCallImpl.qll | 2 +- .../rust/elements/internal/PathImpl.qll | 5 +-- .../rust/elements/internal/PathPatImpl.qll | 2 +- .../elements/internal/PathSegmentImpl.qll | 20 ++++++---- .../rust/elements/internal/PathTypeImpl.qll | 4 +- .../elements/internal/RecordExprFieldImpl.qll | 2 +- .../rust/elements/internal/RecordPatImpl.qll | 2 +- .../rust/elements/internal/TraitImpl.qll | 2 +- .../rust/elements/internal/UnionImpl.qll | 2 +- .../rust/elements/internal/generated/Path.qll | 1 + .../internal/generated/PathSegment.qll | 5 +-- .../rust/elements/internal/generated/Raw.qll | 6 +-- .../generated/.generated_tests.list | 9 ++--- .../extractor-tests/generated/.gitattributes | 7 ++-- .../generated/Path/Path.expected | 25 +++++++++++- .../generated/Path/PathExpr.expected | 7 ++++ .../generated/{PathExpr => Path}/PathExpr.ql | 0 .../PathExpr_getAttr.expected | 0 .../{PathExpr => Path}/PathExpr_getAttr.ql | 0 .../generated/Path/PathExpr_getPath.expected | 7 ++++ .../{PathExpr => Path}/PathExpr_getPath.ql | 0 .../generated/Path/PathPat.expected | 1 + .../generated/{PathPat => Path}/PathPat.ql | 0 .../generated/Path/PathPat_getPath.expected | 1 + .../{PathPat => Path}/PathPat_getPath.ql | 0 .../generated/Path/PathSegment.expected | 23 +++++++++++ .../{PathSegment => Path}/PathSegment.ql | 0 .../PathSegment_getGenericArgList.expected | 0 .../PathSegment_getGenericArgList.ql | 0 .../Path/PathSegment_getNameRef.expected | 21 ++++++++++ .../PathSegment_getNameRef.ql | 0 .../PathSegment_getParamList.expected | 0 .../PathSegment_getParamList.ql | 0 .../Path/PathSegment_getPathType.expected | 2 + .../PathSegment_getPathType.ql | 0 .../PathSegment_getRetType.expected | 0 .../PathSegment_getRetType.ql | 0 .../PathSegment_getReturnTypeSyntax.expected | 0 .../PathSegment_getReturnTypeSyntax.ql | 0 .../generated/Path/PathSegment_getTy.expected | 2 + .../PathSegment_getTy.ql | 0 .../generated/Path/PathType.expected | 4 ++ .../generated/{PathType => Path}/PathType.ql | 0 .../generated/Path/PathType_getPath.expected | 4 ++ .../{PathType => Path}/PathType_getPath.ql | 0 .../generated/Path/Path_getPart.expected | 25 +++++++++++- .../generated/Path/Path_getQualifier.expected | 10 ++++- .../Path/Path_getResolvedCrateOrigin.expected | 2 + .../Path/Path_getResolvedPath.expected | 2 + .../generated/Path/gen_path.rs | 1 + .../{PathExpr => Path}/gen_path_expr.rs | 0 .../{PathPat => Path}/gen_path_pat.rs | 0 .../{PathType => Path}/gen_path_type.rs | 0 .../CONSISTENCY/DataFlowConsistency.expected | 3 -- .../generated/PathExpr/PathExpr.expected | 4 -- .../PathExpr/PathExpr_getPath.expected | 4 -- .../generated/PathPat/PathPat.expected | 1 - .../PathPat/PathPat_getPath.expected | 1 - .../PathSegment/PathSegment.expected | 4 -- .../PathSegment_getNameRef.expected | 4 -- .../PathSegment_getPathType.expected | 0 .../PathSegment/PathSegment_getTy.expected | 0 .../generated/PathSegment/gen_path_segment.rs | 6 --- .../generated/PathType/PathType.expected | 0 .../PathType/PathType_getPath.expected | 0 rust/schema/annotations.py | 10 +++-- 82 files changed, 261 insertions(+), 127 deletions(-) create mode 100644 rust/ql/test/extractor-tests/generated/Path/PathExpr.expected rename rust/ql/test/extractor-tests/generated/{PathExpr => Path}/PathExpr.ql (100%) rename rust/ql/test/extractor-tests/generated/{PathExpr => Path}/PathExpr_getAttr.expected (100%) rename rust/ql/test/extractor-tests/generated/{PathExpr => Path}/PathExpr_getAttr.ql (100%) create mode 100644 rust/ql/test/extractor-tests/generated/Path/PathExpr_getPath.expected rename rust/ql/test/extractor-tests/generated/{PathExpr => Path}/PathExpr_getPath.ql (100%) create mode 100644 rust/ql/test/extractor-tests/generated/Path/PathPat.expected rename rust/ql/test/extractor-tests/generated/{PathPat => Path}/PathPat.ql (100%) create mode 100644 rust/ql/test/extractor-tests/generated/Path/PathPat_getPath.expected rename rust/ql/test/extractor-tests/generated/{PathPat => Path}/PathPat_getPath.ql (100%) create mode 100644 rust/ql/test/extractor-tests/generated/Path/PathSegment.expected rename rust/ql/test/extractor-tests/generated/{PathSegment => Path}/PathSegment.ql (100%) rename rust/ql/test/extractor-tests/generated/{PathSegment => Path}/PathSegment_getGenericArgList.expected (100%) rename rust/ql/test/extractor-tests/generated/{PathSegment => Path}/PathSegment_getGenericArgList.ql (100%) create mode 100644 rust/ql/test/extractor-tests/generated/Path/PathSegment_getNameRef.expected rename rust/ql/test/extractor-tests/generated/{PathSegment => Path}/PathSegment_getNameRef.ql (100%) rename rust/ql/test/extractor-tests/generated/{PathSegment => Path}/PathSegment_getParamList.expected (100%) rename rust/ql/test/extractor-tests/generated/{PathSegment => Path}/PathSegment_getParamList.ql (100%) create mode 100644 rust/ql/test/extractor-tests/generated/Path/PathSegment_getPathType.expected rename rust/ql/test/extractor-tests/generated/{PathSegment => Path}/PathSegment_getPathType.ql (100%) rename rust/ql/test/extractor-tests/generated/{PathSegment => Path}/PathSegment_getRetType.expected (100%) rename rust/ql/test/extractor-tests/generated/{PathSegment => Path}/PathSegment_getRetType.ql (100%) rename rust/ql/test/extractor-tests/generated/{PathSegment => Path}/PathSegment_getReturnTypeSyntax.expected (100%) rename rust/ql/test/extractor-tests/generated/{PathSegment => Path}/PathSegment_getReturnTypeSyntax.ql (100%) create mode 100644 rust/ql/test/extractor-tests/generated/Path/PathSegment_getTy.expected rename rust/ql/test/extractor-tests/generated/{PathSegment => Path}/PathSegment_getTy.ql (100%) create mode 100644 rust/ql/test/extractor-tests/generated/Path/PathType.expected rename rust/ql/test/extractor-tests/generated/{PathType => Path}/PathType.ql (100%) create mode 100644 rust/ql/test/extractor-tests/generated/Path/PathType_getPath.expected rename rust/ql/test/extractor-tests/generated/{PathType => Path}/PathType_getPath.ql (100%) rename rust/ql/test/extractor-tests/generated/{PathExpr => Path}/gen_path_expr.rs (100%) rename rust/ql/test/extractor-tests/generated/{PathPat => Path}/gen_path_pat.rs (100%) rename rust/ql/test/extractor-tests/generated/{PathType => Path}/gen_path_type.rs (100%) delete mode 100644 rust/ql/test/extractor-tests/generated/PathExpr/CONSISTENCY/DataFlowConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/PathExpr/PathExpr.expected delete mode 100644 rust/ql/test/extractor-tests/generated/PathExpr/PathExpr_getPath.expected delete mode 100644 rust/ql/test/extractor-tests/generated/PathPat/PathPat.expected delete mode 100644 rust/ql/test/extractor-tests/generated/PathPat/PathPat_getPath.expected delete mode 100644 rust/ql/test/extractor-tests/generated/PathSegment/PathSegment.expected delete mode 100644 rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getNameRef.expected delete mode 100644 rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getPathType.expected delete mode 100644 rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getTy.expected delete mode 100644 rust/ql/test/extractor-tests/generated/PathSegment/gen_path_segment.rs delete mode 100644 rust/ql/test/extractor-tests/generated/PathType/PathType.expected delete mode 100644 rust/ql/test/extractor-tests/generated/PathType/PathType_getPath.expected diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 3e240b0b61d..4ab35c1b4b3 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -98,11 +98,11 @@ lib/codeql/rust/elements/ParenExpr.qll b635f0e5d300cd9cf3651cfcefd58316c21727295 lib/codeql/rust/elements/ParenPat.qll 40d033de6c85ad042223e0da80479adebab35494396ab652da85d3497e435c5a 8f2febe5d5cefcb076d201ae9607d403b9cfe8169d2f4b71d13868e0af43dc25 lib/codeql/rust/elements/ParenType.qll e1f5695b143c97b98ccdb460a5cf872461cfc13b83a4f005f26c288dc0afae10 1164f8efae7f255925411bddb33939fab0bf1c07955a16fef173b3f4675d09ae lib/codeql/rust/elements/Pat.qll 56211c5cb4709e7c12a2bfd2da5e413a451672d99e23a8386c08ad0b999fd45c b1b1893a13a75c4f0390f7e2a14ee98a46f067cfdc991a8d43adc82497d20aff -lib/codeql/rust/elements/Path.qll a0078e6d57dfd5a3b7fb2be4587f55f8e9c65ee042815a8a5b8dbd5273b4076a 0e2d4f8cbd54bd60aa4929b5fd50fe214346b6c0451f73e45143445d15420108 +lib/codeql/rust/elements/Path.qll 94869df09b929c4a60bae42b7e3a66c007f41078c08b7d9c6defb705b953ce8e eb317f75b89978d41fd3b166c7e3d871da4c04b3e17afbbcd0a5d73881e0d1d9 lib/codeql/rust/elements/PathExpr.qll 906df1d80c662b79f1b0b0428c39754b7f8dbcb2234919dd45dd8206a099dd36 1d6015afab6378c926c5838c9a5772cfcfeedf474e2eeca3e46085300ff8d4e1 lib/codeql/rust/elements/PathExprBase.qll bb41092ec690ae926e3233c215dcaf1fd8e161b8a6955151949f492e02dba13a b2257072f8062d31c29c63ee1311b07e0d2eb37075f582cfc76bb542ef773198 lib/codeql/rust/elements/PathPat.qll 6897e69bcb24b56d39ede796cf5767988dcd5741e02333fa8495dd7c814f771a 2a011fb92f17e4b4ff713e6d29f591054dfede22a9aaa006e67fca2c23ab76bf -lib/codeql/rust/elements/PathSegment.qll 536a8fe172db367e5f1dc678a014e2350eadfc379242d2b5451725e826ab1448 1a3a237f56c1d9ccdce6832ec6417fed25cd3e29ba836363cc6085e2125de4c5 +lib/codeql/rust/elements/PathSegment.qll 9560551cf8b65e84705e7f302e12b48330e048613129e87c0f65a7eb297a6cc3 3aa75a5fd81f8ea32bd2b4bf0c51c386de57cbe9ab035fe3ec68ad7fcf51b375 lib/codeql/rust/elements/PathType.qll a7bd3b05dc2c0e96c91c5485db508a1f5bb8fe3a01486be6815ae9dabb163add b11e996b6c0cc21a3d8d1ddc23c37e4d54a78e84a9278b3ceca1e94cb7321532 lib/codeql/rust/elements/PrefixExpr.qll 107e7bd111b637fd6d76026062d54c2780760b965f172ef119c50dd0714a377d 46954a9404e561c51682395729daac3bda5442113f29839d043e9605d63f7f6d lib/codeql/rust/elements/PtrType.qll b137f47a53e41b3b30c7d80dbdd6724bf15f99530ca40cc264a04af5f07aa878 b2ffdf739bfb7564d942fe54409834a59511c0b305b6d5b2219a8ee0ef594332 @@ -512,18 +512,18 @@ lib/codeql/rust/elements/internal/generated/ParenPat.qll ce24b8f8ecbf0f204af2003 lib/codeql/rust/elements/internal/generated/ParenType.qll 9cc954d73f8330dcac7b475f97748b63af5c8766dee9d2f2872c0a7e4c903537 c07534c8a9c683c4a9b11d490095647e420de0a0bfc23273eaf6f31b00244273 lib/codeql/rust/elements/internal/generated/ParentChild.qll 2237ba700c7d790cbbf7ad4d86889d22c6d210af62474ad8d363d79abb574722 36f9d47b002a241f0f793816ca9e6327fbbefb02268665553c56ded6012f82ec lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4 -lib/codeql/rust/elements/internal/generated/Path.qll f2b1be2f8f44001a6533533c978c4a9a8b7d64838d6f39eef5f0c0e7890611b8 d724a00a38f42429ffa8fb3bffbb5ec69e16a32ceeeb1d1f026fc7adf87424a8 +lib/codeql/rust/elements/internal/generated/Path.qll 4c1c8e840ed57880e574142b081b11d7a7428a009f10e3aa8f4645e211f6b2e0 989668cf0f1bdee7557e2f97c01e41d2a56848227fed41477833f5fc1e1d35f6 lib/codeql/rust/elements/internal/generated/PathExpr.qll 2096e3c1db22ee488a761690adabfc9cfdea501c99f7c5d96c0019cb113fc506 54245ce0449c4e263173213df01e079d5168a758503a5dbd61b25ad35a311140 lib/codeql/rust/elements/internal/generated/PathExprBase.qll d8218e201b8557fa6d9ca2c30b764e5ad9a04a2e4fb695cc7219bbd7636a6ac2 4ef178426d7095a156f4f8c459b4d16f63abc64336cb50a6cf883a5f7ee09113 lib/codeql/rust/elements/internal/generated/PathPat.qll 98c9938d6a359fd717829b196eb09701d2c798e18c1f43fa7b2a9145afdf6c19 caba2e629cae08682baac90a76ae9a48cda2d7d6f9c23d506fa0ff3f292978a4 -lib/codeql/rust/elements/internal/generated/PathSegment.qll 4621597fd86246f788b8f9ca73f6b0f27929fc04261ce3ccf85da1183071431d aadda8bce386a3b7a9c53b98465eedcc4f724e37b8a904c1775af5b7ffb041ee +lib/codeql/rust/elements/internal/generated/PathSegment.qll 0fa07886deb0fc4d909d7edf691238a344f2739900aafb168cbac171eb1729a8 8f4bb418d8bea5e40128a87977c57d0a9183d06d111601ad93130c8615c11465 lib/codeql/rust/elements/internal/generated/PathType.qll 45de78e5374d6eb0446e2112ec72d3692c2811df9fa2ad03d0127e426940abe3 622cf70408413a565a0dac58f451035ac1339c8d0ee5b24f630680201cb0aa48 lib/codeql/rust/elements/internal/generated/PrefixExpr.qll c9ede5f2deb7b41bc8240969e8554f645057018fe96e7e9ad9c2924c8b14722b 5ae2e3c3dc8fa73e7026ef6534185afa6b0b5051804435d8b741dd3640c864e1 lib/codeql/rust/elements/internal/generated/PtrType.qll 40099c5a4041314b66932dfd777c9e2bef90a0711fb8d7c2c2cec764c003ac4a cf8297d93557356a572223d3e8acca701837c4b1f54e8d4351ba195fb7ed27f8 lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll efd93730de217cf50dcba5875595263a5eadf9f7e4e1272401342a094d158614 229b251b3d118932e31e78ac4dfb75f48b766f240f20d436062785606d44467b -lib/codeql/rust/elements/internal/generated/Raw.qll 462d87edee9e0fc463f789a765e19d94c4c027a73db876ad306f918dd87e9511 33a6782598a6ba0e02e6b772b5b74ebbe609b0bc3a92180f85db7472e00aa8d9 +lib/codeql/rust/elements/internal/generated/Raw.qll fd2eeb93f84b668f5083ecad8ff5f5d4bbdfcf4c65f4a40907aca47e33b031d6 de433b9feec8276ed34d106b97c7b66d81206a21a2b5343253f4cf799f1bf567 lib/codeql/rust/elements/internal/generated/RecordExpr.qll eb6cb662e463f9260efae1a6ce874fa781172063b916ef1963f861e9942d308d 1a21cbccc8f3799ff13281e822818ebfb21d81591720a427cac3625512cb9d40 lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1 lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0 @@ -888,25 +888,25 @@ test/extractor-tests/generated/ParenPat/ParenPat_getPat.ql 96f3db0ec4e71fd870619 test/extractor-tests/generated/ParenType/ParenType.ql 81c8ad667397ce36157941abd9b879e9305a440018853af4528eb737ae4d2935 3ef3b86203b0143be2d7f7f4833f55fd6c226cb9205e3c1940b6c2a1371622f3 test/extractor-tests/generated/ParenType/ParenType_getTy.ql 41dd6605e7b348618156712b559e2f1b6aac02d6c727e8cbf8653530794ec969 30ac6611c730e76cfb75f98efcf817783a50cec0cf3b3197459d7642f74dde85 test/extractor-tests/generated/Path/Path.ql f17c1c4d23c0d5e9776cee84444f6ee7445de88afbc1f26c34b96e13ab618158 89499cb0f63b3634d6b5e2b8c4a13bd4401ce82e54af0ab46e41a34b0288eeb9 +test/extractor-tests/generated/Path/PathExpr.ql b9696cd7ad9f3874e4bc4b1b9c77f42f06ab6c61b77fb641458da63667087b9b db84a7a8dd05e30ff80733af01f08d43ff031bb4b3e3af06332a73ba7e7bbc43 +test/extractor-tests/generated/Path/PathExpr_getAttr.ql 2ccac48cd91d86670c1d2742de20344135d424e6f0e3dafcc059555046f92d92 9b7b5f5f9e3674fad9b3a5bcd3cabc0dff32a95640da0fce6f4d0eb931f1757d +test/extractor-tests/generated/Path/PathExpr_getPath.ql e7894071313a74166bdd31d7cd974037fcd5a7f0e92d5eec42833266196eb858 46a06e8a1207e7a0fa175cd4b61068e5fd6c43b5575b88986409f0ac2be64c51 +test/extractor-tests/generated/Path/PathPat.ql 823732954a5882e33a37bd0bf0cafb2cec51659a5203a4831eec2516da0e49fa 54001149718a9ca15d8c0d4be63f3fe00a9f0d44fa1309e2f605d7932355ea5d +test/extractor-tests/generated/Path/PathPat_getPath.ql 6c0c71c80a6e631ea7775ec8660b470ff6b264bab14a399606cf113b1fb190fc 8e34cbb4d064db929e94652e1901ec4f26affa71e30e556b7acdff71dd622cbb +test/extractor-tests/generated/Path/PathSegment.ql efc39cea1b4c0b2b0da6434136334430d074699f84124d6bcf94c24aa854dc64 c0a4bd60c67665c058ca22a59e535e925fdb00dec95ffc5c71697fb0ed78a329 +test/extractor-tests/generated/Path/PathSegment_getGenericArgList.ql 8f6e67b3e316309f20e21d7e7944accf66b0256b76fa50ee9a714044c6ec8cea 15f10a701fc4d3f9fd6734da90790cdbc8a1ddd57bf52695740acedcb2e6e485 +test/extractor-tests/generated/Path/PathSegment_getNameRef.ql 799d284e2f9267d6bbe67aa7035e525ef347dc74cb3e2180e7b2171b5cb49674 592130bc2358989536abf62e8a261272c851483ede4f19783f7d61ffc1803e4b +test/extractor-tests/generated/Path/PathSegment_getParamList.ql e1e7b9b5062f936c33b7e7e29b21456448242df4985c6cffb54900063cfd3e63 6568e851cb6bcb32622f89d01e3aa6e7dd21940d21572a9988584e34bdf25366 +test/extractor-tests/generated/Path/PathSegment_getPathType.ql 01942da6d0b10c1d15caec6abb8c53f1dc7f8c04a91a797f572063aa003dbc4b cb21e6cb160652527ba571265297dae86beffe191dd7dfc4d0beee45cb0cda29 +test/extractor-tests/generated/Path/PathSegment_getRetType.ql 36386a514bc925f5b17ad87afba9fef7986900c1b791732de061213c6e86743f f38bcee68c1da19e70bb1e1c4a4047c763a466f1b8ef2c4f65f8c724c0b58197 +test/extractor-tests/generated/Path/PathSegment_getReturnTypeSyntax.ql d1db51208a311c30af369ce2fdc3a3296e7d598b27bf4960b8b34622a9d9163b 561b1e38c6d8b301fdc016e1d012dd805fde1b42b0720c17d7b15535715047f2 +test/extractor-tests/generated/Path/PathSegment_getTy.ql a0ceaf3f37e521cc92c21cc0bae929499ef3584f86349ef34808c20963d31c75 d674e56e08a6d2a7d211503a466df2cc90c35a3951e41598febf62c8dc693655 +test/extractor-tests/generated/Path/PathType.ql cb67b05cf7e4f32cbd46ac89a15f6eafe3507cc655db0b9d54a1cf8e7fbcca40 890053e7fd8cd8a92015c09588c7c646f075901cddc3eb8d57210b02b23a5944 +test/extractor-tests/generated/Path/PathType_getPath.ql 7043c7939e4f835e4b2c7e3e207637c362d7a9dbdba0151b38c873fdaf43e7a5 ee2aad1b4fb2b00e1a5d39387848aa164a39e3cd49141f07c175b205c8451bb1 test/extractor-tests/generated/Path/Path_getPart.ql 8aa45a0b58203ef1177166efbe1c2851faf4b4c9a453c83137f0c9298badcdbf b82d490d9b3a8237487cd5da8b3b6fc4aa477977b332a5c6539b3cd4e6d5b45b test/extractor-tests/generated/Path/Path_getQualifier.ql 9af95e22cdf3a65da6a41d93136aef4523db5ce81d38f6ed4bc613f1c68784d0 3102d9241a417a92c97a53ac56a7a8683463f1adc7a593cda1382c0d25b3f261 test/extractor-tests/generated/Path/Path_getResolvedCrateOrigin.ql 7c0ff524595514630de4178028260d4832bfc4f57bfddec9f8e72a6c6dbf241c 55e617380476c183ef9259199d2cfd551b07466e94bc452c4723754d0c82691b test/extractor-tests/generated/Path/Path_getResolvedPath.ql 20c8977781dfe687d5db03290612179cf1360eb47b86ea62d25d1eef62a681e7 c35b76e7d63c05dc80867285bb913042cbe90b45d4d4306df9eac2cba5e8db70 -test/extractor-tests/generated/PathExpr/PathExpr.ql b9696cd7ad9f3874e4bc4b1b9c77f42f06ab6c61b77fb641458da63667087b9b db84a7a8dd05e30ff80733af01f08d43ff031bb4b3e3af06332a73ba7e7bbc43 -test/extractor-tests/generated/PathExpr/PathExpr_getAttr.ql 2ccac48cd91d86670c1d2742de20344135d424e6f0e3dafcc059555046f92d92 9b7b5f5f9e3674fad9b3a5bcd3cabc0dff32a95640da0fce6f4d0eb931f1757d -test/extractor-tests/generated/PathExpr/PathExpr_getPath.ql e7894071313a74166bdd31d7cd974037fcd5a7f0e92d5eec42833266196eb858 46a06e8a1207e7a0fa175cd4b61068e5fd6c43b5575b88986409f0ac2be64c51 -test/extractor-tests/generated/PathPat/PathPat.ql 823732954a5882e33a37bd0bf0cafb2cec51659a5203a4831eec2516da0e49fa 54001149718a9ca15d8c0d4be63f3fe00a9f0d44fa1309e2f605d7932355ea5d -test/extractor-tests/generated/PathPat/PathPat_getPath.ql 6c0c71c80a6e631ea7775ec8660b470ff6b264bab14a399606cf113b1fb190fc 8e34cbb4d064db929e94652e1901ec4f26affa71e30e556b7acdff71dd622cbb -test/extractor-tests/generated/PathSegment/PathSegment.ql efc39cea1b4c0b2b0da6434136334430d074699f84124d6bcf94c24aa854dc64 c0a4bd60c67665c058ca22a59e535e925fdb00dec95ffc5c71697fb0ed78a329 -test/extractor-tests/generated/PathSegment/PathSegment_getGenericArgList.ql 8f6e67b3e316309f20e21d7e7944accf66b0256b76fa50ee9a714044c6ec8cea 15f10a701fc4d3f9fd6734da90790cdbc8a1ddd57bf52695740acedcb2e6e485 -test/extractor-tests/generated/PathSegment/PathSegment_getNameRef.ql 799d284e2f9267d6bbe67aa7035e525ef347dc74cb3e2180e7b2171b5cb49674 592130bc2358989536abf62e8a261272c851483ede4f19783f7d61ffc1803e4b -test/extractor-tests/generated/PathSegment/PathSegment_getParamList.ql e1e7b9b5062f936c33b7e7e29b21456448242df4985c6cffb54900063cfd3e63 6568e851cb6bcb32622f89d01e3aa6e7dd21940d21572a9988584e34bdf25366 -test/extractor-tests/generated/PathSegment/PathSegment_getPathType.ql 01942da6d0b10c1d15caec6abb8c53f1dc7f8c04a91a797f572063aa003dbc4b cb21e6cb160652527ba571265297dae86beffe191dd7dfc4d0beee45cb0cda29 -test/extractor-tests/generated/PathSegment/PathSegment_getRetType.ql 36386a514bc925f5b17ad87afba9fef7986900c1b791732de061213c6e86743f f38bcee68c1da19e70bb1e1c4a4047c763a466f1b8ef2c4f65f8c724c0b58197 -test/extractor-tests/generated/PathSegment/PathSegment_getReturnTypeSyntax.ql d1db51208a311c30af369ce2fdc3a3296e7d598b27bf4960b8b34622a9d9163b 561b1e38c6d8b301fdc016e1d012dd805fde1b42b0720c17d7b15535715047f2 -test/extractor-tests/generated/PathSegment/PathSegment_getTy.ql a0ceaf3f37e521cc92c21cc0bae929499ef3584f86349ef34808c20963d31c75 d674e56e08a6d2a7d211503a466df2cc90c35a3951e41598febf62c8dc693655 -test/extractor-tests/generated/PathType/PathType.ql cb67b05cf7e4f32cbd46ac89a15f6eafe3507cc655db0b9d54a1cf8e7fbcca40 890053e7fd8cd8a92015c09588c7c646f075901cddc3eb8d57210b02b23a5944 -test/extractor-tests/generated/PathType/PathType_getPath.ql 7043c7939e4f835e4b2c7e3e207637c362d7a9dbdba0151b38c873fdaf43e7a5 ee2aad1b4fb2b00e1a5d39387848aa164a39e3cd49141f07c175b205c8451bb1 test/extractor-tests/generated/PrefixExpr/PrefixExpr.ql 44fb7174365c6deecdc22c720d84617c6e060c05d49c41c90433451588f8aa6f 871fab471c82fede3c36edc003f9decee5bb7844c016951d28be78d0c91487e5 test/extractor-tests/generated/PrefixExpr/PrefixExpr_getAttr.ql fdad6ad5199435ded1e4a9ea6b246e76b904cd73a36aaa4780e84eef91741c5b 75d63940046e62c1efa1151b0cac45b5ec0bab5e39aec2e11d43f6c385e37984 test/extractor-tests/generated/PrefixExpr/PrefixExpr_getExpr.ql 2d1d97f6277794871fbb032ea87ac30b1aa902a74cd874720156162057ea202e b1b9880fce07d66df7ec87f12189c37adf9f233a1d0b38a1b09808d052a95642 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 91644fc94af..40fea9eb65d 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -890,25 +890,25 @@ /test/extractor-tests/generated/ParenType/ParenType.ql linguist-generated /test/extractor-tests/generated/ParenType/ParenType_getTy.ql linguist-generated /test/extractor-tests/generated/Path/Path.ql linguist-generated +/test/extractor-tests/generated/Path/PathExpr.ql linguist-generated +/test/extractor-tests/generated/Path/PathExpr_getAttr.ql linguist-generated +/test/extractor-tests/generated/Path/PathExpr_getPath.ql linguist-generated +/test/extractor-tests/generated/Path/PathPat.ql linguist-generated +/test/extractor-tests/generated/Path/PathPat_getPath.ql linguist-generated +/test/extractor-tests/generated/Path/PathSegment.ql linguist-generated +/test/extractor-tests/generated/Path/PathSegment_getGenericArgList.ql linguist-generated +/test/extractor-tests/generated/Path/PathSegment_getNameRef.ql linguist-generated +/test/extractor-tests/generated/Path/PathSegment_getParamList.ql linguist-generated +/test/extractor-tests/generated/Path/PathSegment_getPathType.ql linguist-generated +/test/extractor-tests/generated/Path/PathSegment_getRetType.ql linguist-generated +/test/extractor-tests/generated/Path/PathSegment_getReturnTypeSyntax.ql linguist-generated +/test/extractor-tests/generated/Path/PathSegment_getTy.ql linguist-generated +/test/extractor-tests/generated/Path/PathType.ql linguist-generated +/test/extractor-tests/generated/Path/PathType_getPath.ql linguist-generated /test/extractor-tests/generated/Path/Path_getPart.ql linguist-generated /test/extractor-tests/generated/Path/Path_getQualifier.ql linguist-generated /test/extractor-tests/generated/Path/Path_getResolvedCrateOrigin.ql linguist-generated /test/extractor-tests/generated/Path/Path_getResolvedPath.ql linguist-generated -/test/extractor-tests/generated/PathExpr/PathExpr.ql linguist-generated -/test/extractor-tests/generated/PathExpr/PathExpr_getAttr.ql linguist-generated -/test/extractor-tests/generated/PathExpr/PathExpr_getPath.ql linguist-generated -/test/extractor-tests/generated/PathPat/PathPat.ql linguist-generated -/test/extractor-tests/generated/PathPat/PathPat_getPath.ql linguist-generated -/test/extractor-tests/generated/PathSegment/PathSegment.ql linguist-generated -/test/extractor-tests/generated/PathSegment/PathSegment_getGenericArgList.ql linguist-generated -/test/extractor-tests/generated/PathSegment/PathSegment_getNameRef.ql linguist-generated -/test/extractor-tests/generated/PathSegment/PathSegment_getParamList.ql linguist-generated -/test/extractor-tests/generated/PathSegment/PathSegment_getPathType.ql linguist-generated -/test/extractor-tests/generated/PathSegment/PathSegment_getRetType.ql linguist-generated -/test/extractor-tests/generated/PathSegment/PathSegment_getReturnTypeSyntax.ql linguist-generated -/test/extractor-tests/generated/PathSegment/PathSegment_getTy.ql linguist-generated -/test/extractor-tests/generated/PathType/PathType.ql linguist-generated -/test/extractor-tests/generated/PathType/PathType_getPath.ql linguist-generated /test/extractor-tests/generated/PrefixExpr/PrefixExpr.ql linguist-generated /test/extractor-tests/generated/PrefixExpr/PrefixExpr_getAttr.ql linguist-generated /test/extractor-tests/generated/PrefixExpr/PrefixExpr_getExpr.ql linguist-generated diff --git a/rust/ql/lib/codeql/rust/elements/Path.qll b/rust/ql/lib/codeql/rust/elements/Path.qll index 530c40397c3..cb228373cf5 100644 --- a/rust/ql/lib/codeql/rust/elements/Path.qll +++ b/rust/ql/lib/codeql/rust/elements/Path.qll @@ -10,6 +10,7 @@ import codeql.rust.elements.Resolvable /** * A path. For example: * ```rust + * use some_crate::some_module::some_item; * foo::bar; * ``` */ diff --git a/rust/ql/lib/codeql/rust/elements/PathSegment.qll b/rust/ql/lib/codeql/rust/elements/PathSegment.qll index 5566ba322b6..9edc7d6573f 100644 --- a/rust/ql/lib/codeql/rust/elements/PathSegment.qll +++ b/rust/ql/lib/codeql/rust/elements/PathSegment.qll @@ -14,9 +14,6 @@ import codeql.rust.elements.ReturnTypeSyntax import codeql.rust.elements.TypeRef /** - * A PathSegment. For example: - * ```rust - * todo!() - * ``` + * A path segment, which is one part of a whole path. */ final class PathSegment = Impl::PathSegment; diff --git a/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll index 9104a07a547..d156e207150 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll @@ -104,7 +104,9 @@ module Impl { ) } - override string toString() { result = concat(int i | | this.toStringPart(i), " " order by i) } + override string toString() { + result = strictconcat(int i | | this.toStringPart(i), " " order by i) + } private string toStringPart(int index) { index = 0 and result = "break" diff --git a/rust/ql/lib/codeql/rust/elements/internal/CastExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CastExprImpl.qll index 59cc960a67b..13270d1ca0b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CastExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CastExprImpl.qll @@ -20,7 +20,7 @@ module Impl { */ class CastExpr extends Generated::CastExpr { override string toString() { - result = this.getExpr().toAbbreviatedString() + " as " + this.getTy().toString() + result = this.getExpr().toAbbreviatedString() + " as " + this.getTy().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll index 957574d409a..ecfcd1a4842 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll @@ -49,12 +49,14 @@ module Impl { * ``` */ class ContinueExpr extends Generated::ContinueExpr { - override string toString() { result = concat(int i | | this.toStringPart(i), " " order by i) } + override string toString() { + result = strictconcat(int i | | this.toStringPart(i), " " order by i) + } private string toStringPart(int index) { index = 0 and result = "continue" or - index = 1 and result = this.getLifetime().toString() + index = 1 and result = this.getLifetime().getText() } /** diff --git a/rust/ql/lib/codeql/rust/elements/internal/EnumImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/EnumImpl.qll index 532fa3ed0b3..0299ce9f05e 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/EnumImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/EnumImpl.qll @@ -19,6 +19,6 @@ module Impl { * ``` */ class Enum extends Generated::Enum { - override string toString() { result = "enum " + this.getName().toString() } + override string toString() { result = "enum " + this.getName().getText() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/FieldExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/FieldExprImpl.qll index 922de73c65d..b3cd63b7922 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/FieldExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/FieldExprImpl.qll @@ -22,7 +22,7 @@ module Impl { override string toString() { exists(string abbr, string name | abbr = this.getExpr().toAbbreviatedString() and - name = this.getNameRef().toString() and + name = this.getNameRef().getText() and if abbr = "..." then result = "... ." + name else result = abbr + "." + name ) } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll index d8ec0ca9d37..c75c36b280b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll @@ -22,11 +22,11 @@ module Impl { override string toString() { exists(string trait | ( - trait = this.getTrait().toString() + " for " + trait = this.getTrait().toAbbreviatedString() + " for " or not this.hasTrait() and trait = "" ) and - result = "impl " + trait + this.getSelfTy().toString() + " { ... }" + result = "impl " + trait + this.getSelfTy().toAbbreviatedString() + " { ... }" ) } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LabelImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LabelImpl.qll index e1b3eb4e4d7..822029bf3a7 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LabelImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LabelImpl.qll @@ -22,6 +22,13 @@ module Impl { * ``` */ class Label extends Generated::Label { - override string toString() { result = this.getLifetime().toString() } + override string toString() { result = this.getText() } + + override string toAbbreviatedString() { result = this.getText() } + + /** + * Gets the name of the label, together with the leading `'`. + */ + string getText() { result = this.getLifetime().getText() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LabelableExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LabelableExprImpl.qll index 1b354658a2e..07048181714 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LabelableExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LabelableExprImpl.qll @@ -16,8 +16,16 @@ module Impl { * The base class for expressions that can be labeled (`LoopExpr`, `ForExpr`, `WhileExpr` or `BlockExpr`). */ class LabelableExpr extends Generated::LabelableExpr { - override string toString() { - result = concat([this.getLabel().toString() + ":", this.toStringPrefix(), "{ ... }"], " ") + final override string toString() { + result = strictconcat(int i | | this.toStringPart(i), " " order by i) + } + + private string toStringPart(int index) { + index = 0 and result = this.getLabel().getText() + ":" + or + index = 1 and result = this.toStringPrefix() + or + index = 2 and result = "{ ... }" } /** diff --git a/rust/ql/lib/codeql/rust/elements/internal/LetElseImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LetElseImpl.qll index 7924d8d8453..0ca4e58fb85 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LetElseImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LetElseImpl.qll @@ -19,6 +19,8 @@ module Impl { * ``` */ class LetElse extends Generated::LetElse { - override string toString() { result = "else { ... }" } + override string toString() { result = this.toAbbreviatedString() } + + override string toAbbreviatedString() { result = "else {...}" } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LetStmtImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LetStmtImpl.qll index 1205836c230..d612c2082a6 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LetStmtImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LetStmtImpl.qll @@ -26,7 +26,9 @@ module Impl { * ``` */ class LetStmt extends Generated::LetStmt { - override string toString() { result = concat(int i | | this.toStringPart(i), " " order by i) } + override string toString() { + result = strictconcat(int i | | this.toStringPart(i), " " order by i) + } private string toStringPart(int index) { index = 0 and result = "let" @@ -35,7 +37,7 @@ module Impl { or index = 2 and result = "= " + this.getInitializer().toAbbreviatedString() or - index = 3 and result = this.getLetElse().toString() + index = 3 and result = this.getLetElse().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LiteralExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LiteralExprImpl.qll index efcc4bf073e..f68c79da16b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LiteralExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LiteralExprImpl.qll @@ -26,8 +26,20 @@ module Impl { * ``` */ class LiteralExpr extends Generated::LiteralExpr { - override string toString() { result = this.getTextValue() } + override string toString() { result = this.getTrimmedText() } - override string toAbbreviatedString() { result = this.getTextValue() } + override string toAbbreviatedString() { result = this.getTrimmedText() } + + /** + * Get the text of this literal, trimmed with `...` if it is too long. + * + * INTERNAL: Do not use. + */ + string getTrimmedText() { + exists(string v | + v = this.getTextValue() and + if v.length() > 30 then result = v.substring(0, 30) + "..." else result = v + ) + } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LiteralPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LiteralPatImpl.qll index 65074603796..1c59c3fa284 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LiteralPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LiteralPatImpl.qll @@ -24,6 +24,6 @@ module Impl { class LiteralPat extends Generated::LiteralPat { override string toString() { result = this.toAbbreviatedString() } - override string toAbbreviatedString() { result = this.getLiteral().toString() } + override string toAbbreviatedString() { result = this.getLiteral().getTrimmedText() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/MacroCallImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/MacroCallImpl.qll index eed9a65d432..a34d64c0735 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/MacroCallImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/MacroCallImpl.qll @@ -19,6 +19,6 @@ module Impl { * ``` */ class MacroCall extends Generated::MacroCall { - override string toString() { result = this.getPath().toString() + "!..." } + override string toString() { result = this.getPath().toAbbreviatedString() + "!..." } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/PathImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/PathImpl.qll index 8d0a2ab0ecf..34cd16c144b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/PathImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/PathImpl.qll @@ -15,6 +15,7 @@ module Impl { /** * A path. For example: * ```rust + * use some_crate::some_module::some_item; * foo::bar; * ``` */ @@ -23,9 +24,7 @@ module Impl { override string toAbbreviatedString() { if this.hasQualifier() - then - result = - this.getQualifier().toAbbreviatedString() + "::" + this.getPart().toAbbreviatedString() + then result = "...::" + this.getPart().toAbbreviatedString() else result = this.getPart().toAbbreviatedString() } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/PathPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/PathPatImpl.qll index a78d0dd7ab9..27914a8f415 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/PathPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/PathPatImpl.qll @@ -24,6 +24,6 @@ module Impl { class PathPat extends Generated::PathPat { override string toString() { result = this.toAbbreviatedString() } - override string toAbbreviatedString() { result = this.getPath().toString() } + override string toAbbreviatedString() { result = this.getPath().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/PathSegmentImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/PathSegmentImpl.qll index 90d7cee6639..01ce5878834 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/PathSegmentImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/PathSegmentImpl.qll @@ -13,19 +13,23 @@ private import codeql.rust.elements.internal.generated.PathSegment module Impl { // the following QLdoc is generated: if you need to edit it, do it in the schema file /** - * A PathSegment. For example: - * ```rust - * todo!() - * ``` + * A path segment, which is one part of a whole path. */ class PathSegment extends Generated::PathSegment { override string toString() { result = this.toAbbreviatedString() } override string toAbbreviatedString() { - // TODO: this does not cover everything - if this.hasGenericArgList() - then result = this.getNameRef().toString() + "::<...>" - else result = this.getNameRef().toString() + result = this.getAbbreviatedPrefix() + this.getAbbreviatedGenericArgList() + } + + private string getAbbreviatedGenericArgList() { + if this.hasGenericArgList() then result = "::<...>" else result = "" + } + + private string getAbbreviatedPrefix() { + if this.hasPathType() or this.hasTy() + then result = "<...>" + else result = this.getNameRef().getText() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll index 3f88c50fa6a..a2ca1752cca 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll @@ -21,6 +21,8 @@ module Impl { class PathType extends Generated::PathType { override string toString() { result = this.toAbbreviatedString() } - override string toAbbreviatedString() { result = this.getPath().toString() } + override string toAbbreviatedString() { + result = "<" + this.getPath().toAbbreviatedString() + ">" + } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/RecordExprFieldImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RecordExprFieldImpl.qll index 6e24c31d552..fe898c82fea 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RecordExprFieldImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RecordExprFieldImpl.qll @@ -22,7 +22,7 @@ module Impl { override string toString() { result = concat(int i | | this.toStringPart(i) order by i) } private string toStringPart(int index) { - index = 0 and result = this.getNameRef().toString() + index = 0 and result = this.getNameRef().getText() or index = 1 and result = ": " + this.getExpr().toAbbreviatedString() } diff --git a/rust/ql/lib/codeql/rust/elements/internal/RecordPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RecordPatImpl.qll index 39ccad02065..0bed25bb779 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RecordPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RecordPatImpl.qll @@ -22,6 +22,6 @@ module Impl { * ``` */ class RecordPat extends Generated::RecordPat { - override string toString() { result = this.getPath().toString() + " {...}" } + override string toString() { result = this.getPath().toAbbreviatedString() + " {...}" } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/TraitImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/TraitImpl.qll index 59d685a18e8..564e54e78d6 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/TraitImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/TraitImpl.qll @@ -25,6 +25,6 @@ module Impl { * ``` */ class Trait extends Generated::Trait { - override string toString() { result = "trait " + this.getName() } + override string toString() { result = "trait " + this.getName().getText() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll index 4357dcf68a9..15a79374117 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll @@ -19,6 +19,6 @@ module Impl { * ``` */ class Union extends Generated::Union { - override string toString() { result = "union " + this.getName().toString() } + override string toString() { result = "union " + this.getName().getText() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Path.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Path.qll index 58f7d891d26..36313ca9fe9 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Path.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Path.qll @@ -18,6 +18,7 @@ module Generated { /** * A path. For example: * ```rust + * use some_crate::some_module::some_item; * foo::bar; * ``` * INTERNAL: Do not reference the `Generated::Path` class directly. diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/PathSegment.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/PathSegment.qll index 0878635e7d1..a2c3b970df6 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/PathSegment.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/PathSegment.qll @@ -21,10 +21,7 @@ import codeql.rust.elements.TypeRef */ module Generated { /** - * A PathSegment. For example: - * ```rust - * todo!() - * ``` + * A path segment, which is one part of a whole path. * INTERNAL: Do not reference the `Generated::PathSegment` class directly. * Use the subclass `PathSegment`, where the following predicates are available. */ diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index dc9f577bffc..90fc0ae935b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -578,10 +578,7 @@ module Raw { /** * INTERNAL: Do not use. - * A PathSegment. For example: - * ```rust - * todo!() - * ``` + * A path segment, which is one part of a whole path. */ class PathSegment extends @path_segment, AstNode { override string toString() { result = "PathSegment" } @@ -2337,6 +2334,7 @@ module Raw { * INTERNAL: Do not use. * A path. For example: * ```rust + * use some_crate::some_module::some_item; * foo::bar; * ``` */ diff --git a/rust/ql/test/extractor-tests/generated/.generated_tests.list b/rust/ql/test/extractor-tests/generated/.generated_tests.list index b60779ebd86..e8221c66efd 100644 --- a/rust/ql/test/extractor-tests/generated/.generated_tests.list +++ b/rust/ql/test/extractor-tests/generated/.generated_tests.list @@ -78,11 +78,10 @@ ParamList/gen_param_list.rs ef2e83d0aed45b969fe78dd717e87ef3c1f848e6179cfb4dc3cb ParenExpr/gen_paren_expr.rs dd0c4a21a92e54e8a6151145e013cbec9c9e1cad093d572e293b4f51d6c44aea dd0c4a21a92e54e8a6151145e013cbec9c9e1cad093d572e293b4f51d6c44aea ParenPat/gen_paren_pat.rs c8d18521b9a0b7d39841eb72e3895914aa652b7235dea42ed12a4eb280e3bf0e c8d18521b9a0b7d39841eb72e3895914aa652b7235dea42ed12a4eb280e3bf0e ParenType/gen_paren_type.rs ae1a945b56020eab14bb0ef75ae9ccb735d8e45d1213adee210a90e6dba8430f ae1a945b56020eab14bb0ef75ae9ccb735d8e45d1213adee210a90e6dba8430f -Path/gen_path.rs e32637d04445d5b9411086f3ad5d8b41de24327f7ad641d1a1a25c1d160121c8 e32637d04445d5b9411086f3ad5d8b41de24327f7ad641d1a1a25c1d160121c8 -PathExpr/gen_path_expr.rs a1e0ececfe62a63a43583c9bd8064a80a90c042c55bac29d86776c0c6559f33a a1e0ececfe62a63a43583c9bd8064a80a90c042c55bac29d86776c0c6559f33a -PathPat/gen_path_pat.rs fd7f941f8b33f19d3693be1fdb595c2fb2e85e8296702b82bf12bcd44632f371 fd7f941f8b33f19d3693be1fdb595c2fb2e85e8296702b82bf12bcd44632f371 -PathSegment/gen_path_segment.rs bc0c914821a70f9a7db23766f4d84e2d69fc76d5075a8bc3341f2ba59a8ce911 bc0c914821a70f9a7db23766f4d84e2d69fc76d5075a8bc3341f2ba59a8ce911 -PathType/gen_path_type.rs 710a5505615769da940202e7c6d9031edc23a4b05cd9fb25241c60affbba4027 710a5505615769da940202e7c6d9031edc23a4b05cd9fb25241c60affbba4027 +Path/gen_path.rs 490268d6bfb1635883b8bdefc683d59c4dd0e9c7f86c2e55954661efb3ab0253 490268d6bfb1635883b8bdefc683d59c4dd0e9c7f86c2e55954661efb3ab0253 +Path/gen_path_expr.rs a1e0ececfe62a63a43583c9bd8064a80a90c042c55bac29d86776c0c6559f33a a1e0ececfe62a63a43583c9bd8064a80a90c042c55bac29d86776c0c6559f33a +Path/gen_path_pat.rs fd7f941f8b33f19d3693be1fdb595c2fb2e85e8296702b82bf12bcd44632f371 fd7f941f8b33f19d3693be1fdb595c2fb2e85e8296702b82bf12bcd44632f371 +Path/gen_path_type.rs 710a5505615769da940202e7c6d9031edc23a4b05cd9fb25241c60affbba4027 710a5505615769da940202e7c6d9031edc23a4b05cd9fb25241c60affbba4027 PrefixExpr/gen_prefix_expr.rs c4b53e87f370713b9a9e257be26d082b0761497bac19b1d7401a31b22b30d1ab c4b53e87f370713b9a9e257be26d082b0761497bac19b1d7401a31b22b30d1ab PtrType/gen_ptr_type.rs dd7faad19454b92d7942ef664df1a5f26c01863e408b87249aa4d5d4f68c78b3 dd7faad19454b92d7942ef664df1a5f26c01863e408b87249aa4d5d4f68c78b3 RangeExpr/gen_range_expr.rs 3f27cff9cc76b2703beff622d1453b84121e1970a869e45f9428deac92c4ecb0 3f27cff9cc76b2703beff622d1453b84121e1970a869e45f9428deac92c4ecb0 diff --git a/rust/ql/test/extractor-tests/generated/.gitattributes b/rust/ql/test/extractor-tests/generated/.gitattributes index 8ea3a00a31f..b585a058480 100644 --- a/rust/ql/test/extractor-tests/generated/.gitattributes +++ b/rust/ql/test/extractor-tests/generated/.gitattributes @@ -81,10 +81,9 @@ /ParenPat/gen_paren_pat.rs linguist-generated /ParenType/gen_paren_type.rs linguist-generated /Path/gen_path.rs linguist-generated -/PathExpr/gen_path_expr.rs linguist-generated -/PathPat/gen_path_pat.rs linguist-generated -/PathSegment/gen_path_segment.rs linguist-generated -/PathType/gen_path_type.rs linguist-generated +/Path/gen_path_expr.rs linguist-generated +/Path/gen_path_pat.rs linguist-generated +/Path/gen_path_type.rs linguist-generated /PrefixExpr/gen_prefix_expr.rs linguist-generated /PtrType/gen_ptr_type.rs linguist-generated /RangeExpr/gen_range_expr.rs linguist-generated diff --git a/rust/ql/test/extractor-tests/generated/Path/Path.expected b/rust/ql/test/extractor-tests/generated/Path/Path.expected index db093224b76..42f266cb4ed 100644 --- a/rust/ql/test/extractor-tests/generated/Path/Path.expected +++ b/rust/ql/test/extractor-tests/generated/Path/Path.expected @@ -1,2 +1,23 @@ -| gen_path.rs:5:5:5:7 | foo | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | -| gen_path.rs:5:5:5:12 | foo::bar | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | yes | hasPart: | yes | +| gen_path.rs:5:9:5:18 | some_crate | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path.rs:5:9:5:31 | ...::some_module | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | yes | hasPart: | yes | +| gen_path.rs:5:9:5:42 | ...::some_item | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | yes | hasPart: | yes | +| gen_path.rs:6:5:6:7 | foo | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path.rs:6:5:6:12 | ...::bar | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | yes | hasPart: | yes | +| gen_path_expr.rs:5:13:5:20 | variable | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_expr.rs:6:13:6:15 | foo | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_expr.rs:6:13:6:20 | ...::bar | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | yes | hasPart: | yes | +| gen_path_expr.rs:7:13:7:15 | <...> | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_expr.rs:7:13:7:20 | ...::foo | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | yes | hasPart: | yes | +| gen_path_expr.rs:7:14:7:14 | T | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_expr.rs:7:14:7:14 | T | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_expr.rs:8:13:8:30 | <...> | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_expr.rs:8:13:8:35 | ...::foo | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | yes | hasPart: | yes | +| gen_path_expr.rs:8:14:8:20 | TypeRef | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_expr.rs:8:14:8:20 | TypeRef | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_pat.rs:5:11:5:11 | x | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_pat.rs:6:9:6:11 | Foo | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_pat.rs:6:9:6:16 | ...::Bar | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | yes | hasPart: | yes | +| gen_path_type.rs:5:5:5:8 | todo | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_type.rs:5:5:5:11 | $crate | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_type.rs:5:5:5:11 | ...::panic | hasResolvedPath: | yes | hasResolvedCrateOrigin: | yes | hasQualifier: | yes | hasPart: | yes | +| gen_path_type.rs:5:5:5:11 | ...::panicking | hasResolvedPath: | yes | hasResolvedCrateOrigin: | yes | hasQualifier: | yes | hasPart: | yes | diff --git a/rust/ql/test/extractor-tests/generated/Path/PathExpr.expected b/rust/ql/test/extractor-tests/generated/Path/PathExpr.expected new file mode 100644 index 00000000000..c84497c6881 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/Path/PathExpr.expected @@ -0,0 +1,7 @@ +| gen_path.rs:6:5:6:12 | ...::bar | getNumberOfAttrs: | 0 | hasPath: | yes | +| gen_path_expr.rs:5:13:5:20 | variable | getNumberOfAttrs: | 0 | hasPath: | yes | +| gen_path_expr.rs:6:13:6:20 | ...::bar | getNumberOfAttrs: | 0 | hasPath: | yes | +| gen_path_expr.rs:7:13:7:20 | ...::foo | getNumberOfAttrs: | 0 | hasPath: | yes | +| gen_path_expr.rs:8:13:8:35 | ...::foo | getNumberOfAttrs: | 0 | hasPath: | yes | +| gen_path_pat.rs:5:11:5:11 | x | getNumberOfAttrs: | 0 | hasPath: | yes | +| gen_path_type.rs:5:5:5:11 | ...::panic | getNumberOfAttrs: | 0 | hasPath: | yes | diff --git a/rust/ql/test/extractor-tests/generated/PathExpr/PathExpr.ql b/rust/ql/test/extractor-tests/generated/Path/PathExpr.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathExpr/PathExpr.ql rename to rust/ql/test/extractor-tests/generated/Path/PathExpr.ql diff --git a/rust/ql/test/extractor-tests/generated/PathExpr/PathExpr_getAttr.expected b/rust/ql/test/extractor-tests/generated/Path/PathExpr_getAttr.expected similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathExpr/PathExpr_getAttr.expected rename to rust/ql/test/extractor-tests/generated/Path/PathExpr_getAttr.expected diff --git a/rust/ql/test/extractor-tests/generated/PathExpr/PathExpr_getAttr.ql b/rust/ql/test/extractor-tests/generated/Path/PathExpr_getAttr.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathExpr/PathExpr_getAttr.ql rename to rust/ql/test/extractor-tests/generated/Path/PathExpr_getAttr.ql diff --git a/rust/ql/test/extractor-tests/generated/Path/PathExpr_getPath.expected b/rust/ql/test/extractor-tests/generated/Path/PathExpr_getPath.expected new file mode 100644 index 00000000000..925412bc616 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/Path/PathExpr_getPath.expected @@ -0,0 +1,7 @@ +| gen_path.rs:6:5:6:12 | ...::bar | gen_path.rs:6:5:6:12 | ...::bar | +| gen_path_expr.rs:5:13:5:20 | variable | gen_path_expr.rs:5:13:5:20 | variable | +| gen_path_expr.rs:6:13:6:20 | ...::bar | gen_path_expr.rs:6:13:6:20 | ...::bar | +| gen_path_expr.rs:7:13:7:20 | ...::foo | gen_path_expr.rs:7:13:7:20 | ...::foo | +| gen_path_expr.rs:8:13:8:35 | ...::foo | gen_path_expr.rs:8:13:8:35 | ...::foo | +| gen_path_pat.rs:5:11:5:11 | x | gen_path_pat.rs:5:11:5:11 | x | +| gen_path_type.rs:5:5:5:11 | ...::panic | gen_path_type.rs:5:5:5:11 | ...::panic | diff --git a/rust/ql/test/extractor-tests/generated/PathExpr/PathExpr_getPath.ql b/rust/ql/test/extractor-tests/generated/Path/PathExpr_getPath.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathExpr/PathExpr_getPath.ql rename to rust/ql/test/extractor-tests/generated/Path/PathExpr_getPath.ql diff --git a/rust/ql/test/extractor-tests/generated/Path/PathPat.expected b/rust/ql/test/extractor-tests/generated/Path/PathPat.expected new file mode 100644 index 00000000000..159f006eecb --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/Path/PathPat.expected @@ -0,0 +1 @@ +| gen_path_pat.rs:6:9:6:16 | ...::Bar | hasPath: | yes | diff --git a/rust/ql/test/extractor-tests/generated/PathPat/PathPat.ql b/rust/ql/test/extractor-tests/generated/Path/PathPat.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathPat/PathPat.ql rename to rust/ql/test/extractor-tests/generated/Path/PathPat.ql diff --git a/rust/ql/test/extractor-tests/generated/Path/PathPat_getPath.expected b/rust/ql/test/extractor-tests/generated/Path/PathPat_getPath.expected new file mode 100644 index 00000000000..3a601023f3f --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/Path/PathPat_getPath.expected @@ -0,0 +1 @@ +| gen_path_pat.rs:6:9:6:16 | ...::Bar | gen_path_pat.rs:6:9:6:16 | ...::Bar | diff --git a/rust/ql/test/extractor-tests/generated/PathPat/PathPat_getPath.ql b/rust/ql/test/extractor-tests/generated/Path/PathPat_getPath.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathPat/PathPat_getPath.ql rename to rust/ql/test/extractor-tests/generated/Path/PathPat_getPath.ql diff --git a/rust/ql/test/extractor-tests/generated/Path/PathSegment.expected b/rust/ql/test/extractor-tests/generated/Path/PathSegment.expected new file mode 100644 index 00000000000..41889509341 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/Path/PathSegment.expected @@ -0,0 +1,23 @@ +| gen_path.rs:5:9:5:18 | some_crate | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path.rs:5:21:5:31 | some_module | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path.rs:5:34:5:42 | some_item | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path.rs:6:5:6:7 | foo | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path.rs:6:10:6:12 | bar | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_expr.rs:5:13:5:20 | variable | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_expr.rs:6:13:6:15 | foo | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_expr.rs:6:18:6:20 | bar | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_expr.rs:7:13:7:15 | <...> | hasGenericArgList: | no | hasNameRef: | no | hasParamList: | no | hasPathType: | yes | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | yes | +| gen_path_expr.rs:7:14:7:14 | T | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_expr.rs:7:14:7:14 | T | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_expr.rs:7:18:7:20 | foo | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_expr.rs:8:13:8:30 | <...> | hasGenericArgList: | no | hasNameRef: | no | hasParamList: | no | hasPathType: | yes | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | yes | +| gen_path_expr.rs:8:14:8:20 | TypeRef | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_expr.rs:8:14:8:20 | TypeRef | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_expr.rs:8:33:8:35 | foo | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_pat.rs:5:11:5:11 | x | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_pat.rs:6:9:6:11 | Foo | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_pat.rs:6:14:6:16 | Bar | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_type.rs:5:5:5:8 | todo | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_type.rs:5:5:5:11 | $crate | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_type.rs:5:5:5:11 | panic | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_type.rs:5:5:5:11 | panicking | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment.ql b/rust/ql/test/extractor-tests/generated/Path/PathSegment.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathSegment/PathSegment.ql rename to rust/ql/test/extractor-tests/generated/Path/PathSegment.ql diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getGenericArgList.expected b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getGenericArgList.expected similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getGenericArgList.expected rename to rust/ql/test/extractor-tests/generated/Path/PathSegment_getGenericArgList.expected diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getGenericArgList.ql b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getGenericArgList.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getGenericArgList.ql rename to rust/ql/test/extractor-tests/generated/Path/PathSegment_getGenericArgList.ql diff --git a/rust/ql/test/extractor-tests/generated/Path/PathSegment_getNameRef.expected b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getNameRef.expected new file mode 100644 index 00000000000..e6b487851b7 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getNameRef.expected @@ -0,0 +1,21 @@ +| gen_path.rs:5:9:5:18 | some_crate | gen_path.rs:5:9:5:18 | some_crate | +| gen_path.rs:5:21:5:31 | some_module | gen_path.rs:5:21:5:31 | some_module | +| gen_path.rs:5:34:5:42 | some_item | gen_path.rs:5:34:5:42 | some_item | +| gen_path.rs:6:5:6:7 | foo | gen_path.rs:6:5:6:7 | foo | +| gen_path.rs:6:10:6:12 | bar | gen_path.rs:6:10:6:12 | bar | +| gen_path_expr.rs:5:13:5:20 | variable | gen_path_expr.rs:5:13:5:20 | variable | +| gen_path_expr.rs:6:13:6:15 | foo | gen_path_expr.rs:6:13:6:15 | foo | +| gen_path_expr.rs:6:18:6:20 | bar | gen_path_expr.rs:6:18:6:20 | bar | +| gen_path_expr.rs:7:14:7:14 | T | gen_path_expr.rs:7:14:7:14 | T | +| gen_path_expr.rs:7:14:7:14 | T | gen_path_expr.rs:7:14:7:14 | T | +| gen_path_expr.rs:7:18:7:20 | foo | gen_path_expr.rs:7:18:7:20 | foo | +| gen_path_expr.rs:8:14:8:20 | TypeRef | gen_path_expr.rs:8:14:8:20 | TypeRef | +| gen_path_expr.rs:8:14:8:20 | TypeRef | gen_path_expr.rs:8:14:8:20 | TypeRef | +| gen_path_expr.rs:8:33:8:35 | foo | gen_path_expr.rs:8:33:8:35 | foo | +| gen_path_pat.rs:5:11:5:11 | x | gen_path_pat.rs:5:11:5:11 | x | +| gen_path_pat.rs:6:9:6:11 | Foo | gen_path_pat.rs:6:9:6:11 | Foo | +| gen_path_pat.rs:6:14:6:16 | Bar | gen_path_pat.rs:6:14:6:16 | Bar | +| gen_path_type.rs:5:5:5:8 | todo | gen_path_type.rs:5:5:5:8 | todo | +| gen_path_type.rs:5:5:5:11 | $crate | gen_path_type.rs:5:5:5:11 | $crate | +| gen_path_type.rs:5:5:5:11 | panic | gen_path_type.rs:5:5:5:11 | panic | +| gen_path_type.rs:5:5:5:11 | panicking | gen_path_type.rs:5:5:5:11 | panicking | diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getNameRef.ql b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getNameRef.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getNameRef.ql rename to rust/ql/test/extractor-tests/generated/Path/PathSegment_getNameRef.ql diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getParamList.expected b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getParamList.expected similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getParamList.expected rename to rust/ql/test/extractor-tests/generated/Path/PathSegment_getParamList.expected diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getParamList.ql b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getParamList.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getParamList.ql rename to rust/ql/test/extractor-tests/generated/Path/PathSegment_getParamList.ql diff --git a/rust/ql/test/extractor-tests/generated/Path/PathSegment_getPathType.expected b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getPathType.expected new file mode 100644 index 00000000000..b63a629ccb1 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getPathType.expected @@ -0,0 +1,2 @@ +| gen_path_expr.rs:7:13:7:15 | <...> | gen_path_expr.rs:7:14:7:14 | | +| gen_path_expr.rs:8:13:8:30 | <...> | gen_path_expr.rs:8:14:8:20 | | diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getPathType.ql b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getPathType.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getPathType.ql rename to rust/ql/test/extractor-tests/generated/Path/PathSegment_getPathType.ql diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getRetType.expected b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getRetType.expected similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getRetType.expected rename to rust/ql/test/extractor-tests/generated/Path/PathSegment_getRetType.expected diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getRetType.ql b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getRetType.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getRetType.ql rename to rust/ql/test/extractor-tests/generated/Path/PathSegment_getRetType.ql diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getReturnTypeSyntax.expected b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getReturnTypeSyntax.expected similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getReturnTypeSyntax.expected rename to rust/ql/test/extractor-tests/generated/Path/PathSegment_getReturnTypeSyntax.expected diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getReturnTypeSyntax.ql b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getReturnTypeSyntax.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getReturnTypeSyntax.ql rename to rust/ql/test/extractor-tests/generated/Path/PathSegment_getReturnTypeSyntax.ql diff --git a/rust/ql/test/extractor-tests/generated/Path/PathSegment_getTy.expected b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getTy.expected new file mode 100644 index 00000000000..b63a629ccb1 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getTy.expected @@ -0,0 +1,2 @@ +| gen_path_expr.rs:7:13:7:15 | <...> | gen_path_expr.rs:7:14:7:14 | | +| gen_path_expr.rs:8:13:8:30 | <...> | gen_path_expr.rs:8:14:8:20 | | diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getTy.ql b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getTy.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getTy.ql rename to rust/ql/test/extractor-tests/generated/Path/PathSegment_getTy.ql diff --git a/rust/ql/test/extractor-tests/generated/Path/PathType.expected b/rust/ql/test/extractor-tests/generated/Path/PathType.expected new file mode 100644 index 00000000000..5347001fb41 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/Path/PathType.expected @@ -0,0 +1,4 @@ +| gen_path_expr.rs:7:14:7:14 | | hasPath: | yes | +| gen_path_expr.rs:7:14:7:14 | | hasPath: | yes | +| gen_path_expr.rs:8:14:8:20 | | hasPath: | yes | +| gen_path_expr.rs:8:14:8:20 | | hasPath: | yes | diff --git a/rust/ql/test/extractor-tests/generated/PathType/PathType.ql b/rust/ql/test/extractor-tests/generated/Path/PathType.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathType/PathType.ql rename to rust/ql/test/extractor-tests/generated/Path/PathType.ql diff --git a/rust/ql/test/extractor-tests/generated/Path/PathType_getPath.expected b/rust/ql/test/extractor-tests/generated/Path/PathType_getPath.expected new file mode 100644 index 00000000000..3d98da0c2b8 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/Path/PathType_getPath.expected @@ -0,0 +1,4 @@ +| gen_path_expr.rs:7:14:7:14 | | gen_path_expr.rs:7:14:7:14 | T | +| gen_path_expr.rs:7:14:7:14 | | gen_path_expr.rs:7:14:7:14 | T | +| gen_path_expr.rs:8:14:8:20 | | gen_path_expr.rs:8:14:8:20 | TypeRef | +| gen_path_expr.rs:8:14:8:20 | | gen_path_expr.rs:8:14:8:20 | TypeRef | diff --git a/rust/ql/test/extractor-tests/generated/PathType/PathType_getPath.ql b/rust/ql/test/extractor-tests/generated/Path/PathType_getPath.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathType/PathType_getPath.ql rename to rust/ql/test/extractor-tests/generated/Path/PathType_getPath.ql diff --git a/rust/ql/test/extractor-tests/generated/Path/Path_getPart.expected b/rust/ql/test/extractor-tests/generated/Path/Path_getPart.expected index 0e05956ea89..9b0f05f0727 100644 --- a/rust/ql/test/extractor-tests/generated/Path/Path_getPart.expected +++ b/rust/ql/test/extractor-tests/generated/Path/Path_getPart.expected @@ -1,2 +1,23 @@ -| gen_path.rs:5:5:5:7 | foo | gen_path.rs:5:5:5:7 | foo | -| gen_path.rs:5:5:5:12 | foo::bar | gen_path.rs:5:10:5:12 | bar | +| gen_path.rs:5:9:5:18 | some_crate | gen_path.rs:5:9:5:18 | some_crate | +| gen_path.rs:5:9:5:31 | ...::some_module | gen_path.rs:5:21:5:31 | some_module | +| gen_path.rs:5:9:5:42 | ...::some_item | gen_path.rs:5:34:5:42 | some_item | +| gen_path.rs:6:5:6:7 | foo | gen_path.rs:6:5:6:7 | foo | +| gen_path.rs:6:5:6:12 | ...::bar | gen_path.rs:6:10:6:12 | bar | +| gen_path_expr.rs:5:13:5:20 | variable | gen_path_expr.rs:5:13:5:20 | variable | +| gen_path_expr.rs:6:13:6:15 | foo | gen_path_expr.rs:6:13:6:15 | foo | +| gen_path_expr.rs:6:13:6:20 | ...::bar | gen_path_expr.rs:6:18:6:20 | bar | +| gen_path_expr.rs:7:13:7:15 | <...> | gen_path_expr.rs:7:13:7:15 | <...> | +| gen_path_expr.rs:7:13:7:20 | ...::foo | gen_path_expr.rs:7:18:7:20 | foo | +| gen_path_expr.rs:7:14:7:14 | T | gen_path_expr.rs:7:14:7:14 | T | +| gen_path_expr.rs:7:14:7:14 | T | gen_path_expr.rs:7:14:7:14 | T | +| gen_path_expr.rs:8:13:8:30 | <...> | gen_path_expr.rs:8:13:8:30 | <...> | +| gen_path_expr.rs:8:13:8:35 | ...::foo | gen_path_expr.rs:8:33:8:35 | foo | +| gen_path_expr.rs:8:14:8:20 | TypeRef | gen_path_expr.rs:8:14:8:20 | TypeRef | +| gen_path_expr.rs:8:14:8:20 | TypeRef | gen_path_expr.rs:8:14:8:20 | TypeRef | +| gen_path_pat.rs:5:11:5:11 | x | gen_path_pat.rs:5:11:5:11 | x | +| gen_path_pat.rs:6:9:6:11 | Foo | gen_path_pat.rs:6:9:6:11 | Foo | +| gen_path_pat.rs:6:9:6:16 | ...::Bar | gen_path_pat.rs:6:14:6:16 | Bar | +| gen_path_type.rs:5:5:5:8 | todo | gen_path_type.rs:5:5:5:8 | todo | +| gen_path_type.rs:5:5:5:11 | $crate | gen_path_type.rs:5:5:5:11 | $crate | +| gen_path_type.rs:5:5:5:11 | ...::panic | gen_path_type.rs:5:5:5:11 | panic | +| gen_path_type.rs:5:5:5:11 | ...::panicking | gen_path_type.rs:5:5:5:11 | panicking | diff --git a/rust/ql/test/extractor-tests/generated/Path/Path_getQualifier.expected b/rust/ql/test/extractor-tests/generated/Path/Path_getQualifier.expected index 44aa2ca5a00..6fb72c5159a 100644 --- a/rust/ql/test/extractor-tests/generated/Path/Path_getQualifier.expected +++ b/rust/ql/test/extractor-tests/generated/Path/Path_getQualifier.expected @@ -1 +1,9 @@ -| gen_path.rs:5:5:5:12 | foo::bar | gen_path.rs:5:5:5:7 | foo | +| gen_path.rs:5:9:5:31 | ...::some_module | gen_path.rs:5:9:5:18 | some_crate | +| gen_path.rs:5:9:5:42 | ...::some_item | gen_path.rs:5:9:5:31 | ...::some_module | +| gen_path.rs:6:5:6:12 | ...::bar | gen_path.rs:6:5:6:7 | foo | +| gen_path_expr.rs:6:13:6:20 | ...::bar | gen_path_expr.rs:6:13:6:15 | foo | +| gen_path_expr.rs:7:13:7:20 | ...::foo | gen_path_expr.rs:7:13:7:15 | <...> | +| gen_path_expr.rs:8:13:8:35 | ...::foo | gen_path_expr.rs:8:13:8:30 | <...> | +| gen_path_pat.rs:6:9:6:16 | ...::Bar | gen_path_pat.rs:6:9:6:11 | Foo | +| gen_path_type.rs:5:5:5:11 | ...::panic | gen_path_type.rs:5:5:5:11 | ...::panicking | +| gen_path_type.rs:5:5:5:11 | ...::panicking | gen_path_type.rs:5:5:5:11 | $crate | diff --git a/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedCrateOrigin.expected b/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedCrateOrigin.expected index e69de29bb2d..9da37a05d71 100644 --- a/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedCrateOrigin.expected +++ b/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedCrateOrigin.expected @@ -0,0 +1,2 @@ +| gen_path_type.rs:5:5:5:11 | ...::panic | lang:core | +| gen_path_type.rs:5:5:5:11 | ...::panicking | lang:core | diff --git a/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedPath.expected b/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedPath.expected index e69de29bb2d..4a7a9a1e2ae 100644 --- a/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedPath.expected +++ b/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedPath.expected @@ -0,0 +1,2 @@ +| gen_path_type.rs:5:5:5:11 | ...::panic | crate::panicking::panic | +| gen_path_type.rs:5:5:5:11 | ...::panicking | crate::panicking | diff --git a/rust/ql/test/extractor-tests/generated/Path/gen_path.rs b/rust/ql/test/extractor-tests/generated/Path/gen_path.rs index 3b3f054875a..de58e6978af 100644 --- a/rust/ql/test/extractor-tests/generated/Path/gen_path.rs +++ b/rust/ql/test/extractor-tests/generated/Path/gen_path.rs @@ -2,5 +2,6 @@ fn test_path() -> () { // A path. For example: + use some_crate::some_module::some_item; foo::bar; } diff --git a/rust/ql/test/extractor-tests/generated/PathExpr/gen_path_expr.rs b/rust/ql/test/extractor-tests/generated/Path/gen_path_expr.rs similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathExpr/gen_path_expr.rs rename to rust/ql/test/extractor-tests/generated/Path/gen_path_expr.rs diff --git a/rust/ql/test/extractor-tests/generated/PathPat/gen_path_pat.rs b/rust/ql/test/extractor-tests/generated/Path/gen_path_pat.rs similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathPat/gen_path_pat.rs rename to rust/ql/test/extractor-tests/generated/Path/gen_path_pat.rs diff --git a/rust/ql/test/extractor-tests/generated/PathType/gen_path_type.rs b/rust/ql/test/extractor-tests/generated/Path/gen_path_type.rs similarity index 100% rename from rust/ql/test/extractor-tests/generated/PathType/gen_path_type.rs rename to rust/ql/test/extractor-tests/generated/Path/gen_path_type.rs diff --git a/rust/ql/test/extractor-tests/generated/PathExpr/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/extractor-tests/generated/PathExpr/CONSISTENCY/DataFlowConsistency.expected deleted file mode 100644 index c54360f7361..00000000000 --- a/rust/ql/test/extractor-tests/generated/PathExpr/CONSISTENCY/DataFlowConsistency.expected +++ /dev/null @@ -1,3 +0,0 @@ -uniqueNodeToString -| gen_path_expr.rs:7:13:7:20 | (no string representation) | Node should have one toString but has 0. | -| gen_path_expr.rs:8:13:8:35 | (no string representation) | Node should have one toString but has 0. | diff --git a/rust/ql/test/extractor-tests/generated/PathExpr/PathExpr.expected b/rust/ql/test/extractor-tests/generated/PathExpr/PathExpr.expected deleted file mode 100644 index a676396a2f9..00000000000 --- a/rust/ql/test/extractor-tests/generated/PathExpr/PathExpr.expected +++ /dev/null @@ -1,4 +0,0 @@ -| gen_path_expr.rs:5:13:5:20 | variable | getNumberOfAttrs: | 0 | hasPath: | yes | -| gen_path_expr.rs:6:13:6:20 | foo::bar | getNumberOfAttrs: | 0 | hasPath: | yes | -| gen_path_expr.rs:7:13:7:20 | (no string representation) | getNumberOfAttrs: | 0 | hasPath: | yes | -| gen_path_expr.rs:8:13:8:35 | (no string representation) | getNumberOfAttrs: | 0 | hasPath: | yes | diff --git a/rust/ql/test/extractor-tests/generated/PathExpr/PathExpr_getPath.expected b/rust/ql/test/extractor-tests/generated/PathExpr/PathExpr_getPath.expected deleted file mode 100644 index a5765b5be60..00000000000 --- a/rust/ql/test/extractor-tests/generated/PathExpr/PathExpr_getPath.expected +++ /dev/null @@ -1,4 +0,0 @@ -| gen_path_expr.rs:5:13:5:20 | variable | gen_path_expr.rs:5:13:5:20 | variable | -| gen_path_expr.rs:6:13:6:20 | foo::bar | gen_path_expr.rs:6:13:6:20 | foo::bar | -| gen_path_expr.rs:7:13:7:20 | (no string representation) | gen_path_expr.rs:7:13:7:20 | (no string representation) | -| gen_path_expr.rs:8:13:8:35 | (no string representation) | gen_path_expr.rs:8:13:8:35 | (no string representation) | diff --git a/rust/ql/test/extractor-tests/generated/PathPat/PathPat.expected b/rust/ql/test/extractor-tests/generated/PathPat/PathPat.expected deleted file mode 100644 index f7cee5c5586..00000000000 --- a/rust/ql/test/extractor-tests/generated/PathPat/PathPat.expected +++ /dev/null @@ -1 +0,0 @@ -| gen_path_pat.rs:6:9:6:16 | Foo::Bar | hasPath: | yes | diff --git a/rust/ql/test/extractor-tests/generated/PathPat/PathPat_getPath.expected b/rust/ql/test/extractor-tests/generated/PathPat/PathPat_getPath.expected deleted file mode 100644 index 1f450c24938..00000000000 --- a/rust/ql/test/extractor-tests/generated/PathPat/PathPat_getPath.expected +++ /dev/null @@ -1 +0,0 @@ -| gen_path_pat.rs:6:9:6:16 | Foo::Bar | gen_path_pat.rs:6:9:6:16 | Foo::Bar | diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment.expected b/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment.expected deleted file mode 100644 index 32042fc6a59..00000000000 --- a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment.expected +++ /dev/null @@ -1,4 +0,0 @@ -| gen_path_segment.rs:5:5:5:8 | todo | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | -| gen_path_segment.rs:5:5:5:11 | $crate | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | -| gen_path_segment.rs:5:5:5:11 | panic | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | -| gen_path_segment.rs:5:5:5:11 | panicking | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getNameRef.expected b/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getNameRef.expected deleted file mode 100644 index 28346240d29..00000000000 --- a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getNameRef.expected +++ /dev/null @@ -1,4 +0,0 @@ -| gen_path_segment.rs:5:5:5:8 | todo | gen_path_segment.rs:5:5:5:8 | todo | -| gen_path_segment.rs:5:5:5:11 | $crate | gen_path_segment.rs:5:5:5:11 | $crate | -| gen_path_segment.rs:5:5:5:11 | panic | gen_path_segment.rs:5:5:5:11 | panic | -| gen_path_segment.rs:5:5:5:11 | panicking | gen_path_segment.rs:5:5:5:11 | panicking | diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getPathType.expected b/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getPathType.expected deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getTy.expected b/rust/ql/test/extractor-tests/generated/PathSegment/PathSegment_getTy.expected deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/gen_path_segment.rs b/rust/ql/test/extractor-tests/generated/PathSegment/gen_path_segment.rs deleted file mode 100644 index 0ab008b6a68..00000000000 --- a/rust/ql/test/extractor-tests/generated/PathSegment/gen_path_segment.rs +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen, do not edit - -fn test_path_segment() -> () { - // A PathSegment. For example: - todo!() -} diff --git a/rust/ql/test/extractor-tests/generated/PathType/PathType.expected b/rust/ql/test/extractor-tests/generated/PathType/PathType.expected deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/rust/ql/test/extractor-tests/generated/PathType/PathType_getPath.expected b/rust/ql/test/extractor-tests/generated/PathType/PathType_getPath.expected deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index 323e946e4f9..8f5aee1677b 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -81,6 +81,7 @@ class _: """ A path. For example: ```rust + use some_crate::some_module::some_item; foo::bar; ``` """ @@ -120,6 +121,7 @@ class PathExprBase(Expr): @annotate(PathExpr, replace_bases={Expr: PathExprBase}) +@qltest.test_with(Path) class _: """ A path expression. For example: @@ -721,6 +723,7 @@ class _: @annotate(PathPat) +@qltest.test_with(Path) class _: """ A path pattern. For example: @@ -1366,16 +1369,15 @@ class _: @annotate(PathSegment) +@qltest.test_with(Path) class _: """ - A PathSegment. For example: - ```rust - todo!() - ``` + A path segment, which is one part of a whole path. """ @annotate(PathType) +@qltest.test_with(Path) class _: """ A PathType. For example: From d8b453fc0d7dbb5fdcc1510503f83f06be13c37b Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Nov 2024 11:14:59 +0100 Subject: [PATCH 149/470] Rust: add consistency query printing AST classes of nodes with wrong `toString` --- rust/ql/consistency-queries/DataFlowConsistency.ql | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rust/ql/consistency-queries/DataFlowConsistency.ql b/rust/ql/consistency-queries/DataFlowConsistency.ql index 3513121f260..9c472b2d97c 100644 --- a/rust/ql/consistency-queries/DataFlowConsistency.ql +++ b/rust/ql/consistency-queries/DataFlowConsistency.ql @@ -14,3 +14,11 @@ private import codeql.dataflow.internal.DataFlowImplConsistency private module Input implements InputSig { } import MakeConsistency + +/** + * This adds `AstNode` class names to the results of `uniqueNodeToString`, if any. + */ +query predicate uniqueNodeToStringClasses(Node n, string cls) { + uniqueNodeToString(n, _) and + cls = n.getCfgNode().getAstNode().getPrimaryQlClasses() +} From 36d8a6d05fda6bbf1633af89905e0d71e0a6eb99 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Nov 2024 11:42:00 +0100 Subject: [PATCH 150/470] Rust: add class printouts to `AstConsistency.ql` --- rust/ql/consistency-queries/DataFlowConsistency.ql | 8 -------- rust/ql/lib/codeql/rust/AstConsistency.qll | 9 ++++++--- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/rust/ql/consistency-queries/DataFlowConsistency.ql b/rust/ql/consistency-queries/DataFlowConsistency.ql index 9c472b2d97c..3513121f260 100644 --- a/rust/ql/consistency-queries/DataFlowConsistency.ql +++ b/rust/ql/consistency-queries/DataFlowConsistency.ql @@ -14,11 +14,3 @@ private import codeql.dataflow.internal.DataFlowImplConsistency private module Input implements InputSig { } import MakeConsistency - -/** - * This adds `AstNode` class names to the results of `uniqueNodeToString`, if any. - */ -query predicate uniqueNodeToStringClasses(Node n, string cls) { - uniqueNodeToString(n, _) and - cls = n.getCfgNode().getAstNode().getPrimaryQlClasses() -} diff --git a/rust/ql/lib/codeql/rust/AstConsistency.qll b/rust/ql/lib/codeql/rust/AstConsistency.qll index dbb7f7216d7..3902f56d20b 100644 --- a/rust/ql/lib/codeql/rust/AstConsistency.qll +++ b/rust/ql/lib/codeql/rust/AstConsistency.qll @@ -10,8 +10,9 @@ private predicate multipleToStrings(Element e) { strictcount(e.toString()) > 1 } /** * Holds if `e` has more than one `toString()` result. */ -query predicate multipleToStrings(Element e, string s) { +query predicate multipleToStrings(Element e, string cls, string s) { multipleToStrings(e) and + cls = e.getPrimaryQlClasses() and s = strictconcat(e.toString(), ", ") } @@ -39,9 +40,11 @@ private predicate multipleParents(Element child) { strictcount(getParent(child)) /** * Holds if `child` has more than one AST parent. */ -query predicate multipleParents(Element child, Element parent) { +query predicate multipleParents(Element child, string childClass, Element parent, string parentClass) { multipleParents(child) and - parent = getParent(child) + childClass = child.getPrimaryQlClasses() and + parent = getParent(child) and + parentClass = parent.getPrimaryQlClasses() } /** From c2b426df768b62dd2bb38c43a3515f64905ae2b8 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Nov 2024 12:54:13 +0100 Subject: [PATCH 151/470] Rust: accept test changes --- .../canonical_path/canonical_paths.expected | 28 +++++++++---------- .../generated/BlockExpr/BlockExpr.expected | 2 +- .../BlockExpr/BlockExpr_getLabel.expected | 2 +- .../BlockExpr/BlockExpr_getStmtList.expected | 2 +- .../generated/BoxPat/BoxPat.expected | 2 +- .../generated/BoxPat/BoxPat_getPat.expected | 2 +- .../generated/CastExpr/CastExpr.expected | 2 +- .../CastExpr/CastExpr_getExpr.expected | 2 +- .../CastExpr/CastExpr_getTy.expected | 2 +- .../ContinueExpr/ContinueExpr.expected | 2 +- .../ContinueExpr_getLifetime.expected | 2 +- .../generated/Label/Label.expected | 2 +- .../Label/Label_getLifetime.expected | 2 +- .../generated/LetStmt/LetStmt.expected | 2 +- .../LetStmt/LetStmt_getInitializer.expected | 2 +- .../LetStmt/LetStmt_getLetElse.expected | 2 +- .../generated/LetStmt/LetStmt_getPat.expected | 2 +- .../generated/LetStmt/LetStmt_getTy.expected | 4 +-- .../generated/LoopExpr/LoopExpr.expected | 2 +- .../LoopExpr/LoopExpr_getLabel.expected | 2 +- .../LoopExpr/LoopExpr_getLoopBody.expected | 2 +- .../generated/MatchArm/MatchArm.expected | 2 +- .../MatchArm/MatchArm_getExpr.expected | 2 +- .../MatchArm/MatchArm_getPat.expected | 2 +- .../OffsetOfExpr/OffsetOfExpr_getTy.expected | 2 +- .../generated/OrPat/OrPat.expected | 2 +- .../generated/OrPat/OrPat_getPat.expected | 4 +-- .../generated/RefPat/RefPat.expected | 2 +- .../generated/RefPat/RefPat_getPat.expected | 2 +- .../ql/test/extractor-tests/utf8/ast.expected | 2 +- .../controlflow-unstable/Cfg.expected | 24 ++++++++-------- 31 files changed, 57 insertions(+), 57 deletions(-) diff --git a/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected b/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected index d9919af198c..c65eaaff234 100644 --- a/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected +++ b/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected @@ -3,13 +3,13 @@ canonicalPaths | canonical_paths.rs:2:5:3:22 | Struct | repo::test | crate::canonical_paths::a::Struct | | canonical_paths.rs:5:5:7:5 | trait Trait | repo::test | crate::canonical_paths::a::Trait | | canonical_paths.rs:6:9:6:20 | fn f | repo::test | crate::canonical_paths::a::Trait::f | -| canonical_paths.rs:9:5:11:5 | impl Trait for Struct { ... } | None | None | +| canonical_paths.rs:9:5:11:5 | impl for { ... } | None | None | | canonical_paths.rs:10:9:10:22 | fn f | repo::test | ::f | -| canonical_paths.rs:13:5:15:5 | impl Struct { ... } | None | None | +| canonical_paths.rs:13:5:15:5 | impl { ... } | None | None | | canonical_paths.rs:14:9:14:22 | fn g | repo::test | ::g | | canonical_paths.rs:17:5:19:5 | trait TraitWithBlanketImpl | repo::test | crate::canonical_paths::a::TraitWithBlanketImpl | | canonical_paths.rs:18:9:18:20 | fn h | repo::test | crate::canonical_paths::a::TraitWithBlanketImpl::h | -| canonical_paths.rs:21:5:23:5 | impl TraitWithBlanketImpl for T { ... } | None | None | +| canonical_paths.rs:21:5:23:5 | impl for { ... } | None | None | | canonical_paths.rs:22:9:22:22 | fn h | repo::test | <_ as crate::canonical_paths::a::TraitWithBlanketImpl>::h | | canonical_paths.rs:25:5:25:16 | fn free | repo::test | crate::canonical_paths::a::free | | canonical_paths.rs:27:5:33:5 | fn usage | repo::test | crate::canonical_paths::a::usage | @@ -19,11 +19,11 @@ canonicalPaths | canonical_paths.rs:40:9:40:27 | Struct | repo::test | {34}::OtherStruct | | canonical_paths.rs:42:9:44:9 | trait OtherTrait | repo::test | {34}::OtherTrait | | canonical_paths.rs:43:13:43:24 | fn g | repo::test | {34}::OtherTrait::g | -| canonical_paths.rs:46:9:48:9 | impl OtherTrait for OtherStruct { ... } | None | None | +| canonical_paths.rs:46:9:48:9 | impl for { ... } | None | None | | canonical_paths.rs:47:13:47:26 | fn g | repo::test | <{34}::OtherStruct as {34}::OtherTrait>::g | -| canonical_paths.rs:50:9:52:9 | impl OtherTrait for crate::canonical_paths::a::Struct { ... } | None | None | +| canonical_paths.rs:50:9:52:9 | impl for <...::Struct> { ... } | None | None | | canonical_paths.rs:51:13:51:26 | fn g | repo::test | ::g | -| canonical_paths.rs:54:9:56:9 | impl crate::canonical_paths::a::Trait for OtherStruct { ... } | None | None | +| canonical_paths.rs:54:9:56:9 | impl <...::Trait> for { ... } | None | None | | canonical_paths.rs:55:13:55:26 | fn f | repo::test | <{34}::OtherStruct as crate::canonical_paths::a::Trait>::f | | canonical_paths.rs:58:9:60:9 | fn nested | repo::test | {34}::nested | | canonical_paths.rs:59:13:59:31 | Struct | repo::test | {35}::OtherStruct | @@ -48,19 +48,19 @@ resolvedPaths | canonical_paths.rs:31:9:31:13 | ... .h(...) | repo::test | <_ as crate::canonical_paths::a::TraitWithBlanketImpl>::h | | canonical_paths.rs:32:9:32:12 | free | repo::test | crate::canonical_paths::a::free | | canonical_paths.rs:37:9:37:13 | super | repo::test | crate::canonical_paths | -| canonical_paths.rs:37:9:37:16 | super::a | repo::test | crate::canonical_paths::a | -| canonical_paths.rs:37:9:37:23 | super::a::Trait | repo::test | crate::canonical_paths::a::Trait | +| canonical_paths.rs:37:9:37:16 | ...::a | repo::test | crate::canonical_paths::a | +| canonical_paths.rs:37:9:37:23 | ...::Trait | repo::test | crate::canonical_paths::a::Trait | | canonical_paths.rs:46:14:46:23 | OtherTrait | repo::test | {34}::OtherTrait | | canonical_paths.rs:46:29:46:39 | OtherStruct | repo::test | {34}::OtherStruct | | canonical_paths.rs:50:14:50:23 | OtherTrait | repo::test | {34}::OtherTrait | | canonical_paths.rs:50:29:50:33 | crate | None | None | -| canonical_paths.rs:50:29:50:50 | crate::canonical_paths | repo::test | crate::canonical_paths | -| canonical_paths.rs:50:29:50:53 | crate::canonical_paths::a | repo::test | crate::canonical_paths::a | -| canonical_paths.rs:50:29:50:61 | crate::canonical_paths::a::Struct | repo::test | crate::canonical_paths::a::Struct | +| canonical_paths.rs:50:29:50:50 | ...::canonical_paths | repo::test | crate::canonical_paths | +| canonical_paths.rs:50:29:50:53 | ...::a | repo::test | crate::canonical_paths::a | +| canonical_paths.rs:50:29:50:61 | ...::Struct | repo::test | crate::canonical_paths::a::Struct | | canonical_paths.rs:54:14:54:18 | crate | None | None | -| canonical_paths.rs:54:14:54:35 | crate::canonical_paths | repo::test | crate::canonical_paths | -| canonical_paths.rs:54:14:54:38 | crate::canonical_paths::a | repo::test | crate::canonical_paths::a | -| canonical_paths.rs:54:14:54:45 | crate::canonical_paths::a::Trait | repo::test | crate::canonical_paths::a::Trait | +| canonical_paths.rs:54:14:54:35 | ...::canonical_paths | repo::test | crate::canonical_paths | +| canonical_paths.rs:54:14:54:38 | ...::a | repo::test | crate::canonical_paths::a | +| canonical_paths.rs:54:14:54:45 | ...::Trait | repo::test | crate::canonical_paths::a::Trait | | canonical_paths.rs:54:51:54:61 | OtherStruct | repo::test | {34}::OtherStruct | | canonical_paths.rs:63:21:63:31 | OtherStruct | repo::test | {34}::OtherStruct | | canonical_paths.rs:64:13:64:13 | s | None | None | diff --git a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.expected b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.expected index b832addc799..b6be24d0bb7 100644 --- a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.expected +++ b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr.expected @@ -1,3 +1,3 @@ | gen_block_expr.rs:3:28:12:1 | { ... } | hasLabel: | no | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasStmtList: | yes | | gen_block_expr.rs:5:5:7:5 | { ... } | hasLabel: | no | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasStmtList: | yes | -| gen_block_expr.rs:8:5:11:5 | ''label: { ... } | hasLabel: | yes | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasStmtList: | yes | +| gen_block_expr.rs:8:5:11:5 | 'label: { ... } | hasLabel: | yes | getNumberOfAttrs: | 0 | isAsync: | no | isConst: | no | isGen: | no | isMove: | no | isTry: | no | isUnsafe: | no | hasStmtList: | yes | diff --git a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getLabel.expected b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getLabel.expected index 289a157b0dc..a6933d65b22 100644 --- a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getLabel.expected +++ b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getLabel.expected @@ -1 +1 @@ -| gen_block_expr.rs:8:5:11:5 | ''label: { ... } | gen_block_expr.rs:8:5:8:11 | ''label | +| gen_block_expr.rs:8:5:11:5 | 'label: { ... } | gen_block_expr.rs:8:5:8:11 | 'label | diff --git a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getStmtList.expected b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getStmtList.expected index 582cff1a3cb..4863264491b 100644 --- a/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getStmtList.expected +++ b/rust/ql/test/extractor-tests/generated/BlockExpr/BlockExpr_getStmtList.expected @@ -1,3 +1,3 @@ | gen_block_expr.rs:3:28:12:1 | { ... } | gen_block_expr.rs:3:28:12:1 | StmtList | | gen_block_expr.rs:5:5:7:5 | { ... } | gen_block_expr.rs:5:5:7:5 | StmtList | -| gen_block_expr.rs:8:5:11:5 | ''label: { ... } | gen_block_expr.rs:8:13:11:5 | StmtList | +| gen_block_expr.rs:8:5:11:5 | 'label: { ... } | gen_block_expr.rs:8:13:11:5 | StmtList | diff --git a/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat.expected b/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat.expected index 810704f963e..8ca2412e8ff 100644 --- a/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat.expected +++ b/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat.expected @@ -1,2 +1,2 @@ | gen_box_pat.rs:6:9:6:27 | box ... | hasPat: | yes | -| gen_box_pat.rs:7:9:7:24 | box Option::None | hasPat: | yes | +| gen_box_pat.rs:7:9:7:24 | box ...::None | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat_getPat.expected b/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat_getPat.expected index f30ce324802..4e12432652d 100644 --- a/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/BoxPat/BoxPat_getPat.expected @@ -1,2 +1,2 @@ | gen_box_pat.rs:6:9:6:27 | box ... | gen_box_pat.rs:6:13:6:27 | TupleStructPat | -| gen_box_pat.rs:7:9:7:24 | box Option::None | gen_box_pat.rs:7:13:7:24 | Option::None | +| gen_box_pat.rs:7:9:7:24 | box ...::None | gen_box_pat.rs:7:13:7:24 | ...::None | diff --git a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected index c85e4186631..35cb00b044a 100644 --- a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected @@ -1 +1 @@ -| gen_cast_expr.rs:5:5:5:16 | value as u64 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasTy: | yes | +| gen_cast_expr.rs:5:5:5:16 | value as | getNumberOfAttrs: | 0 | hasExpr: | yes | hasTy: | yes | diff --git a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected index 01a710bfb53..d3bf1efc8b1 100644 --- a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected @@ -1 +1 @@ -| gen_cast_expr.rs:5:5:5:16 | value as u64 | gen_cast_expr.rs:5:5:5:9 | value | +| gen_cast_expr.rs:5:5:5:16 | value as | gen_cast_expr.rs:5:5:5:9 | value | diff --git a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected index 87c07babb02..4e7fdb1e25c 100644 --- a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected +++ b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected @@ -1 +1 @@ -| gen_cast_expr.rs:5:5:5:16 | value as u64 | gen_cast_expr.rs:5:14:5:16 | u64 | +| gen_cast_expr.rs:5:5:5:16 | value as | gen_cast_expr.rs:5:14:5:16 | | diff --git a/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr.expected b/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr.expected index f2c4e28c337..a09556b9a3f 100644 --- a/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr.expected +++ b/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr.expected @@ -1,2 +1,2 @@ | gen_continue_expr.rs:7:13:7:20 | continue | getNumberOfAttrs: | 0 | hasLifetime: | no | -| gen_continue_expr.rs:12:13:12:27 | continue ''label | getNumberOfAttrs: | 0 | hasLifetime: | yes | +| gen_continue_expr.rs:12:13:12:27 | continue 'label | getNumberOfAttrs: | 0 | hasLifetime: | yes | diff --git a/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected b/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected index f4fa30ade3c..d81d276ce0a 100644 --- a/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected +++ b/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected @@ -1 +1 @@ -| gen_continue_expr.rs:12:13:12:27 | continue ''label | gen_continue_expr.rs:12:22:12:27 | ''label | +| gen_continue_expr.rs:12:13:12:27 | continue 'label | gen_continue_expr.rs:12:22:12:27 | ''label | diff --git a/rust/ql/test/extractor-tests/generated/Label/Label.expected b/rust/ql/test/extractor-tests/generated/Label/Label.expected index ad594afe55b..7525044aaa2 100644 --- a/rust/ql/test/extractor-tests/generated/Label/Label.expected +++ b/rust/ql/test/extractor-tests/generated/Label/Label.expected @@ -1 +1 @@ -| gen_label.rs:5:5:5:11 | ''label | hasLifetime: | yes | +| gen_label.rs:5:5:5:11 | 'label | hasLifetime: | yes | diff --git a/rust/ql/test/extractor-tests/generated/Label/Label_getLifetime.expected b/rust/ql/test/extractor-tests/generated/Label/Label_getLifetime.expected index d3ea9171b8c..73ebbe963e8 100644 --- a/rust/ql/test/extractor-tests/generated/Label/Label_getLifetime.expected +++ b/rust/ql/test/extractor-tests/generated/Label/Label_getLifetime.expected @@ -1 +1 @@ -| gen_label.rs:5:5:5:11 | ''label | gen_label.rs:5:5:5:10 | ''label | +| gen_label.rs:5:5:5:11 | 'label | gen_label.rs:5:5:5:10 | ''label | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt.expected index 87c62a65a3a..847ff988ff0 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt.expected @@ -3,4 +3,4 @@ | gen_let_stmt.rs:7:5:7:15 | let ... | getNumberOfAttrs: | 0 | hasInitializer: | no | hasLetElse: | no | hasPat: | yes | hasTy: | yes | | gen_let_stmt.rs:8:5:8:10 | let ... | getNumberOfAttrs: | 0 | hasInitializer: | no | hasLetElse: | no | hasPat: | yes | hasTy: | no | | gen_let_stmt.rs:9:5:9:24 | let ... = ... | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | no | hasPat: | yes | hasTy: | no | -| gen_let_stmt.rs:10:5:12:6 | let ... = ... else { ... } | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | yes | hasPat: | yes | hasTy: | no | +| gen_let_stmt.rs:10:5:12:6 | let ... = ... else {...} | getNumberOfAttrs: | 0 | hasInitializer: | yes | hasLetElse: | yes | hasPat: | yes | hasTy: | no | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected index a88557f9d70..bd8368e351f 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.expected @@ -1,4 +1,4 @@ | gen_let_stmt.rs:5:5:5:15 | let ... = 42 | gen_let_stmt.rs:5:13:5:14 | 42 | | gen_let_stmt.rs:6:5:6:20 | let ... = 42 | gen_let_stmt.rs:6:18:6:19 | 42 | | gen_let_stmt.rs:9:5:9:24 | let ... = ... | gen_let_stmt.rs:9:18:9:23 | TupleExpr | -| gen_let_stmt.rs:10:5:12:6 | let ... = ... else { ... } | gen_let_stmt.rs:10:19:10:38 | std::env::var(...) | +| gen_let_stmt.rs:10:5:12:6 | let ... = ... else {...} | gen_let_stmt.rs:10:19:10:38 | ...::var(...) | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getLetElse.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getLetElse.expected index 84efa0be3b2..5e8090859af 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getLetElse.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getLetElse.expected @@ -1 +1 @@ -| gen_let_stmt.rs:10:5:12:6 | let ... = ... else { ... } | gen_let_stmt.rs:10:40:12:5 | else { ... } | +| gen_let_stmt.rs:10:5:12:6 | let ... = ... else {...} | gen_let_stmt.rs:10:40:12:5 | else {...} | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected index e2aa2b9e957..758837c946d 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected @@ -3,4 +3,4 @@ | gen_let_stmt.rs:7:5:7:15 | let ... | gen_let_stmt.rs:7:9:7:9 | x | | gen_let_stmt.rs:8:5:8:10 | let ... | gen_let_stmt.rs:8:9:8:9 | x | | gen_let_stmt.rs:9:5:9:24 | let ... = ... | gen_let_stmt.rs:9:9:9:14 | TuplePat | -| gen_let_stmt.rs:10:5:12:6 | let ... = ... else { ... } | gen_let_stmt.rs:10:9:10:15 | TupleStructPat | +| gen_let_stmt.rs:10:5:12:6 | let ... = ... else {...} | gen_let_stmt.rs:10:9:10:15 | TupleStructPat | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected index 489647f4793..b917fcb8c7c 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected @@ -1,2 +1,2 @@ -| gen_let_stmt.rs:6:5:6:20 | let ... = 42 | gen_let_stmt.rs:6:12:6:14 | i32 | -| gen_let_stmt.rs:7:5:7:15 | let ... | gen_let_stmt.rs:7:12:7:14 | i32 | +| gen_let_stmt.rs:6:5:6:20 | let ... = 42 | gen_let_stmt.rs:6:12:6:14 | | +| gen_let_stmt.rs:7:5:7:15 | let ... | gen_let_stmt.rs:7:12:7:14 | | diff --git a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.expected b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.expected index f7129b16385..b0adbe40897 100644 --- a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.expected +++ b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr.expected @@ -1,3 +1,3 @@ | gen_loop_expr.rs:5:5:7:5 | loop { ... } | hasLabel: | no | hasLoopBody: | yes | getNumberOfAttrs: | 0 | -| gen_loop_expr.rs:8:5:11:5 | ''label: loop { ... } | hasLabel: | yes | hasLoopBody: | yes | getNumberOfAttrs: | 0 | +| gen_loop_expr.rs:8:5:11:5 | 'label: loop { ... } | hasLabel: | yes | hasLoopBody: | yes | getNumberOfAttrs: | 0 | | gen_loop_expr.rs:13:5:19:5 | loop { ... } | hasLabel: | no | hasLoopBody: | yes | getNumberOfAttrs: | 0 | diff --git a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLabel.expected b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLabel.expected index 167f84096fe..e2dc2fdf895 100644 --- a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLabel.expected +++ b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLabel.expected @@ -1 +1 @@ -| gen_loop_expr.rs:8:5:11:5 | ''label: loop { ... } | gen_loop_expr.rs:8:5:8:11 | ''label | +| gen_loop_expr.rs:8:5:11:5 | 'label: loop { ... } | gen_loop_expr.rs:8:5:8:11 | 'label | diff --git a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.expected b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.expected index 952955da19d..9cf0c64dd0b 100644 --- a/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.expected +++ b/rust/ql/test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.expected @@ -1,3 +1,3 @@ | gen_loop_expr.rs:5:5:7:5 | loop { ... } | gen_loop_expr.rs:5:10:7:5 | { ... } | -| gen_loop_expr.rs:8:5:11:5 | ''label: loop { ... } | gen_loop_expr.rs:8:18:11:5 | { ... } | +| gen_loop_expr.rs:8:5:11:5 | 'label: loop { ... } | gen_loop_expr.rs:8:18:11:5 | { ... } | | gen_loop_expr.rs:13:5:19:5 | loop { ... } | gen_loop_expr.rs:13:10:19:5 | { ... } | diff --git a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm.expected b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm.expected index d21faa7ff19..b3eb4c178b2 100644 --- a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm.expected +++ b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm.expected @@ -1,4 +1,4 @@ | gen_match_arm.rs:6:9:6:29 | ... => y | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | -| gen_match_arm.rs:7:9:7:26 | Option::None => 0 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | +| gen_match_arm.rs:7:9:7:26 | ...::None => 0 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | | gen_match_arm.rs:10:9:10:35 | ... if ... => ... | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | yes | hasPat: | yes | | gen_match_arm.rs:11:9:11:15 | _ => 0 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasGuard: | no | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getExpr.expected b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getExpr.expected index ecf8098fd78..95d4a7fc2f2 100644 --- a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getExpr.expected @@ -1,4 +1,4 @@ | gen_match_arm.rs:6:9:6:29 | ... => y | gen_match_arm.rs:6:28:6:28 | y | -| gen_match_arm.rs:7:9:7:26 | Option::None => 0 | gen_match_arm.rs:7:25:7:25 | 0 | +| gen_match_arm.rs:7:9:7:26 | ...::None => 0 | gen_match_arm.rs:7:25:7:25 | 0 | | gen_match_arm.rs:10:9:10:35 | ... if ... => ... | gen_match_arm.rs:10:30:10:34 | ... / ... | | gen_match_arm.rs:11:9:11:15 | _ => 0 | gen_match_arm.rs:11:14:11:14 | 0 | diff --git a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getPat.expected b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getPat.expected index 010c7b50b06..9928555fc32 100644 --- a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getPat.expected @@ -1,4 +1,4 @@ | gen_match_arm.rs:6:9:6:29 | ... => y | gen_match_arm.rs:6:9:6:23 | TupleStructPat | -| gen_match_arm.rs:7:9:7:26 | Option::None => 0 | gen_match_arm.rs:7:9:7:20 | Option::None | +| gen_match_arm.rs:7:9:7:26 | ...::None => 0 | gen_match_arm.rs:7:9:7:20 | ...::None | | gen_match_arm.rs:10:9:10:35 | ... if ... => ... | gen_match_arm.rs:10:9:10:15 | TupleStructPat | | gen_match_arm.rs:11:9:11:15 | _ => 0 | gen_match_arm.rs:11:9:11:9 | _ | diff --git a/rust/ql/test/extractor-tests/generated/OffsetOfExpr/OffsetOfExpr_getTy.expected b/rust/ql/test/extractor-tests/generated/OffsetOfExpr/OffsetOfExpr_getTy.expected index e2e11abb6a0..f6ab8a92aff 100644 --- a/rust/ql/test/extractor-tests/generated/OffsetOfExpr/OffsetOfExpr_getTy.expected +++ b/rust/ql/test/extractor-tests/generated/OffsetOfExpr/OffsetOfExpr_getTy.expected @@ -1 +1 @@ -| gen_offset_of_expr.rs:5:5:5:38 | OffsetOfExpr | gen_offset_of_expr.rs:5:25:5:30 | Struct | +| gen_offset_of_expr.rs:5:5:5:38 | OffsetOfExpr | gen_offset_of_expr.rs:5:25:5:30 | | diff --git a/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected b/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected index 26426d2c5aa..1d67a8509b9 100644 --- a/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected +++ b/rust/ql/test/extractor-tests/generated/OrPat/OrPat.expected @@ -1 +1 @@ -| gen_or_pat.rs:6:9:6:38 | ... \| Option::None | getNumberOfPats: | 2 | +| gen_or_pat.rs:6:9:6:38 | ... \| ...::None | getNumberOfPats: | 2 | diff --git a/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected b/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected index 80326c82f0d..22ebce5dde5 100644 --- a/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/OrPat/OrPat_getPat.expected @@ -1,2 +1,2 @@ -| gen_or_pat.rs:6:9:6:38 | ... \| Option::None | 0 | gen_or_pat.rs:6:9:6:23 | TupleStructPat | -| gen_or_pat.rs:6:9:6:38 | ... \| Option::None | 1 | gen_or_pat.rs:6:27:6:38 | Option::None | +| gen_or_pat.rs:6:9:6:38 | ... \| ...::None | 0 | gen_or_pat.rs:6:9:6:23 | TupleStructPat | +| gen_or_pat.rs:6:9:6:38 | ... \| ...::None | 1 | gen_or_pat.rs:6:27:6:38 | ...::None | diff --git a/rust/ql/test/extractor-tests/generated/RefPat/RefPat.expected b/rust/ql/test/extractor-tests/generated/RefPat/RefPat.expected index 3e52c12807e..a9dfaf87456 100644 --- a/rust/ql/test/extractor-tests/generated/RefPat/RefPat.expected +++ b/rust/ql/test/extractor-tests/generated/RefPat/RefPat.expected @@ -1,2 +1,2 @@ | gen_ref_pat.rs:6:9:6:28 | &mut ... | isMut: | yes | hasPat: | yes | -| gen_ref_pat.rs:7:9:7:21 | &Option::None | isMut: | no | hasPat: | yes | +| gen_ref_pat.rs:7:9:7:21 | &...::None | isMut: | no | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/RefPat/RefPat_getPat.expected b/rust/ql/test/extractor-tests/generated/RefPat/RefPat_getPat.expected index 96b017a42ea..d4f78daeb82 100644 --- a/rust/ql/test/extractor-tests/generated/RefPat/RefPat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/RefPat/RefPat_getPat.expected @@ -1,2 +1,2 @@ | gen_ref_pat.rs:6:9:6:28 | &mut ... | gen_ref_pat.rs:6:14:6:28 | TupleStructPat | -| gen_ref_pat.rs:7:9:7:21 | &Option::None | gen_ref_pat.rs:7:10:7:21 | Option::None | +| gen_ref_pat.rs:7:9:7:21 | &...::None | gen_ref_pat.rs:7:10:7:21 | ...::None | diff --git a/rust/ql/test/extractor-tests/utf8/ast.expected b/rust/ql/test/extractor-tests/utf8/ast.expected index 560f834766e..e1d0418c206 100644 --- a/rust/ql/test/extractor-tests/utf8/ast.expected +++ b/rust/ql/test/extractor-tests/utf8/ast.expected @@ -17,7 +17,7 @@ | utf8_identifiers.rs:6:10:8:1 | RecordFieldList | | utf8_identifiers.rs:7:5:7:5 | \u03b4 | | utf8_identifiers.rs:7:5:7:13 | RecordField | -| utf8_identifiers.rs:7:9:7:13 | usize | +| utf8_identifiers.rs:7:9:7:13 | | | utf8_identifiers.rs:7:9:7:13 | usize | | utf8_identifiers.rs:7:9:7:13 | usize | | utf8_identifiers.rs:7:9:7:13 | usize | diff --git a/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected b/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected index 4260e2384c8..bdc9d30f09c 100644 --- a/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected @@ -1,12 +1,12 @@ edges | test.rs:5:5:11:5 | enter fn test_and_if_let | test.rs:5:24:5:24 | a | | | test.rs:5:5:11:5 | exit fn test_and_if_let (normal) | test.rs:5:5:11:5 | exit fn test_and_if_let | | -| test.rs:5:24:5:24 | a | test.rs:5:24:5:30 | ...: bool | match | -| test.rs:5:24:5:30 | ...: bool | test.rs:5:33:5:33 | b | | -| test.rs:5:33:5:33 | b | test.rs:5:33:5:47 | ...: Option::<...> | match | -| test.rs:5:33:5:47 | ...: Option::<...> | test.rs:5:50:5:50 | c | | -| test.rs:5:50:5:50 | c | test.rs:5:50:5:56 | ...: bool | match | -| test.rs:5:50:5:56 | ...: bool | test.rs:6:12:6:12 | a | | +| test.rs:5:24:5:24 | a | test.rs:5:24:5:30 | ...: | match | +| test.rs:5:24:5:30 | ...: | test.rs:5:33:5:33 | b | | +| test.rs:5:33:5:33 | b | test.rs:5:33:5:47 | ...: > | match | +| test.rs:5:33:5:47 | ...: > | test.rs:5:50:5:50 | c | | +| test.rs:5:50:5:50 | c | test.rs:5:50:5:56 | ...: | match | +| test.rs:5:50:5:56 | ...: | test.rs:6:12:6:12 | a | | | test.rs:5:67:11:5 | { ... } | test.rs:5:5:11:5 | exit fn test_and_if_let (normal) | | | test.rs:6:9:10:9 | if ... {...} else {...} | test.rs:5:67:11:5 | { ... } | | | test.rs:6:12:6:12 | a | test.rs:6:12:6:31 | [boolean(false)] ... && ... | false | @@ -24,12 +24,12 @@ edges | test.rs:9:13:9:17 | false | test.rs:8:16:10:9 | { ... } | | | test.rs:13:5:21:5 | enter fn test_and_if_let2 | test.rs:13:25:13:25 | a | | | test.rs:13:5:21:5 | exit fn test_and_if_let2 (normal) | test.rs:13:5:21:5 | exit fn test_and_if_let2 | | -| test.rs:13:25:13:25 | a | test.rs:13:25:13:31 | ...: bool | match | -| test.rs:13:25:13:31 | ...: bool | test.rs:13:34:13:34 | b | | -| test.rs:13:34:13:34 | b | test.rs:13:34:13:39 | ...: i64 | match | -| test.rs:13:34:13:39 | ...: i64 | test.rs:13:42:13:42 | c | | -| test.rs:13:42:13:42 | c | test.rs:13:42:13:48 | ...: bool | match | -| test.rs:13:42:13:48 | ...: bool | test.rs:14:12:14:12 | a | | +| test.rs:13:25:13:25 | a | test.rs:13:25:13:31 | ...: | match | +| test.rs:13:25:13:31 | ...: | test.rs:13:34:13:34 | b | | +| test.rs:13:34:13:34 | b | test.rs:13:34:13:39 | ...: | match | +| test.rs:13:34:13:39 | ...: | test.rs:13:42:13:42 | c | | +| test.rs:13:42:13:42 | c | test.rs:13:42:13:48 | ...: | match | +| test.rs:13:42:13:48 | ...: | test.rs:14:12:14:12 | a | | | test.rs:13:59:21:5 | { ... } | test.rs:13:5:21:5 | exit fn test_and_if_let2 (normal) | | | test.rs:14:9:20:9 | if ... {...} else {...} | test.rs:13:59:21:5 | { ... } | | | test.rs:14:12:14:12 | a | test.rs:14:12:14:25 | [boolean(false)] ... && ... | false | From 65be8a8aedb71d9a1081bc5ef0ac2362d6fb888b Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 21 Nov 2024 13:15:49 +0100 Subject: [PATCH 152/470] CI: Set `--ram` in `compile-queries.yml` --- .github/workflows/compile-queries.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/compile-queries.yml b/.github/workflows/compile-queries.yml index 38452f97d36..dfd99f6b806 100644 --- a/.github/workflows/compile-queries.yml +++ b/.github/workflows/compile-queries.yml @@ -33,9 +33,9 @@ jobs: # run with --check-only if running in a PR (github.sha != main) if : ${{ github.event_name == 'pull_request' }} shell: bash - run: codeql query compile -q -j0 */ql/{src,examples} --keep-going --warnings=error --check-only --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" --compilation-cache-size=500 + run: codeql query compile -q -j0 */ql/{src,examples} --keep-going --warnings=error --check-only --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" --compilation-cache-size=500 --ram=56000 - name: compile queries - full # do full compile if running on main - this populates the cache if : ${{ github.event_name != 'pull_request' }} shell: bash - run: codeql query compile -q -j0 */ql/{src,examples} --keep-going --warnings=error --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" --compilation-cache-size=500 + run: codeql query compile -q -j0 */ql/{src,examples} --keep-going --warnings=error --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" --compilation-cache-size=500 --ram=56000 From 7ee0a7b3982e47a7aefdeeb64fd7c24caa43a9d4 Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Thu, 21 Nov 2024 14:02:42 +0100 Subject: [PATCH 153/470] Update javascript/ql/lib/semmle/javascript/Collections.qll Co-authored-by: Erik Krogh Kristensen --- javascript/ql/lib/semmle/javascript/Collections.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/Collections.qll b/javascript/ql/lib/semmle/javascript/Collections.qll index df7ad317014..028c3abe4b3 100644 --- a/javascript/ql/lib/semmle/javascript/Collections.qll +++ b/javascript/ql/lib/semmle/javascript/Collections.qll @@ -160,7 +160,7 @@ private module CollectionDataFlow { exists(DataFlow::MethodCallNode call | call = DataFlow::globalVarRef(["Map", "Object"]).getAMemberCall("groupBy") and pred = call.getArgument(0) and - (succ = call.getCallback(1).getParameter(0) or succ = call.getALocalUse()) + (succ = call.getCallback(1).getParameter(0) or succ = call) ) } } From 6f3e6edd0e50f256bd69ebc89d1086bf21be7ac1 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Mon, 18 Nov 2024 14:17:13 +0000 Subject: [PATCH 154/470] C++: Implement compilation_build_mode --- cpp/ql/lib/semmle/code/cpp/Compilation.qll | 3 +++ cpp/ql/lib/semmlecode.cpp.dbscheme | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/Compilation.qll b/cpp/ql/lib/semmle/code/cpp/Compilation.qll index 1a8d90f991c..407dc31e05f 100644 --- a/cpp/ql/lib/semmle/code/cpp/Compilation.qll +++ b/cpp/ql/lib/semmle/code/cpp/Compilation.qll @@ -112,4 +112,7 @@ class Compilation extends @compilation { * termination, but crashing due to something like a segfault is not. */ predicate normalTermination() { compilation_finished(this, _, _) } + + /** Holds if this compilation was compiled using the "none" build mode. */ + predicate buildModeNone() { compilation_build_mode(this, 0) } } diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index e51fad7a243..0c8b8927c0c 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -46,6 +46,20 @@ compilation_args( string arg : string ref ); +/** + * Optionally, record the build mode for each compilation. + * The build mode should be the same for all compilations. + * Build mode: + * 0 = none + * 1 = manual + * 2 = auto + */ +#keyset[id, mode] +compilation_build_mode( + int id : @compilation ref, + int mode : int ref +); + /** * The source files that are compiled by a compiler invocation. * If `id` is for the compiler invocation From ac4121dd6ceffe195f30bfbd5e6bf7fb278c22cb Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Mon, 18 Nov 2024 17:20:48 +0000 Subject: [PATCH 155/470] C++: Describe compilation_build_mode using a case --- cpp/ql/lib/semmlecode.cpp.dbscheme | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index 0c8b8927c0c..54b0075a9d8 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -49,10 +49,6 @@ compilation_args( /** * Optionally, record the build mode for each compilation. * The build mode should be the same for all compilations. - * Build mode: - * 0 = none - * 1 = manual - * 2 = auto */ #keyset[id, mode] compilation_build_mode( @@ -60,6 +56,14 @@ compilation_build_mode( int mode : int ref ); +/* +case @compilation_build_mode.mode of + 0 = @build_mode_none +| 1 = @build_mode_manual +| 2 = @build_mode_auto +; +/* + /** * The source files that are compiled by a compiler invocation. * If `id` is for the compiler invocation From d3e8292db990f2839efe61eee3f9fe38f067abd5 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Tue, 19 Nov 2024 10:50:21 +0000 Subject: [PATCH 156/470] C++: Update dbscheme --- cpp/ql/lib/semmlecode.cpp.dbscheme | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index 54b0075a9d8..f0156f5f88a 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -48,11 +48,9 @@ compilation_args( /** * Optionally, record the build mode for each compilation. - * The build mode should be the same for all compilations. */ -#keyset[id, mode] compilation_build_mode( - int id : @compilation ref, + unique int id : @compilation ref, int mode : int ref ); @@ -62,7 +60,7 @@ case @compilation_build_mode.mode of | 1 = @build_mode_manual | 2 = @build_mode_auto ; -/* +*/ /** * The source files that are compiled by a compiler invocation. From 10f692b57cfb0cd7be1be70945db676390f5be39 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Tue, 19 Nov 2024 12:18:38 +0000 Subject: [PATCH 157/470] C++: DB upgrade scripts --- .../old.dbscheme | 2339 +++++++++++++++++ .../semmlecode.cpp.dbscheme | 2323 ++++++++++++++++ .../upgrade.properties | 2 + .../old.dbscheme | 2323 ++++++++++++++++ .../semmlecode.cpp.dbscheme | 2339 +++++++++++++++++ .../upgrade.properties | 2 + 6 files changed, 9328 insertions(+) create mode 100644 cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/old.dbscheme create mode 100644 cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/semmlecode.cpp.dbscheme create mode 100644 cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties create mode 100644 cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/old.dbscheme create mode 100644 cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/semmlecode.cpp.dbscheme create mode 100644 cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/upgrade.properties diff --git a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/old.dbscheme b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/old.dbscheme new file mode 100644 index 00000000000..f0156f5f88a --- /dev/null +++ b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/old.dbscheme @@ -0,0 +1,2339 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * Optionally, record the build mode for each compilation. + */ +compilation_build_mode( + unique int id : @compilation ref, + int mode : int ref +); + +/* +case @compilation_build_mode.mode of + 0 = @build_mode_none +| 1 = @build_mode_manual +| 2 = @build_mode_auto +; +*/ + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref +); + +/* +case @coroutine_placeholder_variable.kind of + 1 = @handle +| 2 = @promise +| 3 = @init_await_resume +; +*/ + +coroutine_placeholder_variable( + unique int placeholder_variable: @variable ref, + int kind: int ref, + int function: @function ref +) + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @parameterized_element ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + | @c11_generic + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +| 389 = @c11_generic +| 390 = @requires_expr +| 391 = @nested_requirement +| 392 = @compound_requirement +| 393 = @concept_id +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + ; + +compound_requirement_is_noexcept( + int expr: @compound_requirement ref +); + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@parameterized_element = @function | @stmt_block | @requires_expr; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @parameterized_element ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/semmlecode.cpp.dbscheme b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..e51fad7a243 --- /dev/null +++ b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/semmlecode.cpp.dbscheme @@ -0,0 +1,2323 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref +); + +/* +case @coroutine_placeholder_variable.kind of + 1 = @handle +| 2 = @promise +| 3 = @init_await_resume +; +*/ + +coroutine_placeholder_variable( + unique int placeholder_variable: @variable ref, + int kind: int ref, + int function: @function ref +) + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @parameterized_element ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + | @c11_generic + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +| 389 = @c11_generic +| 390 = @requires_expr +| 391 = @nested_requirement +| 392 = @compound_requirement +| 393 = @concept_id +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + ; + +compound_requirement_is_noexcept( + int expr: @compound_requirement ref +); + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@parameterized_element = @function | @stmt_block | @requires_expr; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @parameterized_element ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties new file mode 100644 index 00000000000..08e1dc42eb2 --- /dev/null +++ b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties @@ -0,0 +1,2 @@ +description: Implement compilation_build_mode/2 +compatibility: backwards diff --git a/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/old.dbscheme b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/old.dbscheme new file mode 100644 index 00000000000..e51fad7a243 --- /dev/null +++ b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/old.dbscheme @@ -0,0 +1,2323 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref +); + +/* +case @coroutine_placeholder_variable.kind of + 1 = @handle +| 2 = @promise +| 3 = @init_await_resume +; +*/ + +coroutine_placeholder_variable( + unique int placeholder_variable: @variable ref, + int kind: int ref, + int function: @function ref +) + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @parameterized_element ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + | @c11_generic + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +| 389 = @c11_generic +| 390 = @requires_expr +| 391 = @nested_requirement +| 392 = @compound_requirement +| 393 = @concept_id +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + ; + +compound_requirement_is_noexcept( + int expr: @compound_requirement ref +); + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@parameterized_element = @function | @stmt_block | @requires_expr; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @parameterized_element ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..f0156f5f88a --- /dev/null +++ b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/semmlecode.cpp.dbscheme @@ -0,0 +1,2339 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * Optionally, record the build mode for each compilation. + */ +compilation_build_mode( + unique int id : @compilation ref, + int mode : int ref +); + +/* +case @compilation_build_mode.mode of + 0 = @build_mode_none +| 1 = @build_mode_manual +| 2 = @build_mode_auto +; +*/ + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref +); + +/* +case @coroutine_placeholder_variable.kind of + 1 = @handle +| 2 = @promise +| 3 = @init_await_resume +; +*/ + +coroutine_placeholder_variable( + unique int placeholder_variable: @variable ref, + int kind: int ref, + int function: @function ref +) + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @parameterized_element ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + | @c11_generic + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +| 389 = @c11_generic +| 390 = @requires_expr +| 391 = @nested_requirement +| 392 = @compound_requirement +| 393 = @concept_id +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + ; + +compound_requirement_is_noexcept( + int expr: @compound_requirement ref +); + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@parameterized_element = @function | @stmt_block | @requires_expr; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @parameterized_element ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/upgrade.properties b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/upgrade.properties new file mode 100644 index 00000000000..08e1dc42eb2 --- /dev/null +++ b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/upgrade.properties @@ -0,0 +1,2 @@ +description: Implement compilation_build_mode/2 +compatibility: backwards From 8050b8246b8e2b0a95ba60c390001e278fa57c05 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Tue, 19 Nov 2024 13:57:03 +0000 Subject: [PATCH 158/470] C++: Update stats --- cpp/ql/lib/semmlecode.cpp.dbscheme.stats | 1096 ++++++++++------------ 1 file changed, 474 insertions(+), 622 deletions(-) diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats index 7f0d99272e7..f37e932ca54 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats @@ -42,7 +42,7 @@ @macro_expansion - 33257760 + 33257556 @other_macro_reference @@ -78,7 +78,7 @@ @using_enum_declaration - 1 + 0 @static_assert @@ -98,7 +98,7 @@ @localvariable - 576945 + 576944 @enumconstant @@ -362,7 +362,7 @@ @block - 10 + 0 @decltype @@ -406,7 +406,7 @@ @msattribute - 3 + 0 @alignas @@ -422,11 +422,11 @@ @attribute_arg_empty - 1 + 0 @attribute_arg_constant - 1 + 0 @attribute_arg_type @@ -434,7 +434,7 @@ @attribute_arg_expr - 3 + 0 @derivation @@ -482,7 +482,7 @@ @parexpr - 3587463 + 3587464 @arithnegexpr @@ -766,39 +766,39 @@ @jmulexpr - 1 + 0 @jdivexpr - 1 + 0 @fjaddexpr - 1 + 0 @jfaddexpr - 1 + 0 @fjsubexpr - 1 + 0 @jfsubexpr - 1 + 0 @minexpr - 1 + 0 @maxexpr - 1 + 0 @virtfunptrexpr - 1 + 0 @thisaccess @@ -834,43 +834,43 @@ @hasassignexpr - 2 + 0 @hascopyexpr - 2 + 0 @hasnothrowassign - 3 + 0 @hasnothrowconstr - 3 + 0 @hasnothrowcopy - 5 + 0 @hastrivialassign - 2 + 0 @hastrivialconstr - 3 + 0 @hastrivialcopy - 2 + 0 @hasuserdestr - 3 + 0 @hasvirtualdestr - 3 + 0 @isabstractexpr @@ -902,15 +902,15 @@ @ispolyexpr - 3 + 0 @isunionexpr - 5 + 0 @intaddrexpr - 1 + 0 @hastrivialdestructor @@ -930,7 +930,7 @@ @foldexpr - 4 + 0 @ctordirectinit @@ -962,7 +962,7 @@ @static_cast - 215648 + 215647 @reinterpret_cast @@ -994,11 +994,11 @@ @isdestructibleexpr - 4 + 0 @isnothrowdestructibleexpr - 5 + 0 @istriviallydestructibleexpr @@ -1006,7 +1006,7 @@ @istriviallyassignableexpr - 3 + 0 @isnothrowassignableexpr @@ -1018,7 +1018,7 @@ @isstandardlayoutexpr - 2 + 0 @istriviallycopyableexpr @@ -1026,19 +1026,19 @@ @isliteraltypeexpr - 2 + 0 @hastrivialmoveconstructorexpr - 3 + 0 @hastrivialmoveassignexpr - 3 + 0 @hasnothrowmoveassignexpr - 4 + 0 @isconstructibleexpr @@ -1050,35 +1050,35 @@ @hasfinalizerexpr - 1 + 0 @isdelegateexpr - 1 + 0 @isinterfaceclassexpr - 1 + 0 @isrefarrayexpr - 1 + 0 @isrefclassexpr - 1 + 0 @issealedexpr - 1 + 0 @issimplevalueclassexpr - 1 + 0 @isvalueclassexpr - 1 + 0 @isfinalexpr @@ -1090,7 +1090,7 @@ @builtinshufflevector - 1 + 0 @builtinchooseexpr @@ -1102,43 +1102,43 @@ @vec_fill - 1 + 0 @builtinconvertvector - 1 + 0 @builtincomplex - 4 + 0 @spaceshipexpr - 1 + 0 @co_await - 12 + 0 @co_yield - 4 + 0 @isassignable - 3 + 0 @isaggregate - 2 + 0 @hasuniqueobjectrepresentations - 2 + 0 @builtinbitcast - 1 + 0 @builtinshuffle @@ -1150,111 +1150,111 @@ @issame - 2 + 0 @isfunction - 2 + 0 @islayoutcompatible - 2 + 0 @ispointerinterconvertiblebaseof - 2 + 0 @isarray - 2 + 0 @arrayrank - 2 + 0 @arrayextent - 3 + 0 @isarithmetic - 2 + 0 @iscompletetype - 2 + 0 @iscompound - 2 + 0 @isconst - 2 + 0 @isfloatingpoint - 2 + 0 @isfundamental - 2 + 0 @isintegral - 2 + 0 @islvaluereference - 2 + 0 @ismemberfunctionpointer - 2 + 0 @ismemberobjectpointer - 2 + 0 @ismemberpointer - 3 + 0 @isobject - 2 + 0 @ispointer - 2 + 0 @isreference - 2 + 0 @isrvaluereference - 2 + 0 @isscalar - 2 + 0 @issigned - 2 + 0 @isunsigned - 2 + 0 @isvoid - 2 + 0 @isvolatile - 2 + 0 @reuseexpr @@ -1262,115 +1262,115 @@ @istriviallycopyassignable - 2 + 0 @isassignablenopreconditioncheck - 3 + 0 @referencebindstotemporary - 2 + 0 @issameas - 2 + 0 @builtinhasattribute - 2 + 0 @ispointerinterconvertiblewithclass - 2 + 0 @builtinispointerinterconvertiblewithclass - 2 + 0 @iscorrespondingmember - 2 + 0 @builtiniscorrespondingmember - 2 + 0 @isboundedarray - 2 + 0 @isunboundedarray - 2 + 0 @isreferenceable - 2 + 0 @isnothrowconvertible - 2 + 0 @referenceconstructsfromtemporary - 2 + 0 @referenceconvertsfromtemporary - 2 + 0 @isconvertible - 2 + 0 @isvalidwinrttype - 1 + 0 @iswinclass - 1 + 0 @iswininterface - 1 + 0 @istriviallyequalitycomparable - 2 + 0 @isscopedenum - 2 + 0 @istriviallyrelocatable - 2 + 0 @datasizeof - 10 + 0 @c11_generic - 8 + 0 @requires_expr - 8 + 0 @nested_requirement - 1 + 0 @compound_requirement - 2 + 0 @concept_id - 2 + 0 @lambdacapture @@ -1426,7 +1426,7 @@ @stmt_decl - 593121 + 593118 @stmt_empty @@ -1474,7 +1474,7 @@ @stmt_co_return - 5 + 0 @ppd_if @@ -1530,11 +1530,11 @@ @ppd_objc_import - 2 + 0 @ppd_warning - 1 + 0 @link_target @@ -1900,6 +1900,48 @@ + + compilation_build_mode + 0 + + + id + 0 + + + mode + 0 + + + + + id + mode + + + 12 + + + 1 + 2 + 17 + + + + + + + mode + id + + + 12 + + + + + + compilation_compiling_files 11546 @@ -2164,7 +2206,7 @@ seconds - 8429 + 9468 @@ -2242,18 +2284,23 @@ 12 + + 2 + 3 + 39 + 3 4 - 639 + 479 4 5 - 359 + 479 - 6 + 5 7 119 @@ -2265,27 +2312,27 @@ 10 11 - 119 - - - 11 - 15 159 - 16 + 11 + 17 + 159 + + + 17 19 159 19 - 24 + 44 159 - 40 - 89 - 119 + 54 + 100 + 79 @@ -2353,43 +2400,43 @@ 3 4 - 1438 + 1398 4 5 - 319 + 359 5 6 - 199 + 159 6 7 - 439 + 519 7 8 - 159 + 79 8 - 10 + 9 + 239 + + + 9 + 21 279 - 10 - 26 + 24 + 86 279 - - 28 - 81 - 199 - @@ -2439,13 +2486,13 @@ 79 - 125 - 126 + 141 + 142 39 - 128 - 129 + 145 + 146 39 @@ -2462,27 +2509,27 @@ 1 2 - 3635 + 4234 2 3 - 1917 + 2357 3 4 - 1558 + 1797 4 6 - 719 + 838 6 48 - 599 + 239 @@ -2498,37 +2545,32 @@ 1 2 - 3595 + 4274 2 3 - 1438 + 1757 3 4 - 1358 + 1158 4 5 - 639 + 1158 5 - 6 - 479 + 7 + 799 - 6 - 8 - 679 - - - 8 - 73 - 239 + 7 + 74 + 319 @@ -2544,12 +2586,12 @@ 1 2 - 6512 + 7271 2 3 - 1917 + 2197 @@ -2893,7 +2935,7 @@ cpu_seconds - 7507 + 7382 elapsed_seconds @@ -2943,16 +2985,16 @@ 1 2 - 6242 + 5881 2 3 - 835 + 1072 3 - 15 + 12 428 @@ -2969,12 +3011,12 @@ 1 2 - 6976 + 6694 2 3 - 530 + 688 @@ -2987,24 +3029,14 @@ 12 - - 1 - 2 - 11 - 2 3 - 11 + 33 - 3 - 4 - 11 - - - 6 - 7 + 7 + 8 11 @@ -3013,8 +3045,8 @@ 11 - 11 - 12 + 10 + 11 11 @@ -3023,28 +3055,28 @@ 11 - 49 - 50 + 50 + 51 11 - 154 - 155 + 163 + 164 11 - 160 - 161 + 165 + 166 11 - 204 - 205 + 194 + 195 11 - 248 - 249 + 243 + 244 11 @@ -3058,24 +3090,14 @@ 12 - - 1 - 2 - 11 - 2 3 - 11 + 33 - 3 - 4 - 11 - - - 6 - 7 + 7 + 8 11 @@ -3084,8 +3106,8 @@ 11 - 11 - 12 + 10 + 11 11 @@ -3094,28 +3116,28 @@ 11 - 47 - 48 + 48 + 49 11 - 118 - 119 + 120 + 121 11 - 128 - 129 + 137 + 138 11 - 149 - 150 + 146 + 147 11 - 222 - 223 + 216 + 217 11 @@ -11816,7 +11838,7 @@ fileannotations - 5129436 + 5129404 id @@ -12392,15 +12414,15 @@ inmacroexpansion - 109779080 + 109779103 id - 18027694 + 18027697 inv - 2700160 + 2700159 @@ -12414,12 +12436,12 @@ 1 3 - 1582361 + 1582360 3 5 - 1077793 + 1077794 5 @@ -12429,17 +12451,17 @@ 6 7 - 4819903 + 4819904 7 8 - 6385932 + 6385934 8 9 - 2605242 + 2605243 9 @@ -12460,12 +12482,12 @@ 1 2 - 378424 + 378422 2 3 - 544104 + 544105 3 @@ -12500,7 +12522,7 @@ 11 337 - 224847 + 224845 339 @@ -12520,15 +12542,15 @@ affectedbymacroexpansion - 35689251 + 35689257 id - 5156949 + 5156948 inv - 2784762 + 2784761 @@ -12542,7 +12564,7 @@ 1 2 - 2816079 + 2816078 2 @@ -12588,7 +12610,7 @@ 1 4 - 229116 + 229115 4 @@ -12603,12 +12625,12 @@ 9 12 - 251119 + 251120 12 13 - 333984 + 333985 13 @@ -12628,7 +12650,7 @@ 16 17 - 276608 + 276609 17 @@ -12658,19 +12680,19 @@ macroinvocations - 33491008 + 33490802 id - 33491008 + 33490802 macro_id - 79484 + 79483 location - 760387 + 760382 kind @@ -12688,7 +12710,7 @@ 1 2 - 33491008 + 33490802 @@ -12704,7 +12726,7 @@ 1 2 - 33491008 + 33490802 @@ -12720,7 +12742,7 @@ 1 2 - 33491008 + 33490802 @@ -12802,7 +12824,7 @@ 1 2 - 42468 + 42467 2 @@ -12848,7 +12870,7 @@ 1 2 - 73749 + 73748 2 @@ -12869,22 +12891,22 @@ 1 2 - 281225 + 281223 2 3 - 169658 + 169657 3 4 - 70735 + 70734 4 5 - 60327 + 60326 5 @@ -12920,7 +12942,7 @@ 1 2 - 714216 + 714211 2 @@ -12941,7 +12963,7 @@ 1 2 - 760387 + 760382 @@ -13014,15 +13036,15 @@ macroparent - 29950722 + 29950538 id - 29950722 + 29950538 parent_id - 23286998 + 23286856 @@ -13036,7 +13058,7 @@ 1 2 - 29950722 + 29950538 @@ -13052,17 +13074,17 @@ 1 2 - 17992792 + 17992681 2 3 - 4459550 + 4459523 3 88 - 834655 + 834650 @@ -13150,11 +13172,11 @@ macro_argument_unexpanded - 84549437 + 84548918 invocation - 26214757 + 26214596 argument_index @@ -13162,7 +13184,7 @@ text - 318308 + 318306 @@ -13176,22 +13198,22 @@ 1 2 - 7432464 + 7432418 2 3 - 10674027 + 10673962 3 4 - 6139327 + 6139289 4 67 - 1968937 + 1968925 @@ -13207,22 +13229,22 @@ 1 2 - 7502624 + 7502578 2 3 - 10820578 + 10820511 3 4 - 5972999 + 5972962 4 67 - 1918556 + 1918544 @@ -13290,12 +13312,12 @@ 1 2 - 35074 + 35073 2 3 - 61264 + 61263 3 @@ -13305,12 +13327,12 @@ 4 5 - 45087 + 45086 5 7 - 23932 + 23931 7 @@ -13356,7 +13378,7 @@ 1 2 - 230200 + 230198 2 @@ -13366,7 +13388,7 @@ 3 9 - 10284 + 10283 @@ -13376,11 +13398,11 @@ macro_argument_expanded - 84549437 + 84548918 invocation - 26214757 + 26214596 argument_index @@ -13388,7 +13410,7 @@ text - 192902 + 192900 @@ -13402,22 +13424,22 @@ 1 2 - 7432464 + 7432418 2 3 - 10674027 + 10673962 3 4 - 6139327 + 6139289 4 67 - 1968937 + 1968925 @@ -13433,22 +13455,22 @@ 1 2 - 10688793 + 10688727 2 3 - 9201862 + 9201805 3 4 - 5208277 + 5208245 4 9 - 1115824 + 1115817 @@ -13587,7 +13609,7 @@ 1 2 - 97625 + 97624 2 @@ -13919,15 +13941,15 @@ coroutine - 6 + 0 function - 6 + 0 traits - 3 + 0 @@ -13941,7 +13963,7 @@ 1 2 - 6 + 17 @@ -13953,23 +13975,7 @@ 12 - - - 1 - 2 - 1 - - - 2 - 3 - 1 - - - 3 - 4 - 1 - - + @@ -13977,19 +13983,19 @@ coroutine_placeholder_variable - 18 + 0 placeholder_variable - 18 + 0 kind - 3 + 0 function - 6 + 0 @@ -14003,7 +14009,7 @@ 1 2 - 18 + 17 @@ -14019,7 +14025,7 @@ 1 2 - 18 + 17 @@ -14031,13 +14037,7 @@ 12 - - - 6 - 7 - 3 - - + @@ -14047,13 +14047,7 @@ 12 - - - 6 - 7 - 3 - - + @@ -14063,13 +14057,7 @@ 12 - - - 3 - 4 - 6 - - + @@ -14079,13 +14067,7 @@ 12 - - - 3 - 4 - 6 - - + @@ -14093,15 +14075,15 @@ coroutine_new - 6 + 0 function - 6 + 0 new - 1 + 0 @@ -14115,7 +14097,7 @@ 1 2 - 6 + 17 @@ -14127,13 +14109,7 @@ 12 - - - 6 - 7 - 1 - - + @@ -14141,15 +14117,15 @@ coroutine_delete - 6 + 0 function - 6 + 0 delete - 1 + 0 @@ -14163,7 +14139,7 @@ 1 2 - 6 + 17 @@ -14175,13 +14151,7 @@ 12 - - - 6 - 7 - 1 - - + @@ -15023,19 +14993,19 @@ fun_decl_throws - 7 + 0 fun_decl - 7 + 0 index - 1 + 0 type_id - 2 + 0 @@ -15045,13 +15015,7 @@ 12 - - - 1 - 2 - 7 - - + @@ -15061,13 +15025,7 @@ 12 - - - 1 - 2 - 7 - - + @@ -15077,13 +15035,7 @@ 12 - - - 7 - 8 - 1 - - + @@ -15093,13 +15045,7 @@ 12 - - - 2 - 3 - 1 - - + @@ -15109,18 +15055,7 @@ 12 - - - 1 - 2 - 1 - - - 6 - 7 - 1 - - + @@ -15130,13 +15065,7 @@ 12 - - - 1 - 2 - 2 - - + @@ -16260,11 +16189,11 @@ is_structured_binding - 18 + 0 id - 18 + 0 @@ -17076,7 +17005,7 @@ using_container - 466800 + 466798 parent @@ -17084,7 +17013,7 @@ child - 295990 + 295989 @@ -17154,12 +17083,12 @@ 1 2 - 218313 + 218311 2 3 - 51725 + 51724 3 @@ -18713,11 +18642,11 @@ localvariables - 576945 + 576944 id - 576945 + 576944 type_id @@ -18739,7 +18668,7 @@ 1 2 - 576945 + 576944 @@ -18755,7 +18684,7 @@ 1 2 - 576945 + 576944 @@ -18776,7 +18705,7 @@ 2 3 - 5366 + 5362 3 @@ -18786,7 +18715,7 @@ 4 7 - 3376 + 3380 7 @@ -18812,7 +18741,7 @@ 1 2 - 26912 + 26908 2 @@ -18822,7 +18751,7 @@ 3 5 - 2914 + 2918 5 @@ -21442,15 +21371,15 @@ typedefbase - 1686109 + 1686099 id - 1686109 + 1686099 type_id - 793485 + 793481 @@ -21464,7 +21393,7 @@ 1 2 - 1686109 + 1686099 @@ -21480,12 +21409,12 @@ 1 2 - 617404 + 617400 2 3 - 83254 + 83253 3 @@ -22428,11 +22357,11 @@ is_pod_class - 534713 + 534710 id - 534713 + 534710 @@ -22560,11 +22489,11 @@ class_template_argument - 2882750 + 2882732 type_id - 1315511 + 1315503 index @@ -22572,7 +22501,7 @@ arg_type - 840390 + 840385 @@ -22586,22 +22515,22 @@ 1 2 - 540956 + 540953 2 3 - 399237 + 399235 3 4 - 231396 + 231395 4 7 - 120315 + 120314 7 @@ -22622,17 +22551,17 @@ 1 2 - 567609 + 567605 2 3 - 410481 + 410478 3 4 - 244841 + 244840 4 @@ -22745,17 +22674,17 @@ 1 2 - 523346 + 523343 2 3 - 174343 + 174342 3 4 - 51341 + 51340 4 @@ -22781,7 +22710,7 @@ 1 2 - 746490 + 746486 2 @@ -25019,7 +24948,7 @@ funspecifiers - 10305080 + 10304614 func_id @@ -25046,12 +24975,12 @@ 2 3 - 640536 + 641003 3 4 - 985549 + 985082 4 @@ -25160,8 +25089,8 @@ 466 - 6435 - 6436 + 6434 + 6435 466 @@ -26478,15 +26407,15 @@ attribute_arg_expr - 3 + 0 arg - 3 + 0 expr - 3 + 0 @@ -26500,7 +26429,7 @@ 1 2 - 3 + 17 @@ -26512,13 +26441,7 @@ 12 - - - 1 - 2 - 3 - - + @@ -26526,15 +26449,15 @@ attribute_arg_name - 6 + 0 arg - 6 + 0 name - 5 + 0 @@ -26548,7 +26471,7 @@ 1 2 - 6 + 17 @@ -26560,18 +26483,7 @@ 12 - - - 1 - 2 - 4 - - - 2 - 3 - 1 - - + @@ -27215,11 +27127,11 @@ enclosingfunction - 118328 + 118327 child - 118328 + 118327 parent @@ -27237,7 +27149,7 @@ 1 2 - 118328 + 118327 @@ -27268,7 +27180,7 @@ 4 45 - 4888 + 4887 @@ -28793,15 +28705,15 @@ exprconv - 7032991 + 7032993 converted - 7032991 + 7032993 conversion - 7032991 + 7032993 @@ -28815,7 +28727,7 @@ 1 2 - 7032991 + 7032993 @@ -28831,7 +28743,7 @@ 1 2 - 7032991 + 7032993 @@ -30261,7 +30173,7 @@ fun - 511342 + 511304 @@ -30296,12 +30208,12 @@ 1 2 - 315088 + 315012 2 3 - 77893 + 77931 3 @@ -32081,15 +31993,15 @@ expr_types - 18451442 + 18451396 id - 18319781 + 18319782 typeid - 1214623 + 1214616 value_category @@ -32107,12 +32019,12 @@ 1 2 - 18188121 + 18188167 2 3 - 131660 + 131614 @@ -32128,7 +32040,7 @@ 1 2 - 18319781 + 18319782 @@ -32144,17 +32056,17 @@ 1 2 - 438567 + 438565 2 3 - 249334 + 249332 3 4 - 102840 + 102839 4 @@ -32164,12 +32076,12 @@ 5 8 - 109275 + 109274 8 14 - 96496 + 96495 14 @@ -32179,7 +32091,7 @@ 41 125325 - 44579 + 44578 @@ -32195,7 +32107,7 @@ 1 2 - 1050237 + 1050230 2 @@ -32229,8 +32141,8 @@ 11 - 1239479 - 1239480 + 1239489 + 1239490 11 @@ -32267,11 +32179,11 @@ compound_requirement_is_noexcept - 1 + 0 expr - 1 + 0 @@ -33658,15 +33570,15 @@ code_block - 15 + 0 block - 15 + 0 routine - 15 + 0 @@ -33680,7 +33592,7 @@ 1 2 - 15 + 17 @@ -33696,7 +33608,7 @@ 1 2 - 15 + 17 @@ -34585,19 +34497,19 @@ fold - 4 + 0 expr - 4 + 0 operator - 4 + 0 is_left_fold - 2 + 0 @@ -34607,13 +34519,7 @@ 12 - - - 1 - 2 - 4 - - + @@ -34623,13 +34529,7 @@ 12 - - - 1 - 2 - 4 - - + @@ -34639,13 +34539,7 @@ 12 - - - 1 - 2 - 4 - - + @@ -34655,13 +34549,7 @@ 12 - - - 1 - 2 - 4 - - + @@ -34671,13 +34559,7 @@ 12 - - - 2 - 3 - 2 - - + @@ -34687,13 +34569,7 @@ 12 - - - 2 - 3 - 2 - - + @@ -35017,15 +34893,15 @@ type_vla - 1 + 0 type_id - 1 + 0 decl - 1 + 0 @@ -35035,13 +34911,7 @@ 12 - - - 1 - 2 - 1 - - + @@ -35051,13 +34921,7 @@ 12 - - - 1 - 2 - 1 - - + @@ -35257,15 +35121,15 @@ constexpr_if_initialization - 3 + 0 constexpr_if_stmt - 3 + 0 init_id - 3 + 0 @@ -35279,7 +35143,7 @@ 1 2 - 3 + 17 @@ -35291,13 +35155,7 @@ 12 - - - 1 - 2 - 3 - - + @@ -35497,15 +35355,15 @@ switch_initialization - 8 + 0 switch_stmt - 8 + 0 init_id - 8 + 0 @@ -35519,7 +35377,7 @@ 1 2 - 8 + 17 @@ -35531,13 +35389,7 @@ 12 - - - 1 - 2 - 8 - - + @@ -36318,11 +36170,11 @@ stmt_decl_bind - 580842 + 580841 stmt - 541060 + 541059 num @@ -36330,7 +36182,7 @@ decl - 580738 + 580737 @@ -36589,7 +36441,7 @@ 1 2 - 580738 + 580737 @@ -36599,11 +36451,11 @@ stmt_decl_entry_bind - 580842 + 580841 stmt - 541060 + 541059 num @@ -36611,7 +36463,7 @@ decl_entry - 580784 + 580783 @@ -36849,7 +36701,7 @@ 1 2 - 580763 + 580762 3 @@ -36870,7 +36722,7 @@ 1 2 - 580784 + 580783 From d3e44028ea5aa69b7ece8a2f11fa91e86440f676 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Tue, 19 Nov 2024 14:17:36 +0000 Subject: [PATCH 159/470] C++: Fix upgrade.properties --- .../f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties index 08e1dc42eb2..53cac4c4fec 100644 --- a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties +++ b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties @@ -1,2 +1,3 @@ description: Implement compilation_build_mode/2 compatibility: backwards +compilation_build_mode.rel: delete From 38fa3c10d620bde39a8e555ecdec768fda44d020 Mon Sep 17 00:00:00 2001 From: Calum Grant <42069085+calumgrant@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:30:20 +0000 Subject: [PATCH 160/470] Update cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- .../f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties index 53cac4c4fec..cf362f384da 100644 --- a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties +++ b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties @@ -1,3 +1,3 @@ description: Implement compilation_build_mode/2 -compatibility: backwards +compatibility: full compilation_build_mode.rel: delete From 0836c3d6a51a98a9fac999fe63c434106971c2d7 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Tue, 19 Nov 2024 14:42:23 +0000 Subject: [PATCH 161/470] C++: Update stats --- cpp/ql/lib/semmlecode.cpp.dbscheme.stats | 3321 ++++++++++++---------- 1 file changed, 1766 insertions(+), 1555 deletions(-) diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats index f37e932ca54..758aba34608 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats @@ -18,7 +18,7 @@ @location_default - 29764890 + 29746763 @location_stmt @@ -34,35 +34,35 @@ @file - 123251 + 123176 @folder - 16340 + 16330 @macro_expansion - 33257556 + 33257760 @other_macro_reference - 859029 + 858505 @function - 4179363 + 4176817 @fun_decl - 4543516 + 4541216 @var_decl - 8039391 + 8034962 @type_decl - 3283451 + 3281452 @namespace_decl @@ -70,15 +70,15 @@ @using_declaration - 363219 + 362998 @using_directive - 6536 + 6532 @using_enum_declaration - 0 + 1 @static_assert @@ -86,7 +86,7 @@ @parameter - 6190611 + 6186841 @membervariable @@ -98,7 +98,7 @@ @localvariable - 576944 + 576952 @enumconstant @@ -330,15 +330,15 @@ @pointer - 568173 + 567827 @type_with_specifiers - 852026 + 851507 @array - 110179 + 110112 @routineptr @@ -346,7 +346,7 @@ @reference - 1276405 + 1275627 @gnu_vector @@ -358,23 +358,23 @@ @rvalue_reference - 333340 + 333137 @block - 0 + 10 @decltype - 27078 + 27061 @usertype - 5234008 + 5230820 @mangledname - 6061757 + 6058065 @type_mention @@ -386,15 +386,15 @@ @ptrtomember - 37815 + 37792 @specifier - 24743 + 24728 @gnuattribute - 553700 + 553363 @stdattribute @@ -406,27 +406,27 @@ @msattribute - 0 + 3 @alignas - 4668 + 4665 @attribute_arg_token - 25210 + 25195 @attribute_arg_constant_expr - 318400 + 318207 @attribute_arg_empty - 0 + 1 @attribute_arg_constant - 0 + 1 @attribute_arg_type @@ -434,7 +434,7 @@ @attribute_arg_expr - 0 + 3 @derivation @@ -450,7 +450,7 @@ @namespace - 12138 + 12131 @specialnamequalifyingelement @@ -582,11 +582,11 @@ @gtexpr - 104110 + 104047 @ltexpr - 101776 + 101714 @geexpr @@ -634,7 +634,7 @@ @assignorexpr - 23627 + 23628 @assignxorexpr @@ -662,11 +662,11 @@ @subscriptexpr - 364477 + 364481 @callexpr - 316533 + 316340 @vastartexpr @@ -678,7 +678,7 @@ @vaendexpr - 2801 + 2799 @vacopyexpr @@ -766,39 +766,39 @@ @jmulexpr - 0 + 1 @jdivexpr - 0 + 1 @fjaddexpr - 0 + 1 @jfaddexpr - 0 + 1 @fjsubexpr - 0 + 1 @jfsubexpr - 0 + 1 @minexpr - 0 + 1 @maxexpr - 0 + 1 @virtfunptrexpr - 0 + 1 @thisaccess @@ -830,47 +830,47 @@ @sizeof_pack - 5602 + 5598 @hasassignexpr - 0 + 2 @hascopyexpr - 0 + 2 @hasnothrowassign - 0 + 3 @hasnothrowconstr - 0 + 3 @hasnothrowcopy - 0 + 5 @hastrivialassign - 0 + 2 @hastrivialconstr - 0 + 3 @hastrivialcopy - 0 + 2 @hasuserdestr - 0 + 3 @hasvirtualdestr - 0 + 3 @isabstractexpr @@ -902,15 +902,15 @@ @ispolyexpr - 0 + 3 @isunionexpr - 0 + 5 @intaddrexpr - 0 + 1 @hastrivialdestructor @@ -930,7 +930,7 @@ @foldexpr - 0 + 4 @ctordirectinit @@ -962,7 +962,7 @@ @static_cast - 215647 + 215648 @reinterpret_cast @@ -978,7 +978,7 @@ @lambdaexpr - 21475 + 21462 @param_ref @@ -994,11 +994,11 @@ @isdestructibleexpr - 0 + 4 @isnothrowdestructibleexpr - 0 + 5 @istriviallydestructibleexpr @@ -1006,7 +1006,7 @@ @istriviallyassignableexpr - 0 + 3 @isnothrowassignableexpr @@ -1018,27 +1018,27 @@ @isstandardlayoutexpr - 0 + 2 @istriviallycopyableexpr - 3734 + 3732 @isliteraltypeexpr - 0 + 2 @hastrivialmoveconstructorexpr - 0 + 3 @hastrivialmoveassignexpr - 0 + 3 @hasnothrowmoveassignexpr - 0 + 4 @isconstructibleexpr @@ -1050,35 +1050,35 @@ @hasfinalizerexpr - 0 + 1 @isdelegateexpr - 0 + 1 @isinterfaceclassexpr - 0 + 1 @isrefarrayexpr - 0 + 1 @isrefclassexpr - 0 + 1 @issealedexpr - 0 + 1 @issimplevalueclassexpr - 0 + 1 @isvalueclassexpr - 0 + 1 @isfinalexpr @@ -1090,7 +1090,7 @@ @builtinshufflevector - 0 + 1 @builtinchooseexpr @@ -1102,43 +1102,43 @@ @vec_fill - 0 + 1 @builtinconvertvector - 0 + 1 @builtincomplex - 0 + 4 @spaceshipexpr - 0 + 1 @co_await - 0 + 12 @co_yield - 0 + 4 @isassignable - 0 + 3 @isaggregate - 0 + 2 @hasuniqueobjectrepresentations - 0 + 2 @builtinbitcast - 0 + 1 @builtinshuffle @@ -1150,111 +1150,111 @@ @issame - 0 + 2 @isfunction - 0 + 2 @islayoutcompatible - 0 + 2 @ispointerinterconvertiblebaseof - 0 + 2 @isarray - 0 + 2 @arrayrank - 0 + 2 @arrayextent - 0 + 3 @isarithmetic - 0 + 2 @iscompletetype - 0 + 2 @iscompound - 0 + 2 @isconst - 0 + 2 @isfloatingpoint - 0 + 2 @isfundamental - 0 + 2 @isintegral - 0 + 2 @islvaluereference - 0 + 2 @ismemberfunctionpointer - 0 + 2 @ismemberobjectpointer - 0 + 2 @ismemberpointer - 0 + 3 @isobject - 0 + 2 @ispointer - 0 + 2 @isreference - 0 + 2 @isrvaluereference - 0 + 2 @isscalar - 0 + 2 @issigned - 0 + 2 @isunsigned - 0 + 2 @isvoid - 0 + 2 @isvolatile - 0 + 2 @reuseexpr @@ -1262,119 +1262,119 @@ @istriviallycopyassignable - 0 + 2 @isassignablenopreconditioncheck - 0 + 3 @referencebindstotemporary - 0 + 2 @issameas - 0 + 2 @builtinhasattribute - 0 + 2 @ispointerinterconvertiblewithclass - 0 + 2 @builtinispointerinterconvertiblewithclass - 0 + 2 @iscorrespondingmember - 0 + 2 @builtiniscorrespondingmember - 0 + 2 @isboundedarray - 0 + 2 @isunboundedarray - 0 + 2 @isreferenceable - 0 + 2 @isnothrowconvertible - 0 + 2 @referenceconstructsfromtemporary - 0 + 2 @referenceconvertsfromtemporary - 0 + 2 @isconvertible - 0 + 2 @isvalidwinrttype - 0 + 1 @iswinclass - 0 + 1 @iswininterface - 0 + 1 @istriviallyequalitycomparable - 0 + 2 @isscopedenum - 0 + 2 @istriviallyrelocatable - 0 + 2 @datasizeof - 0 + 10 @c11_generic - 0 + 8 @requires_expr - 0 + 8 @nested_requirement - 0 + 1 @compound_requirement - 0 + 2 @concept_id - 0 + 2 @lambdacapture - 28011 + 27994 @stmt_expr @@ -1398,11 +1398,11 @@ @stmt_return - 1280140 + 1279827 @stmt_block - 1419265 + 1418867 @stmt_end_test_while @@ -1426,11 +1426,11 @@ @stmt_decl - 593118 + 593121 @stmt_empty - 192682 + 192685 @stmt_continue @@ -1462,7 +1462,7 @@ @stmt_range_based_for - 8403 + 8398 @stmt_handler @@ -1474,35 +1474,35 @@ @stmt_co_return - 0 + 5 @ppd_if - 667148 + 666741 @ppd_ifdef - 263311 + 263150 @ppd_ifndef - 266579 + 266416 @ppd_elif - 25210 + 25195 @ppd_else - 209154 + 209027 @ppd_endif - 1197038 + 1196309 @ppd_plain_include - 311398 + 311208 @ppd_define @@ -1510,15 +1510,15 @@ @ppd_undef - 258642 + 258484 @ppd_include_next - 1867 + 1866 @ppd_line - 27520 + 27521 @ppd_error @@ -1530,11 +1530,11 @@ @ppd_objc_import - 0 + 2 @ppd_warning - 0 + 1 @link_target @@ -1902,15 +1902,15 @@ compilation_build_mode - 0 + 9742 id - 0 + 9742 mode - 0 + 11 @@ -1924,7 +1924,7 @@ 1 2 - 17 + 9742 @@ -1936,7 +1936,13 @@ 12 - + + + 863 + 864 + 11 + + @@ -2206,7 +2212,7 @@ seconds - 9468 + 8030 @@ -2284,20 +2290,15 @@ 12 - - 2 - 3 - 39 - 3 4 - 479 + 799 4 5 - 479 + 199 5 @@ -2306,32 +2307,37 @@ 8 + 9 + 79 + + + 9 10 - 159 + 119 10 - 11 + 12 159 - 11 - 17 - 159 + 12 + 16 + 119 17 - 19 + 20 159 - 19 - 44 + 21 + 42 159 - 54 - 100 + 55 + 90 79 @@ -2400,27 +2406,27 @@ 3 4 - 1398 + 1438 4 5 - 359 + 319 5 6 - 159 + 199 6 7 - 519 + 399 7 8 - 79 + 159 8 @@ -2429,12 +2435,12 @@ 9 - 21 + 24 279 - 24 - 86 + 25 + 85 279 @@ -2486,13 +2492,13 @@ 79 - 141 - 142 + 124 + 125 39 - 145 - 146 + 128 + 129 39 @@ -2509,27 +2515,37 @@ 1 2 - 4234 + 3755 2 3 - 2357 + 1398 3 4 - 1797 + 998 4 + 5 + 759 + + + 5 6 - 838 + 439 6 - 48 - 239 + 25 + 639 + + + 46 + 47 + 39 @@ -2545,31 +2561,36 @@ 1 2 - 4274 + 3515 2 3 - 1757 + 1278 3 4 - 1158 + 599 4 5 - 1158 + 878 5 - 7 - 799 + 6 + 759 - 7 - 74 + 6 + 8 + 679 + + + 8 + 76 319 @@ -2586,12 +2607,12 @@ 1 2 - 7271 + 5753 2 3 - 2197 + 2277 @@ -2935,7 +2956,7 @@ cpu_seconds - 7382 + 7292 elapsed_seconds @@ -2985,17 +3006,17 @@ 1 2 - 5881 + 5937 2 3 - 1072 + 846 3 - 12 - 428 + 16 + 507 @@ -3011,12 +3032,12 @@ 1 2 - 6694 + 6682 2 3 - 688 + 609 @@ -3029,10 +3050,20 @@ 12 + + 1 + 2 + 11 + 2 3 - 33 + 11 + + + 3 + 4 + 11 7 @@ -3040,23 +3071,23 @@ 11 - 9 - 10 + 8 + 9 11 - 10 - 11 + 12 + 13 11 - 16 - 17 + 13 + 14 11 - 50 - 51 + 51 + 52 11 @@ -3065,18 +3096,18 @@ 11 - 165 - 166 + 167 + 168 11 - 194 - 195 + 187 + 188 11 - 243 - 244 + 249 + 250 11 @@ -3090,10 +3121,20 @@ 12 + + 1 + 2 + 11 + 2 3 - 33 + 11 + + + 3 + 4 + 11 7 @@ -3101,23 +3142,23 @@ 11 - 9 - 10 + 8 + 9 11 - 10 - 11 + 12 + 13 11 - 16 - 17 + 13 + 14 11 - 48 - 49 + 49 + 50 11 @@ -3126,18 +3167,18 @@ 11 - 137 - 138 + 123 + 124 11 - 146 - 147 + 138 + 139 11 - 216 - 217 + 224 + 225 11 @@ -4910,31 +4951,31 @@ locations_default - 29764890 + 29746763 id - 29764890 + 29746763 container - 123251 + 123176 startLine - 2095283 + 2094007 startColumn - 36882 + 36859 endLine - 2099485 + 2098207 endColumn - 48086 + 48057 @@ -4948,7 +4989,7 @@ 1 2 - 29764890 + 29746763 @@ -4964,7 +5005,7 @@ 1 2 - 29764890 + 29746763 @@ -4980,7 +5021,7 @@ 1 2 - 29764890 + 29746763 @@ -4996,7 +5037,7 @@ 1 2 - 29764890 + 29746763 @@ -5012,7 +5053,7 @@ 1 2 - 29764890 + 29746763 @@ -5028,67 +5069,67 @@ 1 11 - 9804 + 9798 11 18 - 10270 + 10264 18 30 - 9337 + 9331 30 42 - 9804 + 9798 43 61 - 9804 + 9798 61 79 - 9337 + 9331 80 106 - 9804 + 9798 108 149 - 9337 + 9331 149 199 - 9337 + 9331 206 291 - 9337 + 9331 304 469 - 9337 + 9331 482 850 - 9337 + 9331 936 2380 - 8403 + 8398 @@ -5104,67 +5145,67 @@ 1 8 - 9337 + 9331 8 13 - 9337 + 9331 13 20 - 9804 + 9798 20 32 - 9337 + 9331 32 43 - 9804 + 9798 44 61 - 9337 + 9331 62 72 - 9337 + 9331 73 93 - 9337 + 9331 97 128 - 9337 + 9331 128 180 - 9337 + 9331 180 267 - 9337 + 9331 277 414 - 9337 + 9331 439 1465 - 9337 + 9331 1557 @@ -5185,67 +5226,67 @@ 1 4 - 8870 + 8865 4 5 - 7936 + 7931 5 6 - 7469 + 7465 6 8 - 11204 + 11197 8 10 - 9337 + 9331 10 15 - 10737 + 10731 15 23 - 9804 + 9798 23 28 - 11204 + 11197 28 34 - 9804 + 9798 34 44 - 9337 + 9331 44 55 - 9337 + 9331 55 66 - 9804 + 9798 66 77 - 8403 + 8398 @@ -5261,67 +5302,67 @@ 1 8 - 9337 + 9331 8 13 - 9337 + 9331 13 20 - 9804 + 9798 20 32 - 9337 + 9331 32 43 - 9804 + 9798 43 60 - 9337 + 9331 61 71 - 9337 + 9331 72 93 - 9337 + 9331 94 127 - 9337 + 9331 128 179 - 9337 + 9331 180 268 - 9337 + 9331 278 413 - 9337 + 9331 437 1465 - 9337 + 9331 1554 @@ -5342,67 +5383,67 @@ 1 9 - 9804 + 9798 9 13 - 9337 + 9331 13 18 - 9337 + 9331 18 26 - 10270 + 10264 27 33 - 9337 + 9331 33 39 - 9337 + 9331 39 47 - 10270 + 10264 47 53 - 9337 + 9331 53 60 - 10270 + 10264 60 66 - 9337 + 9331 66 74 - 9804 + 9798 74 78 - 9804 + 9798 78 90 - 7002 + 6998 @@ -5418,52 +5459,52 @@ 1 2 - 583112 + 582757 2 3 - 314199 + 314007 3 4 - 195615 + 195496 4 6 - 162001 + 161903 6 10 - 183010 + 182899 10 16 - 162935 + 162836 16 25 - 169004 + 168901 25 46 - 161067 + 160969 46 169 - 157333 + 157237 169 265 - 7002 + 6998 @@ -5479,42 +5520,42 @@ 1 2 - 871167 + 870636 2 3 - 273582 + 273415 3 5 - 193748 + 193630 5 8 - 173673 + 173567 8 13 - 188146 + 188031 13 20 - 161067 + 160969 20 51 - 159667 + 159570 51 265 - 74231 + 74186 @@ -5530,47 +5571,47 @@ 1 2 - 612058 + 611685 2 3 - 313265 + 313074 3 4 - 198417 + 198296 4 6 - 183010 + 182899 6 9 - 173206 + 173100 9 13 - 163402 + 163302 13 19 - 174606 + 174500 19 29 - 164802 + 164702 29 52 - 112514 + 112445 @@ -5586,22 +5627,22 @@ 1 2 - 1531779 + 1530846 2 3 - 348747 + 348534 3 5 - 162001 + 161903 5 16 - 52755 + 52723 @@ -5617,47 +5658,47 @@ 1 2 - 587781 + 587423 2 3 - 316066 + 315874 3 4 - 197483 + 197363 4 6 - 168537 + 168435 6 9 - 158266 + 158170 9 14 - 170872 + 170768 14 21 - 175073 + 174967 21 32 - 162468 + 162369 32 63 - 157799 + 157703 64 @@ -5678,67 +5719,67 @@ 1 31 - 2801 + 2799 42 85 - 2801 + 2799 86 128 - 2801 + 2799 129 229 - 2801 + 2799 247 286 - 2801 + 2799 291 360 - 2801 + 2799 373 457 - 2801 + 2799 473 565 - 2801 + 2799 566 619 - 2801 + 2799 619 689 - 2801 + 2799 696 807 - 2801 + 2799 819 1563 - 2801 + 2799 1634 5631 - 2801 + 2799 15295 @@ -5759,67 +5800,67 @@ 1 18 - 2801 + 2799 23 35 - 3268 + 3266 38 43 - 2801 + 2799 44 61 - 2801 + 2799 65 73 - 2801 + 2799 73 84 - 3268 + 3266 84 96 - 2801 + 2799 96 101 - 3268 + 3266 101 105 - 3268 + 3266 107 112 - 2801 + 2799 112 126 - 2801 + 2799 137 170 - 2801 + 2799 195 265 - 1400 + 1399 @@ -5835,67 +5876,67 @@ 1 19 - 2801 + 2799 30 72 - 2801 + 2799 83 122 - 2801 + 2799 122 205 - 2801 + 2799 214 261 - 2801 + 2799 265 322 - 2801 + 2799 322 379 - 2801 + 2799 404 430 - 2801 + 2799 453 474 - 2801 + 2799 478 505 - 2801 + 2799 511 583 - 2801 + 2799 585 836 - 2801 + 2799 1104 2196 - 2801 + 2799 2387 @@ -5916,67 +5957,67 @@ 1 19 - 2801 + 2799 30 72 - 2801 + 2799 83 122 - 2801 + 2799 122 205 - 2801 + 2799 214 261 - 2801 + 2799 265 322 - 2801 + 2799 322 380 - 2801 + 2799 404 430 - 2801 + 2799 453 474 - 2801 + 2799 477 504 - 2801 + 2799 514 582 - 2801 + 2799 585 835 - 2801 + 2799 1109 2203 - 2801 + 2799 2382 @@ -5997,67 +6038,67 @@ 1 7 - 2801 + 2799 7 11 - 3268 + 3266 11 16 - 3268 + 3266 16 22 - 2801 + 2799 22 24 - 3268 + 3266 24 28 - 2801 + 2799 29 34 - 3268 + 3266 34 41 - 3268 + 3266 41 46 - 2801 + 2799 47 49 - 1867 + 1866 49 54 - 2801 + 2799 54 74 - 2801 + 2799 75 86 - 1867 + 1866 @@ -6073,52 +6114,52 @@ 1 2 - 593383 + 593022 2 3 - 306262 + 306076 3 4 - 198417 + 198296 4 6 - 159667 + 159570 6 10 - 182543 + 182432 10 16 - 162001 + 161903 16 25 - 171338 + 171234 25 46 - 158733 + 158636 46 161 - 158266 + 158170 162 265 - 8870 + 8865 @@ -6134,47 +6175,47 @@ 1 2 - 886574 + 886034 2 3 - 260043 + 259884 3 4 - 125119 + 125043 4 6 - 140992 + 140906 6 10 - 184877 + 184765 10 15 - 168537 + 168435 15 26 - 163402 + 163302 26 120 - 158266 + 158170 121 265 - 11671 + 11664 @@ -6190,22 +6231,22 @@ 1 2 - 1529445 + 1528513 2 3 - 341744 + 341536 3 5 - 170872 + 170768 5 10 - 57424 + 57389 @@ -6221,47 +6262,47 @@ 1 2 - 623262 + 622883 2 3 - 303461 + 303276 3 4 - 201685 + 201562 4 6 - 183944 + 183832 6 9 - 169938 + 169834 9 13 - 166670 + 166568 13 19 - 175073 + 174967 19 29 - 161067 + 160969 29 52 - 114381 + 114311 @@ -6277,52 +6318,52 @@ 1 2 - 599919 + 599554 2 3 - 306262 + 306076 3 4 - 197016 + 196896 4 6 - 169004 + 168901 6 9 - 156399 + 156304 9 14 - 169004 + 168901 14 21 - 177875 + 177766 21 32 - 162001 + 161903 32 60 - 158266 + 158170 60 65 - 3734 + 3732 @@ -6338,67 +6379,67 @@ 1 2 - 5135 + 5132 2 8 - 3734 + 3732 9 186 - 3734 + 3732 193 288 - 3734 + 3732 294 495 - 3734 + 3732 503 555 - 3734 + 3732 561 633 - 3734 + 3732 640 758 - 3734 + 3732 758 869 - 3734 + 3732 875 1074 - 3734 + 3732 1074 1281 - 3734 + 3732 1289 1590 - 3734 + 3732 1685 2418 - 1867 + 1866 @@ -6414,62 +6455,62 @@ 1 2 - 5602 + 5598 2 5 - 3734 + 3732 5 65 - 3734 + 3732 70 100 - 3734 + 3732 100 111 - 3734 + 3732 112 122 - 4201 + 4199 122 140 - 3734 + 3732 143 153 - 3734 + 3732 153 161 - 4201 + 4199 161 173 - 4201 + 4199 173 178 - 3734 + 3732 188 265 - 3734 + 3732 @@ -6485,62 +6526,62 @@ 1 2 - 5602 + 5598 2 8 - 3734 + 3732 9 105 - 3734 + 3732 155 241 - 3734 + 3732 253 336 - 3734 + 3732 340 426 - 3734 + 3732 434 488 - 3734 + 3732 489 572 - 3734 + 3732 573 623 - 3734 + 3732 626 696 - 4201 + 4199 701 813 - 3734 + 3732 818 1095 - 3734 + 3732 1172 @@ -6561,67 +6602,67 @@ 1 2 - 6069 + 6065 2 4 - 3734 + 3732 4 8 - 4201 + 4199 8 15 - 3734 + 3732 15 23 - 3734 + 3732 23 29 - 3734 + 3732 29 35 - 4201 + 4199 35 39 - 3268 + 3266 39 42 - 3268 + 3266 42 44 - 3268 + 3266 44 46 - 3734 + 3732 46 49 - 3734 + 3732 49 53 - 1400 + 1399 @@ -6637,67 +6678,67 @@ 1 2 - 5602 + 5598 2 8 - 3734 + 3732 9 156 - 3734 + 3732 159 240 - 3734 + 3732 251 335 - 3734 + 3732 342 430 - 3734 + 3732 432 490 - 3734 + 3732 490 573 - 3734 + 3732 574 622 - 3734 + 3732 626 698 - 3734 + 3732 700 798 - 3734 + 3732 811 987 - 3734 + 3732 1096 1180 - 1400 + 1399 @@ -10621,23 +10662,23 @@ numlines - 1383783 + 1382941 element_id - 1376780 + 1375942 num_lines - 101776 + 101714 num_code - 84969 + 84917 num_comment - 59758 + 59722 @@ -10651,12 +10692,12 @@ 1 2 - 1369777 + 1368943 2 3 - 7002 + 6998 @@ -10672,12 +10713,12 @@ 1 2 - 1370711 + 1369876 2 3 - 6069 + 6065 @@ -10693,7 +10734,7 @@ 1 2 - 1376780 + 1375942 @@ -10709,27 +10750,27 @@ 1 2 - 68162 + 68120 2 3 - 12138 + 12131 3 4 - 7469 + 7465 4 21 - 7936 + 7931 29 921 - 6069 + 6065 @@ -10745,27 +10786,27 @@ 1 2 - 70496 + 70453 2 3 - 12138 + 12131 3 4 - 8403 + 8398 4 6 - 9337 + 9331 6 7 - 1400 + 1399 @@ -10781,22 +10822,22 @@ 1 2 - 69562 + 69520 2 3 - 14939 + 14930 3 4 - 10737 + 10731 4 7 - 6536 + 6532 @@ -10812,27 +10853,27 @@ 1 2 - 52755 + 52723 2 3 - 14472 + 14463 3 5 - 6536 + 6532 5 42 - 6536 + 6532 44 922 - 4668 + 4665 @@ -10848,27 +10889,27 @@ 1 2 - 52755 + 52723 2 3 - 16807 + 16796 3 5 - 6069 + 6065 5 8 - 6536 + 6532 8 12 - 2801 + 2799 @@ -10884,27 +10925,27 @@ 1 2 - 53222 + 53190 2 3 - 15873 + 15863 3 5 - 7469 + 7465 5 7 - 5135 + 5132 7 10 - 3268 + 3266 @@ -10920,32 +10961,32 @@ 1 2 - 34547 + 34526 2 3 - 9337 + 9331 3 4 - 4201 + 4199 4 6 - 4668 + 4665 6 11 - 5135 + 5132 17 2596 - 1867 + 1866 @@ -10961,32 +11002,32 @@ 1 2 - 34547 + 34526 2 3 - 9337 + 9331 3 4 - 4201 + 4199 4 6 - 4668 + 4665 6 8 - 4668 + 4665 10 38 - 2334 + 2332 @@ -11002,32 +11043,32 @@ 1 2 - 34547 + 34526 2 3 - 9337 + 9331 3 4 - 4201 + 4199 4 6 - 4668 + 4665 6 10 - 4668 + 4665 10 37 - 2334 + 2332 @@ -11669,15 +11710,15 @@ files - 123251 + 123176 id - 123251 + 123176 name - 123251 + 123176 @@ -11691,7 +11732,7 @@ 1 2 - 123251 + 123176 @@ -11707,7 +11748,7 @@ 1 2 - 123251 + 123176 @@ -11717,15 +11758,15 @@ folders - 16340 + 16330 id - 16340 + 16330 name - 16340 + 16330 @@ -11739,7 +11780,7 @@ 1 2 - 16340 + 16330 @@ -11755,7 +11796,7 @@ 1 2 - 16340 + 16330 @@ -11765,15 +11806,15 @@ containerparent - 138658 + 138574 parent - 16340 + 16330 child - 138658 + 138574 @@ -11787,32 +11828,32 @@ 1 2 - 7469 + 7465 2 3 - 3268 + 3266 3 4 - 1400 + 1399 4 12 - 1400 + 1399 23 28 - 1400 + 1399 40 67 - 1400 + 1399 @@ -11828,7 +11869,7 @@ 1 2 - 138658 + 138574 @@ -11838,7 +11879,7 @@ fileannotations - 5129404 + 5129436 id @@ -12680,19 +12721,19 @@ macroinvocations - 33490802 + 33491008 id - 33490802 + 33491008 macro_id - 79483 + 79484 location - 760382 + 760387 kind @@ -12710,7 +12751,7 @@ 1 2 - 33490802 + 33491008 @@ -12726,7 +12767,7 @@ 1 2 - 33490802 + 33491008 @@ -12742,7 +12783,7 @@ 1 2 - 33490802 + 33491008 @@ -12824,7 +12865,7 @@ 1 2 - 42467 + 42468 2 @@ -12870,7 +12911,7 @@ 1 2 - 73748 + 73749 2 @@ -12891,22 +12932,22 @@ 1 2 - 281223 + 281225 2 3 - 169657 + 169658 3 4 - 70734 + 70735 4 5 - 60326 + 60327 5 @@ -12942,7 +12983,7 @@ 1 2 - 714211 + 714216 2 @@ -12963,7 +13004,7 @@ 1 2 - 760382 + 760387 @@ -13036,15 +13077,15 @@ macroparent - 29950538 + 29950722 id - 29950538 + 29950722 parent_id - 23286856 + 23286998 @@ -13058,7 +13099,7 @@ 1 2 - 29950538 + 29950722 @@ -13074,17 +13115,17 @@ 1 2 - 17992681 + 17992792 2 3 - 4459523 + 4459550 3 88 - 834650 + 834655 @@ -13172,11 +13213,11 @@ macro_argument_unexpanded - 84548918 + 84549437 invocation - 26214596 + 26214757 argument_index @@ -13184,7 +13225,7 @@ text - 318306 + 318308 @@ -13198,22 +13239,22 @@ 1 2 - 7432418 + 7432464 2 3 - 10673962 + 10674027 3 4 - 6139289 + 6139327 4 67 - 1968925 + 1968937 @@ -13229,22 +13270,22 @@ 1 2 - 7502578 + 7502624 2 3 - 10820511 + 10820578 3 4 - 5972962 + 5972999 4 67 - 1918544 + 1918556 @@ -13312,12 +13353,12 @@ 1 2 - 35073 + 35074 2 3 - 61263 + 61264 3 @@ -13327,12 +13368,12 @@ 4 5 - 45086 + 45087 5 7 - 23931 + 23932 7 @@ -13378,7 +13419,7 @@ 1 2 - 230198 + 230200 2 @@ -13388,7 +13429,7 @@ 3 9 - 10283 + 10284 @@ -13398,11 +13439,11 @@ macro_argument_expanded - 84548918 + 84549437 invocation - 26214596 + 26214757 argument_index @@ -13410,7 +13451,7 @@ text - 192900 + 192902 @@ -13424,22 +13465,22 @@ 1 2 - 7432418 + 7432464 2 3 - 10673962 + 10674027 3 4 - 6139289 + 6139327 4 67 - 1968925 + 1968937 @@ -13455,22 +13496,22 @@ 1 2 - 10688727 + 10688793 2 3 - 9201805 + 9201862 3 4 - 5208245 + 5208277 4 9 - 1115817 + 1115824 @@ -13609,7 +13650,7 @@ 1 2 - 97624 + 97625 2 @@ -13629,19 +13670,19 @@ functions - 4179363 + 4176817 id - 4179363 + 4176817 name - 1895466 + 1894311 kind - 3268 + 3266 @@ -13655,7 +13696,7 @@ 1 2 - 4179363 + 4176817 @@ -13671,7 +13712,7 @@ 1 2 - 4179363 + 4176817 @@ -13687,22 +13728,22 @@ 1 2 - 1498165 + 1497253 2 3 - 153131 + 153038 3 5 - 142860 + 142773 5 952 - 101309 + 101247 @@ -13718,7 +13759,7 @@ 1 2 - 1894999 + 1893845 2 @@ -13820,15 +13861,15 @@ function_entry_point - 1151752 + 1151517 id - 1141948 + 1141719 entry_point - 1151752 + 1151517 @@ -13842,12 +13883,12 @@ 1 2 - 1132144 + 1131921 2 3 - 9804 + 9798 @@ -13863,7 +13904,7 @@ 1 2 - 1151752 + 1151517 @@ -13873,15 +13914,15 @@ function_return_type - 4184498 + 4181950 id - 4179363 + 4176817 return_type - 817945 + 817446 @@ -13895,12 +13936,12 @@ 1 2 - 4174227 + 4171685 2 3 - 5135 + 5132 @@ -13916,22 +13957,22 @@ 1 2 - 506080 + 505771 2 3 - 211489 + 211360 3 7 - 66294 + 66254 7 2231 - 34081 + 34060 @@ -13941,15 +13982,15 @@ coroutine - 0 + 6 function - 0 + 6 traits - 0 + 3 @@ -13963,7 +14004,7 @@ 1 2 - 17 + 6 @@ -13975,7 +14016,23 @@ 12 - + + + 1 + 2 + 1 + + + 2 + 3 + 1 + + + 3 + 4 + 1 + + @@ -13983,19 +14040,19 @@ coroutine_placeholder_variable - 0 + 18 placeholder_variable - 0 + 18 kind - 0 + 3 function - 0 + 6 @@ -14009,7 +14066,7 @@ 1 2 - 17 + 18 @@ -14025,7 +14082,7 @@ 1 2 - 17 + 18 @@ -14037,7 +14094,13 @@ 12 - + + + 6 + 7 + 3 + + @@ -14047,7 +14110,13 @@ 12 - + + + 6 + 7 + 3 + + @@ -14057,7 +14126,13 @@ 12 - + + + 3 + 4 + 6 + + @@ -14067,7 +14142,13 @@ 12 - + + + 3 + 4 + 6 + + @@ -14075,15 +14156,15 @@ coroutine_new - 0 + 6 function - 0 + 6 new - 0 + 1 @@ -14097,7 +14178,7 @@ 1 2 - 17 + 6 @@ -14109,7 +14190,13 @@ 12 - + + + 6 + 7 + 1 + + @@ -14117,15 +14204,15 @@ coroutine_delete - 0 + 6 function - 0 + 6 delete - 0 + 1 @@ -14139,7 +14226,7 @@ 1 2 - 17 + 6 @@ -14151,7 +14238,13 @@ 12 - + + + 6 + 7 + 1 + + @@ -14170,33 +14263,33 @@ function_deleted - 96173 + 96115 id - 96173 + 96115 function_defaulted - 73764 + 73719 id - 73764 + 73719 function_prototyped - 4087391 + 4084901 id - 4087391 + 4084901 @@ -14349,27 +14442,27 @@ fun_decls - 4548652 + 4546348 id - 4543516 + 4541216 function - 4035569 + 4033111 type_id - 816544 + 816047 name - 1797891 + 1796796 location - 3370755 + 3368702 @@ -14383,7 +14476,7 @@ 1 2 - 4543516 + 4541216 @@ -14399,12 +14492,12 @@ 1 2 - 4538381 + 4536084 2 3 - 5135 + 5132 @@ -14420,7 +14513,7 @@ 1 2 - 4543516 + 4541216 @@ -14436,7 +14529,7 @@ 1 2 - 4543516 + 4541216 @@ -14452,17 +14545,17 @@ 1 2 - 3606521 + 3603858 2 3 - 356216 + 356466 3 7 - 72830 + 72786 @@ -14478,12 +14571,12 @@ 1 2 - 3995885 + 3993452 2 3 - 39683 + 39659 @@ -14499,7 +14592,7 @@ 1 2 - 4035569 + 4033111 @@ -14515,17 +14608,17 @@ 1 2 - 3663012 + 3660781 2 3 - 311864 + 311674 3 6 - 60692 + 60655 @@ -14541,22 +14634,22 @@ 1 2 - 431381 + 431119 2 3 - 274048 + 273882 3 6 - 63493 + 63454 6 - 2476 - 47620 + 2477 + 47591 @@ -14572,22 +14665,22 @@ 1 2 - 515417 + 515103 2 3 - 203085 + 202961 3 7 - 63026 + 62988 7 2192 - 35014 + 34993 @@ -14603,17 +14696,17 @@ 1 2 - 690024 + 689604 2 4 - 67228 + 67187 4 773 - 59291 + 59255 @@ -14629,22 +14722,22 @@ 1 2 - 595251 + 594888 2 3 - 121384 + 121310 3 7 - 63493 + 63454 7 1959 - 36415 + 36393 @@ -14660,27 +14753,27 @@ 1 2 - 1228318 + 1227570 2 3 - 267045 + 266883 3 4 - 77966 + 77918 4 7 - 146128 + 146039 7 986 - 78433 + 78385 @@ -14696,22 +14789,22 @@ 1 2 - 1407593 + 1406736 2 3 - 152197 + 152104 3 5 - 136791 + 136707 5 936 - 101309 + 101247 @@ -14727,17 +14820,17 @@ 1 2 - 1579399 + 1578437 2 4 - 134923 + 134841 4 562 - 83568 + 83517 @@ -14753,27 +14846,27 @@ 1 2 - 1236254 + 1235502 2 3 - 293190 + 293011 3 4 - 78899 + 78851 4 8 - 137257 + 137174 8 542 - 52288 + 52256 @@ -14789,17 +14882,17 @@ 1 2 - 2966451 + 2964644 2 4 - 277783 + 277614 4 55 - 126520 + 126442 @@ -14815,17 +14908,17 @@ 1 2 - 3033679 + 3031832 2 7 - 244169 + 244020 7 55 - 92905 + 92849 @@ -14841,12 +14934,12 @@ 1 2 - 3207353 + 3205399 2 18 - 163402 + 163302 @@ -14862,12 +14955,12 @@ 1 2 - 3232563 + 3230595 2 13 - 138191 + 138107 @@ -14877,22 +14970,22 @@ fun_def - 1888930 + 1888246 id - 1888930 + 1888246 fun_specialized - 26144 + 26128 id - 26144 + 26128 @@ -14910,15 +15003,15 @@ fun_decl_specifiers - 2906692 + 2904922 id - 1689579 + 1688550 name - 2801 + 2799 @@ -14932,17 +15025,17 @@ 1 2 - 491140 + 490841 2 3 - 1179764 + 1179045 3 4 - 18674 + 18663 @@ -14993,19 +15086,19 @@ fun_decl_throws - 0 + 7 fun_decl - 0 + 7 index - 0 + 1 type_id - 0 + 2 @@ -15015,7 +15108,13 @@ 12 - + + + 1 + 2 + 7 + + @@ -15025,7 +15124,13 @@ 12 - + + + 1 + 2 + 7 + + @@ -15035,7 +15140,13 @@ 12 - + + + 7 + 8 + 1 + + @@ -15045,7 +15156,13 @@ 12 - + + + 2 + 3 + 1 + + @@ -15055,7 +15172,18 @@ 12 - + + + 1 + 2 + 1 + + + 6 + 7 + 1 + + @@ -15065,7 +15193,13 @@ 12 - + + + 1 + 2 + 2 + + @@ -15073,11 +15207,11 @@ fun_decl_empty_throws - 1472021 + 1471124 fun_decl - 1472021 + 1471124 @@ -15137,11 +15271,11 @@ fun_decl_empty_noexcept - 863230 + 863171 fun_decl - 863230 + 863171 @@ -15246,19 +15380,19 @@ param_decl_bind - 6995017 + 6991224 id - 6995017 + 6991224 index - 7936 + 7931 fun_decl - 3835284 + 3833415 @@ -15272,7 +15406,7 @@ 1 2 - 6995017 + 6991224 @@ -15288,7 +15422,7 @@ 1 2 - 6995017 + 6991224 @@ -15367,8 +15501,8 @@ 466 - 8215 - 8216 + 8216 + 8217 466 @@ -15448,8 +15582,8 @@ 466 - 8215 - 8216 + 8216 + 8217 466 @@ -15466,27 +15600,27 @@ 1 2 - 1973899 + 1973163 2 3 - 1061647 + 1061001 3 4 - 502812 + 502505 4 8 - 290856 + 290678 8 18 - 6069 + 6065 @@ -15502,27 +15636,27 @@ 1 2 - 1973899 + 1973163 2 3 - 1061647 + 1061001 3 4 - 502812 + 502505 4 8 - 290856 + 290678 8 18 - 6069 + 6065 @@ -15532,27 +15666,27 @@ var_decls - 8110354 + 8105882 id - 8039391 + 8034962 variable - 7027231 + 7022951 type_id - 2043462 + 2042217 name - 667614 + 667208 location - 5311974 + 5308739 @@ -15566,7 +15700,7 @@ 1 2 - 8039391 + 8034962 @@ -15582,12 +15716,12 @@ 1 2 - 7971229 + 7966841 2 3 - 68162 + 68120 @@ -15603,7 +15737,7 @@ 1 2 - 8039391 + 8034962 @@ -15619,12 +15753,12 @@ 1 2 - 8036590 + 8032162 2 3 - 2801 + 2799 @@ -15640,17 +15774,17 @@ 1 2 - 6175205 + 6170977 2 3 - 698427 + 698469 3 7 - 153598 + 153504 @@ -15666,12 +15800,12 @@ 1 2 - 6855892 + 6851717 2 4 - 171338 + 171234 @@ -15687,12 +15821,12 @@ 1 2 - 6911916 + 6907706 2 3 - 115315 + 115245 @@ -15708,17 +15842,17 @@ 1 2 - 6481934 + 6477987 2 3 - 542962 + 542631 3 4 - 2334 + 2332 @@ -15734,27 +15868,27 @@ 1 2 - 1165758 + 1165048 2 3 - 477134 + 476377 3 4 - 94773 + 95182 4 7 - 184877 + 184765 7 762 - 120917 + 120844 @@ -15770,22 +15904,22 @@ 1 2 - 1299281 + 1298490 2 3 - 452390 + 452115 3 6 - 155932 + 155837 6 724 - 135857 + 135774 @@ -15801,17 +15935,17 @@ 1 2 - 1539249 + 1538311 2 3 - 383295 + 383061 3 128 - 120917 + 120844 @@ -15827,22 +15961,22 @@ 1 2 - 1365576 + 1364744 2 3 - 404303 + 404057 3 7 - 173206 + 173100 7 592 - 100375 + 100314 @@ -15858,37 +15992,37 @@ 1 2 - 341277 + 341069 2 3 - 86836 + 86783 3 4 - 48553 + 48524 4 6 - 51821 + 51790 6 12 - 52288 + 52256 12 33 - 50421 + 50390 34 - 2384 - 36415 + 2385 + 36393 @@ -15904,37 +16038,37 @@ 1 2 - 368822 + 368597 2 3 - 77966 + 77918 3 4 - 45285 + 45258 4 6 - 49487 + 49457 6 14 - 53222 + 53190 14 56 - 50888 + 50857 56 2301 - 21942 + 21929 @@ -15950,27 +16084,27 @@ 1 2 - 457059 + 456781 2 3 - 93839 + 93782 3 5 - 46686 + 46657 5 19 - 50888 + 50857 19 1182 - 19141 + 19129 @@ -15986,32 +16120,32 @@ 1 2 - 379093 + 378862 2 3 - 90571 + 90516 3 5 - 59758 + 59722 5 9 - 51354 + 51323 9 21 - 50421 + 50390 21 1010 - 36415 + 36393 @@ -16027,17 +16161,17 @@ 1 2 - 4496363 + 4493625 2 3 - 531757 + 531433 3 - 896 - 283853 + 897 + 283680 @@ -16053,17 +16187,17 @@ 1 2 - 4885727 + 4882752 2 17 - 415508 + 415255 17 892 - 10737 + 10731 @@ -16079,12 +16213,12 @@ 1 2 - 4961826 + 4958804 2 759 - 350147 + 349934 @@ -16100,12 +16234,12 @@ 1 2 - 5302637 + 5299407 2 6 - 9337 + 9331 @@ -16115,26 +16249,26 @@ var_def - 3994952 + 3992985 id - 3994952 + 3992985 var_decl_specifiers - 378626 + 378395 id - 378626 + 378395 name - 1867 + 1866 @@ -16148,7 +16282,7 @@ 1 2 - 378626 + 378395 @@ -16189,30 +16323,30 @@ is_structured_binding - 0 + 18 id - 0 + 18 type_decls - 3283451 + 3281452 id - 3283451 + 3281452 type_id - 3233030 + 3231061 location - 3166269 + 3164340 @@ -16226,7 +16360,7 @@ 1 2 - 3283451 + 3281452 @@ -16242,7 +16376,7 @@ 1 2 - 3283451 + 3281452 @@ -16258,12 +16392,12 @@ 1 2 - 3191479 + 3189536 2 5 - 41550 + 41525 @@ -16279,12 +16413,12 @@ 1 2 - 3191479 + 3189536 2 5 - 41550 + 41525 @@ -16300,12 +16434,12 @@ 1 2 - 3113980 + 3112083 2 20 - 52288 + 52256 @@ -16321,12 +16455,12 @@ 1 2 - 3113980 + 3112083 2 20 - 52288 + 52256 @@ -16336,22 +16470,22 @@ type_def - 2641981 + 2640372 id - 2641981 + 2640372 type_decl_top - 743713 + 743260 type_decl - 743713 + 743260 @@ -16724,19 +16858,19 @@ usings - 369755 + 369530 id - 369755 + 369530 element_id - 315599 + 315407 location - 247904 + 247753 kind @@ -16754,7 +16888,7 @@ 1 2 - 369755 + 369530 @@ -16770,7 +16904,7 @@ 1 2 - 369755 + 369530 @@ -16786,7 +16920,7 @@ 1 2 - 369755 + 369530 @@ -16802,17 +16936,17 @@ 1 2 - 263311 + 263150 2 3 - 50888 + 50857 3 5 - 1400 + 1399 @@ -16828,17 +16962,17 @@ 1 2 - 263311 + 263150 2 3 - 50888 + 50857 3 5 - 1400 + 1399 @@ -16854,7 +16988,7 @@ 1 2 - 315599 + 315407 @@ -16870,22 +17004,22 @@ 1 2 - 202618 + 202495 2 4 - 10737 + 10731 4 5 - 31279 + 31260 5 11 - 3268 + 3266 @@ -16901,22 +17035,22 @@ 1 2 - 202618 + 202495 2 4 - 10737 + 10731 4 5 - 31279 + 31260 5 11 - 3268 + 3266 @@ -16932,7 +17066,7 @@ 1 2 - 247904 + 247753 @@ -17005,7 +17139,7 @@ using_container - 466798 + 466800 parent @@ -17013,7 +17147,7 @@ child - 295989 + 295990 @@ -17083,12 +17217,12 @@ 1 2 - 218311 + 218313 2 3 - 51724 + 51725 3 @@ -17716,23 +17850,23 @@ params - 6354480 + 6350610 id - 6190611 + 6186841 function - 3491673 + 3489546 index - 7936 + 7931 type_id - 1846445 + 1845321 @@ -17746,7 +17880,7 @@ 1 2 - 6190611 + 6186841 @@ -17762,7 +17896,7 @@ 1 2 - 6190611 + 6186841 @@ -17778,12 +17912,12 @@ 1 2 - 6066892 + 6063198 2 4 - 123718 + 123643 @@ -17799,22 +17933,22 @@ 1 2 - 1867454 + 1866317 2 3 - 952868 + 952288 3 4 - 429981 + 429719 4 18 - 241368 + 241221 @@ -17830,22 +17964,22 @@ 1 2 - 1867454 + 1866317 2 3 - 952868 + 952288 3 4 - 429981 + 429719 4 18 - 241368 + 241221 @@ -17861,22 +17995,22 @@ 1 2 - 2165780 + 2164461 2 3 - 826815 + 826311 3 4 - 346412 + 346201 4 12 - 152664 + 152571 @@ -18074,7 +18208,7 @@ 6 7 - 1400 + 1399 7 @@ -18130,22 +18264,22 @@ 1 2 - 1183966 + 1183245 2 3 - 406171 + 405923 3 7 - 154064 + 153971 7 518 - 102243 + 102180 @@ -18161,22 +18295,22 @@ 1 2 - 1404792 + 1403937 2 3 - 212422 + 212293 3 7 - 147528 + 147439 7 502 - 81701 + 81651 @@ -18192,17 +18326,17 @@ 1 2 - 1420199 + 1419334 2 3 - 347346 + 347135 3 13 - 78899 + 78851 @@ -18212,11 +18346,11 @@ overrides - 125725 + 125735 new - 122752 + 122762 old @@ -18234,7 +18368,7 @@ 1 2 - 119788 + 119797 2 @@ -18642,11 +18776,11 @@ localvariables - 576944 + 576952 id - 576944 + 576952 type_id @@ -18654,7 +18788,7 @@ name - 90547 + 90549 @@ -18668,7 +18802,7 @@ 1 2 - 576944 + 576952 @@ -18684,7 +18818,7 @@ 1 2 - 576944 + 576952 @@ -18705,7 +18839,7 @@ 2 3 - 5362 + 5366 3 @@ -18715,7 +18849,7 @@ 4 7 - 3380 + 3376 7 @@ -18741,7 +18875,7 @@ 1 2 - 26908 + 26913 2 @@ -18751,7 +18885,7 @@ 3 5 - 2918 + 2914 5 @@ -18777,12 +18911,12 @@ 1 2 - 57031 + 57032 2 3 - 14284 + 14285 3 @@ -18813,7 +18947,7 @@ 1 2 - 76491 + 76492 2 @@ -18823,7 +18957,7 @@ 3 1486 - 6644 + 6645 @@ -19851,31 +19985,31 @@ builtintypes - 26144 + 26128 id - 26144 + 26128 name - 26144 + 26128 kind - 26144 + 26128 size - 3268 + 3266 sign - 1400 + 1399 alignment - 2334 + 2332 @@ -19889,7 +20023,7 @@ 1 2 - 26144 + 26128 @@ -19905,7 +20039,7 @@ 1 2 - 26144 + 26128 @@ -19921,7 +20055,7 @@ 1 2 - 26144 + 26128 @@ -19937,7 +20071,7 @@ 1 2 - 26144 + 26128 @@ -19953,7 +20087,7 @@ 1 2 - 26144 + 26128 @@ -19969,7 +20103,7 @@ 1 2 - 26144 + 26128 @@ -19985,7 +20119,7 @@ 1 2 - 26144 + 26128 @@ -20001,7 +20135,7 @@ 1 2 - 26144 + 26128 @@ -20017,7 +20151,7 @@ 1 2 - 26144 + 26128 @@ -20033,7 +20167,7 @@ 1 2 - 26144 + 26128 @@ -20049,7 +20183,7 @@ 1 2 - 26144 + 26128 @@ -20065,7 +20199,7 @@ 1 2 - 26144 + 26128 @@ -20081,7 +20215,7 @@ 1 2 - 26144 + 26128 @@ -20097,7 +20231,7 @@ 1 2 - 26144 + 26128 @@ -20113,7 +20247,7 @@ 1 2 - 26144 + 26128 @@ -20272,7 +20406,7 @@ 3 4 - 2334 + 2332 @@ -20288,12 +20422,12 @@ 1 2 - 1867 + 1866 2 3 - 1400 + 1399 @@ -20408,7 +20542,7 @@ 5 6 - 1400 + 1399 @@ -20532,7 +20666,7 @@ 2 3 - 2334 + 2332 @@ -20548,7 +20682,7 @@ 3 4 - 2334 + 2332 @@ -20558,23 +20692,23 @@ derivedtypes - 3669548 + 3667313 id - 3669548 + 3667313 name - 1552788 + 1551842 kind - 2801 + 2799 type_id - 2362796 + 2361357 @@ -20588,7 +20722,7 @@ 1 2 - 3669548 + 3667313 @@ -20604,7 +20738,7 @@ 1 2 - 3669548 + 3667313 @@ -20620,7 +20754,7 @@ 1 2 - 3669548 + 3667313 @@ -20636,17 +20770,17 @@ 1 2 - 1324025 + 1323218 2 4 - 120450 + 120377 4 1153 - 108312 + 108246 @@ -20662,7 +20796,7 @@ 1 2 - 1551854 + 1550909 2 @@ -20683,17 +20817,17 @@ 1 2 - 1324025 + 1323218 2 4 - 120450 + 120377 4 1135 - 108312 + 108246 @@ -20832,22 +20966,22 @@ 1 2 - 1515439 + 1514516 2 3 - 546230 + 545897 3 4 - 218492 + 218359 4 72 - 82634 + 82584 @@ -20863,22 +20997,22 @@ 1 2 - 1526644 + 1525714 2 3 - 538760 + 538432 3 4 - 215690 + 215559 4 72 - 81701 + 81651 @@ -20894,22 +21028,22 @@ 1 2 - 1519641 + 1518715 2 3 - 549965 + 549630 3 4 - 217558 + 217425 4 6 - 75631 + 75585 @@ -20919,11 +21053,11 @@ pointerishsize - 2707342 + 2705693 id - 2707342 + 2705693 size @@ -20945,7 +21079,7 @@ 1 2 - 2707342 + 2705693 @@ -20961,7 +21095,7 @@ 1 2 - 2707342 + 2705693 @@ -21035,23 +21169,23 @@ arraysizes - 88237 + 88183 id - 88237 + 88183 num_elements - 31746 + 31727 bytesize - 33147 + 33127 alignment - 1867 + 1866 @@ -21065,7 +21199,7 @@ 1 2 - 88237 + 88183 @@ -21081,7 +21215,7 @@ 1 2 - 88237 + 88183 @@ -21097,7 +21231,7 @@ 1 2 - 88237 + 88183 @@ -21113,22 +21247,22 @@ 1 2 - 1867 + 1866 2 3 - 23810 + 23795 3 5 - 2801 + 2799 5 13 - 2801 + 2799 13 @@ -21149,17 +21283,17 @@ 1 2 - 26611 + 26595 2 3 - 2334 + 2332 3 7 - 2801 + 2799 @@ -21175,17 +21309,17 @@ 1 2 - 26611 + 26595 2 3 - 2801 + 2799 3 5 - 2334 + 2332 @@ -21201,27 +21335,27 @@ 1 2 - 1867 + 1866 2 3 - 23810 + 23795 3 4 - 3268 + 3266 4 6 - 2334 + 2332 7 16 - 1867 + 1866 @@ -21237,17 +21371,17 @@ 1 2 - 27544 + 27528 2 3 - 3734 + 3732 3 5 - 1867 + 1866 @@ -21263,12 +21397,12 @@ 1 2 - 27544 + 27528 2 3 - 4668 + 4665 4 @@ -21371,15 +21505,15 @@ typedefbase - 1686099 + 1686109 id - 1686099 + 1686109 type_id - 793481 + 793485 @@ -21393,7 +21527,7 @@ 1 2 - 1686099 + 1686109 @@ -21409,12 +21543,12 @@ 1 2 - 617400 + 617404 2 3 - 83253 + 83254 3 @@ -21720,19 +21854,19 @@ usertypes - 5234008 + 5230820 id - 5234008 + 5230820 name - 1352503 + 1351680 kind - 5135 + 5132 @@ -21746,7 +21880,7 @@ 1 2 - 5234008 + 5230820 @@ -21762,7 +21896,7 @@ 1 2 - 5234008 + 5230820 @@ -21778,27 +21912,27 @@ 1 2 - 983681 + 983082 2 3 - 153598 + 153504 3 7 - 104577 + 104513 7 61 - 101776 + 101714 65 874 - 8870 + 8865 @@ -21814,17 +21948,17 @@ 1 2 - 1211977 + 1211239 2 3 - 125586 + 125509 3 7 - 14939 + 14930 @@ -21966,19 +22100,19 @@ usertypesize - 1706386 + 1705347 id - 1706386 + 1705347 size - 13539 + 13530 alignment - 2334 + 2332 @@ -21992,7 +22126,7 @@ 1 2 - 1706386 + 1705347 @@ -22008,7 +22142,7 @@ 1 2 - 1706386 + 1705347 @@ -22024,12 +22158,12 @@ 1 2 - 3268 + 3266 2 3 - 4201 + 4199 3 @@ -22080,12 +22214,12 @@ 1 2 - 10270 + 10264 2 3 - 2801 + 2799 3 @@ -22236,15 +22370,15 @@ mangled_name - 9019338 + 9013845 id - 9019338 + 9013845 mangled_name - 6061757 + 6058065 is_complete @@ -22262,7 +22396,7 @@ 1 2 - 9019338 + 9013845 @@ -22278,7 +22412,7 @@ 1 2 - 9019338 + 9013845 @@ -22294,12 +22428,12 @@ 1 2 - 5789108 + 5785583 2 874 - 272648 + 272482 @@ -22315,7 +22449,7 @@ 1 2 - 6061757 + 6058065 @@ -22357,59 +22491,59 @@ is_pod_class - 534710 + 534713 id - 534710 + 534713 is_standard_layout_class - 1253995 + 1253232 id - 1253995 + 1253232 is_complete - 1645694 + 1644692 id - 1645694 + 1644692 is_class_template - 398234 + 397992 id - 398234 + 397992 class_instantiation - 1089659 + 1088996 to - 1089659 + 1088996 from - 168537 + 168435 @@ -22423,7 +22557,7 @@ 1 2 - 1089659 + 1088996 @@ -22439,47 +22573,47 @@ 1 2 - 59758 + 59722 2 3 - 29412 + 29394 3 4 - 15873 + 15863 4 5 - 13072 + 13064 5 6 - 9804 + 9798 6 10 - 12605 + 12597 10 16 - 13072 + 13064 16 70 - 13539 + 13530 70 84 - 1400 + 1399 @@ -22489,11 +22623,11 @@ class_template_argument - 2882732 + 2882750 type_id - 1315503 + 1315511 index @@ -22501,7 +22635,7 @@ arg_type - 840385 + 840390 @@ -22515,22 +22649,22 @@ 1 2 - 540953 + 540956 2 3 - 399235 + 399237 3 4 - 231395 + 231396 4 7 - 120314 + 120315 7 @@ -22551,17 +22685,17 @@ 1 2 - 567605 + 567609 2 3 - 410478 + 410481 3 4 - 244840 + 244841 4 @@ -22674,17 +22808,17 @@ 1 2 - 523343 + 523346 2 3 - 174342 + 174343 3 4 - 51340 + 51341 4 @@ -22710,7 +22844,7 @@ 1 2 - 746486 + 746490 2 @@ -22730,19 +22864,19 @@ class_template_argument_value - 495342 + 495040 type_id - 304861 + 304676 index - 1867 + 1866 arg_value - 495342 + 495040 @@ -22756,17 +22890,17 @@ 1 2 - 249772 + 249619 2 3 - 53222 + 53190 3 4 - 1867 + 1866 @@ -22782,22 +22916,22 @@ 1 2 - 189546 + 189431 2 3 - 81234 + 81184 3 4 - 12138 + 12131 4 9 - 21942 + 21929 @@ -22875,7 +23009,7 @@ 1 2 - 495342 + 495040 @@ -22891,7 +23025,7 @@ 1 2 - 495342 + 495040 @@ -22901,15 +23035,15 @@ is_proxy_class_for - 62092 + 62055 id - 62092 + 62055 templ_param_id - 62092 + 62055 @@ -22923,7 +23057,7 @@ 1 2 - 62092 + 62055 @@ -22939,7 +23073,7 @@ 1 2 - 62092 + 62055 @@ -23245,11 +23379,11 @@ is_function_template - 1402925 + 1402070 id - 1402925 + 1402070 @@ -24380,19 +24514,19 @@ routinetypeargs - 983214 + 982616 routine - 423445 + 423187 index - 7936 + 7931 type_id - 226895 + 226757 @@ -24406,27 +24540,27 @@ 1 2 - 152664 + 152571 2 3 - 133989 + 133908 3 4 - 63493 + 63454 4 5 - 45752 + 45724 5 18 - 27544 + 27528 @@ -24442,27 +24576,27 @@ 1 2 - 182543 + 182432 2 3 - 133522 + 133441 3 4 - 58824 + 58788 4 5 - 33614 + 33593 5 11 - 14939 + 14930 @@ -24503,7 +24637,7 @@ 10 11 - 1400 + 1399 13 @@ -24564,7 +24698,7 @@ 4 5 - 1400 + 1399 5 @@ -24620,27 +24754,27 @@ 1 2 - 146595 + 146505 2 3 - 30812 + 30794 3 5 - 16807 + 16796 5 12 - 18207 + 18196 12 110 - 14472 + 14463 @@ -24656,22 +24790,22 @@ 1 2 - 172739 + 172634 2 3 - 30812 + 30794 3 6 - 18674 + 18663 6 14 - 4668 + 4665 @@ -24681,19 +24815,19 @@ ptrtomembers - 37815 + 37792 id - 37815 + 37792 type_id - 37815 + 37792 class_id - 15406 + 15397 @@ -24707,7 +24841,7 @@ 1 2 - 37815 + 37792 @@ -24723,7 +24857,7 @@ 1 2 - 37815 + 37792 @@ -24739,7 +24873,7 @@ 1 2 - 37815 + 37792 @@ -24755,7 +24889,7 @@ 1 2 - 37815 + 37792 @@ -24771,12 +24905,12 @@ 1 2 - 13539 + 13530 8 9 - 1400 + 1399 28 @@ -24797,12 +24931,12 @@ 1 2 - 13539 + 13530 8 9 - 1400 + 1399 28 @@ -24817,15 +24951,15 @@ specifiers - 24743 + 24728 id - 24743 + 24728 str - 24743 + 24728 @@ -24839,7 +24973,7 @@ 1 2 - 24743 + 24728 @@ -24855,7 +24989,7 @@ 1 2 - 24743 + 24728 @@ -24865,15 +24999,15 @@ typespecifiers - 1132144 + 1131454 type_id - 1113936 + 1113258 spec_id - 3734 + 3732 @@ -24887,12 +25021,12 @@ 1 2 - 1095728 + 1095061 2 3 - 18207 + 18196 @@ -24948,15 +25082,15 @@ funspecifiers - 10304614 + 10298338 func_id - 4068249 + 4065772 spec_id - 8403 + 8398 @@ -24970,27 +25104,27 @@ 1 2 - 1357639 + 1356812 2 3 - 641003 + 640613 3 4 - 985082 + 984482 4 5 - 780129 + 779654 5 8 - 304395 + 304209 @@ -25101,15 +25235,15 @@ varspecifiers - 2246080 + 2244713 var_id - 1225050 + 1224304 spec_id - 3734 + 3732 @@ -25123,22 +25257,22 @@ 1 2 - 730174 + 729730 2 3 - 202618 + 202495 3 4 - 58357 + 58322 4 5 - 233898 + 233756 @@ -25247,19 +25381,19 @@ attributes - 561636 + 561294 id - 561636 + 561294 kind - 1400 + 1399 name - 11204 + 11197 name_space @@ -25267,7 +25401,7 @@ location - 481336 + 481043 @@ -25281,7 +25415,7 @@ 1 2 - 561636 + 561294 @@ -25297,7 +25431,7 @@ 1 2 - 561636 + 561294 @@ -25313,7 +25447,7 @@ 1 2 - 561636 + 561294 @@ -25329,7 +25463,7 @@ 1 2 - 561636 + 561294 @@ -25520,7 +25654,7 @@ 1 2 - 10270 + 10264 2 @@ -25541,7 +25675,7 @@ 1 2 - 11204 + 11197 @@ -25712,17 +25846,17 @@ 1 2 - 431848 + 431585 2 3 - 20075 + 20062 3 7 - 29412 + 29394 @@ -25738,7 +25872,7 @@ 1 2 - 481336 + 481043 @@ -25754,17 +25888,17 @@ 1 2 - 433249 + 432985 2 3 - 19608 + 19596 3 4 - 28478 + 28461 @@ -25780,7 +25914,7 @@ 1 2 - 481336 + 481043 @@ -25790,27 +25924,27 @@ attribute_args - 344078 + 343868 id - 344078 + 343868 kind - 1400 + 1399 attribute - 262844 + 262684 index - 1400 + 1399 location - 327738 + 327538 @@ -25824,7 +25958,7 @@ 1 2 - 344078 + 343868 @@ -25840,7 +25974,7 @@ 1 2 - 344078 + 343868 @@ -25856,7 +25990,7 @@ 1 2 - 344078 + 343868 @@ -25872,7 +26006,7 @@ 1 2 - 344078 + 343868 @@ -25987,17 +26121,17 @@ 1 2 - 197483 + 197363 2 3 - 49487 + 49457 3 4 - 15873 + 15863 @@ -26013,12 +26147,12 @@ 1 2 - 252573 + 252419 2 3 - 10270 + 10264 @@ -26034,17 +26168,17 @@ 1 2 - 197483 + 197363 2 3 - 49487 + 49457 3 4 - 15873 + 15863 @@ -26060,17 +26194,17 @@ 1 2 - 197483 + 197363 2 3 - 49487 + 49457 3 4 - 15873 + 15863 @@ -26185,12 +26319,12 @@ 1 2 - 313732 + 313541 2 7 - 14005 + 13997 @@ -26206,12 +26340,12 @@ 1 2 - 315132 + 314941 2 3 - 12605 + 12597 @@ -26227,12 +26361,12 @@ 1 2 - 313732 + 313541 2 7 - 14005 + 13997 @@ -26248,7 +26382,7 @@ 1 2 - 327738 + 327538 @@ -26258,15 +26392,15 @@ attribute_arg_value - 25210 + 25195 arg - 25210 + 25195 value - 15873 + 15863 @@ -26280,7 +26414,7 @@ 1 2 - 25210 + 25195 @@ -26296,12 +26430,12 @@ 1 2 - 14472 + 14463 2 16 - 1400 + 1399 @@ -26359,15 +26493,15 @@ attribute_arg_constant - 318400 + 318207 arg - 318400 + 318207 constant - 318400 + 318207 @@ -26381,7 +26515,7 @@ 1 2 - 318400 + 318207 @@ -26397,7 +26531,7 @@ 1 2 - 318400 + 318207 @@ -26407,15 +26541,15 @@ attribute_arg_expr - 0 + 3 arg - 0 + 3 expr - 0 + 3 @@ -26429,7 +26563,7 @@ 1 2 - 17 + 3 @@ -26441,7 +26575,13 @@ 12 - + + + 1 + 2 + 3 + + @@ -26449,15 +26589,15 @@ attribute_arg_name - 0 + 6 arg - 0 + 6 name - 0 + 5 @@ -26471,7 +26611,7 @@ 1 2 - 17 + 6 @@ -26483,7 +26623,18 @@ 12 - + + + 1 + 2 + 4 + + + 2 + 3 + 1 + + @@ -26559,15 +26710,15 @@ funcattributes - 630265 + 629882 func_id - 443520 + 443250 spec_id - 524754 + 524435 @@ -26581,17 +26732,17 @@ 1 2 - 338476 + 338269 2 3 - 64427 + 64387 3 6 - 39683 + 39659 6 @@ -26612,12 +26763,12 @@ 1 2 - 506080 + 505771 2 17 - 18674 + 18663 @@ -26753,15 +26904,15 @@ unspecifiedtype - 9488069 + 9482291 type_id - 9488069 + 9482291 unspecified_type_id - 6490338 + 6486385 @@ -26775,7 +26926,7 @@ 1 2 - 9488069 + 9482291 @@ -26791,17 +26942,17 @@ 1 2 - 4558923 + 4556146 2 3 - 1715723 + 1714678 3 145 - 215690 + 215559 @@ -26811,19 +26962,19 @@ member - 3881037 + 3878673 parent - 545763 + 545431 index - 92905 + 92849 child - 3809607 + 3807287 @@ -26837,47 +26988,47 @@ 1 2 - 129788 + 129709 2 3 - 64894 + 64854 3 4 - 73297 + 73252 4 5 - 75165 + 75119 5 6 - 40617 + 40592 6 8 - 46686 + 46657 8 14 - 45752 + 45724 14 30 - 41550 + 41525 30 200 - 28011 + 27994 @@ -26893,52 +27044,52 @@ 1 2 - 129788 + 129709 2 3 - 64894 + 64854 3 4 - 73297 + 73252 4 5 - 76098 + 76052 5 6 - 39683 + 39659 6 7 - 24276 + 24262 7 9 - 42017 + 41992 9 17 - 43885 + 43858 17 41 - 41550 + 41525 41 200 - 10270 + 10264 @@ -26954,62 +27105,62 @@ 1 2 - 26144 + 26128 2 3 - 7002 + 6998 3 4 - 3734 + 3732 4 5 - 7936 + 7931 5 6 - 5602 + 5598 6 7 - 5602 + 5598 7 9 - 7469 + 7465 9 16 - 7002 + 6998 16 52 - 7002 + 6998 52 107 - 7002 + 6998 108 577 - 7002 + 6998 737 1162 - 1400 + 1399 @@ -27025,62 +27176,62 @@ 1 2 - 26144 + 26128 2 3 - 7002 + 6998 3 4 - 3734 + 3732 4 5 - 7936 + 7931 5 6 - 5602 + 5598 6 7 - 5602 + 5598 7 9 - 7469 + 7465 9 16 - 7002 + 6998 16 52 - 7002 + 6998 52 107 - 7002 + 6998 108 577 - 7002 + 6998 738 1163 - 1400 + 1399 @@ -27096,7 +27247,7 @@ 1 2 - 3809607 + 3807287 @@ -27112,12 +27263,12 @@ 1 2 - 3738177 + 3735900 2 3 - 71430 + 71386 @@ -27127,11 +27278,11 @@ enclosingfunction - 118327 + 118328 child - 118327 + 118328 parent @@ -27149,7 +27300,7 @@ 1 2 - 118327 + 118328 @@ -27180,7 +27331,7 @@ 4 45 - 4887 + 4888 @@ -28647,15 +28798,15 @@ commentbinding - 3091104 + 3089221 id - 2445431 + 2443942 element - 3014538 + 3012702 @@ -28669,12 +28820,12 @@ 1 2 - 2368399 + 2366956 2 97 - 77032 + 76985 @@ -28690,12 +28841,12 @@ 1 2 - 2937972 + 2936183 2 3 - 76565 + 76519 @@ -29100,15 +29251,15 @@ namespaces - 12138 + 12131 id - 12138 + 12131 name - 9804 + 9798 @@ -29122,7 +29273,7 @@ 1 2 - 12138 + 12131 @@ -29138,7 +29289,7 @@ 1 2 - 8403 + 8398 2 @@ -29158,26 +29309,26 @@ namespace_inline - 1400 + 1399 id - 1400 + 1399 namespacembrs - 2388007 + 2386553 parentid - 10270 + 10264 memberid - 2388007 + 2386553 @@ -29191,7 +29342,7 @@ 1 2 - 1867 + 1866 2 @@ -29252,7 +29403,7 @@ 1 2 - 2388007 + 2386553 @@ -29748,7 +29899,7 @@ qualifyingelement - 97518 + 97537 location @@ -29862,7 +30013,7 @@ 1 2 - 58401 + 58420 2 @@ -29898,7 +30049,7 @@ 1 2 - 58401 + 58420 2 @@ -29934,7 +30085,7 @@ 1 2 - 63815 + 63834 2 @@ -30047,12 +30198,12 @@ 1 2 - 137073 + 137054 2 3 - 55684 + 55703 3 @@ -30173,7 +30324,7 @@ fun - 511304 + 511342 @@ -30208,12 +30359,12 @@ 1 2 - 315012 + 315088 2 3 - 77931 + 77893 3 @@ -31993,15 +32144,15 @@ expr_types - 18451396 + 18451397 id - 18319782 + 18319781 typeid - 1214616 + 1214623 value_category @@ -32019,12 +32170,12 @@ 1 2 - 18188167 + 18188166 2 3 - 131614 + 131615 @@ -32040,7 +32191,7 @@ 1 2 - 18319782 + 18319781 @@ -32056,42 +32207,42 @@ 1 2 - 438565 + 438567 2 3 - 249332 + 249345 3 4 - 102839 + 102817 4 5 - 81865 + 81877 5 8 - 109274 + 109275 8 14 - 96495 + 96496 14 41 - 91664 + 91653 41 125325 - 44578 + 44590 @@ -32107,7 +32258,7 @@ 1 2 - 1050230 + 1050237 2 @@ -32141,8 +32292,8 @@ 11 - 1239489 - 1239490 + 1239479 + 1239480 11 @@ -32179,11 +32330,11 @@ compound_requirement_is_noexcept - 0 + 1 expr - 0 + 1 @@ -33570,15 +33721,15 @@ code_block - 0 + 15 block - 0 + 15 routine - 0 + 15 @@ -33592,7 +33743,7 @@ 1 2 - 17 + 15 @@ -33608,7 +33759,7 @@ 1 2 - 17 + 15 @@ -33618,11 +33769,11 @@ lambdas - 21475 + 21462 expr - 21475 + 21462 default_capture @@ -33644,7 +33795,7 @@ 1 2 - 21475 + 21462 @@ -33660,7 +33811,7 @@ 1 2 - 21475 + 21462 @@ -33734,15 +33885,15 @@ lambda_capture - 28011 + 27994 id - 28011 + 27994 lambda - 20541 + 20529 index @@ -33750,7 +33901,7 @@ field - 28011 + 27994 captured_by_reference @@ -33762,7 +33913,7 @@ location - 2801 + 2799 @@ -33776,7 +33927,7 @@ 1 2 - 28011 + 27994 @@ -33792,7 +33943,7 @@ 1 2 - 28011 + 27994 @@ -33808,7 +33959,7 @@ 1 2 - 28011 + 27994 @@ -33824,7 +33975,7 @@ 1 2 - 28011 + 27994 @@ -33840,7 +33991,7 @@ 1 2 - 28011 + 27994 @@ -33856,7 +34007,7 @@ 1 2 - 28011 + 27994 @@ -33872,12 +34023,12 @@ 1 2 - 13072 + 13064 2 3 - 7469 + 7465 @@ -33893,12 +34044,12 @@ 1 2 - 13072 + 13064 2 3 - 7469 + 7465 @@ -33914,12 +34065,12 @@ 1 2 - 13072 + 13064 2 3 - 7469 + 7465 @@ -33935,7 +34086,7 @@ 1 2 - 20541 + 20529 @@ -33951,7 +34102,7 @@ 1 2 - 20541 + 20529 @@ -33967,12 +34118,12 @@ 1 2 - 13072 + 13064 2 3 - 7469 + 7465 @@ -34104,7 +34255,7 @@ 1 2 - 28011 + 27994 @@ -34120,7 +34271,7 @@ 1 2 - 28011 + 27994 @@ -34136,7 +34287,7 @@ 1 2 - 28011 + 27994 @@ -34152,7 +34303,7 @@ 1 2 - 28011 + 27994 @@ -34168,7 +34319,7 @@ 1 2 - 28011 + 27994 @@ -34184,7 +34335,7 @@ 1 2 - 28011 + 27994 @@ -34392,7 +34543,7 @@ 8 9 - 1867 + 1866 14 @@ -34413,7 +34564,7 @@ 8 9 - 1867 + 1866 14 @@ -34434,7 +34585,7 @@ 1 2 - 2801 + 2799 @@ -34450,7 +34601,7 @@ 8 9 - 1867 + 1866 14 @@ -34471,7 +34622,7 @@ 1 2 - 2801 + 2799 @@ -34487,7 +34638,7 @@ 1 2 - 2801 + 2799 @@ -34497,19 +34648,19 @@ fold - 0 + 4 expr - 0 + 4 operator - 0 + 4 is_left_fold - 0 + 2 @@ -34519,7 +34670,13 @@ 12 - + + + 1 + 2 + 4 + + @@ -34529,7 +34686,13 @@ 12 - + + + 1 + 2 + 4 + + @@ -34539,7 +34702,13 @@ 12 - + + + 1 + 2 + 4 + + @@ -34549,7 +34718,13 @@ 12 - + + + 1 + 2 + 4 + + @@ -34559,7 +34734,13 @@ 12 - + + + 2 + 3 + 2 + + @@ -34569,7 +34750,13 @@ 12 - + + + 2 + 3 + 2 + + @@ -34893,15 +35080,15 @@ type_vla - 0 + 1 type_id - 0 + 1 decl - 0 + 1 @@ -34911,7 +35098,13 @@ 12 - + + + 1 + 2 + 1 + + @@ -34921,7 +35114,13 @@ 12 - + + + 1 + 2 + 1 + + @@ -35121,15 +35320,15 @@ constexpr_if_initialization - 0 + 3 constexpr_if_stmt - 0 + 3 init_id - 0 + 3 @@ -35143,7 +35342,7 @@ 1 2 - 17 + 3 @@ -35155,7 +35354,13 @@ 12 - + + + 1 + 2 + 3 + + @@ -35355,15 +35560,15 @@ switch_initialization - 0 + 8 switch_stmt - 0 + 8 init_id - 0 + 8 @@ -35377,7 +35582,7 @@ 1 2 - 17 + 8 @@ -35389,7 +35594,13 @@ 12 - + + + 1 + 2 + 8 + + @@ -36170,11 +36381,11 @@ stmt_decl_bind - 580841 + 580849 stmt - 541059 + 541066 num @@ -36182,7 +36393,7 @@ decl - 580737 + 580745 @@ -36196,7 +36407,7 @@ 1 2 - 520371 + 520377 2 @@ -36217,7 +36428,7 @@ 1 2 - 520371 + 520377 2 @@ -36420,7 +36631,7 @@ 1 2 - 580700 + 580707 2 @@ -36441,7 +36652,7 @@ 1 2 - 580737 + 580745 @@ -36451,11 +36662,11 @@ stmt_decl_entry_bind - 580841 + 580849 stmt - 541059 + 541066 num @@ -36463,7 +36674,7 @@ decl_entry - 580783 + 580791 @@ -36477,7 +36688,7 @@ 1 2 - 520371 + 520377 2 @@ -36498,7 +36709,7 @@ 1 2 - 520371 + 520377 2 @@ -36701,7 +36912,7 @@ 1 2 - 580762 + 580770 3 @@ -36722,7 +36933,7 @@ 1 2 - 580783 + 580791 @@ -36732,15 +36943,15 @@ blockscope - 1410861 + 1410469 block - 1410861 + 1410469 enclosing - 1295546 + 1295224 @@ -36754,7 +36965,7 @@ 1 2 - 1410861 + 1410469 @@ -36770,12 +36981,12 @@ 1 2 - 1230185 + 1229903 2 13 - 65360 + 65321 @@ -36971,19 +37182,19 @@ preprocdirects - 4190567 + 4188015 id - 4190567 + 4188015 kind - 5135 + 5132 location - 4149950 + 4147423 @@ -36997,7 +37208,7 @@ 1 2 - 4190567 + 4188015 @@ -37013,7 +37224,7 @@ 1 2 - 4190567 + 4188015 @@ -37161,7 +37372,7 @@ 1 2 - 4149483 + 4146956 88 @@ -37182,7 +37393,7 @@ 1 2 - 4149950 + 4147423 @@ -37192,15 +37403,15 @@ preprocpair - 1431403 + 1430532 begin - 1197038 + 1196309 elseelifend - 1431403 + 1430532 @@ -37214,17 +37425,17 @@ 1 2 - 978546 + 977950 2 3 - 208221 + 208094 3 11 - 10270 + 10264 @@ -37240,7 +37451,7 @@ 1 2 - 1431403 + 1430532 @@ -37250,22 +37461,22 @@ preproctrue - 767056 + 766589 branch - 767056 + 766589 preprocfalse - 331473 + 331271 branch - 331473 + 331271 @@ -37418,15 +37629,15 @@ includes - 313265 + 313074 id - 313265 + 313074 included - 117182 + 117111 @@ -37440,7 +37651,7 @@ 1 2 - 313265 + 313074 @@ -37456,32 +37667,32 @@ 1 2 - 61159 + 61121 2 3 - 21942 + 21929 3 4 - 12605 + 12597 4 6 - 10270 + 10264 6 14 - 8870 + 8865 14 47 - 2334 + 2332 From 636c047c415af7b43e4577bb675ed72fd2bc0796 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 21 Nov 2024 13:53:49 +0000 Subject: [PATCH 162/470] Rust: Use final class. --- rust/ql/lib/codeql/rust/Concepts.qll | 32 ++++------------------------ 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/rust/ql/lib/codeql/rust/Concepts.qll b/rust/ql/lib/codeql/rust/Concepts.qll index 62cd24467d1..402c720ab6f 100644 --- a/rust/ql/lib/codeql/rust/Concepts.qll +++ b/rust/ql/lib/codeql/rust/Concepts.qll @@ -13,21 +13,7 @@ private import codeql.threatmodels.ThreatModels * Extend this class to refine existing API models. If you want to model new APIs, * extend `ThreatModelSource::Range` instead. */ -class ThreatModelSource extends DataFlow::Node instanceof ThreatModelSource::Range { - /** - * Gets a string that represents the source kind with respect to threat modeling. - * - * See - * - https://github.com/github/codeql/blob/main/docs/codeql/reusables/threat-model-description.rst - * - https://github.com/github/codeql/blob/main/shared/threat-models/ext/threat-model-grouping.model.yml - */ - string getThreatModel() { result = super.getThreatModel() } - - /** - * Gets a string that describes the type of this threat-model source. - */ - string getSourceType() { result = super.getSourceType() } -} +final class ThreatModelSource = ThreatModelSource::Range; /** * Provides a class for modeling new sources for specific threat-models. @@ -67,12 +53,7 @@ class ActiveThreatModelSource extends ThreatModelSource { * Extend this class to refine existing API models. If you want to model new APIs, * extend `SqlConstruction::Range` instead. */ -class SqlConstruction extends DataFlow::Node instanceof SqlConstruction::Range { - /** - * Gets the argument that specifies the SQL statements to be constructed. - */ - DataFlow::Node getSql() { result = super.getSql() } -} +final class SqlConstruction = SqlConstruction::Range; /** * Provides a class for modeling new SQL execution APIs. @@ -98,12 +79,7 @@ module SqlConstruction { * Extend this class to refine existing API models. If you want to model new APIs, * extend `SqlExecution::Range` instead. */ -class SqlExecution extends DataFlow::Node instanceof SqlExecution::Range { - /** - * Gets the argument that specifies the SQL statements to be executed. - */ - DataFlow::Node getSql() { result = super.getSql() } -} +final class SqlExecution = SqlExecution::Range; /** * Provides a class for modeling new SQL execution APIs. @@ -123,7 +99,7 @@ module SqlExecution { /** * A data-flow node that performs SQL sanitization. */ -class SqlSanitization extends DataFlow::Node instanceof SqlSanitization::Range { } +final class SqlSanitization = SqlSanitization::Range; /** * Provides a class for modeling new SQL sanitization APIs. From bb70bfce4354f7e53c153b239513f6f36c7fd144 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 21 Nov 2024 13:11:40 +0100 Subject: [PATCH 163/470] Rust: Tweak global data flow test and add inline flow test --- .../dataflow/global/inline-flow.expected | 6 ++++ .../dataflow/global/inline-flow.ql | 12 +++++++ .../library-tests/dataflow/global/main.rs | 22 ++++++++---- .../dataflow/global/viableCallable.expected | 35 ++++++++++--------- 4 files changed, 52 insertions(+), 23 deletions(-) create mode 100644 rust/ql/test/library-tests/dataflow/global/inline-flow.expected create mode 100644 rust/ql/test/library-tests/dataflow/global/inline-flow.ql diff --git a/rust/ql/test/library-tests/dataflow/global/inline-flow.expected b/rust/ql/test/library-tests/dataflow/global/inline-flow.expected new file mode 100644 index 00000000000..4e4a41dfc62 --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/global/inline-flow.expected @@ -0,0 +1,6 @@ +models +edges +nodes +subpaths +testFailures +#select diff --git a/rust/ql/test/library-tests/dataflow/global/inline-flow.ql b/rust/ql/test/library-tests/dataflow/global/inline-flow.ql new file mode 100644 index 00000000000..ad553fe548d --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/global/inline-flow.ql @@ -0,0 +1,12 @@ +/** + * @kind path-problem + */ + +import rust +import utils.InlineFlowTest +import DefaultFlowTest +import ValueFlow::PathGraph + +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) +select sink, source, sink, "$@", source, source.toString() diff --git a/rust/ql/test/library-tests/dataflow/global/main.rs b/rust/ql/test/library-tests/dataflow/global/main.rs index eb3a5985692..730ddd3cf4a 100644 --- a/rust/ql/test/library-tests/dataflow/global/main.rs +++ b/rust/ql/test/library-tests/dataflow/global/main.rs @@ -15,11 +15,11 @@ fn get_data(n: i64) -> i64 { fn data_out_of_call() { let a = get_data(7); - sink(a); // $ hasValueFlow=n + sink(a); // $ MISSING: hasValueFlow=n } fn data_in(n: i64) { - sink(n + 7); // $ hasValueFlow + sink(n); // $ MISSING: hasValueFlow=3 } fn data_in_to_call() { @@ -34,7 +34,15 @@ fn pass_through(i: i64) -> i64 { fn data_through_call() { let a = source(1); let b = pass_through(a); - sink(b); // $ hasValueFlow=1 + sink(b); // $ MISSING: hasValueFlow=1 +} + +fn block_expression_as_argument() { + let a = pass_through({ + println!("Hello"); + source(14) + }); + sink(a); // $ MISSING: hasValueFlow=14 } // ----------------------------------------------------------------------------- @@ -46,7 +54,7 @@ struct MyFlag { impl MyFlag { fn data_in(&self, n: i64) { - sink(n); // $ hasValueFlow=1 + sink(n); // $ MISSING: hasValueFlow=1 } fn get_data(&self) -> i64 { if self.flag { @@ -67,7 +75,7 @@ impl MyFlag { fn data_out_of_method() { let mn = MyFlag { flag: true }; let a = mn.get_data(); - sink(a); + sink(a); // $ MISSING: hasValueFlow=2 } fn data_in_to_method_call() { @@ -79,8 +87,8 @@ fn data_in_to_method_call() { fn data_through_method() { let mn = MyFlag { flag: true }; let a = source(4); - mn.data_through(a); - sink(a); // $ hasValueFlow=4 + let b = mn.data_through(a); + sink(b); // $ MISSING: hasValueFlow=4 } fn main() { diff --git a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected index 6a15bb25249..3a1db5acf22 100644 --- a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected +++ b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected @@ -1,24 +1,27 @@ | main.rs:13:5:13:13 | CallExpr | main.rs:1:1:3:1 | source | | main.rs:17:13:17:23 | CallExpr | main.rs:12:1:14:1 | get_data | | main.rs:18:5:18:11 | CallExpr | main.rs:5:1:7:1 | sink | -| main.rs:22:5:22:15 | CallExpr | main.rs:5:1:7:1 | sink | +| main.rs:22:5:22:11 | CallExpr | main.rs:5:1:7:1 | sink | | main.rs:26:13:26:21 | CallExpr | main.rs:1:1:3:1 | source | | main.rs:27:5:27:14 | CallExpr | main.rs:21:1:23:1 | data_in | | main.rs:35:13:35:21 | CallExpr | main.rs:1:1:3:1 | source | | main.rs:36:13:36:27 | CallExpr | main.rs:30:1:32:1 | pass_through | | main.rs:37:5:37:11 | CallExpr | main.rs:5:1:7:1 | sink | -| main.rs:49:9:49:15 | CallExpr | main.rs:5:1:7:1 | sink | -| main.rs:55:13:55:21 | CallExpr | main.rs:1:1:3:1 | source | -| main.rs:69:13:69:25 | ... .get_data(...) | main.rs:51:5:57:5 | get_data | -| main.rs:70:5:70:11 | CallExpr | main.rs:5:1:7:1 | sink | -| main.rs:75:13:75:21 | CallExpr | main.rs:1:1:3:1 | source | -| main.rs:76:5:76:17 | ... .data_in(...) | main.rs:48:5:50:5 | data_in | -| main.rs:81:13:81:21 | CallExpr | main.rs:1:1:3:1 | source | -| main.rs:82:5:82:22 | ... .data_through(...) | main.rs:58:5:64:5 | data_through | -| main.rs:83:5:83:11 | CallExpr | main.rs:5:1:7:1 | sink | -| main.rs:87:5:87:22 | CallExpr | main.rs:16:1:19:1 | data_out_of_call | -| main.rs:88:5:88:21 | CallExpr | main.rs:25:1:28:1 | data_in_to_call | -| main.rs:89:5:89:23 | CallExpr | main.rs:34:1:38:1 | data_through_call | -| main.rs:91:5:91:24 | CallExpr | main.rs:67:1:71:1 | data_out_of_method | -| main.rs:92:5:92:28 | CallExpr | main.rs:73:1:77:1 | data_in_to_method_call | -| main.rs:93:5:93:25 | CallExpr | main.rs:79:1:84:1 | data_through_method | +| main.rs:41:13:44:6 | CallExpr | main.rs:30:1:32:1 | pass_through | +| main.rs:43:9:43:18 | CallExpr | main.rs:1:1:3:1 | source | +| main.rs:45:5:45:11 | CallExpr | main.rs:5:1:7:1 | sink | +| main.rs:57:9:57:15 | CallExpr | main.rs:5:1:7:1 | sink | +| main.rs:63:13:63:21 | CallExpr | main.rs:1:1:3:1 | source | +| main.rs:77:13:77:25 | ... .get_data(...) | main.rs:59:5:65:5 | get_data | +| main.rs:78:5:78:11 | CallExpr | main.rs:5:1:7:1 | sink | +| main.rs:83:13:83:21 | CallExpr | main.rs:1:1:3:1 | source | +| main.rs:84:5:84:17 | ... .data_in(...) | main.rs:56:5:58:5 | data_in | +| main.rs:89:13:89:21 | CallExpr | main.rs:1:1:3:1 | source | +| main.rs:90:13:90:30 | ... .data_through(...) | main.rs:66:5:72:5 | data_through | +| main.rs:91:5:91:11 | CallExpr | main.rs:5:1:7:1 | sink | +| main.rs:95:5:95:22 | CallExpr | main.rs:16:1:19:1 | data_out_of_call | +| main.rs:96:5:96:21 | CallExpr | main.rs:25:1:28:1 | data_in_to_call | +| main.rs:97:5:97:23 | CallExpr | main.rs:34:1:38:1 | data_through_call | +| main.rs:99:5:99:24 | CallExpr | main.rs:75:1:79:1 | data_out_of_method | +| main.rs:100:5:100:28 | CallExpr | main.rs:81:1:85:1 | data_in_to_method_call | +| main.rs:101:5:101:25 | CallExpr | main.rs:87:1:92:1 | data_through_method | From 49e002843e78f7c0d4e9da70aeeeb378447add50 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 21 Nov 2024 13:57:45 +0000 Subject: [PATCH 164/470] Rust: Restore some documentation. --- rust/ql/lib/codeql/rust/Concepts.qll | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rust/ql/lib/codeql/rust/Concepts.qll b/rust/ql/lib/codeql/rust/Concepts.qll index 402c720ab6f..5befe006bc6 100644 --- a/rust/ql/lib/codeql/rust/Concepts.qll +++ b/rust/ql/lib/codeql/rust/Concepts.qll @@ -25,6 +25,10 @@ module ThreatModelSource { abstract class Range extends DataFlow::Node { /** * Gets a string that represents the source kind with respect to threat modeling. + * + * See + * - https://github.com/github/codeql/blob/main/docs/codeql/reusables/threat-model-description.rst + * - https://github.com/github/codeql/blob/main/shared/threat-models/ext/threat-model-grouping.model.yml */ abstract string getThreatModel(); From fffeac6a1384358335992191baf33228436da6e2 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 21 Nov 2024 15:11:25 +0100 Subject: [PATCH 165/470] Rust: Extend data flow library instantiation for global data flow --- .../lib/codeql/rust/controlflow/CfgNodes.qll | 2 + .../rust/dataflow/internal/DataFlowImpl.qll | 164 +++++++++++++----- .../CONSISTENCY/DataFlowConsistency.expected | 4 +- .../dataflow/barrier/inline-flow.expected | 13 ++ .../library-tests/dataflow/barrier/main.rs | 4 +- .../dataflow/global/inline-flow.expected | 69 ++++++++ .../library-tests/dataflow/global/main.rs | 12 +- .../dataflow/local/DataFlowStep.expected | 6 + 8 files changed, 219 insertions(+), 55 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll index b60a6b857b2..3ee3a3eeb61 100644 --- a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll @@ -13,6 +13,8 @@ class AstCfgNode = CfgImpl::AstCfgNode; class ExitCfgNode = CfgImpl::ExitNode; +class AnnotatedExitCfgNode = CfgImpl::AnnotatedExitNode; + /** * An assignment expression, for example * diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 210f12825cf..35ab9ade7b2 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -43,22 +43,59 @@ final class DataFlowCallable extends TDataFlowCallable { } final class DataFlowCall extends TDataFlowCall { + private CallExprBaseCfgNode call; + + DataFlowCall() { this = TCall(call) } + /** Gets the underlying call in the CFG, if any. */ - CallExprCfgNode asCallExprCfgNode() { this = TNormalCall(result) } + CallExprCfgNode asCallExprCfgNode() { result = call } - MethodCallExprCfgNode asMethodCallExprCfgNode() { this = TMethodCall(result) } + MethodCallExprCfgNode asMethodCallExprCfgNode() { result = call } - CallExprBaseCfgNode asExprCfgNode() { - result = this.asCallExprCfgNode() or result = this.asMethodCallExprCfgNode() - } + CallExprBaseCfgNode asCallBaseExprCfgNode() { result = call } DataFlowCallable getEnclosingCallable() { - result = TCfgScope(this.asExprCfgNode().getExpr().getEnclosingCfgScope()) + result = TCfgScope(call.getExpr().getEnclosingCfgScope()) } - string toString() { result = this.asExprCfgNode().toString() } + string toString() { result = this.asCallBaseExprCfgNode().toString() } - Location getLocation() { result = this.asExprCfgNode().getLocation() } + Location getLocation() { result = this.asCallBaseExprCfgNode().getLocation() } +} + +/** + * The position of a parameter or an argument in a function or call. + * + * As there is a 1-to-1 correspondence between parameter positions and + * arguments positions in Rust we use the same type for both. + */ +final class ParameterPosition extends TParameterPosition { + /** Gets the underlying integer position, if any. */ + int getPosition() { this = TPositionalParameterPosition(result) } + + /** Holds if this position represents the `self` position. */ + predicate isSelf() { this = TSelfParameterPosition() } + + /** Gets a textual representation of this position. */ + string toString() { + result = this.getPosition().toString() + or + result = "self" and this.isSelf() + } + + AstNode getParameterIn(ParamList ps) { + result = ps.getParam(this.getPosition()) + or + result = ps.getSelfParam() and this.isSelf() + } +} + +/** Holds if `arg` is an argument of `call` at the position `pos`. */ +private predicate isArgumentForCall(ExprCfgNode arg, CallExprBaseCfgNode call, ParameterPosition pos) { + arg = call.getArgument(pos.getPosition()) + or + // The self argument in a method call. + arg = call.(MethodCallExprCfgNode).getReceiver() and pos.isSelf() } module Node { @@ -93,11 +130,6 @@ module Node { * Gets this node's underlying SSA definition, if any. */ Ssa::Definition asDefinition() { none() } - - /** - * Gets the parameter that corresponds to this node, if any. - */ - Param asParameter() { none() } } /** A node type that is not implemented. */ @@ -111,7 +143,7 @@ module Node { override Location getLocation() { none() } } - /** A data flow node that corresponds to a CFG node for an AST node. */ + /** A data flow node that corresponds directly to a CFG node for an AST node. */ abstract class AstCfgFlowNode extends Node { AstCfgNode n; @@ -145,24 +177,37 @@ module Node { PatNode() { this = TPatNode(n) } - /** Gets the `Pat` in the AST that this node corresponds to. */ - Pat getPat() { result = n.getPat() } + /** Gets the `PatCfgNode` in the CFG that this node corresponds to. */ + PatCfgNode getPat() { result = n } } + abstract class ParameterNode extends AstCfgFlowNode { } + /** * The value of a parameter at function entry, viewed as a node in a data * flow graph. */ - final class ParameterNode extends AstCfgFlowNode, TParameterNode { + final class NormalParameterNode extends ParameterNode, TParameterNode { override ParamCfgNode n; - ParameterNode() { this = TParameterNode(n) } + NormalParameterNode() { this = TParameterNode(n) } /** Gets the parameter in the CFG that this node corresponds to. */ ParamCfgNode getParameter() { result = n } } - final class ArgumentNode = NaNode; + final class SelfParameterNode extends ParameterNode, TSelfParameterNode { + override SelfParamCfgNode n; + + SelfParameterNode() { this = TSelfParameterNode(n) } + + /** Gets the self parameter in the AST that this node corresponds to. */ + SelfParamCfgNode getSelfParameter() { result = n } + } + + final class ArgumentNode extends ExprNode { + ArgumentNode() { isArgumentForCall(n, _, _) } + } /** An SSA node. */ class SsaNode extends Node, TSsaNode { @@ -185,7 +230,10 @@ module Node { /** A data flow node that represents a value returned by a callable. */ final class ReturnNode extends ExprNode { - ReturnNode() { this.getCfgNode().getASuccessor() instanceof ExitCfgNode } + ReturnNode() { + this.getCfgNode().getASuccessor() instanceof ExitCfgNode or + this.getCfgNode().getASuccessor() instanceof AnnotatedExitCfgNode + } ReturnKind getKind() { any() } } @@ -197,10 +245,10 @@ module Node { } final private class ExprOutNode extends ExprNode, OutNode { - ExprOutNode() { this.asExpr() instanceof CallExprCfgNode } + ExprOutNode() { this.asExpr() instanceof CallExprBaseCfgNode } /** Gets the underlying call CFG node that includes this out node. */ - override DataFlowCall getCall() { result.asExprCfgNode() = this.getCfgNode() } + override DataFlowCall getCall() { result.asCallBaseExprCfgNode() = this.getCfgNode() } } /** @@ -214,9 +262,19 @@ module Node { * Nodes corresponding to AST elements, for example `ExprNode`, usually refer * to the value before the update. */ - final class PostUpdateNode extends Node::NaNode { + final class PostUpdateNode extends Node, TArgumentPostUpdateNode { + private ExprCfgNode n; + + PostUpdateNode() { this = TArgumentPostUpdateNode(n) } + /** Gets the node before the state update. */ - Node getPreUpdateNode() { none() } + Node getPreUpdateNode() { result = TExprNode(n) } + + final override CfgScope getCfgScope() { result = n.getAstNode().getEnclosingCfgScope() } + + final override Location getLocation() { result = n.getAstNode().getLocation() } + + final override string toString() { result = n.getAstNode().toString() } } final class CastNode = NaNode; @@ -226,25 +284,27 @@ final class Node = Node::Node; /** Provides logic related to SSA. */ module SsaFlow { - private module Impl = SsaImpl::DataFlowIntegration; + private module SsaFlow = SsaImpl::DataFlowIntegration; - private Node::ParameterNode toParameterNode(ParamCfgNode p) { result.getParameter() = p } + private Node::ParameterNode toParameterNode(ParamCfgNode p) { + result.(Node::NormalParameterNode).getParameter() = p + } /** Converts a control flow node into an SSA control flow node. */ - Impl::Node asNode(Node n) { + SsaFlow::Node asNode(Node n) { n = TSsaNode(result) or - result.(Impl::ExprNode).getExpr() = n.asExpr() + result.(SsaFlow::ExprNode).getExpr() = n.asExpr() or - n = toParameterNode(result.(Impl::ParameterNode).getParameter()) + n = toParameterNode(result.(SsaFlow::ParameterNode).getParameter()) } predicate localFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo, boolean isUseStep) { - Impl::localFlowStep(def, asNode(nodeFrom), asNode(nodeTo), isUseStep) + SsaFlow::localFlowStep(def, asNode(nodeFrom), asNode(nodeTo), isUseStep) } predicate localMustFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) { - Impl::localMustFlowStep(def, asNode(nodeFrom), asNode(nodeTo)) + SsaFlow::localMustFlowStep(def, asNode(nodeFrom), asNode(nodeTo)) } } @@ -276,6 +336,8 @@ module LocalFlow { nodeFrom.(Node::AstCfgFlowNode).getCfgNode() = nodeTo.(Node::SsaNode).getDefinitionExt().(Ssa::WriteDefinition).getControlFlowNode() or + nodeFrom.(Node::NormalParameterNode).getParameter().getPat() = nodeTo.(Node::PatNode).getPat() + or SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _) or exists(AssignmentExprCfgNode a | @@ -291,6 +353,8 @@ private class ReturnKindAlias = ReturnKind; private class DataFlowCallAlias = DataFlowCall; +private class ParameterPositionAlias = ParameterPosition; + module RustDataFlow implements InputSig { /** * An element, viewed as a node in a data flow graph. Either an expression @@ -310,9 +374,15 @@ module RustDataFlow implements InputSig { final class CastNode = Node::NaNode; - predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) { none() } + /** Holds if `p` is a parameter of `c` at the position `pos`. */ + predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) { + p.getCfgNode().getAstNode() = pos.getParameterIn(c.asCfgScope().(Function).getParamList()) + } - predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos) { none() } + /** Holds if `n` is an argument of `c` at the position `pos`. */ + predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos) { + isArgumentForCall(n.getCfgNode(), call.asCallBaseExprCfgNode(), pos) + } DataFlowCallable nodeGetEnclosingCallable(Node node) { result = node.getEnclosingCallable() } @@ -335,10 +405,9 @@ module RustDataFlow implements InputSig { DataFlowCallable viableCallable(DataFlowCall c) { exists(Function f, string name | result.asCfgScope() = f and name = f.getName().toString() | if f.getParamList().hasSelfParam() - then name = c.asMethodCallExprCfgNode().getMethodCallExpr().getNameRef().getText() + then name = c.asMethodCallExprCfgNode().getNameRef().getText() else - name = - c.asCallExprCfgNode().getCallExpr().getExpr().(PathExpr).getPath().getPart().toString() + name = c.asCallExprCfgNode().getExpr().getExpr().(PathExpr).getPath().getPart().toString() ) } @@ -377,19 +446,15 @@ module RustDataFlow implements InputSig { ContentApprox getContentApprox(Content c) { any() } - class ParameterPosition extends string { - ParameterPosition() { this = "pos" } - } + class ParameterPosition = ParameterPositionAlias; - class ArgumentPosition extends string { - ArgumentPosition() { this = "pos" } - } + class ArgumentPosition = ParameterPosition; /** * Holds if the parameter position `ppos` matches the argument position * `apos`. */ - predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { none() } + predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos } /** * Holds if there is a simple local flow step from `node1` to `node2`. These @@ -497,13 +562,13 @@ private module Cached { newtype TNode = TExprNode(ExprCfgNode n) or TParameterNode(ParamCfgNode p) or + TSelfParameterNode(SelfParamCfgNode p) or TPatNode(PatCfgNode p) or + TArgumentPostUpdateNode(ExprCfgNode e) { isArgumentForCall(e, _, _) } or TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node) cached - newtype TDataFlowCall = - TNormalCall(CallExprCfgNode c) or - TMethodCall(MethodCallExprCfgNode c) + newtype TDataFlowCall = TCall(CallExprBaseCfgNode c) cached newtype TOptionalContentSet = @@ -521,6 +586,13 @@ private module Cached { predicate localFlowStepImpl(Node::Node nodeFrom, Node::Node nodeTo) { LocalFlow::localFlowStepCommon(nodeFrom, nodeTo) } + + cached + newtype TParameterPosition = + TPositionalParameterPosition(int i) { + exists(any(ParamList l).getParam(i)) or exists(any(ArgList l).getArg(i)) + } or + TSelfParameterPosition() } import Cached diff --git a/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected index 02210855a69..1a9588efd03 100644 --- a/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected +++ b/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected @@ -1,9 +1,11 @@ uniqueNodeLocation | file://:0:0:0:0 | ... .parent(...) | Node should have one location but has 0. | +| file://:0:0:0:0 | ... .parent(...) | Node should have one location but has 0. | | file://:0:0:0:0 | ... .unwrap(...) | Node should have one location but has 0. | | file://:0:0:0:0 | BlockExpr | Node should have one location but has 0. | | file://:0:0:0:0 | Param | Node should have one location but has 0. | | file://:0:0:0:0 | path | Node should have one location but has 0. | | file://:0:0:0:0 | path | Node should have one location but has 0. | +| file://:0:0:0:0 | path | Node should have one location but has 0. | missingLocation -| Nodes without location: 6 | +| Nodes without location: 8 | diff --git a/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected b/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected index a54c75d0c17..dd98dd9cee4 100644 --- a/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected @@ -1,16 +1,29 @@ models edges +| main.rs:9:13:9:19 | Param : unit | main.rs:9:30:14:1 | BlockExpr : unit | provenance | | | main.rs:21:13:21:21 | CallExpr : unit | main.rs:22:10:22:10 | s | provenance | | +| main.rs:26:13:26:21 | CallExpr : unit | main.rs:27:22:27:22 | s : unit | provenance | | +| main.rs:27:13:27:23 | CallExpr : unit | main.rs:28:10:28:10 | s | provenance | | +| main.rs:27:22:27:22 | s : unit | main.rs:9:13:9:19 | Param : unit | provenance | | +| main.rs:27:22:27:22 | s : unit | main.rs:27:13:27:23 | CallExpr : unit | provenance | | | main.rs:32:13:32:21 | CallExpr : unit | main.rs:33:10:33:10 | s | provenance | | nodes +| main.rs:9:13:9:19 | Param : unit | semmle.label | Param : unit | +| main.rs:9:30:14:1 | BlockExpr : unit | semmle.label | BlockExpr : unit | | main.rs:17:10:17:18 | CallExpr | semmle.label | CallExpr | | main.rs:21:13:21:21 | CallExpr : unit | semmle.label | CallExpr : unit | | main.rs:22:10:22:10 | s | semmle.label | s | +| main.rs:26:13:26:21 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:27:13:27:23 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:27:22:27:22 | s : unit | semmle.label | s : unit | +| main.rs:28:10:28:10 | s | semmle.label | s | | main.rs:32:13:32:21 | CallExpr : unit | semmle.label | CallExpr : unit | | main.rs:33:10:33:10 | s | semmle.label | s | subpaths +| main.rs:27:22:27:22 | s : unit | main.rs:9:13:9:19 | Param : unit | main.rs:9:30:14:1 | BlockExpr : unit | main.rs:27:13:27:23 | CallExpr : unit | testFailures #select | main.rs:17:10:17:18 | CallExpr | main.rs:17:10:17:18 | CallExpr | main.rs:17:10:17:18 | CallExpr | $@ | main.rs:17:10:17:18 | CallExpr | CallExpr | | main.rs:22:10:22:10 | s | main.rs:21:13:21:21 | CallExpr : unit | main.rs:22:10:22:10 | s | $@ | main.rs:21:13:21:21 | CallExpr : unit | CallExpr : unit | +| main.rs:28:10:28:10 | s | main.rs:26:13:26:21 | CallExpr : unit | main.rs:28:10:28:10 | s | $@ | main.rs:26:13:26:21 | CallExpr : unit | CallExpr : unit | | main.rs:33:10:33:10 | s | main.rs:32:13:32:21 | CallExpr : unit | main.rs:33:10:33:10 | s | $@ | main.rs:32:13:32:21 | CallExpr : unit | CallExpr : unit | diff --git a/rust/ql/test/library-tests/dataflow/barrier/main.rs b/rust/ql/test/library-tests/dataflow/barrier/main.rs index 8a0a7bc2be6..14935f0f328 100644 --- a/rust/ql/test/library-tests/dataflow/barrier/main.rs +++ b/rust/ql/test/library-tests/dataflow/barrier/main.rs @@ -9,7 +9,7 @@ fn sink(s: &str) { fn sanitize(s: &str) -> &str { match s { "dangerous" => "", - s => s + s => s, } } @@ -25,7 +25,7 @@ fn through_variable() { fn with_barrier() { let s = source(1); let s = sanitize(s); - sink(s); + sink(s); // $ SPURIOUS: hasValueFlow=1 } fn main() { diff --git a/rust/ql/test/library-tests/dataflow/global/inline-flow.expected b/rust/ql/test/library-tests/dataflow/global/inline-flow.expected index 4e4a41dfc62..6054637c126 100644 --- a/rust/ql/test/library-tests/dataflow/global/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/global/inline-flow.expected @@ -1,6 +1,75 @@ models edges +| main.rs:12:28:14:1 | BlockExpr : unit | main.rs:17:13:17:23 | CallExpr : unit | provenance | | +| main.rs:13:5:13:13 | CallExpr : unit | main.rs:12:28:14:1 | BlockExpr : unit | provenance | | +| main.rs:17:13:17:23 | CallExpr : unit | main.rs:18:10:18:10 | a | provenance | | +| main.rs:21:12:21:17 | Param : unit | main.rs:22:10:22:10 | n | provenance | | +| main.rs:26:13:26:21 | CallExpr : unit | main.rs:27:13:27:13 | a : unit | provenance | | +| main.rs:27:13:27:13 | a : unit | main.rs:21:12:21:17 | Param : unit | provenance | | +| main.rs:30:17:30:22 | Param : unit | main.rs:30:32:32:1 | BlockExpr : unit | provenance | | +| main.rs:35:13:35:21 | CallExpr : unit | main.rs:36:26:36:26 | a : unit | provenance | | +| main.rs:36:13:36:27 | CallExpr : unit | main.rs:37:10:37:10 | b | provenance | | +| main.rs:36:26:36:26 | a : unit | main.rs:30:17:30:22 | Param : unit | provenance | | +| main.rs:36:26:36:26 | a : unit | main.rs:36:13:36:27 | CallExpr : unit | provenance | | +| main.rs:41:13:44:6 | CallExpr : unit | main.rs:45:10:45:10 | a | provenance | | +| main.rs:41:26:44:5 | BlockExpr : unit | main.rs:30:17:30:22 | Param : unit | provenance | | +| main.rs:41:26:44:5 | BlockExpr : unit | main.rs:41:13:44:6 | CallExpr : unit | provenance | | +| main.rs:43:9:43:18 | CallExpr : unit | main.rs:41:26:44:5 | BlockExpr : unit | provenance | | +| main.rs:56:23:56:28 | Param : unit | main.rs:57:14:57:14 | n | provenance | | +| main.rs:59:31:65:5 | BlockExpr : unit | main.rs:77:13:77:25 | ... .get_data(...) : unit | provenance | | +| main.rs:63:13:63:21 | CallExpr : unit | main.rs:59:31:65:5 | BlockExpr : unit | provenance | | +| main.rs:66:28:66:33 | Param : unit | main.rs:66:43:72:5 | BlockExpr : unit | provenance | | +| main.rs:77:13:77:25 | ... .get_data(...) : unit | main.rs:78:10:78:10 | a | provenance | | +| main.rs:83:13:83:21 | CallExpr : unit | main.rs:84:16:84:16 | a : unit | provenance | | +| main.rs:84:16:84:16 | a : unit | main.rs:56:23:56:28 | Param : unit | provenance | | +| main.rs:89:13:89:21 | CallExpr : unit | main.rs:90:29:90:29 | a : unit | provenance | | +| main.rs:90:13:90:30 | ... .data_through(...) : unit | main.rs:91:10:91:10 | b | provenance | | +| main.rs:90:29:90:29 | a : unit | main.rs:66:28:66:33 | Param : unit | provenance | | +| main.rs:90:29:90:29 | a : unit | main.rs:90:13:90:30 | ... .data_through(...) : unit | provenance | | nodes +| main.rs:12:28:14:1 | BlockExpr : unit | semmle.label | BlockExpr : unit | +| main.rs:13:5:13:13 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:17:13:17:23 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:18:10:18:10 | a | semmle.label | a | +| main.rs:21:12:21:17 | Param : unit | semmle.label | Param : unit | +| main.rs:22:10:22:10 | n | semmle.label | n | +| main.rs:26:13:26:21 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:27:13:27:13 | a : unit | semmle.label | a : unit | +| main.rs:30:17:30:22 | Param : unit | semmle.label | Param : unit | +| main.rs:30:32:32:1 | BlockExpr : unit | semmle.label | BlockExpr : unit | +| main.rs:35:13:35:21 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:36:13:36:27 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:36:26:36:26 | a : unit | semmle.label | a : unit | +| main.rs:37:10:37:10 | b | semmle.label | b | +| main.rs:41:13:44:6 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:41:26:44:5 | BlockExpr : unit | semmle.label | BlockExpr : unit | +| main.rs:43:9:43:18 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:45:10:45:10 | a | semmle.label | a | +| main.rs:56:23:56:28 | Param : unit | semmle.label | Param : unit | +| main.rs:57:14:57:14 | n | semmle.label | n | +| main.rs:59:31:65:5 | BlockExpr : unit | semmle.label | BlockExpr : unit | +| main.rs:63:13:63:21 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:66:28:66:33 | Param : unit | semmle.label | Param : unit | +| main.rs:66:43:72:5 | BlockExpr : unit | semmle.label | BlockExpr : unit | +| main.rs:77:13:77:25 | ... .get_data(...) : unit | semmle.label | ... .get_data(...) : unit | +| main.rs:78:10:78:10 | a | semmle.label | a | +| main.rs:83:13:83:21 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:84:16:84:16 | a : unit | semmle.label | a : unit | +| main.rs:89:13:89:21 | CallExpr : unit | semmle.label | CallExpr : unit | +| main.rs:90:13:90:30 | ... .data_through(...) : unit | semmle.label | ... .data_through(...) : unit | +| main.rs:90:29:90:29 | a : unit | semmle.label | a : unit | +| main.rs:91:10:91:10 | b | semmle.label | b | subpaths +| main.rs:36:26:36:26 | a : unit | main.rs:30:17:30:22 | Param : unit | main.rs:30:32:32:1 | BlockExpr : unit | main.rs:36:13:36:27 | CallExpr : unit | +| main.rs:41:26:44:5 | BlockExpr : unit | main.rs:30:17:30:22 | Param : unit | main.rs:30:32:32:1 | BlockExpr : unit | main.rs:41:13:44:6 | CallExpr : unit | +| main.rs:90:29:90:29 | a : unit | main.rs:66:28:66:33 | Param : unit | main.rs:66:43:72:5 | BlockExpr : unit | main.rs:90:13:90:30 | ... .data_through(...) : unit | testFailures +| main.rs:45:10:45:10 | a | Fixed missing result: hasValueFlow=14 | #select +| main.rs:18:10:18:10 | a | main.rs:13:5:13:13 | CallExpr : unit | main.rs:18:10:18:10 | a | $@ | main.rs:13:5:13:13 | CallExpr : unit | CallExpr : unit | +| main.rs:22:10:22:10 | n | main.rs:26:13:26:21 | CallExpr : unit | main.rs:22:10:22:10 | n | $@ | main.rs:26:13:26:21 | CallExpr : unit | CallExpr : unit | +| main.rs:37:10:37:10 | b | main.rs:35:13:35:21 | CallExpr : unit | main.rs:37:10:37:10 | b | $@ | main.rs:35:13:35:21 | CallExpr : unit | CallExpr : unit | +| main.rs:45:10:45:10 | a | main.rs:43:9:43:18 | CallExpr : unit | main.rs:45:10:45:10 | a | $@ | main.rs:43:9:43:18 | CallExpr : unit | CallExpr : unit | +| main.rs:57:14:57:14 | n | main.rs:83:13:83:21 | CallExpr : unit | main.rs:57:14:57:14 | n | $@ | main.rs:83:13:83:21 | CallExpr : unit | CallExpr : unit | +| main.rs:78:10:78:10 | a | main.rs:63:13:63:21 | CallExpr : unit | main.rs:78:10:78:10 | a | $@ | main.rs:63:13:63:21 | CallExpr : unit | CallExpr : unit | +| main.rs:91:10:91:10 | b | main.rs:89:13:89:21 | CallExpr : unit | main.rs:91:10:91:10 | b | $@ | main.rs:89:13:89:21 | CallExpr : unit | CallExpr : unit | diff --git a/rust/ql/test/library-tests/dataflow/global/main.rs b/rust/ql/test/library-tests/dataflow/global/main.rs index 730ddd3cf4a..ebdb7b30d75 100644 --- a/rust/ql/test/library-tests/dataflow/global/main.rs +++ b/rust/ql/test/library-tests/dataflow/global/main.rs @@ -15,11 +15,11 @@ fn get_data(n: i64) -> i64 { fn data_out_of_call() { let a = get_data(7); - sink(a); // $ MISSING: hasValueFlow=n + sink(a); // $ hasValueFlow=n } fn data_in(n: i64) { - sink(n); // $ MISSING: hasValueFlow=3 + sink(n); // $ hasValueFlow=3 } fn data_in_to_call() { @@ -34,7 +34,7 @@ fn pass_through(i: i64) -> i64 { fn data_through_call() { let a = source(1); let b = pass_through(a); - sink(b); // $ MISSING: hasValueFlow=1 + sink(b); // $ hasValueFlow=1 } fn block_expression_as_argument() { @@ -54,7 +54,7 @@ struct MyFlag { impl MyFlag { fn data_in(&self, n: i64) { - sink(n); // $ MISSING: hasValueFlow=1 + sink(n); // $ hasValueFlow=1 } fn get_data(&self) -> i64 { if self.flag { @@ -75,7 +75,7 @@ impl MyFlag { fn data_out_of_method() { let mn = MyFlag { flag: true }; let a = mn.get_data(); - sink(a); // $ MISSING: hasValueFlow=2 + sink(a); // $ hasValueFlow=2 } fn data_in_to_method_call() { @@ -88,7 +88,7 @@ fn data_through_method() { let mn = MyFlag { flag: true }; let a = source(4); let b = mn.data_through(a); - sink(b); // $ MISSING: hasValueFlow=4 + sink(b); // $ hasValueFlow=4 } fn main() { diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 1ccc9c219c3..86bc28d7940 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -1,13 +1,16 @@ | main.rs:3:11:3:11 | [SSA] i | main.rs:4:12:4:12 | i | | main.rs:3:11:3:11 | i | main.rs:3:11:3:11 | [SSA] i | +| main.rs:3:11:3:16 | Param | main.rs:3:11:3:11 | i | | main.rs:4:5:4:12 | ... + ... | main.rs:3:26:5:1 | BlockExpr | | main.rs:7:9:7:9 | [SSA] s | main.rs:8:20:8:20 | s | | main.rs:7:9:7:9 | s | main.rs:7:9:7:9 | [SSA] s | +| main.rs:7:9:7:14 | Param | main.rs:7:9:7:9 | s | | main.rs:19:9:19:9 | [SSA] s | main.rs:20:10:20:10 | s | | main.rs:19:9:19:9 | s | main.rs:19:9:19:9 | [SSA] s | | main.rs:19:13:19:21 | CallExpr | main.rs:19:9:19:9 | s | | main.rs:23:18:23:21 | [SSA] cond | main.rs:26:16:26:19 | cond | | main.rs:23:18:23:21 | cond | main.rs:23:18:23:21 | [SSA] cond | +| main.rs:23:18:23:27 | Param | main.rs:23:18:23:21 | cond | | main.rs:24:9:24:9 | [SSA] a | main.rs:26:23:26:23 | a | | main.rs:24:9:24:9 | a | main.rs:24:9:24:9 | [SSA] a | | main.rs:24:13:24:21 | CallExpr | main.rs:24:9:24:9 | a | @@ -23,6 +26,7 @@ | main.rs:26:34:26:34 | b | main.rs:26:32:26:36 | BlockExpr | | main.rs:30:21:30:21 | [SSA] m | main.rs:32:19:32:19 | m | | main.rs:30:21:30:21 | m | main.rs:30:21:30:21 | [SSA] m | +| main.rs:30:21:30:34 | Param | main.rs:30:21:30:21 | m | | main.rs:31:9:31:9 | [SSA] a | main.rs:33:20:33:20 | a | | main.rs:31:9:31:9 | a | main.rs:31:9:31:9 | [SSA] a | | main.rs:31:13:31:21 | CallExpr | main.rs:31:9:31:9 | a | @@ -91,6 +95,7 @@ | main.rs:118:5:118:5 | a | main.rs:116:31:119:1 | BlockExpr | | main.rs:121:22:121:22 | [SSA] b | main.rs:123:12:123:12 | b | | main.rs:121:22:121:22 | b | main.rs:121:22:121:22 | [SSA] b | +| main.rs:121:22:121:28 | Param | main.rs:121:22:121:22 | b | | main.rs:122:9:122:9 | [SSA] a | main.rs:128:5:128:5 | a | | main.rs:122:9:122:9 | a | main.rs:122:9:122:9 | [SSA] a | | main.rs:122:13:127:5 | BlockExpr | main.rs:122:9:122:9 | a | @@ -100,6 +105,7 @@ | main.rs:128:5:128:5 | a | main.rs:121:38:129:1 | BlockExpr | | main.rs:131:22:131:22 | [SSA] b | main.rs:133:12:133:12 | b | | main.rs:131:22:131:22 | b | main.rs:131:22:131:22 | [SSA] b | +| main.rs:131:22:131:28 | Param | main.rs:131:22:131:22 | b | | main.rs:132:9:132:9 | [SSA] a | main.rs:138:5:138:5 | a | | main.rs:132:9:132:9 | a | main.rs:132:9:132:9 | [SSA] a | | main.rs:132:13:137:5 | BlockExpr | main.rs:132:9:132:9 | a | From b7c7a9ee7c2d5303ecc52c242f05e43dc4dae6d1 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 21 Nov 2024 14:23:51 +0000 Subject: [PATCH 166/470] Rust: Accept consistency check failures. --- .../security/CWE-089/CONSISTENCY/DataFlowConsistency.expected | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected index d9a60435a6f..6e35019c1cb 100644 --- a/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected +++ b/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected @@ -1,3 +1,7 @@ +uniqueEnclosingCallable +| sqlx.rs:52:72:52:84 | remote_number | Node should have one enclosing callable but has 0. | +| sqlx.rs:56:74:56:86 | remote_string | Node should have one enclosing callable but has 0. | +| sqlx.rs:199:32:199:44 | enable_remote | Node should have one enclosing callable but has 0. | uniqueNodeToString | sqlx.rs:154:13:154:81 | (no string representation) | Node should have one toString but has 0. | | sqlx.rs:156:17:156:86 | (no string representation) | Node should have one toString but has 0. | From 6776b31c0d2613eaafc26959af658e87cd01b66e Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Nov 2024 15:27:34 +0100 Subject: [PATCH 167/470] Rust: tweak `PathType` string representations and add one for `InferType` --- rust/ql/.generated.list | 8 +++----- rust/ql/.gitattributes | 2 -- rust/ql/lib/codeql/rust/elements/PathType.qll | 5 +++-- .../rust/elements/internal/GenericArgListImpl.qll | 8 ++++++-- .../codeql/rust/elements/internal/InferTypeImpl.qll | 8 ++++++-- .../rust/elements/internal/PathSegmentImpl.qll | 11 +++++------ .../codeql/rust/elements/internal/PathTypeImpl.qll | 9 ++++----- .../rust/elements/internal/generated/PathType.qll | 5 +++-- .../codeql/rust/elements/internal/generated/Raw.qll | 5 +++-- .../extractor-tests/generated/.generated_tests.list | 2 +- .../extractor-tests/generated/Path/Path.expected | 11 +++++++---- .../extractor-tests/generated/Path/PathExpr.expected | 1 - .../generated/Path/PathExpr_getPath.expected | 1 - .../generated/Path/PathSegment.expected | 11 +++++++---- .../Path/PathSegment_getGenericArgList.expected | 1 + .../generated/Path/PathSegment_getNameRef.expected | 11 +++++++---- .../generated/Path/PathSegment_getPathType.expected | 4 ++-- .../generated/Path/PathSegment_getTy.expected | 4 ++-- .../extractor-tests/generated/Path/PathType.expected | 12 ++++++++---- .../generated/Path/PathType_getPath.expected | 12 ++++++++---- .../generated/Path/Path_getPart.expected | 11 +++++++---- .../generated/Path/Path_getQualifier.expected | 5 +++-- .../Path/Path_getResolvedCrateOrigin.expected | 4 ++-- .../generated/Path/Path_getResolvedPath.expected | 4 ++-- .../extractor-tests/generated/Path/gen_path_type.rs | 5 +++-- rust/schema/annotations.py | 5 +++-- 26 files changed, 96 insertions(+), 69 deletions(-) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 0e6b53b2067..b51e8fb53ef 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -104,7 +104,7 @@ lib/codeql/rust/elements/PathExpr.qll 906df1d80c662b79f1b0b0428c39754b7f8dbcb223 lib/codeql/rust/elements/PathExprBase.qll bb41092ec690ae926e3233c215dcaf1fd8e161b8a6955151949f492e02dba13a b2257072f8062d31c29c63ee1311b07e0d2eb37075f582cfc76bb542ef773198 lib/codeql/rust/elements/PathPat.qll 6897e69bcb24b56d39ede796cf5767988dcd5741e02333fa8495dd7c814f771a 2a011fb92f17e4b4ff713e6d29f591054dfede22a9aaa006e67fca2c23ab76bf lib/codeql/rust/elements/PathSegment.qll 9560551cf8b65e84705e7f302e12b48330e048613129e87c0f65a7eb297a6cc3 3aa75a5fd81f8ea32bd2b4bf0c51c386de57cbe9ab035fe3ec68ad7fcf51b375 -lib/codeql/rust/elements/PathType.qll a7bd3b05dc2c0e96c91c5485db508a1f5bb8fe3a01486be6815ae9dabb163add b11e996b6c0cc21a3d8d1ddc23c37e4d54a78e84a9278b3ceca1e94cb7321532 +lib/codeql/rust/elements/PathType.qll 257ede178bb74ebdb8e266ebaa95082e7fb7cc8d921ef476f4df268ee8a1366c c48f6e04a8945a11f965e71819f68c00abc53a055042882b61716feda3ca63ae lib/codeql/rust/elements/PrefixExpr.qll 107e7bd111b637fd6d76026062d54c2780760b965f172ef119c50dd0714a377d 46954a9404e561c51682395729daac3bda5442113f29839d043e9605d63f7f6d lib/codeql/rust/elements/PtrType.qll b137f47a53e41b3b30c7d80dbdd6724bf15f99530ca40cc264a04af5f07aa878 b2ffdf739bfb7564d942fe54409834a59511c0b305b6d5b2219a8ee0ef594332 lib/codeql/rust/elements/RangeExpr.qll 43785bea08a6a537010db1138e68ae92eed7e481744188dfb3bad119425ff740 5e81cfbdf4617372a73d662a248a0b380c1f40988a5daefb7f00057cae10d3d4 @@ -233,7 +233,6 @@ lib/codeql/rust/elements/internal/FormatArgsExprConstructor.qll ce29ff5a839b885b lib/codeql/rust/elements/internal/FunctionConstructor.qll b50aea579938d03745dfbd8b5fa8498f7f83b967369f63d6875510e09ab7f5d2 19cca32aeaecaf9debc27329e8c39ecec69464bb1d89d7b09908a1d73a8d92a2 lib/codeql/rust/elements/internal/GenericArgImpl.qll 6b1b804c357425c223f926e560a688e81506f5a35b95485cecf704e88cc009ee cc1ccf6a23dadc397e82664f3911d4b385d4c8ca80b1ee16d5275d9c936148dd lib/codeql/rust/elements/internal/GenericArgListConstructor.qll 46859bb3eb09d77987a18642d65ba2e13471a4dc9c0a83a192fddc82e37c335c 2c7d54c876269a88d3461b05745e73b06532b1616cae9b614ac94b28735d8fc4 -lib/codeql/rust/elements/internal/GenericArgListImpl.qll 1a39ba7080147abccaaba451852c9c124fb6177f2ebd64e38ee74014444a34e1 80df3150c961936037ac02b46ef5f775c3f82e66490afbca00a016cb9eee798a lib/codeql/rust/elements/internal/GenericParamImpl.qll f435f80d7f275803c1311d362467f4a367deb5a2c0245b17a9e12468a2c3ce2f 8e8fcc29f510efa03ce194ad3a1e2ae3fbd7f8e04ab5a4a2d1db03e95f388446 lib/codeql/rust/elements/internal/GenericParamListConstructor.qll 7221146d1724e0add3a8e70e0e46670142589eb7143425e1871ac4358a8c8bdb 2fbb7576444d6b2da6164245e2660d592d276ae2c1ca9f2bda5656b1c5c0a73a lib/codeql/rust/elements/internal/GenericParamListImpl.qll 524aa0949df6d4d2cb9bee6226650f63a6f181d7644933fa265673b281074885 27b0210e5eaa2040bc8a093e35e1394befb6994b25369544738d0447ef269a9c @@ -244,7 +243,6 @@ lib/codeql/rust/elements/internal/ImplTraitTypeConstructor.qll b47501280b026a4e9 lib/codeql/rust/elements/internal/ImplTraitTypeImpl.qll 9826a676525c98c30019f62f3c5943b4f62f278ed738dcc023d15f82f36a9d32 da369a61b95685c29fce3c07082d2a58ab633d526d094fa9eaefa82f564609f6 lib/codeql/rust/elements/internal/IndexExprConstructor.qll 99bdc3d793c4dbd993860da60abe2b7c604345d645e86916462bc55a6939a5d1 3fe9d7da725956903707806aadbecac8d5b3874e8bed63c9bab54fff630e75dd lib/codeql/rust/elements/internal/InferTypeConstructor.qll fb8f2aec6cd1e681cd84a7bd574459e19b9b2a152009290e2eac550f012a06b7 e2b1694f00a4e6a82b13d08d7bb95c98a73792370c1155263d696e60d39b2c3b -lib/codeql/rust/elements/internal/InferTypeImpl.qll 9d0bf471a7e0c2671aae52cebadc763ed13e6a62451bf22da3061d7781d8f0bf 4e9e218862e48700523d882eb64d24135289216653cf92195f74eb8a35f50d7c lib/codeql/rust/elements/internal/ItemImpl.qll 3eaa97dcbdb8870acaebc1e11a37a5cfdfa200751461e54d3a52ca48b90ba9bd 41fbd1110b0e24f4d5a3deee0a51c02d206178111a361a1e94501ca1ab70d7f7 lib/codeql/rust/elements/internal/ItemListConstructor.qll 08af3bd12536941c3dd4a43c81cc861be24325e242e2593c087a3ce632674291 2fa166159c409d2aaffa73a30babb40829a6de580bd40894d909ee6152801082 lib/codeql/rust/elements/internal/ItemListImpl.qll fb27417bb3ee17a739ae966dd7c6f382bc2a1de3e7efdfe1586d76a257c0b573 dee7ded650df8ef46b2ac9d472718536fd76dffee86bc208b5a6144060221886 @@ -518,13 +516,13 @@ lib/codeql/rust/elements/internal/generated/PathExpr.qll 2096e3c1db22ee488a76169 lib/codeql/rust/elements/internal/generated/PathExprBase.qll d8218e201b8557fa6d9ca2c30b764e5ad9a04a2e4fb695cc7219bbd7636a6ac2 4ef178426d7095a156f4f8c459b4d16f63abc64336cb50a6cf883a5f7ee09113 lib/codeql/rust/elements/internal/generated/PathPat.qll 98c9938d6a359fd717829b196eb09701d2c798e18c1f43fa7b2a9145afdf6c19 caba2e629cae08682baac90a76ae9a48cda2d7d6f9c23d506fa0ff3f292978a4 lib/codeql/rust/elements/internal/generated/PathSegment.qll 0fa07886deb0fc4d909d7edf691238a344f2739900aafb168cbac171eb1729a8 8f4bb418d8bea5e40128a87977c57d0a9183d06d111601ad93130c8615c11465 -lib/codeql/rust/elements/internal/generated/PathType.qll 45de78e5374d6eb0446e2112ec72d3692c2811df9fa2ad03d0127e426940abe3 622cf70408413a565a0dac58f451035ac1339c8d0ee5b24f630680201cb0aa48 +lib/codeql/rust/elements/internal/generated/PathType.qll df6fd322ba0d99d6cb315edce8dbf099b661b84fdfcc3ad629fdd1fd066c1986 e11c8615cd7b02034b47b58f30a7b6fcbc6d33ec53303288dfd34d9a25f5a186 lib/codeql/rust/elements/internal/generated/PrefixExpr.qll c9ede5f2deb7b41bc8240969e8554f645057018fe96e7e9ad9c2924c8b14722b 5ae2e3c3dc8fa73e7026ef6534185afa6b0b5051804435d8b741dd3640c864e1 lib/codeql/rust/elements/internal/generated/PtrType.qll 40099c5a4041314b66932dfd777c9e2bef90a0711fb8d7c2c2cec764c003ac4a cf8297d93557356a572223d3e8acca701837c4b1f54e8d4351ba195fb7ed27f8 lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll efd93730de217cf50dcba5875595263a5eadf9f7e4e1272401342a094d158614 229b251b3d118932e31e78ac4dfb75f48b766f240f20d436062785606d44467b -lib/codeql/rust/elements/internal/generated/Raw.qll fd2eeb93f84b668f5083ecad8ff5f5d4bbdfcf4c65f4a40907aca47e33b031d6 de433b9feec8276ed34d106b97c7b66d81206a21a2b5343253f4cf799f1bf567 +lib/codeql/rust/elements/internal/generated/Raw.qll b534b0f2318a3a15d27cfa1d2d98ad4ef778b48edf2d36b49c56cf350a0f8328 baf18167656d407fc496ed222fcc9766030b018651f8bc4e2801a1ccbbfb29d6 lib/codeql/rust/elements/internal/generated/RecordExpr.qll eb6cb662e463f9260efae1a6ce874fa781172063b916ef1963f861e9942d308d 1a21cbccc8f3799ff13281e822818ebfb21d81591720a427cac3625512cb9d40 lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1 lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index f83cefce87b..eaefca5a2c1 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -235,7 +235,6 @@ /lib/codeql/rust/elements/internal/FunctionConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/GenericArgImpl.qll linguist-generated /lib/codeql/rust/elements/internal/GenericArgListConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/GenericArgListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/GenericParamImpl.qll linguist-generated /lib/codeql/rust/elements/internal/GenericParamListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/GenericParamListImpl.qll linguist-generated @@ -246,7 +245,6 @@ /lib/codeql/rust/elements/internal/ImplTraitTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/IndexExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/InferTypeConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/InferTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ItemImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ItemListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ItemListImpl.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/elements/PathType.qll b/rust/ql/lib/codeql/rust/elements/PathType.qll index e313b9d1b56..773fe910bfa 100644 --- a/rust/ql/lib/codeql/rust/elements/PathType.qll +++ b/rust/ql/lib/codeql/rust/elements/PathType.qll @@ -8,9 +8,10 @@ import codeql.rust.elements.Path import codeql.rust.elements.TypeRef /** - * A PathType. For example: + * A type referring to a path. For example: * ```rust - * todo!() + * type X = std::collections::HashMap; + * type Y = X::Item; * ``` */ final class PathType = Impl::PathType; diff --git a/rust/ql/lib/codeql/rust/elements/internal/GenericArgListImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/GenericArgListImpl.qll index 44d74bffbc6..a701801b68c 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/GenericArgListImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/GenericArgListImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `GenericArgList`. * @@ -12,11 +11,16 @@ private import codeql.rust.elements.internal.generated.GenericArgList * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * The base class for generic arguments. * ```rust * x.foo::(42); * ``` */ - class GenericArgList extends Generated::GenericArgList { } + class GenericArgList extends Generated::GenericArgList { + override string toString() { result = this.toAbbreviatedString() } + + override string toAbbreviatedString() { result = "<...>" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/InferTypeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/InferTypeImpl.qll index b29406661ba..25c1a40701f 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/InferTypeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/InferTypeImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `InferType`. * @@ -12,11 +11,16 @@ private import codeql.rust.elements.internal.generated.InferType * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A InferType. For example: * ```rust * todo!() * ``` */ - class InferType extends Generated::InferType { } + class InferType extends Generated::InferType { + override string toString() { result = this.toAbbreviatedString() } + + override string toAbbreviatedString() { result = "_" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/PathSegmentImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/PathSegmentImpl.qll index 01ce5878834..7f586afa375 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/PathSegmentImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/PathSegmentImpl.qll @@ -19,17 +19,16 @@ module Impl { override string toString() { result = this.toAbbreviatedString() } override string toAbbreviatedString() { - result = this.getAbbreviatedPrefix() + this.getAbbreviatedGenericArgList() + result = strictconcat(int i | | this.toAbbreviatedStringPart(i), "::" order by i) } - private string getAbbreviatedGenericArgList() { - if this.hasGenericArgList() then result = "::<...>" else result = "" - } - - private string getAbbreviatedPrefix() { + private string toAbbreviatedStringPart(int index) { + index = 0 and if this.hasPathType() or this.hasTy() then result = "<...>" else result = this.getNameRef().getText() + or + index = 1 and result = this.getGenericArgList().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll index a2ca1752cca..02d8a98d42a 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/PathTypeImpl.qll @@ -13,16 +13,15 @@ private import codeql.rust.elements.internal.generated.PathType module Impl { // the following QLdoc is generated: if you need to edit it, do it in the schema file /** - * A PathType. For example: + * A type referring to a path. For example: * ```rust - * todo!() + * type X = std::collections::HashMap; + * type Y = X::Item; * ``` */ class PathType extends Generated::PathType { override string toString() { result = this.toAbbreviatedString() } - override string toAbbreviatedString() { - result = "<" + this.getPath().toAbbreviatedString() + ">" - } + override string toAbbreviatedString() { result = this.getPath().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/PathType.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/PathType.qll index 3ac799108cc..13d7957c40e 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/PathType.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/PathType.qll @@ -15,9 +15,10 @@ import codeql.rust.elements.internal.TypeRefImpl::Impl as TypeRefImpl */ module Generated { /** - * A PathType. For example: + * A type referring to a path. For example: * ```rust - * todo!() + * type X = std::collections::HashMap; + * type Y = X::Item; * ``` * INTERNAL: Do not reference the `Generated::PathType` class directly. * Use the subclass `PathType`, where the following predicates are available. diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index 90fc0ae935b..3ab5808bad3 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -2379,9 +2379,10 @@ module Raw { /** * INTERNAL: Do not use. - * A PathType. For example: + * A type referring to a path. For example: * ```rust - * todo!() + * type X = std::collections::HashMap; + * type Y = X::Item; * ``` */ class PathType extends @path_type, TypeRef { diff --git a/rust/ql/test/extractor-tests/generated/.generated_tests.list b/rust/ql/test/extractor-tests/generated/.generated_tests.list index e8221c66efd..7e6f2cb6589 100644 --- a/rust/ql/test/extractor-tests/generated/.generated_tests.list +++ b/rust/ql/test/extractor-tests/generated/.generated_tests.list @@ -81,7 +81,7 @@ ParenType/gen_paren_type.rs ae1a945b56020eab14bb0ef75ae9ccb735d8e45d1213adee210a Path/gen_path.rs 490268d6bfb1635883b8bdefc683d59c4dd0e9c7f86c2e55954661efb3ab0253 490268d6bfb1635883b8bdefc683d59c4dd0e9c7f86c2e55954661efb3ab0253 Path/gen_path_expr.rs a1e0ececfe62a63a43583c9bd8064a80a90c042c55bac29d86776c0c6559f33a a1e0ececfe62a63a43583c9bd8064a80a90c042c55bac29d86776c0c6559f33a Path/gen_path_pat.rs fd7f941f8b33f19d3693be1fdb595c2fb2e85e8296702b82bf12bcd44632f371 fd7f941f8b33f19d3693be1fdb595c2fb2e85e8296702b82bf12bcd44632f371 -Path/gen_path_type.rs 710a5505615769da940202e7c6d9031edc23a4b05cd9fb25241c60affbba4027 710a5505615769da940202e7c6d9031edc23a4b05cd9fb25241c60affbba4027 +Path/gen_path_type.rs 210f2ce4000b59d2f908801c22c5497a0f0c9a3b1a5130e7dad0931430f49eb9 210f2ce4000b59d2f908801c22c5497a0f0c9a3b1a5130e7dad0931430f49eb9 PrefixExpr/gen_prefix_expr.rs c4b53e87f370713b9a9e257be26d082b0761497bac19b1d7401a31b22b30d1ab c4b53e87f370713b9a9e257be26d082b0761497bac19b1d7401a31b22b30d1ab PtrType/gen_ptr_type.rs dd7faad19454b92d7942ef664df1a5f26c01863e408b87249aa4d5d4f68c78b3 dd7faad19454b92d7942ef664df1a5f26c01863e408b87249aa4d5d4f68c78b3 RangeExpr/gen_range_expr.rs 3f27cff9cc76b2703beff622d1453b84121e1970a869e45f9428deac92c4ecb0 3f27cff9cc76b2703beff622d1453b84121e1970a869e45f9428deac92c4ecb0 diff --git a/rust/ql/test/extractor-tests/generated/Path/Path.expected b/rust/ql/test/extractor-tests/generated/Path/Path.expected index 42f266cb4ed..dfc303c3293 100644 --- a/rust/ql/test/extractor-tests/generated/Path/Path.expected +++ b/rust/ql/test/extractor-tests/generated/Path/Path.expected @@ -17,7 +17,10 @@ | gen_path_pat.rs:5:11:5:11 | x | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | | gen_path_pat.rs:6:9:6:11 | Foo | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | | gen_path_pat.rs:6:9:6:16 | ...::Bar | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | yes | hasPart: | yes | -| gen_path_type.rs:5:5:5:8 | todo | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | -| gen_path_type.rs:5:5:5:11 | $crate | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | -| gen_path_type.rs:5:5:5:11 | ...::panic | hasResolvedPath: | yes | hasResolvedCrateOrigin: | yes | hasQualifier: | yes | hasPart: | yes | -| gen_path_type.rs:5:5:5:11 | ...::panicking | hasResolvedPath: | yes | hasResolvedCrateOrigin: | yes | hasQualifier: | yes | hasPart: | yes | +| gen_path_type.rs:5:14:5:16 | std | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_type.rs:5:14:5:29 | ...::collections | hasResolvedPath: | yes | hasResolvedCrateOrigin: | yes | hasQualifier: | yes | hasPart: | yes | +| gen_path_type.rs:5:14:5:48 | ...::HashMap::<...> | hasResolvedPath: | yes | hasResolvedCrateOrigin: | yes | hasQualifier: | yes | hasPart: | yes | +| gen_path_type.rs:5:40:5:42 | i32 | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_type.rs:5:45:5:47 | i32 | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_type.rs:6:14:6:14 | X | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | no | hasPart: | yes | +| gen_path_type.rs:6:14:6:20 | ...::Item | hasResolvedPath: | no | hasResolvedCrateOrigin: | no | hasQualifier: | yes | hasPart: | yes | diff --git a/rust/ql/test/extractor-tests/generated/Path/PathExpr.expected b/rust/ql/test/extractor-tests/generated/Path/PathExpr.expected index c84497c6881..4f6def5dd43 100644 --- a/rust/ql/test/extractor-tests/generated/Path/PathExpr.expected +++ b/rust/ql/test/extractor-tests/generated/Path/PathExpr.expected @@ -4,4 +4,3 @@ | gen_path_expr.rs:7:13:7:20 | ...::foo | getNumberOfAttrs: | 0 | hasPath: | yes | | gen_path_expr.rs:8:13:8:35 | ...::foo | getNumberOfAttrs: | 0 | hasPath: | yes | | gen_path_pat.rs:5:11:5:11 | x | getNumberOfAttrs: | 0 | hasPath: | yes | -| gen_path_type.rs:5:5:5:11 | ...::panic | getNumberOfAttrs: | 0 | hasPath: | yes | diff --git a/rust/ql/test/extractor-tests/generated/Path/PathExpr_getPath.expected b/rust/ql/test/extractor-tests/generated/Path/PathExpr_getPath.expected index 925412bc616..31b98a6a8ec 100644 --- a/rust/ql/test/extractor-tests/generated/Path/PathExpr_getPath.expected +++ b/rust/ql/test/extractor-tests/generated/Path/PathExpr_getPath.expected @@ -4,4 +4,3 @@ | gen_path_expr.rs:7:13:7:20 | ...::foo | gen_path_expr.rs:7:13:7:20 | ...::foo | | gen_path_expr.rs:8:13:8:35 | ...::foo | gen_path_expr.rs:8:13:8:35 | ...::foo | | gen_path_pat.rs:5:11:5:11 | x | gen_path_pat.rs:5:11:5:11 | x | -| gen_path_type.rs:5:5:5:11 | ...::panic | gen_path_type.rs:5:5:5:11 | ...::panic | diff --git a/rust/ql/test/extractor-tests/generated/Path/PathSegment.expected b/rust/ql/test/extractor-tests/generated/Path/PathSegment.expected index 41889509341..8278d7685dc 100644 --- a/rust/ql/test/extractor-tests/generated/Path/PathSegment.expected +++ b/rust/ql/test/extractor-tests/generated/Path/PathSegment.expected @@ -17,7 +17,10 @@ | gen_path_pat.rs:5:11:5:11 | x | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | | gen_path_pat.rs:6:9:6:11 | Foo | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | | gen_path_pat.rs:6:14:6:16 | Bar | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | -| gen_path_type.rs:5:5:5:8 | todo | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | -| gen_path_type.rs:5:5:5:11 | $crate | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | -| gen_path_type.rs:5:5:5:11 | panic | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | -| gen_path_type.rs:5:5:5:11 | panicking | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_type.rs:5:14:5:16 | std | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_type.rs:5:19:5:29 | collections | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_type.rs:5:32:5:48 | HashMap::<...> | hasGenericArgList: | yes | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_type.rs:5:40:5:42 | i32 | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_type.rs:5:45:5:47 | i32 | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_type.rs:6:14:6:14 | X | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | +| gen_path_type.rs:6:17:6:20 | Item | hasGenericArgList: | no | hasNameRef: | yes | hasParamList: | no | hasPathType: | no | hasRetType: | no | hasReturnTypeSyntax: | no | hasTy: | no | diff --git a/rust/ql/test/extractor-tests/generated/Path/PathSegment_getGenericArgList.expected b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getGenericArgList.expected index e69de29bb2d..7487eb65c84 100644 --- a/rust/ql/test/extractor-tests/generated/Path/PathSegment_getGenericArgList.expected +++ b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getGenericArgList.expected @@ -0,0 +1 @@ +| gen_path_type.rs:5:32:5:48 | HashMap::<...> | gen_path_type.rs:5:39:5:48 | <...> | diff --git a/rust/ql/test/extractor-tests/generated/Path/PathSegment_getNameRef.expected b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getNameRef.expected index e6b487851b7..8778f6b4aef 100644 --- a/rust/ql/test/extractor-tests/generated/Path/PathSegment_getNameRef.expected +++ b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getNameRef.expected @@ -15,7 +15,10 @@ | gen_path_pat.rs:5:11:5:11 | x | gen_path_pat.rs:5:11:5:11 | x | | gen_path_pat.rs:6:9:6:11 | Foo | gen_path_pat.rs:6:9:6:11 | Foo | | gen_path_pat.rs:6:14:6:16 | Bar | gen_path_pat.rs:6:14:6:16 | Bar | -| gen_path_type.rs:5:5:5:8 | todo | gen_path_type.rs:5:5:5:8 | todo | -| gen_path_type.rs:5:5:5:11 | $crate | gen_path_type.rs:5:5:5:11 | $crate | -| gen_path_type.rs:5:5:5:11 | panic | gen_path_type.rs:5:5:5:11 | panic | -| gen_path_type.rs:5:5:5:11 | panicking | gen_path_type.rs:5:5:5:11 | panicking | +| gen_path_type.rs:5:14:5:16 | std | gen_path_type.rs:5:14:5:16 | std | +| gen_path_type.rs:5:19:5:29 | collections | gen_path_type.rs:5:19:5:29 | collections | +| gen_path_type.rs:5:32:5:48 | HashMap::<...> | gen_path_type.rs:5:32:5:38 | HashMap | +| gen_path_type.rs:5:40:5:42 | i32 | gen_path_type.rs:5:40:5:42 | i32 | +| gen_path_type.rs:5:45:5:47 | i32 | gen_path_type.rs:5:45:5:47 | i32 | +| gen_path_type.rs:6:14:6:14 | X | gen_path_type.rs:6:14:6:14 | X | +| gen_path_type.rs:6:17:6:20 | Item | gen_path_type.rs:6:17:6:20 | Item | diff --git a/rust/ql/test/extractor-tests/generated/Path/PathSegment_getPathType.expected b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getPathType.expected index b63a629ccb1..db25db90b83 100644 --- a/rust/ql/test/extractor-tests/generated/Path/PathSegment_getPathType.expected +++ b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getPathType.expected @@ -1,2 +1,2 @@ -| gen_path_expr.rs:7:13:7:15 | <...> | gen_path_expr.rs:7:14:7:14 | | -| gen_path_expr.rs:8:13:8:30 | <...> | gen_path_expr.rs:8:14:8:20 | | +| gen_path_expr.rs:7:13:7:15 | <...> | gen_path_expr.rs:7:14:7:14 | T | +| gen_path_expr.rs:8:13:8:30 | <...> | gen_path_expr.rs:8:14:8:20 | TypeRef | diff --git a/rust/ql/test/extractor-tests/generated/Path/PathSegment_getTy.expected b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getTy.expected index b63a629ccb1..db25db90b83 100644 --- a/rust/ql/test/extractor-tests/generated/Path/PathSegment_getTy.expected +++ b/rust/ql/test/extractor-tests/generated/Path/PathSegment_getTy.expected @@ -1,2 +1,2 @@ -| gen_path_expr.rs:7:13:7:15 | <...> | gen_path_expr.rs:7:14:7:14 | | -| gen_path_expr.rs:8:13:8:30 | <...> | gen_path_expr.rs:8:14:8:20 | | +| gen_path_expr.rs:7:13:7:15 | <...> | gen_path_expr.rs:7:14:7:14 | T | +| gen_path_expr.rs:8:13:8:30 | <...> | gen_path_expr.rs:8:14:8:20 | TypeRef | diff --git a/rust/ql/test/extractor-tests/generated/Path/PathType.expected b/rust/ql/test/extractor-tests/generated/Path/PathType.expected index 5347001fb41..7d876dc4fa8 100644 --- a/rust/ql/test/extractor-tests/generated/Path/PathType.expected +++ b/rust/ql/test/extractor-tests/generated/Path/PathType.expected @@ -1,4 +1,8 @@ -| gen_path_expr.rs:7:14:7:14 | | hasPath: | yes | -| gen_path_expr.rs:7:14:7:14 | | hasPath: | yes | -| gen_path_expr.rs:8:14:8:20 | | hasPath: | yes | -| gen_path_expr.rs:8:14:8:20 | | hasPath: | yes | +| gen_path_expr.rs:7:14:7:14 | T | hasPath: | yes | +| gen_path_expr.rs:7:14:7:14 | T | hasPath: | yes | +| gen_path_expr.rs:8:14:8:20 | TypeRef | hasPath: | yes | +| gen_path_expr.rs:8:14:8:20 | TypeRef | hasPath: | yes | +| gen_path_type.rs:5:14:5:48 | ...::HashMap::<...> | hasPath: | yes | +| gen_path_type.rs:5:40:5:42 | i32 | hasPath: | yes | +| gen_path_type.rs:5:45:5:47 | i32 | hasPath: | yes | +| gen_path_type.rs:6:14:6:20 | ...::Item | hasPath: | yes | diff --git a/rust/ql/test/extractor-tests/generated/Path/PathType_getPath.expected b/rust/ql/test/extractor-tests/generated/Path/PathType_getPath.expected index 3d98da0c2b8..879ed298b93 100644 --- a/rust/ql/test/extractor-tests/generated/Path/PathType_getPath.expected +++ b/rust/ql/test/extractor-tests/generated/Path/PathType_getPath.expected @@ -1,4 +1,8 @@ -| gen_path_expr.rs:7:14:7:14 | | gen_path_expr.rs:7:14:7:14 | T | -| gen_path_expr.rs:7:14:7:14 | | gen_path_expr.rs:7:14:7:14 | T | -| gen_path_expr.rs:8:14:8:20 | | gen_path_expr.rs:8:14:8:20 | TypeRef | -| gen_path_expr.rs:8:14:8:20 | | gen_path_expr.rs:8:14:8:20 | TypeRef | +| gen_path_expr.rs:7:14:7:14 | T | gen_path_expr.rs:7:14:7:14 | T | +| gen_path_expr.rs:7:14:7:14 | T | gen_path_expr.rs:7:14:7:14 | T | +| gen_path_expr.rs:8:14:8:20 | TypeRef | gen_path_expr.rs:8:14:8:20 | TypeRef | +| gen_path_expr.rs:8:14:8:20 | TypeRef | gen_path_expr.rs:8:14:8:20 | TypeRef | +| gen_path_type.rs:5:14:5:48 | ...::HashMap::<...> | gen_path_type.rs:5:14:5:48 | ...::HashMap::<...> | +| gen_path_type.rs:5:40:5:42 | i32 | gen_path_type.rs:5:40:5:42 | i32 | +| gen_path_type.rs:5:45:5:47 | i32 | gen_path_type.rs:5:45:5:47 | i32 | +| gen_path_type.rs:6:14:6:20 | ...::Item | gen_path_type.rs:6:14:6:20 | ...::Item | diff --git a/rust/ql/test/extractor-tests/generated/Path/Path_getPart.expected b/rust/ql/test/extractor-tests/generated/Path/Path_getPart.expected index 9b0f05f0727..99ed98b3f52 100644 --- a/rust/ql/test/extractor-tests/generated/Path/Path_getPart.expected +++ b/rust/ql/test/extractor-tests/generated/Path/Path_getPart.expected @@ -17,7 +17,10 @@ | gen_path_pat.rs:5:11:5:11 | x | gen_path_pat.rs:5:11:5:11 | x | | gen_path_pat.rs:6:9:6:11 | Foo | gen_path_pat.rs:6:9:6:11 | Foo | | gen_path_pat.rs:6:9:6:16 | ...::Bar | gen_path_pat.rs:6:14:6:16 | Bar | -| gen_path_type.rs:5:5:5:8 | todo | gen_path_type.rs:5:5:5:8 | todo | -| gen_path_type.rs:5:5:5:11 | $crate | gen_path_type.rs:5:5:5:11 | $crate | -| gen_path_type.rs:5:5:5:11 | ...::panic | gen_path_type.rs:5:5:5:11 | panic | -| gen_path_type.rs:5:5:5:11 | ...::panicking | gen_path_type.rs:5:5:5:11 | panicking | +| gen_path_type.rs:5:14:5:16 | std | gen_path_type.rs:5:14:5:16 | std | +| gen_path_type.rs:5:14:5:29 | ...::collections | gen_path_type.rs:5:19:5:29 | collections | +| gen_path_type.rs:5:14:5:48 | ...::HashMap::<...> | gen_path_type.rs:5:32:5:48 | HashMap::<...> | +| gen_path_type.rs:5:40:5:42 | i32 | gen_path_type.rs:5:40:5:42 | i32 | +| gen_path_type.rs:5:45:5:47 | i32 | gen_path_type.rs:5:45:5:47 | i32 | +| gen_path_type.rs:6:14:6:14 | X | gen_path_type.rs:6:14:6:14 | X | +| gen_path_type.rs:6:14:6:20 | ...::Item | gen_path_type.rs:6:17:6:20 | Item | diff --git a/rust/ql/test/extractor-tests/generated/Path/Path_getQualifier.expected b/rust/ql/test/extractor-tests/generated/Path/Path_getQualifier.expected index 6fb72c5159a..162efd4b187 100644 --- a/rust/ql/test/extractor-tests/generated/Path/Path_getQualifier.expected +++ b/rust/ql/test/extractor-tests/generated/Path/Path_getQualifier.expected @@ -5,5 +5,6 @@ | gen_path_expr.rs:7:13:7:20 | ...::foo | gen_path_expr.rs:7:13:7:15 | <...> | | gen_path_expr.rs:8:13:8:35 | ...::foo | gen_path_expr.rs:8:13:8:30 | <...> | | gen_path_pat.rs:6:9:6:16 | ...::Bar | gen_path_pat.rs:6:9:6:11 | Foo | -| gen_path_type.rs:5:5:5:11 | ...::panic | gen_path_type.rs:5:5:5:11 | ...::panicking | -| gen_path_type.rs:5:5:5:11 | ...::panicking | gen_path_type.rs:5:5:5:11 | $crate | +| gen_path_type.rs:5:14:5:29 | ...::collections | gen_path_type.rs:5:14:5:16 | std | +| gen_path_type.rs:5:14:5:48 | ...::HashMap::<...> | gen_path_type.rs:5:14:5:29 | ...::collections | +| gen_path_type.rs:6:14:6:20 | ...::Item | gen_path_type.rs:6:14:6:14 | X | diff --git a/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedCrateOrigin.expected b/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedCrateOrigin.expected index 9da37a05d71..df80e22f744 100644 --- a/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedCrateOrigin.expected +++ b/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedCrateOrigin.expected @@ -1,2 +1,2 @@ -| gen_path_type.rs:5:5:5:11 | ...::panic | lang:core | -| gen_path_type.rs:5:5:5:11 | ...::panicking | lang:core | +| gen_path_type.rs:5:14:5:29 | ...::collections | lang:std | +| gen_path_type.rs:5:14:5:48 | ...::HashMap::<...> | lang:std | diff --git a/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedPath.expected b/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedPath.expected index 4a7a9a1e2ae..7d1c698b0ce 100644 --- a/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedPath.expected +++ b/rust/ql/test/extractor-tests/generated/Path/Path_getResolvedPath.expected @@ -1,2 +1,2 @@ -| gen_path_type.rs:5:5:5:11 | ...::panic | crate::panicking::panic | -| gen_path_type.rs:5:5:5:11 | ...::panicking | crate::panicking | +| gen_path_type.rs:5:14:5:29 | ...::collections | crate::collections | +| gen_path_type.rs:5:14:5:48 | ...::HashMap::<...> | crate::collections::hash::map::HashMap | diff --git a/rust/ql/test/extractor-tests/generated/Path/gen_path_type.rs b/rust/ql/test/extractor-tests/generated/Path/gen_path_type.rs index e7666e2128a..62797d75677 100644 --- a/rust/ql/test/extractor-tests/generated/Path/gen_path_type.rs +++ b/rust/ql/test/extractor-tests/generated/Path/gen_path_type.rs @@ -1,6 +1,7 @@ // generated by codegen, do not edit fn test_path_type() -> () { - // A PathType. For example: - todo!() + // A type referring to a path. For example: + type X = std::collections::HashMap; + type Y = X::Item; } diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index d716b3370fb..a0292876eab 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -1380,9 +1380,10 @@ class _: @qltest.test_with(Path) class _: """ - A PathType. For example: + A type referring to a path. For example: ```rust - todo!() + type X = std::collections::HashMap; + type Y = X::Item; ``` """ From a82d2672233e5199a3097c213b2d8544954e5b50 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Nov 2024 16:03:56 +0100 Subject: [PATCH 168/470] Rust: accept test changes --- .../canonical_path/canonical_paths.expected | 12 +- .../generated/CastExpr/CastExpr.expected | 2 +- .../CastExpr/CastExpr_getExpr.expected | 2 +- .../CastExpr/CastExpr_getTy.expected | 2 +- .../GenericArgList/GenericArgList.expected | 2 +- .../GenericArgList_getGenericArg.expected | 4 +- .../generated/LetStmt/LetStmt_getTy.expected | 4 +- .../MethodCallExpr_getGenericArgList.expected | 2 +- .../OffsetOfExpr/OffsetOfExpr_getTy.expected | 2 +- .../ql/test/extractor-tests/utf8/ast.expected | 2 +- .../controlflow-unstable/Cfg.expected | 24 +-- .../library-tests/controlflow/Cfg.expected | 204 +++++++++--------- .../test/library-tests/variables/Cfg.expected | 28 +-- 13 files changed, 145 insertions(+), 145 deletions(-) diff --git a/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected b/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected index c65eaaff234..94bcc7379d9 100644 --- a/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected +++ b/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected @@ -3,13 +3,13 @@ canonicalPaths | canonical_paths.rs:2:5:3:22 | Struct | repo::test | crate::canonical_paths::a::Struct | | canonical_paths.rs:5:5:7:5 | trait Trait | repo::test | crate::canonical_paths::a::Trait | | canonical_paths.rs:6:9:6:20 | fn f | repo::test | crate::canonical_paths::a::Trait::f | -| canonical_paths.rs:9:5:11:5 | impl for { ... } | None | None | +| canonical_paths.rs:9:5:11:5 | impl Trait for Struct { ... } | None | None | | canonical_paths.rs:10:9:10:22 | fn f | repo::test | ::f | -| canonical_paths.rs:13:5:15:5 | impl { ... } | None | None | +| canonical_paths.rs:13:5:15:5 | impl Struct { ... } | None | None | | canonical_paths.rs:14:9:14:22 | fn g | repo::test | ::g | | canonical_paths.rs:17:5:19:5 | trait TraitWithBlanketImpl | repo::test | crate::canonical_paths::a::TraitWithBlanketImpl | | canonical_paths.rs:18:9:18:20 | fn h | repo::test | crate::canonical_paths::a::TraitWithBlanketImpl::h | -| canonical_paths.rs:21:5:23:5 | impl for { ... } | None | None | +| canonical_paths.rs:21:5:23:5 | impl TraitWithBlanketImpl for T { ... } | None | None | | canonical_paths.rs:22:9:22:22 | fn h | repo::test | <_ as crate::canonical_paths::a::TraitWithBlanketImpl>::h | | canonical_paths.rs:25:5:25:16 | fn free | repo::test | crate::canonical_paths::a::free | | canonical_paths.rs:27:5:33:5 | fn usage | repo::test | crate::canonical_paths::a::usage | @@ -19,11 +19,11 @@ canonicalPaths | canonical_paths.rs:40:9:40:27 | Struct | repo::test | {34}::OtherStruct | | canonical_paths.rs:42:9:44:9 | trait OtherTrait | repo::test | {34}::OtherTrait | | canonical_paths.rs:43:13:43:24 | fn g | repo::test | {34}::OtherTrait::g | -| canonical_paths.rs:46:9:48:9 | impl for { ... } | None | None | +| canonical_paths.rs:46:9:48:9 | impl OtherTrait for OtherStruct { ... } | None | None | | canonical_paths.rs:47:13:47:26 | fn g | repo::test | <{34}::OtherStruct as {34}::OtherTrait>::g | -| canonical_paths.rs:50:9:52:9 | impl for <...::Struct> { ... } | None | None | +| canonical_paths.rs:50:9:52:9 | impl OtherTrait for ...::Struct { ... } | None | None | | canonical_paths.rs:51:13:51:26 | fn g | repo::test | ::g | -| canonical_paths.rs:54:9:56:9 | impl <...::Trait> for { ... } | None | None | +| canonical_paths.rs:54:9:56:9 | impl ...::Trait for OtherStruct { ... } | None | None | | canonical_paths.rs:55:13:55:26 | fn f | repo::test | <{34}::OtherStruct as crate::canonical_paths::a::Trait>::f | | canonical_paths.rs:58:9:60:9 | fn nested | repo::test | {34}::nested | | canonical_paths.rs:59:13:59:31 | Struct | repo::test | {35}::OtherStruct | diff --git a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected index 35cb00b044a..c85e4186631 100644 --- a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr.expected @@ -1 +1 @@ -| gen_cast_expr.rs:5:5:5:16 | value as | getNumberOfAttrs: | 0 | hasExpr: | yes | hasTy: | yes | +| gen_cast_expr.rs:5:5:5:16 | value as u64 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasTy: | yes | diff --git a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected index d3bf1efc8b1..01a710bfb53 100644 --- a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.expected @@ -1 +1 @@ -| gen_cast_expr.rs:5:5:5:16 | value as | gen_cast_expr.rs:5:5:5:9 | value | +| gen_cast_expr.rs:5:5:5:16 | value as u64 | gen_cast_expr.rs:5:5:5:9 | value | diff --git a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected index 4e7fdb1e25c..87c07babb02 100644 --- a/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected +++ b/rust/ql/test/extractor-tests/generated/CastExpr/CastExpr_getTy.expected @@ -1 +1 @@ -| gen_cast_expr.rs:5:5:5:16 | value as | gen_cast_expr.rs:5:14:5:16 | | +| gen_cast_expr.rs:5:5:5:16 | value as u64 | gen_cast_expr.rs:5:14:5:16 | u64 | diff --git a/rust/ql/test/extractor-tests/generated/GenericArgList/GenericArgList.expected b/rust/ql/test/extractor-tests/generated/GenericArgList/GenericArgList.expected index 370ee8ce4d6..d2a5b7bcd8f 100644 --- a/rust/ql/test/extractor-tests/generated/GenericArgList/GenericArgList.expected +++ b/rust/ql/test/extractor-tests/generated/GenericArgList/GenericArgList.expected @@ -1 +1 @@ -| gen_generic_arg_list.rs:5:10:5:21 | GenericArgList | getNumberOfGenericArgs: | 2 | +| gen_generic_arg_list.rs:5:10:5:21 | <...> | getNumberOfGenericArgs: | 2 | diff --git a/rust/ql/test/extractor-tests/generated/GenericArgList/GenericArgList_getGenericArg.expected b/rust/ql/test/extractor-tests/generated/GenericArgList/GenericArgList_getGenericArg.expected index b72d3035ed1..69e416a57ad 100644 --- a/rust/ql/test/extractor-tests/generated/GenericArgList/GenericArgList_getGenericArg.expected +++ b/rust/ql/test/extractor-tests/generated/GenericArgList/GenericArgList_getGenericArg.expected @@ -1,2 +1,2 @@ -| gen_generic_arg_list.rs:5:10:5:21 | GenericArgList | 0 | gen_generic_arg_list.rs:5:13:5:15 | TypeArg | -| gen_generic_arg_list.rs:5:10:5:21 | GenericArgList | 1 | gen_generic_arg_list.rs:5:18:5:20 | TypeArg | +| gen_generic_arg_list.rs:5:10:5:21 | <...> | 0 | gen_generic_arg_list.rs:5:13:5:15 | TypeArg | +| gen_generic_arg_list.rs:5:10:5:21 | <...> | 1 | gen_generic_arg_list.rs:5:18:5:20 | TypeArg | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected index b917fcb8c7c..489647f4793 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getTy.expected @@ -1,2 +1,2 @@ -| gen_let_stmt.rs:6:5:6:20 | let ... = 42 | gen_let_stmt.rs:6:12:6:14 | | -| gen_let_stmt.rs:7:5:7:15 | let ... | gen_let_stmt.rs:7:12:7:14 | | +| gen_let_stmt.rs:6:5:6:20 | let ... = 42 | gen_let_stmt.rs:6:12:6:14 | i32 | +| gen_let_stmt.rs:7:5:7:15 | let ... | gen_let_stmt.rs:7:12:7:14 | i32 | diff --git a/rust/ql/test/extractor-tests/generated/MethodCallExpr/MethodCallExpr_getGenericArgList.expected b/rust/ql/test/extractor-tests/generated/MethodCallExpr/MethodCallExpr_getGenericArgList.expected index 8b2622f09ab..dd1ed8c0304 100644 --- a/rust/ql/test/extractor-tests/generated/MethodCallExpr/MethodCallExpr_getGenericArgList.expected +++ b/rust/ql/test/extractor-tests/generated/MethodCallExpr/MethodCallExpr_getGenericArgList.expected @@ -1 +1 @@ -| gen_method_call_expr.rs:6:5:6:25 | ... .foo(...) | gen_method_call_expr.rs:6:10:6:21 | GenericArgList | +| gen_method_call_expr.rs:6:5:6:25 | ... .foo(...) | gen_method_call_expr.rs:6:10:6:21 | <...> | diff --git a/rust/ql/test/extractor-tests/generated/OffsetOfExpr/OffsetOfExpr_getTy.expected b/rust/ql/test/extractor-tests/generated/OffsetOfExpr/OffsetOfExpr_getTy.expected index f6ab8a92aff..e2e11abb6a0 100644 --- a/rust/ql/test/extractor-tests/generated/OffsetOfExpr/OffsetOfExpr_getTy.expected +++ b/rust/ql/test/extractor-tests/generated/OffsetOfExpr/OffsetOfExpr_getTy.expected @@ -1 +1 @@ -| gen_offset_of_expr.rs:5:5:5:38 | OffsetOfExpr | gen_offset_of_expr.rs:5:25:5:30 | | +| gen_offset_of_expr.rs:5:5:5:38 | OffsetOfExpr | gen_offset_of_expr.rs:5:25:5:30 | Struct | diff --git a/rust/ql/test/extractor-tests/utf8/ast.expected b/rust/ql/test/extractor-tests/utf8/ast.expected index e1d0418c206..560f834766e 100644 --- a/rust/ql/test/extractor-tests/utf8/ast.expected +++ b/rust/ql/test/extractor-tests/utf8/ast.expected @@ -17,7 +17,7 @@ | utf8_identifiers.rs:6:10:8:1 | RecordFieldList | | utf8_identifiers.rs:7:5:7:5 | \u03b4 | | utf8_identifiers.rs:7:5:7:13 | RecordField | -| utf8_identifiers.rs:7:9:7:13 | | +| utf8_identifiers.rs:7:9:7:13 | usize | | utf8_identifiers.rs:7:9:7:13 | usize | | utf8_identifiers.rs:7:9:7:13 | usize | | utf8_identifiers.rs:7:9:7:13 | usize | diff --git a/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected b/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected index bdc9d30f09c..4260e2384c8 100644 --- a/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow-unstable/Cfg.expected @@ -1,12 +1,12 @@ edges | test.rs:5:5:11:5 | enter fn test_and_if_let | test.rs:5:24:5:24 | a | | | test.rs:5:5:11:5 | exit fn test_and_if_let (normal) | test.rs:5:5:11:5 | exit fn test_and_if_let | | -| test.rs:5:24:5:24 | a | test.rs:5:24:5:30 | ...: | match | -| test.rs:5:24:5:30 | ...: | test.rs:5:33:5:33 | b | | -| test.rs:5:33:5:33 | b | test.rs:5:33:5:47 | ...: > | match | -| test.rs:5:33:5:47 | ...: > | test.rs:5:50:5:50 | c | | -| test.rs:5:50:5:50 | c | test.rs:5:50:5:56 | ...: | match | -| test.rs:5:50:5:56 | ...: | test.rs:6:12:6:12 | a | | +| test.rs:5:24:5:24 | a | test.rs:5:24:5:30 | ...: bool | match | +| test.rs:5:24:5:30 | ...: bool | test.rs:5:33:5:33 | b | | +| test.rs:5:33:5:33 | b | test.rs:5:33:5:47 | ...: Option::<...> | match | +| test.rs:5:33:5:47 | ...: Option::<...> | test.rs:5:50:5:50 | c | | +| test.rs:5:50:5:50 | c | test.rs:5:50:5:56 | ...: bool | match | +| test.rs:5:50:5:56 | ...: bool | test.rs:6:12:6:12 | a | | | test.rs:5:67:11:5 | { ... } | test.rs:5:5:11:5 | exit fn test_and_if_let (normal) | | | test.rs:6:9:10:9 | if ... {...} else {...} | test.rs:5:67:11:5 | { ... } | | | test.rs:6:12:6:12 | a | test.rs:6:12:6:31 | [boolean(false)] ... && ... | false | @@ -24,12 +24,12 @@ edges | test.rs:9:13:9:17 | false | test.rs:8:16:10:9 | { ... } | | | test.rs:13:5:21:5 | enter fn test_and_if_let2 | test.rs:13:25:13:25 | a | | | test.rs:13:5:21:5 | exit fn test_and_if_let2 (normal) | test.rs:13:5:21:5 | exit fn test_and_if_let2 | | -| test.rs:13:25:13:25 | a | test.rs:13:25:13:31 | ...: | match | -| test.rs:13:25:13:31 | ...: | test.rs:13:34:13:34 | b | | -| test.rs:13:34:13:34 | b | test.rs:13:34:13:39 | ...: | match | -| test.rs:13:34:13:39 | ...: | test.rs:13:42:13:42 | c | | -| test.rs:13:42:13:42 | c | test.rs:13:42:13:48 | ...: | match | -| test.rs:13:42:13:48 | ...: | test.rs:14:12:14:12 | a | | +| test.rs:13:25:13:25 | a | test.rs:13:25:13:31 | ...: bool | match | +| test.rs:13:25:13:31 | ...: bool | test.rs:13:34:13:34 | b | | +| test.rs:13:34:13:34 | b | test.rs:13:34:13:39 | ...: i64 | match | +| test.rs:13:34:13:39 | ...: i64 | test.rs:13:42:13:42 | c | | +| test.rs:13:42:13:42 | c | test.rs:13:42:13:48 | ...: bool | match | +| test.rs:13:42:13:48 | ...: bool | test.rs:14:12:14:12 | a | | | test.rs:13:59:21:5 | { ... } | test.rs:13:5:21:5 | exit fn test_and_if_let2 (normal) | | | test.rs:14:9:20:9 | if ... {...} else {...} | test.rs:13:59:21:5 | { ... } | | | test.rs:14:12:14:12 | a | test.rs:14:12:14:25 | [boolean(false)] ... && ... | false | diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 7045c8c3f8b..5137e2f8b89 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -25,8 +25,8 @@ edges | test.rs:12:24:12:26 | "a" | test.rs:12:9:12:27 | ... .insert(...) | | | test.rs:18:5:24:5 | enter fn next | test.rs:18:13:18:13 | n | | | test.rs:18:5:24:5 | exit fn next (normal) | test.rs:18:5:24:5 | exit fn next | | -| test.rs:18:13:18:13 | n | test.rs:18:13:18:18 | ...: | match | -| test.rs:18:13:18:18 | ...: | test.rs:19:12:19:12 | n | | +| test.rs:18:13:18:13 | n | test.rs:18:13:18:18 | ...: i64 | match | +| test.rs:18:13:18:18 | ...: i64 | test.rs:19:12:19:12 | n | | | test.rs:18:28:24:5 | { ... } | test.rs:18:5:24:5 | exit fn next (normal) | | | test.rs:19:9:23:9 | if ... {...} else {...} | test.rs:18:28:24:5 | { ... } | | | test.rs:19:12:19:12 | n | test.rs:19:16:19:16 | 2 | | @@ -47,8 +47,8 @@ edges | test.rs:22:21:22:21 | 1 | test.rs:22:13:22:21 | ... + ... | | | test.rs:26:5:42:5 | enter fn test_break_and_continue | test.rs:26:32:26:32 | n | | | test.rs:26:5:42:5 | exit fn test_break_and_continue (normal) | test.rs:26:5:42:5 | exit fn test_break_and_continue | | -| test.rs:26:32:26:32 | n | test.rs:26:32:26:37 | ...: | match | -| test.rs:26:32:26:37 | ...: | test.rs:27:9:27:22 | let ... = n | | +| test.rs:26:32:26:32 | n | test.rs:26:32:26:37 | ...: i64 | match | +| test.rs:26:32:26:37 | ...: i64 | test.rs:27:9:27:22 | let ... = n | | | test.rs:27:9:27:22 | let ... = n | test.rs:27:21:27:21 | n | | | test.rs:27:13:27:17 | i | test.rs:28:9:40:9 | ExprStmt | match | | test.rs:27:21:27:21 | n | test.rs:27:13:27:17 | i | | @@ -98,8 +98,8 @@ edges | test.rs:41:16:41:19 | true | test.rs:41:9:41:19 | return true | | | test.rs:44:5:56:5 | enter fn test_break_with_labels | test.rs:44:31:44:31 | b | | | test.rs:44:5:56:5 | exit fn test_break_with_labels (normal) | test.rs:44:5:56:5 | exit fn test_break_with_labels | | -| test.rs:44:31:44:31 | b | test.rs:44:31:44:37 | ...: | match | -| test.rs:44:31:44:37 | ...: | test.rs:45:9:54:9 | ExprStmt | | +| test.rs:44:31:44:31 | b | test.rs:44:31:44:37 | ...: bool | match | +| test.rs:44:31:44:37 | ...: bool | test.rs:45:9:54:9 | ExprStmt | | | test.rs:44:48:56:5 | { ... } | test.rs:44:5:56:5 | exit fn test_break_with_labels (normal) | | | test.rs:45:9:54:9 | 'outer: loop { ... } | test.rs:55:9:55:12 | true | | | test.rs:45:9:54:9 | ExprStmt | test.rs:47:17:51:17 | ExprStmt | | @@ -120,8 +120,8 @@ edges | test.rs:52:17:52:29 | ExprStmt | test.rs:52:17:52:28 | break ''inner | | | test.rs:55:9:55:12 | true | test.rs:44:48:56:5 | { ... } | | | test.rs:58:5:70:5 | enter fn test_continue_with_labels | test.rs:58:34:58:34 | b | | -| test.rs:58:34:58:34 | b | test.rs:58:34:58:40 | ...: | match | -| test.rs:58:34:58:40 | ...: | test.rs:60:13:60:14 | ExprStmt | | +| test.rs:58:34:58:34 | b | test.rs:58:34:58:40 | ...: bool | match | +| test.rs:58:34:58:40 | ...: bool | test.rs:60:13:60:14 | ExprStmt | | | test.rs:60:13:60:13 | 1 | test.rs:62:17:66:17 | ExprStmt | | | test.rs:60:13:60:14 | ExprStmt | test.rs:60:13:60:13 | 1 | | | test.rs:62:17:66:17 | ExprStmt | test.rs:62:20:62:20 | b | | @@ -138,8 +138,8 @@ edges | test.rs:67:17:67:31 | continue 'inner | test.rs:62:17:66:17 | ExprStmt | continue | | test.rs:67:17:67:32 | ExprStmt | test.rs:67:17:67:31 | continue 'inner | | | test.rs:72:5:84:5 | enter fn test_loop_label_shadowing | test.rs:72:34:72:34 | b | | -| test.rs:72:34:72:34 | b | test.rs:72:34:72:40 | ...: | match | -| test.rs:72:34:72:40 | ...: | test.rs:74:13:74:14 | ExprStmt | | +| test.rs:72:34:72:34 | b | test.rs:72:34:72:40 | ...: bool | match | +| test.rs:72:34:72:40 | ...: bool | test.rs:74:13:74:14 | ExprStmt | | | test.rs:74:13:74:13 | 1 | test.rs:76:17:80:17 | ExprStmt | | | test.rs:74:13:74:14 | ExprStmt | test.rs:74:13:74:13 | 1 | | | test.rs:76:17:80:17 | ExprStmt | test.rs:76:20:76:20 | b | | @@ -157,8 +157,8 @@ edges | test.rs:81:17:81:32 | ExprStmt | test.rs:81:17:81:31 | continue 'label | | | test.rs:86:5:95:5 | enter fn test_while | test.rs:86:19:86:19 | i | | | test.rs:86:5:95:5 | exit fn test_while (normal) | test.rs:86:5:95:5 | exit fn test_while | | -| test.rs:86:19:86:19 | i | test.rs:86:19:86:24 | ...: | match | -| test.rs:86:19:86:24 | ...: | test.rs:87:9:87:25 | let ... = true | | +| test.rs:86:19:86:19 | i | test.rs:86:19:86:24 | ...: i64 | match | +| test.rs:86:19:86:24 | ...: i64 | test.rs:87:9:87:25 | let ... = true | | | test.rs:86:27:95:5 | { ... } | test.rs:86:5:95:5 | exit fn test_while (normal) | | | test.rs:87:9:87:25 | let ... = true | test.rs:87:21:87:24 | true | | | test.rs:87:13:87:17 | b | test.rs:88:15:88:15 | b | match | @@ -206,8 +206,8 @@ edges | test.rs:101:17:101:22 | ExprStmt | test.rs:101:17:101:21 | break | | | test.rs:106:5:113:5 | enter fn test_for | test.rs:106:17:106:17 | j | | | test.rs:106:5:113:5 | exit fn test_for (normal) | test.rs:106:5:113:5 | exit fn test_for | | -| test.rs:106:17:106:17 | j | test.rs:106:17:106:22 | ...: | match | -| test.rs:106:17:106:22 | ...: | test.rs:107:18:107:18 | 0 | | +| test.rs:106:17:106:17 | j | test.rs:106:17:106:22 | ...: i64 | match | +| test.rs:106:17:106:22 | ...: i64 | test.rs:107:18:107:18 | 0 | | | test.rs:106:25:113:5 | { ... } | test.rs:106:5:113:5 | exit fn test_for (normal) | | | test.rs:107:9:112:9 | for ... in ... { ... } | test.rs:106:25:113:5 | { ... } | | | test.rs:107:13:107:13 | i | test.rs:107:9:112:9 | for ... in ... { ... } | no-match | @@ -233,8 +233,8 @@ edges | test.rs:117:26:117:26 | 1 | test.rs:117:19:117:26 | return 1 | | | test.rs:122:1:125:1 | enter fn test_nested_function | test.rs:122:25:122:25 | n | | | test.rs:122:1:125:1 | exit fn test_nested_function (normal) | test.rs:122:1:125:1 | exit fn test_nested_function | | -| test.rs:122:25:122:25 | n | test.rs:122:25:122:30 | ...: | match | -| test.rs:122:25:122:30 | ...: | test.rs:123:5:123:28 | let ... = ... | | +| test.rs:122:25:122:25 | n | test.rs:122:25:122:30 | ...: i64 | match | +| test.rs:122:25:122:30 | ...: i64 | test.rs:123:5:123:28 | let ... = ... | | | test.rs:122:40:125:1 | { ... } | test.rs:122:1:125:1 | exit fn test_nested_function (normal) | | | test.rs:123:5:123:28 | let ... = ... | test.rs:123:19:123:27 | \|...\| ... | | | test.rs:123:9:123:15 | add_one | test.rs:124:5:124:11 | add_one | match | @@ -253,8 +253,8 @@ edges | test.rs:124:21:124:21 | n | test.rs:124:13:124:22 | add_one(...) | | | test.rs:129:5:135:5 | enter fn test_if_else | test.rs:129:21:129:21 | n | | | test.rs:129:5:135:5 | exit fn test_if_else (normal) | test.rs:129:5:135:5 | exit fn test_if_else | | -| test.rs:129:21:129:21 | n | test.rs:129:21:129:26 | ...: | match | -| test.rs:129:21:129:26 | ...: | test.rs:130:12:130:12 | n | | +| test.rs:129:21:129:21 | n | test.rs:129:21:129:26 | ...: i64 | match | +| test.rs:129:21:129:26 | ...: i64 | test.rs:130:12:130:12 | n | | | test.rs:129:36:135:5 | { ... } | test.rs:129:5:135:5 | exit fn test_if_else (normal) | | | test.rs:130:9:134:9 | if ... {...} else {...} | test.rs:129:36:135:5 | { ... } | | | test.rs:130:12:130:12 | n | test.rs:130:17:130:17 | 0 | | @@ -269,8 +269,8 @@ edges | test.rs:133:17:133:17 | 1 | test.rs:133:13:133:17 | ... - ... | | | test.rs:137:5:143:5 | enter fn test_if_let_else | test.rs:137:25:137:25 | a | | | test.rs:137:5:143:5 | exit fn test_if_let_else (normal) | test.rs:137:5:143:5 | exit fn test_if_let_else | | -| test.rs:137:25:137:25 | a | test.rs:137:25:137:38 | ...: > | match | -| test.rs:137:25:137:38 | ...: > | test.rs:138:12:138:26 | let ... = a | | +| test.rs:137:25:137:25 | a | test.rs:137:25:137:38 | ...: Option::<...> | match | +| test.rs:137:25:137:38 | ...: Option::<...> | test.rs:138:12:138:26 | let ... = a | | | test.rs:137:48:143:5 | { ... } | test.rs:137:5:143:5 | exit fn test_if_let_else (normal) | | | test.rs:138:9:142:9 | if ... {...} else {...} | test.rs:137:48:143:5 | { ... } | | | test.rs:138:12:138:26 | let ... = a | test.rs:138:26:138:26 | a | | @@ -284,8 +284,8 @@ edges | test.rs:141:13:141:13 | 0 | test.rs:140:16:142:9 | { ... } | | | test.rs:145:5:150:5 | enter fn test_if_let | test.rs:145:20:145:20 | a | | | test.rs:145:5:150:5 | exit fn test_if_let (normal) | test.rs:145:5:150:5 | exit fn test_if_let | | -| test.rs:145:20:145:20 | a | test.rs:145:20:145:33 | ...: > | match | -| test.rs:145:20:145:33 | ...: > | test.rs:146:9:148:9 | ExprStmt | | +| test.rs:145:20:145:20 | a | test.rs:145:20:145:33 | ...: Option::<...> | match | +| test.rs:145:20:145:33 | ...: Option::<...> | test.rs:146:9:148:9 | ExprStmt | | | test.rs:145:43:150:5 | { ... } | test.rs:145:5:150:5 | exit fn test_if_let (normal) | | | test.rs:146:9:148:9 | ExprStmt | test.rs:146:12:146:26 | let ... = a | | | test.rs:146:9:148:9 | if ... {...} | test.rs:149:9:149:9 | 0 | | @@ -300,8 +300,8 @@ edges | test.rs:149:9:149:9 | 0 | test.rs:145:43:150:5 | { ... } | | | test.rs:152:5:158:5 | enter fn test_nested_if | test.rs:152:23:152:23 | a | | | test.rs:152:5:158:5 | exit fn test_nested_if (normal) | test.rs:152:5:158:5 | exit fn test_nested_if | | -| test.rs:152:23:152:23 | a | test.rs:152:23:152:28 | ...: | match | -| test.rs:152:23:152:28 | ...: | test.rs:153:16:153:16 | a | | +| test.rs:152:23:152:23 | a | test.rs:152:23:152:28 | ...: i64 | match | +| test.rs:152:23:152:28 | ...: i64 | test.rs:153:16:153:16 | a | | | test.rs:152:38:158:5 | { ... } | test.rs:152:5:158:5 | exit fn test_nested_if (normal) | | | test.rs:153:9:157:9 | if ... {...} else {...} | test.rs:152:38:158:5 | { ... } | | | test.rs:153:13:153:48 | [boolean(false)] if ... {...} else {...} | test.rs:156:13:156:13 | 0 | false | @@ -329,8 +329,8 @@ edges | test.rs:156:13:156:13 | 0 | test.rs:155:16:157:9 | { ... } | | | test.rs:160:5:169:5 | enter fn test_nested_if_match | test.rs:160:29:160:29 | a | | | test.rs:160:5:169:5 | exit fn test_nested_if_match (normal) | test.rs:160:5:169:5 | exit fn test_nested_if_match | | -| test.rs:160:29:160:29 | a | test.rs:160:29:160:34 | ...: | match | -| test.rs:160:29:160:34 | ...: | test.rs:161:19:161:19 | a | | +| test.rs:160:29:160:29 | a | test.rs:160:29:160:34 | ...: i64 | match | +| test.rs:160:29:160:34 | ...: i64 | test.rs:161:19:161:19 | a | | | test.rs:160:44:169:5 | { ... } | test.rs:160:5:169:5 | exit fn test_nested_if_match (normal) | | | test.rs:161:9:168:9 | if ... {...} else {...} | test.rs:160:44:169:5 | { ... } | | | test.rs:161:13:164:9 | [boolean(false)] match a { ... } | test.rs:167:13:167:13 | 0 | false | @@ -348,8 +348,8 @@ edges | test.rs:167:13:167:13 | 0 | test.rs:166:16:168:9 | { ... } | | | test.rs:171:5:180:5 | enter fn test_nested_if_block | test.rs:171:29:171:29 | a | | | test.rs:171:5:180:5 | exit fn test_nested_if_block (normal) | test.rs:171:5:180:5 | exit fn test_nested_if_block | | -| test.rs:171:29:171:29 | a | test.rs:171:29:171:34 | ...: | match | -| test.rs:171:29:171:34 | ...: | test.rs:173:13:173:15 | ExprStmt | | +| test.rs:171:29:171:29 | a | test.rs:171:29:171:34 | ...: i64 | match | +| test.rs:171:29:171:34 | ...: i64 | test.rs:173:13:173:15 | ExprStmt | | | test.rs:171:44:180:5 | { ... } | test.rs:171:5:180:5 | exit fn test_nested_if_block (normal) | | | test.rs:172:9:179:9 | if ... {...} else {...} | test.rs:171:44:180:5 | { ... } | | | test.rs:172:12:175:9 | [boolean(false)] { ... } | test.rs:178:13:178:13 | 0 | false | @@ -366,8 +366,8 @@ edges | test.rs:178:13:178:13 | 0 | test.rs:177:16:179:9 | { ... } | | | test.rs:182:5:192:5 | enter fn test_if_assignment | test.rs:182:27:182:27 | a | | | test.rs:182:5:192:5 | exit fn test_if_assignment (normal) | test.rs:182:5:192:5 | exit fn test_if_assignment | | -| test.rs:182:27:182:27 | a | test.rs:182:27:182:32 | ...: | match | -| test.rs:182:27:182:32 | ...: | test.rs:183:9:183:26 | let ... = false | | +| test.rs:182:27:182:27 | a | test.rs:182:27:182:32 | ...: i64 | match | +| test.rs:182:27:182:32 | ...: i64 | test.rs:183:9:183:26 | let ... = false | | | test.rs:182:42:192:5 | { ... } | test.rs:182:5:192:5 | exit fn test_if_assignment (normal) | | | test.rs:183:9:183:26 | let ... = false | test.rs:183:21:183:25 | false | | | test.rs:183:13:183:17 | x | test.rs:185:13:185:21 | ExprStmt | match | @@ -387,8 +387,8 @@ edges | test.rs:190:13:190:13 | 0 | test.rs:189:16:191:9 | { ... } | | | test.rs:194:5:205:5 | enter fn test_if_loop1 | test.rs:194:22:194:22 | a | | | test.rs:194:5:205:5 | exit fn test_if_loop1 (normal) | test.rs:194:5:205:5 | exit fn test_if_loop1 | | -| test.rs:194:22:194:22 | a | test.rs:194:22:194:27 | ...: | match | -| test.rs:194:22:194:27 | ...: | test.rs:196:13:198:14 | ExprStmt | | +| test.rs:194:22:194:22 | a | test.rs:194:22:194:27 | ...: i64 | match | +| test.rs:194:22:194:27 | ...: i64 | test.rs:196:13:198:14 | ExprStmt | | | test.rs:194:37:205:5 | { ... } | test.rs:194:5:205:5 | exit fn test_if_loop1 (normal) | | | test.rs:195:9:204:9 | if ... {...} else {...} | test.rs:194:37:205:5 | { ... } | | | test.rs:195:13:200:9 | [boolean(false)] loop { ... } | test.rs:203:13:203:13 | 0 | false | @@ -417,8 +417,8 @@ edges | test.rs:203:13:203:13 | 0 | test.rs:202:16:204:9 | { ... } | | | test.rs:207:5:218:5 | enter fn test_if_loop2 | test.rs:207:22:207:22 | a | | | test.rs:207:5:218:5 | exit fn test_if_loop2 (normal) | test.rs:207:5:218:5 | exit fn test_if_loop2 | | -| test.rs:207:22:207:22 | a | test.rs:207:22:207:27 | ...: | match | -| test.rs:207:22:207:27 | ...: | test.rs:209:13:211:14 | ExprStmt | | +| test.rs:207:22:207:22 | a | test.rs:207:22:207:27 | ...: i64 | match | +| test.rs:207:22:207:27 | ...: i64 | test.rs:209:13:211:14 | ExprStmt | | | test.rs:207:37:218:5 | { ... } | test.rs:207:5:218:5 | exit fn test_if_loop2 (normal) | | | test.rs:208:9:217:9 | if ... {...} else {...} | test.rs:207:37:218:5 | { ... } | | | test.rs:208:13:213:9 | [boolean(false)] 'label: loop { ... } | test.rs:216:13:216:13 | 0 | false | @@ -447,8 +447,8 @@ edges | test.rs:216:13:216:13 | 0 | test.rs:215:16:217:9 | { ... } | | | test.rs:220:5:228:5 | enter fn test_labelled_block | test.rs:220:28:220:28 | a | | | test.rs:220:5:228:5 | exit fn test_labelled_block (normal) | test.rs:220:5:228:5 | exit fn test_labelled_block | | -| test.rs:220:28:220:28 | a | test.rs:220:28:220:33 | ...: | match | -| test.rs:220:28:220:33 | ...: | test.rs:222:13:222:31 | ExprStmt | | +| test.rs:220:28:220:28 | a | test.rs:220:28:220:33 | ...: i64 | match | +| test.rs:220:28:220:33 | ...: i64 | test.rs:222:13:222:31 | ExprStmt | | | test.rs:220:43:228:5 | { ... } | test.rs:220:5:228:5 | exit fn test_labelled_block (normal) | | | test.rs:221:9:227:9 | if ... {...} else {...} | test.rs:220:43:228:5 | { ... } | | | test.rs:221:13:223:9 | [boolean(false)] 'block: { ... } | test.rs:226:13:226:13 | 0 | false | @@ -466,12 +466,12 @@ edges | test.rs:226:13:226:13 | 0 | test.rs:225:16:227:9 | { ... } | | | test.rs:233:5:236:5 | enter fn test_and_operator | test.rs:233:30:233:30 | a | | | test.rs:233:5:236:5 | exit fn test_and_operator (normal) | test.rs:233:5:236:5 | exit fn test_and_operator | | -| test.rs:233:30:233:30 | a | test.rs:233:30:233:36 | ...: | match | -| test.rs:233:30:233:36 | ...: | test.rs:233:39:233:39 | b | | -| test.rs:233:39:233:39 | b | test.rs:233:39:233:45 | ...: | match | -| test.rs:233:39:233:45 | ...: | test.rs:233:48:233:48 | c | | -| test.rs:233:48:233:48 | c | test.rs:233:48:233:54 | ...: | match | -| test.rs:233:48:233:54 | ...: | test.rs:234:9:234:28 | let ... = ... | | +| test.rs:233:30:233:30 | a | test.rs:233:30:233:36 | ...: bool | match | +| test.rs:233:30:233:36 | ...: bool | test.rs:233:39:233:39 | b | | +| test.rs:233:39:233:39 | b | test.rs:233:39:233:45 | ...: bool | match | +| test.rs:233:39:233:45 | ...: bool | test.rs:233:48:233:48 | c | | +| test.rs:233:48:233:48 | c | test.rs:233:48:233:54 | ...: bool | match | +| test.rs:233:48:233:54 | ...: bool | test.rs:234:9:234:28 | let ... = ... | | | test.rs:233:65:236:5 | { ... } | test.rs:233:5:236:5 | exit fn test_and_operator (normal) | | | test.rs:234:9:234:28 | let ... = ... | test.rs:234:17:234:17 | a | | | test.rs:234:13:234:13 | d | test.rs:235:9:235:9 | d | match | @@ -486,12 +486,12 @@ edges | test.rs:235:9:235:9 | d | test.rs:233:65:236:5 | { ... } | | | test.rs:238:5:241:5 | enter fn test_or_operator | test.rs:238:25:238:25 | a | | | test.rs:238:5:241:5 | exit fn test_or_operator (normal) | test.rs:238:5:241:5 | exit fn test_or_operator | | -| test.rs:238:25:238:25 | a | test.rs:238:25:238:31 | ...: | match | -| test.rs:238:25:238:31 | ...: | test.rs:238:34:238:34 | b | | -| test.rs:238:34:238:34 | b | test.rs:238:34:238:40 | ...: | match | -| test.rs:238:34:238:40 | ...: | test.rs:238:43:238:43 | c | | -| test.rs:238:43:238:43 | c | test.rs:238:43:238:49 | ...: | match | -| test.rs:238:43:238:49 | ...: | test.rs:239:9:239:28 | let ... = ... | | +| test.rs:238:25:238:25 | a | test.rs:238:25:238:31 | ...: bool | match | +| test.rs:238:25:238:31 | ...: bool | test.rs:238:34:238:34 | b | | +| test.rs:238:34:238:34 | b | test.rs:238:34:238:40 | ...: bool | match | +| test.rs:238:34:238:40 | ...: bool | test.rs:238:43:238:43 | c | | +| test.rs:238:43:238:43 | c | test.rs:238:43:238:49 | ...: bool | match | +| test.rs:238:43:238:49 | ...: bool | test.rs:239:9:239:28 | let ... = ... | | | test.rs:238:60:241:5 | { ... } | test.rs:238:5:241:5 | exit fn test_or_operator (normal) | | | test.rs:239:9:239:28 | let ... = ... | test.rs:239:17:239:17 | a | | | test.rs:239:13:239:13 | d | test.rs:240:9:240:9 | d | match | @@ -506,12 +506,12 @@ edges | test.rs:240:9:240:9 | d | test.rs:238:60:241:5 | { ... } | | | test.rs:243:5:246:5 | enter fn test_or_operator_2 | test.rs:243:27:243:27 | a | | | test.rs:243:5:246:5 | exit fn test_or_operator_2 (normal) | test.rs:243:5:246:5 | exit fn test_or_operator_2 | | -| test.rs:243:27:243:27 | a | test.rs:243:27:243:33 | ...: | match | -| test.rs:243:27:243:33 | ...: | test.rs:243:36:243:36 | b | | -| test.rs:243:36:243:36 | b | test.rs:243:36:243:41 | ...: | match | -| test.rs:243:36:243:41 | ...: | test.rs:243:44:243:44 | c | | -| test.rs:243:44:243:44 | c | test.rs:243:44:243:50 | ...: | match | -| test.rs:243:44:243:50 | ...: | test.rs:244:9:244:36 | let ... = ... | | +| test.rs:243:27:243:27 | a | test.rs:243:27:243:33 | ...: bool | match | +| test.rs:243:27:243:33 | ...: bool | test.rs:243:36:243:36 | b | | +| test.rs:243:36:243:36 | b | test.rs:243:36:243:41 | ...: i64 | match | +| test.rs:243:36:243:41 | ...: i64 | test.rs:243:44:243:44 | c | | +| test.rs:243:44:243:44 | c | test.rs:243:44:243:50 | ...: bool | match | +| test.rs:243:44:243:50 | ...: bool | test.rs:244:9:244:36 | let ... = ... | | | test.rs:243:61:246:5 | { ... } | test.rs:243:5:246:5 | exit fn test_or_operator_2 (normal) | | | test.rs:244:9:244:36 | let ... = ... | test.rs:244:17:244:17 | a | | | test.rs:244:13:244:13 | d | test.rs:245:9:245:9 | d | match | @@ -528,8 +528,8 @@ edges | test.rs:245:9:245:9 | d | test.rs:243:61:246:5 | { ... } | | | test.rs:248:5:251:5 | enter fn test_not_operator | test.rs:248:26:248:26 | a | | | test.rs:248:5:251:5 | exit fn test_not_operator (normal) | test.rs:248:5:251:5 | exit fn test_not_operator | | -| test.rs:248:26:248:26 | a | test.rs:248:26:248:32 | ...: | match | -| test.rs:248:26:248:32 | ...: | test.rs:249:9:249:19 | let ... = ... | | +| test.rs:248:26:248:26 | a | test.rs:248:26:248:32 | ...: bool | match | +| test.rs:248:26:248:32 | ...: bool | test.rs:249:9:249:19 | let ... = ... | | | test.rs:248:43:251:5 | { ... } | test.rs:248:5:251:5 | exit fn test_not_operator (normal) | | | test.rs:249:9:249:19 | let ... = ... | test.rs:249:18:249:18 | a | | | test.rs:249:13:249:13 | d | test.rs:250:9:250:9 | d | match | @@ -538,12 +538,12 @@ edges | test.rs:250:9:250:9 | d | test.rs:248:43:251:5 | { ... } | | | test.rs:253:5:259:5 | enter fn test_if_and_operator | test.rs:253:29:253:29 | a | | | test.rs:253:5:259:5 | exit fn test_if_and_operator (normal) | test.rs:253:5:259:5 | exit fn test_if_and_operator | | -| test.rs:253:29:253:29 | a | test.rs:253:29:253:35 | ...: | match | -| test.rs:253:29:253:35 | ...: | test.rs:253:38:253:38 | b | | -| test.rs:253:38:253:38 | b | test.rs:253:38:253:44 | ...: | match | -| test.rs:253:38:253:44 | ...: | test.rs:253:47:253:47 | c | | -| test.rs:253:47:253:47 | c | test.rs:253:47:253:53 | ...: | match | -| test.rs:253:47:253:53 | ...: | test.rs:254:12:254:12 | a | | +| test.rs:253:29:253:29 | a | test.rs:253:29:253:35 | ...: bool | match | +| test.rs:253:29:253:35 | ...: bool | test.rs:253:38:253:38 | b | | +| test.rs:253:38:253:38 | b | test.rs:253:38:253:44 | ...: bool | match | +| test.rs:253:38:253:44 | ...: bool | test.rs:253:47:253:47 | c | | +| test.rs:253:47:253:47 | c | test.rs:253:47:253:53 | ...: bool | match | +| test.rs:253:47:253:53 | ...: bool | test.rs:254:12:254:12 | a | | | test.rs:253:64:259:5 | { ... } | test.rs:253:5:259:5 | exit fn test_if_and_operator (normal) | | | test.rs:254:9:258:9 | if ... {...} else {...} | test.rs:253:64:259:5 | { ... } | | | test.rs:254:12:254:12 | a | test.rs:254:12:254:17 | [boolean(false)] ... && ... | false | @@ -562,12 +562,12 @@ edges | test.rs:257:13:257:17 | false | test.rs:256:16:258:9 | { ... } | | | test.rs:261:5:267:5 | enter fn test_if_or_operator | test.rs:261:28:261:28 | a | | | test.rs:261:5:267:5 | exit fn test_if_or_operator (normal) | test.rs:261:5:267:5 | exit fn test_if_or_operator | | -| test.rs:261:28:261:28 | a | test.rs:261:28:261:34 | ...: | match | -| test.rs:261:28:261:34 | ...: | test.rs:261:37:261:37 | b | | -| test.rs:261:37:261:37 | b | test.rs:261:37:261:43 | ...: | match | -| test.rs:261:37:261:43 | ...: | test.rs:261:46:261:46 | c | | -| test.rs:261:46:261:46 | c | test.rs:261:46:261:52 | ...: | match | -| test.rs:261:46:261:52 | ...: | test.rs:262:12:262:12 | a | | +| test.rs:261:28:261:28 | a | test.rs:261:28:261:34 | ...: bool | match | +| test.rs:261:28:261:34 | ...: bool | test.rs:261:37:261:37 | b | | +| test.rs:261:37:261:37 | b | test.rs:261:37:261:43 | ...: bool | match | +| test.rs:261:37:261:43 | ...: bool | test.rs:261:46:261:46 | c | | +| test.rs:261:46:261:46 | c | test.rs:261:46:261:52 | ...: bool | match | +| test.rs:261:46:261:52 | ...: bool | test.rs:262:12:262:12 | a | | | test.rs:261:63:267:5 | { ... } | test.rs:261:5:267:5 | exit fn test_if_or_operator (normal) | | | test.rs:262:9:266:9 | if ... {...} else {...} | test.rs:261:63:267:5 | { ... } | | | test.rs:262:12:262:12 | a | test.rs:262:12:262:17 | [boolean(true)] ... \|\| ... | true | @@ -586,8 +586,8 @@ edges | test.rs:265:13:265:17 | false | test.rs:264:16:266:9 | { ... } | | | test.rs:269:5:275:5 | enter fn test_if_not_operator | test.rs:269:29:269:29 | a | | | test.rs:269:5:275:5 | exit fn test_if_not_operator (normal) | test.rs:269:5:275:5 | exit fn test_if_not_operator | | -| test.rs:269:29:269:29 | a | test.rs:269:29:269:35 | ...: | match | -| test.rs:269:29:269:35 | ...: | test.rs:270:13:270:13 | a | | +| test.rs:269:29:269:29 | a | test.rs:269:29:269:35 | ...: bool | match | +| test.rs:269:29:269:35 | ...: bool | test.rs:270:13:270:13 | a | | | test.rs:269:46:275:5 | { ... } | test.rs:269:5:275:5 | exit fn test_if_not_operator (normal) | | | test.rs:270:9:274:9 | if ... {...} else {...} | test.rs:269:46:275:5 | { ... } | | | test.rs:270:12:270:13 | [boolean(false)] ! ... | test.rs:273:13:273:17 | false | false | @@ -600,8 +600,8 @@ edges | test.rs:273:13:273:17 | false | test.rs:272:16:274:9 | { ... } | | | test.rs:277:5:279:5 | enter fn test_and_return | test.rs:277:24:277:24 | a | | | test.rs:277:5:279:5 | exit fn test_and_return (normal) | test.rs:277:5:279:5 | exit fn test_and_return | | -| test.rs:277:24:277:24 | a | test.rs:277:24:277:30 | ...: | match | -| test.rs:277:24:277:30 | ...: | test.rs:278:9:278:20 | ExprStmt | | +| test.rs:277:24:277:24 | a | test.rs:277:24:277:30 | ...: bool | match | +| test.rs:277:24:277:30 | ...: bool | test.rs:278:9:278:20 | ExprStmt | | | test.rs:277:33:279:5 | { ... } | test.rs:277:5:279:5 | exit fn test_and_return (normal) | | | test.rs:278:9:278:9 | a | test.rs:278:9:278:19 | ... && ... | false | | test.rs:278:9:278:9 | a | test.rs:278:14:278:19 | return | true | @@ -610,8 +610,8 @@ edges | test.rs:278:14:278:19 | return | test.rs:277:5:279:5 | exit fn test_and_return (normal) | return | | test.rs:281:5:286:5 | enter fn test_and_true | test.rs:281:22:281:22 | a | | | test.rs:281:5:286:5 | exit fn test_and_true (normal) | test.rs:281:5:286:5 | exit fn test_and_true | | -| test.rs:281:22:281:22 | a | test.rs:281:22:281:28 | ...: | match | -| test.rs:281:22:281:28 | ...: | test.rs:282:9:284:9 | ExprStmt | | +| test.rs:281:22:281:22 | a | test.rs:281:22:281:28 | ...: bool | match | +| test.rs:281:22:281:28 | ...: bool | test.rs:282:9:284:9 | ExprStmt | | | test.rs:281:38:286:5 | { ... } | test.rs:281:5:286:5 | exit fn test_and_true (normal) | | | test.rs:282:9:284:9 | ExprStmt | test.rs:282:13:282:13 | a | | | test.rs:282:9:284:9 | if ... {...} | test.rs:285:9:285:9 | 0 | | @@ -639,8 +639,8 @@ edges | test.rs:293:32:293:32 | 4 | test.rs:293:12:293:32 | ... + ... | | | test.rs:296:5:301:5 | enter fn test_question_mark_operator_2 | test.rs:296:38:296:38 | b | | | test.rs:296:5:301:5 | exit fn test_question_mark_operator_2 (normal) | test.rs:296:5:301:5 | exit fn test_question_mark_operator_2 | | -| test.rs:296:38:296:38 | b | test.rs:296:38:296:52 | ...: > | match | -| test.rs:296:38:296:52 | ...: > | test.rs:297:15:297:15 | b | | +| test.rs:296:38:296:38 | b | test.rs:296:38:296:52 | ...: Option::<...> | match | +| test.rs:296:38:296:52 | ...: Option::<...> | test.rs:297:15:297:15 | b | | | test.rs:296:71:301:5 | { ... } | test.rs:296:5:301:5 | exit fn test_question_mark_operator_2 (normal) | | | test.rs:297:9:300:9 | match ... { ... } | test.rs:296:71:301:5 | { ... } | | | test.rs:297:15:297:15 | b | test.rs:297:15:297:16 | TryExpr | | @@ -659,8 +659,8 @@ edges | test.rs:299:27:299:30 | true | test.rs:299:22:299:31 | Some(...) | | | test.rs:307:5:313:5 | enter fn test_match | test.rs:307:19:307:29 | maybe_digit | | | test.rs:307:5:313:5 | exit fn test_match (normal) | test.rs:307:5:313:5 | exit fn test_match | | -| test.rs:307:19:307:29 | maybe_digit | test.rs:307:19:307:42 | ...: > | match | -| test.rs:307:19:307:42 | ...: > | test.rs:308:15:308:25 | maybe_digit | | +| test.rs:307:19:307:29 | maybe_digit | test.rs:307:19:307:42 | ...: Option::<...> | match | +| test.rs:307:19:307:42 | ...: Option::<...> | test.rs:308:15:308:25 | maybe_digit | | | test.rs:307:52:313:5 | { ... } | test.rs:307:5:313:5 | exit fn test_match (normal) | | | test.rs:308:9:312:9 | match maybe_digit { ... } | test.rs:307:52:313:5 | { ... } | | | test.rs:308:15:308:25 | maybe_digit | test.rs:309:13:309:27 | TupleStructPat | | @@ -682,8 +682,8 @@ edges | test.rs:311:29:311:29 | 5 | test.rs:308:9:312:9 | match maybe_digit { ... } | | | test.rs:315:5:324:5 | enter fn test_match_with_return_in_scrutinee | test.rs:315:44:315:54 | maybe_digit | | | test.rs:315:5:324:5 | exit fn test_match_with_return_in_scrutinee (normal) | test.rs:315:5:324:5 | exit fn test_match_with_return_in_scrutinee | | -| test.rs:315:44:315:54 | maybe_digit | test.rs:315:44:315:67 | ...: > | match | -| test.rs:315:44:315:67 | ...: > | test.rs:316:19:316:29 | maybe_digit | | +| test.rs:315:44:315:54 | maybe_digit | test.rs:315:44:315:67 | ...: Option::<...> | match | +| test.rs:315:44:315:67 | ...: Option::<...> | test.rs:316:19:316:29 | maybe_digit | | | test.rs:315:77:324:5 | { ... } | test.rs:315:5:324:5 | exit fn test_match_with_return_in_scrutinee (normal) | | | test.rs:316:9:323:9 | match ... { ... } | test.rs:315:77:324:5 | { ... } | | | test.rs:316:16:320:9 | if ... {...} else {...} | test.rs:321:13:321:27 | TupleStructPat | | @@ -708,10 +708,10 @@ edges | test.rs:322:29:322:29 | 5 | test.rs:316:9:323:9 | match ... { ... } | | | test.rs:326:5:331:5 | enter fn test_match_and | test.rs:326:23:326:26 | cond | | | test.rs:326:5:331:5 | exit fn test_match_and (normal) | test.rs:326:5:331:5 | exit fn test_match_and | | -| test.rs:326:23:326:26 | cond | test.rs:326:23:326:32 | ...: | match | -| test.rs:326:23:326:32 | ...: | test.rs:326:35:326:35 | r | | -| test.rs:326:35:326:35 | r | test.rs:326:35:326:49 | ...: > | match | -| test.rs:326:35:326:49 | ...: > | test.rs:327:16:327:16 | r | | +| test.rs:326:23:326:26 | cond | test.rs:326:23:326:32 | ...: bool | match | +| test.rs:326:23:326:32 | ...: bool | test.rs:326:35:326:35 | r | | +| test.rs:326:35:326:35 | r | test.rs:326:35:326:49 | ...: Option::<...> | match | +| test.rs:326:35:326:49 | ...: Option::<...> | test.rs:327:16:327:16 | r | | | test.rs:326:60:331:5 | { ... } | test.rs:326:5:331:5 | exit fn test_match_and (normal) | | | test.rs:327:9:330:18 | ... && ... | test.rs:326:60:331:5 | { ... } | | | test.rs:327:10:330:9 | [boolean(false)] match r { ... } | test.rs:327:9:330:18 | ... && ... | false | @@ -727,8 +727,8 @@ edges | test.rs:330:15:330:18 | cond | test.rs:327:9:330:18 | ... && ... | | | test.rs:333:5:338:5 | enter fn test_match_with_no_arms | test.rs:333:35:333:35 | r | | | test.rs:333:5:338:5 | exit fn test_match_with_no_arms (normal) | test.rs:333:5:338:5 | exit fn test_match_with_no_arms | | -| test.rs:333:35:333:35 | r | test.rs:333:35:333:58 | ...: > | match | -| test.rs:333:35:333:58 | ...: > | test.rs:334:15:334:15 | r | | +| test.rs:333:35:333:35 | r | test.rs:333:35:333:58 | ...: Result::<...> | match | +| test.rs:333:35:333:58 | ...: Result::<...> | test.rs:334:15:334:15 | r | | | test.rs:333:66:338:5 | { ... } | test.rs:333:5:338:5 | exit fn test_match_with_no_arms (normal) | | | test.rs:334:9:337:9 | match r { ... } | test.rs:333:66:338:5 | { ... } | | | test.rs:334:15:334:15 | r | test.rs:335:13:335:21 | TupleStructPat | | @@ -742,8 +742,8 @@ edges | test.rs:336:33:336:37 | never | test.rs:336:27:336:40 | match never { ... } | | | test.rs:343:5:346:5 | enter fn test_let_match | test.rs:343:23:343:23 | a | | | test.rs:343:5:346:5 | exit fn test_let_match (normal) | test.rs:343:5:346:5 | exit fn test_let_match | | -| test.rs:343:23:343:23 | a | test.rs:343:23:343:36 | ...: > | match | -| test.rs:343:23:343:36 | ...: > | test.rs:344:9:344:57 | let ... = a else {...} | | +| test.rs:343:23:343:23 | a | test.rs:343:23:343:36 | ...: Option::<...> | match | +| test.rs:343:23:343:36 | ...: Option::<...> | test.rs:344:9:344:57 | let ... = a else {...} | | | test.rs:343:46:346:5 | { ... } | test.rs:343:5:346:5 | exit fn test_let_match (normal) | | | test.rs:344:9:344:57 | let ... = a else {...} | test.rs:344:23:344:23 | a | | | test.rs:344:13:344:19 | TupleStructPat | test.rs:344:18:344:18 | n | match | @@ -764,8 +764,8 @@ edges | test.rs:345:9:345:9 | n | test.rs:343:46:346:5 | { ... } | | | test.rs:348:5:354:5 | enter fn test_let_with_return | test.rs:348:29:348:29 | m | | | test.rs:348:5:354:5 | exit fn test_let_with_return (normal) | test.rs:348:5:354:5 | exit fn test_let_with_return | | -| test.rs:348:29:348:29 | m | test.rs:348:29:348:42 | ...: > | match | -| test.rs:348:29:348:42 | ...: > | test.rs:349:9:352:10 | let ... = ... | | +| test.rs:348:29:348:29 | m | test.rs:348:29:348:42 | ...: Option::<...> | match | +| test.rs:348:29:348:42 | ...: Option::<...> | test.rs:349:9:352:10 | let ... = ... | | | test.rs:348:53:354:5 | { ... } | test.rs:348:5:354:5 | exit fn test_let_with_return (normal) | | | test.rs:349:9:352:10 | let ... = ... | test.rs:349:25:349:25 | m | | | test.rs:349:13:349:15 | ret | test.rs:353:9:353:12 | true | match | @@ -790,8 +790,8 @@ edges | test.rs:361:9:361:15 | ExprStmt | test.rs:361:9:361:14 | return | | | test.rs:366:5:370:5 | enter fn empty_struct_pattern | test.rs:366:29:366:30 | st | | | test.rs:366:5:370:5 | exit fn empty_struct_pattern (normal) | test.rs:366:5:370:5 | exit fn empty_struct_pattern | | -| test.rs:366:29:366:30 | st | test.rs:366:29:366:40 | ...: | match | -| test.rs:366:29:366:40 | ...: | test.rs:367:15:367:16 | st | | +| test.rs:366:29:366:30 | st | test.rs:366:29:366:40 | ...: MyStruct | match | +| test.rs:366:29:366:40 | ...: MyStruct | test.rs:367:15:367:16 | st | | | test.rs:366:50:370:5 | { ... } | test.rs:366:5:370:5 | exit fn empty_struct_pattern (normal) | | | test.rs:367:9:369:9 | match st { ... } | test.rs:366:50:370:5 | { ... } | | | test.rs:367:15:367:16 | st | test.rs:368:13:368:27 | MyStruct {...} | | @@ -845,8 +845,8 @@ edges | test.rs:393:18:393:32 | { ... } | test.rs:393:9:393:33 | MacroExpr | | | test.rs:396:5:415:5 | enter fn async_block | test.rs:396:26:396:26 | b | | | test.rs:396:5:415:5 | exit fn async_block (normal) | test.rs:396:5:415:5 | exit fn async_block | | -| test.rs:396:26:396:26 | b | test.rs:396:26:396:32 | ...: | match | -| test.rs:396:26:396:32 | ...: | test.rs:397:9:399:10 | let ... = ... | | +| test.rs:396:26:396:26 | b | test.rs:396:26:396:32 | ...: bool | match | +| test.rs:396:26:396:32 | ...: bool | test.rs:397:9:399:10 | let ... = ... | | | test.rs:396:35:415:5 | { ... } | test.rs:396:5:415:5 | exit fn async_block (normal) | | | test.rs:397:9:399:10 | let ... = ... | test.rs:397:26:399:9 | { ... } | | | test.rs:397:13:397:22 | say_godbye | test.rs:400:9:402:10 | let ... = ... | match | @@ -916,8 +916,8 @@ edges | test.rs:413:13:413:15 | foo | test.rs:409:28:414:9 | exit { ... } (normal) | | | test.rs:421:5:423:5 | enter fn add_two | test.rs:421:22:421:22 | n | | | test.rs:421:5:423:5 | exit fn add_two (normal) | test.rs:421:5:423:5 | exit fn add_two | | -| test.rs:421:22:421:22 | n | test.rs:421:22:421:27 | ...: | match | -| test.rs:421:22:421:27 | ...: | test.rs:422:9:422:9 | n | | +| test.rs:421:22:421:22 | n | test.rs:421:22:421:27 | ...: i64 | match | +| test.rs:421:22:421:27 | ...: i64 | test.rs:422:9:422:9 | n | | | test.rs:421:37:423:5 | { ... } | test.rs:421:5:423:5 | exit fn add_two (normal) | | | test.rs:422:9:422:9 | n | test.rs:422:13:422:13 | 2 | | | test.rs:422:9:422:13 | ... + ... | test.rs:421:37:423:5 | { ... } | | @@ -1062,8 +1062,8 @@ edges | test.rs:497:17:497:17 | x | test.rs:497:12:497:17 | &mut x | | | test.rs:509:5:511:5 | enter fn new | test.rs:509:12:509:12 | a | | | test.rs:509:5:511:5 | exit fn new (normal) | test.rs:509:5:511:5 | exit fn new | | -| test.rs:509:12:509:12 | a | test.rs:509:12:509:17 | ...: | match | -| test.rs:509:12:509:17 | ...: | test.rs:510:23:510:23 | a | | +| test.rs:509:12:509:12 | a | test.rs:509:12:509:17 | ...: i64 | match | +| test.rs:509:12:509:17 | ...: i64 | test.rs:510:23:510:23 | a | | | test.rs:509:28:511:5 | { ... } | test.rs:509:5:511:5 | exit fn new (normal) | | | test.rs:510:9:510:25 | MyNumber {...} | test.rs:509:28:511:5 | { ... } | | | test.rs:510:23:510:23 | a | test.rs:510:9:510:25 | MyNumber {...} | | @@ -1079,10 +1079,10 @@ edges | test.rs:517:5:519:5 | exit fn multifly_add (normal) | test.rs:517:5:519:5 | exit fn multifly_add | | | test.rs:517:21:517:29 | SelfParam | test.rs:517:32:517:32 | a | | | test.rs:517:26:517:29 | self | test.rs:517:21:517:29 | SelfParam | | -| test.rs:517:32:517:32 | a | test.rs:517:32:517:37 | ...: | match | -| test.rs:517:32:517:37 | ...: | test.rs:517:40:517:40 | b | | -| test.rs:517:40:517:40 | b | test.rs:517:40:517:45 | ...: | match | -| test.rs:517:40:517:45 | ...: | test.rs:518:9:518:34 | ExprStmt | | +| test.rs:517:32:517:32 | a | test.rs:517:32:517:37 | ...: i64 | match | +| test.rs:517:32:517:37 | ...: i64 | test.rs:517:40:517:40 | b | | +| test.rs:517:40:517:40 | b | test.rs:517:40:517:45 | ...: i64 | match | +| test.rs:517:40:517:45 | ...: i64 | test.rs:518:9:518:34 | ExprStmt | | | test.rs:517:48:519:5 | { ... } | test.rs:517:5:519:5 | exit fn multifly_add (normal) | | | test.rs:518:9:518:12 | self | test.rs:518:9:518:14 | self.n | | | test.rs:518:9:518:14 | self.n | test.rs:518:19:518:22 | self | | diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected index f3a4e282dab..77ea9a8b15b 100644 --- a/rust/ql/test/library-tests/variables/Cfg.expected +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -17,8 +17,8 @@ edges | variables.rs:4:20:4:20 | s | variables.rs:4:14:4:20 | FormatArgsExpr | | | variables.rs:7:1:9:1 | enter fn print_i64 | variables.rs:7:14:7:14 | i | | | variables.rs:7:1:9:1 | exit fn print_i64 (normal) | variables.rs:7:1:9:1 | exit fn print_i64 | | -| variables.rs:7:14:7:14 | i | variables.rs:7:14:7:19 | ...: | match | -| variables.rs:7:14:7:19 | ...: | variables.rs:8:5:8:22 | ExprStmt | | +| variables.rs:7:14:7:14 | i | variables.rs:7:14:7:19 | ...: i64 | match | +| variables.rs:7:14:7:19 | ...: i64 | variables.rs:8:5:8:22 | ExprStmt | | | variables.rs:7:22:9:1 | { ... } | variables.rs:7:1:9:1 | exit fn print_i64 (normal) | | | variables.rs:8:5:8:21 | ...::_print | variables.rs:8:14:8:17 | "{}\\n" | | | variables.rs:8:5:8:21 | MacroExpr | variables.rs:7:22:9:1 | { ... } | | @@ -584,10 +584,10 @@ edges | variables.rs:268:15:268:16 | c1 | variables.rs:268:5:268:17 | print_str(...) | | | variables.rs:271:1:275:1 | enter fn param_pattern2 | variables.rs:272:6:272:21 | TupleStructPat | | | variables.rs:271:1:275:1 | exit fn param_pattern2 (normal) | variables.rs:271:1:275:1 | exit fn param_pattern2 | | -| variables.rs:272:5:272:50 | ...: | variables.rs:274:5:274:18 | ExprStmt | | +| variables.rs:272:5:272:50 | ...: Either | variables.rs:274:5:274:18 | ExprStmt | | | variables.rs:272:6:272:21 | TupleStructPat | variables.rs:272:19:272:20 | a9 | match | | variables.rs:272:6:272:21 | TupleStructPat | variables.rs:272:25:272:41 | TupleStructPat | no-match | -| variables.rs:272:6:272:41 | [match(true)] ... \| ... | variables.rs:272:5:272:50 | ...: | match | +| variables.rs:272:6:272:41 | [match(true)] ... \| ... | variables.rs:272:5:272:50 | ...: Either | match | | variables.rs:272:19:272:20 | a9 | variables.rs:272:6:272:41 | [match(true)] ... \| ... | match | | variables.rs:272:25:272:41 | TupleStructPat | variables.rs:272:39:272:40 | a9 | match | | variables.rs:272:39:272:40 | a9 | variables.rs:272:6:272:41 | [match(true)] ... \| ... | match | @@ -675,8 +675,8 @@ edges | variables.rs:316:9:317:9 | \|...\| x | variables.rs:315:9:315:23 | example_closure | | | variables.rs:316:9:317:9 | enter \|...\| x | variables.rs:316:10:316:10 | x | | | variables.rs:316:9:317:9 | exit \|...\| x (normal) | variables.rs:316:9:317:9 | exit \|...\| x | | -| variables.rs:316:10:316:10 | x | variables.rs:316:10:316:15 | ...: | match | -| variables.rs:316:10:316:15 | ...: | variables.rs:317:9:317:9 | x | | +| variables.rs:316:10:316:10 | x | variables.rs:316:10:316:15 | ...: i64 | match | +| variables.rs:316:10:316:15 | ...: i64 | variables.rs:317:9:317:9 | x | | | variables.rs:317:9:317:9 | x | variables.rs:316:9:317:9 | exit \|...\| x (normal) | | | variables.rs:318:5:319:27 | let ... = ... | variables.rs:319:9:319:23 | example_closure | | | variables.rs:318:9:318:10 | n1 | variables.rs:320:5:320:18 | ExprStmt | match | @@ -695,8 +695,8 @@ edges | variables.rs:324:9:325:9 | \|...\| x | variables.rs:323:9:323:26 | immutable_variable | | | variables.rs:324:9:325:9 | enter \|...\| x | variables.rs:324:10:324:10 | x | | | variables.rs:324:9:325:9 | exit \|...\| x (normal) | variables.rs:324:9:325:9 | exit \|...\| x | | -| variables.rs:324:10:324:10 | x | variables.rs:324:10:324:15 | ...: | match | -| variables.rs:324:10:324:15 | ...: | variables.rs:325:9:325:9 | x | | +| variables.rs:324:10:324:10 | x | variables.rs:324:10:324:15 | ...: i64 | match | +| variables.rs:324:10:324:15 | ...: i64 | variables.rs:325:9:325:9 | x | | | variables.rs:325:9:325:9 | x | variables.rs:324:9:325:9 | exit \|...\| x (normal) | | | variables.rs:326:5:327:30 | let ... = ... | variables.rs:327:9:327:26 | immutable_variable | | | variables.rs:326:9:326:10 | n2 | variables.rs:328:5:328:18 | ExprStmt | match | @@ -979,8 +979,8 @@ edges | variables.rs:442:15:442:15 | i | variables.rs:442:5:442:16 | print_i64(...) | | | variables.rs:445:1:459:1 | enter fn phi | variables.rs:445:8:445:8 | b | | | variables.rs:445:1:459:1 | exit fn phi (normal) | variables.rs:445:1:459:1 | exit fn phi | | -| variables.rs:445:8:445:8 | b | variables.rs:445:8:445:15 | ...: | match | -| variables.rs:445:8:445:15 | ...: | variables.rs:446:5:446:18 | let ... = 1 | | +| variables.rs:445:8:445:8 | b | variables.rs:445:8:445:15 | ...: bool | match | +| variables.rs:445:8:445:15 | ...: bool | variables.rs:446:5:446:18 | let ... = 1 | | | variables.rs:445:18:459:1 | { ... } | variables.rs:445:1:459:1 | exit fn phi (normal) | | | variables.rs:446:5:446:18 | let ... = 1 | variables.rs:446:17:446:17 | 1 | | | variables.rs:446:9:446:13 | x | variables.rs:447:5:447:17 | ExprStmt | match | @@ -1035,10 +1035,10 @@ edges | variables.rs:458:15:458:15 | x | variables.rs:458:5:458:16 | print_i64(...) | | | variables.rs:461:1:474:1 | enter fn phi_read | variables.rs:461:13:461:14 | b1 | | | variables.rs:461:1:474:1 | exit fn phi_read (normal) | variables.rs:461:1:474:1 | exit fn phi_read | | -| variables.rs:461:13:461:14 | b1 | variables.rs:461:13:461:21 | ...: | match | -| variables.rs:461:13:461:21 | ...: | variables.rs:461:24:461:25 | b2 | | -| variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:32 | ...: | match | -| variables.rs:461:24:461:32 | ...: | variables.rs:462:5:462:14 | let ... = 1 | | +| variables.rs:461:13:461:14 | b1 | variables.rs:461:13:461:21 | ...: bool | match | +| variables.rs:461:13:461:21 | ...: bool | variables.rs:461:24:461:25 | b2 | | +| variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:32 | ...: bool | match | +| variables.rs:461:24:461:32 | ...: bool | variables.rs:462:5:462:14 | let ... = 1 | | | variables.rs:461:35:474:1 | { ... } | variables.rs:461:1:474:1 | exit fn phi_read (normal) | | | variables.rs:462:5:462:14 | let ... = 1 | variables.rs:462:13:462:13 | 1 | | | variables.rs:462:9:462:9 | x | variables.rs:463:5:467:5 | ExprStmt | match | From 9b2590ec7a2c49771e12b45bdeec185c76767769 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 21 Nov 2024 11:28:11 -0500 Subject: [PATCH 169/470] Updating PR per review comments. Moving more towards a simplified model. --- .../raw/internal/TranslatedCall.qll | 4 +- .../cpp/models/implementations/Memcpy.qll | 6 +- .../cpp/models/implementations/Memset.qll | 6 +- .../implementations/NoexceptFunction.qll | 6 +- .../cpp/models/implementations/Printf.qll | 14 +--- .../cpp/models/implementations/Strcat.qll | 6 +- .../cpp/models/implementations/Strcpy.qll | 6 +- .../StructuredExceptionHandling.qll | 6 +- .../cpp/models/interfaces/NonThrowing.qll | 10 ++- .../code/cpp/models/interfaces/Throwing.qll | 73 +++++-------------- 10 files changed, 41 insertions(+), 96 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index daa6bdaafcf..df92e73ed37 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -363,11 +363,11 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { } final override predicate mayThrowException() { - expr.getTarget().(ThrowingFunction).mayThrowException(_) + expr.getTarget() instanceof AlwaysSehThrowingFunction } final override predicate mustThrowException() { - expr.getTarget().(ThrowingFunction).mayThrowException(true) + expr.getTarget() instanceof AlwaysSehThrowingFunction } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll index 8c3ae368da9..311847e8aec 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll @@ -9,14 +9,14 @@ import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect import semmle.code.cpp.models.interfaces.Taint -import semmle.code.cpp.models.interfaces.Throwing +import semmle.code.cpp.models.interfaces.NonThrowing /** * The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant * `__builtin___memcpy_chk`. */ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction, - AliasFunction, NonThrowingFunction + AliasFunction, NonCppThrowingFunction { MemcpyFunction() { // memcpy(dest, src, num) @@ -106,8 +106,6 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect not this.hasGlobalName(["bcopy", mempcpy(), "memccpy"]) and index = this.getParamDest() } - - override TCxxException getExceptionType() { any() } } private string mempcpy() { result = ["mempcpy", "wmempcpy"] } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll index 6a4ab8a133f..51234e50f94 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll @@ -8,10 +8,10 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.Throwing +import semmle.code.cpp.models.interfaces.NonThrowing private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, AliasFunction, - SideEffectFunction, NonThrowingFunction + SideEffectFunction, NonCppThrowingFunction { MemsetFunctionModel() { this.hasGlobalOrStdOrBslName("memset") @@ -74,8 +74,6 @@ private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, Alias i = 0 and if this.hasGlobalName(bzero()) then result = 1 else result = 2 } - - override TCxxException getExceptionType() { any() } } private string bzero() { result = ["bzero", "explicit_bzero"] } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll index ee05b2a68a0..22f860bc593 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll @@ -1,4 +1,4 @@ -import semmle.code.cpp.models.interfaces.Throwing +import semmle.code.cpp.models.interfaces.NonThrowing /** * A function that is annotated with a `noexcept` specifier (or the equivalent @@ -6,8 +6,6 @@ import semmle.code.cpp.models.interfaces.Throwing * * Note: The `throw` specifier was deprecated in C++11 and removed in C++17. */ -class NoexceptFunction extends NonThrowingFunction { +class NoexceptFunction extends NonCppThrowingFunction { NoexceptFunction() { this.isNoExcept() or this.isNoThrow() } - - override TCxxException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll index 7dbd38126bf..f28359c7f64 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll @@ -8,12 +8,12 @@ import semmle.code.cpp.models.interfaces.FormattingFunction import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.Throwing +import semmle.code.cpp.models.interfaces.NonThrowing /** * The standard functions `printf`, `wprintf` and their glib variants. */ -private class Printf extends FormattingFunction, AliasFunction, NonThrowingFunction { +private class Printf extends FormattingFunction, AliasFunction, NonCppThrowingFunction { Printf() { this instanceof TopLevelFunction and ( @@ -32,8 +32,6 @@ private class Printf extends FormattingFunction, AliasFunction, NonThrowingFunct override predicate parameterEscapesOnlyViaReturn(int n) { none() } override predicate parameterIsAlwaysReturned(int n) { none() } - - override TCxxException getExceptionType() { any() } } /** @@ -52,8 +50,6 @@ private class Fprintf extends FormattingFunction, NonThrowingFunction { override int getFormatParameterIndex() { result = 1 } override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = true } - - override TCxxException getExceptionType() { any() } } /** @@ -97,8 +93,6 @@ private class Sprintf extends FormattingFunction, NonThrowingFunction { then result = 4 else result = super.getFirstFormatArgumentIndex() } - - override TCxxException getExceptionType() { any() } } /** @@ -171,8 +165,6 @@ private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, // We don't know how many parameters are passed to the function since it's varargs, but they also have read side effects. i = this.getFormatParameterIndex() and buffer = true } - - override TCxxException getExceptionType() { any() } } /** @@ -223,6 +215,4 @@ private class Syslog extends FormattingFunction, NonThrowingFunction { override int getFormatParameterIndex() { result = 1 } override predicate isOutputGlobal() { any() } - - override TCxxException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll index df85c56148a..966c7425dc4 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll @@ -7,7 +7,7 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.Throwing +import semmle.code.cpp.models.interfaces.NonThrowing /** * The standard function `strcat` and its wide, sized, and Microsoft variants. @@ -15,7 +15,7 @@ import semmle.code.cpp.models.interfaces.Throwing * Does not include `strlcat`, which is covered by `StrlcatFunction` */ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction, - NonThrowingFunction + NonCppThrowingFunction { StrcatFunction() { this.hasGlobalOrStdOrBslName([ @@ -94,8 +94,6 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid (i = 0 or i = 1) and buffer = true } - - override TCxxException getExceptionType() { any() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll index b09cbeb8dc6..b7ed20f1bab 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll @@ -7,13 +7,13 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.Throwing +import semmle.code.cpp.models.interfaces.NonThrowing /** * The standard function `strcpy` and its wide, sized, and Microsoft variants. */ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction, - NonThrowingFunction + NonCppThrowingFunction { StrcpyFunction() { this.hasGlobalOrStdOrBslName([ @@ -145,6 +145,4 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid i = this.getParamDest() and result = this.getParamSize() } - - override TCxxException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll index 36a2f6cdbe4..e561bfadee6 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll @@ -1,11 +1,7 @@ import semmle.code.cpp.models.interfaces.Throwing -class WindowsDriverExceptionAnnotation extends ThrowingFunction { +class WindowsDriverExceptionAnnotation extends AlwaysSehThrowingFunction { WindowsDriverExceptionAnnotation() { this.hasGlobalName(["RaiseException", "ExRaiseAccessViolation", "ExRaiseDatatypeMisalignment"]) } - - override predicate mayThrowException(boolean unconditional) { unconditional = true } - - override TSehException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll index 9f2c28979b4..5ddf754f745 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll @@ -5,9 +5,15 @@ import semmle.code.cpp.Function import semmle.code.cpp.models.Models +/** + * A function that is guaranteed to never throw a C++ exception + * (distinct from a structured exception handling, SEH, exception). + */ +abstract class NonCppThrowingFunction extends Function { } + /** * A function that is guaranteed to never throw. * - * DEPRECATED: use `NonThrowingFunction` in `semmle.code.cpp.models.Models.Interfaces.Throwing` instead. + * DEPRECATED: use `NonCppThrowingFunction` instead. */ -abstract deprecated class NonThrowingFunction extends Function { } +deprecated class NonThrowingFunction = NonCppThrowingFunction; diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll index d64ba61caa0..f75d0a78592 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll @@ -11,65 +11,28 @@ import semmle.code.cpp.models.Models import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs /** - * Represents a type of exception, - * either Structured Exception Handling (SEH) or C++ exceptions. - */ -newtype TException = - /** Structured Exception Handling (SEH) exception */ - TSehException() or - /** C++ exception */ - TCxxException() - -/** - * Functions with information about how an exception is thrown or if one is thrown at all. - * If throwing details conflict for the same function, IR is assumed - * to use the most restricted interpretation, meaning taking options - * that stipulate no exception is raised, before the exception is always raised, - * before conditional exceptions. + * A function that is known to raise an exception. * - * Annotations must specify if the exception is from SEH (structured exception handling) - * or ordinary c++ exceptions. + * DEPRECATED: use `AlwaysSehThrowingFunction` instead if a function unconditionally throws. + * These are assumed the only case where functions throw/raise exceptions unconditionally. + * For functions that may throw, this will be the default behavior in the IR. */ -abstract private class ExceptionAnnotation extends Function { - /** - * Returns the type of exception this annotation is for, - * either a CPP exception or a STructured Exception Handling (SEH) exception. - */ - abstract TException getExceptionType(); - - /** - * Holds if the exception type of this annotation is for a Structured Exception Handling (SEH) exception. - */ - final predicate isSeh() { this.getExceptionType() = TSehException() } - - /** - * Holds if the exception type of this annotation is for a CPP exception. - */ - final predicate isCxx() { this.getExceptionType() = TCxxException() } -} - -/** - * A Function that is known to not throw an exception. - */ -abstract class NonThrowingFunction extends ExceptionAnnotation { } - -/** - * A function this is known to raise an exception. - */ -abstract class ThrowingFunction extends ExceptionAnnotation { +abstract deprecated class ThrowingFunction extends Function { ThrowingFunction() { any() } /** - * Holds if this function may raise an exception during evaluation. - * If `unconditional` is `false` the function may raise, and if `true` the function - * will always raise an exception. - * Do not specify `none()` if no exception is raised, instead use the - * `NonThrowingFunction` class instead. + * Holds if this function may throw an exception during evaluation. + * If `unconditional` is `true` the function always throws an exception. + * + * DPERECATED: for always throwing functions use `AlwaysSehThrowingFunction` instead. + * For functions that may throw, this will be the default behavior in the IR. */ - abstract predicate mayThrowException(boolean unconditional); - - /** - * Holds if this function will always raise an exception if called - */ - final predicate alwaysThrowsException() { this.mayThrowException(true) } + abstract deprecated predicate mayThrowException(boolean unconditional); } + +/** + * A function that is known to raise an exception unconditionally. + * The only cases known where this happens is for SEH + * (structured exception handling) exceptions. + */ +abstract class AlwaysSehThrowingFunction extends Function { } From f8fff4b18c5c93da643e055a5965b8d570875199 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 21 Nov 2024 17:06:32 +0000 Subject: [PATCH 170/470] Update rust/ql/src/queries/security/CWE-089/SqlInjection.ql Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com> --- rust/ql/src/queries/security/CWE-089/SqlInjection.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-089/SqlInjection.ql b/rust/ql/src/queries/security/CWE-089/SqlInjection.ql index cf1ea5534aa..ee2a3d14486 100644 --- a/rust/ql/src/queries/security/CWE-089/SqlInjection.ql +++ b/rust/ql/src/queries/security/CWE-089/SqlInjection.ql @@ -1,6 +1,6 @@ /** * @name Database query built from user-controlled sources - * @description Building a database query from user-controlled sources is vulnerable to insertion of malicious code by the user. + * @description Building a database query from user-controlled sources is vulnerable to insertion of malicious code by attackers. * @kind path-problem * @problem.severity error * @security-severity 8.8 From 44126913cd8af92e731247f3d534b388aa0d3179 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 21 Nov 2024 12:08:04 -0500 Subject: [PATCH 171/470] Delaying deprecation of ThrowingFunction. --- .../ir/implementation/raw/internal/TranslatedCall.qll | 4 ++-- .../semmle/code/cpp/models/interfaces/Throwing.qll | 11 ++--------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index df92e73ed37..daa6bdaafcf 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -363,11 +363,11 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { } final override predicate mayThrowException() { - expr.getTarget() instanceof AlwaysSehThrowingFunction + expr.getTarget().(ThrowingFunction).mayThrowException(_) } final override predicate mustThrowException() { - expr.getTarget() instanceof AlwaysSehThrowingFunction + expr.getTarget().(ThrowingFunction).mayThrowException(true) } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll index f75d0a78592..044b30f7b70 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll @@ -12,22 +12,15 @@ import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs /** * A function that is known to raise an exception. - * - * DEPRECATED: use `AlwaysSehThrowingFunction` instead if a function unconditionally throws. - * These are assumed the only case where functions throw/raise exceptions unconditionally. - * For functions that may throw, this will be the default behavior in the IR. */ -abstract deprecated class ThrowingFunction extends Function { +abstract class ThrowingFunction extends Function { ThrowingFunction() { any() } /** * Holds if this function may throw an exception during evaluation. * If `unconditional` is `true` the function always throws an exception. - * - * DPERECATED: for always throwing functions use `AlwaysSehThrowingFunction` instead. - * For functions that may throw, this will be the default behavior in the IR. */ - abstract deprecated predicate mayThrowException(boolean unconditional); + abstract predicate mayThrowException(boolean unconditional); } /** From 01cddcc0428a5f4ae926e4dcd9e22592795ed719 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:54:47 +0000 Subject: [PATCH 172/470] Rust: Suggestions from docs review. --- rust/ql/src/queries/security/CWE-089/SqlInjection.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-089/SqlInjection.qhelp b/rust/ql/src/queries/security/CWE-089/SqlInjection.qhelp index bcf54fca582..0b56ac54d0d 100644 --- a/rust/ql/src/queries/security/CWE-089/SqlInjection.qhelp +++ b/rust/ql/src/queries/security/CWE-089/SqlInjection.qhelp @@ -5,7 +5,7 @@

    -If a database query (such as a SQL query) is built from user-provided data without sufficient sanitization, a user may be able to run malicious database queries. An attacker can craft the part of the query they control to change the overall meaning of the query. +If a database query (such as an SQL query) is built from user-provided data without sufficient sanitization, a user may be able to run malicious database queries. An attacker can craft the part of the query they control to change the overall meaning of the query.

    From 7059fc3e31bc5b66b1ed971091960080ad422533 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 21 Nov 2024 12:10:42 -0500 Subject: [PATCH 173/470] Adding intermediate solution towards deprecating ThrowingFunction --- .../cpp/ir/implementation/raw/internal/TranslatedCall.qll | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index daa6bdaafcf..2ddc55f91f5 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -364,10 +364,14 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { final override predicate mayThrowException() { expr.getTarget().(ThrowingFunction).mayThrowException(_) + or + expr.getTarget() instanceof AlwaysSehThrowingFunction } final override predicate mustThrowException() { expr.getTarget().(ThrowingFunction).mayThrowException(true) + or + expr.getTarget() instanceof AlwaysSehThrowingFunction } } From 248f1c4ebea29dd967898b3077ac3dccea105919 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 21 Nov 2024 12:15:14 -0500 Subject: [PATCH 174/470] Updating change log --- cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md b/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md index 114822e6c8f..73b358a0e1f 100644 --- a/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md +++ b/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md @@ -1,4 +1,4 @@ --- category: deprecated --- -* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonThrowing` class from `semmle.code.cpp.models.interfaces.Throwing` instead. \ No newline at end of file +* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonCppThrowingFunction` class instead. \ No newline at end of file From 583651ba40ff84c834905ded056fb65adfe7d835 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 21 Nov 2024 12:41:26 -0500 Subject: [PATCH 175/470] Missing NonCppThrowingFunction changes in Printf.qll --- .../lib/semmle/code/cpp/models/implementations/Printf.qll | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll index f28359c7f64..585091eff70 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll @@ -37,7 +37,7 @@ private class Printf extends FormattingFunction, AliasFunction, NonCppThrowingFu /** * The standard functions `fprintf`, `fwprintf` and their glib variants. */ -private class Fprintf extends FormattingFunction, NonThrowingFunction { +private class Fprintf extends FormattingFunction, NonCppThrowingFunction { Fprintf() { this instanceof TopLevelFunction and ( @@ -55,7 +55,7 @@ private class Fprintf extends FormattingFunction, NonThrowingFunction { /** * The standard function `sprintf` and its Microsoft and glib variants. */ -private class Sprintf extends FormattingFunction, NonThrowingFunction { +private class Sprintf extends FormattingFunction, NonCppThrowingFunction { Sprintf() { this instanceof TopLevelFunction and ( @@ -98,7 +98,7 @@ private class Sprintf extends FormattingFunction, NonThrowingFunction { /** * Implements `Snprintf`. */ -private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, NonThrowingFunction { +private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, NonCppThrowingFunction { SnprintfImpl() { this instanceof TopLevelFunction and ( @@ -205,7 +205,7 @@ private class StringCchPrintf extends FormattingFunction { /** * The standard function `syslog`. */ -private class Syslog extends FormattingFunction, NonThrowingFunction { +private class Syslog extends FormattingFunction, NonCppThrowingFunction { Syslog() { this instanceof TopLevelFunction and this.hasGlobalName("syslog") and From 66cf736b4c8f56e2b5787a3906513fd5801c0a0d Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 21 Nov 2024 12:44:28 -0500 Subject: [PATCH 176/470] printf formatting. --- cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll index 585091eff70..d4b054ea0b5 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll @@ -98,7 +98,9 @@ private class Sprintf extends FormattingFunction, NonCppThrowingFunction { /** * Implements `Snprintf`. */ -private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, NonCppThrowingFunction { +private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, + NonCppThrowingFunction +{ SnprintfImpl() { this instanceof TopLevelFunction and ( From 37365c746ccf15848cc9abc77f96678d11b01ec4 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 21 Nov 2024 12:59:56 -0500 Subject: [PATCH 177/470] Updating to NonCppThrowingFunction use in IncorrectALlocationErrorHandling.ql --- .../Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql b/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql index 92daf31b057..d4d908f8474 100644 --- a/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql +++ b/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql @@ -45,7 +45,7 @@ predicate deleteMayThrow(DeleteOrDeleteArrayExpr deleteExpr) { * like it might throw an exception, and the function does not have a `noexcept` or `throw()` specifier. */ predicate functionMayThrow(Function f) { - not f instanceof NonThrowingFunction and + not f instanceof NonCppThrowingFunction and (not exists(f.getBlock()) or stmtMayThrow(f.getBlock())) } From 3fa93e5ca9d35a71603b6180e008a36ff9375c8c Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Nov 2024 19:35:24 +0000 Subject: [PATCH 178/470] Rust: Add rust/summary/taint-sources query. --- rust/ql/src/queries/summary/TaintSources.ql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 rust/ql/src/queries/summary/TaintSources.ql diff --git a/rust/ql/src/queries/summary/TaintSources.ql b/rust/ql/src/queries/summary/TaintSources.ql new file mode 100644 index 00000000000..2e1bc7205e2 --- /dev/null +++ b/rust/ql/src/queries/summary/TaintSources.ql @@ -0,0 +1,17 @@ +/** + * @name Taint Sources + * @description List all sources of untrusted input that have been idenfitied + * in the database. + * @kind problem + * @problem.severity info + * @id rust/summary/taint-sources + * @tags summary + */ + +import rust +import codeql.rust.Concepts + +from ThreatModelSource s, string defaultString +where + if s instanceof ActiveThreatModelSource then defaultString = ", DEFAULT" else defaultString = "" +select s, s.getSourceType() + " (" + s.getThreatModel() + defaultString + ")" From ca424d1e61ed1fb1e10610071a24e9a1bc2e1a33 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 20 Nov 2024 16:36:03 +0000 Subject: [PATCH 179/470] Rust: Add a count of flow sources to rust/summary/summary-statistics. --- rust/ql/src/queries/summary/SummaryStats.ql | 5 +++++ rust/ql/test/query-tests/diagnostics/SummaryStats.expected | 2 ++ 2 files changed, 7 insertions(+) diff --git a/rust/ql/src/queries/summary/SummaryStats.ql b/rust/ql/src/queries/summary/SummaryStats.ql index 3f24eb50d19..b453d80e5e0 100644 --- a/rust/ql/src/queries/summary/SummaryStats.ql +++ b/rust/ql/src/queries/summary/SummaryStats.ql @@ -7,6 +7,7 @@ */ import rust +import codeql.rust.Concepts import codeql.rust.Diagnostics import Stats @@ -37,4 +38,8 @@ where key = "Inconsistencies - CFG" and value = getTotalCfgInconsistencies() or key = "Inconsistencies - data flow" and value = getTotalDataFlowInconsistencies() + or + key = "Taint sources - total" and value = count(ThreatModelSource s) + or + key = "Taint sources - active" and value = count(ActiveThreatModelSource s) select key, value diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index aeba0ac1ee6..69be8e0c6d0 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -10,3 +10,5 @@ | Inconsistencies - data flow | 0 | | Lines of code extracted | 59 | | Lines of user code extracted | 59 | +| Taint sources - active | 0 | +| Taint sources - total | 0 | From a85ad4ec294df25fe44acf0d60e493131be07273 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Nov 2024 21:34:16 +0000 Subject: [PATCH 180/470] Rust: Add a dataflow/sources test. --- .../dataflow/sources/TaintSources.expected | 0 .../dataflow/sources/TaintSources.qlref | 2 + .../dataflow/sources/options.yml | 3 + .../library-tests/dataflow/sources/reqwest.rs | 36 ++++++++++ .../library-tests/dataflow/sources/test.rs | 70 +++++++++++++++++++ 5 files changed, 111 insertions(+) create mode 100644 rust/ql/test/library-tests/dataflow/sources/TaintSources.expected create mode 100644 rust/ql/test/library-tests/dataflow/sources/TaintSources.qlref create mode 100644 rust/ql/test/library-tests/dataflow/sources/options.yml create mode 100644 rust/ql/test/library-tests/dataflow/sources/reqwest.rs create mode 100644 rust/ql/test/library-tests/dataflow/sources/test.rs diff --git a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/rust/ql/test/library-tests/dataflow/sources/TaintSources.qlref b/rust/ql/test/library-tests/dataflow/sources/TaintSources.qlref new file mode 100644 index 00000000000..3f6de4d0e4e --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/sources/TaintSources.qlref @@ -0,0 +1,2 @@ +query: queries/summary/TaintSources.ql +postprocess: utils/InlineExpectationsTestQuery.ql diff --git a/rust/ql/test/library-tests/dataflow/sources/options.yml b/rust/ql/test/library-tests/dataflow/sources/options.yml new file mode 100644 index 00000000000..3885768c7fa --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/sources/options.yml @@ -0,0 +1,3 @@ +qltest_cargo_check: true +qltest_dependencies: + - reqwest = { version = "0.12.9", features = ["blocking"] } diff --git a/rust/ql/test/library-tests/dataflow/sources/reqwest.rs b/rust/ql/test/library-tests/dataflow/sources/reqwest.rs new file mode 100644 index 00000000000..3e8f5ef8510 --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/sources/reqwest.rs @@ -0,0 +1,36 @@ + +// --- stubs for the "reqwest" library --- + +/* + --- we don't seem to have a way to use this, hence we currently test against the real reqwest library +#[derive(Debug)] +pub struct Error { } + +pub mod blocking { + pub struct Response { } + impl Response { + pub fn text(self) -> Result { + Ok("".to_string()) + } + } + + pub fn get(url: T) -> Result { + let _url = url; + + Ok(Response {}) + } +} + +pub struct Response { } +impl Response { + pub async fn text(self) -> Result { + Ok("".to_string()) + } +} + +pub async fn get(url: T) -> Result { + let _url = url; + + Ok(Response {}) +} +*/ diff --git a/rust/ql/test/library-tests/dataflow/sources/test.rs b/rust/ql/test/library-tests/dataflow/sources/test.rs new file mode 100644 index 00000000000..62b00e94b9d --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/sources/test.rs @@ -0,0 +1,70 @@ +#![allow(deprecated)] + +fn sink(_: T) { } + +// --- tests --- + +fn test_env_vars() { + sink(std::env::var("HOME")); // $ MISSING: Alert[rust/summary/taint-sources] hasTaintFlow + sink(std::env::var_os("PATH")); // $ MISSING: Alert[rust/summary/taint-sources] hasTaintFlow + + let var1 = std::env::var("HOME").expect("HOME not set"); // $ MISSING: Alert[rust/summary/taint-sources] + let var2 = std::env::var_os("PATH").unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] + + sink(var1); // $ MISSING: hasTaintFlow + sink(var2); // $ MISSING: hasTaintFlow + + for (key, value) in std::env::vars() { // $ MISSING: Alert[rust/summary/taint-sources] + sink(key); // $ MISSING: hasTaintFlow + sink(value); // $ MISSING: hasTaintFlow + } + + for (key, value) in std::env::vars_os() { // $ MISSING: Alert[rust/summary/taint-sources] + sink(key); // $ MISSING: hasTaintFlow + sink(value); // $ MISSING: hasTaintFlow + } +} + +fn test_env_args() { + let args: Vec = std::env::args().collect(); // $ MISSING: Alert[rust/summary/taint-sources] + let my_path = &args[0]; + let arg1 = &args[1]; + let arg2 = std::env::args().nth(2).unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] + let arg3 = std::env::args_os().nth(3).unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] + + sink(my_path); // $ MISSING: hasTaintFlow + sink(arg1); // $ MISSING: hasTaintFlow + sink(arg2); // $ MISSING: hasTaintFlow + sink(arg3); // $ MISSING: hasTaintFlow + + for arg in std::env::args() { // $ MISSING: Alert[rust/summary/taint-sources] + sink(arg); // $ MISSING: hasTaintFlow + } + + for arg in std::env::args_os() { // $ MISSING: Alert[rust/summary/taint-sources] + sink(arg); // $ MISSING: hasTaintFlow + } +} + +fn test_env_dirs() { + let dir = std::env::current_dir().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources] + let exe = std::env::current_exe().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources] + let home = std::env::home_dir().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources] + + sink(dir); // $ MISSING: hasTaintFlow + sink(exe); // $ MISSING: hasTaintFlow + sink(home); // $ MISSING: hasTaintFlow +} + +async fn test_reqwest() -> Result<(), reqwest::Error> { + let remote_string1 = reqwest::blocking::get("http://example.com/")?.text()?; // $ MISSING: Alert[rust/summary/taint-sources] + sink(remote_string1); // $ MISSING: hasTaintFlow + + let remote_string2 = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] + sink(remote_string2); // $ MISSING: hasTaintFlow + + let remote_string3 = reqwest::get("http://example.com/").await?.text().await?; // $ MISSING: Alert[rust/summary/taint-sources] + sink(remote_string3); // $ MISSING: hasTaintFlow + + Ok(()) +} From be40085982b6771278e7f3add8c75899d380f4f8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 20 Nov 2024 16:12:47 +0000 Subject: [PATCH 181/470] Rust: Add a test of flow sources reaching sinks as well. --- .../dataflow/sources/InlineFlow.expected | 0 .../dataflow/sources/InlineFlow.ql | 21 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected create mode 100644 rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql diff --git a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql new file mode 100644 index 00000000000..85bb2c9dbf0 --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql @@ -0,0 +1,21 @@ +import rust +import codeql.rust.dataflow.DataFlow +import codeql.rust.Concepts +import utils.InlineFlowTest + +/** + * Configuration for flow from any threat model source to an argument of a function called `sink`. + */ +module MyFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof ThreatModelSource } + + predicate isSink(DataFlow::Node sink) { + any(CallExpr call | call.getExpr().(PathExpr).getPath().toString() = "sink") + .getArgList() + .getAnArg() = sink.asExpr() + } +} + +module MyFlowTest = TaintFlowTest; + +import MyFlowTest From 374769873ac0eaf6e24076ce29f4a23bd5f2e438 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:15:36 +0000 Subject: [PATCH 182/470] Rust: Add Frameworks.qll infrastructure. --- rust/ql/lib/codeql/rust/Concepts.qll | 1 + rust/ql/lib/codeql/rust/Frameworks.qll | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 rust/ql/lib/codeql/rust/Frameworks.qll diff --git a/rust/ql/lib/codeql/rust/Concepts.qll b/rust/ql/lib/codeql/rust/Concepts.qll index 5befe006bc6..672ae09e4c2 100644 --- a/rust/ql/lib/codeql/rust/Concepts.qll +++ b/rust/ql/lib/codeql/rust/Concepts.qll @@ -6,6 +6,7 @@ private import codeql.rust.dataflow.DataFlow private import codeql.threatmodels.ThreatModels +private import codeql.rust.Frameworks /** * A data flow source for a specific threat-model. diff --git a/rust/ql/lib/codeql/rust/Frameworks.qll b/rust/ql/lib/codeql/rust/Frameworks.qll new file mode 100644 index 00000000000..2b4bdaff056 --- /dev/null +++ b/rust/ql/lib/codeql/rust/Frameworks.qll @@ -0,0 +1,3 @@ +/** + * This file imports all models of frameworks and libraries. + */ From e64f139c98360e81c1d799ada385ab95f1441444 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 20 Nov 2024 12:47:01 +0000 Subject: [PATCH 183/470] Rust: Model std::env. --- rust/ql/lib/codeql/rust/Concepts.qll | 26 +++++++++++++++ rust/ql/lib/codeql/rust/Frameworks.qll | 2 ++ .../lib/codeql/rust/frameworks/stdlib/Env.qll | 33 +++++++++++++++++++ .../dataflow/sources/TaintSources.expected | 14 ++++++++ .../library-tests/dataflow/sources/test.rs | 28 ++++++++-------- 5 files changed, 89 insertions(+), 14 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll diff --git a/rust/ql/lib/codeql/rust/Concepts.qll b/rust/ql/lib/codeql/rust/Concepts.qll index 672ae09e4c2..8f35ea589e8 100644 --- a/rust/ql/lib/codeql/rust/Concepts.qll +++ b/rust/ql/lib/codeql/rust/Concepts.qll @@ -47,6 +47,32 @@ class ActiveThreatModelSource extends ThreatModelSource { ActiveThreatModelSource() { currentThreatModel(this.getThreatModel()) } } +/** + * A data flow source corresponding to the program's command line arguments or path. + */ +class CommandLineArgsSource extends ThreatModelSource instanceof CommandLineArgsSource::Range { } + +module CommandLineArgsSource { + abstract class Range extends ThreatModelSource::Range { + override string getThreatModel() { result = "commandargs" } + + override string getSourceType() { result = "CommandLineArgs" } + } +} + +/** + * A data flow source corresponding to the program's environment. + */ +class EnvironmentSource extends ThreatModelSource instanceof EnvironmentSource::Range { } + +module EnvironmentSource { + abstract class Range extends ThreatModelSource::Range { + override string getThreatModel() { result = "environment" } + + override string getSourceType() { result = "EnvironmentSource" } + } +} + /** * A data-flow node that constructs a SQL statement. * diff --git a/rust/ql/lib/codeql/rust/Frameworks.qll b/rust/ql/lib/codeql/rust/Frameworks.qll index 2b4bdaff056..4ed5d72b898 100644 --- a/rust/ql/lib/codeql/rust/Frameworks.qll +++ b/rust/ql/lib/codeql/rust/Frameworks.qll @@ -1,3 +1,5 @@ /** * This file imports all models of frameworks and libraries. */ + +private import codeql.rust.frameworks.stdlib.Env diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll b/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll new file mode 100644 index 00000000000..b3d1eac8f5d --- /dev/null +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll @@ -0,0 +1,33 @@ +/** + * Provides modeling for the `std::env` library. + */ + +private import rust +private import codeql.rust.Concepts + +/** + * A call to `std::env::args` or `std::env::args_os`. + */ +private class StdEnvArgs extends CommandLineArgsSource::Range { + StdEnvArgs() { + this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::args", "crate::env::args_os"] + } +} + +/** + * A call to `std::env::current_dir`, `std::env::current_exe` or `std::env::home_dir`. + */ +private class StdEnvDir extends CommandLineArgsSource::Range { + StdEnvDir() { + this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::current_dir", "crate::env::current_exe", "crate::env::home_dir"] + } +} + +/** + * A call to `std::env::var`, `std::env::var_os`, `std::env::vars` or `std::env::vars_os`. + */ +private class StdEnvVar extends EnvironmentSource::Range { + StdEnvVar() { + this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::var", "crate::env::var_os", "crate::env::vars", "crate::env::vars_os"] + } +} diff --git a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected index e69de29bb2d..06b84dc590a 100644 --- a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected +++ b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected @@ -0,0 +1,14 @@ +| test.rs:8:10:8:30 | CallExpr | EnvironmentSource (environment) | +| test.rs:9:10:9:33 | CallExpr | EnvironmentSource (environment) | +| test.rs:11:16:11:36 | CallExpr | EnvironmentSource (environment) | +| test.rs:12:16:12:39 | CallExpr | EnvironmentSource (environment) | +| test.rs:17:25:17:40 | CallExpr | EnvironmentSource (environment) | +| test.rs:22:25:22:43 | CallExpr | EnvironmentSource (environment) | +| test.rs:29:29:29:44 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:32:16:32:31 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:33:16:33:34 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:40:16:40:31 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:44:16:44:34 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:50:15:50:37 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:51:15:51:37 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:52:16:52:35 | CallExpr | CommandLineArgs (commandargs) | diff --git a/rust/ql/test/library-tests/dataflow/sources/test.rs b/rust/ql/test/library-tests/dataflow/sources/test.rs index 62b00e94b9d..00cc96bdc00 100644 --- a/rust/ql/test/library-tests/dataflow/sources/test.rs +++ b/rust/ql/test/library-tests/dataflow/sources/test.rs @@ -5,51 +5,51 @@ fn sink(_: T) { } // --- tests --- fn test_env_vars() { - sink(std::env::var("HOME")); // $ MISSING: Alert[rust/summary/taint-sources] hasTaintFlow - sink(std::env::var_os("PATH")); // $ MISSING: Alert[rust/summary/taint-sources] hasTaintFlow + sink(std::env::var("HOME")); // $ Alert[rust/summary/taint-sources] hasTaintFlow + sink(std::env::var_os("PATH")); // $ Alert[rust/summary/taint-sources] hasTaintFlow - let var1 = std::env::var("HOME").expect("HOME not set"); // $ MISSING: Alert[rust/summary/taint-sources] - let var2 = std::env::var_os("PATH").unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] + let var1 = std::env::var("HOME").expect("HOME not set"); // $ Alert[rust/summary/taint-sources] + let var2 = std::env::var_os("PATH").unwrap(); // $ Alert[rust/summary/taint-sources] sink(var1); // $ MISSING: hasTaintFlow sink(var2); // $ MISSING: hasTaintFlow - for (key, value) in std::env::vars() { // $ MISSING: Alert[rust/summary/taint-sources] + for (key, value) in std::env::vars() { // $ Alert[rust/summary/taint-sources] sink(key); // $ MISSING: hasTaintFlow sink(value); // $ MISSING: hasTaintFlow } - for (key, value) in std::env::vars_os() { // $ MISSING: Alert[rust/summary/taint-sources] + for (key, value) in std::env::vars_os() { // $ Alert[rust/summary/taint-sources] sink(key); // $ MISSING: hasTaintFlow sink(value); // $ MISSING: hasTaintFlow } } fn test_env_args() { - let args: Vec = std::env::args().collect(); // $ MISSING: Alert[rust/summary/taint-sources] + let args: Vec = std::env::args().collect(); // $ Alert[rust/summary/taint-sources] let my_path = &args[0]; let arg1 = &args[1]; - let arg2 = std::env::args().nth(2).unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] - let arg3 = std::env::args_os().nth(3).unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] + let arg2 = std::env::args().nth(2).unwrap(); // $ Alert[rust/summary/taint-sources] + let arg3 = std::env::args_os().nth(3).unwrap(); // $ Alert[rust/summary/taint-sources] sink(my_path); // $ MISSING: hasTaintFlow sink(arg1); // $ MISSING: hasTaintFlow sink(arg2); // $ MISSING: hasTaintFlow sink(arg3); // $ MISSING: hasTaintFlow - for arg in std::env::args() { // $ MISSING: Alert[rust/summary/taint-sources] + for arg in std::env::args() { // $ Alert[rust/summary/taint-sources] sink(arg); // $ MISSING: hasTaintFlow } - for arg in std::env::args_os() { // $ MISSING: Alert[rust/summary/taint-sources] + for arg in std::env::args_os() { // $ Alert[rust/summary/taint-sources] sink(arg); // $ MISSING: hasTaintFlow } } fn test_env_dirs() { - let dir = std::env::current_dir().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources] - let exe = std::env::current_exe().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources] - let home = std::env::home_dir().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources] + let dir = std::env::current_dir().expect("FAILED"); // $ Alert[rust/summary/taint-sources] + let exe = std::env::current_exe().expect("FAILED"); // $ Alert[rust/summary/taint-sources] + let home = std::env::home_dir().expect("FAILED"); // $ Alert[rust/summary/taint-sources] sink(dir); // $ MISSING: hasTaintFlow sink(exe); // $ MISSING: hasTaintFlow From 176e9a425ffe80a49de258d106d5e34bac822ef1 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:25:58 +0000 Subject: [PATCH 184/470] Rust: Model reqwest. --- rust/ql/lib/codeql/rust/Concepts.qll | 13 +++++++++++++ rust/ql/lib/codeql/rust/Frameworks.qll | 1 + rust/ql/lib/codeql/rust/frameworks/Reqwest.qll | 16 ++++++++++++++++ .../dataflow/sources/TaintSources.expected | 3 +++ .../test/library-tests/dataflow/sources/test.rs | 6 +++--- 5 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/frameworks/Reqwest.qll diff --git a/rust/ql/lib/codeql/rust/Concepts.qll b/rust/ql/lib/codeql/rust/Concepts.qll index 8f35ea589e8..21fd9bd0d39 100644 --- a/rust/ql/lib/codeql/rust/Concepts.qll +++ b/rust/ql/lib/codeql/rust/Concepts.qll @@ -73,6 +73,19 @@ module EnvironmentSource { } } +/** + * A data flow source for remote (network) data. + */ +class RemoteSource extends ThreatModelSource instanceof RemoteSource::Range { } + +module RemoteSource { + abstract class Range extends ThreatModelSource::Range { + override string getThreatModel() { result = "remote" } + + override string getSourceType() { result = "RemoteSource" } + } +} + /** * A data-flow node that constructs a SQL statement. * diff --git a/rust/ql/lib/codeql/rust/Frameworks.qll b/rust/ql/lib/codeql/rust/Frameworks.qll index 4ed5d72b898..601e87ef6eb 100644 --- a/rust/ql/lib/codeql/rust/Frameworks.qll +++ b/rust/ql/lib/codeql/rust/Frameworks.qll @@ -2,4 +2,5 @@ * This file imports all models of frameworks and libraries. */ +private import codeql.rust.frameworks.Reqwest private import codeql.rust.frameworks.stdlib.Env diff --git a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll new file mode 100644 index 00000000000..3f24c1e9e7f --- /dev/null +++ b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll @@ -0,0 +1,16 @@ +/** + * Provides modeling for the `reqwest` library. + */ + +private import rust +private import codeql.rust.Concepts + +/** + * A call to `reqwest::get` or `reqwest::blocking::get`. + */ +private class ReqwestGet extends RemoteSource::Range { + ReqwestGet() { + this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = + ["crate::get", "crate::blocking::get"] + } +} diff --git a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected index 06b84dc590a..e7d561f5f58 100644 --- a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected +++ b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected @@ -12,3 +12,6 @@ | test.rs:50:15:50:37 | CallExpr | CommandLineArgs (commandargs) | | test.rs:51:15:51:37 | CallExpr | CommandLineArgs (commandargs) | | test.rs:52:16:52:35 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:60:26:60:70 | CallExpr | RemoteSource (remote, DEFAULT) | +| test.rs:63:26:63:70 | CallExpr | RemoteSource (remote, DEFAULT) | +| test.rs:66:26:66:60 | CallExpr | RemoteSource (remote, DEFAULT) | diff --git a/rust/ql/test/library-tests/dataflow/sources/test.rs b/rust/ql/test/library-tests/dataflow/sources/test.rs index 00cc96bdc00..e4701865a7e 100644 --- a/rust/ql/test/library-tests/dataflow/sources/test.rs +++ b/rust/ql/test/library-tests/dataflow/sources/test.rs @@ -57,13 +57,13 @@ fn test_env_dirs() { } async fn test_reqwest() -> Result<(), reqwest::Error> { - let remote_string1 = reqwest::blocking::get("http://example.com/")?.text()?; // $ MISSING: Alert[rust/summary/taint-sources] + let remote_string1 = reqwest::blocking::get("http://example.com/")?.text()?; // $ Alert[rust/summary/taint-sources] sink(remote_string1); // $ MISSING: hasTaintFlow - let remote_string2 = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] + let remote_string2 = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap(); // $ Alert[rust/summary/taint-sources] sink(remote_string2); // $ MISSING: hasTaintFlow - let remote_string3 = reqwest::get("http://example.com/").await?.text().await?; // $ MISSING: Alert[rust/summary/taint-sources] + let remote_string3 = reqwest::get("http://example.com/").await?.text().await?; // $ Alert[rust/summary/taint-sources] sink(remote_string3); // $ MISSING: hasTaintFlow Ok(()) From 292b29b0e3d7ba7cbf85f4700bc54e343a82a1f1 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 21 Nov 2024 23:05:08 +0000 Subject: [PATCH 185/470] Rust: Fix following rebase on main. --- rust/ql/lib/codeql/rust/frameworks/Reqwest.qll | 2 +- rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll | 6 +++--- rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll index 3f24c1e9e7f..cb0924f93a1 100644 --- a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll +++ b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll @@ -10,7 +10,7 @@ private import codeql.rust.Concepts */ private class ReqwestGet extends RemoteSource::Range { ReqwestGet() { - this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = + this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::get", "crate::blocking::get"] } } diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll b/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll index b3d1eac8f5d..2319c426248 100644 --- a/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll @@ -10,7 +10,7 @@ private import codeql.rust.Concepts */ private class StdEnvArgs extends CommandLineArgsSource::Range { StdEnvArgs() { - this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::args", "crate::env::args_os"] + this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::args", "crate::env::args_os"] } } @@ -19,7 +19,7 @@ private class StdEnvArgs extends CommandLineArgsSource::Range { */ private class StdEnvDir extends CommandLineArgsSource::Range { StdEnvDir() { - this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::current_dir", "crate::env::current_exe", "crate::env::home_dir"] + this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::current_dir", "crate::env::current_exe", "crate::env::home_dir"] } } @@ -28,6 +28,6 @@ private class StdEnvDir extends CommandLineArgsSource::Range { */ private class StdEnvVar extends EnvironmentSource::Range { StdEnvVar() { - this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::var", "crate::env::var_os", "crate::env::vars", "crate::env::vars_os"] + this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::var", "crate::env::var_os", "crate::env::vars", "crate::env::vars_os"] } } diff --git a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql index 85bb2c9dbf0..1499784ac0e 100644 --- a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql +++ b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql @@ -12,7 +12,7 @@ module MyFlowConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { any(CallExpr call | call.getExpr().(PathExpr).getPath().toString() = "sink") .getArgList() - .getAnArg() = sink.asExpr() + .getAnArg() = sink.asExpr().getExpr() } } From e81c3483dbe2c93f210ecc33841fd06a2e064f9f Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Fri, 22 Nov 2024 09:43:27 +0100 Subject: [PATCH 186/470] Rust: Apply suggestions from PR comments --- .../rust/dataflow/internal/DataFlowImpl.qll | 24 +++++++++---------- .../dataflow/global/inline-flow.expected | 1 - .../library-tests/dataflow/global/main.rs | 2 +- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 35ab9ade7b2..1ec8a42ee7e 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -187,10 +187,10 @@ module Node { * The value of a parameter at function entry, viewed as a node in a data * flow graph. */ - final class NormalParameterNode extends ParameterNode, TParameterNode { + final class PositionalParameterNode extends ParameterNode, TParameterNode { override ParamCfgNode n; - NormalParameterNode() { this = TParameterNode(n) } + PositionalParameterNode() { this = TParameterNode(n) } /** Gets the parameter in the CFG that this node corresponds to. */ ParamCfgNode getParameter() { result = n } @@ -230,10 +230,7 @@ module Node { /** A data flow node that represents a value returned by a callable. */ final class ReturnNode extends ExprNode { - ReturnNode() { - this.getCfgNode().getASuccessor() instanceof ExitCfgNode or - this.getCfgNode().getASuccessor() instanceof AnnotatedExitCfgNode - } + ReturnNode() { this.getCfgNode().getASuccessor() instanceof AnnotatedExitCfgNode } ReturnKind getKind() { any() } } @@ -270,11 +267,11 @@ module Node { /** Gets the node before the state update. */ Node getPreUpdateNode() { result = TExprNode(n) } - final override CfgScope getCfgScope() { result = n.getAstNode().getEnclosingCfgScope() } + final override CfgScope getCfgScope() { result = n.getScope() } - final override Location getLocation() { result = n.getAstNode().getLocation() } + final override Location getLocation() { result = n.getLocation() } - final override string toString() { result = n.getAstNode().toString() } + final override string toString() { result = n.toString() } } final class CastNode = NaNode; @@ -287,7 +284,7 @@ module SsaFlow { private module SsaFlow = SsaImpl::DataFlowIntegration; private Node::ParameterNode toParameterNode(ParamCfgNode p) { - result.(Node::NormalParameterNode).getParameter() = p + result.(Node::PositionalParameterNode).getParameter() = p } /** Converts a control flow node into an SSA control flow node. */ @@ -336,7 +333,8 @@ module LocalFlow { nodeFrom.(Node::AstCfgFlowNode).getCfgNode() = nodeTo.(Node::SsaNode).getDefinitionExt().(Ssa::WriteDefinition).getControlFlowNode() or - nodeFrom.(Node::NormalParameterNode).getParameter().getPat() = nodeTo.(Node::PatNode).getPat() + nodeFrom.(Node::PositionalParameterNode).getParameter().getPat() = + nodeTo.(Node::PatNode).getPat() or SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _) or @@ -376,7 +374,7 @@ module RustDataFlow implements InputSig { /** Holds if `p` is a parameter of `c` at the position `pos`. */ predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) { - p.getCfgNode().getAstNode() = pos.getParameterIn(c.asCfgScope().(Function).getParamList()) + p.getCfgNode().getAstNode() = pos.getParameterIn(c.asCfgScope().(Callable).getParamList()) } /** Holds if `n` is an argument of `c` at the position `pos`. */ @@ -590,7 +588,7 @@ private module Cached { cached newtype TParameterPosition = TPositionalParameterPosition(int i) { - exists(any(ParamList l).getParam(i)) or exists(any(ArgList l).getArg(i)) + i in [0 .. max([any(ParamList l).getNumberOfParams(), any(ArgList l).getNumberOfArgs()]) - 1] } or TSelfParameterPosition() } diff --git a/rust/ql/test/library-tests/dataflow/global/inline-flow.expected b/rust/ql/test/library-tests/dataflow/global/inline-flow.expected index 6054637c126..8c1d90ee45a 100644 --- a/rust/ql/test/library-tests/dataflow/global/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/global/inline-flow.expected @@ -64,7 +64,6 @@ subpaths | main.rs:41:26:44:5 | BlockExpr : unit | main.rs:30:17:30:22 | Param : unit | main.rs:30:32:32:1 | BlockExpr : unit | main.rs:41:13:44:6 | CallExpr : unit | | main.rs:90:29:90:29 | a : unit | main.rs:66:28:66:33 | Param : unit | main.rs:66:43:72:5 | BlockExpr : unit | main.rs:90:13:90:30 | ... .data_through(...) : unit | testFailures -| main.rs:45:10:45:10 | a | Fixed missing result: hasValueFlow=14 | #select | main.rs:18:10:18:10 | a | main.rs:13:5:13:13 | CallExpr : unit | main.rs:18:10:18:10 | a | $@ | main.rs:13:5:13:13 | CallExpr : unit | CallExpr : unit | | main.rs:22:10:22:10 | n | main.rs:26:13:26:21 | CallExpr : unit | main.rs:22:10:22:10 | n | $@ | main.rs:26:13:26:21 | CallExpr : unit | CallExpr : unit | diff --git a/rust/ql/test/library-tests/dataflow/global/main.rs b/rust/ql/test/library-tests/dataflow/global/main.rs index ebdb7b30d75..77c37a945b8 100644 --- a/rust/ql/test/library-tests/dataflow/global/main.rs +++ b/rust/ql/test/library-tests/dataflow/global/main.rs @@ -42,7 +42,7 @@ fn block_expression_as_argument() { println!("Hello"); source(14) }); - sink(a); // $ MISSING: hasValueFlow=14 + sink(a); // $ hasValueFlow=14 } // ----------------------------------------------------------------------------- From 20eaaa56999e0774b9bf416b7653a5b5fd75366b Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 09:22:11 +0000 Subject: [PATCH 187/470] Rust: Use final extensions. --- rust/ql/lib/codeql/rust/Concepts.qll | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/ql/lib/codeql/rust/Concepts.qll b/rust/ql/lib/codeql/rust/Concepts.qll index 21fd9bd0d39..a9ec8dfe530 100644 --- a/rust/ql/lib/codeql/rust/Concepts.qll +++ b/rust/ql/lib/codeql/rust/Concepts.qll @@ -50,7 +50,7 @@ class ActiveThreatModelSource extends ThreatModelSource { /** * A data flow source corresponding to the program's command line arguments or path. */ -class CommandLineArgsSource extends ThreatModelSource instanceof CommandLineArgsSource::Range { } +final class CommandLineArgsSource = CommandLineArgsSource::Range; module CommandLineArgsSource { abstract class Range extends ThreatModelSource::Range { @@ -63,7 +63,7 @@ module CommandLineArgsSource { /** * A data flow source corresponding to the program's environment. */ -class EnvironmentSource extends ThreatModelSource instanceof EnvironmentSource::Range { } +final class EnvironmentSource = EnvironmentSource::Range; module EnvironmentSource { abstract class Range extends ThreatModelSource::Range { @@ -76,7 +76,7 @@ module EnvironmentSource { /** * A data flow source for remote (network) data. */ -class RemoteSource extends ThreatModelSource instanceof RemoteSource::Range { } +final class RemoteSource = RemoteSource::Range; module RemoteSource { abstract class Range extends ThreatModelSource::Range { From e49a5be62f4cd70a4c9e3564f06299364139282b Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 22 Nov 2024 12:16:12 +0100 Subject: [PATCH 188/470] Rust: fix parent/child relationship for format entities --- rust/ql/.generated.list | 32 +++++++++++-------- rust/ql/.gitattributes | 12 +++++-- .../internal/generated/CfgNodes.qll | 21 +++++++++++- rust/ql/lib/codeql/rust/elements/Format.qll | 1 + .../codeql/rust/elements/FormatArgsExpr.qll | 7 +++- .../codeql/rust/elements/FormatArgument.qll | 1 + .../elements/internal/FormatArgsExprImpl.qll | 14 ++++---- .../elements/internal/FormatArgumentImpl.qll | 2 ++ .../rust/elements/internal/FormatImpl.qll | 2 ++ .../elements/internal/generated/Format.qll | 11 +++++++ .../internal/generated/FormatArgsExpr.qll | 22 ++++++++++++- .../internal/generated/FormatArgument.qll | 11 +++++++ .../internal/generated/ParentChild.qll | 16 ++++++++-- .../rust/elements/internal/generated/Raw.qll | 6 +++- .../generated/.generated_tests.list | 6 ++-- .../extractor-tests/generated/.gitattributes | 4 ++- .../generated/FormatArgsExpr/Format.expected | 9 ++++++ .../generated/FormatArgsExpr/Format.ql | 12 +++++++ .../FormatArgsExpr/FormatArgsArg.expected | 8 +++++ .../FormatArgsArg.ql | 0 .../FormatArgsArg_getExpr.expected | 8 +++++ .../FormatArgsArg_getExpr.ql | 0 .../FormatArgsArg_getName.expected | 2 ++ .../FormatArgsArg_getName.ql | 0 .../FormatArgsExpr/FormatArgsExpr.expected | 7 ++++ .../FormatArgsExpr/FormatArgsExpr.ql | 9 ++++-- .../FormatArgsExpr_getArg.expected | 8 +++++ .../FormatArgsExpr_getFormat.expected | 9 ++++++ .../FormatArgsExpr_getFormat.ql | 7 ++++ .../FormatArgsExpr_getTemplate.expected | 7 ++++ .../FormatArgsExpr_getVariable.expected | 5 +++ .../FormatArgsExpr/FormatArgument.expected | 10 ++++++ .../FormatArgsExpr/FormatArgument.ql | 11 +++++++ .../FormatArgument_getVariable.expected | 5 +++ .../FormatArgument_getVariable.ql | 7 ++++ .../FormatTemplateVariableAccess.expected | 5 +++ .../FormatTemplateVariableAccess.ql | 7 ++++ .../Format_getArgument.expected | 10 ++++++ .../FormatArgsExpr/Format_getArgument.ql | 7 ++++ .../generated/FormatArgsExpr/gen_format.rs | 6 ++++ .../gen_format_args_arg.rs | 0 .../FormatArgsExpr/gen_format_args_expr.rs | 6 +++- .../FormatArgsExpr/gen_format_argument.rs | 8 +++++ rust/schema/annotations.py | 17 +++++++--- 44 files changed, 317 insertions(+), 41 deletions(-) create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.expected create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.ql create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg.expected rename rust/ql/test/extractor-tests/generated/{FormatArgsArg => FormatArgsExpr}/FormatArgsArg.ql (100%) create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getExpr.expected rename rust/ql/test/extractor-tests/generated/{FormatArgsArg => FormatArgsExpr}/FormatArgsArg_getExpr.ql (100%) create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getName.expected rename rust/ql/test/extractor-tests/generated/{FormatArgsArg => FormatArgsExpr}/FormatArgsArg_getName.ql (100%) create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getFormat.expected create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getFormat.ql create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getVariable.expected create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument.expected create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument.ql create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument_getVariable.expected create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument_getVariable.ql create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatTemplateVariableAccess.expected create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatTemplateVariableAccess.ql create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.expected create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/gen_format.rs rename rust/ql/test/extractor-tests/generated/{FormatArgsArg => FormatArgsExpr}/gen_format_args_arg.rs (100%) create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/gen_format_argument.rs diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index e3fe15f3e5b..1d4dabf2871 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -1,4 +1,4 @@ -lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll e7bcae1016e1853d46d9c91dc5f9b81e81d207fdf91fdaa6eadb3bf185879674 541d386db1f0b662d0cbe1aface1bc6e4b1bc484d1230b95523f35ca63c08875 +lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll a2d9717410e73aca512cad3af633700158ddd80b1c07dfd6ebe0f84723b4ac5b 3cfd6ae768958db3a4d633b4d781a8f4be80eb7a0d2ee871773584128e4551fd lib/codeql/rust/elements/Abi.qll 4c973d28b6d628f5959d1f1cc793704572fd0acaae9a97dfce82ff9d73f73476 250f68350180af080f904cd34cb2af481c5c688dc93edf7365fd0ae99855e893 lib/codeql/rust/elements/ArgList.qll 661f5100f5d3ef8351452d9058b663a2a5c720eea8cf11bedd628969741486a2 28e424aac01a90fb58cd6f9f83c7e4cf379eea39e636bc0ba07efc818be71c71 lib/codeql/rust/elements/ArrayExpr.qll a3e6e122632f4011644ec31b37f88b32fe3f2b7e388e7e878a6883309937049f 12ccb5873d95c433da5606fd371d182ef2f71b78d0c53c2d6dec10fa45852bdc @@ -41,10 +41,10 @@ lib/codeql/rust/elements/FieldList.qll bd243adc4696c60f636055a1c2da28039fe202847 lib/codeql/rust/elements/FnPtrType.qll c4a90dc660cf620972dc23b95494f5caf9f050eabd4bdb52fdc061f8797ba9a1 f8defc91582fa503607664668f9e2e6c2cd8b320c7c449610f21e52e332a129f lib/codeql/rust/elements/ForExpr.qll 312804d53dd9236a2f2a15c9d6ec348b46e139a54eb5893e7e12487725df7444 fa5e20099b1179033bc209bad3548e3d1d4019c7fe0e455cec8ca1a9d48692ab lib/codeql/rust/elements/ForType.qll 0036bed8749358c356d78c4a0eef40d73e2796284293cde5604ae70ddd6d0470 4edcaf8f7c67d42ebe3ebb1be6a7643758717d4fe88f5f648b6a1c5ff4ee4de7 -lib/codeql/rust/elements/Format.qll 506172d176f4b965f428585c032464f4abe07a0e47c574f8e011d8641ec45370 653e81bf233b8729649064de64f4a7a8533f8864ac6d2ea913f347088c924c60 +lib/codeql/rust/elements/Format.qll 51222fa2d2e85d496ab093d74d3bc606ede3ce48f926106e059dc8478e657203 b4da6be38413c86f2e9d82004624abab16e23ef238197a5c85246009cce276d5 lib/codeql/rust/elements/FormatArgsArg.qll 5bc9b4cd1bac7131165836e93838c45452a08ea6011741cbddace3cbf9c69440 f825140e98dc9800d5c045402186793c7b21511448e2f6bf6402d1e06305219c -lib/codeql/rust/elements/FormatArgsExpr.qll f2ffad5a1105b29a8437c8ed6cf918cfcf4d65ac164bbf1be0585c3b673ca749 3ba20dc312a0a994bb43b37b2db72cbd4e06061b97918fa0e84ce355070ffbeb -lib/codeql/rust/elements/FormatArgument.qll bdd93e1da78637f19beee6f953d3a45512100e925d90cb5ad08a097f412009b8 2a0ae7eb885615e380f925c0d130a1b795bf3c395486550a1f1c9c82848f8d77 +lib/codeql/rust/elements/FormatArgsExpr.qll 8127cbe4082f7acc3d8a05298c2c9bea302519b8a6cd2d158a83c516d18fc487 88cf9b3bedd69a1150968f9a465c904bbb6805da0e0b90cfd1fc0dab1f6d9319 +lib/codeql/rust/elements/FormatArgument.qll f6fe17ee1481c353dd42edae8b5fa79aeb99dff25b4842ec9a6f267b1837d1e3 5aed19c2daf2383b89ad7fd527375641cff26ddee7afddb89bc0d18d520f4034 lib/codeql/rust/elements/FormatTemplateVariableAccess.qll ff3218a1dda30c232d0ecd9d1c60bbb9f3973456ef0bee1d1a12ad14b1e082b5 e4316291c939800d8b34d477d92be9404a30d52b7eee37302aef3d3205cf4ae0 lib/codeql/rust/elements/Function.qll 2c76c2c7036891996b1f0ebde16c414edf37ebb44ff9c3483088dc6218733e07 d84d017d98aa240bf3bee6502a030aa8cfb7ed95425ffa9853e73b41485e1f4a lib/codeql/rust/elements/GenericArg.qll 5f11ce0e3c5f08de84db61f56ba1b984652455ba6b95a8b8a5b5a235913d4072 756b6a73d66fde45bdcc65ce2362a5b1391af2927e6d54b6550b3ecd5fd11e75 @@ -494,10 +494,10 @@ lib/codeql/rust/elements/internal/generated/FieldList.qll 43c13c6e3c9ba75a7a4cb8 lib/codeql/rust/elements/internal/generated/FnPtrType.qll 748d766dbefd19a7d644734c57885eeede66897029bbfe1b87919517f43bfde2 5a7d80acc00e56594ed85026a8ea4923104d2e98c2e42db8c5bcd32ddd164e48 lib/codeql/rust/elements/internal/generated/ForExpr.qll 541b62b48911d4999f9ed64ab6c8b9910073ac4add0225761f319677328cf120 976c3a91c9eedfb1e2d9ea76ac501348643b3d23c723d7a777042258d416d091 lib/codeql/rust/elements/internal/generated/ForType.qll 3d43d044a1189281f09c55caafb6c8020a836f49e2866077086101925a573cf2 646b59bfd1b428aaf7211f574c49f79cb4c6a79ca151aa0663b2b31480298721 -lib/codeql/rust/elements/internal/generated/Format.qll 37ad20cf2bf363b4027a8913d095292c8a4eb8ccdf2a9965f2fb7d41930f9bfe 329b89cdd75ce951269273dd18897e32ff5cfcc94f451001c64143386c1e48dd +lib/codeql/rust/elements/internal/generated/Format.qll df7ef61e6ba61fa0eb093f8e6b3e7a0329104e03f659c9507db9535b8b4ea759 ef8ddd98405fc84938ad8cd5f87d2858e01d06a6bb00566a785a984b60a79dc6 lib/codeql/rust/elements/internal/generated/FormatArgsArg.qll e07a1ae310f590003f1b88fada7dcf4847c99adb9d4c838d1c88e66e1da85c5f 0ef7342451fe2cb06e765fb4b33bb8c4a9b927f5edbc8feb5c6ba3655697f447 -lib/codeql/rust/elements/internal/generated/FormatArgsExpr.qll 40d6daa7d2bafb33798a21d79774dc802cfbd7a31618ac3bd0149399ea2bf893 d1172e2151791228559004792e125fc4625f6a26ffad25f29efb0ad263bf8795 -lib/codeql/rust/elements/internal/generated/FormatArgument.qll 00646f38217a66978b8b2648cca39dddbed22ece693b26cb682f019fbfedda95 e364e085f967847a7ed21b76156a9203d64032f0f0eea357b4779885a41bf9a7 +lib/codeql/rust/elements/internal/generated/FormatArgsExpr.qll 8aed8715a27d3af3de56ded4610c6792a25216b1544eb7e57c8b0b37c14bd9c1 590a2b0063d2ecd00bbbd1ce29603c8fd69972e34e6daddf309c915ce4ec1375 +lib/codeql/rust/elements/internal/generated/FormatArgument.qll cd05153276e63e689c95d5537fbc7d892615f62e110323759ef02e23a7587407 be2a4531b498f01625effa4c631d51ee8857698b00cfb829074120a0f2696d57 lib/codeql/rust/elements/internal/generated/FormatTemplateVariableAccess.qll a6175214fad445df9234b3ee9bf5147da75baf82473fb8d384b455e3add0dac1 a928db0ff126b2e54a18f5c488232abd1bd6c5eda24591d3c3bb80c6ee71c770 lib/codeql/rust/elements/internal/generated/Function.qll f285ee0c771f897eba6db34a7e98f3cfb7db91b0df252ff4b37fc9d779de0bfb 07401e832565ff376acda219514c2e2bbe4ae5058c76a73b40ca6ca66f1626c7 lib/codeql/rust/elements/internal/generated/GenericArg.qll 464da0ba1c5ddcd1be68617167f177773d99b5ac4775ec8ea24d503e789a9099 6faa1033d59baf7c210ac4837a55781cfc054b7acbad8027faf4630dbfa6e101 @@ -549,7 +549,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60 lib/codeql/rust/elements/internal/generated/ParenPat.qll ce24b8f8ecbf0f204af200317405724063887257460c80cf250c39b2fdf37185 e7c87d37e1a0ca7ea03840017e1aa9ddb7f927f1f3b6396c0305b46aeee33db6 lib/codeql/rust/elements/internal/generated/ParenType.qll 9cc954d73f8330dcac7b475f97748b63af5c8766dee9d2f2872c0a7e4c903537 c07534c8a9c683c4a9b11d490095647e420de0a0bfc23273eaf6f31b00244273 -lib/codeql/rust/elements/internal/generated/ParentChild.qll b4d25c43ed44715053255c3c2f8aeb8d21826adc365f24026b2123a4f25cba86 1bc4bb0380a1a8b69055ffeac203b11b2a1b94e5ad88d1b32ff659e8feb26016 +lib/codeql/rust/elements/internal/generated/ParentChild.qll c1eca840f6c97dc3c7fec5deaf1be98c17558610ffc37b503571779afdadc912 9564f6ae3803505c2bc086b76e43570127a13374655d2013c77ce1863e0c1397 lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4 lib/codeql/rust/elements/internal/generated/Path.qll f2b1be2f8f44001a6533533c978c4a9a8b7d64838d6f39eef5f0c0e7890611b8 d724a00a38f42429ffa8fb3bffbb5ec69e16a32ceeeb1d1f026fc7adf87424a8 lib/codeql/rust/elements/internal/generated/PathExpr.qll 2096e3c1db22ee488a761690adabfc9cfdea501c99f7c5d96c0019cb113fc506 54245ce0449c4e263173213df01e079d5168a758503a5dbd61b25ad35a311140 @@ -562,7 +562,7 @@ lib/codeql/rust/elements/internal/generated/PtrType.qll 40099c5a4041314b66932dfd lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll efd93730de217cf50dcba5875595263a5eadf9f7e4e1272401342a094d158614 229b251b3d118932e31e78ac4dfb75f48b766f240f20d436062785606d44467b -lib/codeql/rust/elements/internal/generated/Raw.qll 5f83209cda8319c5c6c932631b60c6f2163d2d9cf7be63f63523e2206c01d004 3581039746e86365f37644e86ac2c89d67e2123aa1b039d9e0afdffc7156c96d +lib/codeql/rust/elements/internal/generated/Raw.qll d679e866776a927f61d62ba980203e1142454606bdac69cc9b6720679ca5bbdd f47922df7f8c8efba0e2e5adde030247e43f02e9df7d263096c697bfe65c4277 lib/codeql/rust/elements/internal/generated/RecordExpr.qll eb6cb662e463f9260efae1a6ce874fa781172063b916ef1963f861e9942d308d 1a21cbccc8f3799ff13281e822818ebfb21d81591720a427cac3625512cb9d40 lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1 lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0 @@ -752,13 +752,19 @@ test/extractor-tests/generated/ForExpr/ForExpr_getPat.ql 1e0205a9b3a58fd2ddba49e test/extractor-tests/generated/ForType/ForType.ql ba930d0c4fe52d57449ce4025b1c3e49c688afc5ef18ee8ac1ed7a9fd3eb8d41 08e9aa0301a942f6f9564ddeddc69606f3e2916e1b551cc56ae3b6048c56ce61 test/extractor-tests/generated/ForType/ForType_getGenericParamList.ql e25cd79737bbae92d8f417c6bbf6fb8ae660976b8005cd91d0900c7076fdd827 b1e32b7e3ca9f29a4564f83e37ae53de6baf04837a393e6dedc64a01cc7d10e8 test/extractor-tests/generated/ForType/ForType_getTy.ql e932d3412828bb83afc42e2dc1a4cbe9fcf25ec9a9617ec138722f834091a61a 298fc9df34b2cb436c8f180c4d229341ee4a73e3c451b905f017f32a6f65056c -test/extractor-tests/generated/FormatArgsArg/FormatArgsArg.ql a521903c73f79e2616f7b8ef76790e11cbf432f8437825d52d117da232022b9e 4cb195d09ecb51e5bbd5c1c069ec1720f74fc074efc88b0f5c07cfc140167775 -test/extractor-tests/generated/FormatArgsArg/FormatArgsArg_getExpr.ql 7e1a7f902fb661660760d2a2f3f4cb6818a0c9f5b5061ede6ae80223774e4e09 8a50f64cba6f56320631206c801160201e3c98e74367bb035d689baaa9b4e411 -test/extractor-tests/generated/FormatArgsArg/FormatArgsArg_getName.ql 0e2f24388d516e14d195957163a2d5d97029c9e11a83ca71cf69e00ecc0bb2a8 dab2969f5ae6a15ec331c0152e7c116d1ee2c3d073b2d4da59ffbcb83404c65f -test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr.ql 0cd439f61569ecf046e9548c458329647f331bfa034ae8b3d4f7628595881287 013a948607e1ac96100ea9a8cd3c8f357e378ac21baa015dcf4927022c2bdafb +test/extractor-tests/generated/FormatArgsExpr/Format.ql 25268dd7ad2a58b071c3a38164944c1b7389dfdda01c99ef2694a475596341b4 0a3f674d5a4f005835b9a5ba11a6e8bf58477829258f30ae7d8f76f8986f7b7f +test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg.ql a521903c73f79e2616f7b8ef76790e11cbf432f8437825d52d117da232022b9e 4cb195d09ecb51e5bbd5c1c069ec1720f74fc074efc88b0f5c07cfc140167775 +test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getExpr.ql 7e1a7f902fb661660760d2a2f3f4cb6818a0c9f5b5061ede6ae80223774e4e09 8a50f64cba6f56320631206c801160201e3c98e74367bb035d689baaa9b4e411 +test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getName.ql 0e2f24388d516e14d195957163a2d5d97029c9e11a83ca71cf69e00ecc0bb2a8 dab2969f5ae6a15ec331c0152e7c116d1ee2c3d073b2d4da59ffbcb83404c65f +test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr.ql 7b6f09b23d0dffa19b8dddf7f5cfe53068f8a8e5279e235c6d54e60616bd0822 47db74f035770ce708a00355acbfd4ae99152b7eb29cf28001985806a4efe5aa test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getArg.ql 8f692486be1546b914b17abdff4a989dfbaa889bfa1fc44597f4357806c1a1dd da9fd237e31e9c8dd0ef0c3c968157815b87d3e8dcdfd74674c988ce2ab6d270 test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getAttr.ql 1f9bf1344f942e65c3a3591b6ae04d3f5a2a1a65459bce0d976698de7d8a5958 02acb861d8ab4d32cf144c589881a888c3da5e2ade27e8c85fec3ae45219bb3b +test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getFormat.ql 02d3fad540700966488b24c62dcf200548154a2f10f578ee2995d8c4ebe32287 cccfe779b9804c2bb968a2b1f54da8a72393805c2c8b31d7160e8538f2f335f2 test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getTemplate.ql c912ac37275cbe7b3b29607bed1a3190c80779436422c14a475113e1bfd91a54 ef90f67a9b952a38ce557b1afbf0b5ce8551e83ddfaad8309a0c9523e40b5ea7 +test/extractor-tests/generated/FormatArgsExpr/FormatArgument.ql 7a7ee3a3322b4af8cb3b525cfed8cc9719d136ea80aa6b3fb30c7e16394dd93f 5aa8a77d7741b02f8ceb9e5991efa4c2c43c6f1624989218990e985108dae535 +test/extractor-tests/generated/FormatArgsExpr/FormatArgument_getVariable.ql 7bd4ec3dde2ef0463585794101e6cc426c368b0e4ab95fbb1f24f8f0a76cf471 e7b01e8b21df5b22c51643e2c909c6fc4ca96fda41b3290c907ba228abe8669b +test/extractor-tests/generated/FormatArgsExpr/FormatTemplateVariableAccess.ql 2793ba1ff52182dab992d82d3767a000928f6b2fbfdb621349cafc183f0d2480 c3777d03214f7feb9020de3ce45af6556129e39e9b30d083de605b70ab9a0a12 +test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql 26d592398a17795427b5b6b51ff4a013ee15c31443e732a000baca5f2e65acca 7940a864b84b89e84d7fb186599cb8b6bcbead7141c592b8ab0c59fcd380d5fb test/extractor-tests/generated/Function/Function.ql c1c2a9b68c35f839ccd2b5e62e87d1acd94dcc2a3dc4c307c269b84b2a0806e6 1c446f19d2f81dd139aa5a1578d1b165e13bddbaeab8cfee8f0430bced3a99ab test/extractor-tests/generated/Function/Function_getAbi.ql e5c9c97de036ddd51cae5d99d41847c35c6b2eabbbd145f4467cb501edc606d8 0b81511528bd0ef9e63b19edfc3cb638d8af43eb87d018fad69d6ef8f8221454 test/extractor-tests/generated/Function/Function_getAttr.ql 44067ee11bdec8e91774ff10de0704a8c5c1b60816d587378e86bf3d82e1f660 b4bebf9441bda1f2d1e34e9261e07a7468cbabf53cf8047384f3c8b11869f04e diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 68b893ba9c7..5e2e30e2ffe 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -754,13 +754,19 @@ /test/extractor-tests/generated/ForType/ForType.ql linguist-generated /test/extractor-tests/generated/ForType/ForType_getGenericParamList.ql linguist-generated /test/extractor-tests/generated/ForType/ForType_getTy.ql linguist-generated -/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg.ql linguist-generated -/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg_getExpr.ql linguist-generated -/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg_getName.ql linguist-generated +/test/extractor-tests/generated/FormatArgsExpr/Format.ql linguist-generated +/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg.ql linguist-generated +/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getExpr.ql linguist-generated +/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getName.ql linguist-generated /test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr.ql linguist-generated /test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getArg.ql linguist-generated /test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getAttr.ql linguist-generated +/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getFormat.ql linguist-generated /test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getTemplate.ql linguist-generated +/test/extractor-tests/generated/FormatArgsExpr/FormatArgument.ql linguist-generated +/test/extractor-tests/generated/FormatArgsExpr/FormatArgument_getVariable.ql linguist-generated +/test/extractor-tests/generated/FormatArgsExpr/FormatTemplateVariableAccess.ql linguist-generated +/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql linguist-generated /test/extractor-tests/generated/Function/Function.ql linguist-generated /test/extractor-tests/generated/Function/Function_getAbi.ql linguist-generated /test/extractor-tests/generated/Function/Function_getAttr.ql linguist-generated diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll index b42a00bf551..2cbb9e9d3bd 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll @@ -928,7 +928,11 @@ module MakeCfgNodes Input> { /** * A FormatArgsExpr. For example: * ```rust - * todo!() + * format_args!("no args"); + * format_args!("{} foo {:?}", 1, 2); + * format_args!("{b} foo {a:?}", a=1, b=2); + * let (x, y) = (1, 42); + * format_args!("{x}, {y}"); * ``` */ final class FormatArgsExprCfgNode extends CfgNodeFinal, ExprCfgNode { @@ -980,6 +984,21 @@ module MakeCfgNodes Input> { * Holds if `getTemplate()` exists. */ predicate hasTemplate() { exists(this.getTemplate()) } + + /** + * Gets the `index`th format of this format arguments expression (0-based). + */ + Format getFormat(int index) { result = node.getFormat(index) } + + /** + * Gets any of the formats of this format arguments expression. + */ + Format getAFormat() { result = this.getFormat(_) } + + /** + * Gets the number of formats of this format arguments expression. + */ + int getNumberOfFormats() { result = count(int i | exists(this.getFormat(i))) } } final private class ParentFormatTemplateVariableAccess extends ParentAstNode, diff --git a/rust/ql/lib/codeql/rust/elements/Format.qll b/rust/ql/lib/codeql/rust/elements/Format.qll index 0c8b5d1c541..f8b705be4fd 100644 --- a/rust/ql/lib/codeql/rust/elements/Format.qll +++ b/rust/ql/lib/codeql/rust/elements/Format.qll @@ -5,6 +5,7 @@ private import internal.FormatImpl import codeql.rust.elements.FormatArgsExpr +import codeql.rust.elements.FormatArgument import codeql.rust.elements.Locatable /** diff --git a/rust/ql/lib/codeql/rust/elements/FormatArgsExpr.qll b/rust/ql/lib/codeql/rust/elements/FormatArgsExpr.qll index 226b4d211aa..419a48a5335 100644 --- a/rust/ql/lib/codeql/rust/elements/FormatArgsExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/FormatArgsExpr.qll @@ -6,12 +6,17 @@ private import internal.FormatArgsExprImpl import codeql.rust.elements.Attr import codeql.rust.elements.Expr +import codeql.rust.elements.Format import codeql.rust.elements.FormatArgsArg /** * A FormatArgsExpr. For example: * ```rust - * todo!() + * format_args!("no args"); + * format_args!("{} foo {:?}", 1, 2); + * format_args!("{b} foo {a:?}", a=1, b=2); + * let (x, y) = (1, 42); + * format_args!("{x}, {y}"); * ``` */ final class FormatArgsExpr = Impl::FormatArgsExpr; diff --git a/rust/ql/lib/codeql/rust/elements/FormatArgument.qll b/rust/ql/lib/codeql/rust/elements/FormatArgument.qll index 62313c52372..00e9007434b 100644 --- a/rust/ql/lib/codeql/rust/elements/FormatArgument.qll +++ b/rust/ql/lib/codeql/rust/elements/FormatArgument.qll @@ -5,6 +5,7 @@ private import internal.FormatArgumentImpl import codeql.rust.elements.Format +import codeql.rust.elements.FormatTemplateVariableAccess import codeql.rust.elements.Locatable /** diff --git a/rust/ql/lib/codeql/rust/elements/internal/FormatArgsExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/FormatArgsExprImpl.qll index 667439777b1..59e020fb9e4 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/FormatArgsExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/FormatArgsExprImpl.qll @@ -16,16 +16,16 @@ module Impl { /** * A FormatArgsExpr. For example: * ```rust - * todo!() + * format_args!("no args"); + * format_args!("{} foo {:?}", 1, 2); + * format_args!("{b} foo {a:?}", a=1, b=2); + * let (x, y) = (1, 42); + * format_args!("{x}, {y}"); * ``` */ class FormatArgsExpr extends Generated::FormatArgsExpr { - /** - * Gets the `index`th format of this `FormatArgsExpr`'s formatting template (0-based). - */ - Format getFormat(int index) { - result = - rank[index + 1](Format f, int i | f.getParent() = this and f.getIndex() = i | f order by i) + override Format getFormat(int index) { + result.getParent() = this and result.getIndex() = index + 1 } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/FormatArgumentImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/FormatArgumentImpl.qll index 7370939716d..6719d9d8cb3 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/FormatArgumentImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/FormatArgumentImpl.qll @@ -39,6 +39,8 @@ module Impl { override string toString() { result = name } override Format getParent() { result = Synth::TFormat(parent, index, _, _) } + + override FormatTemplateVariableAccess getVariable() { result.getArgument() = this } } private class FormatSynthLocationImpl extends FormatArgument, LocatableImpl::SynthLocatable { diff --git a/rust/ql/lib/codeql/rust/elements/internal/FormatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/FormatImpl.qll index 59c66768f05..7cde91053e9 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/FormatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/FormatImpl.qll @@ -38,6 +38,8 @@ module Impl { override int getIndex() { result = index } + override FormatArgument getArgument() { result.getParent() = this } + /** * Gets the name or position reference of this format, if any. For example `name` and `0` in: * ```rust diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Format.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Format.qll index f2ade708ffa..41c748d7fde 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Format.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Format.qll @@ -7,6 +7,7 @@ private import codeql.rust.elements.internal.generated.Synth private import codeql.rust.elements.internal.generated.Raw import codeql.rust.elements.FormatArgsExpr +import codeql.rust.elements.FormatArgument import codeql.rust.elements.internal.LocatableImpl::Impl as LocatableImpl /** @@ -34,5 +35,15 @@ module Generated { * Gets the index of this format. */ int getIndex() { none() } + + /** + * Gets the argument of this format, if it exists. + */ + FormatArgument getArgument() { none() } + + /** + * Holds if `getArgument()` exists. + */ + final predicate hasArgument() { exists(this.getArgument()) } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/FormatArgsExpr.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/FormatArgsExpr.qll index 7fe088e2541..38034779e05 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/FormatArgsExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/FormatArgsExpr.qll @@ -9,6 +9,7 @@ private import codeql.rust.elements.internal.generated.Raw import codeql.rust.elements.Attr import codeql.rust.elements.Expr import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl +import codeql.rust.elements.Format import codeql.rust.elements.FormatArgsArg /** @@ -19,7 +20,11 @@ module Generated { /** * A FormatArgsExpr. For example: * ```rust - * todo!() + * format_args!("no args"); + * format_args!("{} foo {:?}", 1, 2); + * format_args!("{b} foo {a:?}", a=1, b=2); + * let (x, y) = (1, 42); + * format_args!("{x}, {y}"); * ``` * INTERNAL: Do not reference the `Generated::FormatArgsExpr` class directly. * Use the subclass `FormatArgsExpr`, where the following predicates are available. @@ -81,5 +86,20 @@ module Generated { * Holds if `getTemplate()` exists. */ final predicate hasTemplate() { exists(this.getTemplate()) } + + /** + * Gets the `index`th format of this format arguments expression (0-based). + */ + Format getFormat(int index) { none() } + + /** + * Gets any of the formats of this format arguments expression. + */ + final Format getAFormat() { result = this.getFormat(_) } + + /** + * Gets the number of formats of this format arguments expression. + */ + final int getNumberOfFormats() { result = count(int i | exists(this.getFormat(i))) } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/FormatArgument.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/FormatArgument.qll index 658d6b92e7a..a1db224494b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/FormatArgument.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/FormatArgument.qll @@ -7,6 +7,7 @@ private import codeql.rust.elements.internal.generated.Synth private import codeql.rust.elements.internal.generated.Raw import codeql.rust.elements.Format +import codeql.rust.elements.FormatTemplateVariableAccess import codeql.rust.elements.internal.LocatableImpl::Impl as LocatableImpl /** @@ -33,5 +34,15 @@ module Generated { * Gets the parent of this format argument. */ Format getParent() { none() } + + /** + * Gets the variable of this format argument, if it exists. + */ + FormatTemplateVariableAccess getVariable() { none() } + + /** + * Holds if `getVariable()` exists. + */ + final predicate hasVariable() { exists(this.getVariable()) } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll index 470207683ae..a396da834d4 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll @@ -52,14 +52,17 @@ private module Impl { } private Element getImmediateChildOfFormat(Format e, int index, string partialPredicateCall) { - exists(int b, int bLocatable, int n | + exists(int b, int bLocatable, int n, int nArgument | b = 0 and bLocatable = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLocatable(e, i, _)) | i) and n = bLocatable and + nArgument = n + 1 and ( none() or result = getImmediateChildOfLocatable(e, index - b, partialPredicateCall) + or + index = n and result = e.getArgument() and partialPredicateCall = "Argument()" ) ) } @@ -67,14 +70,17 @@ private module Impl { private Element getImmediateChildOfFormatArgument( FormatArgument e, int index, string partialPredicateCall ) { - exists(int b, int bLocatable, int n | + exists(int b, int bLocatable, int n, int nVariable | b = 0 and bLocatable = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLocatable(e, i, _)) | i) and n = bLocatable and + nVariable = n + 1 and ( none() or result = getImmediateChildOfLocatable(e, index - b, partialPredicateCall) + or + index = n and result = e.getVariable() and partialPredicateCall = "Variable()" ) ) } @@ -1761,13 +1767,14 @@ private module Impl { private Element getImmediateChildOfFormatArgsExpr( FormatArgsExpr e, int index, string partialPredicateCall ) { - exists(int b, int bExpr, int n, int nArg, int nAttr, int nTemplate | + exists(int b, int bExpr, int n, int nArg, int nAttr, int nTemplate, int nFormat | b = 0 and bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and n = bExpr and nArg = n + 1 + max(int i | i = -1 or exists(e.getArg(i)) | i) and nAttr = nArg + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and nTemplate = nAttr + 1 and + nFormat = nTemplate + 1 + max(int i | i = -1 or exists(e.getFormat(i)) | i) and ( none() or @@ -1780,6 +1787,9 @@ private module Impl { partialPredicateCall = "Attr(" + (index - nArg).toString() + ")" or index = nAttr and result = e.getTemplate() and partialPredicateCall = "Template()" + or + result = e.getFormat(index - nTemplate) and + partialPredicateCall = "Format(" + (index - nTemplate).toString() + ")" ) ) } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index 25af8ddac64..efcdd4818dc 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -1885,7 +1885,11 @@ module Raw { * INTERNAL: Do not use. * A FormatArgsExpr. For example: * ```rust - * todo!() + * format_args!("no args"); + * format_args!("{} foo {:?}", 1, 2); + * format_args!("{b} foo {a:?}", a=1, b=2); + * let (x, y) = (1, 42); + * format_args!("{x}, {y}"); * ``` */ class FormatArgsExpr extends @format_args_expr, Expr { diff --git a/rust/ql/test/extractor-tests/generated/.generated_tests.list b/rust/ql/test/extractor-tests/generated/.generated_tests.list index b60779ebd86..bfbe339bcc8 100644 --- a/rust/ql/test/extractor-tests/generated/.generated_tests.list +++ b/rust/ql/test/extractor-tests/generated/.generated_tests.list @@ -31,8 +31,10 @@ FieldExpr/gen_field_expr.rs 9a70500d592e0a071b03d974a55558b3bc0df531ff11bce5898f FnPtrType/gen_fn_ptr_type.rs a7842d8c21636739d1be959e5ce5e0b23482d5ef6eab5c45b009895da8175932 a7842d8c21636739d1be959e5ce5e0b23482d5ef6eab5c45b009895da8175932 ForExpr/gen_for_expr.rs 67decf3073e1a9363d9df05a5a64a6059349e50b81356f480f7aeb352189136d 67decf3073e1a9363d9df05a5a64a6059349e50b81356f480f7aeb352189136d ForType/gen_for_type.rs 6cb447df02c61b192e283e019576c28225added02d167030d64ebd0bebb1b158 6cb447df02c61b192e283e019576c28225added02d167030d64ebd0bebb1b158 -FormatArgsArg/gen_format_args_arg.rs c466f2fc2c0f9592061a159a217a87551d67f1ccb0e4d8f7f56a463a2aa4a73a c466f2fc2c0f9592061a159a217a87551d67f1ccb0e4d8f7f56a463a2aa4a73a -FormatArgsExpr/gen_format_args_expr.rs 7184dbb8833f970676e59fca3a40ec51d14a68e3151d8a6d637896494f2b4454 7184dbb8833f970676e59fca3a40ec51d14a68e3151d8a6d637896494f2b4454 +FormatArgsExpr/gen_format.rs bd009cb152c35e2aacd147b5520a42be31e66e9a8715ec1d0fd57b8e97c743ed bd009cb152c35e2aacd147b5520a42be31e66e9a8715ec1d0fd57b8e97c743ed +FormatArgsExpr/gen_format_args_arg.rs c466f2fc2c0f9592061a159a217a87551d67f1ccb0e4d8f7f56a463a2aa4a73a c466f2fc2c0f9592061a159a217a87551d67f1ccb0e4d8f7f56a463a2aa4a73a +FormatArgsExpr/gen_format_args_expr.rs 72c806ed163e9dcce2d0c5c8664d409b2aa635c1022c91959f9e8ae084f05bf2 72c806ed163e9dcce2d0c5c8664d409b2aa635c1022c91959f9e8ae084f05bf2 +FormatArgsExpr/gen_format_argument.rs 350d370e6f1db03d756384a3dbdb294697d241ff7c28d159cf57748abe99cfe9 350d370e6f1db03d756384a3dbdb294697d241ff7c28d159cf57748abe99cfe9 Function/gen_function.rs ba6ecb9e0d89183295eb02f3c20ebbf5c209f89bd0172c73a3b4a6dacbf3a54c ba6ecb9e0d89183295eb02f3c20ebbf5c209f89bd0172c73a3b4a6dacbf3a54c GenericArgList/gen_generic_arg_list.rs cfb072d3b48f9dd568c23d4dfefba28766628678f66bbf9a436de9919ead35f5 cfb072d3b48f9dd568c23d4dfefba28766628678f66bbf9a436de9919ead35f5 GenericParamList/gen_generic_param_list.rs 4cc9b628f53e1a6c5781ad195b8648fa6dee0bb41b24007fbd986527374d3669 4cc9b628f53e1a6c5781ad195b8648fa6dee0bb41b24007fbd986527374d3669 diff --git a/rust/ql/test/extractor-tests/generated/.gitattributes b/rust/ql/test/extractor-tests/generated/.gitattributes index 8ea3a00a31f..df5c0c5b60c 100644 --- a/rust/ql/test/extractor-tests/generated/.gitattributes +++ b/rust/ql/test/extractor-tests/generated/.gitattributes @@ -33,8 +33,10 @@ /FnPtrType/gen_fn_ptr_type.rs linguist-generated /ForExpr/gen_for_expr.rs linguist-generated /ForType/gen_for_type.rs linguist-generated -/FormatArgsArg/gen_format_args_arg.rs linguist-generated +/FormatArgsExpr/gen_format.rs linguist-generated +/FormatArgsExpr/gen_format_args_arg.rs linguist-generated /FormatArgsExpr/gen_format_args_expr.rs linguist-generated +/FormatArgsExpr/gen_format_argument.rs linguist-generated /Function/gen_function.rs linguist-generated /GenericArgList/gen_generic_arg_list.rs linguist-generated /GenericParamList/gen_generic_param_list.rs linguist-generated diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.expected new file mode 100644 index 00000000000..312f5a3b071 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.expected @@ -0,0 +1,9 @@ +| gen_format.rs:5:21:5:22 | {} | getParent: | gen_format.rs:5:14:5:32 | FormatArgsExpr | getIndex: | 1 | hasArgument: | no | +| gen_format_args_expr.rs:6:19:6:20 | {} | getParent: | gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | getIndex: | 1 | hasArgument: | no | +| gen_format_args_expr.rs:6:26:6:29 | {:?} | getParent: | gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | getIndex: | 3 | hasArgument: | no | +| gen_format_args_expr.rs:7:19:7:21 | {b} | getParent: | gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | getIndex: | 1 | hasArgument: | yes | +| gen_format_args_expr.rs:7:27:7:31 | {a:?} | getParent: | gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | getIndex: | 3 | hasArgument: | yes | +| gen_format_args_expr.rs:9:19:9:21 | {x} | getParent: | gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | getIndex: | 1 | hasArgument: | yes | +| gen_format_args_expr.rs:9:24:9:26 | {y} | getParent: | gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | getIndex: | 3 | hasArgument: | yes | +| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | getParent: | gen_format_argument.rs:5:14:5:47 | FormatArgsExpr | getIndex: | 1 | hasArgument: | yes | +| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | getParent: | gen_format_argument.rs:7:14:7:56 | FormatArgsExpr | getIndex: | 1 | hasArgument: | yes | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.ql new file mode 100644 index 00000000000..fa17b4294f7 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.ql @@ -0,0 +1,12 @@ +// generated by codegen, do not edit +import codeql.rust.elements +import TestUtils + +from Format x, FormatArgsExpr getParent, int getIndex, string hasArgument +where + toBeTested(x) and + not x.isUnknown() and + getParent = x.getParent() and + getIndex = x.getIndex() and + if x.hasArgument() then hasArgument = "yes" else hasArgument = "no" +select x, "getParent:", getParent, "getIndex:", getIndex, "hasArgument:", hasArgument diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg.expected new file mode 100644 index 00000000000..8e704471e02 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg.expected @@ -0,0 +1,8 @@ +| gen_format.rs:5:26:5:32 | FormatArgsArg | hasExpr: | yes | hasName: | no | +| gen_format_args_expr.rs:6:33:6:33 | FormatArgsArg | hasExpr: | yes | hasName: | no | +| gen_format_args_expr.rs:6:36:6:36 | FormatArgsArg | hasExpr: | yes | hasName: | no | +| gen_format_args_expr.rs:7:35:7:37 | FormatArgsArg | hasExpr: | yes | hasName: | yes | +| gen_format_args_expr.rs:7:40:7:42 | FormatArgsArg | hasExpr: | yes | hasName: | yes | +| gen_format_argument.rs:7:34:7:38 | FormatArgsArg | hasExpr: | yes | hasName: | no | +| gen_format_argument.rs:7:41:7:45 | FormatArgsArg | hasExpr: | yes | hasName: | no | +| gen_format_argument.rs:7:48:7:56 | FormatArgsArg | hasExpr: | yes | hasName: | no | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg.ql rename to rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg.ql diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getExpr.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getExpr.expected new file mode 100644 index 00000000000..90cf2cae221 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getExpr.expected @@ -0,0 +1,8 @@ +| gen_format.rs:5:26:5:32 | FormatArgsArg | gen_format.rs:5:26:5:32 | "world" | +| gen_format_args_expr.rs:6:33:6:33 | FormatArgsArg | gen_format_args_expr.rs:6:33:6:33 | 1 | +| gen_format_args_expr.rs:6:36:6:36 | FormatArgsArg | gen_format_args_expr.rs:6:36:6:36 | 2 | +| gen_format_args_expr.rs:7:35:7:37 | FormatArgsArg | gen_format_args_expr.rs:7:37:7:37 | 1 | +| gen_format_args_expr.rs:7:40:7:42 | FormatArgsArg | gen_format_args_expr.rs:7:42:7:42 | 2 | +| gen_format_argument.rs:7:34:7:38 | FormatArgsArg | gen_format_argument.rs:7:34:7:38 | value | +| gen_format_argument.rs:7:41:7:45 | FormatArgsArg | gen_format_argument.rs:7:41:7:45 | width | +| gen_format_argument.rs:7:48:7:56 | FormatArgsArg | gen_format_argument.rs:7:48:7:56 | precision | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg_getExpr.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getExpr.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg_getExpr.ql rename to rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getExpr.ql diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getName.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getName.expected new file mode 100644 index 00000000000..ad5d7ab4ab2 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getName.expected @@ -0,0 +1,2 @@ +| gen_format_args_expr.rs:7:35:7:37 | FormatArgsArg | gen_format_args_expr.rs:7:35:7:35 | a | +| gen_format_args_expr.rs:7:40:7:42 | FormatArgsArg | gen_format_args_expr.rs:7:40:7:40 | b | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg_getName.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getName.ql similarity index 100% rename from rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg_getName.ql rename to rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getName.ql diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr.expected index e69de29bb2d..bed19ed26d4 100644 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr.expected +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr.expected @@ -0,0 +1,7 @@ +| gen_format.rs:5:14:5:32 | FormatArgsExpr | getNumberOfArgs: | 1 | getNumberOfAttrs: | 0 | hasTemplate: | yes | getNumberOfFormats: | 1 | +| gen_format_args_expr.rs:5:17:5:27 | FormatArgsExpr | getNumberOfArgs: | 0 | getNumberOfAttrs: | 0 | hasTemplate: | yes | getNumberOfFormats: | 0 | +| gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | getNumberOfArgs: | 2 | getNumberOfAttrs: | 0 | hasTemplate: | yes | getNumberOfFormats: | 2 | +| gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | getNumberOfArgs: | 2 | getNumberOfAttrs: | 0 | hasTemplate: | yes | getNumberOfFormats: | 2 | +| gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | getNumberOfArgs: | 0 | getNumberOfAttrs: | 0 | hasTemplate: | yes | getNumberOfFormats: | 2 | +| gen_format_argument.rs:5:14:5:47 | FormatArgsExpr | getNumberOfArgs: | 0 | getNumberOfAttrs: | 0 | hasTemplate: | yes | getNumberOfFormats: | 1 | +| gen_format_argument.rs:7:14:7:56 | FormatArgsExpr | getNumberOfArgs: | 3 | getNumberOfAttrs: | 0 | hasTemplate: | yes | getNumberOfFormats: | 1 | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr.ql index 4d5bcf05173..6a43bc1ea0a 100644 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr.ql +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr.ql @@ -2,12 +2,15 @@ import codeql.rust.elements import TestUtils -from FormatArgsExpr x, int getNumberOfArgs, int getNumberOfAttrs, string hasTemplate +from + FormatArgsExpr x, int getNumberOfArgs, int getNumberOfAttrs, string hasTemplate, + int getNumberOfFormats where toBeTested(x) and not x.isUnknown() and getNumberOfArgs = x.getNumberOfArgs() and getNumberOfAttrs = x.getNumberOfAttrs() and - if x.hasTemplate() then hasTemplate = "yes" else hasTemplate = "no" + (if x.hasTemplate() then hasTemplate = "yes" else hasTemplate = "no") and + getNumberOfFormats = x.getNumberOfFormats() select x, "getNumberOfArgs:", getNumberOfArgs, "getNumberOfAttrs:", getNumberOfAttrs, - "hasTemplate:", hasTemplate + "hasTemplate:", hasTemplate, "getNumberOfFormats:", getNumberOfFormats diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getArg.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getArg.expected index e69de29bb2d..89fce13908f 100644 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getArg.expected +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getArg.expected @@ -0,0 +1,8 @@ +| gen_format.rs:5:14:5:32 | FormatArgsExpr | 0 | gen_format.rs:5:26:5:32 | FormatArgsArg | +| gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | 0 | gen_format_args_expr.rs:6:33:6:33 | FormatArgsArg | +| gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | 1 | gen_format_args_expr.rs:6:36:6:36 | FormatArgsArg | +| gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | 0 | gen_format_args_expr.rs:7:35:7:37 | FormatArgsArg | +| gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | 1 | gen_format_args_expr.rs:7:40:7:42 | FormatArgsArg | +| gen_format_argument.rs:7:14:7:56 | FormatArgsExpr | 0 | gen_format_argument.rs:7:34:7:38 | FormatArgsArg | +| gen_format_argument.rs:7:14:7:56 | FormatArgsExpr | 1 | gen_format_argument.rs:7:41:7:45 | FormatArgsArg | +| gen_format_argument.rs:7:14:7:56 | FormatArgsExpr | 2 | gen_format_argument.rs:7:48:7:56 | FormatArgsArg | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getFormat.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getFormat.expected new file mode 100644 index 00000000000..acbe782a35d --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getFormat.expected @@ -0,0 +1,9 @@ +| gen_format.rs:5:14:5:32 | FormatArgsExpr | 0 | gen_format.rs:5:21:5:22 | {} | +| gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | 0 | gen_format_args_expr.rs:6:19:6:20 | {} | +| gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | 2 | gen_format_args_expr.rs:6:26:6:29 | {:?} | +| gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | 0 | gen_format_args_expr.rs:7:19:7:21 | {b} | +| gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | 2 | gen_format_args_expr.rs:7:27:7:31 | {a:?} | +| gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | 0 | gen_format_args_expr.rs:9:19:9:21 | {x} | +| gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | 2 | gen_format_args_expr.rs:9:24:9:26 | {y} | +| gen_format_argument.rs:5:14:5:47 | FormatArgsExpr | 0 | gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | +| gen_format_argument.rs:7:14:7:56 | FormatArgsExpr | 0 | gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getFormat.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getFormat.ql new file mode 100644 index 00000000000..ca61ca2bebd --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getFormat.ql @@ -0,0 +1,7 @@ +// generated by codegen, do not edit +import codeql.rust.elements +import TestUtils + +from FormatArgsExpr x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getFormat(index) diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getTemplate.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getTemplate.expected index e69de29bb2d..6c4f7030810 100644 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getTemplate.expected +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getTemplate.expected @@ -0,0 +1,7 @@ +| gen_format.rs:5:14:5:32 | FormatArgsExpr | gen_format.rs:5:14:5:23 | "Hello {}\\n" | +| gen_format_args_expr.rs:5:17:5:27 | FormatArgsExpr | gen_format_args_expr.rs:5:18:5:26 | "no args" | +| gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | gen_format_args_expr.rs:6:18:6:30 | "{} foo {:?}" | +| gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | gen_format_args_expr.rs:7:18:7:32 | "{b} foo {a:?}" | +| gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | gen_format_args_expr.rs:9:18:9:27 | "{x}, {y}" | +| gen_format_argument.rs:5:14:5:47 | FormatArgsExpr | gen_format_argument.rs:5:14:5:47 | "Value {value:#width$.precision$}\\n" | +| gen_format_argument.rs:7:14:7:56 | FormatArgsExpr | gen_format_argument.rs:7:14:7:31 | "Value {0:#1$.2$}\\n" | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getVariable.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getVariable.expected new file mode 100644 index 00000000000..dca240710f7 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getVariable.expected @@ -0,0 +1,5 @@ +| gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | 1 | gen_format_args_expr.rs:9:20:9:20 | x | +| gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | 3 | gen_format_args_expr.rs:9:25:9:25 | y | +| gen_format_argument.rs:5:14:5:47 | FormatArgsExpr | 1 | gen_format_argument.rs:5:22:5:26 | value | +| gen_format_argument.rs:5:14:5:47 | FormatArgsExpr | 1 | gen_format_argument.rs:5:29:5:33 | width | +| gen_format_argument.rs:5:14:5:47 | FormatArgsExpr | 1 | gen_format_argument.rs:5:36:5:44 | precision | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument.expected new file mode 100644 index 00000000000..e63b4b6558f --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument.expected @@ -0,0 +1,10 @@ +| gen_format_args_expr.rs:7:20:7:20 | b | getParent: | gen_format_args_expr.rs:7:19:7:21 | {b} | hasVariable: | no | +| gen_format_args_expr.rs:7:28:7:28 | a | getParent: | gen_format_args_expr.rs:7:27:7:31 | {a:?} | hasVariable: | no | +| gen_format_args_expr.rs:9:20:9:20 | x | getParent: | gen_format_args_expr.rs:9:19:9:21 | {x} | hasVariable: | yes | +| gen_format_args_expr.rs:9:25:9:25 | y | getParent: | gen_format_args_expr.rs:9:24:9:26 | {y} | hasVariable: | yes | +| gen_format_argument.rs:5:22:5:26 | value | getParent: | gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | hasVariable: | yes | +| gen_format_argument.rs:5:29:5:33 | width | getParent: | gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | hasVariable: | yes | +| gen_format_argument.rs:5:36:5:44 | precision | getParent: | gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | hasVariable: | yes | +| gen_format_argument.rs:7:22:7:22 | 0 | getParent: | gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | hasVariable: | no | +| gen_format_argument.rs:7:25:7:25 | 1 | getParent: | gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | hasVariable: | no | +| gen_format_argument.rs:7:28:7:28 | 2 | getParent: | gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | hasVariable: | no | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument.ql new file mode 100644 index 00000000000..ed57154f7e8 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument.ql @@ -0,0 +1,11 @@ +// generated by codegen, do not edit +import codeql.rust.elements +import TestUtils + +from FormatArgument x, Format getParent, string hasVariable +where + toBeTested(x) and + not x.isUnknown() and + getParent = x.getParent() and + if x.hasVariable() then hasVariable = "yes" else hasVariable = "no" +select x, "getParent:", getParent, "hasVariable:", hasVariable diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument_getVariable.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument_getVariable.expected new file mode 100644 index 00000000000..11db93ec06d --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument_getVariable.expected @@ -0,0 +1,5 @@ +| gen_format_args_expr.rs:9:20:9:20 | x | gen_format_args_expr.rs:9:20:9:20 | x | +| gen_format_args_expr.rs:9:25:9:25 | y | gen_format_args_expr.rs:9:25:9:25 | y | +| gen_format_argument.rs:5:22:5:26 | value | gen_format_argument.rs:5:22:5:26 | value | +| gen_format_argument.rs:5:29:5:33 | width | gen_format_argument.rs:5:29:5:33 | width | +| gen_format_argument.rs:5:36:5:44 | precision | gen_format_argument.rs:5:36:5:44 | precision | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument_getVariable.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument_getVariable.ql new file mode 100644 index 00000000000..5d303bc4b6c --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgument_getVariable.ql @@ -0,0 +1,7 @@ +// generated by codegen, do not edit +import codeql.rust.elements +import TestUtils + +from FormatArgument x +where toBeTested(x) and not x.isUnknown() +select x, x.getVariable() diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatTemplateVariableAccess.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatTemplateVariableAccess.expected new file mode 100644 index 00000000000..df4fdad5c91 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatTemplateVariableAccess.expected @@ -0,0 +1,5 @@ +| gen_format_args_expr.rs:9:20:9:20 | x | +| gen_format_args_expr.rs:9:25:9:25 | y | +| gen_format_argument.rs:5:22:5:26 | value | +| gen_format_argument.rs:5:29:5:33 | width | +| gen_format_argument.rs:5:36:5:44 | precision | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatTemplateVariableAccess.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatTemplateVariableAccess.ql new file mode 100644 index 00000000000..4f43ca11870 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatTemplateVariableAccess.ql @@ -0,0 +1,7 @@ +// generated by codegen, do not edit +import codeql.rust.elements +import TestUtils + +from FormatTemplateVariableAccess x +where toBeTested(x) and not x.isUnknown() +select x diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.expected new file mode 100644 index 00000000000..af9dd77578c --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.expected @@ -0,0 +1,10 @@ +| gen_format_args_expr.rs:7:19:7:21 | {b} | gen_format_args_expr.rs:7:20:7:20 | b | +| gen_format_args_expr.rs:7:27:7:31 | {a:?} | gen_format_args_expr.rs:7:28:7:28 | a | +| gen_format_args_expr.rs:9:19:9:21 | {x} | gen_format_args_expr.rs:9:20:9:20 | x | +| gen_format_args_expr.rs:9:24:9:26 | {y} | gen_format_args_expr.rs:9:25:9:25 | y | +| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | gen_format_argument.rs:5:22:5:26 | value | +| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | gen_format_argument.rs:5:29:5:33 | width | +| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | gen_format_argument.rs:5:36:5:44 | precision | +| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | gen_format_argument.rs:7:22:7:22 | 0 | +| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | gen_format_argument.rs:7:25:7:25 | 1 | +| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | gen_format_argument.rs:7:28:7:28 | 2 | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql new file mode 100644 index 00000000000..e131365770b --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql @@ -0,0 +1,7 @@ +// generated by codegen, do not edit +import codeql.rust.elements +import TestUtils + +from Format x +where toBeTested(x) and not x.isUnknown() +select x, x.getArgument() diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/gen_format.rs b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/gen_format.rs new file mode 100644 index 00000000000..86b78256d40 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/gen_format.rs @@ -0,0 +1,6 @@ +// generated by codegen, do not edit + +fn test_format() -> () { + // A format element in a formatting template. For example the `{}` in: + println!("Hello {}", "world"); +} diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsArg/gen_format_args_arg.rs b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/gen_format_args_arg.rs similarity index 100% rename from rust/ql/test/extractor-tests/generated/FormatArgsArg/gen_format_args_arg.rs rename to rust/ql/test/extractor-tests/generated/FormatArgsExpr/gen_format_args_arg.rs diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/gen_format_args_expr.rs b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/gen_format_args_expr.rs index 7345a633ba5..3c2acb387fc 100644 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/gen_format_args_expr.rs +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/gen_format_args_expr.rs @@ -2,5 +2,9 @@ fn test_format_args_expr() -> () { // A FormatArgsExpr. For example: - todo!() + format_args!("no args"); + format_args!("{} foo {:?}", 1, 2); + format_args!("{b} foo {a:?}", a=1, b=2); + let (x, y) = (1, 42); + format_args!("{x}, {y}"); } diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/gen_format_argument.rs b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/gen_format_argument.rs new file mode 100644 index 00000000000..32cb123f51d --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/gen_format_argument.rs @@ -0,0 +1,8 @@ +// generated by codegen, do not edit + +fn test_format_argument() -> () { + // An argument in a format element in a formatting template. For example the `width`, `precision`, and `value` in: + println!("Value {value:#width$.precision$}"); + // or the `0`, `1` and `2` in: + println!("Value {0:#1$.2$}", value, width, precision); +} diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index ae94b0604e7..60f67a710d8 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -1011,6 +1011,7 @@ class _: @annotate(FormatArgsArg) +@qltest.test_with(FormatArgsExpr) class _: """ A FormatArgsArg. For example: @@ -1025,9 +1026,14 @@ class _: """ A FormatArgsExpr. For example: ```rust - todo!() + format_args!("no args"); + format_args!("{} foo {:?}", 1, 2); + format_args!("{b} foo {a:?}", a=1, b=2); + let (x, y) = (1, 42); + format_args!("{x}, {y}"); ``` """ + formats: list["Format"] | child | synth @annotate(GenericArg) @@ -1766,14 +1772,15 @@ class _: attrs: drop -@qltest.skip @synth.on_arguments(parent="FormatArgsExpr", index=int, kind=int) +@qltest.test_with(FormatArgsExpr) class FormatTemplateVariableAccess(PathExprBase): pass -@qltest.skip @synth.on_arguments(parent=FormatArgsExpr, index=int, text=string, offset=int) +@qltest.test_with(FormatArgsExpr) + class Format(Locatable): """ A format element in a formatting template. For example the `{}` in: @@ -1783,10 +1790,11 @@ class Format(Locatable): """ parent: FormatArgsExpr index: int + argument: optional["FormatArgument"] | child -@qltest.skip @synth.on_arguments(parent=FormatArgsExpr, index=int, kind=int, name=string, positional=boolean, offset=int) +@qltest.test_with(FormatArgsExpr) class FormatArgument(Locatable): """ An argument in a format element in a formatting template. For example the `width`, `precision`, and `value` in: @@ -1799,6 +1807,7 @@ class FormatArgument(Locatable): ``` """ parent: Format + variable: optional[FormatTemplateVariableAccess] | child @annotate(Item) class _: From 9a07b3c3d4d76e618c0bee5f363778285ef2984e Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 22 Nov 2024 12:24:44 +0100 Subject: [PATCH 189/470] Rust: remove obsolete expected files --- .../generated/FormatArgsArg/FormatArgsArg.expected | 0 .../generated/FormatArgsArg/FormatArgsArg_getExpr.expected | 0 .../generated/FormatArgsArg/FormatArgsArg_getName.expected | 0 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg.expected delete mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg_getExpr.expected delete mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg_getName.expected diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg.expected b/rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg.expected deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg_getExpr.expected b/rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg_getExpr.expected deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg_getName.expected b/rust/ql/test/extractor-tests/generated/FormatArgsArg/FormatArgsArg_getName.expected deleted file mode 100644 index e69de29bb2d..00000000000 From ed67dae8500fe886312b21968673eb749a19764e Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:20:04 +0000 Subject: [PATCH 190/470] Rust: Make ql-for-ql happy. --- rust/ql/src/queries/summary/TaintSources.ql | 4 +-- .../dataflow/sources/TaintSources.expected | 34 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/rust/ql/src/queries/summary/TaintSources.ql b/rust/ql/src/queries/summary/TaintSources.ql index 2e1bc7205e2..f7dc95eccb4 100644 --- a/rust/ql/src/queries/summary/TaintSources.ql +++ b/rust/ql/src/queries/summary/TaintSources.ql @@ -13,5 +13,5 @@ import codeql.rust.Concepts from ThreatModelSource s, string defaultString where - if s instanceof ActiveThreatModelSource then defaultString = ", DEFAULT" else defaultString = "" -select s, s.getSourceType() + " (" + s.getThreatModel() + defaultString + ")" + if s instanceof ActiveThreatModelSource then defaultString = " (DEFAULT)" else defaultString = "" +select s, "Flow source '" + s.getSourceType() + "' of type " + s.getThreatModel() + defaultString + "." diff --git a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected index e7d561f5f58..50336f15571 100644 --- a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected +++ b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected @@ -1,17 +1,17 @@ -| test.rs:8:10:8:30 | CallExpr | EnvironmentSource (environment) | -| test.rs:9:10:9:33 | CallExpr | EnvironmentSource (environment) | -| test.rs:11:16:11:36 | CallExpr | EnvironmentSource (environment) | -| test.rs:12:16:12:39 | CallExpr | EnvironmentSource (environment) | -| test.rs:17:25:17:40 | CallExpr | EnvironmentSource (environment) | -| test.rs:22:25:22:43 | CallExpr | EnvironmentSource (environment) | -| test.rs:29:29:29:44 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:32:16:32:31 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:33:16:33:34 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:40:16:40:31 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:44:16:44:34 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:50:15:50:37 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:51:15:51:37 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:52:16:52:35 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:60:26:60:70 | CallExpr | RemoteSource (remote, DEFAULT) | -| test.rs:63:26:63:70 | CallExpr | RemoteSource (remote, DEFAULT) | -| test.rs:66:26:66:60 | CallExpr | RemoteSource (remote, DEFAULT) | +| test.rs:8:10:8:30 | CallExpr | Flow source 'EnvironmentSource' of type environment. | +| test.rs:9:10:9:33 | CallExpr | Flow source 'EnvironmentSource' of type environment. | +| test.rs:11:16:11:36 | CallExpr | Flow source 'EnvironmentSource' of type environment. | +| test.rs:12:16:12:39 | CallExpr | Flow source 'EnvironmentSource' of type environment. | +| test.rs:17:25:17:40 | CallExpr | Flow source 'EnvironmentSource' of type environment. | +| test.rs:22:25:22:43 | CallExpr | Flow source 'EnvironmentSource' of type environment. | +| test.rs:29:29:29:44 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:32:16:32:31 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:33:16:33:34 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:40:16:40:31 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:44:16:44:34 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:50:15:50:37 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:51:15:51:37 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:52:16:52:35 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:60:26:60:70 | CallExpr | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:63:26:63:70 | CallExpr | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:66:26:66:60 | CallExpr | Flow source 'RemoteSource' of type remote (DEFAULT). | From 194f967d74f2e2e0cc88c79711fe88d289d5bdef Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:36:54 +0000 Subject: [PATCH 191/470] Rust: Required doc comments. --- rust/ql/lib/codeql/rust/Concepts.qll | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/rust/ql/lib/codeql/rust/Concepts.qll b/rust/ql/lib/codeql/rust/Concepts.qll index a9ec8dfe530..9369668923f 100644 --- a/rust/ql/lib/codeql/rust/Concepts.qll +++ b/rust/ql/lib/codeql/rust/Concepts.qll @@ -52,7 +52,13 @@ class ActiveThreatModelSource extends ThreatModelSource { */ final class CommandLineArgsSource = CommandLineArgsSource::Range; +/** + * Provides a class for modeling new sources for the program's command line arguments or path. + */ module CommandLineArgsSource { + /** + * A data flow source corresponding to the program's command line arguments or path. + */ abstract class Range extends ThreatModelSource::Range { override string getThreatModel() { result = "commandargs" } @@ -65,7 +71,13 @@ module CommandLineArgsSource { */ final class EnvironmentSource = EnvironmentSource::Range; +/** + * Provides a class for modeling new sources for the program's environment. + */ module EnvironmentSource { + /** + * A data flow source corresponding to the program's environment. + */ abstract class Range extends ThreatModelSource::Range { override string getThreatModel() { result = "environment" } @@ -78,7 +90,13 @@ module EnvironmentSource { */ final class RemoteSource = RemoteSource::Range; +/** + * Provides a class for modeling new sources of remote (network) data. + */ module RemoteSource { + /** + * A data flow source for remote (network) data. + */ abstract class Range extends ThreatModelSource::Range { override string getThreatModel() { result = "remote" } From fe2d0b631c87f059c3b9db367dc5da8516e88aba Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:37:15 +0000 Subject: [PATCH 192/470] Rust: Autoformat. --- rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll b/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll index 2319c426248..69658d5fec5 100644 --- a/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll @@ -10,7 +10,8 @@ private import codeql.rust.Concepts */ private class StdEnvArgs extends CommandLineArgsSource::Range { StdEnvArgs() { - this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::args", "crate::env::args_os"] + this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = + ["crate::env::args", "crate::env::args_os"] } } @@ -19,7 +20,8 @@ private class StdEnvArgs extends CommandLineArgsSource::Range { */ private class StdEnvDir extends CommandLineArgsSource::Range { StdEnvDir() { - this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::current_dir", "crate::env::current_exe", "crate::env::home_dir"] + this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = + ["crate::env::current_dir", "crate::env::current_exe", "crate::env::home_dir"] } } @@ -28,6 +30,7 @@ private class StdEnvDir extends CommandLineArgsSource::Range { */ private class StdEnvVar extends EnvironmentSource::Range { StdEnvVar() { - this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::var", "crate::env::var_os", "crate::env::vars", "crate::env::vars_os"] + this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = + ["crate::env::var", "crate::env::var_os", "crate::env::vars", "crate::env::vars_os"] } } From 169671ad937023b7aa0fee226335ba65eb4c0e3b Mon Sep 17 00:00:00 2001 From: Calum Grant <42069085+calumgrant@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:42:39 +0000 Subject: [PATCH 193/470] Revert "C++: Implement compilation_build_mode" --- .../old.dbscheme | 2339 --------------- .../semmlecode.cpp.dbscheme | 2323 --------------- .../upgrade.properties | 3 - cpp/ql/lib/semmle/code/cpp/Compilation.qll | 3 - cpp/ql/lib/semmlecode.cpp.dbscheme | 16 - cpp/ql/lib/semmlecode.cpp.dbscheme.stats | 2639 ++++++++--------- .../old.dbscheme | 2323 --------------- .../semmlecode.cpp.dbscheme | 2339 --------------- .../upgrade.properties | 2 - 9 files changed, 1288 insertions(+), 10699 deletions(-) delete mode 100644 cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/old.dbscheme delete mode 100644 cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/semmlecode.cpp.dbscheme delete mode 100644 cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties delete mode 100644 cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/old.dbscheme delete mode 100644 cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/semmlecode.cpp.dbscheme delete mode 100644 cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/upgrade.properties diff --git a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/old.dbscheme b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/old.dbscheme deleted file mode 100644 index f0156f5f88a..00000000000 --- a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/old.dbscheme +++ /dev/null @@ -1,2339 +0,0 @@ - -/** - * An invocation of the compiler. Note that more than one file may be - * compiled per invocation. For example, this command compiles three - * source files: - * - * gcc -c f1.c f2.c f3.c - * - * The `id` simply identifies the invocation, while `cwd` is the working - * directory from which the compiler was invoked. - */ -compilations( - /** - * An invocation of the compiler. Note that more than one file may - * be compiled per invocation. For example, this command compiles - * three source files: - * - * gcc -c f1.c f2.c f3.c - */ - unique int id : @compilation, - string cwd : string ref -); - -/** - * The arguments that were passed to the extractor for a compiler - * invocation. If `id` is for the compiler invocation - * - * gcc -c f1.c f2.c f3.c - * - * then typically there will be rows for - * - * num | arg - * --- | --- - * 0 | *path to extractor* - * 1 | `--mimic` - * 2 | `/usr/bin/gcc` - * 3 | `-c` - * 4 | f1.c - * 5 | f2.c - * 6 | f3.c - */ -#keyset[id, num] -compilation_args( - int id : @compilation ref, - int num : int ref, - string arg : string ref -); - -/** - * Optionally, record the build mode for each compilation. - */ -compilation_build_mode( - unique int id : @compilation ref, - int mode : int ref -); - -/* -case @compilation_build_mode.mode of - 0 = @build_mode_none -| 1 = @build_mode_manual -| 2 = @build_mode_auto -; -*/ - -/** - * The source files that are compiled by a compiler invocation. - * If `id` is for the compiler invocation - * - * gcc -c f1.c f2.c f3.c - * - * then there will be rows for - * - * num | arg - * --- | --- - * 0 | f1.c - * 1 | f2.c - * 2 | f3.c - * - * Note that even if those files `#include` headers, those headers - * do not appear as rows. - */ -#keyset[id, num] -compilation_compiling_files( - int id : @compilation ref, - int num : int ref, - int file : @file ref -); - -/** - * The time taken by the extractor for a compiler invocation. - * - * For each file `num`, there will be rows for - * - * kind | seconds - * ---- | --- - * 1 | CPU seconds used by the extractor frontend - * 2 | Elapsed seconds during the extractor frontend - * 3 | CPU seconds used by the extractor backend - * 4 | Elapsed seconds during the extractor backend - */ -#keyset[id, num, kind] -compilation_time( - int id : @compilation ref, - int num : int ref, - /* kind: - 1 = frontend_cpu_seconds - 2 = frontend_elapsed_seconds - 3 = extractor_cpu_seconds - 4 = extractor_elapsed_seconds - */ - int kind : int ref, - float seconds : float ref -); - -/** - * An error or warning generated by the extractor. - * The diagnostic message `diagnostic` was generated during compiler - * invocation `compilation`, and is the `file_number_diagnostic_number`th - * message generated while extracting the `file_number`th file of that - * invocation. - */ -#keyset[compilation, file_number, file_number_diagnostic_number] -diagnostic_for( - int diagnostic : @diagnostic ref, - int compilation : @compilation ref, - int file_number : int ref, - int file_number_diagnostic_number : int ref -); - -/** - * If extraction was successful, then `cpu_seconds` and - * `elapsed_seconds` are the CPU time and elapsed time (respectively) - * that extraction took for compiler invocation `id`. - */ -compilation_finished( - unique int id : @compilation ref, - float cpu_seconds : float ref, - float elapsed_seconds : float ref -); - - -/** - * External data, loaded from CSV files during snapshot creation. See - * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) - * for more information. - */ -externalData( - int id : @externalDataElement, - string path : string ref, - int column: int ref, - string value : string ref -); - -/** - * The source location of the snapshot. - */ -sourceLocationPrefix(string prefix : string ref); - -/** - * Information about packages that provide code used during compilation. - * The `id` is just a unique identifier. - * The `namespace` is typically the name of the package manager that - * provided the package (e.g. "dpkg" or "yum"). - * The `package_name` is the name of the package, and `version` is its - * version (as a string). - */ -external_packages( - unique int id: @external_package, - string namespace : string ref, - string package_name : string ref, - string version : string ref -); - -/** - * Holds if File `fileid` was provided by package `package`. - */ -header_to_external_package( - int fileid : @file ref, - int package : @external_package ref -); - -/* - * Version history - */ - -svnentries( - unique int id : @svnentry, - string revision : string ref, - string author : string ref, - date revisionDate : date ref, - int changeSize : int ref -) - -svnaffectedfiles( - int id : @svnentry ref, - int file : @file ref, - string action : string ref -) - -svnentrymsg( - unique int id : @svnentry ref, - string message : string ref -) - -svnchurn( - int commit : @svnentry ref, - int file : @file ref, - int addedLines : int ref, - int deletedLines : int ref -) - -/* - * C++ dbscheme - */ - -extractor_version( - string codeql_version: string ref, - string frontend_version: string ref -) - -@location = @location_stmt | @location_expr | @location_default ; - -/** - * The location of an element that is not an expression or a statement. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `file`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ -locations_default( - /** The location of an element that is not an expression or a statement. */ - unique int id: @location_default, - int container: @container ref, - int startLine: int ref, - int startColumn: int ref, - int endLine: int ref, - int endColumn: int ref -); - -/** - * The location of a statement. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `file`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ -locations_stmt( - /** The location of a statement. */ - unique int id: @location_stmt, - int container: @container ref, - int startLine: int ref, - int startColumn: int ref, - int endLine: int ref, - int endColumn: int ref -); - -/** - * The location of an expression. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `file`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ -locations_expr( - /** The location of an expression. */ - unique int id: @location_expr, - int container: @container ref, - int startLine: int ref, - int startColumn: int ref, - int endLine: int ref, - int endColumn: int ref -); - -/** An element for which line-count information is available. */ -@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; - -numlines( - int element_id: @sourceline ref, - int num_lines: int ref, - int num_code: int ref, - int num_comment: int ref -); - -diagnostics( - unique int id: @diagnostic, - int severity: int ref, - string error_tag: string ref, - string error_message: string ref, - string full_error_message: string ref, - int location: @location_default ref -); - -files( - unique int id: @file, - string name: string ref -); - -folders( - unique int id: @folder, - string name: string ref -); - -@container = @folder | @file - -containerparent( - int parent: @container ref, - unique int child: @container ref -); - -fileannotations( - int id: @file ref, - int kind: int ref, - string name: string ref, - string value: string ref -); - -inmacroexpansion( - int id: @element ref, - int inv: @macroinvocation ref -); - -affectedbymacroexpansion( - int id: @element ref, - int inv: @macroinvocation ref -); - -case @macroinvocation.kind of - 1 = @macro_expansion -| 2 = @other_macro_reference -; - -macroinvocations( - unique int id: @macroinvocation, - int macro_id: @ppd_define ref, - int location: @location_default ref, - int kind: int ref -); - -macroparent( - unique int id: @macroinvocation ref, - int parent_id: @macroinvocation ref -); - -// a macroinvocation may be part of another location -// the way to find a constant expression that uses a macro -// is thus to find a constant expression that has a location -// to which a macro invocation is bound -macrolocationbind( - int id: @macroinvocation ref, - int location: @location ref -); - -#keyset[invocation, argument_index] -macro_argument_unexpanded( - int invocation: @macroinvocation ref, - int argument_index: int ref, - string text: string ref -); - -#keyset[invocation, argument_index] -macro_argument_expanded( - int invocation: @macroinvocation ref, - int argument_index: int ref, - string text: string ref -); - -/* -case @function.kind of - 1 = @normal_function -| 2 = @constructor -| 3 = @destructor -| 4 = @conversion_function -| 5 = @operator -| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk -| 7 = @user_defined_literal -| 8 = @deduction_guide -; -*/ - -functions( - unique int id: @function, - string name: string ref, - int kind: int ref -); - -function_entry_point( - int id: @function ref, - unique int entry_point: @stmt ref -); - -function_return_type( - int id: @function ref, - int return_type: @type ref -); - -/** - * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` - * instance associated with it, and the variables representing the `handle` and `promise` - * for it. - */ -coroutine( - unique int function: @function ref, - int traits: @type ref -); - -/* -case @coroutine_placeholder_variable.kind of - 1 = @handle -| 2 = @promise -| 3 = @init_await_resume -; -*/ - -coroutine_placeholder_variable( - unique int placeholder_variable: @variable ref, - int kind: int ref, - int function: @function ref -) - -/** The `new` function used for allocating the coroutine state, if any. */ -coroutine_new( - unique int function: @function ref, - int new: @function ref -); - -/** The `delete` function used for deallocating the coroutine state, if any. */ -coroutine_delete( - unique int function: @function ref, - int delete: @function ref -); - -purefunctions(unique int id: @function ref); - -function_deleted(unique int id: @function ref); - -function_defaulted(unique int id: @function ref); - -function_prototyped(unique int id: @function ref) - -deduction_guide_for_class( - int id: @function ref, - int class_template: @usertype ref -) - -member_function_this_type( - unique int id: @function ref, - int this_type: @type ref -); - -#keyset[id, type_id] -fun_decls( - int id: @fun_decl, - int function: @function ref, - int type_id: @type ref, - string name: string ref, - int location: @location_default ref -); -fun_def(unique int id: @fun_decl ref); -fun_specialized(unique int id: @fun_decl ref); -fun_implicit(unique int id: @fun_decl ref); -fun_decl_specifiers( - int id: @fun_decl ref, - string name: string ref -) -#keyset[fun_decl, index] -fun_decl_throws( - int fun_decl: @fun_decl ref, - int index: int ref, - int type_id: @type ref -); -/* an empty throw specification is different from none */ -fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); -fun_decl_noexcept( - int fun_decl: @fun_decl ref, - int constant: @expr ref -); -fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); -fun_decl_typedef_type( - unique int fun_decl: @fun_decl ref, - int typedeftype_id: @usertype ref -); - -param_decl_bind( - unique int id: @var_decl ref, - int index: int ref, - int fun_decl: @fun_decl ref -); - -#keyset[id, type_id] -var_decls( - int id: @var_decl, - int variable: @variable ref, - int type_id: @type ref, - string name: string ref, - int location: @location_default ref -); -var_def(unique int id: @var_decl ref); -var_decl_specifiers( - int id: @var_decl ref, - string name: string ref -) -is_structured_binding(unique int id: @variable ref); - -type_decls( - unique int id: @type_decl, - int type_id: @type ref, - int location: @location_default ref -); -type_def(unique int id: @type_decl ref); -type_decl_top( - unique int type_decl: @type_decl ref -); - -namespace_decls( - unique int id: @namespace_decl, - int namespace_id: @namespace ref, - int location: @location_default ref, - int bodylocation: @location_default ref -); - -case @using.kind of - 1 = @using_declaration -| 2 = @using_directive -| 3 = @using_enum_declaration -; - -usings( - unique int id: @using, - int element_id: @element ref, - int location: @location_default ref, - int kind: int ref -); - -/** The element which contains the `using` declaration. */ -using_container( - int parent: @element ref, - int child: @using ref -); - -static_asserts( - unique int id: @static_assert, - int condition : @expr ref, - string message : string ref, - int location: @location_default ref, - int enclosing : @element ref -); - -// each function has an ordered list of parameters -#keyset[id, type_id] -#keyset[function, index, type_id] -params( - int id: @parameter, - int function: @parameterized_element ref, - int index: int ref, - int type_id: @type ref -); - -overrides( - int new: @function ref, - int old: @function ref -); - -#keyset[id, type_id] -membervariables( - int id: @membervariable, - int type_id: @type ref, - string name: string ref -); - -#keyset[id, type_id] -globalvariables( - int id: @globalvariable, - int type_id: @type ref, - string name: string ref -); - -#keyset[id, type_id] -localvariables( - int id: @localvariable, - int type_id: @type ref, - string name: string ref -); - -autoderivation( - unique int var: @variable ref, - int derivation_type: @type ref -); - -orphaned_variables( - int var: @localvariable ref, - int function: @function ref -) - -enumconstants( - unique int id: @enumconstant, - int parent: @usertype ref, - int index: int ref, - int type_id: @type ref, - string name: string ref, - int location: @location_default ref -); - -@variable = @localscopevariable | @globalvariable | @membervariable; - -@localscopevariable = @localvariable | @parameter; - -/** - * Built-in types are the fundamental types, e.g., integral, floating, and void. - */ -case @builtintype.kind of - 1 = @errortype -| 2 = @unknowntype -| 3 = @void -| 4 = @boolean -| 5 = @char -| 6 = @unsigned_char -| 7 = @signed_char -| 8 = @short -| 9 = @unsigned_short -| 10 = @signed_short -| 11 = @int -| 12 = @unsigned_int -| 13 = @signed_int -| 14 = @long -| 15 = @unsigned_long -| 16 = @signed_long -| 17 = @long_long -| 18 = @unsigned_long_long -| 19 = @signed_long_long -// ... 20 Microsoft-specific __int8 -// ... 21 Microsoft-specific __int16 -// ... 22 Microsoft-specific __int32 -// ... 23 Microsoft-specific __int64 -| 24 = @float -| 25 = @double -| 26 = @long_double -| 27 = @complex_float // C99-specific _Complex float -| 28 = @complex_double // C99-specific _Complex double -| 29 = @complex_long_double // C99-specific _Complex long double -| 30 = @imaginary_float // C99-specific _Imaginary float -| 31 = @imaginary_double // C99-specific _Imaginary double -| 32 = @imaginary_long_double // C99-specific _Imaginary long double -| 33 = @wchar_t // Microsoft-specific -| 34 = @decltype_nullptr // C++11 -| 35 = @int128 // __int128 -| 36 = @unsigned_int128 // unsigned __int128 -| 37 = @signed_int128 // signed __int128 -| 38 = @float128 // __float128 -| 39 = @complex_float128 // _Complex __float128 -| 40 = @decimal32 // _Decimal32 -| 41 = @decimal64 // _Decimal64 -| 42 = @decimal128 // _Decimal128 -| 43 = @char16_t -| 44 = @char32_t -| 45 = @std_float32 // _Float32 -| 46 = @float32x // _Float32x -| 47 = @std_float64 // _Float64 -| 48 = @float64x // _Float64x -| 49 = @std_float128 // _Float128 -// ... 50 _Float128x -| 51 = @char8_t -| 52 = @float16 // _Float16 -| 53 = @complex_float16 // _Complex _Float16 -| 54 = @fp16 // __fp16 -| 55 = @std_bfloat16 // __bf16 -| 56 = @std_float16 // std::float16_t -| 57 = @complex_std_float32 // _Complex _Float32 -| 58 = @complex_float32x // _Complex _Float32x -| 59 = @complex_std_float64 // _Complex _Float64 -| 60 = @complex_float64x // _Complex _Float64x -| 61 = @complex_std_float128 // _Complex _Float128 -; - -builtintypes( - unique int id: @builtintype, - string name: string ref, - int kind: int ref, - int size: int ref, - int sign: int ref, - int alignment: int ref -); - -/** - * Derived types are types that are directly derived from existing types and - * point to, refer to, transform type data to return a new type. - */ -case @derivedtype.kind of - 1 = @pointer -| 2 = @reference -| 3 = @type_with_specifiers -| 4 = @array -| 5 = @gnu_vector -| 6 = @routineptr -| 7 = @routinereference -| 8 = @rvalue_reference // C++11 -// ... 9 type_conforming_to_protocols deprecated -| 10 = @block -; - -derivedtypes( - unique int id: @derivedtype, - string name: string ref, - int kind: int ref, - int type_id: @type ref -); - -pointerishsize(unique int id: @derivedtype ref, - int size: int ref, - int alignment: int ref); - -arraysizes( - unique int id: @derivedtype ref, - int num_elements: int ref, - int bytesize: int ref, - int alignment: int ref -); - -typedefbase( - unique int id: @usertype ref, - int type_id: @type ref -); - -/** - * An instance of the C++11 `decltype` operator. For example: - * ``` - * int a; - * decltype(1+a) b; - * ``` - * Here `expr` is `1+a`. - * - * Sometimes an additional pair of parentheses around the expression - * would change the semantics of this decltype, e.g. - * ``` - * struct A { double x; }; - * const A* a = new A(); - * decltype( a->x ); // type is double - * decltype((a->x)); // type is const double& - * ``` - * (Please consult the C++11 standard for more details). - * `parentheses_would_change_meaning` is `true` iff that is the case. - */ -#keyset[id, expr] -decltypes( - int id: @decltype, - int expr: @expr ref, - int base_type: @type ref, - boolean parentheses_would_change_meaning: boolean ref -); - -/* -case @usertype.kind of - 1 = @struct -| 2 = @class -| 3 = @union -| 4 = @enum -| 5 = @typedef // classic C: typedef typedef type name -| 6 = @template -| 7 = @template_parameter -| 8 = @template_template_parameter -| 9 = @proxy_class // a proxy class associated with a template parameter -// ... 10 objc_class deprecated -// ... 11 objc_protocol deprecated -// ... 12 objc_category deprecated -| 13 = @scoped_enum -| 14 = @using_alias // a using name = type style typedef -; -*/ - -usertypes( - unique int id: @usertype, - string name: string ref, - int kind: int ref -); - -usertypesize( - unique int id: @usertype ref, - int size: int ref, - int alignment: int ref -); - -usertype_final(unique int id: @usertype ref); - -usertype_uuid( - unique int id: @usertype ref, - string uuid: string ref -); - -mangled_name( - unique int id: @declaration ref, - int mangled_name : @mangledname, - boolean is_complete: boolean ref -); - -is_pod_class(unique int id: @usertype ref); -is_standard_layout_class(unique int id: @usertype ref); - -is_complete(unique int id: @usertype ref); - -is_class_template(unique int id: @usertype ref); -class_instantiation( - int to: @usertype ref, - int from: @usertype ref -); -class_template_argument( - int type_id: @usertype ref, - int index: int ref, - int arg_type: @type ref -); -class_template_argument_value( - int type_id: @usertype ref, - int index: int ref, - int arg_value: @expr ref -); - -is_proxy_class_for( - unique int id: @usertype ref, - unique int templ_param_id: @usertype ref -); - -type_mentions( - unique int id: @type_mention, - int type_id: @type ref, - int location: @location ref, - // a_symbol_reference_kind from the frontend. - int kind: int ref -); - -is_function_template(unique int id: @function ref); -function_instantiation( - unique int to: @function ref, - int from: @function ref -); -function_template_argument( - int function_id: @function ref, - int index: int ref, - int arg_type: @type ref -); -function_template_argument_value( - int function_id: @function ref, - int index: int ref, - int arg_value: @expr ref -); - -is_variable_template(unique int id: @variable ref); -variable_instantiation( - unique int to: @variable ref, - int from: @variable ref -); -variable_template_argument( - int variable_id: @variable ref, - int index: int ref, - int arg_type: @type ref -); -variable_template_argument_value( - int variable_id: @variable ref, - int index: int ref, - int arg_value: @expr ref -); - -routinetypes( - unique int id: @routinetype, - int return_type: @type ref -); - -routinetypeargs( - int routine: @routinetype ref, - int index: int ref, - int type_id: @type ref -); - -ptrtomembers( - unique int id: @ptrtomember, - int type_id: @type ref, - int class_id: @type ref -); - -/* - specifiers for types, functions, and variables - - "public", - "protected", - "private", - - "const", - "volatile", - "static", - - "pure", - "virtual", - "sealed", // Microsoft - "__interface", // Microsoft - "inline", - "explicit", - - "near", // near far extension - "far", // near far extension - "__ptr32", // Microsoft - "__ptr64", // Microsoft - "__sptr", // Microsoft - "__uptr", // Microsoft - "dllimport", // Microsoft - "dllexport", // Microsoft - "thread", // Microsoft - "naked", // Microsoft - "microsoft_inline", // Microsoft - "forceinline", // Microsoft - "selectany", // Microsoft - "nothrow", // Microsoft - "novtable", // Microsoft - "noreturn", // Microsoft - "noinline", // Microsoft - "noalias", // Microsoft - "restrict", // Microsoft -*/ - -specifiers( - unique int id: @specifier, - unique string str: string ref -); - -typespecifiers( - int type_id: @type ref, - int spec_id: @specifier ref -); - -funspecifiers( - int func_id: @function ref, - int spec_id: @specifier ref -); - -varspecifiers( - int var_id: @accessible ref, - int spec_id: @specifier ref -); - -explicit_specifier_exprs( - unique int func_id: @function ref, - int constant: @expr ref -) - -attributes( - unique int id: @attribute, - int kind: int ref, - string name: string ref, - string name_space: string ref, - int location: @location_default ref -); - -case @attribute.kind of - 0 = @gnuattribute -| 1 = @stdattribute -| 2 = @declspec -| 3 = @msattribute -| 4 = @alignas -// ... 5 @objc_propertyattribute deprecated -; - -attribute_args( - unique int id: @attribute_arg, - int kind: int ref, - int attribute: @attribute ref, - int index: int ref, - int location: @location_default ref -); - -case @attribute_arg.kind of - 0 = @attribute_arg_empty -| 1 = @attribute_arg_token -| 2 = @attribute_arg_constant -| 3 = @attribute_arg_type -| 4 = @attribute_arg_constant_expr -| 5 = @attribute_arg_expr -; - -attribute_arg_value( - unique int arg: @attribute_arg ref, - string value: string ref -); -attribute_arg_type( - unique int arg: @attribute_arg ref, - int type_id: @type ref -); -attribute_arg_constant( - unique int arg: @attribute_arg ref, - int constant: @expr ref -) -attribute_arg_expr( - unique int arg: @attribute_arg ref, - int expr: @expr ref -) -attribute_arg_name( - unique int arg: @attribute_arg ref, - string name: string ref -); - -typeattributes( - int type_id: @type ref, - int spec_id: @attribute ref -); - -funcattributes( - int func_id: @function ref, - int spec_id: @attribute ref -); - -varattributes( - int var_id: @accessible ref, - int spec_id: @attribute ref -); - -stmtattributes( - int stmt_id: @stmt ref, - int spec_id: @attribute ref -); - -@type = @builtintype - | @derivedtype - | @usertype - /* TODO | @fixedpointtype */ - | @routinetype - | @ptrtomember - | @decltype; - -unspecifiedtype( - unique int type_id: @type ref, - int unspecified_type_id: @type ref -); - -member( - int parent: @type ref, - int index: int ref, - int child: @member ref -); - -@enclosingfunction_child = @usertype | @variable | @namespace - -enclosingfunction( - unique int child: @enclosingfunction_child ref, - int parent: @function ref -); - -derivations( - unique int derivation: @derivation, - int sub: @type ref, - int index: int ref, - int super: @type ref, - int location: @location_default ref -); - -derspecifiers( - int der_id: @derivation ref, - int spec_id: @specifier ref -); - -/** - * Contains the byte offset of the base class subobject within the derived - * class. Only holds for non-virtual base classes, but see table - * `virtual_base_offsets` for offsets of virtual base class subobjects. - */ -direct_base_offsets( - unique int der_id: @derivation ref, - int offset: int ref -); - -/** - * Contains the byte offset of the virtual base class subobject for class - * `super` within a most-derived object of class `sub`. `super` can be either a - * direct or indirect base class. - */ -#keyset[sub, super] -virtual_base_offsets( - int sub: @usertype ref, - int super: @usertype ref, - int offset: int ref -); - -frienddecls( - unique int id: @frienddecl, - int type_id: @type ref, - int decl_id: @declaration ref, - int location: @location_default ref -); - -@declaredtype = @usertype ; - -@declaration = @function - | @declaredtype - | @variable - | @enumconstant - | @frienddecl; - -@member = @membervariable - | @function - | @declaredtype - | @enumconstant; - -@locatable = @diagnostic - | @declaration - | @ppd_include - | @ppd_define - | @macroinvocation - /*| @funcall*/ - | @xmllocatable - | @attribute - | @attribute_arg; - -@namedscope = @namespace | @usertype; - -@element = @locatable - | @file - | @folder - | @specifier - | @type - | @expr - | @namespace - | @initialiser - | @stmt - | @derivation - | @comment - | @preprocdirect - | @fun_decl - | @var_decl - | @type_decl - | @namespace_decl - | @using - | @namequalifier - | @specialnamequalifyingelement - | @static_assert - | @type_mention - | @lambdacapture; - -@exprparent = @element; - -comments( - unique int id: @comment, - string contents: string ref, - int location: @location_default ref -); - -commentbinding( - int id: @comment ref, - int element: @element ref -); - -exprconv( - int converted: @expr ref, - unique int conversion: @expr ref -); - -compgenerated(unique int id: @element ref); - -/** - * `destructor_call` destructs the `i`'th entity that should be - * destructed following `element`. Note that entities should be - * destructed in reverse construction order, so for a given `element` - * these should be called from highest to lowest `i`. - */ -#keyset[element, destructor_call] -#keyset[element, i] -synthetic_destructor_call( - int element: @element ref, - int i: int ref, - int destructor_call: @routineexpr ref -); - -namespaces( - unique int id: @namespace, - string name: string ref -); - -namespace_inline( - unique int id: @namespace ref -); - -namespacembrs( - int parentid: @namespace ref, - unique int memberid: @namespacembr ref -); - -@namespacembr = @declaration | @namespace; - -exprparents( - int expr_id: @expr ref, - int child_index: int ref, - int parent_id: @exprparent ref -); - -expr_isload(unique int expr_id: @expr ref); - -@cast = @c_style_cast - | @const_cast - | @dynamic_cast - | @reinterpret_cast - | @static_cast - ; - -/* -case @conversion.kind of - 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast -| 1 = @bool_conversion // conversion to 'bool' -| 2 = @base_class_conversion // a derived-to-base conversion -| 3 = @derived_class_conversion // a base-to-derived conversion -| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member -| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member -| 6 = @glvalue_adjust // an adjustment of the type of a glvalue -| 7 = @prvalue_adjust // an adjustment of the type of a prvalue -; -*/ -/** - * Describes the semantics represented by a cast expression. This is largely - * independent of the source syntax of the cast, so it is separate from the - * regular expression kind. - */ -conversionkinds( - unique int expr_id: @cast ref, - int kind: int ref -); - -@conversion = @cast - | @array_to_pointer - | @parexpr - | @reference_to - | @ref_indirect - | @temp_init - | @c11_generic - ; - -/* -case @funbindexpr.kind of - 0 = @normal_call // a normal call -| 1 = @virtual_call // a virtual call -| 2 = @adl_call // a call whose target is only found by ADL -; -*/ -iscall( - unique int caller: @funbindexpr ref, - int kind: int ref -); - -numtemplatearguments( - unique int expr_id: @expr ref, - int num: int ref -); - -specialnamequalifyingelements( - unique int id: @specialnamequalifyingelement, - unique string name: string ref -); - -@namequalifiableelement = @expr | @namequalifier; -@namequalifyingelement = @namespace - | @specialnamequalifyingelement - | @usertype; - -namequalifiers( - unique int id: @namequalifier, - unique int qualifiableelement: @namequalifiableelement ref, - int qualifyingelement: @namequalifyingelement ref, - int location: @location_default ref -); - -varbind( - int expr: @varbindexpr ref, - int var: @accessible ref -); - -funbind( - int expr: @funbindexpr ref, - int fun: @function ref -); - -@any_new_expr = @new_expr - | @new_array_expr; - -@new_or_delete_expr = @any_new_expr - | @delete_expr - | @delete_array_expr; - -@prefix_crement_expr = @preincrexpr | @predecrexpr; - -@postfix_crement_expr = @postincrexpr | @postdecrexpr; - -@increment_expr = @preincrexpr | @postincrexpr; - -@decrement_expr = @predecrexpr | @postdecrexpr; - -@crement_expr = @increment_expr | @decrement_expr; - -@un_arith_op_expr = @arithnegexpr - | @unaryplusexpr - | @conjugation - | @realpartexpr - | @imagpartexpr - | @crement_expr - ; - -@un_bitwise_op_expr = @complementexpr; - -@un_log_op_expr = @notexpr; - -@un_op_expr = @address_of - | @indirect - | @un_arith_op_expr - | @un_bitwise_op_expr - | @builtinaddressof - | @vec_fill - | @un_log_op_expr - | @co_await - | @co_yield - ; - -@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; - -@cmp_op_expr = @eq_op_expr | @rel_op_expr; - -@eq_op_expr = @eqexpr | @neexpr; - -@rel_op_expr = @gtexpr - | @ltexpr - | @geexpr - | @leexpr - | @spaceshipexpr - ; - -@bin_bitwise_op_expr = @lshiftexpr - | @rshiftexpr - | @andexpr - | @orexpr - | @xorexpr - ; - -@p_arith_op_expr = @paddexpr - | @psubexpr - | @pdiffexpr - ; - -@bin_arith_op_expr = @addexpr - | @subexpr - | @mulexpr - | @divexpr - | @remexpr - | @jmulexpr - | @jdivexpr - | @fjaddexpr - | @jfaddexpr - | @fjsubexpr - | @jfsubexpr - | @minexpr - | @maxexpr - | @p_arith_op_expr - ; - -@bin_op_expr = @bin_arith_op_expr - | @bin_bitwise_op_expr - | @cmp_op_expr - | @bin_log_op_expr - ; - -@op_expr = @un_op_expr - | @bin_op_expr - | @assign_expr - | @conditionalexpr - ; - -@assign_arith_expr = @assignaddexpr - | @assignsubexpr - | @assignmulexpr - | @assigndivexpr - | @assignremexpr - ; - -@assign_bitwise_expr = @assignandexpr - | @assignorexpr - | @assignxorexpr - | @assignlshiftexpr - | @assignrshiftexpr - ; - -@assign_pointer_expr = @assignpaddexpr - | @assignpsubexpr - ; - -@assign_op_expr = @assign_arith_expr - | @assign_bitwise_expr - | @assign_pointer_expr - ; - -@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr - -/* - Binary encoding of the allocator form. - - case @allocator.form of - 0 = plain - | 1 = alignment - ; -*/ - -/** - * The allocator function associated with a `new` or `new[]` expression. - * The `form` column specified whether the allocation call contains an alignment - * argument. - */ -expr_allocator( - unique int expr: @any_new_expr ref, - int func: @function ref, - int form: int ref -); - -/* - Binary encoding of the deallocator form. - - case @deallocator.form of - 0 = plain - | 1 = size - | 2 = alignment - | 4 = destroying_delete - ; -*/ - -/** - * The deallocator function associated with a `delete`, `delete[]`, `new`, or - * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the - * one used to free memory if the initialization throws an exception. - * The `form` column specifies whether the deallocation call contains a size - * argument, and alignment argument, or both. - */ -expr_deallocator( - unique int expr: @new_or_delete_expr ref, - int func: @function ref, - int form: int ref -); - -/** - * Holds if the `@conditionalexpr` is of the two operand form - * `guard ? : false`. - */ -expr_cond_two_operand( - unique int cond: @conditionalexpr ref -); - -/** - * The guard of `@conditionalexpr` `guard ? true : false` - */ -expr_cond_guard( - unique int cond: @conditionalexpr ref, - int guard: @expr ref -); - -/** - * The expression used when the guard of `@conditionalexpr` - * `guard ? true : false` holds. For the two operand form - * `guard ?: false` consider using `expr_cond_guard` instead. - */ -expr_cond_true( - unique int cond: @conditionalexpr ref, - int true: @expr ref -); - -/** - * The expression used when the guard of `@conditionalexpr` - * `guard ? true : false` does not hold. - */ -expr_cond_false( - unique int cond: @conditionalexpr ref, - int false: @expr ref -); - -/** A string representation of the value. */ -values( - unique int id: @value, - string str: string ref -); - -/** The actual text in the source code for the value, if any. */ -valuetext( - unique int id: @value ref, - string text: string ref -); - -valuebind( - int val: @value ref, - unique int expr: @expr ref -); - -fieldoffsets( - unique int id: @variable ref, - int byteoffset: int ref, - int bitoffset: int ref -); - -bitfield( - unique int id: @variable ref, - int bits: int ref, - int declared_bits: int ref -); - -/* TODO -memberprefix( - int member: @expr ref, - int prefix: @expr ref -); -*/ - -/* - kind(1) = mbrcallexpr - kind(2) = mbrptrcallexpr - kind(3) = mbrptrmbrcallexpr - kind(4) = ptrmbrptrmbrcallexpr - kind(5) = mbrreadexpr // x.y - kind(6) = mbrptrreadexpr // p->y - kind(7) = mbrptrmbrreadexpr // x.*pm - kind(8) = mbrptrmbrptrreadexpr // x->*pm - kind(9) = staticmbrreadexpr // static x.y - kind(10) = staticmbrptrreadexpr // static p->y -*/ -/* TODO -memberaccess( - int member: @expr ref, - int kind: int ref -); -*/ - -initialisers( - unique int init: @initialiser, - int var: @accessible ref, - unique int expr: @expr ref, - int location: @location_expr ref -); - -braced_initialisers( - int init: @initialiser ref -); - -/** - * An ancestor for the expression, for cases in which we cannot - * otherwise find the expression's parent. - */ -expr_ancestor( - int exp: @expr ref, - int ancestor: @element ref -); - -exprs( - unique int id: @expr, - int kind: int ref, - int location: @location_expr ref -); - -expr_reuse( - int reuse: @expr ref, - int original: @expr ref, - int value_category: int ref -) - -/* - case @value.category of - 1 = prval - | 2 = xval - | 3 = lval - ; -*/ -expr_types( - int id: @expr ref, - int typeid: @type ref, - int value_category: int ref -); - -case @expr.kind of - 1 = @errorexpr -| 2 = @address_of // & AddressOfExpr -| 3 = @reference_to // ReferenceToExpr (implicit?) -| 4 = @indirect // * PointerDereferenceExpr -| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) -// ... -| 8 = @array_to_pointer // (???) -| 9 = @vacuous_destructor_call // VacuousDestructorCall -// ... -| 11 = @assume // Microsoft -| 12 = @parexpr -| 13 = @arithnegexpr -| 14 = @unaryplusexpr -| 15 = @complementexpr -| 16 = @notexpr -| 17 = @conjugation // GNU ~ operator -| 18 = @realpartexpr // GNU __real -| 19 = @imagpartexpr // GNU __imag -| 20 = @postincrexpr -| 21 = @postdecrexpr -| 22 = @preincrexpr -| 23 = @predecrexpr -| 24 = @conditionalexpr -| 25 = @addexpr -| 26 = @subexpr -| 27 = @mulexpr -| 28 = @divexpr -| 29 = @remexpr -| 30 = @jmulexpr // C99 mul imaginary -| 31 = @jdivexpr // C99 div imaginary -| 32 = @fjaddexpr // C99 add real + imaginary -| 33 = @jfaddexpr // C99 add imaginary + real -| 34 = @fjsubexpr // C99 sub real - imaginary -| 35 = @jfsubexpr // C99 sub imaginary - real -| 36 = @paddexpr // pointer add (pointer + int or int + pointer) -| 37 = @psubexpr // pointer sub (pointer - integer) -| 38 = @pdiffexpr // difference between two pointers -| 39 = @lshiftexpr -| 40 = @rshiftexpr -| 41 = @andexpr -| 42 = @orexpr -| 43 = @xorexpr -| 44 = @eqexpr -| 45 = @neexpr -| 46 = @gtexpr -| 47 = @ltexpr -| 48 = @geexpr -| 49 = @leexpr -| 50 = @minexpr // GNU minimum -| 51 = @maxexpr // GNU maximum -| 52 = @assignexpr -| 53 = @assignaddexpr -| 54 = @assignsubexpr -| 55 = @assignmulexpr -| 56 = @assigndivexpr -| 57 = @assignremexpr -| 58 = @assignlshiftexpr -| 59 = @assignrshiftexpr -| 60 = @assignandexpr -| 61 = @assignorexpr -| 62 = @assignxorexpr -| 63 = @assignpaddexpr // assign pointer add -| 64 = @assignpsubexpr // assign pointer sub -| 65 = @andlogicalexpr -| 66 = @orlogicalexpr -| 67 = @commaexpr -| 68 = @subscriptexpr // access to member of an array, e.g., a[5] -// ... 69 @objc_subscriptexpr deprecated -// ... 70 @cmdaccess deprecated -// ... -| 73 = @virtfunptrexpr -| 74 = @callexpr -// ... 75 @msgexpr_normal deprecated -// ... 76 @msgexpr_super deprecated -// ... 77 @atselectorexpr deprecated -// ... 78 @atprotocolexpr deprecated -| 79 = @vastartexpr -| 80 = @vaargexpr -| 81 = @vaendexpr -| 82 = @vacopyexpr -// ... 83 @atencodeexpr deprecated -| 84 = @varaccess -| 85 = @thisaccess -// ... 86 @objc_box_expr deprecated -| 87 = @new_expr -| 88 = @delete_expr -| 89 = @throw_expr -| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) -| 91 = @braced_init_list -| 92 = @type_id -| 93 = @runtime_sizeof -| 94 = @runtime_alignof -| 95 = @sizeof_pack -| 96 = @expr_stmt // GNU extension -| 97 = @routineexpr -| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) -| 99 = @offsetofexpr // offsetof ::= type and field -| 100 = @hasassignexpr // __has_assign ::= type -| 101 = @hascopyexpr // __has_copy ::= type -| 102 = @hasnothrowassign // __has_nothrow_assign ::= type -| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type -| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type -| 105 = @hastrivialassign // __has_trivial_assign ::= type -| 106 = @hastrivialconstr // __has_trivial_constructor ::= type -| 107 = @hastrivialcopy // __has_trivial_copy ::= type -| 108 = @hasuserdestr // __has_user_destructor ::= type -| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type -| 110 = @isabstractexpr // __is_abstract ::= type -| 111 = @isbaseofexpr // __is_base_of ::= type type -| 112 = @isclassexpr // __is_class ::= type -| 113 = @isconvtoexpr // __is_convertible_to ::= type type -| 114 = @isemptyexpr // __is_empty ::= type -| 115 = @isenumexpr // __is_enum ::= type -| 116 = @ispodexpr // __is_pod ::= type -| 117 = @ispolyexpr // __is_polymorphic ::= type -| 118 = @isunionexpr // __is_union ::= type -| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type -| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof -// ... -| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type -| 123 = @literal -| 124 = @uuidof -| 127 = @aggregateliteral -| 128 = @delete_array_expr -| 129 = @new_array_expr -// ... 130 @objc_array_literal deprecated -// ... 131 @objc_dictionary_literal deprecated -| 132 = @foldexpr -// ... -| 200 = @ctordirectinit -| 201 = @ctorvirtualinit -| 202 = @ctorfieldinit -| 203 = @ctordelegatinginit -| 204 = @dtordirectdestruct -| 205 = @dtorvirtualdestruct -| 206 = @dtorfielddestruct -// ... -| 210 = @static_cast -| 211 = @reinterpret_cast -| 212 = @const_cast -| 213 = @dynamic_cast -| 214 = @c_style_cast -| 215 = @lambdaexpr -| 216 = @param_ref -| 217 = @noopexpr -// ... -| 294 = @istriviallyconstructibleexpr -| 295 = @isdestructibleexpr -| 296 = @isnothrowdestructibleexpr -| 297 = @istriviallydestructibleexpr -| 298 = @istriviallyassignableexpr -| 299 = @isnothrowassignableexpr -| 300 = @istrivialexpr -| 301 = @isstandardlayoutexpr -| 302 = @istriviallycopyableexpr -| 303 = @isliteraltypeexpr -| 304 = @hastrivialmoveconstructorexpr -| 305 = @hastrivialmoveassignexpr -| 306 = @hasnothrowmoveassignexpr -| 307 = @isconstructibleexpr -| 308 = @isnothrowconstructibleexpr -| 309 = @hasfinalizerexpr -| 310 = @isdelegateexpr -| 311 = @isinterfaceclassexpr -| 312 = @isrefarrayexpr -| 313 = @isrefclassexpr -| 314 = @issealedexpr -| 315 = @issimplevalueclassexpr -| 316 = @isvalueclassexpr -| 317 = @isfinalexpr -| 319 = @noexceptexpr -| 320 = @builtinshufflevector -| 321 = @builtinchooseexpr -| 322 = @builtinaddressof -| 323 = @vec_fill -| 324 = @builtinconvertvector -| 325 = @builtincomplex -| 326 = @spaceshipexpr -| 327 = @co_await -| 328 = @co_yield -| 329 = @temp_init -| 330 = @isassignable -| 331 = @isaggregate -| 332 = @hasuniqueobjectrepresentations -| 333 = @builtinbitcast -| 334 = @builtinshuffle -| 335 = @blockassignexpr -| 336 = @issame -| 337 = @isfunction -| 338 = @islayoutcompatible -| 339 = @ispointerinterconvertiblebaseof -| 340 = @isarray -| 341 = @arrayrank -| 342 = @arrayextent -| 343 = @isarithmetic -| 344 = @iscompletetype -| 345 = @iscompound -| 346 = @isconst -| 347 = @isfloatingpoint -| 348 = @isfundamental -| 349 = @isintegral -| 350 = @islvaluereference -| 351 = @ismemberfunctionpointer -| 352 = @ismemberobjectpointer -| 353 = @ismemberpointer -| 354 = @isobject -| 355 = @ispointer -| 356 = @isreference -| 357 = @isrvaluereference -| 358 = @isscalar -| 359 = @issigned -| 360 = @isunsigned -| 361 = @isvoid -| 362 = @isvolatile -| 363 = @reuseexpr -| 364 = @istriviallycopyassignable -| 365 = @isassignablenopreconditioncheck -| 366 = @referencebindstotemporary -| 367 = @issameas -| 368 = @builtinhasattribute -| 369 = @ispointerinterconvertiblewithclass -| 370 = @builtinispointerinterconvertiblewithclass -| 371 = @iscorrespondingmember -| 372 = @builtiniscorrespondingmember -| 373 = @isboundedarray -| 374 = @isunboundedarray -| 375 = @isreferenceable -| 378 = @isnothrowconvertible -| 379 = @referenceconstructsfromtemporary -| 380 = @referenceconvertsfromtemporary -| 381 = @isconvertible -| 382 = @isvalidwinrttype -| 383 = @iswinclass -| 384 = @iswininterface -| 385 = @istriviallyequalitycomparable -| 386 = @isscopedenum -| 387 = @istriviallyrelocatable -| 388 = @datasizeof -| 389 = @c11_generic -| 390 = @requires_expr -| 391 = @nested_requirement -| 392 = @compound_requirement -| 393 = @concept_id -; - -@var_args_expr = @vastartexpr - | @vaendexpr - | @vaargexpr - | @vacopyexpr - ; - -@builtin_op = @var_args_expr - | @noopexpr - | @offsetofexpr - | @intaddrexpr - | @hasassignexpr - | @hascopyexpr - | @hasnothrowassign - | @hasnothrowconstr - | @hasnothrowcopy - | @hastrivialassign - | @hastrivialconstr - | @hastrivialcopy - | @hastrivialdestructor - | @hasuserdestr - | @hasvirtualdestr - | @isabstractexpr - | @isbaseofexpr - | @isclassexpr - | @isconvtoexpr - | @isemptyexpr - | @isenumexpr - | @ispodexpr - | @ispolyexpr - | @isunionexpr - | @typescompexpr - | @builtinshufflevector - | @builtinconvertvector - | @builtinaddressof - | @istriviallyconstructibleexpr - | @isdestructibleexpr - | @isnothrowdestructibleexpr - | @istriviallydestructibleexpr - | @istriviallyassignableexpr - | @isnothrowassignableexpr - | @istrivialexpr - | @isstandardlayoutexpr - | @istriviallycopyableexpr - | @isliteraltypeexpr - | @hastrivialmoveconstructorexpr - | @hastrivialmoveassignexpr - | @hasnothrowmoveassignexpr - | @isconstructibleexpr - | @isnothrowconstructibleexpr - | @hasfinalizerexpr - | @isdelegateexpr - | @isinterfaceclassexpr - | @isrefarrayexpr - | @isrefclassexpr - | @issealedexpr - | @issimplevalueclassexpr - | @isvalueclassexpr - | @isfinalexpr - | @builtinchooseexpr - | @builtincomplex - | @isassignable - | @isaggregate - | @hasuniqueobjectrepresentations - | @builtinbitcast - | @builtinshuffle - | @issame - | @isfunction - | @islayoutcompatible - | @ispointerinterconvertiblebaseof - | @isarray - | @arrayrank - | @arrayextent - | @isarithmetic - | @iscompletetype - | @iscompound - | @isconst - | @isfloatingpoint - | @isfundamental - | @isintegral - | @islvaluereference - | @ismemberfunctionpointer - | @ismemberobjectpointer - | @ismemberpointer - | @isobject - | @ispointer - | @isreference - | @isrvaluereference - | @isscalar - | @issigned - | @isunsigned - | @isvoid - | @isvolatile - | @istriviallycopyassignable - | @isassignablenopreconditioncheck - | @referencebindstotemporary - | @issameas - | @builtinhasattribute - | @ispointerinterconvertiblewithclass - | @builtinispointerinterconvertiblewithclass - | @iscorrespondingmember - | @builtiniscorrespondingmember - | @isboundedarray - | @isunboundedarray - | @isreferenceable - | @isnothrowconvertible - | @referenceconstructsfromtemporary - | @referenceconvertsfromtemporary - | @isconvertible - | @isvalidwinrttype - | @iswinclass - | @iswininterface - | @istriviallyequalitycomparable - | @isscopedenum - | @istriviallyrelocatable - ; - -compound_requirement_is_noexcept( - int expr: @compound_requirement ref -); - -new_allocated_type( - unique int expr: @new_expr ref, - int type_id: @type ref -); - -new_array_allocated_type( - unique int expr: @new_array_expr ref, - int type_id: @type ref -); - -/** - * The field being initialized by an initializer expression within an aggregate - * initializer for a class/struct/union. Position is used to sort repeated initializers. - */ -#keyset[aggregate, position] -aggregate_field_init( - int aggregate: @aggregateliteral ref, - int initializer: @expr ref, - int field: @membervariable ref, - int position: int ref -); - -/** - * The index of the element being initialized by an initializer expression - * within an aggregate initializer for an array. Position is used to sort repeated initializers. - */ -#keyset[aggregate, position] -aggregate_array_init( - int aggregate: @aggregateliteral ref, - int initializer: @expr ref, - int element_index: int ref, - int position: int ref -); - -@ctorinit = @ctordirectinit - | @ctorvirtualinit - | @ctorfieldinit - | @ctordelegatinginit; -@dtordestruct = @dtordirectdestruct - | @dtorvirtualdestruct - | @dtorfielddestruct; - - -condition_decl_bind( - unique int expr: @condition_decl ref, - unique int decl: @declaration ref -); - -typeid_bind( - unique int expr: @type_id ref, - int type_id: @type ref -); - -uuidof_bind( - unique int expr: @uuidof ref, - int type_id: @type ref -); - -@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; - -sizeof_bind( - unique int expr: @runtime_sizeof_or_alignof ref, - int type_id: @type ref -); - -code_block( - unique int block: @literal ref, - unique int routine: @function ref -); - -lambdas( - unique int expr: @lambdaexpr ref, - string default_capture: string ref, - boolean has_explicit_return_type: boolean ref -); - -lambda_capture( - unique int id: @lambdacapture, - int lambda: @lambdaexpr ref, - int index: int ref, - int field: @membervariable ref, - boolean captured_by_reference: boolean ref, - boolean is_implicit: boolean ref, - int location: @location_default ref -); - -@funbindexpr = @routineexpr - | @new_expr - | @delete_expr - | @delete_array_expr - | @ctordirectinit - | @ctorvirtualinit - | @ctordelegatinginit - | @dtordirectdestruct - | @dtorvirtualdestruct; - -@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; -@addressable = @function | @variable ; -@accessible = @addressable | @enumconstant ; - -@access = @varaccess | @routineexpr ; - -fold( - int expr: @foldexpr ref, - string operator: string ref, - boolean is_left_fold: boolean ref -); - -stmts( - unique int id: @stmt, - int kind: int ref, - int location: @location_stmt ref -); - -case @stmt.kind of - 1 = @stmt_expr -| 2 = @stmt_if -| 3 = @stmt_while -| 4 = @stmt_goto -| 5 = @stmt_label -| 6 = @stmt_return -| 7 = @stmt_block -| 8 = @stmt_end_test_while // do { ... } while ( ... ) -| 9 = @stmt_for -| 10 = @stmt_switch_case -| 11 = @stmt_switch -| 13 = @stmt_asm // "asm" statement or the body of an asm function -| 15 = @stmt_try_block -| 16 = @stmt_microsoft_try // Microsoft -| 17 = @stmt_decl -| 18 = @stmt_set_vla_size // C99 -| 19 = @stmt_vla_decl // C99 -| 25 = @stmt_assigned_goto // GNU -| 26 = @stmt_empty -| 27 = @stmt_continue -| 28 = @stmt_break -| 29 = @stmt_range_based_for // C++11 -// ... 30 @stmt_at_autoreleasepool_block deprecated -// ... 31 @stmt_objc_for_in deprecated -// ... 32 @stmt_at_synchronized deprecated -| 33 = @stmt_handler -// ... 34 @stmt_finally_end deprecated -| 35 = @stmt_constexpr_if -| 37 = @stmt_co_return -; - -type_vla( - int type_id: @type ref, - int decl: @stmt_vla_decl ref -); - -variable_vla( - int var: @variable ref, - int decl: @stmt_vla_decl ref -); - -if_initialization( - unique int if_stmt: @stmt_if ref, - int init_id: @stmt ref -); - -if_then( - unique int if_stmt: @stmt_if ref, - int then_id: @stmt ref -); - -if_else( - unique int if_stmt: @stmt_if ref, - int else_id: @stmt ref -); - -constexpr_if_initialization( - unique int constexpr_if_stmt: @stmt_constexpr_if ref, - int init_id: @stmt ref -); - -constexpr_if_then( - unique int constexpr_if_stmt: @stmt_constexpr_if ref, - int then_id: @stmt ref -); - -constexpr_if_else( - unique int constexpr_if_stmt: @stmt_constexpr_if ref, - int else_id: @stmt ref -); - -while_body( - unique int while_stmt: @stmt_while ref, - int body_id: @stmt ref -); - -do_body( - unique int do_stmt: @stmt_end_test_while ref, - int body_id: @stmt ref -); - -switch_initialization( - unique int switch_stmt: @stmt_switch ref, - int init_id: @stmt ref -); - -#keyset[switch_stmt, index] -switch_case( - int switch_stmt: @stmt_switch ref, - int index: int ref, - int case_id: @stmt_switch_case ref -); - -switch_body( - unique int switch_stmt: @stmt_switch ref, - int body_id: @stmt ref -); - -@stmt_for_or_range_based_for = @stmt_for - | @stmt_range_based_for; - -for_initialization( - unique int for_stmt: @stmt_for_or_range_based_for ref, - int init_id: @stmt ref -); - -for_condition( - unique int for_stmt: @stmt_for ref, - int condition_id: @expr ref -); - -for_update( - unique int for_stmt: @stmt_for ref, - int update_id: @expr ref -); - -for_body( - unique int for_stmt: @stmt_for ref, - int body_id: @stmt ref -); - -@stmtparent = @stmt | @expr_stmt ; -stmtparents( - unique int id: @stmt ref, - int index: int ref, - int parent: @stmtparent ref -); - -ishandler(unique int block: @stmt_block ref); - -@cfgnode = @stmt | @expr | @function | @initialiser ; - -stmt_decl_bind( - int stmt: @stmt_decl ref, - int num: int ref, - int decl: @declaration ref -); - -stmt_decl_entry_bind( - int stmt: @stmt_decl ref, - int num: int ref, - int decl_entry: @element ref -); - -@parameterized_element = @function | @stmt_block | @requires_expr; - -blockscope( - unique int block: @stmt_block ref, - int enclosing: @parameterized_element ref -); - -@jump = @stmt_goto | @stmt_break | @stmt_continue; - -@jumporlabel = @jump | @stmt_label | @literal; - -jumpinfo( - unique int id: @jumporlabel ref, - string str: string ref, - int target: @stmt ref -); - -preprocdirects( - unique int id: @preprocdirect, - int kind: int ref, - int location: @location_default ref -); -case @preprocdirect.kind of - 0 = @ppd_if -| 1 = @ppd_ifdef -| 2 = @ppd_ifndef -| 3 = @ppd_elif -| 4 = @ppd_else -| 5 = @ppd_endif -| 6 = @ppd_plain_include -| 7 = @ppd_define -| 8 = @ppd_undef -| 9 = @ppd_line -| 10 = @ppd_error -| 11 = @ppd_pragma -| 12 = @ppd_objc_import -| 13 = @ppd_include_next -| 18 = @ppd_warning -; - -@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; - -@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; - -preprocpair( - int begin : @ppd_branch ref, - int elseelifend : @preprocdirect ref -); - -preproctrue(int branch : @ppd_branch ref); -preprocfalse(int branch : @ppd_branch ref); - -preproctext( - unique int id: @preprocdirect ref, - string head: string ref, - string body: string ref -); - -includes( - unique int id: @ppd_include ref, - int included: @file ref -); - -link_targets( - int id: @link_target, - int binary: @file ref -); - -link_parent( - int element : @element ref, - int link_target : @link_target ref -); - -/* XML Files */ - -xmlEncoding(unique int id: @file ref, string encoding: string ref); - -xmlDTDs( - unique int id: @xmldtd, - string root: string ref, - string publicId: string ref, - string systemId: string ref, - int fileid: @file ref -); - -xmlElements( - unique int id: @xmlelement, - string name: string ref, - int parentid: @xmlparent ref, - int idx: int ref, - int fileid: @file ref -); - -xmlAttrs( - unique int id: @xmlattribute, - int elementid: @xmlelement ref, - string name: string ref, - string value: string ref, - int idx: int ref, - int fileid: @file ref -); - -xmlNs( - int id: @xmlnamespace, - string prefixName: string ref, - string URI: string ref, - int fileid: @file ref -); - -xmlHasNs( - int elementId: @xmlnamespaceable ref, - int nsId: @xmlnamespace ref, - int fileid: @file ref -); - -xmlComments( - unique int id: @xmlcomment, - string text: string ref, - int parentid: @xmlparent ref, - int fileid: @file ref -); - -xmlChars( - unique int id: @xmlcharacters, - string text: string ref, - int parentid: @xmlparent ref, - int idx: int ref, - int isCDATA: int ref, - int fileid: @file ref -); - -@xmlparent = @file | @xmlelement; -@xmlnamespaceable = @xmlelement | @xmlattribute; - -xmllocations( - int xmlElement: @xmllocatable ref, - int location: @location_default ref -); - -@xmllocatable = @xmlcharacters - | @xmlelement - | @xmlcomment - | @xmlattribute - | @xmldtd - | @file - | @xmlnamespace; diff --git a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/semmlecode.cpp.dbscheme b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/semmlecode.cpp.dbscheme deleted file mode 100644 index e51fad7a243..00000000000 --- a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/semmlecode.cpp.dbscheme +++ /dev/null @@ -1,2323 +0,0 @@ - -/** - * An invocation of the compiler. Note that more than one file may be - * compiled per invocation. For example, this command compiles three - * source files: - * - * gcc -c f1.c f2.c f3.c - * - * The `id` simply identifies the invocation, while `cwd` is the working - * directory from which the compiler was invoked. - */ -compilations( - /** - * An invocation of the compiler. Note that more than one file may - * be compiled per invocation. For example, this command compiles - * three source files: - * - * gcc -c f1.c f2.c f3.c - */ - unique int id : @compilation, - string cwd : string ref -); - -/** - * The arguments that were passed to the extractor for a compiler - * invocation. If `id` is for the compiler invocation - * - * gcc -c f1.c f2.c f3.c - * - * then typically there will be rows for - * - * num | arg - * --- | --- - * 0 | *path to extractor* - * 1 | `--mimic` - * 2 | `/usr/bin/gcc` - * 3 | `-c` - * 4 | f1.c - * 5 | f2.c - * 6 | f3.c - */ -#keyset[id, num] -compilation_args( - int id : @compilation ref, - int num : int ref, - string arg : string ref -); - -/** - * The source files that are compiled by a compiler invocation. - * If `id` is for the compiler invocation - * - * gcc -c f1.c f2.c f3.c - * - * then there will be rows for - * - * num | arg - * --- | --- - * 0 | f1.c - * 1 | f2.c - * 2 | f3.c - * - * Note that even if those files `#include` headers, those headers - * do not appear as rows. - */ -#keyset[id, num] -compilation_compiling_files( - int id : @compilation ref, - int num : int ref, - int file : @file ref -); - -/** - * The time taken by the extractor for a compiler invocation. - * - * For each file `num`, there will be rows for - * - * kind | seconds - * ---- | --- - * 1 | CPU seconds used by the extractor frontend - * 2 | Elapsed seconds during the extractor frontend - * 3 | CPU seconds used by the extractor backend - * 4 | Elapsed seconds during the extractor backend - */ -#keyset[id, num, kind] -compilation_time( - int id : @compilation ref, - int num : int ref, - /* kind: - 1 = frontend_cpu_seconds - 2 = frontend_elapsed_seconds - 3 = extractor_cpu_seconds - 4 = extractor_elapsed_seconds - */ - int kind : int ref, - float seconds : float ref -); - -/** - * An error or warning generated by the extractor. - * The diagnostic message `diagnostic` was generated during compiler - * invocation `compilation`, and is the `file_number_diagnostic_number`th - * message generated while extracting the `file_number`th file of that - * invocation. - */ -#keyset[compilation, file_number, file_number_diagnostic_number] -diagnostic_for( - int diagnostic : @diagnostic ref, - int compilation : @compilation ref, - int file_number : int ref, - int file_number_diagnostic_number : int ref -); - -/** - * If extraction was successful, then `cpu_seconds` and - * `elapsed_seconds` are the CPU time and elapsed time (respectively) - * that extraction took for compiler invocation `id`. - */ -compilation_finished( - unique int id : @compilation ref, - float cpu_seconds : float ref, - float elapsed_seconds : float ref -); - - -/** - * External data, loaded from CSV files during snapshot creation. See - * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) - * for more information. - */ -externalData( - int id : @externalDataElement, - string path : string ref, - int column: int ref, - string value : string ref -); - -/** - * The source location of the snapshot. - */ -sourceLocationPrefix(string prefix : string ref); - -/** - * Information about packages that provide code used during compilation. - * The `id` is just a unique identifier. - * The `namespace` is typically the name of the package manager that - * provided the package (e.g. "dpkg" or "yum"). - * The `package_name` is the name of the package, and `version` is its - * version (as a string). - */ -external_packages( - unique int id: @external_package, - string namespace : string ref, - string package_name : string ref, - string version : string ref -); - -/** - * Holds if File `fileid` was provided by package `package`. - */ -header_to_external_package( - int fileid : @file ref, - int package : @external_package ref -); - -/* - * Version history - */ - -svnentries( - unique int id : @svnentry, - string revision : string ref, - string author : string ref, - date revisionDate : date ref, - int changeSize : int ref -) - -svnaffectedfiles( - int id : @svnentry ref, - int file : @file ref, - string action : string ref -) - -svnentrymsg( - unique int id : @svnentry ref, - string message : string ref -) - -svnchurn( - int commit : @svnentry ref, - int file : @file ref, - int addedLines : int ref, - int deletedLines : int ref -) - -/* - * C++ dbscheme - */ - -extractor_version( - string codeql_version: string ref, - string frontend_version: string ref -) - -@location = @location_stmt | @location_expr | @location_default ; - -/** - * The location of an element that is not an expression or a statement. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `file`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ -locations_default( - /** The location of an element that is not an expression or a statement. */ - unique int id: @location_default, - int container: @container ref, - int startLine: int ref, - int startColumn: int ref, - int endLine: int ref, - int endColumn: int ref -); - -/** - * The location of a statement. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `file`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ -locations_stmt( - /** The location of a statement. */ - unique int id: @location_stmt, - int container: @container ref, - int startLine: int ref, - int startColumn: int ref, - int endLine: int ref, - int endColumn: int ref -); - -/** - * The location of an expression. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `file`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ -locations_expr( - /** The location of an expression. */ - unique int id: @location_expr, - int container: @container ref, - int startLine: int ref, - int startColumn: int ref, - int endLine: int ref, - int endColumn: int ref -); - -/** An element for which line-count information is available. */ -@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; - -numlines( - int element_id: @sourceline ref, - int num_lines: int ref, - int num_code: int ref, - int num_comment: int ref -); - -diagnostics( - unique int id: @diagnostic, - int severity: int ref, - string error_tag: string ref, - string error_message: string ref, - string full_error_message: string ref, - int location: @location_default ref -); - -files( - unique int id: @file, - string name: string ref -); - -folders( - unique int id: @folder, - string name: string ref -); - -@container = @folder | @file - -containerparent( - int parent: @container ref, - unique int child: @container ref -); - -fileannotations( - int id: @file ref, - int kind: int ref, - string name: string ref, - string value: string ref -); - -inmacroexpansion( - int id: @element ref, - int inv: @macroinvocation ref -); - -affectedbymacroexpansion( - int id: @element ref, - int inv: @macroinvocation ref -); - -case @macroinvocation.kind of - 1 = @macro_expansion -| 2 = @other_macro_reference -; - -macroinvocations( - unique int id: @macroinvocation, - int macro_id: @ppd_define ref, - int location: @location_default ref, - int kind: int ref -); - -macroparent( - unique int id: @macroinvocation ref, - int parent_id: @macroinvocation ref -); - -// a macroinvocation may be part of another location -// the way to find a constant expression that uses a macro -// is thus to find a constant expression that has a location -// to which a macro invocation is bound -macrolocationbind( - int id: @macroinvocation ref, - int location: @location ref -); - -#keyset[invocation, argument_index] -macro_argument_unexpanded( - int invocation: @macroinvocation ref, - int argument_index: int ref, - string text: string ref -); - -#keyset[invocation, argument_index] -macro_argument_expanded( - int invocation: @macroinvocation ref, - int argument_index: int ref, - string text: string ref -); - -/* -case @function.kind of - 1 = @normal_function -| 2 = @constructor -| 3 = @destructor -| 4 = @conversion_function -| 5 = @operator -| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk -| 7 = @user_defined_literal -| 8 = @deduction_guide -; -*/ - -functions( - unique int id: @function, - string name: string ref, - int kind: int ref -); - -function_entry_point( - int id: @function ref, - unique int entry_point: @stmt ref -); - -function_return_type( - int id: @function ref, - int return_type: @type ref -); - -/** - * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` - * instance associated with it, and the variables representing the `handle` and `promise` - * for it. - */ -coroutine( - unique int function: @function ref, - int traits: @type ref -); - -/* -case @coroutine_placeholder_variable.kind of - 1 = @handle -| 2 = @promise -| 3 = @init_await_resume -; -*/ - -coroutine_placeholder_variable( - unique int placeholder_variable: @variable ref, - int kind: int ref, - int function: @function ref -) - -/** The `new` function used for allocating the coroutine state, if any. */ -coroutine_new( - unique int function: @function ref, - int new: @function ref -); - -/** The `delete` function used for deallocating the coroutine state, if any. */ -coroutine_delete( - unique int function: @function ref, - int delete: @function ref -); - -purefunctions(unique int id: @function ref); - -function_deleted(unique int id: @function ref); - -function_defaulted(unique int id: @function ref); - -function_prototyped(unique int id: @function ref) - -deduction_guide_for_class( - int id: @function ref, - int class_template: @usertype ref -) - -member_function_this_type( - unique int id: @function ref, - int this_type: @type ref -); - -#keyset[id, type_id] -fun_decls( - int id: @fun_decl, - int function: @function ref, - int type_id: @type ref, - string name: string ref, - int location: @location_default ref -); -fun_def(unique int id: @fun_decl ref); -fun_specialized(unique int id: @fun_decl ref); -fun_implicit(unique int id: @fun_decl ref); -fun_decl_specifiers( - int id: @fun_decl ref, - string name: string ref -) -#keyset[fun_decl, index] -fun_decl_throws( - int fun_decl: @fun_decl ref, - int index: int ref, - int type_id: @type ref -); -/* an empty throw specification is different from none */ -fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); -fun_decl_noexcept( - int fun_decl: @fun_decl ref, - int constant: @expr ref -); -fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); -fun_decl_typedef_type( - unique int fun_decl: @fun_decl ref, - int typedeftype_id: @usertype ref -); - -param_decl_bind( - unique int id: @var_decl ref, - int index: int ref, - int fun_decl: @fun_decl ref -); - -#keyset[id, type_id] -var_decls( - int id: @var_decl, - int variable: @variable ref, - int type_id: @type ref, - string name: string ref, - int location: @location_default ref -); -var_def(unique int id: @var_decl ref); -var_decl_specifiers( - int id: @var_decl ref, - string name: string ref -) -is_structured_binding(unique int id: @variable ref); - -type_decls( - unique int id: @type_decl, - int type_id: @type ref, - int location: @location_default ref -); -type_def(unique int id: @type_decl ref); -type_decl_top( - unique int type_decl: @type_decl ref -); - -namespace_decls( - unique int id: @namespace_decl, - int namespace_id: @namespace ref, - int location: @location_default ref, - int bodylocation: @location_default ref -); - -case @using.kind of - 1 = @using_declaration -| 2 = @using_directive -| 3 = @using_enum_declaration -; - -usings( - unique int id: @using, - int element_id: @element ref, - int location: @location_default ref, - int kind: int ref -); - -/** The element which contains the `using` declaration. */ -using_container( - int parent: @element ref, - int child: @using ref -); - -static_asserts( - unique int id: @static_assert, - int condition : @expr ref, - string message : string ref, - int location: @location_default ref, - int enclosing : @element ref -); - -// each function has an ordered list of parameters -#keyset[id, type_id] -#keyset[function, index, type_id] -params( - int id: @parameter, - int function: @parameterized_element ref, - int index: int ref, - int type_id: @type ref -); - -overrides( - int new: @function ref, - int old: @function ref -); - -#keyset[id, type_id] -membervariables( - int id: @membervariable, - int type_id: @type ref, - string name: string ref -); - -#keyset[id, type_id] -globalvariables( - int id: @globalvariable, - int type_id: @type ref, - string name: string ref -); - -#keyset[id, type_id] -localvariables( - int id: @localvariable, - int type_id: @type ref, - string name: string ref -); - -autoderivation( - unique int var: @variable ref, - int derivation_type: @type ref -); - -orphaned_variables( - int var: @localvariable ref, - int function: @function ref -) - -enumconstants( - unique int id: @enumconstant, - int parent: @usertype ref, - int index: int ref, - int type_id: @type ref, - string name: string ref, - int location: @location_default ref -); - -@variable = @localscopevariable | @globalvariable | @membervariable; - -@localscopevariable = @localvariable | @parameter; - -/** - * Built-in types are the fundamental types, e.g., integral, floating, and void. - */ -case @builtintype.kind of - 1 = @errortype -| 2 = @unknowntype -| 3 = @void -| 4 = @boolean -| 5 = @char -| 6 = @unsigned_char -| 7 = @signed_char -| 8 = @short -| 9 = @unsigned_short -| 10 = @signed_short -| 11 = @int -| 12 = @unsigned_int -| 13 = @signed_int -| 14 = @long -| 15 = @unsigned_long -| 16 = @signed_long -| 17 = @long_long -| 18 = @unsigned_long_long -| 19 = @signed_long_long -// ... 20 Microsoft-specific __int8 -// ... 21 Microsoft-specific __int16 -// ... 22 Microsoft-specific __int32 -// ... 23 Microsoft-specific __int64 -| 24 = @float -| 25 = @double -| 26 = @long_double -| 27 = @complex_float // C99-specific _Complex float -| 28 = @complex_double // C99-specific _Complex double -| 29 = @complex_long_double // C99-specific _Complex long double -| 30 = @imaginary_float // C99-specific _Imaginary float -| 31 = @imaginary_double // C99-specific _Imaginary double -| 32 = @imaginary_long_double // C99-specific _Imaginary long double -| 33 = @wchar_t // Microsoft-specific -| 34 = @decltype_nullptr // C++11 -| 35 = @int128 // __int128 -| 36 = @unsigned_int128 // unsigned __int128 -| 37 = @signed_int128 // signed __int128 -| 38 = @float128 // __float128 -| 39 = @complex_float128 // _Complex __float128 -| 40 = @decimal32 // _Decimal32 -| 41 = @decimal64 // _Decimal64 -| 42 = @decimal128 // _Decimal128 -| 43 = @char16_t -| 44 = @char32_t -| 45 = @std_float32 // _Float32 -| 46 = @float32x // _Float32x -| 47 = @std_float64 // _Float64 -| 48 = @float64x // _Float64x -| 49 = @std_float128 // _Float128 -// ... 50 _Float128x -| 51 = @char8_t -| 52 = @float16 // _Float16 -| 53 = @complex_float16 // _Complex _Float16 -| 54 = @fp16 // __fp16 -| 55 = @std_bfloat16 // __bf16 -| 56 = @std_float16 // std::float16_t -| 57 = @complex_std_float32 // _Complex _Float32 -| 58 = @complex_float32x // _Complex _Float32x -| 59 = @complex_std_float64 // _Complex _Float64 -| 60 = @complex_float64x // _Complex _Float64x -| 61 = @complex_std_float128 // _Complex _Float128 -; - -builtintypes( - unique int id: @builtintype, - string name: string ref, - int kind: int ref, - int size: int ref, - int sign: int ref, - int alignment: int ref -); - -/** - * Derived types are types that are directly derived from existing types and - * point to, refer to, transform type data to return a new type. - */ -case @derivedtype.kind of - 1 = @pointer -| 2 = @reference -| 3 = @type_with_specifiers -| 4 = @array -| 5 = @gnu_vector -| 6 = @routineptr -| 7 = @routinereference -| 8 = @rvalue_reference // C++11 -// ... 9 type_conforming_to_protocols deprecated -| 10 = @block -; - -derivedtypes( - unique int id: @derivedtype, - string name: string ref, - int kind: int ref, - int type_id: @type ref -); - -pointerishsize(unique int id: @derivedtype ref, - int size: int ref, - int alignment: int ref); - -arraysizes( - unique int id: @derivedtype ref, - int num_elements: int ref, - int bytesize: int ref, - int alignment: int ref -); - -typedefbase( - unique int id: @usertype ref, - int type_id: @type ref -); - -/** - * An instance of the C++11 `decltype` operator. For example: - * ``` - * int a; - * decltype(1+a) b; - * ``` - * Here `expr` is `1+a`. - * - * Sometimes an additional pair of parentheses around the expression - * would change the semantics of this decltype, e.g. - * ``` - * struct A { double x; }; - * const A* a = new A(); - * decltype( a->x ); // type is double - * decltype((a->x)); // type is const double& - * ``` - * (Please consult the C++11 standard for more details). - * `parentheses_would_change_meaning` is `true` iff that is the case. - */ -#keyset[id, expr] -decltypes( - int id: @decltype, - int expr: @expr ref, - int base_type: @type ref, - boolean parentheses_would_change_meaning: boolean ref -); - -/* -case @usertype.kind of - 1 = @struct -| 2 = @class -| 3 = @union -| 4 = @enum -| 5 = @typedef // classic C: typedef typedef type name -| 6 = @template -| 7 = @template_parameter -| 8 = @template_template_parameter -| 9 = @proxy_class // a proxy class associated with a template parameter -// ... 10 objc_class deprecated -// ... 11 objc_protocol deprecated -// ... 12 objc_category deprecated -| 13 = @scoped_enum -| 14 = @using_alias // a using name = type style typedef -; -*/ - -usertypes( - unique int id: @usertype, - string name: string ref, - int kind: int ref -); - -usertypesize( - unique int id: @usertype ref, - int size: int ref, - int alignment: int ref -); - -usertype_final(unique int id: @usertype ref); - -usertype_uuid( - unique int id: @usertype ref, - string uuid: string ref -); - -mangled_name( - unique int id: @declaration ref, - int mangled_name : @mangledname, - boolean is_complete: boolean ref -); - -is_pod_class(unique int id: @usertype ref); -is_standard_layout_class(unique int id: @usertype ref); - -is_complete(unique int id: @usertype ref); - -is_class_template(unique int id: @usertype ref); -class_instantiation( - int to: @usertype ref, - int from: @usertype ref -); -class_template_argument( - int type_id: @usertype ref, - int index: int ref, - int arg_type: @type ref -); -class_template_argument_value( - int type_id: @usertype ref, - int index: int ref, - int arg_value: @expr ref -); - -is_proxy_class_for( - unique int id: @usertype ref, - unique int templ_param_id: @usertype ref -); - -type_mentions( - unique int id: @type_mention, - int type_id: @type ref, - int location: @location ref, - // a_symbol_reference_kind from the frontend. - int kind: int ref -); - -is_function_template(unique int id: @function ref); -function_instantiation( - unique int to: @function ref, - int from: @function ref -); -function_template_argument( - int function_id: @function ref, - int index: int ref, - int arg_type: @type ref -); -function_template_argument_value( - int function_id: @function ref, - int index: int ref, - int arg_value: @expr ref -); - -is_variable_template(unique int id: @variable ref); -variable_instantiation( - unique int to: @variable ref, - int from: @variable ref -); -variable_template_argument( - int variable_id: @variable ref, - int index: int ref, - int arg_type: @type ref -); -variable_template_argument_value( - int variable_id: @variable ref, - int index: int ref, - int arg_value: @expr ref -); - -routinetypes( - unique int id: @routinetype, - int return_type: @type ref -); - -routinetypeargs( - int routine: @routinetype ref, - int index: int ref, - int type_id: @type ref -); - -ptrtomembers( - unique int id: @ptrtomember, - int type_id: @type ref, - int class_id: @type ref -); - -/* - specifiers for types, functions, and variables - - "public", - "protected", - "private", - - "const", - "volatile", - "static", - - "pure", - "virtual", - "sealed", // Microsoft - "__interface", // Microsoft - "inline", - "explicit", - - "near", // near far extension - "far", // near far extension - "__ptr32", // Microsoft - "__ptr64", // Microsoft - "__sptr", // Microsoft - "__uptr", // Microsoft - "dllimport", // Microsoft - "dllexport", // Microsoft - "thread", // Microsoft - "naked", // Microsoft - "microsoft_inline", // Microsoft - "forceinline", // Microsoft - "selectany", // Microsoft - "nothrow", // Microsoft - "novtable", // Microsoft - "noreturn", // Microsoft - "noinline", // Microsoft - "noalias", // Microsoft - "restrict", // Microsoft -*/ - -specifiers( - unique int id: @specifier, - unique string str: string ref -); - -typespecifiers( - int type_id: @type ref, - int spec_id: @specifier ref -); - -funspecifiers( - int func_id: @function ref, - int spec_id: @specifier ref -); - -varspecifiers( - int var_id: @accessible ref, - int spec_id: @specifier ref -); - -explicit_specifier_exprs( - unique int func_id: @function ref, - int constant: @expr ref -) - -attributes( - unique int id: @attribute, - int kind: int ref, - string name: string ref, - string name_space: string ref, - int location: @location_default ref -); - -case @attribute.kind of - 0 = @gnuattribute -| 1 = @stdattribute -| 2 = @declspec -| 3 = @msattribute -| 4 = @alignas -// ... 5 @objc_propertyattribute deprecated -; - -attribute_args( - unique int id: @attribute_arg, - int kind: int ref, - int attribute: @attribute ref, - int index: int ref, - int location: @location_default ref -); - -case @attribute_arg.kind of - 0 = @attribute_arg_empty -| 1 = @attribute_arg_token -| 2 = @attribute_arg_constant -| 3 = @attribute_arg_type -| 4 = @attribute_arg_constant_expr -| 5 = @attribute_arg_expr -; - -attribute_arg_value( - unique int arg: @attribute_arg ref, - string value: string ref -); -attribute_arg_type( - unique int arg: @attribute_arg ref, - int type_id: @type ref -); -attribute_arg_constant( - unique int arg: @attribute_arg ref, - int constant: @expr ref -) -attribute_arg_expr( - unique int arg: @attribute_arg ref, - int expr: @expr ref -) -attribute_arg_name( - unique int arg: @attribute_arg ref, - string name: string ref -); - -typeattributes( - int type_id: @type ref, - int spec_id: @attribute ref -); - -funcattributes( - int func_id: @function ref, - int spec_id: @attribute ref -); - -varattributes( - int var_id: @accessible ref, - int spec_id: @attribute ref -); - -stmtattributes( - int stmt_id: @stmt ref, - int spec_id: @attribute ref -); - -@type = @builtintype - | @derivedtype - | @usertype - /* TODO | @fixedpointtype */ - | @routinetype - | @ptrtomember - | @decltype; - -unspecifiedtype( - unique int type_id: @type ref, - int unspecified_type_id: @type ref -); - -member( - int parent: @type ref, - int index: int ref, - int child: @member ref -); - -@enclosingfunction_child = @usertype | @variable | @namespace - -enclosingfunction( - unique int child: @enclosingfunction_child ref, - int parent: @function ref -); - -derivations( - unique int derivation: @derivation, - int sub: @type ref, - int index: int ref, - int super: @type ref, - int location: @location_default ref -); - -derspecifiers( - int der_id: @derivation ref, - int spec_id: @specifier ref -); - -/** - * Contains the byte offset of the base class subobject within the derived - * class. Only holds for non-virtual base classes, but see table - * `virtual_base_offsets` for offsets of virtual base class subobjects. - */ -direct_base_offsets( - unique int der_id: @derivation ref, - int offset: int ref -); - -/** - * Contains the byte offset of the virtual base class subobject for class - * `super` within a most-derived object of class `sub`. `super` can be either a - * direct or indirect base class. - */ -#keyset[sub, super] -virtual_base_offsets( - int sub: @usertype ref, - int super: @usertype ref, - int offset: int ref -); - -frienddecls( - unique int id: @frienddecl, - int type_id: @type ref, - int decl_id: @declaration ref, - int location: @location_default ref -); - -@declaredtype = @usertype ; - -@declaration = @function - | @declaredtype - | @variable - | @enumconstant - | @frienddecl; - -@member = @membervariable - | @function - | @declaredtype - | @enumconstant; - -@locatable = @diagnostic - | @declaration - | @ppd_include - | @ppd_define - | @macroinvocation - /*| @funcall*/ - | @xmllocatable - | @attribute - | @attribute_arg; - -@namedscope = @namespace | @usertype; - -@element = @locatable - | @file - | @folder - | @specifier - | @type - | @expr - | @namespace - | @initialiser - | @stmt - | @derivation - | @comment - | @preprocdirect - | @fun_decl - | @var_decl - | @type_decl - | @namespace_decl - | @using - | @namequalifier - | @specialnamequalifyingelement - | @static_assert - | @type_mention - | @lambdacapture; - -@exprparent = @element; - -comments( - unique int id: @comment, - string contents: string ref, - int location: @location_default ref -); - -commentbinding( - int id: @comment ref, - int element: @element ref -); - -exprconv( - int converted: @expr ref, - unique int conversion: @expr ref -); - -compgenerated(unique int id: @element ref); - -/** - * `destructor_call` destructs the `i`'th entity that should be - * destructed following `element`. Note that entities should be - * destructed in reverse construction order, so for a given `element` - * these should be called from highest to lowest `i`. - */ -#keyset[element, destructor_call] -#keyset[element, i] -synthetic_destructor_call( - int element: @element ref, - int i: int ref, - int destructor_call: @routineexpr ref -); - -namespaces( - unique int id: @namespace, - string name: string ref -); - -namespace_inline( - unique int id: @namespace ref -); - -namespacembrs( - int parentid: @namespace ref, - unique int memberid: @namespacembr ref -); - -@namespacembr = @declaration | @namespace; - -exprparents( - int expr_id: @expr ref, - int child_index: int ref, - int parent_id: @exprparent ref -); - -expr_isload(unique int expr_id: @expr ref); - -@cast = @c_style_cast - | @const_cast - | @dynamic_cast - | @reinterpret_cast - | @static_cast - ; - -/* -case @conversion.kind of - 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast -| 1 = @bool_conversion // conversion to 'bool' -| 2 = @base_class_conversion // a derived-to-base conversion -| 3 = @derived_class_conversion // a base-to-derived conversion -| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member -| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member -| 6 = @glvalue_adjust // an adjustment of the type of a glvalue -| 7 = @prvalue_adjust // an adjustment of the type of a prvalue -; -*/ -/** - * Describes the semantics represented by a cast expression. This is largely - * independent of the source syntax of the cast, so it is separate from the - * regular expression kind. - */ -conversionkinds( - unique int expr_id: @cast ref, - int kind: int ref -); - -@conversion = @cast - | @array_to_pointer - | @parexpr - | @reference_to - | @ref_indirect - | @temp_init - | @c11_generic - ; - -/* -case @funbindexpr.kind of - 0 = @normal_call // a normal call -| 1 = @virtual_call // a virtual call -| 2 = @adl_call // a call whose target is only found by ADL -; -*/ -iscall( - unique int caller: @funbindexpr ref, - int kind: int ref -); - -numtemplatearguments( - unique int expr_id: @expr ref, - int num: int ref -); - -specialnamequalifyingelements( - unique int id: @specialnamequalifyingelement, - unique string name: string ref -); - -@namequalifiableelement = @expr | @namequalifier; -@namequalifyingelement = @namespace - | @specialnamequalifyingelement - | @usertype; - -namequalifiers( - unique int id: @namequalifier, - unique int qualifiableelement: @namequalifiableelement ref, - int qualifyingelement: @namequalifyingelement ref, - int location: @location_default ref -); - -varbind( - int expr: @varbindexpr ref, - int var: @accessible ref -); - -funbind( - int expr: @funbindexpr ref, - int fun: @function ref -); - -@any_new_expr = @new_expr - | @new_array_expr; - -@new_or_delete_expr = @any_new_expr - | @delete_expr - | @delete_array_expr; - -@prefix_crement_expr = @preincrexpr | @predecrexpr; - -@postfix_crement_expr = @postincrexpr | @postdecrexpr; - -@increment_expr = @preincrexpr | @postincrexpr; - -@decrement_expr = @predecrexpr | @postdecrexpr; - -@crement_expr = @increment_expr | @decrement_expr; - -@un_arith_op_expr = @arithnegexpr - | @unaryplusexpr - | @conjugation - | @realpartexpr - | @imagpartexpr - | @crement_expr - ; - -@un_bitwise_op_expr = @complementexpr; - -@un_log_op_expr = @notexpr; - -@un_op_expr = @address_of - | @indirect - | @un_arith_op_expr - | @un_bitwise_op_expr - | @builtinaddressof - | @vec_fill - | @un_log_op_expr - | @co_await - | @co_yield - ; - -@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; - -@cmp_op_expr = @eq_op_expr | @rel_op_expr; - -@eq_op_expr = @eqexpr | @neexpr; - -@rel_op_expr = @gtexpr - | @ltexpr - | @geexpr - | @leexpr - | @spaceshipexpr - ; - -@bin_bitwise_op_expr = @lshiftexpr - | @rshiftexpr - | @andexpr - | @orexpr - | @xorexpr - ; - -@p_arith_op_expr = @paddexpr - | @psubexpr - | @pdiffexpr - ; - -@bin_arith_op_expr = @addexpr - | @subexpr - | @mulexpr - | @divexpr - | @remexpr - | @jmulexpr - | @jdivexpr - | @fjaddexpr - | @jfaddexpr - | @fjsubexpr - | @jfsubexpr - | @minexpr - | @maxexpr - | @p_arith_op_expr - ; - -@bin_op_expr = @bin_arith_op_expr - | @bin_bitwise_op_expr - | @cmp_op_expr - | @bin_log_op_expr - ; - -@op_expr = @un_op_expr - | @bin_op_expr - | @assign_expr - | @conditionalexpr - ; - -@assign_arith_expr = @assignaddexpr - | @assignsubexpr - | @assignmulexpr - | @assigndivexpr - | @assignremexpr - ; - -@assign_bitwise_expr = @assignandexpr - | @assignorexpr - | @assignxorexpr - | @assignlshiftexpr - | @assignrshiftexpr - ; - -@assign_pointer_expr = @assignpaddexpr - | @assignpsubexpr - ; - -@assign_op_expr = @assign_arith_expr - | @assign_bitwise_expr - | @assign_pointer_expr - ; - -@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr - -/* - Binary encoding of the allocator form. - - case @allocator.form of - 0 = plain - | 1 = alignment - ; -*/ - -/** - * The allocator function associated with a `new` or `new[]` expression. - * The `form` column specified whether the allocation call contains an alignment - * argument. - */ -expr_allocator( - unique int expr: @any_new_expr ref, - int func: @function ref, - int form: int ref -); - -/* - Binary encoding of the deallocator form. - - case @deallocator.form of - 0 = plain - | 1 = size - | 2 = alignment - | 4 = destroying_delete - ; -*/ - -/** - * The deallocator function associated with a `delete`, `delete[]`, `new`, or - * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the - * one used to free memory if the initialization throws an exception. - * The `form` column specifies whether the deallocation call contains a size - * argument, and alignment argument, or both. - */ -expr_deallocator( - unique int expr: @new_or_delete_expr ref, - int func: @function ref, - int form: int ref -); - -/** - * Holds if the `@conditionalexpr` is of the two operand form - * `guard ? : false`. - */ -expr_cond_two_operand( - unique int cond: @conditionalexpr ref -); - -/** - * The guard of `@conditionalexpr` `guard ? true : false` - */ -expr_cond_guard( - unique int cond: @conditionalexpr ref, - int guard: @expr ref -); - -/** - * The expression used when the guard of `@conditionalexpr` - * `guard ? true : false` holds. For the two operand form - * `guard ?: false` consider using `expr_cond_guard` instead. - */ -expr_cond_true( - unique int cond: @conditionalexpr ref, - int true: @expr ref -); - -/** - * The expression used when the guard of `@conditionalexpr` - * `guard ? true : false` does not hold. - */ -expr_cond_false( - unique int cond: @conditionalexpr ref, - int false: @expr ref -); - -/** A string representation of the value. */ -values( - unique int id: @value, - string str: string ref -); - -/** The actual text in the source code for the value, if any. */ -valuetext( - unique int id: @value ref, - string text: string ref -); - -valuebind( - int val: @value ref, - unique int expr: @expr ref -); - -fieldoffsets( - unique int id: @variable ref, - int byteoffset: int ref, - int bitoffset: int ref -); - -bitfield( - unique int id: @variable ref, - int bits: int ref, - int declared_bits: int ref -); - -/* TODO -memberprefix( - int member: @expr ref, - int prefix: @expr ref -); -*/ - -/* - kind(1) = mbrcallexpr - kind(2) = mbrptrcallexpr - kind(3) = mbrptrmbrcallexpr - kind(4) = ptrmbrptrmbrcallexpr - kind(5) = mbrreadexpr // x.y - kind(6) = mbrptrreadexpr // p->y - kind(7) = mbrptrmbrreadexpr // x.*pm - kind(8) = mbrptrmbrptrreadexpr // x->*pm - kind(9) = staticmbrreadexpr // static x.y - kind(10) = staticmbrptrreadexpr // static p->y -*/ -/* TODO -memberaccess( - int member: @expr ref, - int kind: int ref -); -*/ - -initialisers( - unique int init: @initialiser, - int var: @accessible ref, - unique int expr: @expr ref, - int location: @location_expr ref -); - -braced_initialisers( - int init: @initialiser ref -); - -/** - * An ancestor for the expression, for cases in which we cannot - * otherwise find the expression's parent. - */ -expr_ancestor( - int exp: @expr ref, - int ancestor: @element ref -); - -exprs( - unique int id: @expr, - int kind: int ref, - int location: @location_expr ref -); - -expr_reuse( - int reuse: @expr ref, - int original: @expr ref, - int value_category: int ref -) - -/* - case @value.category of - 1 = prval - | 2 = xval - | 3 = lval - ; -*/ -expr_types( - int id: @expr ref, - int typeid: @type ref, - int value_category: int ref -); - -case @expr.kind of - 1 = @errorexpr -| 2 = @address_of // & AddressOfExpr -| 3 = @reference_to // ReferenceToExpr (implicit?) -| 4 = @indirect // * PointerDereferenceExpr -| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) -// ... -| 8 = @array_to_pointer // (???) -| 9 = @vacuous_destructor_call // VacuousDestructorCall -// ... -| 11 = @assume // Microsoft -| 12 = @parexpr -| 13 = @arithnegexpr -| 14 = @unaryplusexpr -| 15 = @complementexpr -| 16 = @notexpr -| 17 = @conjugation // GNU ~ operator -| 18 = @realpartexpr // GNU __real -| 19 = @imagpartexpr // GNU __imag -| 20 = @postincrexpr -| 21 = @postdecrexpr -| 22 = @preincrexpr -| 23 = @predecrexpr -| 24 = @conditionalexpr -| 25 = @addexpr -| 26 = @subexpr -| 27 = @mulexpr -| 28 = @divexpr -| 29 = @remexpr -| 30 = @jmulexpr // C99 mul imaginary -| 31 = @jdivexpr // C99 div imaginary -| 32 = @fjaddexpr // C99 add real + imaginary -| 33 = @jfaddexpr // C99 add imaginary + real -| 34 = @fjsubexpr // C99 sub real - imaginary -| 35 = @jfsubexpr // C99 sub imaginary - real -| 36 = @paddexpr // pointer add (pointer + int or int + pointer) -| 37 = @psubexpr // pointer sub (pointer - integer) -| 38 = @pdiffexpr // difference between two pointers -| 39 = @lshiftexpr -| 40 = @rshiftexpr -| 41 = @andexpr -| 42 = @orexpr -| 43 = @xorexpr -| 44 = @eqexpr -| 45 = @neexpr -| 46 = @gtexpr -| 47 = @ltexpr -| 48 = @geexpr -| 49 = @leexpr -| 50 = @minexpr // GNU minimum -| 51 = @maxexpr // GNU maximum -| 52 = @assignexpr -| 53 = @assignaddexpr -| 54 = @assignsubexpr -| 55 = @assignmulexpr -| 56 = @assigndivexpr -| 57 = @assignremexpr -| 58 = @assignlshiftexpr -| 59 = @assignrshiftexpr -| 60 = @assignandexpr -| 61 = @assignorexpr -| 62 = @assignxorexpr -| 63 = @assignpaddexpr // assign pointer add -| 64 = @assignpsubexpr // assign pointer sub -| 65 = @andlogicalexpr -| 66 = @orlogicalexpr -| 67 = @commaexpr -| 68 = @subscriptexpr // access to member of an array, e.g., a[5] -// ... 69 @objc_subscriptexpr deprecated -// ... 70 @cmdaccess deprecated -// ... -| 73 = @virtfunptrexpr -| 74 = @callexpr -// ... 75 @msgexpr_normal deprecated -// ... 76 @msgexpr_super deprecated -// ... 77 @atselectorexpr deprecated -// ... 78 @atprotocolexpr deprecated -| 79 = @vastartexpr -| 80 = @vaargexpr -| 81 = @vaendexpr -| 82 = @vacopyexpr -// ... 83 @atencodeexpr deprecated -| 84 = @varaccess -| 85 = @thisaccess -// ... 86 @objc_box_expr deprecated -| 87 = @new_expr -| 88 = @delete_expr -| 89 = @throw_expr -| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) -| 91 = @braced_init_list -| 92 = @type_id -| 93 = @runtime_sizeof -| 94 = @runtime_alignof -| 95 = @sizeof_pack -| 96 = @expr_stmt // GNU extension -| 97 = @routineexpr -| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) -| 99 = @offsetofexpr // offsetof ::= type and field -| 100 = @hasassignexpr // __has_assign ::= type -| 101 = @hascopyexpr // __has_copy ::= type -| 102 = @hasnothrowassign // __has_nothrow_assign ::= type -| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type -| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type -| 105 = @hastrivialassign // __has_trivial_assign ::= type -| 106 = @hastrivialconstr // __has_trivial_constructor ::= type -| 107 = @hastrivialcopy // __has_trivial_copy ::= type -| 108 = @hasuserdestr // __has_user_destructor ::= type -| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type -| 110 = @isabstractexpr // __is_abstract ::= type -| 111 = @isbaseofexpr // __is_base_of ::= type type -| 112 = @isclassexpr // __is_class ::= type -| 113 = @isconvtoexpr // __is_convertible_to ::= type type -| 114 = @isemptyexpr // __is_empty ::= type -| 115 = @isenumexpr // __is_enum ::= type -| 116 = @ispodexpr // __is_pod ::= type -| 117 = @ispolyexpr // __is_polymorphic ::= type -| 118 = @isunionexpr // __is_union ::= type -| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type -| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof -// ... -| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type -| 123 = @literal -| 124 = @uuidof -| 127 = @aggregateliteral -| 128 = @delete_array_expr -| 129 = @new_array_expr -// ... 130 @objc_array_literal deprecated -// ... 131 @objc_dictionary_literal deprecated -| 132 = @foldexpr -// ... -| 200 = @ctordirectinit -| 201 = @ctorvirtualinit -| 202 = @ctorfieldinit -| 203 = @ctordelegatinginit -| 204 = @dtordirectdestruct -| 205 = @dtorvirtualdestruct -| 206 = @dtorfielddestruct -// ... -| 210 = @static_cast -| 211 = @reinterpret_cast -| 212 = @const_cast -| 213 = @dynamic_cast -| 214 = @c_style_cast -| 215 = @lambdaexpr -| 216 = @param_ref -| 217 = @noopexpr -// ... -| 294 = @istriviallyconstructibleexpr -| 295 = @isdestructibleexpr -| 296 = @isnothrowdestructibleexpr -| 297 = @istriviallydestructibleexpr -| 298 = @istriviallyassignableexpr -| 299 = @isnothrowassignableexpr -| 300 = @istrivialexpr -| 301 = @isstandardlayoutexpr -| 302 = @istriviallycopyableexpr -| 303 = @isliteraltypeexpr -| 304 = @hastrivialmoveconstructorexpr -| 305 = @hastrivialmoveassignexpr -| 306 = @hasnothrowmoveassignexpr -| 307 = @isconstructibleexpr -| 308 = @isnothrowconstructibleexpr -| 309 = @hasfinalizerexpr -| 310 = @isdelegateexpr -| 311 = @isinterfaceclassexpr -| 312 = @isrefarrayexpr -| 313 = @isrefclassexpr -| 314 = @issealedexpr -| 315 = @issimplevalueclassexpr -| 316 = @isvalueclassexpr -| 317 = @isfinalexpr -| 319 = @noexceptexpr -| 320 = @builtinshufflevector -| 321 = @builtinchooseexpr -| 322 = @builtinaddressof -| 323 = @vec_fill -| 324 = @builtinconvertvector -| 325 = @builtincomplex -| 326 = @spaceshipexpr -| 327 = @co_await -| 328 = @co_yield -| 329 = @temp_init -| 330 = @isassignable -| 331 = @isaggregate -| 332 = @hasuniqueobjectrepresentations -| 333 = @builtinbitcast -| 334 = @builtinshuffle -| 335 = @blockassignexpr -| 336 = @issame -| 337 = @isfunction -| 338 = @islayoutcompatible -| 339 = @ispointerinterconvertiblebaseof -| 340 = @isarray -| 341 = @arrayrank -| 342 = @arrayextent -| 343 = @isarithmetic -| 344 = @iscompletetype -| 345 = @iscompound -| 346 = @isconst -| 347 = @isfloatingpoint -| 348 = @isfundamental -| 349 = @isintegral -| 350 = @islvaluereference -| 351 = @ismemberfunctionpointer -| 352 = @ismemberobjectpointer -| 353 = @ismemberpointer -| 354 = @isobject -| 355 = @ispointer -| 356 = @isreference -| 357 = @isrvaluereference -| 358 = @isscalar -| 359 = @issigned -| 360 = @isunsigned -| 361 = @isvoid -| 362 = @isvolatile -| 363 = @reuseexpr -| 364 = @istriviallycopyassignable -| 365 = @isassignablenopreconditioncheck -| 366 = @referencebindstotemporary -| 367 = @issameas -| 368 = @builtinhasattribute -| 369 = @ispointerinterconvertiblewithclass -| 370 = @builtinispointerinterconvertiblewithclass -| 371 = @iscorrespondingmember -| 372 = @builtiniscorrespondingmember -| 373 = @isboundedarray -| 374 = @isunboundedarray -| 375 = @isreferenceable -| 378 = @isnothrowconvertible -| 379 = @referenceconstructsfromtemporary -| 380 = @referenceconvertsfromtemporary -| 381 = @isconvertible -| 382 = @isvalidwinrttype -| 383 = @iswinclass -| 384 = @iswininterface -| 385 = @istriviallyequalitycomparable -| 386 = @isscopedenum -| 387 = @istriviallyrelocatable -| 388 = @datasizeof -| 389 = @c11_generic -| 390 = @requires_expr -| 391 = @nested_requirement -| 392 = @compound_requirement -| 393 = @concept_id -; - -@var_args_expr = @vastartexpr - | @vaendexpr - | @vaargexpr - | @vacopyexpr - ; - -@builtin_op = @var_args_expr - | @noopexpr - | @offsetofexpr - | @intaddrexpr - | @hasassignexpr - | @hascopyexpr - | @hasnothrowassign - | @hasnothrowconstr - | @hasnothrowcopy - | @hastrivialassign - | @hastrivialconstr - | @hastrivialcopy - | @hastrivialdestructor - | @hasuserdestr - | @hasvirtualdestr - | @isabstractexpr - | @isbaseofexpr - | @isclassexpr - | @isconvtoexpr - | @isemptyexpr - | @isenumexpr - | @ispodexpr - | @ispolyexpr - | @isunionexpr - | @typescompexpr - | @builtinshufflevector - | @builtinconvertvector - | @builtinaddressof - | @istriviallyconstructibleexpr - | @isdestructibleexpr - | @isnothrowdestructibleexpr - | @istriviallydestructibleexpr - | @istriviallyassignableexpr - | @isnothrowassignableexpr - | @istrivialexpr - | @isstandardlayoutexpr - | @istriviallycopyableexpr - | @isliteraltypeexpr - | @hastrivialmoveconstructorexpr - | @hastrivialmoveassignexpr - | @hasnothrowmoveassignexpr - | @isconstructibleexpr - | @isnothrowconstructibleexpr - | @hasfinalizerexpr - | @isdelegateexpr - | @isinterfaceclassexpr - | @isrefarrayexpr - | @isrefclassexpr - | @issealedexpr - | @issimplevalueclassexpr - | @isvalueclassexpr - | @isfinalexpr - | @builtinchooseexpr - | @builtincomplex - | @isassignable - | @isaggregate - | @hasuniqueobjectrepresentations - | @builtinbitcast - | @builtinshuffle - | @issame - | @isfunction - | @islayoutcompatible - | @ispointerinterconvertiblebaseof - | @isarray - | @arrayrank - | @arrayextent - | @isarithmetic - | @iscompletetype - | @iscompound - | @isconst - | @isfloatingpoint - | @isfundamental - | @isintegral - | @islvaluereference - | @ismemberfunctionpointer - | @ismemberobjectpointer - | @ismemberpointer - | @isobject - | @ispointer - | @isreference - | @isrvaluereference - | @isscalar - | @issigned - | @isunsigned - | @isvoid - | @isvolatile - | @istriviallycopyassignable - | @isassignablenopreconditioncheck - | @referencebindstotemporary - | @issameas - | @builtinhasattribute - | @ispointerinterconvertiblewithclass - | @builtinispointerinterconvertiblewithclass - | @iscorrespondingmember - | @builtiniscorrespondingmember - | @isboundedarray - | @isunboundedarray - | @isreferenceable - | @isnothrowconvertible - | @referenceconstructsfromtemporary - | @referenceconvertsfromtemporary - | @isconvertible - | @isvalidwinrttype - | @iswinclass - | @iswininterface - | @istriviallyequalitycomparable - | @isscopedenum - | @istriviallyrelocatable - ; - -compound_requirement_is_noexcept( - int expr: @compound_requirement ref -); - -new_allocated_type( - unique int expr: @new_expr ref, - int type_id: @type ref -); - -new_array_allocated_type( - unique int expr: @new_array_expr ref, - int type_id: @type ref -); - -/** - * The field being initialized by an initializer expression within an aggregate - * initializer for a class/struct/union. Position is used to sort repeated initializers. - */ -#keyset[aggregate, position] -aggregate_field_init( - int aggregate: @aggregateliteral ref, - int initializer: @expr ref, - int field: @membervariable ref, - int position: int ref -); - -/** - * The index of the element being initialized by an initializer expression - * within an aggregate initializer for an array. Position is used to sort repeated initializers. - */ -#keyset[aggregate, position] -aggregate_array_init( - int aggregate: @aggregateliteral ref, - int initializer: @expr ref, - int element_index: int ref, - int position: int ref -); - -@ctorinit = @ctordirectinit - | @ctorvirtualinit - | @ctorfieldinit - | @ctordelegatinginit; -@dtordestruct = @dtordirectdestruct - | @dtorvirtualdestruct - | @dtorfielddestruct; - - -condition_decl_bind( - unique int expr: @condition_decl ref, - unique int decl: @declaration ref -); - -typeid_bind( - unique int expr: @type_id ref, - int type_id: @type ref -); - -uuidof_bind( - unique int expr: @uuidof ref, - int type_id: @type ref -); - -@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; - -sizeof_bind( - unique int expr: @runtime_sizeof_or_alignof ref, - int type_id: @type ref -); - -code_block( - unique int block: @literal ref, - unique int routine: @function ref -); - -lambdas( - unique int expr: @lambdaexpr ref, - string default_capture: string ref, - boolean has_explicit_return_type: boolean ref -); - -lambda_capture( - unique int id: @lambdacapture, - int lambda: @lambdaexpr ref, - int index: int ref, - int field: @membervariable ref, - boolean captured_by_reference: boolean ref, - boolean is_implicit: boolean ref, - int location: @location_default ref -); - -@funbindexpr = @routineexpr - | @new_expr - | @delete_expr - | @delete_array_expr - | @ctordirectinit - | @ctorvirtualinit - | @ctordelegatinginit - | @dtordirectdestruct - | @dtorvirtualdestruct; - -@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; -@addressable = @function | @variable ; -@accessible = @addressable | @enumconstant ; - -@access = @varaccess | @routineexpr ; - -fold( - int expr: @foldexpr ref, - string operator: string ref, - boolean is_left_fold: boolean ref -); - -stmts( - unique int id: @stmt, - int kind: int ref, - int location: @location_stmt ref -); - -case @stmt.kind of - 1 = @stmt_expr -| 2 = @stmt_if -| 3 = @stmt_while -| 4 = @stmt_goto -| 5 = @stmt_label -| 6 = @stmt_return -| 7 = @stmt_block -| 8 = @stmt_end_test_while // do { ... } while ( ... ) -| 9 = @stmt_for -| 10 = @stmt_switch_case -| 11 = @stmt_switch -| 13 = @stmt_asm // "asm" statement or the body of an asm function -| 15 = @stmt_try_block -| 16 = @stmt_microsoft_try // Microsoft -| 17 = @stmt_decl -| 18 = @stmt_set_vla_size // C99 -| 19 = @stmt_vla_decl // C99 -| 25 = @stmt_assigned_goto // GNU -| 26 = @stmt_empty -| 27 = @stmt_continue -| 28 = @stmt_break -| 29 = @stmt_range_based_for // C++11 -// ... 30 @stmt_at_autoreleasepool_block deprecated -// ... 31 @stmt_objc_for_in deprecated -// ... 32 @stmt_at_synchronized deprecated -| 33 = @stmt_handler -// ... 34 @stmt_finally_end deprecated -| 35 = @stmt_constexpr_if -| 37 = @stmt_co_return -; - -type_vla( - int type_id: @type ref, - int decl: @stmt_vla_decl ref -); - -variable_vla( - int var: @variable ref, - int decl: @stmt_vla_decl ref -); - -if_initialization( - unique int if_stmt: @stmt_if ref, - int init_id: @stmt ref -); - -if_then( - unique int if_stmt: @stmt_if ref, - int then_id: @stmt ref -); - -if_else( - unique int if_stmt: @stmt_if ref, - int else_id: @stmt ref -); - -constexpr_if_initialization( - unique int constexpr_if_stmt: @stmt_constexpr_if ref, - int init_id: @stmt ref -); - -constexpr_if_then( - unique int constexpr_if_stmt: @stmt_constexpr_if ref, - int then_id: @stmt ref -); - -constexpr_if_else( - unique int constexpr_if_stmt: @stmt_constexpr_if ref, - int else_id: @stmt ref -); - -while_body( - unique int while_stmt: @stmt_while ref, - int body_id: @stmt ref -); - -do_body( - unique int do_stmt: @stmt_end_test_while ref, - int body_id: @stmt ref -); - -switch_initialization( - unique int switch_stmt: @stmt_switch ref, - int init_id: @stmt ref -); - -#keyset[switch_stmt, index] -switch_case( - int switch_stmt: @stmt_switch ref, - int index: int ref, - int case_id: @stmt_switch_case ref -); - -switch_body( - unique int switch_stmt: @stmt_switch ref, - int body_id: @stmt ref -); - -@stmt_for_or_range_based_for = @stmt_for - | @stmt_range_based_for; - -for_initialization( - unique int for_stmt: @stmt_for_or_range_based_for ref, - int init_id: @stmt ref -); - -for_condition( - unique int for_stmt: @stmt_for ref, - int condition_id: @expr ref -); - -for_update( - unique int for_stmt: @stmt_for ref, - int update_id: @expr ref -); - -for_body( - unique int for_stmt: @stmt_for ref, - int body_id: @stmt ref -); - -@stmtparent = @stmt | @expr_stmt ; -stmtparents( - unique int id: @stmt ref, - int index: int ref, - int parent: @stmtparent ref -); - -ishandler(unique int block: @stmt_block ref); - -@cfgnode = @stmt | @expr | @function | @initialiser ; - -stmt_decl_bind( - int stmt: @stmt_decl ref, - int num: int ref, - int decl: @declaration ref -); - -stmt_decl_entry_bind( - int stmt: @stmt_decl ref, - int num: int ref, - int decl_entry: @element ref -); - -@parameterized_element = @function | @stmt_block | @requires_expr; - -blockscope( - unique int block: @stmt_block ref, - int enclosing: @parameterized_element ref -); - -@jump = @stmt_goto | @stmt_break | @stmt_continue; - -@jumporlabel = @jump | @stmt_label | @literal; - -jumpinfo( - unique int id: @jumporlabel ref, - string str: string ref, - int target: @stmt ref -); - -preprocdirects( - unique int id: @preprocdirect, - int kind: int ref, - int location: @location_default ref -); -case @preprocdirect.kind of - 0 = @ppd_if -| 1 = @ppd_ifdef -| 2 = @ppd_ifndef -| 3 = @ppd_elif -| 4 = @ppd_else -| 5 = @ppd_endif -| 6 = @ppd_plain_include -| 7 = @ppd_define -| 8 = @ppd_undef -| 9 = @ppd_line -| 10 = @ppd_error -| 11 = @ppd_pragma -| 12 = @ppd_objc_import -| 13 = @ppd_include_next -| 18 = @ppd_warning -; - -@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; - -@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; - -preprocpair( - int begin : @ppd_branch ref, - int elseelifend : @preprocdirect ref -); - -preproctrue(int branch : @ppd_branch ref); -preprocfalse(int branch : @ppd_branch ref); - -preproctext( - unique int id: @preprocdirect ref, - string head: string ref, - string body: string ref -); - -includes( - unique int id: @ppd_include ref, - int included: @file ref -); - -link_targets( - int id: @link_target, - int binary: @file ref -); - -link_parent( - int element : @element ref, - int link_target : @link_target ref -); - -/* XML Files */ - -xmlEncoding(unique int id: @file ref, string encoding: string ref); - -xmlDTDs( - unique int id: @xmldtd, - string root: string ref, - string publicId: string ref, - string systemId: string ref, - int fileid: @file ref -); - -xmlElements( - unique int id: @xmlelement, - string name: string ref, - int parentid: @xmlparent ref, - int idx: int ref, - int fileid: @file ref -); - -xmlAttrs( - unique int id: @xmlattribute, - int elementid: @xmlelement ref, - string name: string ref, - string value: string ref, - int idx: int ref, - int fileid: @file ref -); - -xmlNs( - int id: @xmlnamespace, - string prefixName: string ref, - string URI: string ref, - int fileid: @file ref -); - -xmlHasNs( - int elementId: @xmlnamespaceable ref, - int nsId: @xmlnamespace ref, - int fileid: @file ref -); - -xmlComments( - unique int id: @xmlcomment, - string text: string ref, - int parentid: @xmlparent ref, - int fileid: @file ref -); - -xmlChars( - unique int id: @xmlcharacters, - string text: string ref, - int parentid: @xmlparent ref, - int idx: int ref, - int isCDATA: int ref, - int fileid: @file ref -); - -@xmlparent = @file | @xmlelement; -@xmlnamespaceable = @xmlelement | @xmlattribute; - -xmllocations( - int xmlElement: @xmllocatable ref, - int location: @location_default ref -); - -@xmllocatable = @xmlcharacters - | @xmlelement - | @xmlcomment - | @xmlattribute - | @xmldtd - | @file - | @xmlnamespace; diff --git a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties deleted file mode 100644 index cf362f384da..00000000000 --- a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties +++ /dev/null @@ -1,3 +0,0 @@ -description: Implement compilation_build_mode/2 -compatibility: full -compilation_build_mode.rel: delete diff --git a/cpp/ql/lib/semmle/code/cpp/Compilation.qll b/cpp/ql/lib/semmle/code/cpp/Compilation.qll index 407dc31e05f..1a8d90f991c 100644 --- a/cpp/ql/lib/semmle/code/cpp/Compilation.qll +++ b/cpp/ql/lib/semmle/code/cpp/Compilation.qll @@ -112,7 +112,4 @@ class Compilation extends @compilation { * termination, but crashing due to something like a segfault is not. */ predicate normalTermination() { compilation_finished(this, _, _) } - - /** Holds if this compilation was compiled using the "none" build mode. */ - predicate buildModeNone() { compilation_build_mode(this, 0) } } diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index f0156f5f88a..e51fad7a243 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -46,22 +46,6 @@ compilation_args( string arg : string ref ); -/** - * Optionally, record the build mode for each compilation. - */ -compilation_build_mode( - unique int id : @compilation ref, - int mode : int ref -); - -/* -case @compilation_build_mode.mode of - 0 = @build_mode_none -| 1 = @build_mode_manual -| 2 = @build_mode_auto -; -*/ - /** * The source files that are compiled by a compiler invocation. * If `id` is for the compiler invocation diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats index 758aba34608..7f0d99272e7 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats @@ -18,7 +18,7 @@ @location_default - 29746763 + 29764890 @location_stmt @@ -34,11 +34,11 @@ @file - 123176 + 123251 @folder - 16330 + 16340 @macro_expansion @@ -46,23 +46,23 @@ @other_macro_reference - 858505 + 859029 @function - 4176817 + 4179363 @fun_decl - 4541216 + 4543516 @var_decl - 8034962 + 8039391 @type_decl - 3281452 + 3283451 @namespace_decl @@ -70,11 +70,11 @@ @using_declaration - 362998 + 363219 @using_directive - 6532 + 6536 @using_enum_declaration @@ -86,7 +86,7 @@ @parameter - 6186841 + 6190611 @membervariable @@ -98,7 +98,7 @@ @localvariable - 576952 + 576945 @enumconstant @@ -330,15 +330,15 @@ @pointer - 567827 + 568173 @type_with_specifiers - 851507 + 852026 @array - 110112 + 110179 @routineptr @@ -346,7 +346,7 @@ @reference - 1275627 + 1276405 @gnu_vector @@ -358,7 +358,7 @@ @rvalue_reference - 333137 + 333340 @block @@ -366,15 +366,15 @@ @decltype - 27061 + 27078 @usertype - 5230820 + 5234008 @mangledname - 6058065 + 6061757 @type_mention @@ -386,15 +386,15 @@ @ptrtomember - 37792 + 37815 @specifier - 24728 + 24743 @gnuattribute - 553363 + 553700 @stdattribute @@ -410,15 +410,15 @@ @alignas - 4665 + 4668 @attribute_arg_token - 25195 + 25210 @attribute_arg_constant_expr - 318207 + 318400 @attribute_arg_empty @@ -450,7 +450,7 @@ @namespace - 12131 + 12138 @specialnamequalifyingelement @@ -482,7 +482,7 @@ @parexpr - 3587464 + 3587463 @arithnegexpr @@ -582,11 +582,11 @@ @gtexpr - 104047 + 104110 @ltexpr - 101714 + 101776 @geexpr @@ -634,7 +634,7 @@ @assignorexpr - 23628 + 23627 @assignxorexpr @@ -662,11 +662,11 @@ @subscriptexpr - 364481 + 364477 @callexpr - 316340 + 316533 @vastartexpr @@ -678,7 +678,7 @@ @vaendexpr - 2799 + 2801 @vacopyexpr @@ -830,7 +830,7 @@ @sizeof_pack - 5598 + 5602 @hasassignexpr @@ -978,7 +978,7 @@ @lambdaexpr - 21462 + 21475 @param_ref @@ -1022,7 +1022,7 @@ @istriviallycopyableexpr - 3732 + 3734 @isliteraltypeexpr @@ -1374,7 +1374,7 @@ @lambdacapture - 27994 + 28011 @stmt_expr @@ -1398,11 +1398,11 @@ @stmt_return - 1279827 + 1280140 @stmt_block - 1418867 + 1419265 @stmt_end_test_while @@ -1430,7 +1430,7 @@ @stmt_empty - 192685 + 192682 @stmt_continue @@ -1462,7 +1462,7 @@ @stmt_range_based_for - 8398 + 8403 @stmt_handler @@ -1478,31 +1478,31 @@ @ppd_if - 666741 + 667148 @ppd_ifdef - 263150 + 263311 @ppd_ifndef - 266416 + 266579 @ppd_elif - 25195 + 25210 @ppd_else - 209027 + 209154 @ppd_endif - 1196309 + 1197038 @ppd_plain_include - 311208 + 311398 @ppd_define @@ -1510,15 +1510,15 @@ @ppd_undef - 258484 + 258642 @ppd_include_next - 1866 + 1867 @ppd_line - 27521 + 27520 @ppd_error @@ -1900,54 +1900,6 @@
    - - compilation_build_mode - 9742 - - - id - 9742 - - - mode - 11 - - - - - id - mode - - - 12 - - - 1 - 2 - 9742 - - - - - - - mode - id - - - 12 - - - 863 - 864 - 11 - - - - - - - compilation_compiling_files 11546 @@ -2212,7 +2164,7 @@ seconds - 8030 + 8429 @@ -2293,52 +2245,47 @@ 3 4 - 799 + 639 4 5 - 199 + 359 - 5 + 6 7 119 8 - 9 - 79 - - - 9 10 - 119 + 159 10 - 12 - 159 - - - 12 - 16 + 11 119 - 17 - 20 + 11 + 15 159 - 21 - 42 + 16 + 19 159 - 55 - 90 - 79 + 19 + 24 + 159 + + + 40 + 89 + 119 @@ -2421,7 +2368,7 @@ 6 7 - 399 + 439 7 @@ -2430,19 +2377,19 @@ 8 - 9 - 239 - - - 9 - 24 + 10 279 - 25 - 85 + 10 + 26 279 + + 28 + 81 + 199 + @@ -2492,8 +2439,8 @@ 79
    - 124 - 125 + 125 + 126 39 @@ -2515,37 +2462,27 @@ 1 2 - 3755 + 3635 2 3 - 1398 + 1917 3 4 - 998 + 1558 4 - 5 - 759 - - - 5 6 - 439 + 719 6 - 25 - 639 - - - 46 - 47 - 39 + 48 + 599 @@ -2561,27 +2498,27 @@ 1 2 - 3515 + 3595 2 3 - 1278 + 1438 3 4 - 599 + 1358 4 5 - 878 + 639 5 6 - 759 + 479 6 @@ -2590,8 +2527,8 @@ 8 - 76 - 319 + 73 + 239 @@ -2607,12 +2544,12 @@ 1 2 - 5753 + 6512 2 3 - 2277 + 1917 @@ -2956,7 +2893,7 @@ cpu_seconds - 7292 + 7507 elapsed_seconds @@ -3006,17 +2943,17 @@ 1 2 - 5937 + 6242 2 3 - 846 + 835 3 - 16 - 507 + 15 + 428 @@ -3032,12 +2969,12 @@ 1 2 - 6682 + 6976 2 3 - 609 + 530 @@ -3066,48 +3003,48 @@ 11 - 7 - 8 + 6 + 7 11 - 8 - 9 + 9 + 10 11 - 12 - 13 + 11 + 12 11 - 13 - 14 + 16 + 17 11 - 51 - 52 + 49 + 50 11 - 163 - 164 + 154 + 155 11 - 167 - 168 + 160 + 161 11 - 187 - 188 + 204 + 205 11 - 249 - 250 + 248 + 249 11 @@ -3137,48 +3074,48 @@ 11
    - 7 - 8 + 6 + 7 11 - 8 - 9 + 9 + 10 11 - 12 - 13 + 11 + 12 11 - 13 - 14 + 16 + 17 11 - 49 - 50 + 47 + 48 11 - 120 - 121 + 118 + 119 11 - 123 - 124 + 128 + 129 11 - 138 - 139 + 149 + 150 11 - 224 - 225 + 222 + 223 11 @@ -4951,31 +4888,31 @@ locations_default - 29746763 + 29764890 id - 29746763 + 29764890 container - 123176 + 123251 startLine - 2094007 + 2095283 startColumn - 36859 + 36882 endLine - 2098207 + 2099485 endColumn - 48057 + 48086 @@ -4989,7 +4926,7 @@ 1 2 - 29746763 + 29764890 @@ -5005,7 +4942,7 @@ 1 2 - 29746763 + 29764890 @@ -5021,7 +4958,7 @@ 1 2 - 29746763 + 29764890 @@ -5037,7 +4974,7 @@ 1 2 - 29746763 + 29764890 @@ -5053,7 +4990,7 @@ 1 2 - 29746763 + 29764890 @@ -5069,67 +5006,67 @@ 1 11 - 9798 + 9804 11 18 - 10264 + 10270 18 30 - 9331 + 9337 30 42 - 9798 + 9804 43 61 - 9798 + 9804 61 79 - 9331 + 9337 80 106 - 9798 + 9804 108 149 - 9331 + 9337 149 199 - 9331 + 9337 206 291 - 9331 + 9337 304 469 - 9331 + 9337 482 850 - 9331 + 9337 936 2380 - 8398 + 8403 @@ -5145,67 +5082,67 @@ 1 8 - 9331 + 9337 8 13 - 9331 + 9337 13 20 - 9798 + 9804 20 32 - 9331 + 9337 32 43 - 9798 + 9804 44 61 - 9331 + 9337 62 72 - 9331 + 9337 73 93 - 9331 + 9337 97 128 - 9331 + 9337 128 180 - 9331 + 9337 180 267 - 9331 + 9337 277 414 - 9331 + 9337 439 1465 - 9331 + 9337 1557 @@ -5226,67 +5163,67 @@ 1 4 - 8865 + 8870 4 5 - 7931 + 7936 5 6 - 7465 + 7469 6 8 - 11197 + 11204 8 10 - 9331 + 9337 10 15 - 10731 + 10737 15 23 - 9798 + 9804 23 28 - 11197 + 11204 28 34 - 9798 + 9804 34 44 - 9331 + 9337 44 55 - 9331 + 9337 55 66 - 9798 + 9804 66 77 - 8398 + 8403 @@ -5302,67 +5239,67 @@ 1 8 - 9331 + 9337 8 13 - 9331 + 9337 13 20 - 9798 + 9804 20 32 - 9331 + 9337 32 43 - 9798 + 9804 43 60 - 9331 + 9337 61 71 - 9331 + 9337 72 93 - 9331 + 9337 94 127 - 9331 + 9337 128 179 - 9331 + 9337 180 268 - 9331 + 9337 278 413 - 9331 + 9337 437 1465 - 9331 + 9337 1554 @@ -5383,67 +5320,67 @@ 1 9 - 9798 + 9804 9 13 - 9331 + 9337 13 18 - 9331 + 9337 18 26 - 10264 + 10270 27 33 - 9331 + 9337 33 39 - 9331 + 9337 39 47 - 10264 + 10270 47 53 - 9331 + 9337 53 60 - 10264 + 10270 60 66 - 9331 + 9337 66 74 - 9798 + 9804 74 78 - 9798 + 9804 78 90 - 6998 + 7002 @@ -5459,52 +5396,52 @@ 1 2 - 582757 + 583112 2 3 - 314007 + 314199 3 4 - 195496 + 195615 4 6 - 161903 + 162001 6 10 - 182899 + 183010 10 16 - 162836 + 162935 16 25 - 168901 + 169004 25 46 - 160969 + 161067 46 169 - 157237 + 157333 169 265 - 6998 + 7002 @@ -5520,42 +5457,42 @@ 1 2 - 870636 + 871167 2 3 - 273415 + 273582 3 5 - 193630 + 193748 5 8 - 173567 + 173673 8 13 - 188031 + 188146 13 20 - 160969 + 161067 20 51 - 159570 + 159667 51 265 - 74186 + 74231 @@ -5571,47 +5508,47 @@ 1 2 - 611685 + 612058 2 3 - 313074 + 313265 3 4 - 198296 + 198417 4 6 - 182899 + 183010 6 9 - 173100 + 173206 9 13 - 163302 + 163402 13 19 - 174500 + 174606 19 29 - 164702 + 164802 29 52 - 112445 + 112514 @@ -5627,22 +5564,22 @@ 1 2 - 1530846 + 1531779 2 3 - 348534 + 348747 3 5 - 161903 + 162001 5 16 - 52723 + 52755 @@ -5658,47 +5595,47 @@ 1 2 - 587423 + 587781 2 3 - 315874 + 316066 3 4 - 197363 + 197483 4 6 - 168435 + 168537 6 9 - 158170 + 158266 9 14 - 170768 + 170872 14 21 - 174967 + 175073 21 32 - 162369 + 162468 32 63 - 157703 + 157799 64 @@ -5719,67 +5656,67 @@ 1 31 - 2799 + 2801 42 85 - 2799 + 2801 86 128 - 2799 + 2801 129 229 - 2799 + 2801 247 286 - 2799 + 2801 291 360 - 2799 + 2801 373 457 - 2799 + 2801 473 565 - 2799 + 2801 566 619 - 2799 + 2801 619 689 - 2799 + 2801 696 807 - 2799 + 2801 819 1563 - 2799 + 2801 1634 5631 - 2799 + 2801 15295 @@ -5800,67 +5737,67 @@ 1 18 - 2799 + 2801 23 35 - 3266 + 3268 38 43 - 2799 + 2801 44 61 - 2799 + 2801 65 73 - 2799 + 2801 73 84 - 3266 + 3268 84 96 - 2799 + 2801 96 101 - 3266 + 3268 101 105 - 3266 + 3268 107 112 - 2799 + 2801 112 126 - 2799 + 2801 137 170 - 2799 + 2801 195 265 - 1399 + 1400 @@ -5876,67 +5813,67 @@ 1 19 - 2799 + 2801 30 72 - 2799 + 2801 83 122 - 2799 + 2801 122 205 - 2799 + 2801 214 261 - 2799 + 2801 265 322 - 2799 + 2801 322 379 - 2799 + 2801 404 430 - 2799 + 2801 453 474 - 2799 + 2801 478 505 - 2799 + 2801 511 583 - 2799 + 2801 585 836 - 2799 + 2801 1104 2196 - 2799 + 2801 2387 @@ -5957,67 +5894,67 @@ 1 19 - 2799 + 2801 30 72 - 2799 + 2801 83 122 - 2799 + 2801 122 205 - 2799 + 2801 214 261 - 2799 + 2801 265 322 - 2799 + 2801 322 380 - 2799 + 2801 404 430 - 2799 + 2801 453 474 - 2799 + 2801 477 504 - 2799 + 2801 514 582 - 2799 + 2801 585 835 - 2799 + 2801 1109 2203 - 2799 + 2801 2382 @@ -6038,67 +5975,67 @@ 1 7 - 2799 + 2801 7 11 - 3266 + 3268 11 16 - 3266 + 3268 16 22 - 2799 + 2801 22 24 - 3266 + 3268 24 28 - 2799 + 2801 29 34 - 3266 + 3268 34 41 - 3266 + 3268 41 46 - 2799 + 2801 47 49 - 1866 + 1867 49 54 - 2799 + 2801 54 74 - 2799 + 2801 75 86 - 1866 + 1867 @@ -6114,52 +6051,52 @@ 1 2 - 593022 + 593383 2 3 - 306076 + 306262 3 4 - 198296 + 198417 4 6 - 159570 + 159667 6 10 - 182432 + 182543 10 16 - 161903 + 162001 16 25 - 171234 + 171338 25 46 - 158636 + 158733 46 161 - 158170 + 158266 162 265 - 8865 + 8870 @@ -6175,47 +6112,47 @@ 1 2 - 886034 + 886574 2 3 - 259884 + 260043 3 4 - 125043 + 125119 4 6 - 140906 + 140992 6 10 - 184765 + 184877 10 15 - 168435 + 168537 15 26 - 163302 + 163402 26 120 - 158170 + 158266 121 265 - 11664 + 11671 @@ -6231,22 +6168,22 @@ 1 2 - 1528513 + 1529445 2 3 - 341536 + 341744 3 5 - 170768 + 170872 5 10 - 57389 + 57424 @@ -6262,47 +6199,47 @@ 1 2 - 622883 + 623262 2 3 - 303276 + 303461 3 4 - 201562 + 201685 4 6 - 183832 + 183944 6 9 - 169834 + 169938 9 13 - 166568 + 166670 13 19 - 174967 + 175073 19 29 - 160969 + 161067 29 52 - 114311 + 114381 @@ -6318,52 +6255,52 @@ 1 2 - 599554 + 599919 2 3 - 306076 + 306262 3 4 - 196896 + 197016 4 6 - 168901 + 169004 6 9 - 156304 + 156399 9 14 - 168901 + 169004 14 21 - 177766 + 177875 21 32 - 161903 + 162001 32 60 - 158170 + 158266 60 65 - 3732 + 3734 @@ -6379,67 +6316,67 @@ 1 2 - 5132 + 5135 2 8 - 3732 + 3734 9 186 - 3732 + 3734 193 288 - 3732 + 3734 294 495 - 3732 + 3734 503 555 - 3732 + 3734 561 633 - 3732 + 3734 640 758 - 3732 + 3734 758 869 - 3732 + 3734 875 1074 - 3732 + 3734 1074 1281 - 3732 + 3734 1289 1590 - 3732 + 3734 1685 2418 - 1866 + 1867 @@ -6455,62 +6392,62 @@ 1 2 - 5598 + 5602 2 5 - 3732 + 3734 5 65 - 3732 + 3734 70 100 - 3732 + 3734 100 111 - 3732 + 3734 112 122 - 4199 + 4201 122 140 - 3732 + 3734 143 153 - 3732 + 3734 153 161 - 4199 + 4201 161 173 - 4199 + 4201 173 178 - 3732 + 3734 188 265 - 3732 + 3734 @@ -6526,62 +6463,62 @@ 1 2 - 5598 + 5602 2 8 - 3732 + 3734 9 105 - 3732 + 3734 155 241 - 3732 + 3734 253 336 - 3732 + 3734 340 426 - 3732 + 3734 434 488 - 3732 + 3734 489 572 - 3732 + 3734 573 623 - 3732 + 3734 626 696 - 4199 + 4201 701 813 - 3732 + 3734 818 1095 - 3732 + 3734 1172 @@ -6602,67 +6539,67 @@ 1 2 - 6065 + 6069 2 4 - 3732 + 3734 4 8 - 4199 + 4201 8 15 - 3732 + 3734 15 23 - 3732 + 3734 23 29 - 3732 + 3734 29 35 - 4199 + 4201 35 39 - 3266 + 3268 39 42 - 3266 + 3268 42 44 - 3266 + 3268 44 46 - 3732 + 3734 46 49 - 3732 + 3734 49 53 - 1399 + 1400 @@ -6678,67 +6615,67 @@ 1 2 - 5598 + 5602 2 8 - 3732 + 3734 9 156 - 3732 + 3734 159 240 - 3732 + 3734 251 335 - 3732 + 3734 342 430 - 3732 + 3734 432 490 - 3732 + 3734 490 573 - 3732 + 3734 574 622 - 3732 + 3734 626 698 - 3732 + 3734 700 798 - 3732 + 3734 811 987 - 3732 + 3734 1096 1180 - 1399 + 1400 @@ -10662,23 +10599,23 @@ numlines - 1382941 + 1383783 element_id - 1375942 + 1376780 num_lines - 101714 + 101776 num_code - 84917 + 84969 num_comment - 59722 + 59758 @@ -10692,12 +10629,12 @@ 1 2 - 1368943 + 1369777 2 3 - 6998 + 7002 @@ -10713,12 +10650,12 @@ 1 2 - 1369876 + 1370711 2 3 - 6065 + 6069 @@ -10734,7 +10671,7 @@ 1 2 - 1375942 + 1376780 @@ -10750,27 +10687,27 @@ 1 2 - 68120 + 68162 2 3 - 12131 + 12138 3 4 - 7465 + 7469 4 21 - 7931 + 7936 29 921 - 6065 + 6069 @@ -10786,27 +10723,27 @@ 1 2 - 70453 + 70496 2 3 - 12131 + 12138 3 4 - 8398 + 8403 4 6 - 9331 + 9337 6 7 - 1399 + 1400 @@ -10822,22 +10759,22 @@ 1 2 - 69520 + 69562 2 3 - 14930 + 14939 3 4 - 10731 + 10737 4 7 - 6532 + 6536 @@ -10853,27 +10790,27 @@ 1 2 - 52723 + 52755 2 3 - 14463 + 14472 3 5 - 6532 + 6536 5 42 - 6532 + 6536 44 922 - 4665 + 4668 @@ -10889,27 +10826,27 @@ 1 2 - 52723 + 52755 2 3 - 16796 + 16807 3 5 - 6065 + 6069 5 8 - 6532 + 6536 8 12 - 2799 + 2801 @@ -10925,27 +10862,27 @@ 1 2 - 53190 + 53222 2 3 - 15863 + 15873 3 5 - 7465 + 7469 5 7 - 5132 + 5135 7 10 - 3266 + 3268 @@ -10961,32 +10898,32 @@ 1 2 - 34526 + 34547 2 3 - 9331 + 9337 3 4 - 4199 + 4201 4 6 - 4665 + 4668 6 11 - 5132 + 5135 17 2596 - 1866 + 1867 @@ -11002,32 +10939,32 @@ 1 2 - 34526 + 34547 2 3 - 9331 + 9337 3 4 - 4199 + 4201 4 6 - 4665 + 4668 6 8 - 4665 + 4668 10 38 - 2332 + 2334 @@ -11043,32 +10980,32 @@ 1 2 - 34526 + 34547 2 3 - 9331 + 9337 3 4 - 4199 + 4201 4 6 - 4665 + 4668 6 10 - 4665 + 4668 10 37 - 2332 + 2334 @@ -11710,15 +11647,15 @@ files - 123176 + 123251 id - 123176 + 123251 name - 123176 + 123251 @@ -11732,7 +11669,7 @@ 1 2 - 123176 + 123251 @@ -11748,7 +11685,7 @@ 1 2 - 123176 + 123251 @@ -11758,15 +11695,15 @@ folders - 16330 + 16340 id - 16330 + 16340 name - 16330 + 16340 @@ -11780,7 +11717,7 @@ 1 2 - 16330 + 16340 @@ -11796,7 +11733,7 @@ 1 2 - 16330 + 16340 @@ -11806,15 +11743,15 @@ containerparent - 138574 + 138658 parent - 16330 + 16340 child - 138574 + 138658 @@ -11828,32 +11765,32 @@ 1 2 - 7465 + 7469 2 3 - 3266 + 3268 3 4 - 1399 + 1400 4 12 - 1399 + 1400 23 28 - 1399 + 1400 40 67 - 1399 + 1400 @@ -11869,7 +11806,7 @@ 1 2 - 138574 + 138658 @@ -12455,15 +12392,15 @@ inmacroexpansion - 109779103 + 109779080 id - 18027697 + 18027694 inv - 2700159 + 2700160 @@ -12477,12 +12414,12 @@ 1 3 - 1582360 + 1582361 3 5 - 1077794 + 1077793 5 @@ -12492,17 +12429,17 @@ 6 7 - 4819904 + 4819903 7 8 - 6385934 + 6385932 8 9 - 2605243 + 2605242 9 @@ -12523,12 +12460,12 @@ 1 2 - 378422 + 378424 2 3 - 544105 + 544104 3 @@ -12563,7 +12500,7 @@ 11 337 - 224845 + 224847 339 @@ -12583,15 +12520,15 @@ affectedbymacroexpansion - 35689257 + 35689251 id - 5156948 + 5156949 inv - 2784761 + 2784762 @@ -12605,7 +12542,7 @@ 1 2 - 2816078 + 2816079 2 @@ -12651,7 +12588,7 @@ 1 4 - 229115 + 229116 4 @@ -12666,12 +12603,12 @@ 9 12 - 251120 + 251119 12 13 - 333985 + 333984 13 @@ -12691,7 +12628,7 @@ 16 17 - 276609 + 276608 17 @@ -13670,19 +13607,19 @@ functions - 4176817 + 4179363 id - 4176817 + 4179363 name - 1894311 + 1895466 kind - 3266 + 3268 @@ -13696,7 +13633,7 @@ 1 2 - 4176817 + 4179363 @@ -13712,7 +13649,7 @@ 1 2 - 4176817 + 4179363 @@ -13728,22 +13665,22 @@ 1 2 - 1497253 + 1498165 2 3 - 153038 + 153131 3 5 - 142773 + 142860 5 952 - 101247 + 101309 @@ -13759,7 +13696,7 @@ 1 2 - 1893845 + 1894999 2 @@ -13861,15 +13798,15 @@ function_entry_point - 1151517 + 1151752 id - 1141719 + 1141948 entry_point - 1151517 + 1151752 @@ -13883,12 +13820,12 @@ 1 2 - 1131921 + 1132144 2 3 - 9798 + 9804 @@ -13904,7 +13841,7 @@ 1 2 - 1151517 + 1151752 @@ -13914,15 +13851,15 @@ function_return_type - 4181950 + 4184498 id - 4176817 + 4179363 return_type - 817446 + 817945 @@ -13936,12 +13873,12 @@ 1 2 - 4171685 + 4174227 2 3 - 5132 + 5135 @@ -13957,22 +13894,22 @@ 1 2 - 505771 + 506080 2 3 - 211360 + 211489 3 7 - 66254 + 66294 7 2231 - 34060 + 34081 @@ -14263,33 +14200,33 @@ function_deleted - 96115 + 96173 id - 96115 + 96173 function_defaulted - 73719 + 73764 id - 73719 + 73764 function_prototyped - 4084901 + 4087391 id - 4084901 + 4087391 @@ -14442,27 +14379,27 @@ fun_decls - 4546348 + 4548652 id - 4541216 + 4543516 function - 4033111 + 4035569 type_id - 816047 + 816544 name - 1796796 + 1797891 location - 3368702 + 3370755 @@ -14476,7 +14413,7 @@ 1 2 - 4541216 + 4543516 @@ -14492,12 +14429,12 @@ 1 2 - 4536084 + 4538381 2 3 - 5132 + 5135 @@ -14513,7 +14450,7 @@ 1 2 - 4541216 + 4543516 @@ -14529,7 +14466,7 @@ 1 2 - 4541216 + 4543516 @@ -14545,17 +14482,17 @@ 1 2 - 3603858 + 3606521 2 3 - 356466 + 356216 3 7 - 72786 + 72830 @@ -14571,12 +14508,12 @@ 1 2 - 3993452 + 3995885 2 3 - 39659 + 39683 @@ -14592,7 +14529,7 @@ 1 2 - 4033111 + 4035569 @@ -14608,17 +14545,17 @@ 1 2 - 3660781 + 3663012 2 3 - 311674 + 311864 3 6 - 60655 + 60692 @@ -14634,22 +14571,22 @@ 1 2 - 431119 + 431381 2 3 - 273882 + 274048 3 6 - 63454 + 63493 6 - 2477 - 47591 + 2476 + 47620 @@ -14665,22 +14602,22 @@ 1 2 - 515103 + 515417 2 3 - 202961 + 203085 3 7 - 62988 + 63026 7 2192 - 34993 + 35014 @@ -14696,17 +14633,17 @@ 1 2 - 689604 + 690024 2 4 - 67187 + 67228 4 773 - 59255 + 59291 @@ -14722,22 +14659,22 @@ 1 2 - 594888 + 595251 2 3 - 121310 + 121384 3 7 - 63454 + 63493 7 1959 - 36393 + 36415 @@ -14753,27 +14690,27 @@ 1 2 - 1227570 + 1228318 2 3 - 266883 + 267045 3 4 - 77918 + 77966 4 7 - 146039 + 146128 7 986 - 78385 + 78433 @@ -14789,22 +14726,22 @@ 1 2 - 1406736 + 1407593 2 3 - 152104 + 152197 3 5 - 136707 + 136791 5 936 - 101247 + 101309 @@ -14820,17 +14757,17 @@ 1 2 - 1578437 + 1579399 2 4 - 134841 + 134923 4 562 - 83517 + 83568 @@ -14846,27 +14783,27 @@ 1 2 - 1235502 + 1236254 2 3 - 293011 + 293190 3 4 - 78851 + 78899 4 8 - 137174 + 137257 8 542 - 52256 + 52288 @@ -14882,17 +14819,17 @@ 1 2 - 2964644 + 2966451 2 4 - 277614 + 277783 4 55 - 126442 + 126520 @@ -14908,17 +14845,17 @@ 1 2 - 3031832 + 3033679 2 7 - 244020 + 244169 7 55 - 92849 + 92905 @@ -14934,12 +14871,12 @@ 1 2 - 3205399 + 3207353 2 18 - 163302 + 163402 @@ -14955,12 +14892,12 @@ 1 2 - 3230595 + 3232563 2 13 - 138107 + 138191 @@ -14970,22 +14907,22 @@ fun_def - 1888246 + 1888930 id - 1888246 + 1888930 fun_specialized - 26128 + 26144 id - 26128 + 26144 @@ -15003,15 +14940,15 @@ fun_decl_specifiers - 2904922 + 2906692 id - 1688550 + 1689579 name - 2799 + 2801 @@ -15025,17 +14962,17 @@ 1 2 - 490841 + 491140 2 3 - 1179045 + 1179764 3 4 - 18663 + 18674 @@ -15207,11 +15144,11 @@ fun_decl_empty_throws - 1471124 + 1472021 fun_decl - 1471124 + 1472021 @@ -15271,11 +15208,11 @@ fun_decl_empty_noexcept - 863171 + 863230 fun_decl - 863171 + 863230 @@ -15380,19 +15317,19 @@ param_decl_bind - 6991224 + 6995017 id - 6991224 + 6995017 index - 7931 + 7936 fun_decl - 3833415 + 3835284 @@ -15406,7 +15343,7 @@ 1 2 - 6991224 + 6995017 @@ -15422,7 +15359,7 @@ 1 2 - 6991224 + 6995017 @@ -15501,8 +15438,8 @@ 466 - 8216 - 8217 + 8215 + 8216 466 @@ -15582,8 +15519,8 @@ 466 - 8216 - 8217 + 8215 + 8216 466 @@ -15600,27 +15537,27 @@ 1 2 - 1973163 + 1973899 2 3 - 1061001 + 1061647 3 4 - 502505 + 502812 4 8 - 290678 + 290856 8 18 - 6065 + 6069 @@ -15636,27 +15573,27 @@ 1 2 - 1973163 + 1973899 2 3 - 1061001 + 1061647 3 4 - 502505 + 502812 4 8 - 290678 + 290856 8 18 - 6065 + 6069 @@ -15666,27 +15603,27 @@ var_decls - 8105882 + 8110354 id - 8034962 + 8039391 variable - 7022951 + 7027231 type_id - 2042217 + 2043462 name - 667208 + 667614 location - 5308739 + 5311974 @@ -15700,7 +15637,7 @@ 1 2 - 8034962 + 8039391 @@ -15716,12 +15653,12 @@ 1 2 - 7966841 + 7971229 2 3 - 68120 + 68162 @@ -15737,7 +15674,7 @@ 1 2 - 8034962 + 8039391 @@ -15753,12 +15690,12 @@ 1 2 - 8032162 + 8036590 2 3 - 2799 + 2801 @@ -15774,17 +15711,17 @@ 1 2 - 6170977 + 6175205 2 3 - 698469 + 698427 3 7 - 153504 + 153598 @@ -15800,12 +15737,12 @@ 1 2 - 6851717 + 6855892 2 4 - 171234 + 171338 @@ -15821,12 +15758,12 @@ 1 2 - 6907706 + 6911916 2 3 - 115245 + 115315 @@ -15842,17 +15779,17 @@ 1 2 - 6477987 + 6481934 2 3 - 542631 + 542962 3 4 - 2332 + 2334 @@ -15868,27 +15805,27 @@ 1 2 - 1165048 + 1165758 2 3 - 476377 + 477134 3 4 - 95182 + 94773 4 7 - 184765 + 184877 7 762 - 120844 + 120917 @@ -15904,22 +15841,22 @@ 1 2 - 1298490 + 1299281 2 3 - 452115 + 452390 3 6 - 155837 + 155932 6 724 - 135774 + 135857 @@ -15935,17 +15872,17 @@ 1 2 - 1538311 + 1539249 2 3 - 383061 + 383295 3 128 - 120844 + 120917 @@ -15961,22 +15898,22 @@ 1 2 - 1364744 + 1365576 2 3 - 404057 + 404303 3 7 - 173100 + 173206 7 592 - 100314 + 100375 @@ -15992,37 +15929,37 @@ 1 2 - 341069 + 341277 2 3 - 86783 + 86836 3 4 - 48524 + 48553 4 6 - 51790 + 51821 6 12 - 52256 + 52288 12 33 - 50390 + 50421 34 - 2385 - 36393 + 2384 + 36415 @@ -16038,37 +15975,37 @@ 1 2 - 368597 + 368822 2 3 - 77918 + 77966 3 4 - 45258 + 45285 4 6 - 49457 + 49487 6 14 - 53190 + 53222 14 56 - 50857 + 50888 56 2301 - 21929 + 21942 @@ -16084,27 +16021,27 @@ 1 2 - 456781 + 457059 2 3 - 93782 + 93839 3 5 - 46657 + 46686 5 19 - 50857 + 50888 19 1182 - 19129 + 19141 @@ -16120,32 +16057,32 @@ 1 2 - 378862 + 379093 2 3 - 90516 + 90571 3 5 - 59722 + 59758 5 9 - 51323 + 51354 9 21 - 50390 + 50421 21 1010 - 36393 + 36415 @@ -16161,17 +16098,17 @@ 1 2 - 4493625 + 4496363 2 3 - 531433 + 531757 3 - 897 - 283680 + 896 + 283853 @@ -16187,17 +16124,17 @@ 1 2 - 4882752 + 4885727 2 17 - 415255 + 415508 17 892 - 10731 + 10737 @@ -16213,12 +16150,12 @@ 1 2 - 4958804 + 4961826 2 759 - 349934 + 350147 @@ -16234,12 +16171,12 @@ 1 2 - 5299407 + 5302637 2 6 - 9331 + 9337 @@ -16249,26 +16186,26 @@ var_def - 3992985 + 3994952 id - 3992985 + 3994952 var_decl_specifiers - 378395 + 378626 id - 378395 + 378626 name - 1866 + 1867 @@ -16282,7 +16219,7 @@ 1 2 - 378395 + 378626 @@ -16334,19 +16271,19 @@ type_decls - 3281452 + 3283451 id - 3281452 + 3283451 type_id - 3231061 + 3233030 location - 3164340 + 3166269 @@ -16360,7 +16297,7 @@ 1 2 - 3281452 + 3283451 @@ -16376,7 +16313,7 @@ 1 2 - 3281452 + 3283451 @@ -16392,12 +16329,12 @@ 1 2 - 3189536 + 3191479 2 5 - 41525 + 41550 @@ -16413,12 +16350,12 @@ 1 2 - 3189536 + 3191479 2 5 - 41525 + 41550 @@ -16434,12 +16371,12 @@ 1 2 - 3112083 + 3113980 2 20 - 52256 + 52288 @@ -16455,12 +16392,12 @@ 1 2 - 3112083 + 3113980 2 20 - 52256 + 52288 @@ -16470,22 +16407,22 @@ type_def - 2640372 + 2641981 id - 2640372 + 2641981 type_decl_top - 743260 + 743713 type_decl - 743260 + 743713 @@ -16858,19 +16795,19 @@ usings - 369530 + 369755 id - 369530 + 369755 element_id - 315407 + 315599 location - 247753 + 247904 kind @@ -16888,7 +16825,7 @@ 1 2 - 369530 + 369755 @@ -16904,7 +16841,7 @@ 1 2 - 369530 + 369755 @@ -16920,7 +16857,7 @@ 1 2 - 369530 + 369755 @@ -16936,17 +16873,17 @@ 1 2 - 263150 + 263311 2 3 - 50857 + 50888 3 5 - 1399 + 1400 @@ -16962,17 +16899,17 @@ 1 2 - 263150 + 263311 2 3 - 50857 + 50888 3 5 - 1399 + 1400 @@ -16988,7 +16925,7 @@ 1 2 - 315407 + 315599 @@ -17004,22 +16941,22 @@ 1 2 - 202495 + 202618 2 4 - 10731 + 10737 4 5 - 31260 + 31279 5 11 - 3266 + 3268 @@ -17035,22 +16972,22 @@ 1 2 - 202495 + 202618 2 4 - 10731 + 10737 4 5 - 31260 + 31279 5 11 - 3266 + 3268 @@ -17066,7 +17003,7 @@ 1 2 - 247753 + 247904 @@ -17850,23 +17787,23 @@ params - 6350610 + 6354480 id - 6186841 + 6190611 function - 3489546 + 3491673 index - 7931 + 7936 type_id - 1845321 + 1846445 @@ -17880,7 +17817,7 @@ 1 2 - 6186841 + 6190611 @@ -17896,7 +17833,7 @@ 1 2 - 6186841 + 6190611 @@ -17912,12 +17849,12 @@ 1 2 - 6063198 + 6066892 2 4 - 123643 + 123718 @@ -17933,22 +17870,22 @@ 1 2 - 1866317 + 1867454 2 3 - 952288 + 952868 3 4 - 429719 + 429981 4 18 - 241221 + 241368 @@ -17964,22 +17901,22 @@ 1 2 - 1866317 + 1867454 2 3 - 952288 + 952868 3 4 - 429719 + 429981 4 18 - 241221 + 241368 @@ -17995,22 +17932,22 @@ 1 2 - 2164461 + 2165780 2 3 - 826311 + 826815 3 4 - 346201 + 346412 4 12 - 152571 + 152664 @@ -18208,7 +18145,7 @@ 6 7 - 1399 + 1400 7 @@ -18264,22 +18201,22 @@ 1 2 - 1183245 + 1183966 2 3 - 405923 + 406171 3 7 - 153971 + 154064 7 518 - 102180 + 102243 @@ -18295,22 +18232,22 @@ 1 2 - 1403937 + 1404792 2 3 - 212293 + 212422 3 7 - 147439 + 147528 7 502 - 81651 + 81701 @@ -18326,17 +18263,17 @@ 1 2 - 1419334 + 1420199 2 3 - 347135 + 347346 3 13 - 78851 + 78899 @@ -18346,11 +18283,11 @@ overrides - 125735 + 125725 new - 122762 + 122752 old @@ -18368,7 +18305,7 @@ 1 2 - 119797 + 119788 2 @@ -18776,11 +18713,11 @@ localvariables - 576952 + 576945 id - 576952 + 576945 type_id @@ -18788,7 +18725,7 @@ name - 90549 + 90547 @@ -18802,7 +18739,7 @@ 1 2 - 576952 + 576945 @@ -18818,7 +18755,7 @@ 1 2 - 576952 + 576945 @@ -18875,7 +18812,7 @@ 1 2 - 26913 + 26912 2 @@ -18911,12 +18848,12 @@ 1 2 - 57032 + 57031 2 3 - 14285 + 14284 3 @@ -18947,7 +18884,7 @@ 1 2 - 76492 + 76491 2 @@ -18957,7 +18894,7 @@ 3 1486 - 6645 + 6644 @@ -19985,31 +19922,31 @@ builtintypes - 26128 + 26144 id - 26128 + 26144 name - 26128 + 26144 kind - 26128 + 26144 size - 3266 + 3268 sign - 1399 + 1400 alignment - 2332 + 2334 @@ -20023,7 +19960,7 @@ 1 2 - 26128 + 26144 @@ -20039,7 +19976,7 @@ 1 2 - 26128 + 26144 @@ -20055,7 +19992,7 @@ 1 2 - 26128 + 26144 @@ -20071,7 +20008,7 @@ 1 2 - 26128 + 26144 @@ -20087,7 +20024,7 @@ 1 2 - 26128 + 26144 @@ -20103,7 +20040,7 @@ 1 2 - 26128 + 26144 @@ -20119,7 +20056,7 @@ 1 2 - 26128 + 26144 @@ -20135,7 +20072,7 @@ 1 2 - 26128 + 26144 @@ -20151,7 +20088,7 @@ 1 2 - 26128 + 26144 @@ -20167,7 +20104,7 @@ 1 2 - 26128 + 26144 @@ -20183,7 +20120,7 @@ 1 2 - 26128 + 26144 @@ -20199,7 +20136,7 @@ 1 2 - 26128 + 26144 @@ -20215,7 +20152,7 @@ 1 2 - 26128 + 26144 @@ -20231,7 +20168,7 @@ 1 2 - 26128 + 26144 @@ -20247,7 +20184,7 @@ 1 2 - 26128 + 26144 @@ -20406,7 +20343,7 @@ 3 4 - 2332 + 2334 @@ -20422,12 +20359,12 @@ 1 2 - 1866 + 1867 2 3 - 1399 + 1400 @@ -20542,7 +20479,7 @@ 5 6 - 1399 + 1400 @@ -20666,7 +20603,7 @@ 2 3 - 2332 + 2334 @@ -20682,7 +20619,7 @@ 3 4 - 2332 + 2334 @@ -20692,23 +20629,23 @@ derivedtypes - 3667313 + 3669548 id - 3667313 + 3669548 name - 1551842 + 1552788 kind - 2799 + 2801 type_id - 2361357 + 2362796 @@ -20722,7 +20659,7 @@ 1 2 - 3667313 + 3669548 @@ -20738,7 +20675,7 @@ 1 2 - 3667313 + 3669548 @@ -20754,7 +20691,7 @@ 1 2 - 3667313 + 3669548 @@ -20770,17 +20707,17 @@ 1 2 - 1323218 + 1324025 2 4 - 120377 + 120450 4 1153 - 108246 + 108312 @@ -20796,7 +20733,7 @@ 1 2 - 1550909 + 1551854 2 @@ -20817,17 +20754,17 @@ 1 2 - 1323218 + 1324025 2 4 - 120377 + 120450 4 1135 - 108246 + 108312 @@ -20966,22 +20903,22 @@ 1 2 - 1514516 + 1515439 2 3 - 545897 + 546230 3 4 - 218359 + 218492 4 72 - 82584 + 82634 @@ -20997,22 +20934,22 @@ 1 2 - 1525714 + 1526644 2 3 - 538432 + 538760 3 4 - 215559 + 215690 4 72 - 81651 + 81701 @@ -21028,22 +20965,22 @@ 1 2 - 1518715 + 1519641 2 3 - 549630 + 549965 3 4 - 217425 + 217558 4 6 - 75585 + 75631 @@ -21053,11 +20990,11 @@ pointerishsize - 2705693 + 2707342 id - 2705693 + 2707342 size @@ -21079,7 +21016,7 @@ 1 2 - 2705693 + 2707342 @@ -21095,7 +21032,7 @@ 1 2 - 2705693 + 2707342 @@ -21169,23 +21106,23 @@ arraysizes - 88183 + 88237 id - 88183 + 88237 num_elements - 31727 + 31746 bytesize - 33127 + 33147 alignment - 1866 + 1867 @@ -21199,7 +21136,7 @@ 1 2 - 88183 + 88237 @@ -21215,7 +21152,7 @@ 1 2 - 88183 + 88237 @@ -21231,7 +21168,7 @@ 1 2 - 88183 + 88237 @@ -21247,22 +21184,22 @@ 1 2 - 1866 + 1867 2 3 - 23795 + 23810 3 5 - 2799 + 2801 5 13 - 2799 + 2801 13 @@ -21283,17 +21220,17 @@ 1 2 - 26595 + 26611 2 3 - 2332 + 2334 3 7 - 2799 + 2801 @@ -21309,17 +21246,17 @@ 1 2 - 26595 + 26611 2 3 - 2799 + 2801 3 5 - 2332 + 2334 @@ -21335,27 +21272,27 @@ 1 2 - 1866 + 1867 2 3 - 23795 + 23810 3 4 - 3266 + 3268 4 6 - 2332 + 2334 7 16 - 1866 + 1867 @@ -21371,17 +21308,17 @@ 1 2 - 27528 + 27544 2 3 - 3732 + 3734 3 5 - 1866 + 1867 @@ -21397,12 +21334,12 @@ 1 2 - 27528 + 27544 2 3 - 4665 + 4668 4 @@ -21854,19 +21791,19 @@ usertypes - 5230820 + 5234008 id - 5230820 + 5234008 name - 1351680 + 1352503 kind - 5132 + 5135 @@ -21880,7 +21817,7 @@ 1 2 - 5230820 + 5234008 @@ -21896,7 +21833,7 @@ 1 2 - 5230820 + 5234008 @@ -21912,27 +21849,27 @@ 1 2 - 983082 + 983681 2 3 - 153504 + 153598 3 7 - 104513 + 104577 7 61 - 101714 + 101776 65 874 - 8865 + 8870 @@ -21948,17 +21885,17 @@ 1 2 - 1211239 + 1211977 2 3 - 125509 + 125586 3 7 - 14930 + 14939 @@ -22100,19 +22037,19 @@ usertypesize - 1705347 + 1706386 id - 1705347 + 1706386 size - 13530 + 13539 alignment - 2332 + 2334 @@ -22126,7 +22063,7 @@ 1 2 - 1705347 + 1706386 @@ -22142,7 +22079,7 @@ 1 2 - 1705347 + 1706386 @@ -22158,12 +22095,12 @@ 1 2 - 3266 + 3268 2 3 - 4199 + 4201 3 @@ -22214,12 +22151,12 @@ 1 2 - 10264 + 10270 2 3 - 2799 + 2801 3 @@ -22370,15 +22307,15 @@ mangled_name - 9013845 + 9019338 id - 9013845 + 9019338 mangled_name - 6058065 + 6061757 is_complete @@ -22396,7 +22333,7 @@ 1 2 - 9013845 + 9019338 @@ -22412,7 +22349,7 @@ 1 2 - 9013845 + 9019338 @@ -22428,12 +22365,12 @@ 1 2 - 5785583 + 5789108 2 874 - 272482 + 272648 @@ -22449,7 +22386,7 @@ 1 2 - 6058065 + 6061757 @@ -22502,48 +22439,48 @@ is_standard_layout_class - 1253232 + 1253995 id - 1253232 + 1253995 is_complete - 1644692 + 1645694 id - 1644692 + 1645694 is_class_template - 397992 + 398234 id - 397992 + 398234 class_instantiation - 1088996 + 1089659 to - 1088996 + 1089659 from - 168435 + 168537 @@ -22557,7 +22494,7 @@ 1 2 - 1088996 + 1089659 @@ -22573,47 +22510,47 @@ 1 2 - 59722 + 59758 2 3 - 29394 + 29412 3 4 - 15863 + 15873 4 5 - 13064 + 13072 5 6 - 9798 + 9804 6 10 - 12597 + 12605 10 16 - 13064 + 13072 16 70 - 13530 + 13539 70 84 - 1399 + 1400 @@ -22864,19 +22801,19 @@ class_template_argument_value - 495040 + 495342 type_id - 304676 + 304861 index - 1866 + 1867 arg_value - 495040 + 495342 @@ -22890,17 +22827,17 @@ 1 2 - 249619 + 249772 2 3 - 53190 + 53222 3 4 - 1866 + 1867 @@ -22916,22 +22853,22 @@ 1 2 - 189431 + 189546 2 3 - 81184 + 81234 3 4 - 12131 + 12138 4 9 - 21929 + 21942 @@ -23009,7 +22946,7 @@ 1 2 - 495040 + 495342 @@ -23025,7 +22962,7 @@ 1 2 - 495040 + 495342 @@ -23035,15 +22972,15 @@ is_proxy_class_for - 62055 + 62092 id - 62055 + 62092 templ_param_id - 62055 + 62092 @@ -23057,7 +22994,7 @@ 1 2 - 62055 + 62092 @@ -23073,7 +23010,7 @@ 1 2 - 62055 + 62092 @@ -23379,11 +23316,11 @@ is_function_template - 1402070 + 1402925 id - 1402070 + 1402925 @@ -24514,19 +24451,19 @@ routinetypeargs - 982616 + 983214 routine - 423187 + 423445 index - 7931 + 7936 type_id - 226757 + 226895 @@ -24540,27 +24477,27 @@ 1 2 - 152571 + 152664 2 3 - 133908 + 133989 3 4 - 63454 + 63493 4 5 - 45724 + 45752 5 18 - 27528 + 27544 @@ -24576,27 +24513,27 @@ 1 2 - 182432 + 182543 2 3 - 133441 + 133522 3 4 - 58788 + 58824 4 5 - 33593 + 33614 5 11 - 14930 + 14939 @@ -24637,7 +24574,7 @@ 10 11 - 1399 + 1400 13 @@ -24698,7 +24635,7 @@ 4 5 - 1399 + 1400 5 @@ -24754,27 +24691,27 @@ 1 2 - 146505 + 146595 2 3 - 30794 + 30812 3 5 - 16796 + 16807 5 12 - 18196 + 18207 12 110 - 14463 + 14472 @@ -24790,22 +24727,22 @@ 1 2 - 172634 + 172739 2 3 - 30794 + 30812 3 6 - 18663 + 18674 6 14 - 4665 + 4668 @@ -24815,19 +24752,19 @@ ptrtomembers - 37792 + 37815 id - 37792 + 37815 type_id - 37792 + 37815 class_id - 15397 + 15406 @@ -24841,7 +24778,7 @@ 1 2 - 37792 + 37815 @@ -24857,7 +24794,7 @@ 1 2 - 37792 + 37815 @@ -24873,7 +24810,7 @@ 1 2 - 37792 + 37815 @@ -24889,7 +24826,7 @@ 1 2 - 37792 + 37815 @@ -24905,12 +24842,12 @@ 1 2 - 13530 + 13539 8 9 - 1399 + 1400 28 @@ -24931,12 +24868,12 @@ 1 2 - 13530 + 13539 8 9 - 1399 + 1400 28 @@ -24951,15 +24888,15 @@ specifiers - 24728 + 24743 id - 24728 + 24743 str - 24728 + 24743 @@ -24973,7 +24910,7 @@ 1 2 - 24728 + 24743 @@ -24989,7 +24926,7 @@ 1 2 - 24728 + 24743 @@ -24999,15 +24936,15 @@ typespecifiers - 1131454 + 1132144 type_id - 1113258 + 1113936 spec_id - 3732 + 3734 @@ -25021,12 +24958,12 @@ 1 2 - 1095061 + 1095728 2 3 - 18196 + 18207 @@ -25082,15 +25019,15 @@ funspecifiers - 10298338 + 10305080 func_id - 4065772 + 4068249 spec_id - 8398 + 8403 @@ -25104,27 +25041,27 @@ 1 2 - 1356812 + 1357639 2 3 - 640613 + 640536 3 4 - 984482 + 985549 4 5 - 779654 + 780129 5 8 - 304209 + 304395 @@ -25223,8 +25160,8 @@ 466 - 6434 - 6435 + 6435 + 6436 466 @@ -25235,15 +25172,15 @@ varspecifiers - 2244713 + 2246080 var_id - 1224304 + 1225050 spec_id - 3732 + 3734 @@ -25257,22 +25194,22 @@ 1 2 - 729730 + 730174 2 3 - 202495 + 202618 3 4 - 58322 + 58357 4 5 - 233756 + 233898 @@ -25381,19 +25318,19 @@ attributes - 561294 + 561636 id - 561294 + 561636 kind - 1399 + 1400 name - 11197 + 11204 name_space @@ -25401,7 +25338,7 @@ location - 481043 + 481336 @@ -25415,7 +25352,7 @@ 1 2 - 561294 + 561636 @@ -25431,7 +25368,7 @@ 1 2 - 561294 + 561636 @@ -25447,7 +25384,7 @@ 1 2 - 561294 + 561636 @@ -25463,7 +25400,7 @@ 1 2 - 561294 + 561636 @@ -25654,7 +25591,7 @@ 1 2 - 10264 + 10270 2 @@ -25675,7 +25612,7 @@ 1 2 - 11197 + 11204 @@ -25846,17 +25783,17 @@ 1 2 - 431585 + 431848 2 3 - 20062 + 20075 3 7 - 29394 + 29412 @@ -25872,7 +25809,7 @@ 1 2 - 481043 + 481336 @@ -25888,17 +25825,17 @@ 1 2 - 432985 + 433249 2 3 - 19596 + 19608 3 4 - 28461 + 28478 @@ -25914,7 +25851,7 @@ 1 2 - 481043 + 481336 @@ -25924,27 +25861,27 @@ attribute_args - 343868 + 344078 id - 343868 + 344078 kind - 1399 + 1400 attribute - 262684 + 262844 index - 1399 + 1400 location - 327538 + 327738 @@ -25958,7 +25895,7 @@ 1 2 - 343868 + 344078 @@ -25974,7 +25911,7 @@ 1 2 - 343868 + 344078 @@ -25990,7 +25927,7 @@ 1 2 - 343868 + 344078 @@ -26006,7 +25943,7 @@ 1 2 - 343868 + 344078 @@ -26121,17 +26058,17 @@ 1 2 - 197363 + 197483 2 3 - 49457 + 49487 3 4 - 15863 + 15873 @@ -26147,12 +26084,12 @@ 1 2 - 252419 + 252573 2 3 - 10264 + 10270 @@ -26168,17 +26105,17 @@ 1 2 - 197363 + 197483 2 3 - 49457 + 49487 3 4 - 15863 + 15873 @@ -26194,17 +26131,17 @@ 1 2 - 197363 + 197483 2 3 - 49457 + 49487 3 4 - 15863 + 15873 @@ -26319,12 +26256,12 @@ 1 2 - 313541 + 313732 2 7 - 13997 + 14005 @@ -26340,12 +26277,12 @@ 1 2 - 314941 + 315132 2 3 - 12597 + 12605 @@ -26361,12 +26298,12 @@ 1 2 - 313541 + 313732 2 7 - 13997 + 14005 @@ -26382,7 +26319,7 @@ 1 2 - 327538 + 327738 @@ -26392,15 +26329,15 @@ attribute_arg_value - 25195 + 25210 arg - 25195 + 25210 value - 15863 + 15873 @@ -26414,7 +26351,7 @@ 1 2 - 25195 + 25210 @@ -26430,12 +26367,12 @@ 1 2 - 14463 + 14472 2 16 - 1399 + 1400 @@ -26493,15 +26430,15 @@ attribute_arg_constant - 318207 + 318400 arg - 318207 + 318400 constant - 318207 + 318400 @@ -26515,7 +26452,7 @@ 1 2 - 318207 + 318400 @@ -26531,7 +26468,7 @@ 1 2 - 318207 + 318400 @@ -26710,15 +26647,15 @@ funcattributes - 629882 + 630265 func_id - 443250 + 443520 spec_id - 524435 + 524754 @@ -26732,17 +26669,17 @@ 1 2 - 338269 + 338476 2 3 - 64387 + 64427 3 6 - 39659 + 39683 6 @@ -26763,12 +26700,12 @@ 1 2 - 505771 + 506080 2 17 - 18663 + 18674 @@ -26904,15 +26841,15 @@ unspecifiedtype - 9482291 + 9488069 type_id - 9482291 + 9488069 unspecified_type_id - 6486385 + 6490338 @@ -26926,7 +26863,7 @@ 1 2 - 9482291 + 9488069 @@ -26942,17 +26879,17 @@ 1 2 - 4556146 + 4558923 2 3 - 1714678 + 1715723 3 145 - 215559 + 215690 @@ -26962,19 +26899,19 @@ member - 3878673 + 3881037 parent - 545431 + 545763 index - 92849 + 92905 child - 3807287 + 3809607 @@ -26988,47 +26925,47 @@ 1 2 - 129709 + 129788 2 3 - 64854 + 64894 3 4 - 73252 + 73297 4 5 - 75119 + 75165 5 6 - 40592 + 40617 6 8 - 46657 + 46686 8 14 - 45724 + 45752 14 30 - 41525 + 41550 30 200 - 27994 + 28011 @@ -27044,52 +26981,52 @@ 1 2 - 129709 + 129788 2 3 - 64854 + 64894 3 4 - 73252 + 73297 4 5 - 76052 + 76098 5 6 - 39659 + 39683 6 7 - 24262 + 24276 7 9 - 41992 + 42017 9 17 - 43858 + 43885 17 41 - 41525 + 41550 41 200 - 10264 + 10270 @@ -27105,62 +27042,62 @@ 1 2 - 26128 + 26144 2 3 - 6998 + 7002 3 4 - 3732 + 3734 4 5 - 7931 + 7936 5 6 - 5598 + 5602 6 7 - 5598 + 5602 7 9 - 7465 + 7469 9 16 - 6998 + 7002 16 52 - 6998 + 7002 52 107 - 6998 + 7002 108 577 - 6998 + 7002 737 1162 - 1399 + 1400 @@ -27176,62 +27113,62 @@ 1 2 - 26128 + 26144 2 3 - 6998 + 7002 3 4 - 3732 + 3734 4 5 - 7931 + 7936 5 6 - 5598 + 5602 6 7 - 5598 + 5602 7 9 - 7465 + 7469 9 16 - 6998 + 7002 16 52 - 6998 + 7002 52 107 - 6998 + 7002 108 577 - 6998 + 7002 738 1163 - 1399 + 1400 @@ -27247,7 +27184,7 @@ 1 2 - 3807287 + 3809607 @@ -27263,12 +27200,12 @@ 1 2 - 3735900 + 3738177 2 3 - 71386 + 71430 @@ -28798,15 +28735,15 @@ commentbinding - 3089221 + 3091104 id - 2443942 + 2445431 element - 3012702 + 3014538 @@ -28820,12 +28757,12 @@ 1 2 - 2366956 + 2368399 2 97 - 76985 + 77032 @@ -28841,12 +28778,12 @@ 1 2 - 2936183 + 2937972 2 3 - 76519 + 76565 @@ -28856,15 +28793,15 @@ exprconv - 7032993 + 7032991 converted - 7032993 + 7032991 conversion - 7032993 + 7032991 @@ -28878,7 +28815,7 @@ 1 2 - 7032993 + 7032991 @@ -28894,7 +28831,7 @@ 1 2 - 7032993 + 7032991 @@ -29251,15 +29188,15 @@ namespaces - 12131 + 12138 id - 12131 + 12138 name - 9798 + 9804 @@ -29273,7 +29210,7 @@ 1 2 - 12131 + 12138 @@ -29289,7 +29226,7 @@ 1 2 - 8398 + 8403 2 @@ -29309,26 +29246,26 @@ namespace_inline - 1399 + 1400 id - 1399 + 1400 namespacembrs - 2386553 + 2388007 parentid - 10264 + 10270 memberid - 2386553 + 2388007 @@ -29342,7 +29279,7 @@ 1 2 - 1866 + 1867 2 @@ -29403,7 +29340,7 @@ 1 2 - 2386553 + 2388007 @@ -29899,7 +29836,7 @@ qualifyingelement - 97537 + 97518 location @@ -30013,7 +29950,7 @@ 1 2 - 58420 + 58401 2 @@ -30049,7 +29986,7 @@ 1 2 - 58420 + 58401 2 @@ -30085,7 +30022,7 @@ 1 2 - 63834 + 63815 2 @@ -30198,12 +30135,12 @@ 1 2 - 137054 + 137073 2 3 - 55703 + 55684 3 @@ -32144,7 +32081,7 @@ expr_types - 18451397 + 18451442 id @@ -32170,12 +32107,12 @@ 1 2 - 18188166 + 18188121 2 3 - 131615 + 131660 @@ -32212,17 +32149,17 @@ 2 3 - 249345 + 249334 3 4 - 102817 + 102840 4 5 - 81877 + 81865 5 @@ -32237,12 +32174,12 @@ 14 41 - 91653 + 91664 41 125325 - 44590 + 44579 @@ -33769,11 +33706,11 @@ lambdas - 21462 + 21475 expr - 21462 + 21475 default_capture @@ -33795,7 +33732,7 @@ 1 2 - 21462 + 21475 @@ -33811,7 +33748,7 @@ 1 2 - 21462 + 21475 @@ -33885,15 +33822,15 @@ lambda_capture - 27994 + 28011 id - 27994 + 28011 lambda - 20529 + 20541 index @@ -33901,7 +33838,7 @@ field - 27994 + 28011 captured_by_reference @@ -33913,7 +33850,7 @@ location - 2799 + 2801 @@ -33927,7 +33864,7 @@ 1 2 - 27994 + 28011 @@ -33943,7 +33880,7 @@ 1 2 - 27994 + 28011 @@ -33959,7 +33896,7 @@ 1 2 - 27994 + 28011 @@ -33975,7 +33912,7 @@ 1 2 - 27994 + 28011 @@ -33991,7 +33928,7 @@ 1 2 - 27994 + 28011 @@ -34007,7 +33944,7 @@ 1 2 - 27994 + 28011 @@ -34023,12 +33960,12 @@ 1 2 - 13064 + 13072 2 3 - 7465 + 7469 @@ -34044,12 +33981,12 @@ 1 2 - 13064 + 13072 2 3 - 7465 + 7469 @@ -34065,12 +34002,12 @@ 1 2 - 13064 + 13072 2 3 - 7465 + 7469 @@ -34086,7 +34023,7 @@ 1 2 - 20529 + 20541 @@ -34102,7 +34039,7 @@ 1 2 - 20529 + 20541 @@ -34118,12 +34055,12 @@ 1 2 - 13064 + 13072 2 3 - 7465 + 7469 @@ -34255,7 +34192,7 @@ 1 2 - 27994 + 28011 @@ -34271,7 +34208,7 @@ 1 2 - 27994 + 28011 @@ -34287,7 +34224,7 @@ 1 2 - 27994 + 28011 @@ -34303,7 +34240,7 @@ 1 2 - 27994 + 28011 @@ -34319,7 +34256,7 @@ 1 2 - 27994 + 28011 @@ -34335,7 +34272,7 @@ 1 2 - 27994 + 28011 @@ -34543,7 +34480,7 @@ 8 9 - 1866 + 1867 14 @@ -34564,7 +34501,7 @@ 8 9 - 1866 + 1867 14 @@ -34585,7 +34522,7 @@ 1 2 - 2799 + 2801 @@ -34601,7 +34538,7 @@ 8 9 - 1866 + 1867 14 @@ -34622,7 +34559,7 @@ 1 2 - 2799 + 2801 @@ -34638,7 +34575,7 @@ 1 2 - 2799 + 2801 @@ -36381,11 +36318,11 @@ stmt_decl_bind - 580849 + 580842 stmt - 541066 + 541060 num @@ -36393,7 +36330,7 @@ decl - 580745 + 580738 @@ -36407,7 +36344,7 @@ 1 2 - 520377 + 520371 2 @@ -36428,7 +36365,7 @@ 1 2 - 520377 + 520371 2 @@ -36631,7 +36568,7 @@ 1 2 - 580707 + 580700 2 @@ -36652,7 +36589,7 @@ 1 2 - 580745 + 580738 @@ -36662,11 +36599,11 @@ stmt_decl_entry_bind - 580849 + 580842 stmt - 541066 + 541060 num @@ -36674,7 +36611,7 @@ decl_entry - 580791 + 580784 @@ -36688,7 +36625,7 @@ 1 2 - 520377 + 520371 2 @@ -36709,7 +36646,7 @@ 1 2 - 520377 + 520371 2 @@ -36912,7 +36849,7 @@ 1 2 - 580770 + 580763 3 @@ -36933,7 +36870,7 @@ 1 2 - 580791 + 580784 @@ -36943,15 +36880,15 @@ blockscope - 1410469 + 1410861 block - 1410469 + 1410861 enclosing - 1295224 + 1295546 @@ -36965,7 +36902,7 @@ 1 2 - 1410469 + 1410861 @@ -36981,12 +36918,12 @@ 1 2 - 1229903 + 1230185 2 13 - 65321 + 65360 @@ -37182,19 +37119,19 @@ preprocdirects - 4188015 + 4190567 id - 4188015 + 4190567 kind - 5132 + 5135 location - 4147423 + 4149950 @@ -37208,7 +37145,7 @@ 1 2 - 4188015 + 4190567 @@ -37224,7 +37161,7 @@ 1 2 - 4188015 + 4190567 @@ -37372,7 +37309,7 @@ 1 2 - 4146956 + 4149483 88 @@ -37393,7 +37330,7 @@ 1 2 - 4147423 + 4149950 @@ -37403,15 +37340,15 @@ preprocpair - 1430532 + 1431403 begin - 1196309 + 1197038 elseelifend - 1430532 + 1431403 @@ -37425,17 +37362,17 @@ 1 2 - 977950 + 978546 2 3 - 208094 + 208221 3 11 - 10264 + 10270 @@ -37451,7 +37388,7 @@ 1 2 - 1430532 + 1431403 @@ -37461,22 +37398,22 @@ preproctrue - 766589 + 767056 branch - 766589 + 767056 preprocfalse - 331271 + 331473 branch - 331271 + 331473 @@ -37629,15 +37566,15 @@ includes - 313074 + 313265 id - 313074 + 313265 included - 117111 + 117182 @@ -37651,7 +37588,7 @@ 1 2 - 313074 + 313265 @@ -37667,32 +37604,32 @@ 1 2 - 61121 + 61159 2 3 - 21929 + 21942 3 4 - 12597 + 12605 4 6 - 10264 + 10270 6 14 - 8865 + 8870 14 47 - 2332 + 2334 diff --git a/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/old.dbscheme b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/old.dbscheme deleted file mode 100644 index e51fad7a243..00000000000 --- a/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/old.dbscheme +++ /dev/null @@ -1,2323 +0,0 @@ - -/** - * An invocation of the compiler. Note that more than one file may be - * compiled per invocation. For example, this command compiles three - * source files: - * - * gcc -c f1.c f2.c f3.c - * - * The `id` simply identifies the invocation, while `cwd` is the working - * directory from which the compiler was invoked. - */ -compilations( - /** - * An invocation of the compiler. Note that more than one file may - * be compiled per invocation. For example, this command compiles - * three source files: - * - * gcc -c f1.c f2.c f3.c - */ - unique int id : @compilation, - string cwd : string ref -); - -/** - * The arguments that were passed to the extractor for a compiler - * invocation. If `id` is for the compiler invocation - * - * gcc -c f1.c f2.c f3.c - * - * then typically there will be rows for - * - * num | arg - * --- | --- - * 0 | *path to extractor* - * 1 | `--mimic` - * 2 | `/usr/bin/gcc` - * 3 | `-c` - * 4 | f1.c - * 5 | f2.c - * 6 | f3.c - */ -#keyset[id, num] -compilation_args( - int id : @compilation ref, - int num : int ref, - string arg : string ref -); - -/** - * The source files that are compiled by a compiler invocation. - * If `id` is for the compiler invocation - * - * gcc -c f1.c f2.c f3.c - * - * then there will be rows for - * - * num | arg - * --- | --- - * 0 | f1.c - * 1 | f2.c - * 2 | f3.c - * - * Note that even if those files `#include` headers, those headers - * do not appear as rows. - */ -#keyset[id, num] -compilation_compiling_files( - int id : @compilation ref, - int num : int ref, - int file : @file ref -); - -/** - * The time taken by the extractor for a compiler invocation. - * - * For each file `num`, there will be rows for - * - * kind | seconds - * ---- | --- - * 1 | CPU seconds used by the extractor frontend - * 2 | Elapsed seconds during the extractor frontend - * 3 | CPU seconds used by the extractor backend - * 4 | Elapsed seconds during the extractor backend - */ -#keyset[id, num, kind] -compilation_time( - int id : @compilation ref, - int num : int ref, - /* kind: - 1 = frontend_cpu_seconds - 2 = frontend_elapsed_seconds - 3 = extractor_cpu_seconds - 4 = extractor_elapsed_seconds - */ - int kind : int ref, - float seconds : float ref -); - -/** - * An error or warning generated by the extractor. - * The diagnostic message `diagnostic` was generated during compiler - * invocation `compilation`, and is the `file_number_diagnostic_number`th - * message generated while extracting the `file_number`th file of that - * invocation. - */ -#keyset[compilation, file_number, file_number_diagnostic_number] -diagnostic_for( - int diagnostic : @diagnostic ref, - int compilation : @compilation ref, - int file_number : int ref, - int file_number_diagnostic_number : int ref -); - -/** - * If extraction was successful, then `cpu_seconds` and - * `elapsed_seconds` are the CPU time and elapsed time (respectively) - * that extraction took for compiler invocation `id`. - */ -compilation_finished( - unique int id : @compilation ref, - float cpu_seconds : float ref, - float elapsed_seconds : float ref -); - - -/** - * External data, loaded from CSV files during snapshot creation. See - * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) - * for more information. - */ -externalData( - int id : @externalDataElement, - string path : string ref, - int column: int ref, - string value : string ref -); - -/** - * The source location of the snapshot. - */ -sourceLocationPrefix(string prefix : string ref); - -/** - * Information about packages that provide code used during compilation. - * The `id` is just a unique identifier. - * The `namespace` is typically the name of the package manager that - * provided the package (e.g. "dpkg" or "yum"). - * The `package_name` is the name of the package, and `version` is its - * version (as a string). - */ -external_packages( - unique int id: @external_package, - string namespace : string ref, - string package_name : string ref, - string version : string ref -); - -/** - * Holds if File `fileid` was provided by package `package`. - */ -header_to_external_package( - int fileid : @file ref, - int package : @external_package ref -); - -/* - * Version history - */ - -svnentries( - unique int id : @svnentry, - string revision : string ref, - string author : string ref, - date revisionDate : date ref, - int changeSize : int ref -) - -svnaffectedfiles( - int id : @svnentry ref, - int file : @file ref, - string action : string ref -) - -svnentrymsg( - unique int id : @svnentry ref, - string message : string ref -) - -svnchurn( - int commit : @svnentry ref, - int file : @file ref, - int addedLines : int ref, - int deletedLines : int ref -) - -/* - * C++ dbscheme - */ - -extractor_version( - string codeql_version: string ref, - string frontend_version: string ref -) - -@location = @location_stmt | @location_expr | @location_default ; - -/** - * The location of an element that is not an expression or a statement. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `file`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ -locations_default( - /** The location of an element that is not an expression or a statement. */ - unique int id: @location_default, - int container: @container ref, - int startLine: int ref, - int startColumn: int ref, - int endLine: int ref, - int endColumn: int ref -); - -/** - * The location of a statement. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `file`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ -locations_stmt( - /** The location of a statement. */ - unique int id: @location_stmt, - int container: @container ref, - int startLine: int ref, - int startColumn: int ref, - int endLine: int ref, - int endColumn: int ref -); - -/** - * The location of an expression. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `file`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ -locations_expr( - /** The location of an expression. */ - unique int id: @location_expr, - int container: @container ref, - int startLine: int ref, - int startColumn: int ref, - int endLine: int ref, - int endColumn: int ref -); - -/** An element for which line-count information is available. */ -@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; - -numlines( - int element_id: @sourceline ref, - int num_lines: int ref, - int num_code: int ref, - int num_comment: int ref -); - -diagnostics( - unique int id: @diagnostic, - int severity: int ref, - string error_tag: string ref, - string error_message: string ref, - string full_error_message: string ref, - int location: @location_default ref -); - -files( - unique int id: @file, - string name: string ref -); - -folders( - unique int id: @folder, - string name: string ref -); - -@container = @folder | @file - -containerparent( - int parent: @container ref, - unique int child: @container ref -); - -fileannotations( - int id: @file ref, - int kind: int ref, - string name: string ref, - string value: string ref -); - -inmacroexpansion( - int id: @element ref, - int inv: @macroinvocation ref -); - -affectedbymacroexpansion( - int id: @element ref, - int inv: @macroinvocation ref -); - -case @macroinvocation.kind of - 1 = @macro_expansion -| 2 = @other_macro_reference -; - -macroinvocations( - unique int id: @macroinvocation, - int macro_id: @ppd_define ref, - int location: @location_default ref, - int kind: int ref -); - -macroparent( - unique int id: @macroinvocation ref, - int parent_id: @macroinvocation ref -); - -// a macroinvocation may be part of another location -// the way to find a constant expression that uses a macro -// is thus to find a constant expression that has a location -// to which a macro invocation is bound -macrolocationbind( - int id: @macroinvocation ref, - int location: @location ref -); - -#keyset[invocation, argument_index] -macro_argument_unexpanded( - int invocation: @macroinvocation ref, - int argument_index: int ref, - string text: string ref -); - -#keyset[invocation, argument_index] -macro_argument_expanded( - int invocation: @macroinvocation ref, - int argument_index: int ref, - string text: string ref -); - -/* -case @function.kind of - 1 = @normal_function -| 2 = @constructor -| 3 = @destructor -| 4 = @conversion_function -| 5 = @operator -| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk -| 7 = @user_defined_literal -| 8 = @deduction_guide -; -*/ - -functions( - unique int id: @function, - string name: string ref, - int kind: int ref -); - -function_entry_point( - int id: @function ref, - unique int entry_point: @stmt ref -); - -function_return_type( - int id: @function ref, - int return_type: @type ref -); - -/** - * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` - * instance associated with it, and the variables representing the `handle` and `promise` - * for it. - */ -coroutine( - unique int function: @function ref, - int traits: @type ref -); - -/* -case @coroutine_placeholder_variable.kind of - 1 = @handle -| 2 = @promise -| 3 = @init_await_resume -; -*/ - -coroutine_placeholder_variable( - unique int placeholder_variable: @variable ref, - int kind: int ref, - int function: @function ref -) - -/** The `new` function used for allocating the coroutine state, if any. */ -coroutine_new( - unique int function: @function ref, - int new: @function ref -); - -/** The `delete` function used for deallocating the coroutine state, if any. */ -coroutine_delete( - unique int function: @function ref, - int delete: @function ref -); - -purefunctions(unique int id: @function ref); - -function_deleted(unique int id: @function ref); - -function_defaulted(unique int id: @function ref); - -function_prototyped(unique int id: @function ref) - -deduction_guide_for_class( - int id: @function ref, - int class_template: @usertype ref -) - -member_function_this_type( - unique int id: @function ref, - int this_type: @type ref -); - -#keyset[id, type_id] -fun_decls( - int id: @fun_decl, - int function: @function ref, - int type_id: @type ref, - string name: string ref, - int location: @location_default ref -); -fun_def(unique int id: @fun_decl ref); -fun_specialized(unique int id: @fun_decl ref); -fun_implicit(unique int id: @fun_decl ref); -fun_decl_specifiers( - int id: @fun_decl ref, - string name: string ref -) -#keyset[fun_decl, index] -fun_decl_throws( - int fun_decl: @fun_decl ref, - int index: int ref, - int type_id: @type ref -); -/* an empty throw specification is different from none */ -fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); -fun_decl_noexcept( - int fun_decl: @fun_decl ref, - int constant: @expr ref -); -fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); -fun_decl_typedef_type( - unique int fun_decl: @fun_decl ref, - int typedeftype_id: @usertype ref -); - -param_decl_bind( - unique int id: @var_decl ref, - int index: int ref, - int fun_decl: @fun_decl ref -); - -#keyset[id, type_id] -var_decls( - int id: @var_decl, - int variable: @variable ref, - int type_id: @type ref, - string name: string ref, - int location: @location_default ref -); -var_def(unique int id: @var_decl ref); -var_decl_specifiers( - int id: @var_decl ref, - string name: string ref -) -is_structured_binding(unique int id: @variable ref); - -type_decls( - unique int id: @type_decl, - int type_id: @type ref, - int location: @location_default ref -); -type_def(unique int id: @type_decl ref); -type_decl_top( - unique int type_decl: @type_decl ref -); - -namespace_decls( - unique int id: @namespace_decl, - int namespace_id: @namespace ref, - int location: @location_default ref, - int bodylocation: @location_default ref -); - -case @using.kind of - 1 = @using_declaration -| 2 = @using_directive -| 3 = @using_enum_declaration -; - -usings( - unique int id: @using, - int element_id: @element ref, - int location: @location_default ref, - int kind: int ref -); - -/** The element which contains the `using` declaration. */ -using_container( - int parent: @element ref, - int child: @using ref -); - -static_asserts( - unique int id: @static_assert, - int condition : @expr ref, - string message : string ref, - int location: @location_default ref, - int enclosing : @element ref -); - -// each function has an ordered list of parameters -#keyset[id, type_id] -#keyset[function, index, type_id] -params( - int id: @parameter, - int function: @parameterized_element ref, - int index: int ref, - int type_id: @type ref -); - -overrides( - int new: @function ref, - int old: @function ref -); - -#keyset[id, type_id] -membervariables( - int id: @membervariable, - int type_id: @type ref, - string name: string ref -); - -#keyset[id, type_id] -globalvariables( - int id: @globalvariable, - int type_id: @type ref, - string name: string ref -); - -#keyset[id, type_id] -localvariables( - int id: @localvariable, - int type_id: @type ref, - string name: string ref -); - -autoderivation( - unique int var: @variable ref, - int derivation_type: @type ref -); - -orphaned_variables( - int var: @localvariable ref, - int function: @function ref -) - -enumconstants( - unique int id: @enumconstant, - int parent: @usertype ref, - int index: int ref, - int type_id: @type ref, - string name: string ref, - int location: @location_default ref -); - -@variable = @localscopevariable | @globalvariable | @membervariable; - -@localscopevariable = @localvariable | @parameter; - -/** - * Built-in types are the fundamental types, e.g., integral, floating, and void. - */ -case @builtintype.kind of - 1 = @errortype -| 2 = @unknowntype -| 3 = @void -| 4 = @boolean -| 5 = @char -| 6 = @unsigned_char -| 7 = @signed_char -| 8 = @short -| 9 = @unsigned_short -| 10 = @signed_short -| 11 = @int -| 12 = @unsigned_int -| 13 = @signed_int -| 14 = @long -| 15 = @unsigned_long -| 16 = @signed_long -| 17 = @long_long -| 18 = @unsigned_long_long -| 19 = @signed_long_long -// ... 20 Microsoft-specific __int8 -// ... 21 Microsoft-specific __int16 -// ... 22 Microsoft-specific __int32 -// ... 23 Microsoft-specific __int64 -| 24 = @float -| 25 = @double -| 26 = @long_double -| 27 = @complex_float // C99-specific _Complex float -| 28 = @complex_double // C99-specific _Complex double -| 29 = @complex_long_double // C99-specific _Complex long double -| 30 = @imaginary_float // C99-specific _Imaginary float -| 31 = @imaginary_double // C99-specific _Imaginary double -| 32 = @imaginary_long_double // C99-specific _Imaginary long double -| 33 = @wchar_t // Microsoft-specific -| 34 = @decltype_nullptr // C++11 -| 35 = @int128 // __int128 -| 36 = @unsigned_int128 // unsigned __int128 -| 37 = @signed_int128 // signed __int128 -| 38 = @float128 // __float128 -| 39 = @complex_float128 // _Complex __float128 -| 40 = @decimal32 // _Decimal32 -| 41 = @decimal64 // _Decimal64 -| 42 = @decimal128 // _Decimal128 -| 43 = @char16_t -| 44 = @char32_t -| 45 = @std_float32 // _Float32 -| 46 = @float32x // _Float32x -| 47 = @std_float64 // _Float64 -| 48 = @float64x // _Float64x -| 49 = @std_float128 // _Float128 -// ... 50 _Float128x -| 51 = @char8_t -| 52 = @float16 // _Float16 -| 53 = @complex_float16 // _Complex _Float16 -| 54 = @fp16 // __fp16 -| 55 = @std_bfloat16 // __bf16 -| 56 = @std_float16 // std::float16_t -| 57 = @complex_std_float32 // _Complex _Float32 -| 58 = @complex_float32x // _Complex _Float32x -| 59 = @complex_std_float64 // _Complex _Float64 -| 60 = @complex_float64x // _Complex _Float64x -| 61 = @complex_std_float128 // _Complex _Float128 -; - -builtintypes( - unique int id: @builtintype, - string name: string ref, - int kind: int ref, - int size: int ref, - int sign: int ref, - int alignment: int ref -); - -/** - * Derived types are types that are directly derived from existing types and - * point to, refer to, transform type data to return a new type. - */ -case @derivedtype.kind of - 1 = @pointer -| 2 = @reference -| 3 = @type_with_specifiers -| 4 = @array -| 5 = @gnu_vector -| 6 = @routineptr -| 7 = @routinereference -| 8 = @rvalue_reference // C++11 -// ... 9 type_conforming_to_protocols deprecated -| 10 = @block -; - -derivedtypes( - unique int id: @derivedtype, - string name: string ref, - int kind: int ref, - int type_id: @type ref -); - -pointerishsize(unique int id: @derivedtype ref, - int size: int ref, - int alignment: int ref); - -arraysizes( - unique int id: @derivedtype ref, - int num_elements: int ref, - int bytesize: int ref, - int alignment: int ref -); - -typedefbase( - unique int id: @usertype ref, - int type_id: @type ref -); - -/** - * An instance of the C++11 `decltype` operator. For example: - * ``` - * int a; - * decltype(1+a) b; - * ``` - * Here `expr` is `1+a`. - * - * Sometimes an additional pair of parentheses around the expression - * would change the semantics of this decltype, e.g. - * ``` - * struct A { double x; }; - * const A* a = new A(); - * decltype( a->x ); // type is double - * decltype((a->x)); // type is const double& - * ``` - * (Please consult the C++11 standard for more details). - * `parentheses_would_change_meaning` is `true` iff that is the case. - */ -#keyset[id, expr] -decltypes( - int id: @decltype, - int expr: @expr ref, - int base_type: @type ref, - boolean parentheses_would_change_meaning: boolean ref -); - -/* -case @usertype.kind of - 1 = @struct -| 2 = @class -| 3 = @union -| 4 = @enum -| 5 = @typedef // classic C: typedef typedef type name -| 6 = @template -| 7 = @template_parameter -| 8 = @template_template_parameter -| 9 = @proxy_class // a proxy class associated with a template parameter -// ... 10 objc_class deprecated -// ... 11 objc_protocol deprecated -// ... 12 objc_category deprecated -| 13 = @scoped_enum -| 14 = @using_alias // a using name = type style typedef -; -*/ - -usertypes( - unique int id: @usertype, - string name: string ref, - int kind: int ref -); - -usertypesize( - unique int id: @usertype ref, - int size: int ref, - int alignment: int ref -); - -usertype_final(unique int id: @usertype ref); - -usertype_uuid( - unique int id: @usertype ref, - string uuid: string ref -); - -mangled_name( - unique int id: @declaration ref, - int mangled_name : @mangledname, - boolean is_complete: boolean ref -); - -is_pod_class(unique int id: @usertype ref); -is_standard_layout_class(unique int id: @usertype ref); - -is_complete(unique int id: @usertype ref); - -is_class_template(unique int id: @usertype ref); -class_instantiation( - int to: @usertype ref, - int from: @usertype ref -); -class_template_argument( - int type_id: @usertype ref, - int index: int ref, - int arg_type: @type ref -); -class_template_argument_value( - int type_id: @usertype ref, - int index: int ref, - int arg_value: @expr ref -); - -is_proxy_class_for( - unique int id: @usertype ref, - unique int templ_param_id: @usertype ref -); - -type_mentions( - unique int id: @type_mention, - int type_id: @type ref, - int location: @location ref, - // a_symbol_reference_kind from the frontend. - int kind: int ref -); - -is_function_template(unique int id: @function ref); -function_instantiation( - unique int to: @function ref, - int from: @function ref -); -function_template_argument( - int function_id: @function ref, - int index: int ref, - int arg_type: @type ref -); -function_template_argument_value( - int function_id: @function ref, - int index: int ref, - int arg_value: @expr ref -); - -is_variable_template(unique int id: @variable ref); -variable_instantiation( - unique int to: @variable ref, - int from: @variable ref -); -variable_template_argument( - int variable_id: @variable ref, - int index: int ref, - int arg_type: @type ref -); -variable_template_argument_value( - int variable_id: @variable ref, - int index: int ref, - int arg_value: @expr ref -); - -routinetypes( - unique int id: @routinetype, - int return_type: @type ref -); - -routinetypeargs( - int routine: @routinetype ref, - int index: int ref, - int type_id: @type ref -); - -ptrtomembers( - unique int id: @ptrtomember, - int type_id: @type ref, - int class_id: @type ref -); - -/* - specifiers for types, functions, and variables - - "public", - "protected", - "private", - - "const", - "volatile", - "static", - - "pure", - "virtual", - "sealed", // Microsoft - "__interface", // Microsoft - "inline", - "explicit", - - "near", // near far extension - "far", // near far extension - "__ptr32", // Microsoft - "__ptr64", // Microsoft - "__sptr", // Microsoft - "__uptr", // Microsoft - "dllimport", // Microsoft - "dllexport", // Microsoft - "thread", // Microsoft - "naked", // Microsoft - "microsoft_inline", // Microsoft - "forceinline", // Microsoft - "selectany", // Microsoft - "nothrow", // Microsoft - "novtable", // Microsoft - "noreturn", // Microsoft - "noinline", // Microsoft - "noalias", // Microsoft - "restrict", // Microsoft -*/ - -specifiers( - unique int id: @specifier, - unique string str: string ref -); - -typespecifiers( - int type_id: @type ref, - int spec_id: @specifier ref -); - -funspecifiers( - int func_id: @function ref, - int spec_id: @specifier ref -); - -varspecifiers( - int var_id: @accessible ref, - int spec_id: @specifier ref -); - -explicit_specifier_exprs( - unique int func_id: @function ref, - int constant: @expr ref -) - -attributes( - unique int id: @attribute, - int kind: int ref, - string name: string ref, - string name_space: string ref, - int location: @location_default ref -); - -case @attribute.kind of - 0 = @gnuattribute -| 1 = @stdattribute -| 2 = @declspec -| 3 = @msattribute -| 4 = @alignas -// ... 5 @objc_propertyattribute deprecated -; - -attribute_args( - unique int id: @attribute_arg, - int kind: int ref, - int attribute: @attribute ref, - int index: int ref, - int location: @location_default ref -); - -case @attribute_arg.kind of - 0 = @attribute_arg_empty -| 1 = @attribute_arg_token -| 2 = @attribute_arg_constant -| 3 = @attribute_arg_type -| 4 = @attribute_arg_constant_expr -| 5 = @attribute_arg_expr -; - -attribute_arg_value( - unique int arg: @attribute_arg ref, - string value: string ref -); -attribute_arg_type( - unique int arg: @attribute_arg ref, - int type_id: @type ref -); -attribute_arg_constant( - unique int arg: @attribute_arg ref, - int constant: @expr ref -) -attribute_arg_expr( - unique int arg: @attribute_arg ref, - int expr: @expr ref -) -attribute_arg_name( - unique int arg: @attribute_arg ref, - string name: string ref -); - -typeattributes( - int type_id: @type ref, - int spec_id: @attribute ref -); - -funcattributes( - int func_id: @function ref, - int spec_id: @attribute ref -); - -varattributes( - int var_id: @accessible ref, - int spec_id: @attribute ref -); - -stmtattributes( - int stmt_id: @stmt ref, - int spec_id: @attribute ref -); - -@type = @builtintype - | @derivedtype - | @usertype - /* TODO | @fixedpointtype */ - | @routinetype - | @ptrtomember - | @decltype; - -unspecifiedtype( - unique int type_id: @type ref, - int unspecified_type_id: @type ref -); - -member( - int parent: @type ref, - int index: int ref, - int child: @member ref -); - -@enclosingfunction_child = @usertype | @variable | @namespace - -enclosingfunction( - unique int child: @enclosingfunction_child ref, - int parent: @function ref -); - -derivations( - unique int derivation: @derivation, - int sub: @type ref, - int index: int ref, - int super: @type ref, - int location: @location_default ref -); - -derspecifiers( - int der_id: @derivation ref, - int spec_id: @specifier ref -); - -/** - * Contains the byte offset of the base class subobject within the derived - * class. Only holds for non-virtual base classes, but see table - * `virtual_base_offsets` for offsets of virtual base class subobjects. - */ -direct_base_offsets( - unique int der_id: @derivation ref, - int offset: int ref -); - -/** - * Contains the byte offset of the virtual base class subobject for class - * `super` within a most-derived object of class `sub`. `super` can be either a - * direct or indirect base class. - */ -#keyset[sub, super] -virtual_base_offsets( - int sub: @usertype ref, - int super: @usertype ref, - int offset: int ref -); - -frienddecls( - unique int id: @frienddecl, - int type_id: @type ref, - int decl_id: @declaration ref, - int location: @location_default ref -); - -@declaredtype = @usertype ; - -@declaration = @function - | @declaredtype - | @variable - | @enumconstant - | @frienddecl; - -@member = @membervariable - | @function - | @declaredtype - | @enumconstant; - -@locatable = @diagnostic - | @declaration - | @ppd_include - | @ppd_define - | @macroinvocation - /*| @funcall*/ - | @xmllocatable - | @attribute - | @attribute_arg; - -@namedscope = @namespace | @usertype; - -@element = @locatable - | @file - | @folder - | @specifier - | @type - | @expr - | @namespace - | @initialiser - | @stmt - | @derivation - | @comment - | @preprocdirect - | @fun_decl - | @var_decl - | @type_decl - | @namespace_decl - | @using - | @namequalifier - | @specialnamequalifyingelement - | @static_assert - | @type_mention - | @lambdacapture; - -@exprparent = @element; - -comments( - unique int id: @comment, - string contents: string ref, - int location: @location_default ref -); - -commentbinding( - int id: @comment ref, - int element: @element ref -); - -exprconv( - int converted: @expr ref, - unique int conversion: @expr ref -); - -compgenerated(unique int id: @element ref); - -/** - * `destructor_call` destructs the `i`'th entity that should be - * destructed following `element`. Note that entities should be - * destructed in reverse construction order, so for a given `element` - * these should be called from highest to lowest `i`. - */ -#keyset[element, destructor_call] -#keyset[element, i] -synthetic_destructor_call( - int element: @element ref, - int i: int ref, - int destructor_call: @routineexpr ref -); - -namespaces( - unique int id: @namespace, - string name: string ref -); - -namespace_inline( - unique int id: @namespace ref -); - -namespacembrs( - int parentid: @namespace ref, - unique int memberid: @namespacembr ref -); - -@namespacembr = @declaration | @namespace; - -exprparents( - int expr_id: @expr ref, - int child_index: int ref, - int parent_id: @exprparent ref -); - -expr_isload(unique int expr_id: @expr ref); - -@cast = @c_style_cast - | @const_cast - | @dynamic_cast - | @reinterpret_cast - | @static_cast - ; - -/* -case @conversion.kind of - 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast -| 1 = @bool_conversion // conversion to 'bool' -| 2 = @base_class_conversion // a derived-to-base conversion -| 3 = @derived_class_conversion // a base-to-derived conversion -| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member -| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member -| 6 = @glvalue_adjust // an adjustment of the type of a glvalue -| 7 = @prvalue_adjust // an adjustment of the type of a prvalue -; -*/ -/** - * Describes the semantics represented by a cast expression. This is largely - * independent of the source syntax of the cast, so it is separate from the - * regular expression kind. - */ -conversionkinds( - unique int expr_id: @cast ref, - int kind: int ref -); - -@conversion = @cast - | @array_to_pointer - | @parexpr - | @reference_to - | @ref_indirect - | @temp_init - | @c11_generic - ; - -/* -case @funbindexpr.kind of - 0 = @normal_call // a normal call -| 1 = @virtual_call // a virtual call -| 2 = @adl_call // a call whose target is only found by ADL -; -*/ -iscall( - unique int caller: @funbindexpr ref, - int kind: int ref -); - -numtemplatearguments( - unique int expr_id: @expr ref, - int num: int ref -); - -specialnamequalifyingelements( - unique int id: @specialnamequalifyingelement, - unique string name: string ref -); - -@namequalifiableelement = @expr | @namequalifier; -@namequalifyingelement = @namespace - | @specialnamequalifyingelement - | @usertype; - -namequalifiers( - unique int id: @namequalifier, - unique int qualifiableelement: @namequalifiableelement ref, - int qualifyingelement: @namequalifyingelement ref, - int location: @location_default ref -); - -varbind( - int expr: @varbindexpr ref, - int var: @accessible ref -); - -funbind( - int expr: @funbindexpr ref, - int fun: @function ref -); - -@any_new_expr = @new_expr - | @new_array_expr; - -@new_or_delete_expr = @any_new_expr - | @delete_expr - | @delete_array_expr; - -@prefix_crement_expr = @preincrexpr | @predecrexpr; - -@postfix_crement_expr = @postincrexpr | @postdecrexpr; - -@increment_expr = @preincrexpr | @postincrexpr; - -@decrement_expr = @predecrexpr | @postdecrexpr; - -@crement_expr = @increment_expr | @decrement_expr; - -@un_arith_op_expr = @arithnegexpr - | @unaryplusexpr - | @conjugation - | @realpartexpr - | @imagpartexpr - | @crement_expr - ; - -@un_bitwise_op_expr = @complementexpr; - -@un_log_op_expr = @notexpr; - -@un_op_expr = @address_of - | @indirect - | @un_arith_op_expr - | @un_bitwise_op_expr - | @builtinaddressof - | @vec_fill - | @un_log_op_expr - | @co_await - | @co_yield - ; - -@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; - -@cmp_op_expr = @eq_op_expr | @rel_op_expr; - -@eq_op_expr = @eqexpr | @neexpr; - -@rel_op_expr = @gtexpr - | @ltexpr - | @geexpr - | @leexpr - | @spaceshipexpr - ; - -@bin_bitwise_op_expr = @lshiftexpr - | @rshiftexpr - | @andexpr - | @orexpr - | @xorexpr - ; - -@p_arith_op_expr = @paddexpr - | @psubexpr - | @pdiffexpr - ; - -@bin_arith_op_expr = @addexpr - | @subexpr - | @mulexpr - | @divexpr - | @remexpr - | @jmulexpr - | @jdivexpr - | @fjaddexpr - | @jfaddexpr - | @fjsubexpr - | @jfsubexpr - | @minexpr - | @maxexpr - | @p_arith_op_expr - ; - -@bin_op_expr = @bin_arith_op_expr - | @bin_bitwise_op_expr - | @cmp_op_expr - | @bin_log_op_expr - ; - -@op_expr = @un_op_expr - | @bin_op_expr - | @assign_expr - | @conditionalexpr - ; - -@assign_arith_expr = @assignaddexpr - | @assignsubexpr - | @assignmulexpr - | @assigndivexpr - | @assignremexpr - ; - -@assign_bitwise_expr = @assignandexpr - | @assignorexpr - | @assignxorexpr - | @assignlshiftexpr - | @assignrshiftexpr - ; - -@assign_pointer_expr = @assignpaddexpr - | @assignpsubexpr - ; - -@assign_op_expr = @assign_arith_expr - | @assign_bitwise_expr - | @assign_pointer_expr - ; - -@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr - -/* - Binary encoding of the allocator form. - - case @allocator.form of - 0 = plain - | 1 = alignment - ; -*/ - -/** - * The allocator function associated with a `new` or `new[]` expression. - * The `form` column specified whether the allocation call contains an alignment - * argument. - */ -expr_allocator( - unique int expr: @any_new_expr ref, - int func: @function ref, - int form: int ref -); - -/* - Binary encoding of the deallocator form. - - case @deallocator.form of - 0 = plain - | 1 = size - | 2 = alignment - | 4 = destroying_delete - ; -*/ - -/** - * The deallocator function associated with a `delete`, `delete[]`, `new`, or - * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the - * one used to free memory if the initialization throws an exception. - * The `form` column specifies whether the deallocation call contains a size - * argument, and alignment argument, or both. - */ -expr_deallocator( - unique int expr: @new_or_delete_expr ref, - int func: @function ref, - int form: int ref -); - -/** - * Holds if the `@conditionalexpr` is of the two operand form - * `guard ? : false`. - */ -expr_cond_two_operand( - unique int cond: @conditionalexpr ref -); - -/** - * The guard of `@conditionalexpr` `guard ? true : false` - */ -expr_cond_guard( - unique int cond: @conditionalexpr ref, - int guard: @expr ref -); - -/** - * The expression used when the guard of `@conditionalexpr` - * `guard ? true : false` holds. For the two operand form - * `guard ?: false` consider using `expr_cond_guard` instead. - */ -expr_cond_true( - unique int cond: @conditionalexpr ref, - int true: @expr ref -); - -/** - * The expression used when the guard of `@conditionalexpr` - * `guard ? true : false` does not hold. - */ -expr_cond_false( - unique int cond: @conditionalexpr ref, - int false: @expr ref -); - -/** A string representation of the value. */ -values( - unique int id: @value, - string str: string ref -); - -/** The actual text in the source code for the value, if any. */ -valuetext( - unique int id: @value ref, - string text: string ref -); - -valuebind( - int val: @value ref, - unique int expr: @expr ref -); - -fieldoffsets( - unique int id: @variable ref, - int byteoffset: int ref, - int bitoffset: int ref -); - -bitfield( - unique int id: @variable ref, - int bits: int ref, - int declared_bits: int ref -); - -/* TODO -memberprefix( - int member: @expr ref, - int prefix: @expr ref -); -*/ - -/* - kind(1) = mbrcallexpr - kind(2) = mbrptrcallexpr - kind(3) = mbrptrmbrcallexpr - kind(4) = ptrmbrptrmbrcallexpr - kind(5) = mbrreadexpr // x.y - kind(6) = mbrptrreadexpr // p->y - kind(7) = mbrptrmbrreadexpr // x.*pm - kind(8) = mbrptrmbrptrreadexpr // x->*pm - kind(9) = staticmbrreadexpr // static x.y - kind(10) = staticmbrptrreadexpr // static p->y -*/ -/* TODO -memberaccess( - int member: @expr ref, - int kind: int ref -); -*/ - -initialisers( - unique int init: @initialiser, - int var: @accessible ref, - unique int expr: @expr ref, - int location: @location_expr ref -); - -braced_initialisers( - int init: @initialiser ref -); - -/** - * An ancestor for the expression, for cases in which we cannot - * otherwise find the expression's parent. - */ -expr_ancestor( - int exp: @expr ref, - int ancestor: @element ref -); - -exprs( - unique int id: @expr, - int kind: int ref, - int location: @location_expr ref -); - -expr_reuse( - int reuse: @expr ref, - int original: @expr ref, - int value_category: int ref -) - -/* - case @value.category of - 1 = prval - | 2 = xval - | 3 = lval - ; -*/ -expr_types( - int id: @expr ref, - int typeid: @type ref, - int value_category: int ref -); - -case @expr.kind of - 1 = @errorexpr -| 2 = @address_of // & AddressOfExpr -| 3 = @reference_to // ReferenceToExpr (implicit?) -| 4 = @indirect // * PointerDereferenceExpr -| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) -// ... -| 8 = @array_to_pointer // (???) -| 9 = @vacuous_destructor_call // VacuousDestructorCall -// ... -| 11 = @assume // Microsoft -| 12 = @parexpr -| 13 = @arithnegexpr -| 14 = @unaryplusexpr -| 15 = @complementexpr -| 16 = @notexpr -| 17 = @conjugation // GNU ~ operator -| 18 = @realpartexpr // GNU __real -| 19 = @imagpartexpr // GNU __imag -| 20 = @postincrexpr -| 21 = @postdecrexpr -| 22 = @preincrexpr -| 23 = @predecrexpr -| 24 = @conditionalexpr -| 25 = @addexpr -| 26 = @subexpr -| 27 = @mulexpr -| 28 = @divexpr -| 29 = @remexpr -| 30 = @jmulexpr // C99 mul imaginary -| 31 = @jdivexpr // C99 div imaginary -| 32 = @fjaddexpr // C99 add real + imaginary -| 33 = @jfaddexpr // C99 add imaginary + real -| 34 = @fjsubexpr // C99 sub real - imaginary -| 35 = @jfsubexpr // C99 sub imaginary - real -| 36 = @paddexpr // pointer add (pointer + int or int + pointer) -| 37 = @psubexpr // pointer sub (pointer - integer) -| 38 = @pdiffexpr // difference between two pointers -| 39 = @lshiftexpr -| 40 = @rshiftexpr -| 41 = @andexpr -| 42 = @orexpr -| 43 = @xorexpr -| 44 = @eqexpr -| 45 = @neexpr -| 46 = @gtexpr -| 47 = @ltexpr -| 48 = @geexpr -| 49 = @leexpr -| 50 = @minexpr // GNU minimum -| 51 = @maxexpr // GNU maximum -| 52 = @assignexpr -| 53 = @assignaddexpr -| 54 = @assignsubexpr -| 55 = @assignmulexpr -| 56 = @assigndivexpr -| 57 = @assignremexpr -| 58 = @assignlshiftexpr -| 59 = @assignrshiftexpr -| 60 = @assignandexpr -| 61 = @assignorexpr -| 62 = @assignxorexpr -| 63 = @assignpaddexpr // assign pointer add -| 64 = @assignpsubexpr // assign pointer sub -| 65 = @andlogicalexpr -| 66 = @orlogicalexpr -| 67 = @commaexpr -| 68 = @subscriptexpr // access to member of an array, e.g., a[5] -// ... 69 @objc_subscriptexpr deprecated -// ... 70 @cmdaccess deprecated -// ... -| 73 = @virtfunptrexpr -| 74 = @callexpr -// ... 75 @msgexpr_normal deprecated -// ... 76 @msgexpr_super deprecated -// ... 77 @atselectorexpr deprecated -// ... 78 @atprotocolexpr deprecated -| 79 = @vastartexpr -| 80 = @vaargexpr -| 81 = @vaendexpr -| 82 = @vacopyexpr -// ... 83 @atencodeexpr deprecated -| 84 = @varaccess -| 85 = @thisaccess -// ... 86 @objc_box_expr deprecated -| 87 = @new_expr -| 88 = @delete_expr -| 89 = @throw_expr -| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) -| 91 = @braced_init_list -| 92 = @type_id -| 93 = @runtime_sizeof -| 94 = @runtime_alignof -| 95 = @sizeof_pack -| 96 = @expr_stmt // GNU extension -| 97 = @routineexpr -| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) -| 99 = @offsetofexpr // offsetof ::= type and field -| 100 = @hasassignexpr // __has_assign ::= type -| 101 = @hascopyexpr // __has_copy ::= type -| 102 = @hasnothrowassign // __has_nothrow_assign ::= type -| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type -| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type -| 105 = @hastrivialassign // __has_trivial_assign ::= type -| 106 = @hastrivialconstr // __has_trivial_constructor ::= type -| 107 = @hastrivialcopy // __has_trivial_copy ::= type -| 108 = @hasuserdestr // __has_user_destructor ::= type -| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type -| 110 = @isabstractexpr // __is_abstract ::= type -| 111 = @isbaseofexpr // __is_base_of ::= type type -| 112 = @isclassexpr // __is_class ::= type -| 113 = @isconvtoexpr // __is_convertible_to ::= type type -| 114 = @isemptyexpr // __is_empty ::= type -| 115 = @isenumexpr // __is_enum ::= type -| 116 = @ispodexpr // __is_pod ::= type -| 117 = @ispolyexpr // __is_polymorphic ::= type -| 118 = @isunionexpr // __is_union ::= type -| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type -| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof -// ... -| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type -| 123 = @literal -| 124 = @uuidof -| 127 = @aggregateliteral -| 128 = @delete_array_expr -| 129 = @new_array_expr -// ... 130 @objc_array_literal deprecated -// ... 131 @objc_dictionary_literal deprecated -| 132 = @foldexpr -// ... -| 200 = @ctordirectinit -| 201 = @ctorvirtualinit -| 202 = @ctorfieldinit -| 203 = @ctordelegatinginit -| 204 = @dtordirectdestruct -| 205 = @dtorvirtualdestruct -| 206 = @dtorfielddestruct -// ... -| 210 = @static_cast -| 211 = @reinterpret_cast -| 212 = @const_cast -| 213 = @dynamic_cast -| 214 = @c_style_cast -| 215 = @lambdaexpr -| 216 = @param_ref -| 217 = @noopexpr -// ... -| 294 = @istriviallyconstructibleexpr -| 295 = @isdestructibleexpr -| 296 = @isnothrowdestructibleexpr -| 297 = @istriviallydestructibleexpr -| 298 = @istriviallyassignableexpr -| 299 = @isnothrowassignableexpr -| 300 = @istrivialexpr -| 301 = @isstandardlayoutexpr -| 302 = @istriviallycopyableexpr -| 303 = @isliteraltypeexpr -| 304 = @hastrivialmoveconstructorexpr -| 305 = @hastrivialmoveassignexpr -| 306 = @hasnothrowmoveassignexpr -| 307 = @isconstructibleexpr -| 308 = @isnothrowconstructibleexpr -| 309 = @hasfinalizerexpr -| 310 = @isdelegateexpr -| 311 = @isinterfaceclassexpr -| 312 = @isrefarrayexpr -| 313 = @isrefclassexpr -| 314 = @issealedexpr -| 315 = @issimplevalueclassexpr -| 316 = @isvalueclassexpr -| 317 = @isfinalexpr -| 319 = @noexceptexpr -| 320 = @builtinshufflevector -| 321 = @builtinchooseexpr -| 322 = @builtinaddressof -| 323 = @vec_fill -| 324 = @builtinconvertvector -| 325 = @builtincomplex -| 326 = @spaceshipexpr -| 327 = @co_await -| 328 = @co_yield -| 329 = @temp_init -| 330 = @isassignable -| 331 = @isaggregate -| 332 = @hasuniqueobjectrepresentations -| 333 = @builtinbitcast -| 334 = @builtinshuffle -| 335 = @blockassignexpr -| 336 = @issame -| 337 = @isfunction -| 338 = @islayoutcompatible -| 339 = @ispointerinterconvertiblebaseof -| 340 = @isarray -| 341 = @arrayrank -| 342 = @arrayextent -| 343 = @isarithmetic -| 344 = @iscompletetype -| 345 = @iscompound -| 346 = @isconst -| 347 = @isfloatingpoint -| 348 = @isfundamental -| 349 = @isintegral -| 350 = @islvaluereference -| 351 = @ismemberfunctionpointer -| 352 = @ismemberobjectpointer -| 353 = @ismemberpointer -| 354 = @isobject -| 355 = @ispointer -| 356 = @isreference -| 357 = @isrvaluereference -| 358 = @isscalar -| 359 = @issigned -| 360 = @isunsigned -| 361 = @isvoid -| 362 = @isvolatile -| 363 = @reuseexpr -| 364 = @istriviallycopyassignable -| 365 = @isassignablenopreconditioncheck -| 366 = @referencebindstotemporary -| 367 = @issameas -| 368 = @builtinhasattribute -| 369 = @ispointerinterconvertiblewithclass -| 370 = @builtinispointerinterconvertiblewithclass -| 371 = @iscorrespondingmember -| 372 = @builtiniscorrespondingmember -| 373 = @isboundedarray -| 374 = @isunboundedarray -| 375 = @isreferenceable -| 378 = @isnothrowconvertible -| 379 = @referenceconstructsfromtemporary -| 380 = @referenceconvertsfromtemporary -| 381 = @isconvertible -| 382 = @isvalidwinrttype -| 383 = @iswinclass -| 384 = @iswininterface -| 385 = @istriviallyequalitycomparable -| 386 = @isscopedenum -| 387 = @istriviallyrelocatable -| 388 = @datasizeof -| 389 = @c11_generic -| 390 = @requires_expr -| 391 = @nested_requirement -| 392 = @compound_requirement -| 393 = @concept_id -; - -@var_args_expr = @vastartexpr - | @vaendexpr - | @vaargexpr - | @vacopyexpr - ; - -@builtin_op = @var_args_expr - | @noopexpr - | @offsetofexpr - | @intaddrexpr - | @hasassignexpr - | @hascopyexpr - | @hasnothrowassign - | @hasnothrowconstr - | @hasnothrowcopy - | @hastrivialassign - | @hastrivialconstr - | @hastrivialcopy - | @hastrivialdestructor - | @hasuserdestr - | @hasvirtualdestr - | @isabstractexpr - | @isbaseofexpr - | @isclassexpr - | @isconvtoexpr - | @isemptyexpr - | @isenumexpr - | @ispodexpr - | @ispolyexpr - | @isunionexpr - | @typescompexpr - | @builtinshufflevector - | @builtinconvertvector - | @builtinaddressof - | @istriviallyconstructibleexpr - | @isdestructibleexpr - | @isnothrowdestructibleexpr - | @istriviallydestructibleexpr - | @istriviallyassignableexpr - | @isnothrowassignableexpr - | @istrivialexpr - | @isstandardlayoutexpr - | @istriviallycopyableexpr - | @isliteraltypeexpr - | @hastrivialmoveconstructorexpr - | @hastrivialmoveassignexpr - | @hasnothrowmoveassignexpr - | @isconstructibleexpr - | @isnothrowconstructibleexpr - | @hasfinalizerexpr - | @isdelegateexpr - | @isinterfaceclassexpr - | @isrefarrayexpr - | @isrefclassexpr - | @issealedexpr - | @issimplevalueclassexpr - | @isvalueclassexpr - | @isfinalexpr - | @builtinchooseexpr - | @builtincomplex - | @isassignable - | @isaggregate - | @hasuniqueobjectrepresentations - | @builtinbitcast - | @builtinshuffle - | @issame - | @isfunction - | @islayoutcompatible - | @ispointerinterconvertiblebaseof - | @isarray - | @arrayrank - | @arrayextent - | @isarithmetic - | @iscompletetype - | @iscompound - | @isconst - | @isfloatingpoint - | @isfundamental - | @isintegral - | @islvaluereference - | @ismemberfunctionpointer - | @ismemberobjectpointer - | @ismemberpointer - | @isobject - | @ispointer - | @isreference - | @isrvaluereference - | @isscalar - | @issigned - | @isunsigned - | @isvoid - | @isvolatile - | @istriviallycopyassignable - | @isassignablenopreconditioncheck - | @referencebindstotemporary - | @issameas - | @builtinhasattribute - | @ispointerinterconvertiblewithclass - | @builtinispointerinterconvertiblewithclass - | @iscorrespondingmember - | @builtiniscorrespondingmember - | @isboundedarray - | @isunboundedarray - | @isreferenceable - | @isnothrowconvertible - | @referenceconstructsfromtemporary - | @referenceconvertsfromtemporary - | @isconvertible - | @isvalidwinrttype - | @iswinclass - | @iswininterface - | @istriviallyequalitycomparable - | @isscopedenum - | @istriviallyrelocatable - ; - -compound_requirement_is_noexcept( - int expr: @compound_requirement ref -); - -new_allocated_type( - unique int expr: @new_expr ref, - int type_id: @type ref -); - -new_array_allocated_type( - unique int expr: @new_array_expr ref, - int type_id: @type ref -); - -/** - * The field being initialized by an initializer expression within an aggregate - * initializer for a class/struct/union. Position is used to sort repeated initializers. - */ -#keyset[aggregate, position] -aggregate_field_init( - int aggregate: @aggregateliteral ref, - int initializer: @expr ref, - int field: @membervariable ref, - int position: int ref -); - -/** - * The index of the element being initialized by an initializer expression - * within an aggregate initializer for an array. Position is used to sort repeated initializers. - */ -#keyset[aggregate, position] -aggregate_array_init( - int aggregate: @aggregateliteral ref, - int initializer: @expr ref, - int element_index: int ref, - int position: int ref -); - -@ctorinit = @ctordirectinit - | @ctorvirtualinit - | @ctorfieldinit - | @ctordelegatinginit; -@dtordestruct = @dtordirectdestruct - | @dtorvirtualdestruct - | @dtorfielddestruct; - - -condition_decl_bind( - unique int expr: @condition_decl ref, - unique int decl: @declaration ref -); - -typeid_bind( - unique int expr: @type_id ref, - int type_id: @type ref -); - -uuidof_bind( - unique int expr: @uuidof ref, - int type_id: @type ref -); - -@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; - -sizeof_bind( - unique int expr: @runtime_sizeof_or_alignof ref, - int type_id: @type ref -); - -code_block( - unique int block: @literal ref, - unique int routine: @function ref -); - -lambdas( - unique int expr: @lambdaexpr ref, - string default_capture: string ref, - boolean has_explicit_return_type: boolean ref -); - -lambda_capture( - unique int id: @lambdacapture, - int lambda: @lambdaexpr ref, - int index: int ref, - int field: @membervariable ref, - boolean captured_by_reference: boolean ref, - boolean is_implicit: boolean ref, - int location: @location_default ref -); - -@funbindexpr = @routineexpr - | @new_expr - | @delete_expr - | @delete_array_expr - | @ctordirectinit - | @ctorvirtualinit - | @ctordelegatinginit - | @dtordirectdestruct - | @dtorvirtualdestruct; - -@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; -@addressable = @function | @variable ; -@accessible = @addressable | @enumconstant ; - -@access = @varaccess | @routineexpr ; - -fold( - int expr: @foldexpr ref, - string operator: string ref, - boolean is_left_fold: boolean ref -); - -stmts( - unique int id: @stmt, - int kind: int ref, - int location: @location_stmt ref -); - -case @stmt.kind of - 1 = @stmt_expr -| 2 = @stmt_if -| 3 = @stmt_while -| 4 = @stmt_goto -| 5 = @stmt_label -| 6 = @stmt_return -| 7 = @stmt_block -| 8 = @stmt_end_test_while // do { ... } while ( ... ) -| 9 = @stmt_for -| 10 = @stmt_switch_case -| 11 = @stmt_switch -| 13 = @stmt_asm // "asm" statement or the body of an asm function -| 15 = @stmt_try_block -| 16 = @stmt_microsoft_try // Microsoft -| 17 = @stmt_decl -| 18 = @stmt_set_vla_size // C99 -| 19 = @stmt_vla_decl // C99 -| 25 = @stmt_assigned_goto // GNU -| 26 = @stmt_empty -| 27 = @stmt_continue -| 28 = @stmt_break -| 29 = @stmt_range_based_for // C++11 -// ... 30 @stmt_at_autoreleasepool_block deprecated -// ... 31 @stmt_objc_for_in deprecated -// ... 32 @stmt_at_synchronized deprecated -| 33 = @stmt_handler -// ... 34 @stmt_finally_end deprecated -| 35 = @stmt_constexpr_if -| 37 = @stmt_co_return -; - -type_vla( - int type_id: @type ref, - int decl: @stmt_vla_decl ref -); - -variable_vla( - int var: @variable ref, - int decl: @stmt_vla_decl ref -); - -if_initialization( - unique int if_stmt: @stmt_if ref, - int init_id: @stmt ref -); - -if_then( - unique int if_stmt: @stmt_if ref, - int then_id: @stmt ref -); - -if_else( - unique int if_stmt: @stmt_if ref, - int else_id: @stmt ref -); - -constexpr_if_initialization( - unique int constexpr_if_stmt: @stmt_constexpr_if ref, - int init_id: @stmt ref -); - -constexpr_if_then( - unique int constexpr_if_stmt: @stmt_constexpr_if ref, - int then_id: @stmt ref -); - -constexpr_if_else( - unique int constexpr_if_stmt: @stmt_constexpr_if ref, - int else_id: @stmt ref -); - -while_body( - unique int while_stmt: @stmt_while ref, - int body_id: @stmt ref -); - -do_body( - unique int do_stmt: @stmt_end_test_while ref, - int body_id: @stmt ref -); - -switch_initialization( - unique int switch_stmt: @stmt_switch ref, - int init_id: @stmt ref -); - -#keyset[switch_stmt, index] -switch_case( - int switch_stmt: @stmt_switch ref, - int index: int ref, - int case_id: @stmt_switch_case ref -); - -switch_body( - unique int switch_stmt: @stmt_switch ref, - int body_id: @stmt ref -); - -@stmt_for_or_range_based_for = @stmt_for - | @stmt_range_based_for; - -for_initialization( - unique int for_stmt: @stmt_for_or_range_based_for ref, - int init_id: @stmt ref -); - -for_condition( - unique int for_stmt: @stmt_for ref, - int condition_id: @expr ref -); - -for_update( - unique int for_stmt: @stmt_for ref, - int update_id: @expr ref -); - -for_body( - unique int for_stmt: @stmt_for ref, - int body_id: @stmt ref -); - -@stmtparent = @stmt | @expr_stmt ; -stmtparents( - unique int id: @stmt ref, - int index: int ref, - int parent: @stmtparent ref -); - -ishandler(unique int block: @stmt_block ref); - -@cfgnode = @stmt | @expr | @function | @initialiser ; - -stmt_decl_bind( - int stmt: @stmt_decl ref, - int num: int ref, - int decl: @declaration ref -); - -stmt_decl_entry_bind( - int stmt: @stmt_decl ref, - int num: int ref, - int decl_entry: @element ref -); - -@parameterized_element = @function | @stmt_block | @requires_expr; - -blockscope( - unique int block: @stmt_block ref, - int enclosing: @parameterized_element ref -); - -@jump = @stmt_goto | @stmt_break | @stmt_continue; - -@jumporlabel = @jump | @stmt_label | @literal; - -jumpinfo( - unique int id: @jumporlabel ref, - string str: string ref, - int target: @stmt ref -); - -preprocdirects( - unique int id: @preprocdirect, - int kind: int ref, - int location: @location_default ref -); -case @preprocdirect.kind of - 0 = @ppd_if -| 1 = @ppd_ifdef -| 2 = @ppd_ifndef -| 3 = @ppd_elif -| 4 = @ppd_else -| 5 = @ppd_endif -| 6 = @ppd_plain_include -| 7 = @ppd_define -| 8 = @ppd_undef -| 9 = @ppd_line -| 10 = @ppd_error -| 11 = @ppd_pragma -| 12 = @ppd_objc_import -| 13 = @ppd_include_next -| 18 = @ppd_warning -; - -@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; - -@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; - -preprocpair( - int begin : @ppd_branch ref, - int elseelifend : @preprocdirect ref -); - -preproctrue(int branch : @ppd_branch ref); -preprocfalse(int branch : @ppd_branch ref); - -preproctext( - unique int id: @preprocdirect ref, - string head: string ref, - string body: string ref -); - -includes( - unique int id: @ppd_include ref, - int included: @file ref -); - -link_targets( - int id: @link_target, - int binary: @file ref -); - -link_parent( - int element : @element ref, - int link_target : @link_target ref -); - -/* XML Files */ - -xmlEncoding(unique int id: @file ref, string encoding: string ref); - -xmlDTDs( - unique int id: @xmldtd, - string root: string ref, - string publicId: string ref, - string systemId: string ref, - int fileid: @file ref -); - -xmlElements( - unique int id: @xmlelement, - string name: string ref, - int parentid: @xmlparent ref, - int idx: int ref, - int fileid: @file ref -); - -xmlAttrs( - unique int id: @xmlattribute, - int elementid: @xmlelement ref, - string name: string ref, - string value: string ref, - int idx: int ref, - int fileid: @file ref -); - -xmlNs( - int id: @xmlnamespace, - string prefixName: string ref, - string URI: string ref, - int fileid: @file ref -); - -xmlHasNs( - int elementId: @xmlnamespaceable ref, - int nsId: @xmlnamespace ref, - int fileid: @file ref -); - -xmlComments( - unique int id: @xmlcomment, - string text: string ref, - int parentid: @xmlparent ref, - int fileid: @file ref -); - -xmlChars( - unique int id: @xmlcharacters, - string text: string ref, - int parentid: @xmlparent ref, - int idx: int ref, - int isCDATA: int ref, - int fileid: @file ref -); - -@xmlparent = @file | @xmlelement; -@xmlnamespaceable = @xmlelement | @xmlattribute; - -xmllocations( - int xmlElement: @xmllocatable ref, - int location: @location_default ref -); - -@xmllocatable = @xmlcharacters - | @xmlelement - | @xmlcomment - | @xmlattribute - | @xmldtd - | @file - | @xmlnamespace; diff --git a/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/semmlecode.cpp.dbscheme deleted file mode 100644 index f0156f5f88a..00000000000 --- a/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/semmlecode.cpp.dbscheme +++ /dev/null @@ -1,2339 +0,0 @@ - -/** - * An invocation of the compiler. Note that more than one file may be - * compiled per invocation. For example, this command compiles three - * source files: - * - * gcc -c f1.c f2.c f3.c - * - * The `id` simply identifies the invocation, while `cwd` is the working - * directory from which the compiler was invoked. - */ -compilations( - /** - * An invocation of the compiler. Note that more than one file may - * be compiled per invocation. For example, this command compiles - * three source files: - * - * gcc -c f1.c f2.c f3.c - */ - unique int id : @compilation, - string cwd : string ref -); - -/** - * The arguments that were passed to the extractor for a compiler - * invocation. If `id` is for the compiler invocation - * - * gcc -c f1.c f2.c f3.c - * - * then typically there will be rows for - * - * num | arg - * --- | --- - * 0 | *path to extractor* - * 1 | `--mimic` - * 2 | `/usr/bin/gcc` - * 3 | `-c` - * 4 | f1.c - * 5 | f2.c - * 6 | f3.c - */ -#keyset[id, num] -compilation_args( - int id : @compilation ref, - int num : int ref, - string arg : string ref -); - -/** - * Optionally, record the build mode for each compilation. - */ -compilation_build_mode( - unique int id : @compilation ref, - int mode : int ref -); - -/* -case @compilation_build_mode.mode of - 0 = @build_mode_none -| 1 = @build_mode_manual -| 2 = @build_mode_auto -; -*/ - -/** - * The source files that are compiled by a compiler invocation. - * If `id` is for the compiler invocation - * - * gcc -c f1.c f2.c f3.c - * - * then there will be rows for - * - * num | arg - * --- | --- - * 0 | f1.c - * 1 | f2.c - * 2 | f3.c - * - * Note that even if those files `#include` headers, those headers - * do not appear as rows. - */ -#keyset[id, num] -compilation_compiling_files( - int id : @compilation ref, - int num : int ref, - int file : @file ref -); - -/** - * The time taken by the extractor for a compiler invocation. - * - * For each file `num`, there will be rows for - * - * kind | seconds - * ---- | --- - * 1 | CPU seconds used by the extractor frontend - * 2 | Elapsed seconds during the extractor frontend - * 3 | CPU seconds used by the extractor backend - * 4 | Elapsed seconds during the extractor backend - */ -#keyset[id, num, kind] -compilation_time( - int id : @compilation ref, - int num : int ref, - /* kind: - 1 = frontend_cpu_seconds - 2 = frontend_elapsed_seconds - 3 = extractor_cpu_seconds - 4 = extractor_elapsed_seconds - */ - int kind : int ref, - float seconds : float ref -); - -/** - * An error or warning generated by the extractor. - * The diagnostic message `diagnostic` was generated during compiler - * invocation `compilation`, and is the `file_number_diagnostic_number`th - * message generated while extracting the `file_number`th file of that - * invocation. - */ -#keyset[compilation, file_number, file_number_diagnostic_number] -diagnostic_for( - int diagnostic : @diagnostic ref, - int compilation : @compilation ref, - int file_number : int ref, - int file_number_diagnostic_number : int ref -); - -/** - * If extraction was successful, then `cpu_seconds` and - * `elapsed_seconds` are the CPU time and elapsed time (respectively) - * that extraction took for compiler invocation `id`. - */ -compilation_finished( - unique int id : @compilation ref, - float cpu_seconds : float ref, - float elapsed_seconds : float ref -); - - -/** - * External data, loaded from CSV files during snapshot creation. See - * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) - * for more information. - */ -externalData( - int id : @externalDataElement, - string path : string ref, - int column: int ref, - string value : string ref -); - -/** - * The source location of the snapshot. - */ -sourceLocationPrefix(string prefix : string ref); - -/** - * Information about packages that provide code used during compilation. - * The `id` is just a unique identifier. - * The `namespace` is typically the name of the package manager that - * provided the package (e.g. "dpkg" or "yum"). - * The `package_name` is the name of the package, and `version` is its - * version (as a string). - */ -external_packages( - unique int id: @external_package, - string namespace : string ref, - string package_name : string ref, - string version : string ref -); - -/** - * Holds if File `fileid` was provided by package `package`. - */ -header_to_external_package( - int fileid : @file ref, - int package : @external_package ref -); - -/* - * Version history - */ - -svnentries( - unique int id : @svnentry, - string revision : string ref, - string author : string ref, - date revisionDate : date ref, - int changeSize : int ref -) - -svnaffectedfiles( - int id : @svnentry ref, - int file : @file ref, - string action : string ref -) - -svnentrymsg( - unique int id : @svnentry ref, - string message : string ref -) - -svnchurn( - int commit : @svnentry ref, - int file : @file ref, - int addedLines : int ref, - int deletedLines : int ref -) - -/* - * C++ dbscheme - */ - -extractor_version( - string codeql_version: string ref, - string frontend_version: string ref -) - -@location = @location_stmt | @location_expr | @location_default ; - -/** - * The location of an element that is not an expression or a statement. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `file`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ -locations_default( - /** The location of an element that is not an expression or a statement. */ - unique int id: @location_default, - int container: @container ref, - int startLine: int ref, - int startColumn: int ref, - int endLine: int ref, - int endColumn: int ref -); - -/** - * The location of a statement. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `file`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ -locations_stmt( - /** The location of a statement. */ - unique int id: @location_stmt, - int container: @container ref, - int startLine: int ref, - int startColumn: int ref, - int endLine: int ref, - int endColumn: int ref -); - -/** - * The location of an expression. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `file`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ -locations_expr( - /** The location of an expression. */ - unique int id: @location_expr, - int container: @container ref, - int startLine: int ref, - int startColumn: int ref, - int endLine: int ref, - int endColumn: int ref -); - -/** An element for which line-count information is available. */ -@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; - -numlines( - int element_id: @sourceline ref, - int num_lines: int ref, - int num_code: int ref, - int num_comment: int ref -); - -diagnostics( - unique int id: @diagnostic, - int severity: int ref, - string error_tag: string ref, - string error_message: string ref, - string full_error_message: string ref, - int location: @location_default ref -); - -files( - unique int id: @file, - string name: string ref -); - -folders( - unique int id: @folder, - string name: string ref -); - -@container = @folder | @file - -containerparent( - int parent: @container ref, - unique int child: @container ref -); - -fileannotations( - int id: @file ref, - int kind: int ref, - string name: string ref, - string value: string ref -); - -inmacroexpansion( - int id: @element ref, - int inv: @macroinvocation ref -); - -affectedbymacroexpansion( - int id: @element ref, - int inv: @macroinvocation ref -); - -case @macroinvocation.kind of - 1 = @macro_expansion -| 2 = @other_macro_reference -; - -macroinvocations( - unique int id: @macroinvocation, - int macro_id: @ppd_define ref, - int location: @location_default ref, - int kind: int ref -); - -macroparent( - unique int id: @macroinvocation ref, - int parent_id: @macroinvocation ref -); - -// a macroinvocation may be part of another location -// the way to find a constant expression that uses a macro -// is thus to find a constant expression that has a location -// to which a macro invocation is bound -macrolocationbind( - int id: @macroinvocation ref, - int location: @location ref -); - -#keyset[invocation, argument_index] -macro_argument_unexpanded( - int invocation: @macroinvocation ref, - int argument_index: int ref, - string text: string ref -); - -#keyset[invocation, argument_index] -macro_argument_expanded( - int invocation: @macroinvocation ref, - int argument_index: int ref, - string text: string ref -); - -/* -case @function.kind of - 1 = @normal_function -| 2 = @constructor -| 3 = @destructor -| 4 = @conversion_function -| 5 = @operator -| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk -| 7 = @user_defined_literal -| 8 = @deduction_guide -; -*/ - -functions( - unique int id: @function, - string name: string ref, - int kind: int ref -); - -function_entry_point( - int id: @function ref, - unique int entry_point: @stmt ref -); - -function_return_type( - int id: @function ref, - int return_type: @type ref -); - -/** - * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` - * instance associated with it, and the variables representing the `handle` and `promise` - * for it. - */ -coroutine( - unique int function: @function ref, - int traits: @type ref -); - -/* -case @coroutine_placeholder_variable.kind of - 1 = @handle -| 2 = @promise -| 3 = @init_await_resume -; -*/ - -coroutine_placeholder_variable( - unique int placeholder_variable: @variable ref, - int kind: int ref, - int function: @function ref -) - -/** The `new` function used for allocating the coroutine state, if any. */ -coroutine_new( - unique int function: @function ref, - int new: @function ref -); - -/** The `delete` function used for deallocating the coroutine state, if any. */ -coroutine_delete( - unique int function: @function ref, - int delete: @function ref -); - -purefunctions(unique int id: @function ref); - -function_deleted(unique int id: @function ref); - -function_defaulted(unique int id: @function ref); - -function_prototyped(unique int id: @function ref) - -deduction_guide_for_class( - int id: @function ref, - int class_template: @usertype ref -) - -member_function_this_type( - unique int id: @function ref, - int this_type: @type ref -); - -#keyset[id, type_id] -fun_decls( - int id: @fun_decl, - int function: @function ref, - int type_id: @type ref, - string name: string ref, - int location: @location_default ref -); -fun_def(unique int id: @fun_decl ref); -fun_specialized(unique int id: @fun_decl ref); -fun_implicit(unique int id: @fun_decl ref); -fun_decl_specifiers( - int id: @fun_decl ref, - string name: string ref -) -#keyset[fun_decl, index] -fun_decl_throws( - int fun_decl: @fun_decl ref, - int index: int ref, - int type_id: @type ref -); -/* an empty throw specification is different from none */ -fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); -fun_decl_noexcept( - int fun_decl: @fun_decl ref, - int constant: @expr ref -); -fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); -fun_decl_typedef_type( - unique int fun_decl: @fun_decl ref, - int typedeftype_id: @usertype ref -); - -param_decl_bind( - unique int id: @var_decl ref, - int index: int ref, - int fun_decl: @fun_decl ref -); - -#keyset[id, type_id] -var_decls( - int id: @var_decl, - int variable: @variable ref, - int type_id: @type ref, - string name: string ref, - int location: @location_default ref -); -var_def(unique int id: @var_decl ref); -var_decl_specifiers( - int id: @var_decl ref, - string name: string ref -) -is_structured_binding(unique int id: @variable ref); - -type_decls( - unique int id: @type_decl, - int type_id: @type ref, - int location: @location_default ref -); -type_def(unique int id: @type_decl ref); -type_decl_top( - unique int type_decl: @type_decl ref -); - -namespace_decls( - unique int id: @namespace_decl, - int namespace_id: @namespace ref, - int location: @location_default ref, - int bodylocation: @location_default ref -); - -case @using.kind of - 1 = @using_declaration -| 2 = @using_directive -| 3 = @using_enum_declaration -; - -usings( - unique int id: @using, - int element_id: @element ref, - int location: @location_default ref, - int kind: int ref -); - -/** The element which contains the `using` declaration. */ -using_container( - int parent: @element ref, - int child: @using ref -); - -static_asserts( - unique int id: @static_assert, - int condition : @expr ref, - string message : string ref, - int location: @location_default ref, - int enclosing : @element ref -); - -// each function has an ordered list of parameters -#keyset[id, type_id] -#keyset[function, index, type_id] -params( - int id: @parameter, - int function: @parameterized_element ref, - int index: int ref, - int type_id: @type ref -); - -overrides( - int new: @function ref, - int old: @function ref -); - -#keyset[id, type_id] -membervariables( - int id: @membervariable, - int type_id: @type ref, - string name: string ref -); - -#keyset[id, type_id] -globalvariables( - int id: @globalvariable, - int type_id: @type ref, - string name: string ref -); - -#keyset[id, type_id] -localvariables( - int id: @localvariable, - int type_id: @type ref, - string name: string ref -); - -autoderivation( - unique int var: @variable ref, - int derivation_type: @type ref -); - -orphaned_variables( - int var: @localvariable ref, - int function: @function ref -) - -enumconstants( - unique int id: @enumconstant, - int parent: @usertype ref, - int index: int ref, - int type_id: @type ref, - string name: string ref, - int location: @location_default ref -); - -@variable = @localscopevariable | @globalvariable | @membervariable; - -@localscopevariable = @localvariable | @parameter; - -/** - * Built-in types are the fundamental types, e.g., integral, floating, and void. - */ -case @builtintype.kind of - 1 = @errortype -| 2 = @unknowntype -| 3 = @void -| 4 = @boolean -| 5 = @char -| 6 = @unsigned_char -| 7 = @signed_char -| 8 = @short -| 9 = @unsigned_short -| 10 = @signed_short -| 11 = @int -| 12 = @unsigned_int -| 13 = @signed_int -| 14 = @long -| 15 = @unsigned_long -| 16 = @signed_long -| 17 = @long_long -| 18 = @unsigned_long_long -| 19 = @signed_long_long -// ... 20 Microsoft-specific __int8 -// ... 21 Microsoft-specific __int16 -// ... 22 Microsoft-specific __int32 -// ... 23 Microsoft-specific __int64 -| 24 = @float -| 25 = @double -| 26 = @long_double -| 27 = @complex_float // C99-specific _Complex float -| 28 = @complex_double // C99-specific _Complex double -| 29 = @complex_long_double // C99-specific _Complex long double -| 30 = @imaginary_float // C99-specific _Imaginary float -| 31 = @imaginary_double // C99-specific _Imaginary double -| 32 = @imaginary_long_double // C99-specific _Imaginary long double -| 33 = @wchar_t // Microsoft-specific -| 34 = @decltype_nullptr // C++11 -| 35 = @int128 // __int128 -| 36 = @unsigned_int128 // unsigned __int128 -| 37 = @signed_int128 // signed __int128 -| 38 = @float128 // __float128 -| 39 = @complex_float128 // _Complex __float128 -| 40 = @decimal32 // _Decimal32 -| 41 = @decimal64 // _Decimal64 -| 42 = @decimal128 // _Decimal128 -| 43 = @char16_t -| 44 = @char32_t -| 45 = @std_float32 // _Float32 -| 46 = @float32x // _Float32x -| 47 = @std_float64 // _Float64 -| 48 = @float64x // _Float64x -| 49 = @std_float128 // _Float128 -// ... 50 _Float128x -| 51 = @char8_t -| 52 = @float16 // _Float16 -| 53 = @complex_float16 // _Complex _Float16 -| 54 = @fp16 // __fp16 -| 55 = @std_bfloat16 // __bf16 -| 56 = @std_float16 // std::float16_t -| 57 = @complex_std_float32 // _Complex _Float32 -| 58 = @complex_float32x // _Complex _Float32x -| 59 = @complex_std_float64 // _Complex _Float64 -| 60 = @complex_float64x // _Complex _Float64x -| 61 = @complex_std_float128 // _Complex _Float128 -; - -builtintypes( - unique int id: @builtintype, - string name: string ref, - int kind: int ref, - int size: int ref, - int sign: int ref, - int alignment: int ref -); - -/** - * Derived types are types that are directly derived from existing types and - * point to, refer to, transform type data to return a new type. - */ -case @derivedtype.kind of - 1 = @pointer -| 2 = @reference -| 3 = @type_with_specifiers -| 4 = @array -| 5 = @gnu_vector -| 6 = @routineptr -| 7 = @routinereference -| 8 = @rvalue_reference // C++11 -// ... 9 type_conforming_to_protocols deprecated -| 10 = @block -; - -derivedtypes( - unique int id: @derivedtype, - string name: string ref, - int kind: int ref, - int type_id: @type ref -); - -pointerishsize(unique int id: @derivedtype ref, - int size: int ref, - int alignment: int ref); - -arraysizes( - unique int id: @derivedtype ref, - int num_elements: int ref, - int bytesize: int ref, - int alignment: int ref -); - -typedefbase( - unique int id: @usertype ref, - int type_id: @type ref -); - -/** - * An instance of the C++11 `decltype` operator. For example: - * ``` - * int a; - * decltype(1+a) b; - * ``` - * Here `expr` is `1+a`. - * - * Sometimes an additional pair of parentheses around the expression - * would change the semantics of this decltype, e.g. - * ``` - * struct A { double x; }; - * const A* a = new A(); - * decltype( a->x ); // type is double - * decltype((a->x)); // type is const double& - * ``` - * (Please consult the C++11 standard for more details). - * `parentheses_would_change_meaning` is `true` iff that is the case. - */ -#keyset[id, expr] -decltypes( - int id: @decltype, - int expr: @expr ref, - int base_type: @type ref, - boolean parentheses_would_change_meaning: boolean ref -); - -/* -case @usertype.kind of - 1 = @struct -| 2 = @class -| 3 = @union -| 4 = @enum -| 5 = @typedef // classic C: typedef typedef type name -| 6 = @template -| 7 = @template_parameter -| 8 = @template_template_parameter -| 9 = @proxy_class // a proxy class associated with a template parameter -// ... 10 objc_class deprecated -// ... 11 objc_protocol deprecated -// ... 12 objc_category deprecated -| 13 = @scoped_enum -| 14 = @using_alias // a using name = type style typedef -; -*/ - -usertypes( - unique int id: @usertype, - string name: string ref, - int kind: int ref -); - -usertypesize( - unique int id: @usertype ref, - int size: int ref, - int alignment: int ref -); - -usertype_final(unique int id: @usertype ref); - -usertype_uuid( - unique int id: @usertype ref, - string uuid: string ref -); - -mangled_name( - unique int id: @declaration ref, - int mangled_name : @mangledname, - boolean is_complete: boolean ref -); - -is_pod_class(unique int id: @usertype ref); -is_standard_layout_class(unique int id: @usertype ref); - -is_complete(unique int id: @usertype ref); - -is_class_template(unique int id: @usertype ref); -class_instantiation( - int to: @usertype ref, - int from: @usertype ref -); -class_template_argument( - int type_id: @usertype ref, - int index: int ref, - int arg_type: @type ref -); -class_template_argument_value( - int type_id: @usertype ref, - int index: int ref, - int arg_value: @expr ref -); - -is_proxy_class_for( - unique int id: @usertype ref, - unique int templ_param_id: @usertype ref -); - -type_mentions( - unique int id: @type_mention, - int type_id: @type ref, - int location: @location ref, - // a_symbol_reference_kind from the frontend. - int kind: int ref -); - -is_function_template(unique int id: @function ref); -function_instantiation( - unique int to: @function ref, - int from: @function ref -); -function_template_argument( - int function_id: @function ref, - int index: int ref, - int arg_type: @type ref -); -function_template_argument_value( - int function_id: @function ref, - int index: int ref, - int arg_value: @expr ref -); - -is_variable_template(unique int id: @variable ref); -variable_instantiation( - unique int to: @variable ref, - int from: @variable ref -); -variable_template_argument( - int variable_id: @variable ref, - int index: int ref, - int arg_type: @type ref -); -variable_template_argument_value( - int variable_id: @variable ref, - int index: int ref, - int arg_value: @expr ref -); - -routinetypes( - unique int id: @routinetype, - int return_type: @type ref -); - -routinetypeargs( - int routine: @routinetype ref, - int index: int ref, - int type_id: @type ref -); - -ptrtomembers( - unique int id: @ptrtomember, - int type_id: @type ref, - int class_id: @type ref -); - -/* - specifiers for types, functions, and variables - - "public", - "protected", - "private", - - "const", - "volatile", - "static", - - "pure", - "virtual", - "sealed", // Microsoft - "__interface", // Microsoft - "inline", - "explicit", - - "near", // near far extension - "far", // near far extension - "__ptr32", // Microsoft - "__ptr64", // Microsoft - "__sptr", // Microsoft - "__uptr", // Microsoft - "dllimport", // Microsoft - "dllexport", // Microsoft - "thread", // Microsoft - "naked", // Microsoft - "microsoft_inline", // Microsoft - "forceinline", // Microsoft - "selectany", // Microsoft - "nothrow", // Microsoft - "novtable", // Microsoft - "noreturn", // Microsoft - "noinline", // Microsoft - "noalias", // Microsoft - "restrict", // Microsoft -*/ - -specifiers( - unique int id: @specifier, - unique string str: string ref -); - -typespecifiers( - int type_id: @type ref, - int spec_id: @specifier ref -); - -funspecifiers( - int func_id: @function ref, - int spec_id: @specifier ref -); - -varspecifiers( - int var_id: @accessible ref, - int spec_id: @specifier ref -); - -explicit_specifier_exprs( - unique int func_id: @function ref, - int constant: @expr ref -) - -attributes( - unique int id: @attribute, - int kind: int ref, - string name: string ref, - string name_space: string ref, - int location: @location_default ref -); - -case @attribute.kind of - 0 = @gnuattribute -| 1 = @stdattribute -| 2 = @declspec -| 3 = @msattribute -| 4 = @alignas -// ... 5 @objc_propertyattribute deprecated -; - -attribute_args( - unique int id: @attribute_arg, - int kind: int ref, - int attribute: @attribute ref, - int index: int ref, - int location: @location_default ref -); - -case @attribute_arg.kind of - 0 = @attribute_arg_empty -| 1 = @attribute_arg_token -| 2 = @attribute_arg_constant -| 3 = @attribute_arg_type -| 4 = @attribute_arg_constant_expr -| 5 = @attribute_arg_expr -; - -attribute_arg_value( - unique int arg: @attribute_arg ref, - string value: string ref -); -attribute_arg_type( - unique int arg: @attribute_arg ref, - int type_id: @type ref -); -attribute_arg_constant( - unique int arg: @attribute_arg ref, - int constant: @expr ref -) -attribute_arg_expr( - unique int arg: @attribute_arg ref, - int expr: @expr ref -) -attribute_arg_name( - unique int arg: @attribute_arg ref, - string name: string ref -); - -typeattributes( - int type_id: @type ref, - int spec_id: @attribute ref -); - -funcattributes( - int func_id: @function ref, - int spec_id: @attribute ref -); - -varattributes( - int var_id: @accessible ref, - int spec_id: @attribute ref -); - -stmtattributes( - int stmt_id: @stmt ref, - int spec_id: @attribute ref -); - -@type = @builtintype - | @derivedtype - | @usertype - /* TODO | @fixedpointtype */ - | @routinetype - | @ptrtomember - | @decltype; - -unspecifiedtype( - unique int type_id: @type ref, - int unspecified_type_id: @type ref -); - -member( - int parent: @type ref, - int index: int ref, - int child: @member ref -); - -@enclosingfunction_child = @usertype | @variable | @namespace - -enclosingfunction( - unique int child: @enclosingfunction_child ref, - int parent: @function ref -); - -derivations( - unique int derivation: @derivation, - int sub: @type ref, - int index: int ref, - int super: @type ref, - int location: @location_default ref -); - -derspecifiers( - int der_id: @derivation ref, - int spec_id: @specifier ref -); - -/** - * Contains the byte offset of the base class subobject within the derived - * class. Only holds for non-virtual base classes, but see table - * `virtual_base_offsets` for offsets of virtual base class subobjects. - */ -direct_base_offsets( - unique int der_id: @derivation ref, - int offset: int ref -); - -/** - * Contains the byte offset of the virtual base class subobject for class - * `super` within a most-derived object of class `sub`. `super` can be either a - * direct or indirect base class. - */ -#keyset[sub, super] -virtual_base_offsets( - int sub: @usertype ref, - int super: @usertype ref, - int offset: int ref -); - -frienddecls( - unique int id: @frienddecl, - int type_id: @type ref, - int decl_id: @declaration ref, - int location: @location_default ref -); - -@declaredtype = @usertype ; - -@declaration = @function - | @declaredtype - | @variable - | @enumconstant - | @frienddecl; - -@member = @membervariable - | @function - | @declaredtype - | @enumconstant; - -@locatable = @diagnostic - | @declaration - | @ppd_include - | @ppd_define - | @macroinvocation - /*| @funcall*/ - | @xmllocatable - | @attribute - | @attribute_arg; - -@namedscope = @namespace | @usertype; - -@element = @locatable - | @file - | @folder - | @specifier - | @type - | @expr - | @namespace - | @initialiser - | @stmt - | @derivation - | @comment - | @preprocdirect - | @fun_decl - | @var_decl - | @type_decl - | @namespace_decl - | @using - | @namequalifier - | @specialnamequalifyingelement - | @static_assert - | @type_mention - | @lambdacapture; - -@exprparent = @element; - -comments( - unique int id: @comment, - string contents: string ref, - int location: @location_default ref -); - -commentbinding( - int id: @comment ref, - int element: @element ref -); - -exprconv( - int converted: @expr ref, - unique int conversion: @expr ref -); - -compgenerated(unique int id: @element ref); - -/** - * `destructor_call` destructs the `i`'th entity that should be - * destructed following `element`. Note that entities should be - * destructed in reverse construction order, so for a given `element` - * these should be called from highest to lowest `i`. - */ -#keyset[element, destructor_call] -#keyset[element, i] -synthetic_destructor_call( - int element: @element ref, - int i: int ref, - int destructor_call: @routineexpr ref -); - -namespaces( - unique int id: @namespace, - string name: string ref -); - -namespace_inline( - unique int id: @namespace ref -); - -namespacembrs( - int parentid: @namespace ref, - unique int memberid: @namespacembr ref -); - -@namespacembr = @declaration | @namespace; - -exprparents( - int expr_id: @expr ref, - int child_index: int ref, - int parent_id: @exprparent ref -); - -expr_isload(unique int expr_id: @expr ref); - -@cast = @c_style_cast - | @const_cast - | @dynamic_cast - | @reinterpret_cast - | @static_cast - ; - -/* -case @conversion.kind of - 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast -| 1 = @bool_conversion // conversion to 'bool' -| 2 = @base_class_conversion // a derived-to-base conversion -| 3 = @derived_class_conversion // a base-to-derived conversion -| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member -| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member -| 6 = @glvalue_adjust // an adjustment of the type of a glvalue -| 7 = @prvalue_adjust // an adjustment of the type of a prvalue -; -*/ -/** - * Describes the semantics represented by a cast expression. This is largely - * independent of the source syntax of the cast, so it is separate from the - * regular expression kind. - */ -conversionkinds( - unique int expr_id: @cast ref, - int kind: int ref -); - -@conversion = @cast - | @array_to_pointer - | @parexpr - | @reference_to - | @ref_indirect - | @temp_init - | @c11_generic - ; - -/* -case @funbindexpr.kind of - 0 = @normal_call // a normal call -| 1 = @virtual_call // a virtual call -| 2 = @adl_call // a call whose target is only found by ADL -; -*/ -iscall( - unique int caller: @funbindexpr ref, - int kind: int ref -); - -numtemplatearguments( - unique int expr_id: @expr ref, - int num: int ref -); - -specialnamequalifyingelements( - unique int id: @specialnamequalifyingelement, - unique string name: string ref -); - -@namequalifiableelement = @expr | @namequalifier; -@namequalifyingelement = @namespace - | @specialnamequalifyingelement - | @usertype; - -namequalifiers( - unique int id: @namequalifier, - unique int qualifiableelement: @namequalifiableelement ref, - int qualifyingelement: @namequalifyingelement ref, - int location: @location_default ref -); - -varbind( - int expr: @varbindexpr ref, - int var: @accessible ref -); - -funbind( - int expr: @funbindexpr ref, - int fun: @function ref -); - -@any_new_expr = @new_expr - | @new_array_expr; - -@new_or_delete_expr = @any_new_expr - | @delete_expr - | @delete_array_expr; - -@prefix_crement_expr = @preincrexpr | @predecrexpr; - -@postfix_crement_expr = @postincrexpr | @postdecrexpr; - -@increment_expr = @preincrexpr | @postincrexpr; - -@decrement_expr = @predecrexpr | @postdecrexpr; - -@crement_expr = @increment_expr | @decrement_expr; - -@un_arith_op_expr = @arithnegexpr - | @unaryplusexpr - | @conjugation - | @realpartexpr - | @imagpartexpr - | @crement_expr - ; - -@un_bitwise_op_expr = @complementexpr; - -@un_log_op_expr = @notexpr; - -@un_op_expr = @address_of - | @indirect - | @un_arith_op_expr - | @un_bitwise_op_expr - | @builtinaddressof - | @vec_fill - | @un_log_op_expr - | @co_await - | @co_yield - ; - -@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; - -@cmp_op_expr = @eq_op_expr | @rel_op_expr; - -@eq_op_expr = @eqexpr | @neexpr; - -@rel_op_expr = @gtexpr - | @ltexpr - | @geexpr - | @leexpr - | @spaceshipexpr - ; - -@bin_bitwise_op_expr = @lshiftexpr - | @rshiftexpr - | @andexpr - | @orexpr - | @xorexpr - ; - -@p_arith_op_expr = @paddexpr - | @psubexpr - | @pdiffexpr - ; - -@bin_arith_op_expr = @addexpr - | @subexpr - | @mulexpr - | @divexpr - | @remexpr - | @jmulexpr - | @jdivexpr - | @fjaddexpr - | @jfaddexpr - | @fjsubexpr - | @jfsubexpr - | @minexpr - | @maxexpr - | @p_arith_op_expr - ; - -@bin_op_expr = @bin_arith_op_expr - | @bin_bitwise_op_expr - | @cmp_op_expr - | @bin_log_op_expr - ; - -@op_expr = @un_op_expr - | @bin_op_expr - | @assign_expr - | @conditionalexpr - ; - -@assign_arith_expr = @assignaddexpr - | @assignsubexpr - | @assignmulexpr - | @assigndivexpr - | @assignremexpr - ; - -@assign_bitwise_expr = @assignandexpr - | @assignorexpr - | @assignxorexpr - | @assignlshiftexpr - | @assignrshiftexpr - ; - -@assign_pointer_expr = @assignpaddexpr - | @assignpsubexpr - ; - -@assign_op_expr = @assign_arith_expr - | @assign_bitwise_expr - | @assign_pointer_expr - ; - -@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr - -/* - Binary encoding of the allocator form. - - case @allocator.form of - 0 = plain - | 1 = alignment - ; -*/ - -/** - * The allocator function associated with a `new` or `new[]` expression. - * The `form` column specified whether the allocation call contains an alignment - * argument. - */ -expr_allocator( - unique int expr: @any_new_expr ref, - int func: @function ref, - int form: int ref -); - -/* - Binary encoding of the deallocator form. - - case @deallocator.form of - 0 = plain - | 1 = size - | 2 = alignment - | 4 = destroying_delete - ; -*/ - -/** - * The deallocator function associated with a `delete`, `delete[]`, `new`, or - * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the - * one used to free memory if the initialization throws an exception. - * The `form` column specifies whether the deallocation call contains a size - * argument, and alignment argument, or both. - */ -expr_deallocator( - unique int expr: @new_or_delete_expr ref, - int func: @function ref, - int form: int ref -); - -/** - * Holds if the `@conditionalexpr` is of the two operand form - * `guard ? : false`. - */ -expr_cond_two_operand( - unique int cond: @conditionalexpr ref -); - -/** - * The guard of `@conditionalexpr` `guard ? true : false` - */ -expr_cond_guard( - unique int cond: @conditionalexpr ref, - int guard: @expr ref -); - -/** - * The expression used when the guard of `@conditionalexpr` - * `guard ? true : false` holds. For the two operand form - * `guard ?: false` consider using `expr_cond_guard` instead. - */ -expr_cond_true( - unique int cond: @conditionalexpr ref, - int true: @expr ref -); - -/** - * The expression used when the guard of `@conditionalexpr` - * `guard ? true : false` does not hold. - */ -expr_cond_false( - unique int cond: @conditionalexpr ref, - int false: @expr ref -); - -/** A string representation of the value. */ -values( - unique int id: @value, - string str: string ref -); - -/** The actual text in the source code for the value, if any. */ -valuetext( - unique int id: @value ref, - string text: string ref -); - -valuebind( - int val: @value ref, - unique int expr: @expr ref -); - -fieldoffsets( - unique int id: @variable ref, - int byteoffset: int ref, - int bitoffset: int ref -); - -bitfield( - unique int id: @variable ref, - int bits: int ref, - int declared_bits: int ref -); - -/* TODO -memberprefix( - int member: @expr ref, - int prefix: @expr ref -); -*/ - -/* - kind(1) = mbrcallexpr - kind(2) = mbrptrcallexpr - kind(3) = mbrptrmbrcallexpr - kind(4) = ptrmbrptrmbrcallexpr - kind(5) = mbrreadexpr // x.y - kind(6) = mbrptrreadexpr // p->y - kind(7) = mbrptrmbrreadexpr // x.*pm - kind(8) = mbrptrmbrptrreadexpr // x->*pm - kind(9) = staticmbrreadexpr // static x.y - kind(10) = staticmbrptrreadexpr // static p->y -*/ -/* TODO -memberaccess( - int member: @expr ref, - int kind: int ref -); -*/ - -initialisers( - unique int init: @initialiser, - int var: @accessible ref, - unique int expr: @expr ref, - int location: @location_expr ref -); - -braced_initialisers( - int init: @initialiser ref -); - -/** - * An ancestor for the expression, for cases in which we cannot - * otherwise find the expression's parent. - */ -expr_ancestor( - int exp: @expr ref, - int ancestor: @element ref -); - -exprs( - unique int id: @expr, - int kind: int ref, - int location: @location_expr ref -); - -expr_reuse( - int reuse: @expr ref, - int original: @expr ref, - int value_category: int ref -) - -/* - case @value.category of - 1 = prval - | 2 = xval - | 3 = lval - ; -*/ -expr_types( - int id: @expr ref, - int typeid: @type ref, - int value_category: int ref -); - -case @expr.kind of - 1 = @errorexpr -| 2 = @address_of // & AddressOfExpr -| 3 = @reference_to // ReferenceToExpr (implicit?) -| 4 = @indirect // * PointerDereferenceExpr -| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) -// ... -| 8 = @array_to_pointer // (???) -| 9 = @vacuous_destructor_call // VacuousDestructorCall -// ... -| 11 = @assume // Microsoft -| 12 = @parexpr -| 13 = @arithnegexpr -| 14 = @unaryplusexpr -| 15 = @complementexpr -| 16 = @notexpr -| 17 = @conjugation // GNU ~ operator -| 18 = @realpartexpr // GNU __real -| 19 = @imagpartexpr // GNU __imag -| 20 = @postincrexpr -| 21 = @postdecrexpr -| 22 = @preincrexpr -| 23 = @predecrexpr -| 24 = @conditionalexpr -| 25 = @addexpr -| 26 = @subexpr -| 27 = @mulexpr -| 28 = @divexpr -| 29 = @remexpr -| 30 = @jmulexpr // C99 mul imaginary -| 31 = @jdivexpr // C99 div imaginary -| 32 = @fjaddexpr // C99 add real + imaginary -| 33 = @jfaddexpr // C99 add imaginary + real -| 34 = @fjsubexpr // C99 sub real - imaginary -| 35 = @jfsubexpr // C99 sub imaginary - real -| 36 = @paddexpr // pointer add (pointer + int or int + pointer) -| 37 = @psubexpr // pointer sub (pointer - integer) -| 38 = @pdiffexpr // difference between two pointers -| 39 = @lshiftexpr -| 40 = @rshiftexpr -| 41 = @andexpr -| 42 = @orexpr -| 43 = @xorexpr -| 44 = @eqexpr -| 45 = @neexpr -| 46 = @gtexpr -| 47 = @ltexpr -| 48 = @geexpr -| 49 = @leexpr -| 50 = @minexpr // GNU minimum -| 51 = @maxexpr // GNU maximum -| 52 = @assignexpr -| 53 = @assignaddexpr -| 54 = @assignsubexpr -| 55 = @assignmulexpr -| 56 = @assigndivexpr -| 57 = @assignremexpr -| 58 = @assignlshiftexpr -| 59 = @assignrshiftexpr -| 60 = @assignandexpr -| 61 = @assignorexpr -| 62 = @assignxorexpr -| 63 = @assignpaddexpr // assign pointer add -| 64 = @assignpsubexpr // assign pointer sub -| 65 = @andlogicalexpr -| 66 = @orlogicalexpr -| 67 = @commaexpr -| 68 = @subscriptexpr // access to member of an array, e.g., a[5] -// ... 69 @objc_subscriptexpr deprecated -// ... 70 @cmdaccess deprecated -// ... -| 73 = @virtfunptrexpr -| 74 = @callexpr -// ... 75 @msgexpr_normal deprecated -// ... 76 @msgexpr_super deprecated -// ... 77 @atselectorexpr deprecated -// ... 78 @atprotocolexpr deprecated -| 79 = @vastartexpr -| 80 = @vaargexpr -| 81 = @vaendexpr -| 82 = @vacopyexpr -// ... 83 @atencodeexpr deprecated -| 84 = @varaccess -| 85 = @thisaccess -// ... 86 @objc_box_expr deprecated -| 87 = @new_expr -| 88 = @delete_expr -| 89 = @throw_expr -| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) -| 91 = @braced_init_list -| 92 = @type_id -| 93 = @runtime_sizeof -| 94 = @runtime_alignof -| 95 = @sizeof_pack -| 96 = @expr_stmt // GNU extension -| 97 = @routineexpr -| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) -| 99 = @offsetofexpr // offsetof ::= type and field -| 100 = @hasassignexpr // __has_assign ::= type -| 101 = @hascopyexpr // __has_copy ::= type -| 102 = @hasnothrowassign // __has_nothrow_assign ::= type -| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type -| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type -| 105 = @hastrivialassign // __has_trivial_assign ::= type -| 106 = @hastrivialconstr // __has_trivial_constructor ::= type -| 107 = @hastrivialcopy // __has_trivial_copy ::= type -| 108 = @hasuserdestr // __has_user_destructor ::= type -| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type -| 110 = @isabstractexpr // __is_abstract ::= type -| 111 = @isbaseofexpr // __is_base_of ::= type type -| 112 = @isclassexpr // __is_class ::= type -| 113 = @isconvtoexpr // __is_convertible_to ::= type type -| 114 = @isemptyexpr // __is_empty ::= type -| 115 = @isenumexpr // __is_enum ::= type -| 116 = @ispodexpr // __is_pod ::= type -| 117 = @ispolyexpr // __is_polymorphic ::= type -| 118 = @isunionexpr // __is_union ::= type -| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type -| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof -// ... -| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type -| 123 = @literal -| 124 = @uuidof -| 127 = @aggregateliteral -| 128 = @delete_array_expr -| 129 = @new_array_expr -// ... 130 @objc_array_literal deprecated -// ... 131 @objc_dictionary_literal deprecated -| 132 = @foldexpr -// ... -| 200 = @ctordirectinit -| 201 = @ctorvirtualinit -| 202 = @ctorfieldinit -| 203 = @ctordelegatinginit -| 204 = @dtordirectdestruct -| 205 = @dtorvirtualdestruct -| 206 = @dtorfielddestruct -// ... -| 210 = @static_cast -| 211 = @reinterpret_cast -| 212 = @const_cast -| 213 = @dynamic_cast -| 214 = @c_style_cast -| 215 = @lambdaexpr -| 216 = @param_ref -| 217 = @noopexpr -// ... -| 294 = @istriviallyconstructibleexpr -| 295 = @isdestructibleexpr -| 296 = @isnothrowdestructibleexpr -| 297 = @istriviallydestructibleexpr -| 298 = @istriviallyassignableexpr -| 299 = @isnothrowassignableexpr -| 300 = @istrivialexpr -| 301 = @isstandardlayoutexpr -| 302 = @istriviallycopyableexpr -| 303 = @isliteraltypeexpr -| 304 = @hastrivialmoveconstructorexpr -| 305 = @hastrivialmoveassignexpr -| 306 = @hasnothrowmoveassignexpr -| 307 = @isconstructibleexpr -| 308 = @isnothrowconstructibleexpr -| 309 = @hasfinalizerexpr -| 310 = @isdelegateexpr -| 311 = @isinterfaceclassexpr -| 312 = @isrefarrayexpr -| 313 = @isrefclassexpr -| 314 = @issealedexpr -| 315 = @issimplevalueclassexpr -| 316 = @isvalueclassexpr -| 317 = @isfinalexpr -| 319 = @noexceptexpr -| 320 = @builtinshufflevector -| 321 = @builtinchooseexpr -| 322 = @builtinaddressof -| 323 = @vec_fill -| 324 = @builtinconvertvector -| 325 = @builtincomplex -| 326 = @spaceshipexpr -| 327 = @co_await -| 328 = @co_yield -| 329 = @temp_init -| 330 = @isassignable -| 331 = @isaggregate -| 332 = @hasuniqueobjectrepresentations -| 333 = @builtinbitcast -| 334 = @builtinshuffle -| 335 = @blockassignexpr -| 336 = @issame -| 337 = @isfunction -| 338 = @islayoutcompatible -| 339 = @ispointerinterconvertiblebaseof -| 340 = @isarray -| 341 = @arrayrank -| 342 = @arrayextent -| 343 = @isarithmetic -| 344 = @iscompletetype -| 345 = @iscompound -| 346 = @isconst -| 347 = @isfloatingpoint -| 348 = @isfundamental -| 349 = @isintegral -| 350 = @islvaluereference -| 351 = @ismemberfunctionpointer -| 352 = @ismemberobjectpointer -| 353 = @ismemberpointer -| 354 = @isobject -| 355 = @ispointer -| 356 = @isreference -| 357 = @isrvaluereference -| 358 = @isscalar -| 359 = @issigned -| 360 = @isunsigned -| 361 = @isvoid -| 362 = @isvolatile -| 363 = @reuseexpr -| 364 = @istriviallycopyassignable -| 365 = @isassignablenopreconditioncheck -| 366 = @referencebindstotemporary -| 367 = @issameas -| 368 = @builtinhasattribute -| 369 = @ispointerinterconvertiblewithclass -| 370 = @builtinispointerinterconvertiblewithclass -| 371 = @iscorrespondingmember -| 372 = @builtiniscorrespondingmember -| 373 = @isboundedarray -| 374 = @isunboundedarray -| 375 = @isreferenceable -| 378 = @isnothrowconvertible -| 379 = @referenceconstructsfromtemporary -| 380 = @referenceconvertsfromtemporary -| 381 = @isconvertible -| 382 = @isvalidwinrttype -| 383 = @iswinclass -| 384 = @iswininterface -| 385 = @istriviallyequalitycomparable -| 386 = @isscopedenum -| 387 = @istriviallyrelocatable -| 388 = @datasizeof -| 389 = @c11_generic -| 390 = @requires_expr -| 391 = @nested_requirement -| 392 = @compound_requirement -| 393 = @concept_id -; - -@var_args_expr = @vastartexpr - | @vaendexpr - | @vaargexpr - | @vacopyexpr - ; - -@builtin_op = @var_args_expr - | @noopexpr - | @offsetofexpr - | @intaddrexpr - | @hasassignexpr - | @hascopyexpr - | @hasnothrowassign - | @hasnothrowconstr - | @hasnothrowcopy - | @hastrivialassign - | @hastrivialconstr - | @hastrivialcopy - | @hastrivialdestructor - | @hasuserdestr - | @hasvirtualdestr - | @isabstractexpr - | @isbaseofexpr - | @isclassexpr - | @isconvtoexpr - | @isemptyexpr - | @isenumexpr - | @ispodexpr - | @ispolyexpr - | @isunionexpr - | @typescompexpr - | @builtinshufflevector - | @builtinconvertvector - | @builtinaddressof - | @istriviallyconstructibleexpr - | @isdestructibleexpr - | @isnothrowdestructibleexpr - | @istriviallydestructibleexpr - | @istriviallyassignableexpr - | @isnothrowassignableexpr - | @istrivialexpr - | @isstandardlayoutexpr - | @istriviallycopyableexpr - | @isliteraltypeexpr - | @hastrivialmoveconstructorexpr - | @hastrivialmoveassignexpr - | @hasnothrowmoveassignexpr - | @isconstructibleexpr - | @isnothrowconstructibleexpr - | @hasfinalizerexpr - | @isdelegateexpr - | @isinterfaceclassexpr - | @isrefarrayexpr - | @isrefclassexpr - | @issealedexpr - | @issimplevalueclassexpr - | @isvalueclassexpr - | @isfinalexpr - | @builtinchooseexpr - | @builtincomplex - | @isassignable - | @isaggregate - | @hasuniqueobjectrepresentations - | @builtinbitcast - | @builtinshuffle - | @issame - | @isfunction - | @islayoutcompatible - | @ispointerinterconvertiblebaseof - | @isarray - | @arrayrank - | @arrayextent - | @isarithmetic - | @iscompletetype - | @iscompound - | @isconst - | @isfloatingpoint - | @isfundamental - | @isintegral - | @islvaluereference - | @ismemberfunctionpointer - | @ismemberobjectpointer - | @ismemberpointer - | @isobject - | @ispointer - | @isreference - | @isrvaluereference - | @isscalar - | @issigned - | @isunsigned - | @isvoid - | @isvolatile - | @istriviallycopyassignable - | @isassignablenopreconditioncheck - | @referencebindstotemporary - | @issameas - | @builtinhasattribute - | @ispointerinterconvertiblewithclass - | @builtinispointerinterconvertiblewithclass - | @iscorrespondingmember - | @builtiniscorrespondingmember - | @isboundedarray - | @isunboundedarray - | @isreferenceable - | @isnothrowconvertible - | @referenceconstructsfromtemporary - | @referenceconvertsfromtemporary - | @isconvertible - | @isvalidwinrttype - | @iswinclass - | @iswininterface - | @istriviallyequalitycomparable - | @isscopedenum - | @istriviallyrelocatable - ; - -compound_requirement_is_noexcept( - int expr: @compound_requirement ref -); - -new_allocated_type( - unique int expr: @new_expr ref, - int type_id: @type ref -); - -new_array_allocated_type( - unique int expr: @new_array_expr ref, - int type_id: @type ref -); - -/** - * The field being initialized by an initializer expression within an aggregate - * initializer for a class/struct/union. Position is used to sort repeated initializers. - */ -#keyset[aggregate, position] -aggregate_field_init( - int aggregate: @aggregateliteral ref, - int initializer: @expr ref, - int field: @membervariable ref, - int position: int ref -); - -/** - * The index of the element being initialized by an initializer expression - * within an aggregate initializer for an array. Position is used to sort repeated initializers. - */ -#keyset[aggregate, position] -aggregate_array_init( - int aggregate: @aggregateliteral ref, - int initializer: @expr ref, - int element_index: int ref, - int position: int ref -); - -@ctorinit = @ctordirectinit - | @ctorvirtualinit - | @ctorfieldinit - | @ctordelegatinginit; -@dtordestruct = @dtordirectdestruct - | @dtorvirtualdestruct - | @dtorfielddestruct; - - -condition_decl_bind( - unique int expr: @condition_decl ref, - unique int decl: @declaration ref -); - -typeid_bind( - unique int expr: @type_id ref, - int type_id: @type ref -); - -uuidof_bind( - unique int expr: @uuidof ref, - int type_id: @type ref -); - -@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; - -sizeof_bind( - unique int expr: @runtime_sizeof_or_alignof ref, - int type_id: @type ref -); - -code_block( - unique int block: @literal ref, - unique int routine: @function ref -); - -lambdas( - unique int expr: @lambdaexpr ref, - string default_capture: string ref, - boolean has_explicit_return_type: boolean ref -); - -lambda_capture( - unique int id: @lambdacapture, - int lambda: @lambdaexpr ref, - int index: int ref, - int field: @membervariable ref, - boolean captured_by_reference: boolean ref, - boolean is_implicit: boolean ref, - int location: @location_default ref -); - -@funbindexpr = @routineexpr - | @new_expr - | @delete_expr - | @delete_array_expr - | @ctordirectinit - | @ctorvirtualinit - | @ctordelegatinginit - | @dtordirectdestruct - | @dtorvirtualdestruct; - -@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; -@addressable = @function | @variable ; -@accessible = @addressable | @enumconstant ; - -@access = @varaccess | @routineexpr ; - -fold( - int expr: @foldexpr ref, - string operator: string ref, - boolean is_left_fold: boolean ref -); - -stmts( - unique int id: @stmt, - int kind: int ref, - int location: @location_stmt ref -); - -case @stmt.kind of - 1 = @stmt_expr -| 2 = @stmt_if -| 3 = @stmt_while -| 4 = @stmt_goto -| 5 = @stmt_label -| 6 = @stmt_return -| 7 = @stmt_block -| 8 = @stmt_end_test_while // do { ... } while ( ... ) -| 9 = @stmt_for -| 10 = @stmt_switch_case -| 11 = @stmt_switch -| 13 = @stmt_asm // "asm" statement or the body of an asm function -| 15 = @stmt_try_block -| 16 = @stmt_microsoft_try // Microsoft -| 17 = @stmt_decl -| 18 = @stmt_set_vla_size // C99 -| 19 = @stmt_vla_decl // C99 -| 25 = @stmt_assigned_goto // GNU -| 26 = @stmt_empty -| 27 = @stmt_continue -| 28 = @stmt_break -| 29 = @stmt_range_based_for // C++11 -// ... 30 @stmt_at_autoreleasepool_block deprecated -// ... 31 @stmt_objc_for_in deprecated -// ... 32 @stmt_at_synchronized deprecated -| 33 = @stmt_handler -// ... 34 @stmt_finally_end deprecated -| 35 = @stmt_constexpr_if -| 37 = @stmt_co_return -; - -type_vla( - int type_id: @type ref, - int decl: @stmt_vla_decl ref -); - -variable_vla( - int var: @variable ref, - int decl: @stmt_vla_decl ref -); - -if_initialization( - unique int if_stmt: @stmt_if ref, - int init_id: @stmt ref -); - -if_then( - unique int if_stmt: @stmt_if ref, - int then_id: @stmt ref -); - -if_else( - unique int if_stmt: @stmt_if ref, - int else_id: @stmt ref -); - -constexpr_if_initialization( - unique int constexpr_if_stmt: @stmt_constexpr_if ref, - int init_id: @stmt ref -); - -constexpr_if_then( - unique int constexpr_if_stmt: @stmt_constexpr_if ref, - int then_id: @stmt ref -); - -constexpr_if_else( - unique int constexpr_if_stmt: @stmt_constexpr_if ref, - int else_id: @stmt ref -); - -while_body( - unique int while_stmt: @stmt_while ref, - int body_id: @stmt ref -); - -do_body( - unique int do_stmt: @stmt_end_test_while ref, - int body_id: @stmt ref -); - -switch_initialization( - unique int switch_stmt: @stmt_switch ref, - int init_id: @stmt ref -); - -#keyset[switch_stmt, index] -switch_case( - int switch_stmt: @stmt_switch ref, - int index: int ref, - int case_id: @stmt_switch_case ref -); - -switch_body( - unique int switch_stmt: @stmt_switch ref, - int body_id: @stmt ref -); - -@stmt_for_or_range_based_for = @stmt_for - | @stmt_range_based_for; - -for_initialization( - unique int for_stmt: @stmt_for_or_range_based_for ref, - int init_id: @stmt ref -); - -for_condition( - unique int for_stmt: @stmt_for ref, - int condition_id: @expr ref -); - -for_update( - unique int for_stmt: @stmt_for ref, - int update_id: @expr ref -); - -for_body( - unique int for_stmt: @stmt_for ref, - int body_id: @stmt ref -); - -@stmtparent = @stmt | @expr_stmt ; -stmtparents( - unique int id: @stmt ref, - int index: int ref, - int parent: @stmtparent ref -); - -ishandler(unique int block: @stmt_block ref); - -@cfgnode = @stmt | @expr | @function | @initialiser ; - -stmt_decl_bind( - int stmt: @stmt_decl ref, - int num: int ref, - int decl: @declaration ref -); - -stmt_decl_entry_bind( - int stmt: @stmt_decl ref, - int num: int ref, - int decl_entry: @element ref -); - -@parameterized_element = @function | @stmt_block | @requires_expr; - -blockscope( - unique int block: @stmt_block ref, - int enclosing: @parameterized_element ref -); - -@jump = @stmt_goto | @stmt_break | @stmt_continue; - -@jumporlabel = @jump | @stmt_label | @literal; - -jumpinfo( - unique int id: @jumporlabel ref, - string str: string ref, - int target: @stmt ref -); - -preprocdirects( - unique int id: @preprocdirect, - int kind: int ref, - int location: @location_default ref -); -case @preprocdirect.kind of - 0 = @ppd_if -| 1 = @ppd_ifdef -| 2 = @ppd_ifndef -| 3 = @ppd_elif -| 4 = @ppd_else -| 5 = @ppd_endif -| 6 = @ppd_plain_include -| 7 = @ppd_define -| 8 = @ppd_undef -| 9 = @ppd_line -| 10 = @ppd_error -| 11 = @ppd_pragma -| 12 = @ppd_objc_import -| 13 = @ppd_include_next -| 18 = @ppd_warning -; - -@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; - -@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; - -preprocpair( - int begin : @ppd_branch ref, - int elseelifend : @preprocdirect ref -); - -preproctrue(int branch : @ppd_branch ref); -preprocfalse(int branch : @ppd_branch ref); - -preproctext( - unique int id: @preprocdirect ref, - string head: string ref, - string body: string ref -); - -includes( - unique int id: @ppd_include ref, - int included: @file ref -); - -link_targets( - int id: @link_target, - int binary: @file ref -); - -link_parent( - int element : @element ref, - int link_target : @link_target ref -); - -/* XML Files */ - -xmlEncoding(unique int id: @file ref, string encoding: string ref); - -xmlDTDs( - unique int id: @xmldtd, - string root: string ref, - string publicId: string ref, - string systemId: string ref, - int fileid: @file ref -); - -xmlElements( - unique int id: @xmlelement, - string name: string ref, - int parentid: @xmlparent ref, - int idx: int ref, - int fileid: @file ref -); - -xmlAttrs( - unique int id: @xmlattribute, - int elementid: @xmlelement ref, - string name: string ref, - string value: string ref, - int idx: int ref, - int fileid: @file ref -); - -xmlNs( - int id: @xmlnamespace, - string prefixName: string ref, - string URI: string ref, - int fileid: @file ref -); - -xmlHasNs( - int elementId: @xmlnamespaceable ref, - int nsId: @xmlnamespace ref, - int fileid: @file ref -); - -xmlComments( - unique int id: @xmlcomment, - string text: string ref, - int parentid: @xmlparent ref, - int fileid: @file ref -); - -xmlChars( - unique int id: @xmlcharacters, - string text: string ref, - int parentid: @xmlparent ref, - int idx: int ref, - int isCDATA: int ref, - int fileid: @file ref -); - -@xmlparent = @file | @xmlelement; -@xmlnamespaceable = @xmlelement | @xmlattribute; - -xmllocations( - int xmlElement: @xmllocatable ref, - int location: @location_default ref -); - -@xmllocatable = @xmlcharacters - | @xmlelement - | @xmlcomment - | @xmlattribute - | @xmldtd - | @file - | @xmlnamespace; diff --git a/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/upgrade.properties b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/upgrade.properties deleted file mode 100644 index 08e1dc42eb2..00000000000 --- a/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/upgrade.properties +++ /dev/null @@ -1,2 +0,0 @@ -description: Implement compilation_build_mode/2 -compatibility: backwards From 75a3c931d1c86dceb2f6b8ebbf727fbafabee751 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:58:23 +0000 Subject: [PATCH 194/470] Rust: Autoformat (again). --- rust/ql/src/queries/summary/TaintSources.ql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rust/ql/src/queries/summary/TaintSources.ql b/rust/ql/src/queries/summary/TaintSources.ql index f7dc95eccb4..9ac72b706ef 100644 --- a/rust/ql/src/queries/summary/TaintSources.ql +++ b/rust/ql/src/queries/summary/TaintSources.ql @@ -14,4 +14,5 @@ import codeql.rust.Concepts from ThreatModelSource s, string defaultString where if s instanceof ActiveThreatModelSource then defaultString = " (DEFAULT)" else defaultString = "" -select s, "Flow source '" + s.getSourceType() + "' of type " + s.getThreatModel() + defaultString + "." +select s, + "Flow source '" + s.getSourceType() + "' of type " + s.getThreatModel() + defaultString + "." From 6e627f6543eac44a32c1549d47a69666e9b26f0a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 12:21:03 +0000 Subject: [PATCH 195/470] Rust: Add new consistency check failure. --- .../diagnostics/CONSISTENCY/ExtractionConsistency.expected | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/ql/test/query-tests/diagnostics/CONSISTENCY/ExtractionConsistency.expected b/rust/ql/test/query-tests/diagnostics/CONSISTENCY/ExtractionConsistency.expected index bdfa4a9792d..7e4e635b8cf 100644 --- a/rust/ql/test/query-tests/diagnostics/CONSISTENCY/ExtractionConsistency.expected +++ b/rust/ql/test/query-tests/diagnostics/CONSISTENCY/ExtractionConsistency.expected @@ -6,3 +6,4 @@ extractionWarning | does_not_compile.rs:2:26:2:25 | expected SEMICOLON | | does_not_compile.rs:2:32:2:31 | expected field name or number | | error.rs:2:5:2:17 | An error! | +| my_macro.rs:17:9:17:27 | macro expansion failed: could not resolve macro 'myUndefinedMacro' | From 143d7e20849bb9abd93a0b4c35b52bcd72795d9e Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 22 Nov 2024 10:30:33 +0100 Subject: [PATCH 196/470] Rust: Use extended canonical paths to resolve calls in data flow --- .../rust/dataflow/internal/DataFlowImpl.qll | 54 ++++++++++++++++--- shared/util/codeql/util/Option.qll | 1 + 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 1ec8a42ee7e..3710004b8de 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -399,13 +399,55 @@ module RustDataFlow implements InputSig { final class ReturnKind = ReturnKindAlias; + private import codeql.util.Option + + private class CrateOrigin extends string { + CrateOrigin() { + this = [any(Item i).getCrateOrigin(), any(Resolvable r).getResolvedCrateOrigin()] + } + } + + private class CrateOriginOption = Option::Option; + + pragma[nomagic] + private predicate hasExtendedCanonicalPath( + DataFlowCallable c, CrateOriginOption crate, string path + ) { + exists(Item i | + i = c.asCfgScope() and + path = i.getExtendedCanonicalPath() + | + crate.asSome() = i.getCrateOrigin() + or + crate.isNone() and + not i.hasCrateOrigin() + ) + } + + pragma[nomagic] + private predicate resolvesExtendedCanonicalPath( + DataFlowCall c, CrateOriginOption crate, string path + ) { + exists(Resolvable r | + path = r.getResolvedPath() and + ( + r = c.asMethodCallExprCfgNode().getExpr() + or + r = c.asCallExprCfgNode().getExpr().(PathExprCfgNode).getPath() + ) + | + crate.asSome() = r.getResolvedCrateOrigin() + or + crate.isNone() and + not r.hasResolvedCrateOrigin() + ) + } + /** Gets a viable implementation of the target of the given `Call`. */ - DataFlowCallable viableCallable(DataFlowCall c) { - exists(Function f, string name | result.asCfgScope() = f and name = f.getName().toString() | - if f.getParamList().hasSelfParam() - then name = c.asMethodCallExprCfgNode().getNameRef().getText() - else - name = c.asCallExprCfgNode().getExpr().getExpr().(PathExpr).getPath().getPart().toString() + DataFlowCallable viableCallable(DataFlowCall call) { + exists(string path, CrateOriginOption crate | + hasExtendedCanonicalPath(result, crate, path) and + resolvesExtendedCanonicalPath(call, crate, path) ) } diff --git a/shared/util/codeql/util/Option.qll b/shared/util/codeql/util/Option.qll index 31df747afe8..8ba4d8e840b 100644 --- a/shared/util/codeql/util/Option.qll +++ b/shared/util/codeql/util/Option.qll @@ -2,6 +2,7 @@ /** A type with `toString`. */ private signature class TypeWithToString { + bindingset[this] string toString(); } From 2e90c80a6f85fb451467b66002e7949490115bd0 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 22 Nov 2024 13:45:00 +0100 Subject: [PATCH 197/470] Rust: accept test changes --- .../CONSISTENCY/DataFlowConsistency.expected | 4 --- .../CONSISTENCY/DataFlowConsistency.expected | 5 ---- .../formatstrings/FormatTemplate.expected | 30 +++++++++---------- .../CONSISTENCY/DataFlowConsistency.expected | 4 --- .../CONSISTENCY/DataFlowConsistency.expected | 5 ---- 5 files changed, 15 insertions(+), 33 deletions(-) delete mode 100644 rust/ql/test/library-tests/definitions/CONSISTENCY/DataFlowConsistency.expected delete mode 100644 rust/ql/test/library-tests/formatstrings/CONSISTENCY/DataFlowConsistency.expected delete mode 100644 rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected diff --git a/rust/ql/test/library-tests/definitions/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/library-tests/definitions/CONSISTENCY/DataFlowConsistency.expected deleted file mode 100644 index 8d729bb5fd9..00000000000 --- a/rust/ql/test/library-tests/definitions/CONSISTENCY/DataFlowConsistency.expected +++ /dev/null @@ -1,4 +0,0 @@ -uniqueEnclosingCallable -| main.rs:5:29:5:33 | width | Node should have one enclosing callable but has 0. | -| main.rs:5:36:5:44 | precision | Node should have one enclosing callable but has 0. | -| main.rs:9:22:9:27 | people | Node should have one enclosing callable but has 0. | diff --git a/rust/ql/test/library-tests/formatstrings/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/library-tests/formatstrings/CONSISTENCY/DataFlowConsistency.expected deleted file mode 100644 index 5bd870a7205..00000000000 --- a/rust/ql/test/library-tests/formatstrings/CONSISTENCY/DataFlowConsistency.expected +++ /dev/null @@ -1,5 +0,0 @@ -uniqueEnclosingCallable -| main.rs:5:29:5:33 | width | Node should have one enclosing callable but has 0. | -| main.rs:5:36:5:44 | precision | Node should have one enclosing callable but has 0. | -| main.rs:16:22:16:27 | people | Node should have one enclosing callable but has 0. | -| main.rs:27:23:27:27 | width | Node should have one enclosing callable but has 0. | diff --git a/rust/ql/test/library-tests/formatstrings/FormatTemplate.expected b/rust/ql/test/library-tests/formatstrings/FormatTemplate.expected index 6750a5dc5f0..b554f7e7920 100644 --- a/rust/ql/test/library-tests/formatstrings/FormatTemplate.expected +++ b/rust/ql/test/library-tests/formatstrings/FormatTemplate.expected @@ -2,20 +2,20 @@ getFormat | main.rs:5:14:5:61 | FormatArgsExpr | main.rs:5:21:5:46 | {value:#width$.precision$} | 0 | | main.rs:6:14:6:56 | FormatArgsExpr | main.rs:6:21:6:30 | {0:#1$.2$} | 0 | | main.rs:7:14:7:40 | FormatArgsExpr | main.rs:7:21:7:22 | {} | 0 | -| main.rs:7:14:7:40 | FormatArgsExpr | main.rs:7:24:7:25 | {} | 1 | +| main.rs:7:14:7:40 | FormatArgsExpr | main.rs:7:24:7:25 | {} | 2 | | main.rs:11:14:11:34 | FormatArgsExpr | main.rs:11:22:11:23 | {} | 0 | | main.rs:12:14:12:34 | FormatArgsExpr | main.rs:12:29:12:30 | {} | 0 | | main.rs:13:14:13:27 | FormatArgsExpr | main.rs:13:15:13:18 | {:?} | 0 | | main.rs:14:14:14:33 | FormatArgsExpr | main.rs:14:15:14:21 | {value} | 0 | | main.rs:16:14:16:30 | FormatArgsExpr | main.rs:16:21:16:28 | {people} | 0 | | main.rs:17:14:17:26 | FormatArgsExpr | main.rs:17:15:17:16 | {} | 0 | -| main.rs:17:14:17:26 | FormatArgsExpr | main.rs:17:18:17:19 | {} | 1 | +| main.rs:17:14:17:26 | FormatArgsExpr | main.rs:17:18:17:19 | {} | 2 | | main.rs:18:14:18:24 | FormatArgsExpr | main.rs:18:15:18:19 | {:04} | 0 | | main.rs:19:14:19:32 | FormatArgsExpr | main.rs:19:15:19:19 | {:#?} | 0 | | main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:15:21:17 | {1} | 0 | -| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:19:21:20 | {} | 1 | -| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:22:21:24 | {0} | 2 | -| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:26:21:27 | {} | 3 | +| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:19:21:20 | {} | 2 | +| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:22:21:24 | {0} | 4 | +| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:26:21:27 | {} | 6 | | main.rs:22:14:22:31 | FormatArgsExpr | main.rs:22:21:22:24 | {:5} | 0 | | main.rs:23:14:23:35 | FormatArgsExpr | main.rs:23:21:23:25 | {:1$} | 0 | | main.rs:24:14:24:36 | FormatArgsExpr | main.rs:24:21:24:26 | {1:0$} | 0 | @@ -33,25 +33,25 @@ getFormat | main.rs:36:24:36:41 | FormatArgsExpr | main.rs:36:31:36:35 | {:05} | 0 | | main.rs:37:24:37:38 | FormatArgsExpr | main.rs:37:25:37:32 | {:#010x} | 0 | | main.rs:39:14:39:45 | FormatArgsExpr | main.rs:39:21:39:23 | {0} | 0 | -| main.rs:39:14:39:45 | FormatArgsExpr | main.rs:39:28:39:33 | {1:.5} | 1 | +| main.rs:39:14:39:45 | FormatArgsExpr | main.rs:39:28:39:33 | {1:.5} | 2 | | main.rs:41:14:41:49 | FormatArgsExpr | main.rs:41:21:41:23 | {1} | 0 | -| main.rs:41:14:41:49 | FormatArgsExpr | main.rs:41:28:41:34 | {2:.0$} | 1 | +| main.rs:41:14:41:49 | FormatArgsExpr | main.rs:41:28:41:34 | {2:.0$} | 2 | | main.rs:43:14:43:49 | FormatArgsExpr | main.rs:43:21:43:23 | {0} | 0 | -| main.rs:43:14:43:49 | FormatArgsExpr | main.rs:43:28:43:34 | {2:.1$} | 1 | +| main.rs:43:14:43:49 | FormatArgsExpr | main.rs:43:28:43:34 | {2:.1$} | 2 | | main.rs:45:14:45:46 | FormatArgsExpr | main.rs:45:21:45:22 | {} | 0 | -| main.rs:45:14:45:46 | FormatArgsExpr | main.rs:45:27:45:31 | {:.*} | 1 | +| main.rs:45:14:45:46 | FormatArgsExpr | main.rs:45:27:45:31 | {:.*} | 2 | | main.rs:47:14:47:48 | FormatArgsExpr | main.rs:47:21:47:23 | {1} | 0 | -| main.rs:47:14:47:48 | FormatArgsExpr | main.rs:47:28:47:33 | {2:.*} | 1 | +| main.rs:47:14:47:48 | FormatArgsExpr | main.rs:47:28:47:33 | {2:.*} | 2 | | main.rs:48:14:48:47 | FormatArgsExpr | main.rs:48:21:48:22 | {} | 0 | -| main.rs:48:14:48:47 | FormatArgsExpr | main.rs:48:27:48:32 | {2:.*} | 1 | +| main.rs:48:14:48:47 | FormatArgsExpr | main.rs:48:27:48:32 | {2:.*} | 2 | | main.rs:49:14:49:72 | FormatArgsExpr | main.rs:49:21:49:22 | {} | 0 | -| main.rs:49:14:49:72 | FormatArgsExpr | main.rs:49:27:49:41 | {number:.prec$} | 1 | +| main.rs:49:14:49:72 | FormatArgsExpr | main.rs:49:27:49:41 | {number:.prec$} | 2 | | main.rs:52:9:55:22 | FormatArgsExpr | main.rs:52:10:52:11 | {} | 0 | -| main.rs:52:9:55:22 | FormatArgsExpr | main.rs:52:15:52:23 | {name:.*} | 1 | +| main.rs:52:9:55:22 | FormatArgsExpr | main.rs:52:15:52:23 | {name:.*} | 2 | | main.rs:58:9:61:24 | FormatArgsExpr | main.rs:58:10:58:11 | {} | 0 | -| main.rs:58:9:61:24 | FormatArgsExpr | main.rs:58:15:58:23 | {name:.*} | 1 | +| main.rs:58:9:61:24 | FormatArgsExpr | main.rs:58:15:58:23 | {name:.*} | 2 | | main.rs:64:9:67:24 | FormatArgsExpr | main.rs:64:10:64:11 | {} | 0 | -| main.rs:64:9:67:24 | FormatArgsExpr | main.rs:64:15:64:25 | {name:>8.*} | 1 | +| main.rs:64:9:67:24 | FormatArgsExpr | main.rs:64:15:64:25 | {name:>8.*} | 2 | | main.rs:70:12:70:31 | FormatArgsExpr | main.rs:70:13:70:20 | {0:.1$e} | 0 | | main.rs:71:12:71:31 | FormatArgsExpr | main.rs:71:13:71:20 | {0:.1$e} | 0 | | main.rs:73:14:73:35 | FormatArgsExpr | main.rs:73:28:73:29 | {} | 0 | diff --git a/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected index 6e35019c1cb..d9a60435a6f 100644 --- a/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected +++ b/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected @@ -1,7 +1,3 @@ -uniqueEnclosingCallable -| sqlx.rs:52:72:52:84 | remote_number | Node should have one enclosing callable but has 0. | -| sqlx.rs:56:74:56:86 | remote_string | Node should have one enclosing callable but has 0. | -| sqlx.rs:199:32:199:44 | enable_remote | Node should have one enclosing callable but has 0. | uniqueNodeToString | sqlx.rs:154:13:154:81 | (no string representation) | Node should have one toString but has 0. | | sqlx.rs:156:17:156:86 | (no string representation) | Node should have one toString but has 0. | diff --git a/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected deleted file mode 100644 index 0a61a151c20..00000000000 --- a/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected +++ /dev/null @@ -1,5 +0,0 @@ -uniqueEnclosingCallable -| main.rs:194:25:194:25 | x | Node should have one enclosing callable but has 0. | -| main.rs:198:28:198:28 | x | Node should have one enclosing callable but has 0. | -| main.rs:202:28:202:28 | x | Node should have one enclosing callable but has 0. | -| main.rs:206:28:206:28 | x | Node should have one enclosing callable but has 0. | From 28d517da59c27d07534e84e43dc3b5d896cbd457 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 22 Nov 2024 14:13:15 +0100 Subject: [PATCH 198/470] Rust: fix regression in `getFormat` indexing --- .../elements/internal/FormatArgsExprImpl.qll | 3 +- .../FormatArgsExpr_getFormat.expected | 6 ++-- .../formatstrings/FormatTemplate.expected | 30 +++++++++---------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/FormatArgsExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/FormatArgsExprImpl.qll index 59e020fb9e4..6cc3aa11461 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/FormatArgsExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/FormatArgsExprImpl.qll @@ -25,7 +25,8 @@ module Impl { */ class FormatArgsExpr extends Generated::FormatArgsExpr { override Format getFormat(int index) { - result.getParent() = this and result.getIndex() = index + 1 + result = + rank[index + 1](Format f, int i | f.getParent() = this and f.getIndex() = i | f order by i) } } } diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getFormat.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getFormat.expected index acbe782a35d..f0061b8dba4 100644 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getFormat.expected +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getFormat.expected @@ -1,9 +1,9 @@ | gen_format.rs:5:14:5:32 | FormatArgsExpr | 0 | gen_format.rs:5:21:5:22 | {} | | gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | 0 | gen_format_args_expr.rs:6:19:6:20 | {} | -| gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | 2 | gen_format_args_expr.rs:6:26:6:29 | {:?} | +| gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | 1 | gen_format_args_expr.rs:6:26:6:29 | {:?} | | gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | 0 | gen_format_args_expr.rs:7:19:7:21 | {b} | -| gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | 2 | gen_format_args_expr.rs:7:27:7:31 | {a:?} | +| gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | 1 | gen_format_args_expr.rs:7:27:7:31 | {a:?} | | gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | 0 | gen_format_args_expr.rs:9:19:9:21 | {x} | -| gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | 2 | gen_format_args_expr.rs:9:24:9:26 | {y} | +| gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | 1 | gen_format_args_expr.rs:9:24:9:26 | {y} | | gen_format_argument.rs:5:14:5:47 | FormatArgsExpr | 0 | gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | | gen_format_argument.rs:7:14:7:56 | FormatArgsExpr | 0 | gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | diff --git a/rust/ql/test/library-tests/formatstrings/FormatTemplate.expected b/rust/ql/test/library-tests/formatstrings/FormatTemplate.expected index b554f7e7920..6750a5dc5f0 100644 --- a/rust/ql/test/library-tests/formatstrings/FormatTemplate.expected +++ b/rust/ql/test/library-tests/formatstrings/FormatTemplate.expected @@ -2,20 +2,20 @@ getFormat | main.rs:5:14:5:61 | FormatArgsExpr | main.rs:5:21:5:46 | {value:#width$.precision$} | 0 | | main.rs:6:14:6:56 | FormatArgsExpr | main.rs:6:21:6:30 | {0:#1$.2$} | 0 | | main.rs:7:14:7:40 | FormatArgsExpr | main.rs:7:21:7:22 | {} | 0 | -| main.rs:7:14:7:40 | FormatArgsExpr | main.rs:7:24:7:25 | {} | 2 | +| main.rs:7:14:7:40 | FormatArgsExpr | main.rs:7:24:7:25 | {} | 1 | | main.rs:11:14:11:34 | FormatArgsExpr | main.rs:11:22:11:23 | {} | 0 | | main.rs:12:14:12:34 | FormatArgsExpr | main.rs:12:29:12:30 | {} | 0 | | main.rs:13:14:13:27 | FormatArgsExpr | main.rs:13:15:13:18 | {:?} | 0 | | main.rs:14:14:14:33 | FormatArgsExpr | main.rs:14:15:14:21 | {value} | 0 | | main.rs:16:14:16:30 | FormatArgsExpr | main.rs:16:21:16:28 | {people} | 0 | | main.rs:17:14:17:26 | FormatArgsExpr | main.rs:17:15:17:16 | {} | 0 | -| main.rs:17:14:17:26 | FormatArgsExpr | main.rs:17:18:17:19 | {} | 2 | +| main.rs:17:14:17:26 | FormatArgsExpr | main.rs:17:18:17:19 | {} | 1 | | main.rs:18:14:18:24 | FormatArgsExpr | main.rs:18:15:18:19 | {:04} | 0 | | main.rs:19:14:19:32 | FormatArgsExpr | main.rs:19:15:19:19 | {:#?} | 0 | | main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:15:21:17 | {1} | 0 | -| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:19:21:20 | {} | 2 | -| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:22:21:24 | {0} | 4 | -| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:26:21:27 | {} | 6 | +| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:19:21:20 | {} | 1 | +| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:22:21:24 | {0} | 2 | +| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:26:21:27 | {} | 3 | | main.rs:22:14:22:31 | FormatArgsExpr | main.rs:22:21:22:24 | {:5} | 0 | | main.rs:23:14:23:35 | FormatArgsExpr | main.rs:23:21:23:25 | {:1$} | 0 | | main.rs:24:14:24:36 | FormatArgsExpr | main.rs:24:21:24:26 | {1:0$} | 0 | @@ -33,25 +33,25 @@ getFormat | main.rs:36:24:36:41 | FormatArgsExpr | main.rs:36:31:36:35 | {:05} | 0 | | main.rs:37:24:37:38 | FormatArgsExpr | main.rs:37:25:37:32 | {:#010x} | 0 | | main.rs:39:14:39:45 | FormatArgsExpr | main.rs:39:21:39:23 | {0} | 0 | -| main.rs:39:14:39:45 | FormatArgsExpr | main.rs:39:28:39:33 | {1:.5} | 2 | +| main.rs:39:14:39:45 | FormatArgsExpr | main.rs:39:28:39:33 | {1:.5} | 1 | | main.rs:41:14:41:49 | FormatArgsExpr | main.rs:41:21:41:23 | {1} | 0 | -| main.rs:41:14:41:49 | FormatArgsExpr | main.rs:41:28:41:34 | {2:.0$} | 2 | +| main.rs:41:14:41:49 | FormatArgsExpr | main.rs:41:28:41:34 | {2:.0$} | 1 | | main.rs:43:14:43:49 | FormatArgsExpr | main.rs:43:21:43:23 | {0} | 0 | -| main.rs:43:14:43:49 | FormatArgsExpr | main.rs:43:28:43:34 | {2:.1$} | 2 | +| main.rs:43:14:43:49 | FormatArgsExpr | main.rs:43:28:43:34 | {2:.1$} | 1 | | main.rs:45:14:45:46 | FormatArgsExpr | main.rs:45:21:45:22 | {} | 0 | -| main.rs:45:14:45:46 | FormatArgsExpr | main.rs:45:27:45:31 | {:.*} | 2 | +| main.rs:45:14:45:46 | FormatArgsExpr | main.rs:45:27:45:31 | {:.*} | 1 | | main.rs:47:14:47:48 | FormatArgsExpr | main.rs:47:21:47:23 | {1} | 0 | -| main.rs:47:14:47:48 | FormatArgsExpr | main.rs:47:28:47:33 | {2:.*} | 2 | +| main.rs:47:14:47:48 | FormatArgsExpr | main.rs:47:28:47:33 | {2:.*} | 1 | | main.rs:48:14:48:47 | FormatArgsExpr | main.rs:48:21:48:22 | {} | 0 | -| main.rs:48:14:48:47 | FormatArgsExpr | main.rs:48:27:48:32 | {2:.*} | 2 | +| main.rs:48:14:48:47 | FormatArgsExpr | main.rs:48:27:48:32 | {2:.*} | 1 | | main.rs:49:14:49:72 | FormatArgsExpr | main.rs:49:21:49:22 | {} | 0 | -| main.rs:49:14:49:72 | FormatArgsExpr | main.rs:49:27:49:41 | {number:.prec$} | 2 | +| main.rs:49:14:49:72 | FormatArgsExpr | main.rs:49:27:49:41 | {number:.prec$} | 1 | | main.rs:52:9:55:22 | FormatArgsExpr | main.rs:52:10:52:11 | {} | 0 | -| main.rs:52:9:55:22 | FormatArgsExpr | main.rs:52:15:52:23 | {name:.*} | 2 | +| main.rs:52:9:55:22 | FormatArgsExpr | main.rs:52:15:52:23 | {name:.*} | 1 | | main.rs:58:9:61:24 | FormatArgsExpr | main.rs:58:10:58:11 | {} | 0 | -| main.rs:58:9:61:24 | FormatArgsExpr | main.rs:58:15:58:23 | {name:.*} | 2 | +| main.rs:58:9:61:24 | FormatArgsExpr | main.rs:58:15:58:23 | {name:.*} | 1 | | main.rs:64:9:67:24 | FormatArgsExpr | main.rs:64:10:64:11 | {} | 0 | -| main.rs:64:9:67:24 | FormatArgsExpr | main.rs:64:15:64:25 | {name:>8.*} | 2 | +| main.rs:64:9:67:24 | FormatArgsExpr | main.rs:64:15:64:25 | {name:>8.*} | 1 | | main.rs:70:12:70:31 | FormatArgsExpr | main.rs:70:13:70:20 | {0:.1$e} | 0 | | main.rs:71:12:71:31 | FormatArgsExpr | main.rs:71:13:71:20 | {0:.1$e} | 0 | | main.rs:73:14:73:35 | FormatArgsExpr | main.rs:73:28:73:29 | {} | 0 | From 4d851440b6d10439b9c6641597815bfb9e4ba5df Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Wed, 6 Nov 2024 14:12:36 +0000 Subject: [PATCH 199/470] C++: Remove FPs from cpp/too-few-arguments --- .../Likely Bugs/Underspecified Functions/TooFewArguments.qll | 4 +++- .../Underspecified Functions/TooFewArguments.expected | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.qll b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.qll index 6f3f4d43e9a..218a54b36c5 100644 --- a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.qll +++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.qll @@ -51,5 +51,7 @@ predicate tooFewArguments(FunctionCall fc, Function f) { hasDefiniteNumberOfParameters(fde) | fde.getNumberOfParameters() > fc.getNumberOfArguments() - ) + ) and + // Don't report on implicit function declarations, as these are likely extraction errors. + not f.getADeclarationEntry().isImplicit() } diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected index 42c4f7f9455..956729115d7 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected @@ -1,4 +1,2 @@ -| test.c:34:3:34:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:32:3:32:3 | not_yet_declared2 | not_yet_declared2 | -| test.c:34:3:34:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:76:6:76:22 | not_yet_declared2 | not_yet_declared2 | | test.c:36:3:36:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:77:6:77:32 | declared_empty_defined_with | declared_empty_defined_with | | test.c:87:10:87:20 | call to dereference | This call has fewer arguments than required by $@. | test.c:90:5:90:15 | dereference | dereference | From 227f9c7c1bfb04e049f965a03d8381908b42f56b Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Fri, 22 Nov 2024 14:56:13 +0000 Subject: [PATCH 200/470] C++: Update the test.c comments --- .../query-tests/Likely Bugs/Underspecified Functions/test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c index 86e940a8e28..324ce9098f4 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c +++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c @@ -30,8 +30,8 @@ void test(int *argv[]) { not_yet_declared1(1); // BAD (GOOD for everything except for cpp/implicit-function-declaration) not_yet_declared2(1); // BAD (GOOD for everything except for cpp/implicit-function-declaration) - not_yet_declared2(ca); // BAD - not_yet_declared2(); // BAD + not_yet_declared2(ca); // BAD (GOOD for everything except for cpp/mistyped-function-arguments) + not_yet_declared2(); // GOOD declared_empty_defined_with(); // BAD declared_empty_defined_with(1); // GOOD From 4fa8c6ae6549a4cbc3bc8cef1a5a99cd73e143fc Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Fri, 22 Nov 2024 15:09:30 +0000 Subject: [PATCH 201/470] C++: Add change note --- cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md diff --git a/cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md b/cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md new file mode 100644 index 00000000000..9ac608ac74c --- /dev/null +++ b/cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query produces no results if the function has been implicitly declared. From 60155ce2052ec22a9ed6e1c5cdeba92bda740003 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Fri, 22 Nov 2024 15:30:24 +0000 Subject: [PATCH 202/470] C++: Address review comments --- cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md | 2 +- .../query-tests/Likely Bugs/Underspecified Functions/test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md b/cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md index 9ac608ac74c..116df08838a 100644 --- a/cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md +++ b/cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query produces no results if the function has been implicitly declared. +* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query no longer produces results if the function has been implicitly declared. diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c index 324ce9098f4..5bcd12e9c2d 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c +++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c @@ -31,7 +31,7 @@ void test(int *argv[]) { not_yet_declared1(1); // BAD (GOOD for everything except for cpp/implicit-function-declaration) not_yet_declared2(1); // BAD (GOOD for everything except for cpp/implicit-function-declaration) not_yet_declared2(ca); // BAD (GOOD for everything except for cpp/mistyped-function-arguments) - not_yet_declared2(); // GOOD + not_yet_declared2(); // BAD [NOT DETECTED] (GOOD for everything except for cpp/too-few-arguments) declared_empty_defined_with(); // BAD declared_empty_defined_with(1); // GOOD From 3b4fdb3fc2922949341b8e23d381e18ce026d179 Mon Sep 17 00:00:00 2001 From: Calum Grant <42069085+calumgrant@users.noreply.github.com> Date: Fri, 22 Nov 2024 15:39:28 +0000 Subject: [PATCH 203/470] Update cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- .../query-tests/Likely Bugs/Underspecified Functions/test.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c index 5bcd12e9c2d..d77c16683ed 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c +++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c @@ -30,7 +30,8 @@ void test(int *argv[]) { not_yet_declared1(1); // BAD (GOOD for everything except for cpp/implicit-function-declaration) not_yet_declared2(1); // BAD (GOOD for everything except for cpp/implicit-function-declaration) - not_yet_declared2(ca); // BAD (GOOD for everything except for cpp/mistyped-function-arguments) + not_yet_declared2(ca); // BAD (GOOD for everything except for cpp/mistyped-function-arguments + // and cpp/too-few-arguments. Not detected in the case of cpp/too-few-arguments.) not_yet_declared2(); // BAD [NOT DETECTED] (GOOD for everything except for cpp/too-few-arguments) declared_empty_defined_with(); // BAD From fcf16848d2a881ff317d7335301027e5f53f4ec6 Mon Sep 17 00:00:00 2001 From: Calum Grant <42069085+calumgrant@users.noreply.github.com> Date: Fri, 22 Nov 2024 15:48:50 +0000 Subject: [PATCH 204/470] Revert "Revert "C++: Implement compilation_build_mode"" --- .../old.dbscheme | 2339 +++++++++++++++ .../semmlecode.cpp.dbscheme | 2323 +++++++++++++++ .../upgrade.properties | 3 + cpp/ql/lib/semmle/code/cpp/Compilation.qll | 3 + cpp/ql/lib/semmlecode.cpp.dbscheme | 16 + cpp/ql/lib/semmlecode.cpp.dbscheme.stats | 2639 +++++++++-------- .../old.dbscheme | 2323 +++++++++++++++ .../semmlecode.cpp.dbscheme | 2339 +++++++++++++++ .../upgrade.properties | 2 + 9 files changed, 10699 insertions(+), 1288 deletions(-) create mode 100644 cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/old.dbscheme create mode 100644 cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/semmlecode.cpp.dbscheme create mode 100644 cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties create mode 100644 cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/old.dbscheme create mode 100644 cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/semmlecode.cpp.dbscheme create mode 100644 cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/upgrade.properties diff --git a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/old.dbscheme b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/old.dbscheme new file mode 100644 index 00000000000..f0156f5f88a --- /dev/null +++ b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/old.dbscheme @@ -0,0 +1,2339 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * Optionally, record the build mode for each compilation. + */ +compilation_build_mode( + unique int id : @compilation ref, + int mode : int ref +); + +/* +case @compilation_build_mode.mode of + 0 = @build_mode_none +| 1 = @build_mode_manual +| 2 = @build_mode_auto +; +*/ + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref +); + +/* +case @coroutine_placeholder_variable.kind of + 1 = @handle +| 2 = @promise +| 3 = @init_await_resume +; +*/ + +coroutine_placeholder_variable( + unique int placeholder_variable: @variable ref, + int kind: int ref, + int function: @function ref +) + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @parameterized_element ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + | @c11_generic + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +| 389 = @c11_generic +| 390 = @requires_expr +| 391 = @nested_requirement +| 392 = @compound_requirement +| 393 = @concept_id +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + ; + +compound_requirement_is_noexcept( + int expr: @compound_requirement ref +); + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@parameterized_element = @function | @stmt_block | @requires_expr; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @parameterized_element ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/semmlecode.cpp.dbscheme b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..e51fad7a243 --- /dev/null +++ b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/semmlecode.cpp.dbscheme @@ -0,0 +1,2323 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref +); + +/* +case @coroutine_placeholder_variable.kind of + 1 = @handle +| 2 = @promise +| 3 = @init_await_resume +; +*/ + +coroutine_placeholder_variable( + unique int placeholder_variable: @variable ref, + int kind: int ref, + int function: @function ref +) + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @parameterized_element ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + | @c11_generic + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +| 389 = @c11_generic +| 390 = @requires_expr +| 391 = @nested_requirement +| 392 = @compound_requirement +| 393 = @concept_id +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + ; + +compound_requirement_is_noexcept( + int expr: @compound_requirement ref +); + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@parameterized_element = @function | @stmt_block | @requires_expr; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @parameterized_element ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties new file mode 100644 index 00000000000..cf362f384da --- /dev/null +++ b/cpp/downgrades/f0156f5f88ab5967c79162012c20f30600ca5ebf/upgrade.properties @@ -0,0 +1,3 @@ +description: Implement compilation_build_mode/2 +compatibility: full +compilation_build_mode.rel: delete diff --git a/cpp/ql/lib/semmle/code/cpp/Compilation.qll b/cpp/ql/lib/semmle/code/cpp/Compilation.qll index 1a8d90f991c..407dc31e05f 100644 --- a/cpp/ql/lib/semmle/code/cpp/Compilation.qll +++ b/cpp/ql/lib/semmle/code/cpp/Compilation.qll @@ -112,4 +112,7 @@ class Compilation extends @compilation { * termination, but crashing due to something like a segfault is not. */ predicate normalTermination() { compilation_finished(this, _, _) } + + /** Holds if this compilation was compiled using the "none" build mode. */ + predicate buildModeNone() { compilation_build_mode(this, 0) } } diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index e51fad7a243..f0156f5f88a 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -46,6 +46,22 @@ compilation_args( string arg : string ref ); +/** + * Optionally, record the build mode for each compilation. + */ +compilation_build_mode( + unique int id : @compilation ref, + int mode : int ref +); + +/* +case @compilation_build_mode.mode of + 0 = @build_mode_none +| 1 = @build_mode_manual +| 2 = @build_mode_auto +; +*/ + /** * The source files that are compiled by a compiler invocation. * If `id` is for the compiler invocation diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats index 7f0d99272e7..758aba34608 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats @@ -18,7 +18,7 @@ @location_default - 29764890 + 29746763 @location_stmt @@ -34,11 +34,11 @@ @file - 123251 + 123176 @folder - 16340 + 16330 @macro_expansion @@ -46,23 +46,23 @@ @other_macro_reference - 859029 + 858505 @function - 4179363 + 4176817 @fun_decl - 4543516 + 4541216 @var_decl - 8039391 + 8034962 @type_decl - 3283451 + 3281452 @namespace_decl @@ -70,11 +70,11 @@ @using_declaration - 363219 + 362998 @using_directive - 6536 + 6532 @using_enum_declaration @@ -86,7 +86,7 @@ @parameter - 6190611 + 6186841 @membervariable @@ -98,7 +98,7 @@ @localvariable - 576945 + 576952 @enumconstant @@ -330,15 +330,15 @@ @pointer - 568173 + 567827 @type_with_specifiers - 852026 + 851507 @array - 110179 + 110112 @routineptr @@ -346,7 +346,7 @@ @reference - 1276405 + 1275627 @gnu_vector @@ -358,7 +358,7 @@ @rvalue_reference - 333340 + 333137 @block @@ -366,15 +366,15 @@ @decltype - 27078 + 27061 @usertype - 5234008 + 5230820 @mangledname - 6061757 + 6058065 @type_mention @@ -386,15 +386,15 @@ @ptrtomember - 37815 + 37792 @specifier - 24743 + 24728 @gnuattribute - 553700 + 553363 @stdattribute @@ -410,15 +410,15 @@ @alignas - 4668 + 4665 @attribute_arg_token - 25210 + 25195 @attribute_arg_constant_expr - 318400 + 318207 @attribute_arg_empty @@ -450,7 +450,7 @@ @namespace - 12138 + 12131 @specialnamequalifyingelement @@ -482,7 +482,7 @@ @parexpr - 3587463 + 3587464 @arithnegexpr @@ -582,11 +582,11 @@ @gtexpr - 104110 + 104047 @ltexpr - 101776 + 101714 @geexpr @@ -634,7 +634,7 @@ @assignorexpr - 23627 + 23628 @assignxorexpr @@ -662,11 +662,11 @@ @subscriptexpr - 364477 + 364481 @callexpr - 316533 + 316340 @vastartexpr @@ -678,7 +678,7 @@ @vaendexpr - 2801 + 2799 @vacopyexpr @@ -830,7 +830,7 @@ @sizeof_pack - 5602 + 5598 @hasassignexpr @@ -978,7 +978,7 @@ @lambdaexpr - 21475 + 21462 @param_ref @@ -1022,7 +1022,7 @@ @istriviallycopyableexpr - 3734 + 3732 @isliteraltypeexpr @@ -1374,7 +1374,7 @@ @lambdacapture - 28011 + 27994 @stmt_expr @@ -1398,11 +1398,11 @@ @stmt_return - 1280140 + 1279827 @stmt_block - 1419265 + 1418867 @stmt_end_test_while @@ -1430,7 +1430,7 @@ @stmt_empty - 192682 + 192685 @stmt_continue @@ -1462,7 +1462,7 @@ @stmt_range_based_for - 8403 + 8398 @stmt_handler @@ -1478,31 +1478,31 @@ @ppd_if - 667148 + 666741 @ppd_ifdef - 263311 + 263150 @ppd_ifndef - 266579 + 266416 @ppd_elif - 25210 + 25195 @ppd_else - 209154 + 209027 @ppd_endif - 1197038 + 1196309 @ppd_plain_include - 311398 + 311208 @ppd_define @@ -1510,15 +1510,15 @@ @ppd_undef - 258642 + 258484 @ppd_include_next - 1867 + 1866 @ppd_line - 27520 + 27521 @ppd_error @@ -1900,6 +1900,54 @@ + + compilation_build_mode + 9742 + + + id + 9742 + + + mode + 11 + + + + + id + mode + + + 12 + + + 1 + 2 + 9742 + + + + + + + mode + id + + + 12 + + + 863 + 864 + 11 + + + + + + + compilation_compiling_files 11546 @@ -2164,7 +2212,7 @@ seconds - 8429 + 8030 @@ -2245,47 +2293,52 @@ 3 4 - 639 + 799 4 5 - 359 + 199 - 6 + 5 7 119 8 + 9 + 79 + + + 9 10 - 159 + 119 10 - 11 + 12 + 159 + + + 12 + 16 119 - 11 - 15 + 17 + 20 159 - 16 - 19 + 21 + 42 159 - 19 - 24 - 159 - - - 40 - 89 - 119 + 55 + 90 + 79 @@ -2368,7 +2421,7 @@ 6 7 - 439 + 399 7 @@ -2377,19 +2430,19 @@ 8 - 10 + 9 + 239 + + + 9 + 24 279 - 10 - 26 + 25 + 85 279 - - 28 - 81 - 199 - @@ -2439,8 +2492,8 @@ 79 - 125 - 126 + 124 + 125 39 @@ -2462,27 +2515,37 @@ 1 2 - 3635 + 3755 2 3 - 1917 + 1398 3 4 - 1558 + 998 4 + 5 + 759 + + + 5 6 - 719 + 439 6 - 48 - 599 + 25 + 639 + + + 46 + 47 + 39 @@ -2498,27 +2561,27 @@ 1 2 - 3595 + 3515 2 3 - 1438 + 1278 3 4 - 1358 + 599 4 5 - 639 + 878 5 6 - 479 + 759 6 @@ -2527,8 +2590,8 @@ 8 - 73 - 239 + 76 + 319 @@ -2544,12 +2607,12 @@ 1 2 - 6512 + 5753 2 3 - 1917 + 2277 @@ -2893,7 +2956,7 @@ cpu_seconds - 7507 + 7292 elapsed_seconds @@ -2943,17 +3006,17 @@ 1 2 - 6242 + 5937 2 3 - 835 + 846 3 - 15 - 428 + 16 + 507 @@ -2969,12 +3032,12 @@ 1 2 - 6976 + 6682 2 3 - 530 + 609 @@ -3003,48 +3066,48 @@ 11 - 6 - 7 + 7 + 8 11 - 9 - 10 + 8 + 9 11 - 11 - 12 + 12 + 13 11 - 16 - 17 + 13 + 14 11 - 49 - 50 + 51 + 52 11 - 154 - 155 + 163 + 164 11 - 160 - 161 + 167 + 168 11 - 204 - 205 + 187 + 188 11 - 248 - 249 + 249 + 250 11 @@ -3074,48 +3137,48 @@ 11 - 6 - 7 + 7 + 8 11 - 9 - 10 + 8 + 9 11 - 11 - 12 + 12 + 13 11 - 16 - 17 + 13 + 14 11 - 47 - 48 + 49 + 50 11 - 118 - 119 + 120 + 121 11 - 128 - 129 + 123 + 124 11 - 149 - 150 + 138 + 139 11 - 222 - 223 + 224 + 225 11 @@ -4888,31 +4951,31 @@ locations_default - 29764890 + 29746763 id - 29764890 + 29746763 container - 123251 + 123176 startLine - 2095283 + 2094007 startColumn - 36882 + 36859 endLine - 2099485 + 2098207 endColumn - 48086 + 48057 @@ -4926,7 +4989,7 @@ 1 2 - 29764890 + 29746763 @@ -4942,7 +5005,7 @@ 1 2 - 29764890 + 29746763 @@ -4958,7 +5021,7 @@ 1 2 - 29764890 + 29746763 @@ -4974,7 +5037,7 @@ 1 2 - 29764890 + 29746763 @@ -4990,7 +5053,7 @@ 1 2 - 29764890 + 29746763 @@ -5006,67 +5069,67 @@ 1 11 - 9804 + 9798 11 18 - 10270 + 10264 18 30 - 9337 + 9331 30 42 - 9804 + 9798 43 61 - 9804 + 9798 61 79 - 9337 + 9331 80 106 - 9804 + 9798 108 149 - 9337 + 9331 149 199 - 9337 + 9331 206 291 - 9337 + 9331 304 469 - 9337 + 9331 482 850 - 9337 + 9331 936 2380 - 8403 + 8398 @@ -5082,67 +5145,67 @@ 1 8 - 9337 + 9331 8 13 - 9337 + 9331 13 20 - 9804 + 9798 20 32 - 9337 + 9331 32 43 - 9804 + 9798 44 61 - 9337 + 9331 62 72 - 9337 + 9331 73 93 - 9337 + 9331 97 128 - 9337 + 9331 128 180 - 9337 + 9331 180 267 - 9337 + 9331 277 414 - 9337 + 9331 439 1465 - 9337 + 9331 1557 @@ -5163,67 +5226,67 @@ 1 4 - 8870 + 8865 4 5 - 7936 + 7931 5 6 - 7469 + 7465 6 8 - 11204 + 11197 8 10 - 9337 + 9331 10 15 - 10737 + 10731 15 23 - 9804 + 9798 23 28 - 11204 + 11197 28 34 - 9804 + 9798 34 44 - 9337 + 9331 44 55 - 9337 + 9331 55 66 - 9804 + 9798 66 77 - 8403 + 8398 @@ -5239,67 +5302,67 @@ 1 8 - 9337 + 9331 8 13 - 9337 + 9331 13 20 - 9804 + 9798 20 32 - 9337 + 9331 32 43 - 9804 + 9798 43 60 - 9337 + 9331 61 71 - 9337 + 9331 72 93 - 9337 + 9331 94 127 - 9337 + 9331 128 179 - 9337 + 9331 180 268 - 9337 + 9331 278 413 - 9337 + 9331 437 1465 - 9337 + 9331 1554 @@ -5320,67 +5383,67 @@ 1 9 - 9804 + 9798 9 13 - 9337 + 9331 13 18 - 9337 + 9331 18 26 - 10270 + 10264 27 33 - 9337 + 9331 33 39 - 9337 + 9331 39 47 - 10270 + 10264 47 53 - 9337 + 9331 53 60 - 10270 + 10264 60 66 - 9337 + 9331 66 74 - 9804 + 9798 74 78 - 9804 + 9798 78 90 - 7002 + 6998 @@ -5396,52 +5459,52 @@ 1 2 - 583112 + 582757 2 3 - 314199 + 314007 3 4 - 195615 + 195496 4 6 - 162001 + 161903 6 10 - 183010 + 182899 10 16 - 162935 + 162836 16 25 - 169004 + 168901 25 46 - 161067 + 160969 46 169 - 157333 + 157237 169 265 - 7002 + 6998 @@ -5457,42 +5520,42 @@ 1 2 - 871167 + 870636 2 3 - 273582 + 273415 3 5 - 193748 + 193630 5 8 - 173673 + 173567 8 13 - 188146 + 188031 13 20 - 161067 + 160969 20 51 - 159667 + 159570 51 265 - 74231 + 74186 @@ -5508,47 +5571,47 @@ 1 2 - 612058 + 611685 2 3 - 313265 + 313074 3 4 - 198417 + 198296 4 6 - 183010 + 182899 6 9 - 173206 + 173100 9 13 - 163402 + 163302 13 19 - 174606 + 174500 19 29 - 164802 + 164702 29 52 - 112514 + 112445 @@ -5564,22 +5627,22 @@ 1 2 - 1531779 + 1530846 2 3 - 348747 + 348534 3 5 - 162001 + 161903 5 16 - 52755 + 52723 @@ -5595,47 +5658,47 @@ 1 2 - 587781 + 587423 2 3 - 316066 + 315874 3 4 - 197483 + 197363 4 6 - 168537 + 168435 6 9 - 158266 + 158170 9 14 - 170872 + 170768 14 21 - 175073 + 174967 21 32 - 162468 + 162369 32 63 - 157799 + 157703 64 @@ -5656,67 +5719,67 @@ 1 31 - 2801 + 2799 42 85 - 2801 + 2799 86 128 - 2801 + 2799 129 229 - 2801 + 2799 247 286 - 2801 + 2799 291 360 - 2801 + 2799 373 457 - 2801 + 2799 473 565 - 2801 + 2799 566 619 - 2801 + 2799 619 689 - 2801 + 2799 696 807 - 2801 + 2799 819 1563 - 2801 + 2799 1634 5631 - 2801 + 2799 15295 @@ -5737,67 +5800,67 @@ 1 18 - 2801 + 2799 23 35 - 3268 + 3266 38 43 - 2801 + 2799 44 61 - 2801 + 2799 65 73 - 2801 + 2799 73 84 - 3268 + 3266 84 96 - 2801 + 2799 96 101 - 3268 + 3266 101 105 - 3268 + 3266 107 112 - 2801 + 2799 112 126 - 2801 + 2799 137 170 - 2801 + 2799 195 265 - 1400 + 1399 @@ -5813,67 +5876,67 @@ 1 19 - 2801 + 2799 30 72 - 2801 + 2799 83 122 - 2801 + 2799 122 205 - 2801 + 2799 214 261 - 2801 + 2799 265 322 - 2801 + 2799 322 379 - 2801 + 2799 404 430 - 2801 + 2799 453 474 - 2801 + 2799 478 505 - 2801 + 2799 511 583 - 2801 + 2799 585 836 - 2801 + 2799 1104 2196 - 2801 + 2799 2387 @@ -5894,67 +5957,67 @@ 1 19 - 2801 + 2799 30 72 - 2801 + 2799 83 122 - 2801 + 2799 122 205 - 2801 + 2799 214 261 - 2801 + 2799 265 322 - 2801 + 2799 322 380 - 2801 + 2799 404 430 - 2801 + 2799 453 474 - 2801 + 2799 477 504 - 2801 + 2799 514 582 - 2801 + 2799 585 835 - 2801 + 2799 1109 2203 - 2801 + 2799 2382 @@ -5975,67 +6038,67 @@ 1 7 - 2801 + 2799 7 11 - 3268 + 3266 11 16 - 3268 + 3266 16 22 - 2801 + 2799 22 24 - 3268 + 3266 24 28 - 2801 + 2799 29 34 - 3268 + 3266 34 41 - 3268 + 3266 41 46 - 2801 + 2799 47 49 - 1867 + 1866 49 54 - 2801 + 2799 54 74 - 2801 + 2799 75 86 - 1867 + 1866 @@ -6051,52 +6114,52 @@ 1 2 - 593383 + 593022 2 3 - 306262 + 306076 3 4 - 198417 + 198296 4 6 - 159667 + 159570 6 10 - 182543 + 182432 10 16 - 162001 + 161903 16 25 - 171338 + 171234 25 46 - 158733 + 158636 46 161 - 158266 + 158170 162 265 - 8870 + 8865 @@ -6112,47 +6175,47 @@ 1 2 - 886574 + 886034 2 3 - 260043 + 259884 3 4 - 125119 + 125043 4 6 - 140992 + 140906 6 10 - 184877 + 184765 10 15 - 168537 + 168435 15 26 - 163402 + 163302 26 120 - 158266 + 158170 121 265 - 11671 + 11664 @@ -6168,22 +6231,22 @@ 1 2 - 1529445 + 1528513 2 3 - 341744 + 341536 3 5 - 170872 + 170768 5 10 - 57424 + 57389 @@ -6199,47 +6262,47 @@ 1 2 - 623262 + 622883 2 3 - 303461 + 303276 3 4 - 201685 + 201562 4 6 - 183944 + 183832 6 9 - 169938 + 169834 9 13 - 166670 + 166568 13 19 - 175073 + 174967 19 29 - 161067 + 160969 29 52 - 114381 + 114311 @@ -6255,52 +6318,52 @@ 1 2 - 599919 + 599554 2 3 - 306262 + 306076 3 4 - 197016 + 196896 4 6 - 169004 + 168901 6 9 - 156399 + 156304 9 14 - 169004 + 168901 14 21 - 177875 + 177766 21 32 - 162001 + 161903 32 60 - 158266 + 158170 60 65 - 3734 + 3732 @@ -6316,67 +6379,67 @@ 1 2 - 5135 + 5132 2 8 - 3734 + 3732 9 186 - 3734 + 3732 193 288 - 3734 + 3732 294 495 - 3734 + 3732 503 555 - 3734 + 3732 561 633 - 3734 + 3732 640 758 - 3734 + 3732 758 869 - 3734 + 3732 875 1074 - 3734 + 3732 1074 1281 - 3734 + 3732 1289 1590 - 3734 + 3732 1685 2418 - 1867 + 1866 @@ -6392,62 +6455,62 @@ 1 2 - 5602 + 5598 2 5 - 3734 + 3732 5 65 - 3734 + 3732 70 100 - 3734 + 3732 100 111 - 3734 + 3732 112 122 - 4201 + 4199 122 140 - 3734 + 3732 143 153 - 3734 + 3732 153 161 - 4201 + 4199 161 173 - 4201 + 4199 173 178 - 3734 + 3732 188 265 - 3734 + 3732 @@ -6463,62 +6526,62 @@ 1 2 - 5602 + 5598 2 8 - 3734 + 3732 9 105 - 3734 + 3732 155 241 - 3734 + 3732 253 336 - 3734 + 3732 340 426 - 3734 + 3732 434 488 - 3734 + 3732 489 572 - 3734 + 3732 573 623 - 3734 + 3732 626 696 - 4201 + 4199 701 813 - 3734 + 3732 818 1095 - 3734 + 3732 1172 @@ -6539,67 +6602,67 @@ 1 2 - 6069 + 6065 2 4 - 3734 + 3732 4 8 - 4201 + 4199 8 15 - 3734 + 3732 15 23 - 3734 + 3732 23 29 - 3734 + 3732 29 35 - 4201 + 4199 35 39 - 3268 + 3266 39 42 - 3268 + 3266 42 44 - 3268 + 3266 44 46 - 3734 + 3732 46 49 - 3734 + 3732 49 53 - 1400 + 1399 @@ -6615,67 +6678,67 @@ 1 2 - 5602 + 5598 2 8 - 3734 + 3732 9 156 - 3734 + 3732 159 240 - 3734 + 3732 251 335 - 3734 + 3732 342 430 - 3734 + 3732 432 490 - 3734 + 3732 490 573 - 3734 + 3732 574 622 - 3734 + 3732 626 698 - 3734 + 3732 700 798 - 3734 + 3732 811 987 - 3734 + 3732 1096 1180 - 1400 + 1399 @@ -10599,23 +10662,23 @@ numlines - 1383783 + 1382941 element_id - 1376780 + 1375942 num_lines - 101776 + 101714 num_code - 84969 + 84917 num_comment - 59758 + 59722 @@ -10629,12 +10692,12 @@ 1 2 - 1369777 + 1368943 2 3 - 7002 + 6998 @@ -10650,12 +10713,12 @@ 1 2 - 1370711 + 1369876 2 3 - 6069 + 6065 @@ -10671,7 +10734,7 @@ 1 2 - 1376780 + 1375942 @@ -10687,27 +10750,27 @@ 1 2 - 68162 + 68120 2 3 - 12138 + 12131 3 4 - 7469 + 7465 4 21 - 7936 + 7931 29 921 - 6069 + 6065 @@ -10723,27 +10786,27 @@ 1 2 - 70496 + 70453 2 3 - 12138 + 12131 3 4 - 8403 + 8398 4 6 - 9337 + 9331 6 7 - 1400 + 1399 @@ -10759,22 +10822,22 @@ 1 2 - 69562 + 69520 2 3 - 14939 + 14930 3 4 - 10737 + 10731 4 7 - 6536 + 6532 @@ -10790,27 +10853,27 @@ 1 2 - 52755 + 52723 2 3 - 14472 + 14463 3 5 - 6536 + 6532 5 42 - 6536 + 6532 44 922 - 4668 + 4665 @@ -10826,27 +10889,27 @@ 1 2 - 52755 + 52723 2 3 - 16807 + 16796 3 5 - 6069 + 6065 5 8 - 6536 + 6532 8 12 - 2801 + 2799 @@ -10862,27 +10925,27 @@ 1 2 - 53222 + 53190 2 3 - 15873 + 15863 3 5 - 7469 + 7465 5 7 - 5135 + 5132 7 10 - 3268 + 3266 @@ -10898,32 +10961,32 @@ 1 2 - 34547 + 34526 2 3 - 9337 + 9331 3 4 - 4201 + 4199 4 6 - 4668 + 4665 6 11 - 5135 + 5132 17 2596 - 1867 + 1866 @@ -10939,32 +11002,32 @@ 1 2 - 34547 + 34526 2 3 - 9337 + 9331 3 4 - 4201 + 4199 4 6 - 4668 + 4665 6 8 - 4668 + 4665 10 38 - 2334 + 2332 @@ -10980,32 +11043,32 @@ 1 2 - 34547 + 34526 2 3 - 9337 + 9331 3 4 - 4201 + 4199 4 6 - 4668 + 4665 6 10 - 4668 + 4665 10 37 - 2334 + 2332 @@ -11647,15 +11710,15 @@ files - 123251 + 123176 id - 123251 + 123176 name - 123251 + 123176 @@ -11669,7 +11732,7 @@ 1 2 - 123251 + 123176 @@ -11685,7 +11748,7 @@ 1 2 - 123251 + 123176 @@ -11695,15 +11758,15 @@ folders - 16340 + 16330 id - 16340 + 16330 name - 16340 + 16330 @@ -11717,7 +11780,7 @@ 1 2 - 16340 + 16330 @@ -11733,7 +11796,7 @@ 1 2 - 16340 + 16330 @@ -11743,15 +11806,15 @@ containerparent - 138658 + 138574 parent - 16340 + 16330 child - 138658 + 138574 @@ -11765,32 +11828,32 @@ 1 2 - 7469 + 7465 2 3 - 3268 + 3266 3 4 - 1400 + 1399 4 12 - 1400 + 1399 23 28 - 1400 + 1399 40 67 - 1400 + 1399 @@ -11806,7 +11869,7 @@ 1 2 - 138658 + 138574 @@ -12392,15 +12455,15 @@ inmacroexpansion - 109779080 + 109779103 id - 18027694 + 18027697 inv - 2700160 + 2700159 @@ -12414,12 +12477,12 @@ 1 3 - 1582361 + 1582360 3 5 - 1077793 + 1077794 5 @@ -12429,17 +12492,17 @@ 6 7 - 4819903 + 4819904 7 8 - 6385932 + 6385934 8 9 - 2605242 + 2605243 9 @@ -12460,12 +12523,12 @@ 1 2 - 378424 + 378422 2 3 - 544104 + 544105 3 @@ -12500,7 +12563,7 @@ 11 337 - 224847 + 224845 339 @@ -12520,15 +12583,15 @@ affectedbymacroexpansion - 35689251 + 35689257 id - 5156949 + 5156948 inv - 2784762 + 2784761 @@ -12542,7 +12605,7 @@ 1 2 - 2816079 + 2816078 2 @@ -12588,7 +12651,7 @@ 1 4 - 229116 + 229115 4 @@ -12603,12 +12666,12 @@ 9 12 - 251119 + 251120 12 13 - 333984 + 333985 13 @@ -12628,7 +12691,7 @@ 16 17 - 276608 + 276609 17 @@ -13607,19 +13670,19 @@ functions - 4179363 + 4176817 id - 4179363 + 4176817 name - 1895466 + 1894311 kind - 3268 + 3266 @@ -13633,7 +13696,7 @@ 1 2 - 4179363 + 4176817 @@ -13649,7 +13712,7 @@ 1 2 - 4179363 + 4176817 @@ -13665,22 +13728,22 @@ 1 2 - 1498165 + 1497253 2 3 - 153131 + 153038 3 5 - 142860 + 142773 5 952 - 101309 + 101247 @@ -13696,7 +13759,7 @@ 1 2 - 1894999 + 1893845 2 @@ -13798,15 +13861,15 @@ function_entry_point - 1151752 + 1151517 id - 1141948 + 1141719 entry_point - 1151752 + 1151517 @@ -13820,12 +13883,12 @@ 1 2 - 1132144 + 1131921 2 3 - 9804 + 9798 @@ -13841,7 +13904,7 @@ 1 2 - 1151752 + 1151517 @@ -13851,15 +13914,15 @@ function_return_type - 4184498 + 4181950 id - 4179363 + 4176817 return_type - 817945 + 817446 @@ -13873,12 +13936,12 @@ 1 2 - 4174227 + 4171685 2 3 - 5135 + 5132 @@ -13894,22 +13957,22 @@ 1 2 - 506080 + 505771 2 3 - 211489 + 211360 3 7 - 66294 + 66254 7 2231 - 34081 + 34060 @@ -14200,33 +14263,33 @@ function_deleted - 96173 + 96115 id - 96173 + 96115 function_defaulted - 73764 + 73719 id - 73764 + 73719 function_prototyped - 4087391 + 4084901 id - 4087391 + 4084901 @@ -14379,27 +14442,27 @@ fun_decls - 4548652 + 4546348 id - 4543516 + 4541216 function - 4035569 + 4033111 type_id - 816544 + 816047 name - 1797891 + 1796796 location - 3370755 + 3368702 @@ -14413,7 +14476,7 @@ 1 2 - 4543516 + 4541216 @@ -14429,12 +14492,12 @@ 1 2 - 4538381 + 4536084 2 3 - 5135 + 5132 @@ -14450,7 +14513,7 @@ 1 2 - 4543516 + 4541216 @@ -14466,7 +14529,7 @@ 1 2 - 4543516 + 4541216 @@ -14482,17 +14545,17 @@ 1 2 - 3606521 + 3603858 2 3 - 356216 + 356466 3 7 - 72830 + 72786 @@ -14508,12 +14571,12 @@ 1 2 - 3995885 + 3993452 2 3 - 39683 + 39659 @@ -14529,7 +14592,7 @@ 1 2 - 4035569 + 4033111 @@ -14545,17 +14608,17 @@ 1 2 - 3663012 + 3660781 2 3 - 311864 + 311674 3 6 - 60692 + 60655 @@ -14571,22 +14634,22 @@ 1 2 - 431381 + 431119 2 3 - 274048 + 273882 3 6 - 63493 + 63454 6 - 2476 - 47620 + 2477 + 47591 @@ -14602,22 +14665,22 @@ 1 2 - 515417 + 515103 2 3 - 203085 + 202961 3 7 - 63026 + 62988 7 2192 - 35014 + 34993 @@ -14633,17 +14696,17 @@ 1 2 - 690024 + 689604 2 4 - 67228 + 67187 4 773 - 59291 + 59255 @@ -14659,22 +14722,22 @@ 1 2 - 595251 + 594888 2 3 - 121384 + 121310 3 7 - 63493 + 63454 7 1959 - 36415 + 36393 @@ -14690,27 +14753,27 @@ 1 2 - 1228318 + 1227570 2 3 - 267045 + 266883 3 4 - 77966 + 77918 4 7 - 146128 + 146039 7 986 - 78433 + 78385 @@ -14726,22 +14789,22 @@ 1 2 - 1407593 + 1406736 2 3 - 152197 + 152104 3 5 - 136791 + 136707 5 936 - 101309 + 101247 @@ -14757,17 +14820,17 @@ 1 2 - 1579399 + 1578437 2 4 - 134923 + 134841 4 562 - 83568 + 83517 @@ -14783,27 +14846,27 @@ 1 2 - 1236254 + 1235502 2 3 - 293190 + 293011 3 4 - 78899 + 78851 4 8 - 137257 + 137174 8 542 - 52288 + 52256 @@ -14819,17 +14882,17 @@ 1 2 - 2966451 + 2964644 2 4 - 277783 + 277614 4 55 - 126520 + 126442 @@ -14845,17 +14908,17 @@ 1 2 - 3033679 + 3031832 2 7 - 244169 + 244020 7 55 - 92905 + 92849 @@ -14871,12 +14934,12 @@ 1 2 - 3207353 + 3205399 2 18 - 163402 + 163302 @@ -14892,12 +14955,12 @@ 1 2 - 3232563 + 3230595 2 13 - 138191 + 138107 @@ -14907,22 +14970,22 @@ fun_def - 1888930 + 1888246 id - 1888930 + 1888246 fun_specialized - 26144 + 26128 id - 26144 + 26128 @@ -14940,15 +15003,15 @@ fun_decl_specifiers - 2906692 + 2904922 id - 1689579 + 1688550 name - 2801 + 2799 @@ -14962,17 +15025,17 @@ 1 2 - 491140 + 490841 2 3 - 1179764 + 1179045 3 4 - 18674 + 18663 @@ -15144,11 +15207,11 @@ fun_decl_empty_throws - 1472021 + 1471124 fun_decl - 1472021 + 1471124 @@ -15208,11 +15271,11 @@ fun_decl_empty_noexcept - 863230 + 863171 fun_decl - 863230 + 863171 @@ -15317,19 +15380,19 @@ param_decl_bind - 6995017 + 6991224 id - 6995017 + 6991224 index - 7936 + 7931 fun_decl - 3835284 + 3833415 @@ -15343,7 +15406,7 @@ 1 2 - 6995017 + 6991224 @@ -15359,7 +15422,7 @@ 1 2 - 6995017 + 6991224 @@ -15438,8 +15501,8 @@ 466 - 8215 - 8216 + 8216 + 8217 466 @@ -15519,8 +15582,8 @@ 466 - 8215 - 8216 + 8216 + 8217 466 @@ -15537,27 +15600,27 @@ 1 2 - 1973899 + 1973163 2 3 - 1061647 + 1061001 3 4 - 502812 + 502505 4 8 - 290856 + 290678 8 18 - 6069 + 6065 @@ -15573,27 +15636,27 @@ 1 2 - 1973899 + 1973163 2 3 - 1061647 + 1061001 3 4 - 502812 + 502505 4 8 - 290856 + 290678 8 18 - 6069 + 6065 @@ -15603,27 +15666,27 @@ var_decls - 8110354 + 8105882 id - 8039391 + 8034962 variable - 7027231 + 7022951 type_id - 2043462 + 2042217 name - 667614 + 667208 location - 5311974 + 5308739 @@ -15637,7 +15700,7 @@ 1 2 - 8039391 + 8034962 @@ -15653,12 +15716,12 @@ 1 2 - 7971229 + 7966841 2 3 - 68162 + 68120 @@ -15674,7 +15737,7 @@ 1 2 - 8039391 + 8034962 @@ -15690,12 +15753,12 @@ 1 2 - 8036590 + 8032162 2 3 - 2801 + 2799 @@ -15711,17 +15774,17 @@ 1 2 - 6175205 + 6170977 2 3 - 698427 + 698469 3 7 - 153598 + 153504 @@ -15737,12 +15800,12 @@ 1 2 - 6855892 + 6851717 2 4 - 171338 + 171234 @@ -15758,12 +15821,12 @@ 1 2 - 6911916 + 6907706 2 3 - 115315 + 115245 @@ -15779,17 +15842,17 @@ 1 2 - 6481934 + 6477987 2 3 - 542962 + 542631 3 4 - 2334 + 2332 @@ -15805,27 +15868,27 @@ 1 2 - 1165758 + 1165048 2 3 - 477134 + 476377 3 4 - 94773 + 95182 4 7 - 184877 + 184765 7 762 - 120917 + 120844 @@ -15841,22 +15904,22 @@ 1 2 - 1299281 + 1298490 2 3 - 452390 + 452115 3 6 - 155932 + 155837 6 724 - 135857 + 135774 @@ -15872,17 +15935,17 @@ 1 2 - 1539249 + 1538311 2 3 - 383295 + 383061 3 128 - 120917 + 120844 @@ -15898,22 +15961,22 @@ 1 2 - 1365576 + 1364744 2 3 - 404303 + 404057 3 7 - 173206 + 173100 7 592 - 100375 + 100314 @@ -15929,37 +15992,37 @@ 1 2 - 341277 + 341069 2 3 - 86836 + 86783 3 4 - 48553 + 48524 4 6 - 51821 + 51790 6 12 - 52288 + 52256 12 33 - 50421 + 50390 34 - 2384 - 36415 + 2385 + 36393 @@ -15975,37 +16038,37 @@ 1 2 - 368822 + 368597 2 3 - 77966 + 77918 3 4 - 45285 + 45258 4 6 - 49487 + 49457 6 14 - 53222 + 53190 14 56 - 50888 + 50857 56 2301 - 21942 + 21929 @@ -16021,27 +16084,27 @@ 1 2 - 457059 + 456781 2 3 - 93839 + 93782 3 5 - 46686 + 46657 5 19 - 50888 + 50857 19 1182 - 19141 + 19129 @@ -16057,32 +16120,32 @@ 1 2 - 379093 + 378862 2 3 - 90571 + 90516 3 5 - 59758 + 59722 5 9 - 51354 + 51323 9 21 - 50421 + 50390 21 1010 - 36415 + 36393 @@ -16098,17 +16161,17 @@ 1 2 - 4496363 + 4493625 2 3 - 531757 + 531433 3 - 896 - 283853 + 897 + 283680 @@ -16124,17 +16187,17 @@ 1 2 - 4885727 + 4882752 2 17 - 415508 + 415255 17 892 - 10737 + 10731 @@ -16150,12 +16213,12 @@ 1 2 - 4961826 + 4958804 2 759 - 350147 + 349934 @@ -16171,12 +16234,12 @@ 1 2 - 5302637 + 5299407 2 6 - 9337 + 9331 @@ -16186,26 +16249,26 @@ var_def - 3994952 + 3992985 id - 3994952 + 3992985 var_decl_specifiers - 378626 + 378395 id - 378626 + 378395 name - 1867 + 1866 @@ -16219,7 +16282,7 @@ 1 2 - 378626 + 378395 @@ -16271,19 +16334,19 @@ type_decls - 3283451 + 3281452 id - 3283451 + 3281452 type_id - 3233030 + 3231061 location - 3166269 + 3164340 @@ -16297,7 +16360,7 @@ 1 2 - 3283451 + 3281452 @@ -16313,7 +16376,7 @@ 1 2 - 3283451 + 3281452 @@ -16329,12 +16392,12 @@ 1 2 - 3191479 + 3189536 2 5 - 41550 + 41525 @@ -16350,12 +16413,12 @@ 1 2 - 3191479 + 3189536 2 5 - 41550 + 41525 @@ -16371,12 +16434,12 @@ 1 2 - 3113980 + 3112083 2 20 - 52288 + 52256 @@ -16392,12 +16455,12 @@ 1 2 - 3113980 + 3112083 2 20 - 52288 + 52256 @@ -16407,22 +16470,22 @@ type_def - 2641981 + 2640372 id - 2641981 + 2640372 type_decl_top - 743713 + 743260 type_decl - 743713 + 743260 @@ -16795,19 +16858,19 @@ usings - 369755 + 369530 id - 369755 + 369530 element_id - 315599 + 315407 location - 247904 + 247753 kind @@ -16825,7 +16888,7 @@ 1 2 - 369755 + 369530 @@ -16841,7 +16904,7 @@ 1 2 - 369755 + 369530 @@ -16857,7 +16920,7 @@ 1 2 - 369755 + 369530 @@ -16873,17 +16936,17 @@ 1 2 - 263311 + 263150 2 3 - 50888 + 50857 3 5 - 1400 + 1399 @@ -16899,17 +16962,17 @@ 1 2 - 263311 + 263150 2 3 - 50888 + 50857 3 5 - 1400 + 1399 @@ -16925,7 +16988,7 @@ 1 2 - 315599 + 315407 @@ -16941,22 +17004,22 @@ 1 2 - 202618 + 202495 2 4 - 10737 + 10731 4 5 - 31279 + 31260 5 11 - 3268 + 3266 @@ -16972,22 +17035,22 @@ 1 2 - 202618 + 202495 2 4 - 10737 + 10731 4 5 - 31279 + 31260 5 11 - 3268 + 3266 @@ -17003,7 +17066,7 @@ 1 2 - 247904 + 247753 @@ -17787,23 +17850,23 @@ params - 6354480 + 6350610 id - 6190611 + 6186841 function - 3491673 + 3489546 index - 7936 + 7931 type_id - 1846445 + 1845321 @@ -17817,7 +17880,7 @@ 1 2 - 6190611 + 6186841 @@ -17833,7 +17896,7 @@ 1 2 - 6190611 + 6186841 @@ -17849,12 +17912,12 @@ 1 2 - 6066892 + 6063198 2 4 - 123718 + 123643 @@ -17870,22 +17933,22 @@ 1 2 - 1867454 + 1866317 2 3 - 952868 + 952288 3 4 - 429981 + 429719 4 18 - 241368 + 241221 @@ -17901,22 +17964,22 @@ 1 2 - 1867454 + 1866317 2 3 - 952868 + 952288 3 4 - 429981 + 429719 4 18 - 241368 + 241221 @@ -17932,22 +17995,22 @@ 1 2 - 2165780 + 2164461 2 3 - 826815 + 826311 3 4 - 346412 + 346201 4 12 - 152664 + 152571 @@ -18145,7 +18208,7 @@ 6 7 - 1400 + 1399 7 @@ -18201,22 +18264,22 @@ 1 2 - 1183966 + 1183245 2 3 - 406171 + 405923 3 7 - 154064 + 153971 7 518 - 102243 + 102180 @@ -18232,22 +18295,22 @@ 1 2 - 1404792 + 1403937 2 3 - 212422 + 212293 3 7 - 147528 + 147439 7 502 - 81701 + 81651 @@ -18263,17 +18326,17 @@ 1 2 - 1420199 + 1419334 2 3 - 347346 + 347135 3 13 - 78899 + 78851 @@ -18283,11 +18346,11 @@ overrides - 125725 + 125735 new - 122752 + 122762 old @@ -18305,7 +18368,7 @@ 1 2 - 119788 + 119797 2 @@ -18713,11 +18776,11 @@ localvariables - 576945 + 576952 id - 576945 + 576952 type_id @@ -18725,7 +18788,7 @@ name - 90547 + 90549 @@ -18739,7 +18802,7 @@ 1 2 - 576945 + 576952 @@ -18755,7 +18818,7 @@ 1 2 - 576945 + 576952 @@ -18812,7 +18875,7 @@ 1 2 - 26912 + 26913 2 @@ -18848,12 +18911,12 @@ 1 2 - 57031 + 57032 2 3 - 14284 + 14285 3 @@ -18884,7 +18947,7 @@ 1 2 - 76491 + 76492 2 @@ -18894,7 +18957,7 @@ 3 1486 - 6644 + 6645 @@ -19922,31 +19985,31 @@ builtintypes - 26144 + 26128 id - 26144 + 26128 name - 26144 + 26128 kind - 26144 + 26128 size - 3268 + 3266 sign - 1400 + 1399 alignment - 2334 + 2332 @@ -19960,7 +20023,7 @@ 1 2 - 26144 + 26128 @@ -19976,7 +20039,7 @@ 1 2 - 26144 + 26128 @@ -19992,7 +20055,7 @@ 1 2 - 26144 + 26128 @@ -20008,7 +20071,7 @@ 1 2 - 26144 + 26128 @@ -20024,7 +20087,7 @@ 1 2 - 26144 + 26128 @@ -20040,7 +20103,7 @@ 1 2 - 26144 + 26128 @@ -20056,7 +20119,7 @@ 1 2 - 26144 + 26128 @@ -20072,7 +20135,7 @@ 1 2 - 26144 + 26128 @@ -20088,7 +20151,7 @@ 1 2 - 26144 + 26128 @@ -20104,7 +20167,7 @@ 1 2 - 26144 + 26128 @@ -20120,7 +20183,7 @@ 1 2 - 26144 + 26128 @@ -20136,7 +20199,7 @@ 1 2 - 26144 + 26128 @@ -20152,7 +20215,7 @@ 1 2 - 26144 + 26128 @@ -20168,7 +20231,7 @@ 1 2 - 26144 + 26128 @@ -20184,7 +20247,7 @@ 1 2 - 26144 + 26128 @@ -20343,7 +20406,7 @@ 3 4 - 2334 + 2332 @@ -20359,12 +20422,12 @@ 1 2 - 1867 + 1866 2 3 - 1400 + 1399 @@ -20479,7 +20542,7 @@ 5 6 - 1400 + 1399 @@ -20603,7 +20666,7 @@ 2 3 - 2334 + 2332 @@ -20619,7 +20682,7 @@ 3 4 - 2334 + 2332 @@ -20629,23 +20692,23 @@ derivedtypes - 3669548 + 3667313 id - 3669548 + 3667313 name - 1552788 + 1551842 kind - 2801 + 2799 type_id - 2362796 + 2361357 @@ -20659,7 +20722,7 @@ 1 2 - 3669548 + 3667313 @@ -20675,7 +20738,7 @@ 1 2 - 3669548 + 3667313 @@ -20691,7 +20754,7 @@ 1 2 - 3669548 + 3667313 @@ -20707,17 +20770,17 @@ 1 2 - 1324025 + 1323218 2 4 - 120450 + 120377 4 1153 - 108312 + 108246 @@ -20733,7 +20796,7 @@ 1 2 - 1551854 + 1550909 2 @@ -20754,17 +20817,17 @@ 1 2 - 1324025 + 1323218 2 4 - 120450 + 120377 4 1135 - 108312 + 108246 @@ -20903,22 +20966,22 @@ 1 2 - 1515439 + 1514516 2 3 - 546230 + 545897 3 4 - 218492 + 218359 4 72 - 82634 + 82584 @@ -20934,22 +20997,22 @@ 1 2 - 1526644 + 1525714 2 3 - 538760 + 538432 3 4 - 215690 + 215559 4 72 - 81701 + 81651 @@ -20965,22 +21028,22 @@ 1 2 - 1519641 + 1518715 2 3 - 549965 + 549630 3 4 - 217558 + 217425 4 6 - 75631 + 75585 @@ -20990,11 +21053,11 @@ pointerishsize - 2707342 + 2705693 id - 2707342 + 2705693 size @@ -21016,7 +21079,7 @@ 1 2 - 2707342 + 2705693 @@ -21032,7 +21095,7 @@ 1 2 - 2707342 + 2705693 @@ -21106,23 +21169,23 @@ arraysizes - 88237 + 88183 id - 88237 + 88183 num_elements - 31746 + 31727 bytesize - 33147 + 33127 alignment - 1867 + 1866 @@ -21136,7 +21199,7 @@ 1 2 - 88237 + 88183 @@ -21152,7 +21215,7 @@ 1 2 - 88237 + 88183 @@ -21168,7 +21231,7 @@ 1 2 - 88237 + 88183 @@ -21184,22 +21247,22 @@ 1 2 - 1867 + 1866 2 3 - 23810 + 23795 3 5 - 2801 + 2799 5 13 - 2801 + 2799 13 @@ -21220,17 +21283,17 @@ 1 2 - 26611 + 26595 2 3 - 2334 + 2332 3 7 - 2801 + 2799 @@ -21246,17 +21309,17 @@ 1 2 - 26611 + 26595 2 3 - 2801 + 2799 3 5 - 2334 + 2332 @@ -21272,27 +21335,27 @@ 1 2 - 1867 + 1866 2 3 - 23810 + 23795 3 4 - 3268 + 3266 4 6 - 2334 + 2332 7 16 - 1867 + 1866 @@ -21308,17 +21371,17 @@ 1 2 - 27544 + 27528 2 3 - 3734 + 3732 3 5 - 1867 + 1866 @@ -21334,12 +21397,12 @@ 1 2 - 27544 + 27528 2 3 - 4668 + 4665 4 @@ -21791,19 +21854,19 @@ usertypes - 5234008 + 5230820 id - 5234008 + 5230820 name - 1352503 + 1351680 kind - 5135 + 5132 @@ -21817,7 +21880,7 @@ 1 2 - 5234008 + 5230820 @@ -21833,7 +21896,7 @@ 1 2 - 5234008 + 5230820 @@ -21849,27 +21912,27 @@ 1 2 - 983681 + 983082 2 3 - 153598 + 153504 3 7 - 104577 + 104513 7 61 - 101776 + 101714 65 874 - 8870 + 8865 @@ -21885,17 +21948,17 @@ 1 2 - 1211977 + 1211239 2 3 - 125586 + 125509 3 7 - 14939 + 14930 @@ -22037,19 +22100,19 @@ usertypesize - 1706386 + 1705347 id - 1706386 + 1705347 size - 13539 + 13530 alignment - 2334 + 2332 @@ -22063,7 +22126,7 @@ 1 2 - 1706386 + 1705347 @@ -22079,7 +22142,7 @@ 1 2 - 1706386 + 1705347 @@ -22095,12 +22158,12 @@ 1 2 - 3268 + 3266 2 3 - 4201 + 4199 3 @@ -22151,12 +22214,12 @@ 1 2 - 10270 + 10264 2 3 - 2801 + 2799 3 @@ -22307,15 +22370,15 @@ mangled_name - 9019338 + 9013845 id - 9019338 + 9013845 mangled_name - 6061757 + 6058065 is_complete @@ -22333,7 +22396,7 @@ 1 2 - 9019338 + 9013845 @@ -22349,7 +22412,7 @@ 1 2 - 9019338 + 9013845 @@ -22365,12 +22428,12 @@ 1 2 - 5789108 + 5785583 2 874 - 272648 + 272482 @@ -22386,7 +22449,7 @@ 1 2 - 6061757 + 6058065 @@ -22439,48 +22502,48 @@ is_standard_layout_class - 1253995 + 1253232 id - 1253995 + 1253232 is_complete - 1645694 + 1644692 id - 1645694 + 1644692 is_class_template - 398234 + 397992 id - 398234 + 397992 class_instantiation - 1089659 + 1088996 to - 1089659 + 1088996 from - 168537 + 168435 @@ -22494,7 +22557,7 @@ 1 2 - 1089659 + 1088996 @@ -22510,47 +22573,47 @@ 1 2 - 59758 + 59722 2 3 - 29412 + 29394 3 4 - 15873 + 15863 4 5 - 13072 + 13064 5 6 - 9804 + 9798 6 10 - 12605 + 12597 10 16 - 13072 + 13064 16 70 - 13539 + 13530 70 84 - 1400 + 1399 @@ -22801,19 +22864,19 @@ class_template_argument_value - 495342 + 495040 type_id - 304861 + 304676 index - 1867 + 1866 arg_value - 495342 + 495040 @@ -22827,17 +22890,17 @@ 1 2 - 249772 + 249619 2 3 - 53222 + 53190 3 4 - 1867 + 1866 @@ -22853,22 +22916,22 @@ 1 2 - 189546 + 189431 2 3 - 81234 + 81184 3 4 - 12138 + 12131 4 9 - 21942 + 21929 @@ -22946,7 +23009,7 @@ 1 2 - 495342 + 495040 @@ -22962,7 +23025,7 @@ 1 2 - 495342 + 495040 @@ -22972,15 +23035,15 @@ is_proxy_class_for - 62092 + 62055 id - 62092 + 62055 templ_param_id - 62092 + 62055 @@ -22994,7 +23057,7 @@ 1 2 - 62092 + 62055 @@ -23010,7 +23073,7 @@ 1 2 - 62092 + 62055 @@ -23316,11 +23379,11 @@ is_function_template - 1402925 + 1402070 id - 1402925 + 1402070 @@ -24451,19 +24514,19 @@ routinetypeargs - 983214 + 982616 routine - 423445 + 423187 index - 7936 + 7931 type_id - 226895 + 226757 @@ -24477,27 +24540,27 @@ 1 2 - 152664 + 152571 2 3 - 133989 + 133908 3 4 - 63493 + 63454 4 5 - 45752 + 45724 5 18 - 27544 + 27528 @@ -24513,27 +24576,27 @@ 1 2 - 182543 + 182432 2 3 - 133522 + 133441 3 4 - 58824 + 58788 4 5 - 33614 + 33593 5 11 - 14939 + 14930 @@ -24574,7 +24637,7 @@ 10 11 - 1400 + 1399 13 @@ -24635,7 +24698,7 @@ 4 5 - 1400 + 1399 5 @@ -24691,27 +24754,27 @@ 1 2 - 146595 + 146505 2 3 - 30812 + 30794 3 5 - 16807 + 16796 5 12 - 18207 + 18196 12 110 - 14472 + 14463 @@ -24727,22 +24790,22 @@ 1 2 - 172739 + 172634 2 3 - 30812 + 30794 3 6 - 18674 + 18663 6 14 - 4668 + 4665 @@ -24752,19 +24815,19 @@ ptrtomembers - 37815 + 37792 id - 37815 + 37792 type_id - 37815 + 37792 class_id - 15406 + 15397 @@ -24778,7 +24841,7 @@ 1 2 - 37815 + 37792 @@ -24794,7 +24857,7 @@ 1 2 - 37815 + 37792 @@ -24810,7 +24873,7 @@ 1 2 - 37815 + 37792 @@ -24826,7 +24889,7 @@ 1 2 - 37815 + 37792 @@ -24842,12 +24905,12 @@ 1 2 - 13539 + 13530 8 9 - 1400 + 1399 28 @@ -24868,12 +24931,12 @@ 1 2 - 13539 + 13530 8 9 - 1400 + 1399 28 @@ -24888,15 +24951,15 @@ specifiers - 24743 + 24728 id - 24743 + 24728 str - 24743 + 24728 @@ -24910,7 +24973,7 @@ 1 2 - 24743 + 24728 @@ -24926,7 +24989,7 @@ 1 2 - 24743 + 24728 @@ -24936,15 +24999,15 @@ typespecifiers - 1132144 + 1131454 type_id - 1113936 + 1113258 spec_id - 3734 + 3732 @@ -24958,12 +25021,12 @@ 1 2 - 1095728 + 1095061 2 3 - 18207 + 18196 @@ -25019,15 +25082,15 @@ funspecifiers - 10305080 + 10298338 func_id - 4068249 + 4065772 spec_id - 8403 + 8398 @@ -25041,27 +25104,27 @@ 1 2 - 1357639 + 1356812 2 3 - 640536 + 640613 3 4 - 985549 + 984482 4 5 - 780129 + 779654 5 8 - 304395 + 304209 @@ -25160,8 +25223,8 @@ 466 - 6435 - 6436 + 6434 + 6435 466 @@ -25172,15 +25235,15 @@ varspecifiers - 2246080 + 2244713 var_id - 1225050 + 1224304 spec_id - 3734 + 3732 @@ -25194,22 +25257,22 @@ 1 2 - 730174 + 729730 2 3 - 202618 + 202495 3 4 - 58357 + 58322 4 5 - 233898 + 233756 @@ -25318,19 +25381,19 @@ attributes - 561636 + 561294 id - 561636 + 561294 kind - 1400 + 1399 name - 11204 + 11197 name_space @@ -25338,7 +25401,7 @@ location - 481336 + 481043 @@ -25352,7 +25415,7 @@ 1 2 - 561636 + 561294 @@ -25368,7 +25431,7 @@ 1 2 - 561636 + 561294 @@ -25384,7 +25447,7 @@ 1 2 - 561636 + 561294 @@ -25400,7 +25463,7 @@ 1 2 - 561636 + 561294 @@ -25591,7 +25654,7 @@ 1 2 - 10270 + 10264 2 @@ -25612,7 +25675,7 @@ 1 2 - 11204 + 11197 @@ -25783,17 +25846,17 @@ 1 2 - 431848 + 431585 2 3 - 20075 + 20062 3 7 - 29412 + 29394 @@ -25809,7 +25872,7 @@ 1 2 - 481336 + 481043 @@ -25825,17 +25888,17 @@ 1 2 - 433249 + 432985 2 3 - 19608 + 19596 3 4 - 28478 + 28461 @@ -25851,7 +25914,7 @@ 1 2 - 481336 + 481043 @@ -25861,27 +25924,27 @@ attribute_args - 344078 + 343868 id - 344078 + 343868 kind - 1400 + 1399 attribute - 262844 + 262684 index - 1400 + 1399 location - 327738 + 327538 @@ -25895,7 +25958,7 @@ 1 2 - 344078 + 343868 @@ -25911,7 +25974,7 @@ 1 2 - 344078 + 343868 @@ -25927,7 +25990,7 @@ 1 2 - 344078 + 343868 @@ -25943,7 +26006,7 @@ 1 2 - 344078 + 343868 @@ -26058,17 +26121,17 @@ 1 2 - 197483 + 197363 2 3 - 49487 + 49457 3 4 - 15873 + 15863 @@ -26084,12 +26147,12 @@ 1 2 - 252573 + 252419 2 3 - 10270 + 10264 @@ -26105,17 +26168,17 @@ 1 2 - 197483 + 197363 2 3 - 49487 + 49457 3 4 - 15873 + 15863 @@ -26131,17 +26194,17 @@ 1 2 - 197483 + 197363 2 3 - 49487 + 49457 3 4 - 15873 + 15863 @@ -26256,12 +26319,12 @@ 1 2 - 313732 + 313541 2 7 - 14005 + 13997 @@ -26277,12 +26340,12 @@ 1 2 - 315132 + 314941 2 3 - 12605 + 12597 @@ -26298,12 +26361,12 @@ 1 2 - 313732 + 313541 2 7 - 14005 + 13997 @@ -26319,7 +26382,7 @@ 1 2 - 327738 + 327538 @@ -26329,15 +26392,15 @@ attribute_arg_value - 25210 + 25195 arg - 25210 + 25195 value - 15873 + 15863 @@ -26351,7 +26414,7 @@ 1 2 - 25210 + 25195 @@ -26367,12 +26430,12 @@ 1 2 - 14472 + 14463 2 16 - 1400 + 1399 @@ -26430,15 +26493,15 @@ attribute_arg_constant - 318400 + 318207 arg - 318400 + 318207 constant - 318400 + 318207 @@ -26452,7 +26515,7 @@ 1 2 - 318400 + 318207 @@ -26468,7 +26531,7 @@ 1 2 - 318400 + 318207 @@ -26647,15 +26710,15 @@ funcattributes - 630265 + 629882 func_id - 443520 + 443250 spec_id - 524754 + 524435 @@ -26669,17 +26732,17 @@ 1 2 - 338476 + 338269 2 3 - 64427 + 64387 3 6 - 39683 + 39659 6 @@ -26700,12 +26763,12 @@ 1 2 - 506080 + 505771 2 17 - 18674 + 18663 @@ -26841,15 +26904,15 @@ unspecifiedtype - 9488069 + 9482291 type_id - 9488069 + 9482291 unspecified_type_id - 6490338 + 6486385 @@ -26863,7 +26926,7 @@ 1 2 - 9488069 + 9482291 @@ -26879,17 +26942,17 @@ 1 2 - 4558923 + 4556146 2 3 - 1715723 + 1714678 3 145 - 215690 + 215559 @@ -26899,19 +26962,19 @@ member - 3881037 + 3878673 parent - 545763 + 545431 index - 92905 + 92849 child - 3809607 + 3807287 @@ -26925,47 +26988,47 @@ 1 2 - 129788 + 129709 2 3 - 64894 + 64854 3 4 - 73297 + 73252 4 5 - 75165 + 75119 5 6 - 40617 + 40592 6 8 - 46686 + 46657 8 14 - 45752 + 45724 14 30 - 41550 + 41525 30 200 - 28011 + 27994 @@ -26981,52 +27044,52 @@ 1 2 - 129788 + 129709 2 3 - 64894 + 64854 3 4 - 73297 + 73252 4 5 - 76098 + 76052 5 6 - 39683 + 39659 6 7 - 24276 + 24262 7 9 - 42017 + 41992 9 17 - 43885 + 43858 17 41 - 41550 + 41525 41 200 - 10270 + 10264 @@ -27042,62 +27105,62 @@ 1 2 - 26144 + 26128 2 3 - 7002 + 6998 3 4 - 3734 + 3732 4 5 - 7936 + 7931 5 6 - 5602 + 5598 6 7 - 5602 + 5598 7 9 - 7469 + 7465 9 16 - 7002 + 6998 16 52 - 7002 + 6998 52 107 - 7002 + 6998 108 577 - 7002 + 6998 737 1162 - 1400 + 1399 @@ -27113,62 +27176,62 @@ 1 2 - 26144 + 26128 2 3 - 7002 + 6998 3 4 - 3734 + 3732 4 5 - 7936 + 7931 5 6 - 5602 + 5598 6 7 - 5602 + 5598 7 9 - 7469 + 7465 9 16 - 7002 + 6998 16 52 - 7002 + 6998 52 107 - 7002 + 6998 108 577 - 7002 + 6998 738 1163 - 1400 + 1399 @@ -27184,7 +27247,7 @@ 1 2 - 3809607 + 3807287 @@ -27200,12 +27263,12 @@ 1 2 - 3738177 + 3735900 2 3 - 71430 + 71386 @@ -28735,15 +28798,15 @@ commentbinding - 3091104 + 3089221 id - 2445431 + 2443942 element - 3014538 + 3012702 @@ -28757,12 +28820,12 @@ 1 2 - 2368399 + 2366956 2 97 - 77032 + 76985 @@ -28778,12 +28841,12 @@ 1 2 - 2937972 + 2936183 2 3 - 76565 + 76519 @@ -28793,15 +28856,15 @@ exprconv - 7032991 + 7032993 converted - 7032991 + 7032993 conversion - 7032991 + 7032993 @@ -28815,7 +28878,7 @@ 1 2 - 7032991 + 7032993 @@ -28831,7 +28894,7 @@ 1 2 - 7032991 + 7032993 @@ -29188,15 +29251,15 @@ namespaces - 12138 + 12131 id - 12138 + 12131 name - 9804 + 9798 @@ -29210,7 +29273,7 @@ 1 2 - 12138 + 12131 @@ -29226,7 +29289,7 @@ 1 2 - 8403 + 8398 2 @@ -29246,26 +29309,26 @@ namespace_inline - 1400 + 1399 id - 1400 + 1399 namespacembrs - 2388007 + 2386553 parentid - 10270 + 10264 memberid - 2388007 + 2386553 @@ -29279,7 +29342,7 @@ 1 2 - 1867 + 1866 2 @@ -29340,7 +29403,7 @@ 1 2 - 2388007 + 2386553 @@ -29836,7 +29899,7 @@ qualifyingelement - 97518 + 97537 location @@ -29950,7 +30013,7 @@ 1 2 - 58401 + 58420 2 @@ -29986,7 +30049,7 @@ 1 2 - 58401 + 58420 2 @@ -30022,7 +30085,7 @@ 1 2 - 63815 + 63834 2 @@ -30135,12 +30198,12 @@ 1 2 - 137073 + 137054 2 3 - 55684 + 55703 3 @@ -32081,7 +32144,7 @@ expr_types - 18451442 + 18451397 id @@ -32107,12 +32170,12 @@ 1 2 - 18188121 + 18188166 2 3 - 131660 + 131615 @@ -32149,17 +32212,17 @@ 2 3 - 249334 + 249345 3 4 - 102840 + 102817 4 5 - 81865 + 81877 5 @@ -32174,12 +32237,12 @@ 14 41 - 91664 + 91653 41 125325 - 44579 + 44590 @@ -33706,11 +33769,11 @@ lambdas - 21475 + 21462 expr - 21475 + 21462 default_capture @@ -33732,7 +33795,7 @@ 1 2 - 21475 + 21462 @@ -33748,7 +33811,7 @@ 1 2 - 21475 + 21462 @@ -33822,15 +33885,15 @@ lambda_capture - 28011 + 27994 id - 28011 + 27994 lambda - 20541 + 20529 index @@ -33838,7 +33901,7 @@ field - 28011 + 27994 captured_by_reference @@ -33850,7 +33913,7 @@ location - 2801 + 2799 @@ -33864,7 +33927,7 @@ 1 2 - 28011 + 27994 @@ -33880,7 +33943,7 @@ 1 2 - 28011 + 27994 @@ -33896,7 +33959,7 @@ 1 2 - 28011 + 27994 @@ -33912,7 +33975,7 @@ 1 2 - 28011 + 27994 @@ -33928,7 +33991,7 @@ 1 2 - 28011 + 27994 @@ -33944,7 +34007,7 @@ 1 2 - 28011 + 27994 @@ -33960,12 +34023,12 @@ 1 2 - 13072 + 13064 2 3 - 7469 + 7465 @@ -33981,12 +34044,12 @@ 1 2 - 13072 + 13064 2 3 - 7469 + 7465 @@ -34002,12 +34065,12 @@ 1 2 - 13072 + 13064 2 3 - 7469 + 7465 @@ -34023,7 +34086,7 @@ 1 2 - 20541 + 20529 @@ -34039,7 +34102,7 @@ 1 2 - 20541 + 20529 @@ -34055,12 +34118,12 @@ 1 2 - 13072 + 13064 2 3 - 7469 + 7465 @@ -34192,7 +34255,7 @@ 1 2 - 28011 + 27994 @@ -34208,7 +34271,7 @@ 1 2 - 28011 + 27994 @@ -34224,7 +34287,7 @@ 1 2 - 28011 + 27994 @@ -34240,7 +34303,7 @@ 1 2 - 28011 + 27994 @@ -34256,7 +34319,7 @@ 1 2 - 28011 + 27994 @@ -34272,7 +34335,7 @@ 1 2 - 28011 + 27994 @@ -34480,7 +34543,7 @@ 8 9 - 1867 + 1866 14 @@ -34501,7 +34564,7 @@ 8 9 - 1867 + 1866 14 @@ -34522,7 +34585,7 @@ 1 2 - 2801 + 2799 @@ -34538,7 +34601,7 @@ 8 9 - 1867 + 1866 14 @@ -34559,7 +34622,7 @@ 1 2 - 2801 + 2799 @@ -34575,7 +34638,7 @@ 1 2 - 2801 + 2799 @@ -36318,11 +36381,11 @@ stmt_decl_bind - 580842 + 580849 stmt - 541060 + 541066 num @@ -36330,7 +36393,7 @@ decl - 580738 + 580745 @@ -36344,7 +36407,7 @@ 1 2 - 520371 + 520377 2 @@ -36365,7 +36428,7 @@ 1 2 - 520371 + 520377 2 @@ -36568,7 +36631,7 @@ 1 2 - 580700 + 580707 2 @@ -36589,7 +36652,7 @@ 1 2 - 580738 + 580745 @@ -36599,11 +36662,11 @@ stmt_decl_entry_bind - 580842 + 580849 stmt - 541060 + 541066 num @@ -36611,7 +36674,7 @@ decl_entry - 580784 + 580791 @@ -36625,7 +36688,7 @@ 1 2 - 520371 + 520377 2 @@ -36646,7 +36709,7 @@ 1 2 - 520371 + 520377 2 @@ -36849,7 +36912,7 @@ 1 2 - 580763 + 580770 3 @@ -36870,7 +36933,7 @@ 1 2 - 580784 + 580791 @@ -36880,15 +36943,15 @@ blockscope - 1410861 + 1410469 block - 1410861 + 1410469 enclosing - 1295546 + 1295224 @@ -36902,7 +36965,7 @@ 1 2 - 1410861 + 1410469 @@ -36918,12 +36981,12 @@ 1 2 - 1230185 + 1229903 2 13 - 65360 + 65321 @@ -37119,19 +37182,19 @@ preprocdirects - 4190567 + 4188015 id - 4190567 + 4188015 kind - 5135 + 5132 location - 4149950 + 4147423 @@ -37145,7 +37208,7 @@ 1 2 - 4190567 + 4188015 @@ -37161,7 +37224,7 @@ 1 2 - 4190567 + 4188015 @@ -37309,7 +37372,7 @@ 1 2 - 4149483 + 4146956 88 @@ -37330,7 +37393,7 @@ 1 2 - 4149950 + 4147423 @@ -37340,15 +37403,15 @@ preprocpair - 1431403 + 1430532 begin - 1197038 + 1196309 elseelifend - 1431403 + 1430532 @@ -37362,17 +37425,17 @@ 1 2 - 978546 + 977950 2 3 - 208221 + 208094 3 11 - 10270 + 10264 @@ -37388,7 +37451,7 @@ 1 2 - 1431403 + 1430532 @@ -37398,22 +37461,22 @@ preproctrue - 767056 + 766589 branch - 767056 + 766589 preprocfalse - 331473 + 331271 branch - 331473 + 331271 @@ -37566,15 +37629,15 @@ includes - 313265 + 313074 id - 313265 + 313074 included - 117182 + 117111 @@ -37588,7 +37651,7 @@ 1 2 - 313265 + 313074 @@ -37604,32 +37667,32 @@ 1 2 - 61159 + 61121 2 3 - 21942 + 21929 3 4 - 12605 + 12597 4 6 - 10270 + 10264 6 14 - 8870 + 8865 14 47 - 2334 + 2332 diff --git a/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/old.dbscheme b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/old.dbscheme new file mode 100644 index 00000000000..e51fad7a243 --- /dev/null +++ b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/old.dbscheme @@ -0,0 +1,2323 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref +); + +/* +case @coroutine_placeholder_variable.kind of + 1 = @handle +| 2 = @promise +| 3 = @init_await_resume +; +*/ + +coroutine_placeholder_variable( + unique int placeholder_variable: @variable ref, + int kind: int ref, + int function: @function ref +) + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @parameterized_element ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + | @c11_generic + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +| 389 = @c11_generic +| 390 = @requires_expr +| 391 = @nested_requirement +| 392 = @compound_requirement +| 393 = @concept_id +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + ; + +compound_requirement_is_noexcept( + int expr: @compound_requirement ref +); + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@parameterized_element = @function | @stmt_block | @requires_expr; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @parameterized_element ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..f0156f5f88a --- /dev/null +++ b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/semmlecode.cpp.dbscheme @@ -0,0 +1,2339 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * Optionally, record the build mode for each compilation. + */ +compilation_build_mode( + unique int id : @compilation ref, + int mode : int ref +); + +/* +case @compilation_build_mode.mode of + 0 = @build_mode_none +| 1 = @build_mode_manual +| 2 = @build_mode_auto +; +*/ + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref +); + +/* +case @coroutine_placeholder_variable.kind of + 1 = @handle +| 2 = @promise +| 3 = @init_await_resume +; +*/ + +coroutine_placeholder_variable( + unique int placeholder_variable: @variable ref, + int kind: int ref, + int function: @function ref +) + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @parameterized_element ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + | @c11_generic + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +| 389 = @c11_generic +| 390 = @requires_expr +| 391 = @nested_requirement +| 392 = @compound_requirement +| 393 = @concept_id +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + ; + +compound_requirement_is_noexcept( + int expr: @compound_requirement ref +); + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@parameterized_element = @function | @stmt_block | @requires_expr; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @parameterized_element ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/upgrade.properties b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/upgrade.properties new file mode 100644 index 00000000000..08e1dc42eb2 --- /dev/null +++ b/cpp/ql/lib/upgrades/e51fad7a2436caefab0c6bd52f05e28e7cce4d92/upgrade.properties @@ -0,0 +1,2 @@ +description: Implement compilation_build_mode/2 +compatibility: backwards From f3cd61f04326ed7a0c414244c18bab9002243975 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 22 Nov 2024 16:19:07 +0100 Subject: [PATCH 205/470] Rust: add extended canonical paths on enum variants --- rust/extractor/src/generated/.generated.list | 2 +- rust/extractor/src/generated/top.rs | 357 ++++++++++++++---- rust/extractor/src/translate/base.rs | 55 ++- rust/ql/.generated.list | 23 +- rust/ql/.gitattributes | 5 + rust/ql/lib/codeql/rust/elements.qll | 1 + .../lib/codeql/rust/elements/Addressable.qll | 14 + rust/ql/lib/codeql/rust/elements/Item.qll | 1 + rust/ql/lib/codeql/rust/elements/Variant.qll | 2 +- .../elements/internal/AddressableImpl.qll | 21 ++ .../internal/generated/Addressable.qll | 58 +++ .../rust/elements/internal/generated/Item.qll | 35 +- .../internal/generated/ParentChild.qll | 91 +++-- .../rust/elements/internal/generated/Raw.qll | 114 +++--- .../elements/internal/generated/Synth.qll | 53 ++- .../elements/internal/generated/Variant.qll | 4 +- rust/ql/lib/rust.dbscheme | 101 ++--- .../canonical_path/anonymous.rs | 36 ++ .../canonical_path/canonical_paths.expected | 155 ++++---- .../canonical_path/canonical_paths.rs | 73 ---- .../extractor-tests/canonical_path/regular.rs | 55 +++ .../generated/Variant/Variant.ql | 13 +- .../Variant/Variant_getCrateOrigin.expected | 0 .../Variant/Variant_getCrateOrigin.ql | 7 + .../Variant_getExtendedCanonicalPath.expected | 0 .../Variant_getExtendedCanonicalPath.ql | 7 + rust/schema/annotations.py | 11 +- rust/schema/prelude.py | 14 + 28 files changed, 879 insertions(+), 429 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/elements/Addressable.qll create mode 100644 rust/ql/lib/codeql/rust/elements/internal/AddressableImpl.qll create mode 100644 rust/ql/lib/codeql/rust/elements/internal/generated/Addressable.qll create mode 100644 rust/ql/test/extractor-tests/canonical_path/anonymous.rs delete mode 100644 rust/ql/test/extractor-tests/canonical_path/canonical_paths.rs create mode 100644 rust/ql/test/extractor-tests/canonical_path/regular.rs create mode 100644 rust/ql/test/extractor-tests/generated/Variant/Variant_getCrateOrigin.expected create mode 100644 rust/ql/test/extractor-tests/generated/Variant/Variant_getCrateOrigin.ql create mode 100644 rust/ql/test/extractor-tests/generated/Variant/Variant_getExtendedCanonicalPath.expected create mode 100644 rust/ql/test/extractor-tests/generated/Variant/Variant_getExtendedCanonicalPath.ql diff --git a/rust/extractor/src/generated/.generated.list b/rust/extractor/src/generated/.generated.list index 7335c95f7b8..8d27571d5fb 100644 --- a/rust/extractor/src/generated/.generated.list +++ b/rust/extractor/src/generated/.generated.list @@ -1,2 +1,2 @@ mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 -top.rs cdfb9890318d847e6db320abd8b9e9939524ecc47bcdc8491b9c8253bd3178c2 cdfb9890318d847e6db320abd8b9e9939524ecc47bcdc8491b9c8253bd3178c2 +top.rs 97394877b36188b1ec327272cca896b070c68ae2620781aa62f43afd405b871a 97394877b36188b1ec327272cca896b070c68ae2620781aa62f43afd405b871a diff --git a/rust/extractor/src/generated/top.rs b/rust/extractor/src/generated/top.rs index 13a0adecbca..c65be2bc74e 100644 --- a/rust/extractor/src/generated/top.rs +++ b/rust/extractor/src/generated/top.rs @@ -200,6 +200,51 @@ impl From> for trap::Label { } } +#[derive(Debug)] +pub struct Addressable { + _unused: () +} + +impl Addressable { + pub fn emit_extended_canonical_path(id: trap::Label, value: String, out: &mut trap::Writer) { + out.add_tuple("addressable_extended_canonical_paths", vec![id.into(), value.into()]); + } + pub fn emit_crate_origin(id: trap::Label, value: String, out: &mut trap::Writer) { + out.add_tuple("addressable_crate_origins", vec![id.into(), value.into()]); + } +} + +impl trap::TrapClass for Addressable { + fn class_name() -> &'static str { "Addressable" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Addressable is a subclass of AstNode + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Addressable is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Addressable is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + #[derive(Debug)] pub struct ArgList { pub id: trap::TrapId, @@ -2817,72 +2862,6 @@ impl From> for trap::Label { } } -#[derive(Debug)] -pub struct Variant { - pub id: trap::TrapId, - pub attrs: Vec>, - pub expr: Option>, - pub field_list: Option>, - pub name: Option>, - pub visibility: Option>, -} - -impl trap::TrapEntry for Variant { - fn extract_id(&mut self) -> trap::TrapId { - std::mem::replace(&mut self.id, trap::TrapId::Star) - } - - fn emit(self, id: trap::Label, out: &mut trap::Writer) { - out.add_tuple("variants", vec![id.into()]); - for (i, v) in self.attrs.into_iter().enumerate() { - out.add_tuple("variant_attrs", vec![id.into(), i.into(), v.into()]); - } - if let Some(v) = self.expr { - out.add_tuple("variant_exprs", vec![id.into(), v.into()]); - } - if let Some(v) = self.field_list { - out.add_tuple("variant_field_lists", vec![id.into(), v.into()]); - } - if let Some(v) = self.name { - out.add_tuple("variant_names", vec![id.into(), v.into()]); - } - if let Some(v) = self.visibility { - out.add_tuple("variant_visibilities", vec![id.into(), v.into()]); - } - } -} - -impl trap::TrapClass for Variant { - fn class_name() -> &'static str { "Variant" } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme Variant is a subclass of AstNode - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme Variant is a subclass of Element - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme Variant is a subclass of Locatable - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - #[derive(Debug)] pub struct VariantList { pub id: trap::TrapId, @@ -5119,19 +5098,19 @@ pub struct Item { _unused: () } -impl Item { - pub fn emit_extended_canonical_path(id: trap::Label, value: String, out: &mut trap::Writer) { - out.add_tuple("item_extended_canonical_paths", vec![id.into(), value.into()]); - } - pub fn emit_crate_origin(id: trap::Label, value: String, out: &mut trap::Writer) { - out.add_tuple("item_crate_origins", vec![id.into(), value.into()]); - } -} - impl trap::TrapClass for Item { fn class_name() -> &'static str { "Item" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Item is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme Item is a subclass of AstNode @@ -7914,6 +7893,81 @@ impl From> for trap::Label { } } +#[derive(Debug)] +pub struct Variant { + pub id: trap::TrapId, + pub attrs: Vec>, + pub expr: Option>, + pub field_list: Option>, + pub name: Option>, + pub visibility: Option>, +} + +impl trap::TrapEntry for Variant { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("variants", vec![id.into()]); + for (i, v) in self.attrs.into_iter().enumerate() { + out.add_tuple("variant_attrs", vec![id.into(), i.into(), v.into()]); + } + if let Some(v) = self.expr { + out.add_tuple("variant_exprs", vec![id.into(), v.into()]); + } + if let Some(v) = self.field_list { + out.add_tuple("variant_field_lists", vec![id.into(), v.into()]); + } + if let Some(v) = self.name { + out.add_tuple("variant_names", vec![id.into(), v.into()]); + } + if let Some(v) = self.visibility { + out.add_tuple("variant_visibilities", vec![id.into(), v.into()]); + } + } +} + +impl trap::TrapClass for Variant { + fn class_name() -> &'static str { "Variant" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Variant is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Variant is a subclass of AstNode + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Variant is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Variant is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + #[derive(Debug)] pub struct WhileExpr { pub id: trap::TrapId, @@ -8289,6 +8343,15 @@ impl trap::TrapClass for Const { fn class_name() -> &'static str { "Const" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Const is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme Const is a subclass of AssocItem @@ -8386,6 +8449,15 @@ impl trap::TrapClass for Enum { fn class_name() -> &'static str { "Enum" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Enum is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme Enum is a subclass of AstNode @@ -8466,6 +8538,15 @@ impl trap::TrapClass for ExternBlock { fn class_name() -> &'static str { "ExternBlock" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ExternBlock is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme ExternBlock is a subclass of AstNode @@ -8546,6 +8627,15 @@ impl trap::TrapClass for ExternCrate { fn class_name() -> &'static str { "ExternCrate" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ExternCrate is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme ExternCrate is a subclass of AstNode @@ -8666,6 +8756,15 @@ impl trap::TrapClass for Function { fn class_name() -> &'static str { "Function" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Function is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme Function is a subclass of AssocItem @@ -8797,6 +8896,15 @@ impl trap::TrapClass for Impl { fn class_name() -> &'static str { "Impl" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Impl is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme Impl is a subclass of AstNode @@ -8879,6 +8987,15 @@ impl trap::TrapClass for MacroCall { fn class_name() -> &'static str { "MacroCall" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme MacroCall is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme MacroCall is a subclass of AssocItem @@ -8981,6 +9098,15 @@ impl trap::TrapClass for MacroDef { fn class_name() -> &'static str { "MacroDef" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme MacroDef is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme MacroDef is a subclass of AstNode @@ -9061,6 +9187,15 @@ impl trap::TrapClass for MacroRules { fn class_name() -> &'static str { "MacroRules" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme MacroRules is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme MacroRules is a subclass of AstNode @@ -9234,6 +9369,15 @@ impl trap::TrapClass for Module { fn class_name() -> &'static str { "Module" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Module is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme Module is a subclass of AstNode @@ -9398,6 +9542,15 @@ impl trap::TrapClass for Static { fn class_name() -> &'static str { "Static" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Static is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme Static is a subclass of AstNode @@ -9495,6 +9648,15 @@ impl trap::TrapClass for Struct { fn class_name() -> &'static str { "Struct" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Struct is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme Struct is a subclass of AstNode @@ -9595,6 +9757,15 @@ impl trap::TrapClass for Trait { fn class_name() -> &'static str { "Trait" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Trait is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme Trait is a subclass of AstNode @@ -9683,6 +9854,15 @@ impl trap::TrapClass for TraitAlias { fn class_name() -> &'static str { "TraitAlias" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme TraitAlias is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme TraitAlias is a subclass of AstNode @@ -9779,6 +9959,15 @@ impl trap::TrapClass for TypeAlias { fn class_name() -> &'static str { "TypeAlias" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme TypeAlias is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme TypeAlias is a subclass of AssocItem @@ -9885,6 +10074,15 @@ impl trap::TrapClass for Union { fn class_name() -> &'static str { "Union" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Union is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme Union is a subclass of AstNode @@ -9961,6 +10159,15 @@ impl trap::TrapClass for Use { fn class_name() -> &'static str { "Use" } } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Use is a subclass of Addressable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + impl From> for trap::Label { fn from(value: trap::Label) -> Self { // SAFETY: this is safe because in the dbscheme Use is a subclass of AstNode diff --git a/rust/extractor/src/translate/base.rs b/rust/extractor/src/translate/base.rs index c7e00edb331..003c86919b6 100644 --- a/rust/extractor/src/translate/base.rs +++ b/rust/extractor/src/translate/base.rs @@ -10,7 +10,9 @@ use log::Level; use ra_ap_base_db::salsa::InternKey; use ra_ap_base_db::CrateOrigin; use ra_ap_hir::db::ExpandDatabase; -use ra_ap_hir::{Adt, Crate, ItemContainer, Module, ModuleDef, PathResolution, Semantics, Type}; +use ra_ap_hir::{ + Adt, Crate, ItemContainer, Module, ModuleDef, PathResolution, Semantics, Type, Variant, +}; use ra_ap_hir_def::type_ref::Mutability; use ra_ap_hir_def::ModuleId; use ra_ap_hir_expand::ExpandTo; @@ -47,6 +49,9 @@ macro_rules! emit_detached { (Module, $self:ident, $node:ident, $label:ident) => { $self.extract_canonical_origin(&$node, $label.into()); }; + (Variant, $self:ident, $node:ident, $label:ident) => { + $self.extract_canonical_origin_of_enum_variant(&$node, $label); + }; // TODO canonical origin of other items (Path, $self:ident, $node:ident, $label:ident) => { $self.extract_canonical_destination(&$node, $label); @@ -396,16 +401,24 @@ impl<'a> Translator<'a> { ModuleDef::Adt(Adt::Struct(it)) => self.canonical_path_from_hir(it), ModuleDef::Adt(Adt::Union(it)) => self.canonical_path_from_hir(it), ModuleDef::Trait(it) => self.canonical_path_from_hir(it), + ModuleDef::Variant(it) => self.canonical_path_from_enum_variant(it), ModuleDef::Static(_) => None, ModuleDef::TraitAlias(_) => None, ModuleDef::TypeAlias(_) => None, ModuleDef::BuiltinType(_) => None, ModuleDef::Macro(_) => None, - ModuleDef::Variant(_) => None, ModuleDef::Const(_) => None, } } + fn canonical_path_from_enum_variant(&self, item: Variant) -> Option { + // if we have a Hir entity, it means we have semantics + let sema = self.semantics.as_ref().unwrap(); + let prefix = self.canonical_path_from_hir(item.parent_enum(sema.db))?; + let name = item.name(sema.db); + Some(format!("{prefix}::{}", name.as_str())) + } + fn origin_from_hir(&self, item: impl AddressableHir) -> String { // if we have a Hir entity, it means we have semantics let sema = self.semantics.as_ref().unwrap(); @@ -437,28 +450,58 @@ impl<'a> Translator<'a> { ModuleDef::Adt(Adt::Struct(it)) => Some(self.origin_from_hir(it)), ModuleDef::Adt(Adt::Union(it)) => Some(self.origin_from_hir(it)), ModuleDef::Trait(it) => Some(self.origin_from_hir(it)), + ModuleDef::Variant(it) => Some(self.origin_from_enum_variant(it)), ModuleDef::Static(_) => None, ModuleDef::TraitAlias(_) => None, ModuleDef::TypeAlias(_) => None, ModuleDef::BuiltinType(_) => None, ModuleDef::Macro(_) => None, - ModuleDef::Variant(_) => None, ModuleDef::Const(_) => None, } } + fn origin_from_enum_variant(&self, item: Variant) -> String { + // if we have a Hir entity, it means we have semantics + let sema = self.semantics.as_ref().unwrap(); + self.origin_from_hir(item.parent_enum(sema.db)) + } + pub(crate) fn extract_canonical_origin( &mut self, item: &T, - label: Label, + label: Label, ) { (|| { let sema = self.semantics.as_ref()?; let def = T::Hir::try_from_source(item, sema)?; let path = self.canonical_path_from_hir(def)?; let origin = self.origin_from_hir(def); - generated::Item::emit_crate_origin(label, origin, &mut self.trap.writer); - generated::Item::emit_extended_canonical_path(label, path, &mut self.trap.writer); + generated::Addressable::emit_crate_origin(label, origin, &mut self.trap.writer); + generated::Addressable::emit_extended_canonical_path( + label, + path, + &mut self.trap.writer, + ); + Some(()) + })(); + } + + pub(crate) fn extract_canonical_origin_of_enum_variant( + &mut self, + item: &ast::Variant, + label: Label, + ) { + (|| { + let sema = self.semantics.as_ref()?; + let def = sema.to_enum_variant_def(item)?; + let path = self.canonical_path_from_enum_variant(def)?; + let origin = self.origin_from_enum_variant(def); + generated::Addressable::emit_crate_origin(label.into(), origin, &mut self.trap.writer); + generated::Addressable::emit_extended_canonical_path( + label.into(), + path, + &mut self.trap.writer, + ); Some(()) })(); } diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 1d4dabf2871..e81f4f3cc14 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -1,5 +1,6 @@ lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll a2d9717410e73aca512cad3af633700158ddd80b1c07dfd6ebe0f84723b4ac5b 3cfd6ae768958db3a4d633b4d781a8f4be80eb7a0d2ee871773584128e4551fd lib/codeql/rust/elements/Abi.qll 4c973d28b6d628f5959d1f1cc793704572fd0acaae9a97dfce82ff9d73f73476 250f68350180af080f904cd34cb2af481c5c688dc93edf7365fd0ae99855e893 +lib/codeql/rust/elements/Addressable.qll 13011bfd2e1556694c3d440cc34af8527da4df49ad92b62f2939d3699ff2cea5 ddb25935f7553a1a384b1abe2e4b4fa90ab50b952dadec32fd867afcb054f4be lib/codeql/rust/elements/ArgList.qll 661f5100f5d3ef8351452d9058b663a2a5c720eea8cf11bedd628969741486a2 28e424aac01a90fb58cd6f9f83c7e4cf379eea39e636bc0ba07efc818be71c71 lib/codeql/rust/elements/ArrayExpr.qll a3e6e122632f4011644ec31b37f88b32fe3f2b7e388e7e878a6883309937049f 12ccb5873d95c433da5606fd371d182ef2f71b78d0c53c2d6dec10fa45852bdc lib/codeql/rust/elements/ArrayType.qll affd43d308200d60d08e8924cdbb2a17a827ebaa62a296e07bb9ce97451e3c4c 80589a7f79bf2ac293a027faf2589b3027a6c4a286533f2ffccad259a306a8cb @@ -57,7 +58,7 @@ lib/codeql/rust/elements/Impl.qll 9593c47af4fa08afb19c52aab7d0bac6740fed7ec60201 lib/codeql/rust/elements/ImplTraitType.qll f7241044f6666a509cfbc01bf6df3db5360e67dd0f9baba4a323566701359203 350636d0b1c7a77e006170cbfa9108c259dd5831b0f242da76c10be3ecc32870 lib/codeql/rust/elements/IndexExpr.qll 0e2e9f018d06ae72be0fc4ddbc019a9aacd8a06f42b4c4431760bd149e7f2290 2bcfd557abd53a48e48de7915c4f2089107c62dfb3e732a904848248dfd3727b lib/codeql/rust/elements/InferType.qll c71184ae6aa181be94e299882503350e057493e17f1133a1e96162a0e5cbd1ef f0f19b611708df45a6ff811f8066c8042a8e1ac9b7bd94910514547ea430d3d5 -lib/codeql/rust/elements/Item.qll 5c9148ff0eaeb4404c2d8156e7df0ef5753fd44ead972da05a49659ddaa25480 78446f788617e40525d4d4b489848e75f2143a90e18d40974c3bff7b1e7c825c +lib/codeql/rust/elements/Item.qll 59353bf99dea5b464f45ed0dc5cef2db8208e92985d81dcd0b5ea09b638d10e4 2b0b87a4b1a1d9b512a67279d1dec2089d22d1df121585f7a9ca9661d689f74f lib/codeql/rust/elements/ItemList.qll c33e46a9ee45ccb194a0fe5b30a6ad3bcecb0f51486c94e0191a943710a17a7d 5a69c4e7712b4529681c4406d23dc1b6b9e5b3c03552688c55addab271912ed5 lib/codeql/rust/elements/Label.qll a31d41db351af7f99a55b26cdbbc7f13b4e96b660a74e2f1cc90c17ee8df8d73 689f87cb056c8a2aefe1a0bfc2486a32feb44eb3175803c61961a6aeee53d66e lib/codeql/rust/elements/LetElse.qll 85d16cb9cb2162493a9bacfe4b9e6a3b325d9466175b6d1a8e649bdf2191b864 c268d0878e9f82e8ede930b3825745c39ab8cd4db818eb9be6dc5ca49bee7579 @@ -156,7 +157,7 @@ lib/codeql/rust/elements/Union.qll 92ffb1abc03889b9b71dae9491d4595e443c80b472474 lib/codeql/rust/elements/Use.qll e27d30ece0456a73732dfd867dfc5abdf48a50de56e7dafcab444b688610af72 7efe59c04dd2f10b4a25b8a17beb51362be0a93d73e5a9e1251cf133cf1227c3 lib/codeql/rust/elements/UseTree.qll 16b6e42146dc4c2e9d8cc6bc143933d675d1a4c9a56b309f390f4bf5df99b25d 9f8dd7d621dd15f6f1ccec676b08da02773673cbb3a3570781c16167c6e08ef4 lib/codeql/rust/elements/UseTreeList.qll 768c4ec25e8807bba65619f566b22fa5c0946c36e96c88cfdee04c2875b44554 6433c8d9acd4e346cadd5fef01d79dd35bb6245115bdceb5322c0511106030b0 -lib/codeql/rust/elements/Variant.qll b0770c3ce0a82dcb2e238024b1db4ee2b76271f5a3d94f03bdaee71a25218da1 af242bd8651b653d931bf4cd3c234bdb58c8516eb4576edc03a929232946c38e +lib/codeql/rust/elements/Variant.qll 328323ef59faf01dcf71e7d728fd10a60465a1bd24e1d3578289cdf6554e5b63 ba49c635790395d9df4398c3c0fec700c3c7761fcc6581623a45d381d23ac34d lib/codeql/rust/elements/VariantList.qll 07adfe5750b2d5b50c8629f36feba24edd84f75698a80339d4cee20f4e95829d 7d322e60c84ea45f8c8b509226da7ae3c0125bcda42a98a94e3e6a9855cab79e lib/codeql/rust/elements/Visibility.qll d2cf0727efaf8df6b3808cb4a6b2e26d18e42db766d92e97ad3ef046d91cb9e5 8947a1e2d48b532c6455ddf143fa5b1dff28c40da1f1c6a72769fc9db7ecbaf6 lib/codeql/rust/elements/WhereClause.qll da51212766700e40713fff968078a0172a4f73eebc5425d8e0d60b03c2fe59fa 0ec036aea729b8f4af0eb8118911dce715e2eb4640ae7b5e40a007a48da03899 @@ -167,6 +168,7 @@ lib/codeql/rust/elements/YeetExpr.qll 4172bf70de31cab17639da6eed4a12a7afcefd7aa9 lib/codeql/rust/elements/YieldExpr.qll de2dc096a077f6c57bba9d1c2b2dcdbecce501333753b866d77c3ffbe06aa516 1f3e8949689c09ed356ff4777394fe39f2ed2b1e6c381fd391790da4f5d5c76a lib/codeql/rust/elements/internal/AbiConstructor.qll 4484538db49d7c1d31c139f0f21879fceb48d00416e24499a1d4b1337b4141ac 460818e397f2a1a8f2e5466d9551698b0e569d4640fcb87de6c4268a519b3da1 lib/codeql/rust/elements/internal/AbiImpl.qll 01439712ecadc9dc8da6f74d2e19cee13c77f8e1e25699055da675b2c88cb02d dcc9395ef8abd1af3805f3e7fcbc2d7ce30affbce654b6f5e559924768db403c +lib/codeql/rust/elements/internal/AddressableImpl.qll e01a6104980960f5708d5a0ada774ba21db9a344e33deeaf3d3239c627268c77 b8bfc711b267df305ac9fe5f6a994f051ddeca7fc95dacd76d1bae2d4fa7adde lib/codeql/rust/elements/internal/ArgListConstructor.qll a73685c8792ae23a2d628e7357658efb3f6e34006ff6e9661863ef116ec0b015 0bee572a046e8dfc031b1216d729843991519d94ae66280f5e795d20aea07a22 lib/codeql/rust/elements/internal/ArgListImpl.qll 19664651c06b46530f0ae5745ccb3233afc97b9152e053761d641de6e9c62d38 40af167e571f5c255f264b3be7cc7f5ff42ec109661ca03dcee94e92f8facfc6 lib/codeql/rust/elements/internal/ArrayExprConstructor.qll f4ac4efefe5fe4fe1e666f35b1ee92d2243d977b3f3308151c89f61582203c09 4167ae58ec869f7dbd8467093c4a53afd7c1efcf1cc865efa62b4eb484bd7ff8 @@ -453,6 +455,7 @@ lib/codeql/rust/elements/internal/YeetExprImpl.qll e8924147c3ebe0c32d04c5b33edfd lib/codeql/rust/elements/internal/YieldExprConstructor.qll 8cbfa6405acb151ee31ccc7c89336948a597d783e8890e5c3e53853850871712 966f685eb6b9063bc359213323d3ff760b536158ecd17608e7618a3e9adf475f lib/codeql/rust/elements/internal/YieldExprImpl.qll af184649a348ddd0be16dee9daae307240bf123ace09243950342e9d71ededd9 17df90f67dd51623e8a5715b344ccd8740c8fc415af092469f801b99caacb70d lib/codeql/rust/elements/internal/generated/Abi.qll 87e1ea6b2a8ebf60e1c69176632740e4e27fc56c3f173939b098ba376562b5fa 94b2121e71c4ec94d53a79f972c05a8484ef0d80ed638f53031e7cf4dc5343d5 +lib/codeql/rust/elements/internal/generated/Addressable.qll 96a8b45166dd035b8d2c6d36b8b67019f2d4d0b4ccff6d492677c0c87197613e d8f1ce29feafc8ff7179399fc7eac5db031a7e1a8bc6b2cd75cfce1da3132e9b lib/codeql/rust/elements/internal/generated/ArgList.qll 1b75b2d7dcf524eb468a0268af6293e9d17832d6bedf3feec49a535824339b57 2bcaf464454bdfdda45fbd24d063f0f1df0eb69f684197b37105adc8f72cd1ea lib/codeql/rust/elements/internal/generated/ArrayExpr.qll 2ca97b602a707fe2c566002d8709792bb166ae52fdb7da28d7c4b8e0d66dd4bc 1cae1ef017171ec9a1ca28b4f2993b1ee26d22b51b3b04816d9b4e89fdff1fb3 lib/codeql/rust/elements/internal/generated/ArrayType.qll 225ac477f67865d72b2a2e17420f5e52c25452a3c14f7ff367f873a859f97783 0030e3bf296dd5b69ea912fc85dc7120b060780033083127257cdca792dc3f4b @@ -510,7 +513,7 @@ lib/codeql/rust/elements/internal/generated/Impl.qll e33ef5d3e49e64beca0ca9d5c0b lib/codeql/rust/elements/internal/generated/ImplTraitType.qll 3c29684f5ef386b883b79dc9758441d97f090e065be177ffc8240aaf0f3d1e7b 03ea42c2a95cf917ec73d88b7b4ca5e53e10d7b046074f59100c0ec6c2c1ed6d lib/codeql/rust/elements/internal/generated/IndexExpr.qll cf951fc40f6690e966b4dc78fa9a6221aa5c6cade44759dcb52254f799292d11 1572e71918cc4e0b7e028331b6d98c9db23100a3646cd3874d1915e06ab6211d lib/codeql/rust/elements/internal/generated/InferType.qll 23ee25135c59ea5578cdf7c34a41f606e217e7260c3c8f404d12836585d5cad4 400da322fa1be62c4e300ebdf481eb92d4226eb6c316c668da8cc5168065774f -lib/codeql/rust/elements/internal/generated/Item.qll 25e645cb41222c21065798fb6cb0488bfef007aeb9b89717f58913f9b29d5559 3146941e55db2ff7c51ec030b4414e20d66d154cf6854b1a3fa42e74a09dfb77 +lib/codeql/rust/elements/internal/generated/Item.qll 97f204f27c12689a01fef502a4eec3b587e4eaccd278ec07a34c70a33ce6119d 139af2d44f794d0f91d9aabc3d50d895107c34bd9bcb72457a2e243c14622e51 lib/codeql/rust/elements/internal/generated/ItemList.qll 73c8398a96d4caa47a2dc114d76c657bd3fcc59e4c63cb397ffac4a85b8cf8ab 540a13ca68d414e3727c3d53c6b1cc97687994d572bc74b3df99ecc8b7d8e791 lib/codeql/rust/elements/internal/generated/Label.qll 6630fe16e9d2de6c759ff2684f5b9950bc8566a1525c835c131ebb26f3eea63e 671143775e811fd88ec90961837a6c0ee4db96e54f42efd80c5ae2571661f108 lib/codeql/rust/elements/internal/generated/LetElse.qll 7ca556118b5446bfc85abba8f0edd4970e029b30d414ea824a1b5f568310a76c a403540881336f9d0269cbcdb4b87107a17ab234a985247dc52a380f150a1641 @@ -549,7 +552,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60 lib/codeql/rust/elements/internal/generated/ParenPat.qll ce24b8f8ecbf0f204af200317405724063887257460c80cf250c39b2fdf37185 e7c87d37e1a0ca7ea03840017e1aa9ddb7f927f1f3b6396c0305b46aeee33db6 lib/codeql/rust/elements/internal/generated/ParenType.qll 9cc954d73f8330dcac7b475f97748b63af5c8766dee9d2f2872c0a7e4c903537 c07534c8a9c683c4a9b11d490095647e420de0a0bfc23273eaf6f31b00244273 -lib/codeql/rust/elements/internal/generated/ParentChild.qll c1eca840f6c97dc3c7fec5deaf1be98c17558610ffc37b503571779afdadc912 9564f6ae3803505c2bc086b76e43570127a13374655d2013c77ce1863e0c1397 +lib/codeql/rust/elements/internal/generated/ParentChild.qll f82255af6c746fd074d9a1128ed481765d23b47676c7d0cca9c36b31ff1875be 80b2796553686333e8170dc2dcd6dd878e623dbdfdaef652b500b5652f0bb374 lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4 lib/codeql/rust/elements/internal/generated/Path.qll f2b1be2f8f44001a6533533c978c4a9a8b7d64838d6f39eef5f0c0e7890611b8 d724a00a38f42429ffa8fb3bffbb5ec69e16a32ceeeb1d1f026fc7adf87424a8 lib/codeql/rust/elements/internal/generated/PathExpr.qll 2096e3c1db22ee488a761690adabfc9cfdea501c99f7c5d96c0019cb113fc506 54245ce0449c4e263173213df01e079d5168a758503a5dbd61b25ad35a311140 @@ -562,7 +565,7 @@ lib/codeql/rust/elements/internal/generated/PtrType.qll 40099c5a4041314b66932dfd lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll efd93730de217cf50dcba5875595263a5eadf9f7e4e1272401342a094d158614 229b251b3d118932e31e78ac4dfb75f48b766f240f20d436062785606d44467b -lib/codeql/rust/elements/internal/generated/Raw.qll d679e866776a927f61d62ba980203e1142454606bdac69cc9b6720679ca5bbdd f47922df7f8c8efba0e2e5adde030247e43f02e9df7d263096c697bfe65c4277 +lib/codeql/rust/elements/internal/generated/Raw.qll 57c2c6a750c469f7db059660f02e4903b50c5b2f99f23f972000567dbf14e34b e16ceed92616c66b8e8b553b7043966c371154e0c75c12a02083e3b3487695db lib/codeql/rust/elements/internal/generated/RecordExpr.qll eb6cb662e463f9260efae1a6ce874fa781172063b916ef1963f861e9942d308d 1a21cbccc8f3799ff13281e822818ebfb21d81591720a427cac3625512cb9d40 lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1 lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0 @@ -588,7 +591,7 @@ lib/codeql/rust/elements/internal/generated/Static.qll 5fbd6879858cf356d4bdaa6da lib/codeql/rust/elements/internal/generated/Stmt.qll 8473ff532dd5cc9d7decaddcd174b94d610f6ca0aec8e473cc051dad9f3db917 6ef7d2b5237c2dbdcacbf7d8b39109d4dc100229f2b28b5c9e3e4fbf673ba72b lib/codeql/rust/elements/internal/generated/StmtList.qll a667193e32341e17400867c6e359878c4e645ef9f5f4d97676afc0283a33a026 a320ed678ee359302e2fc1b70a9476705cd616fcfa44a499d32f0c7715627f73 lib/codeql/rust/elements/internal/generated/Struct.qll 4d57f0db12dc7ad3e31e750a24172ef1505406b4dab16386af0674bd18bf8f4b 1a73c83df926b996f629316f74c61ea775be04532ab61b56af904223354f033e -lib/codeql/rust/elements/internal/generated/Synth.qll 1ba88215c3f0640558a644534b954e4b93acb15a0f51a1e4887230f451718aa9 747eb3bec1c7245e59ea2b500604f5b4e614e4f061473d1a22fa398ee48ba080 +lib/codeql/rust/elements/internal/generated/Synth.qll 93dd2fbc5b86714883e8b02d3dea6f4364f881a38473bc46dab4e1bcb9dd99a7 3514ae3251ad06636e1e648331943e62a26b5e6a439f51e44d4c11b94e02013b lib/codeql/rust/elements/internal/generated/SynthConstructors.qll e929c49ea60810a2bbc19ad38110b8bbaf21db54dae90393b21a3459a54abf6f e929c49ea60810a2bbc19ad38110b8bbaf21db54dae90393b21a3459a54abf6f lib/codeql/rust/elements/internal/generated/Token.qll 77a91a25ca5669703cf3a4353b591cef4d72caa6b0b9db07bb9e005d69c848d1 2fdffc4882ed3a6ca9ac6d1fb5f1ac5a471ca703e2ffdc642885fa558d6e373b lib/codeql/rust/elements/internal/generated/TokenTree.qll 8577c2b097c1be2f0f7daa5acfcf146f78674a424d99563e08a84dd3e6d91b46 d2f30764e84dbfc0a6a5d3d8a5f935cd432413688cb32da9c94e420fbc10665c @@ -614,7 +617,7 @@ lib/codeql/rust/elements/internal/generated/Union.qll 06a602aa7c7097e72fff6ea33d lib/codeql/rust/elements/internal/generated/Use.qll d42ccf3516a9f79ae8766f93ad5f09d3cdcd7b96844d4c9de64189b56018a7b4 70a9553a8f71f6cbfdd0f59a4b42292d13177613ceb0542436436e0ac2e1f8ee lib/codeql/rust/elements/internal/generated/UseTree.qll b39cbc96e473802372726d580febbfa7d73668ba476095aa4a61fae914865913 40ce6515b7df068fa8c0a7e5ae8984f50b71f6f96d625d631b28d525e3e868b7 lib/codeql/rust/elements/internal/generated/UseTreeList.qll 829441cf309f008a6a9d2e784aa414ab4c11880a658f8ee71aa4df385cd2b6a8 ced82df94fea7a191f414f7e6496d13791d2f535046844b6f712a390663ac3d0 -lib/codeql/rust/elements/internal/generated/Variant.qll 2e3d8e7a7a97f2f33d6cad458ec0ded498c17a14b697722a96fffecd50c83097 46149bb257c08d5cd9139198b6519d7ad3fd25cc9ea6bfe99deea66f5f1ef201 +lib/codeql/rust/elements/internal/generated/Variant.qll e40dbb23e07c5b70adc577efdf7a064e773207f216cad8fe8905882b1da9f4a9 13f7be36d043afcfc156d2c01bb828de882df69aa732f284aa76c5f00b063544 lib/codeql/rust/elements/internal/generated/VariantList.qll 4eb923ca341033c256ca9b8a8a5b4e14c7eac9d015be187fd97eeb25dfb1e18e e7865e975c35db49cd72cb8f9864797d3cfed16c3a675b5032b867ced2bbb405 lib/codeql/rust/elements/internal/generated/Visibility.qll aba81820f30bed0fd2cd06831f7256af15ae32525b2a437896420b4cc067ea38 d6aed90b27124b812daf2ddd14b4e181277cbe638b4ccaab74e27681ac30e4ab lib/codeql/rust/elements/internal/generated/WhereClause.qll d6c8f72bbec5d71c024f0d365c1c5e474f4d24ded0d34c56c1f66b1e4a384e9d ed14311d140eee00d3b26a4972f53e20d5af1bddf88fb5618e7e2d3ae1d816f3 @@ -623,7 +626,7 @@ lib/codeql/rust/elements/internal/generated/WhileExpr.qll fec8a9211b82a80601bf73 lib/codeql/rust/elements/internal/generated/WildcardPat.qll d74b70b57a0a66bfae017a329352a5b27a6b9e73dd5521d627f680e810c6c59e 4b913b548ba27ff3c82fcd32cf996ff329cb57d176d3bebd0fcef394486ea499 lib/codeql/rust/elements/internal/generated/YeetExpr.qll cac328200872a35337b4bcb15c851afb4743f82c080f9738d295571eb01d7392 94af734eea08129b587fed849b643e7572800e8330c0b57d727d41abda47930b lib/codeql/rust/elements/internal/generated/YieldExpr.qll 37e5f0c1e373a22bbc53d8b7f2c0e1f476e5be5080b8437c5e964f4e83fad79a 4a9a68643401637bf48e5c2b2f74a6bf0ddcb4ff76f6bffb61d436b685621e85 -lib/codeql/rust/elements.qll 173d5ffbcc2874757033caab37559e84dbcbfed319730f8e41a4e9e10b146835 173d5ffbcc2874757033caab37559e84dbcbfed319730f8e41a4e9e10b146835 +lib/codeql/rust/elements.qll 8924e84ab56326a81e5147202d31cd2ba50f73d35353d9f145da7a4a6c06b243 8924e84ab56326a81e5147202d31cd2ba50f73d35353d9f145da7a4a6c06b243 test/extractor-tests/generated/Abi/Abi.ql 7f6e7dc4af86eca3ebdc79b10373988cd0871bd78b51997d3cffd969105e5fdd 2f936b6ca005c6157c755121584410c03e4a3949c23bee302fbe05ee10ce118f test/extractor-tests/generated/Abi/Abi_getAbiString.ql a496762fcec5a0887b87023bbf93e9b650f02e20113e25c44d6e4281ae8f5335 14109c7ce11ba25e3cd6e7f1b3fcb4cb00622f2a4eac91bfe43145c5f366bc52 test/extractor-tests/generated/ArgList/ArgList.ql e412927756e72165d0e7c5c9bd3fca89d08197bbf760db8fb7683c64bb2229bc 043dba8506946fbb87753e22c387987d7eded6ddb963aa067f9e60ef9024d684 @@ -1134,9 +1137,11 @@ test/extractor-tests/generated/UseTree/UseTree_getRename.ql ec3917501f3c89ac4974 test/extractor-tests/generated/UseTree/UseTree_getUseTreeList.ql c265a88347e813840969ae934dfd2904bc06f502de77709bc0b1c7255e46382a 52a239c8ea5fd8fbfbd606559d70ecadc769887437a9bcab6fb3e774208ad868 test/extractor-tests/generated/UseTreeList/UseTreeList.ql cd943c15c86e66244caafeb95b960a5c3d351d5edbd506258744fb60a61af3b2 cfa584cd9d8aa08267fd1106745a66226b2c99fadd1da65059cc7ecf2f2e68cf test/extractor-tests/generated/UseTreeList/UseTreeList_getUseTree.ql dd72966b1cb7b04f0267503013809063fcfb145e2b2d7d5250d9f24d2e405f9a 75b953aa11c51ca0fe95e67d50d6238962d8df4a4b9054999a2c6338e5a5613d -test/extractor-tests/generated/Variant/Variant.ql bf9b928ab3b1911e6c81fdc3fb9811e754ea28bfd0e4a21dca08b844aa42c3f1 bffd4bcc5019f721010722453985b39a4285240774e474e233ebe46f1cd5beb1 +test/extractor-tests/generated/Variant/Variant.ql c60dd31adac91e09f8b1e5523d6b859747e64ef072c077b5a3326763f9f461f7 55d6446a3a831ed1137264678c5df027eb94cb3570a88d364994851fe6236999 test/extractor-tests/generated/Variant/Variant_getAttr.ql dd38e48e1eb05ce280b880652a90010eb63f7de3be7232411ba6265691249420 f8980680104de1e5fd40f264d8d62346aacaf6403a5e051f6fd680e234c82c1f +test/extractor-tests/generated/Variant/Variant_getCrateOrigin.ql 99e79930f8ff87a25f256926e5c3ce1ee0847daf6fadc5445fb33c85328b4c61 2dd64a53813790654c83be25b5e175c9c5b388e758723c2138fff095353fdd7b test/extractor-tests/generated/Variant/Variant_getExpr.ql ce00af303d28f60c5fd1dc7df628c7974aced21884e223a2f656cb4f0d1a74d5 9de51a65510cf9a15801d4207b616915bd959c95ec7330fdb502c5dff5b650cc +test/extractor-tests/generated/Variant/Variant_getExtendedCanonicalPath.ql fe6a4bfd1440e7629d47283910de84c5e8c2f5645512780e710f53540b5bc886 b1e31b765cb1a5fe063abb8c1b2115e881ae28aa3ccd39e088ff8f2af20d6cf4 test/extractor-tests/generated/Variant/Variant_getFieldList.ql 083c8cf61989663de33d99b72dec231c308ccc8bb6739921465c473a07e8ea03 d03bff6945853c940acdc053b813d53b008ddab9a8bd4307826433828d4763ce test/extractor-tests/generated/Variant/Variant_getName.ql 0d7b47bec9f9031c67f7b684112a84a311ef9b2efeb260bd7cd6f424011ca0d8 73565e6f965dd7fd7bb9b3408c7d7b69120e1971b67ab307fed293eb663a59ae test/extractor-tests/generated/Variant/Variant_getVisibility.ql 2c8f365d28d96af55589f4d71ac3fee718b319b4cbc784560c0591d1f605a119 13160d9cf39fe169410eff6c338f5d063e1948109e8f18dd33ea0064f1dd9283 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 5e2e30e2ffe..9734b0c0e27 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -2,6 +2,7 @@ /.gitattributes linguist-generated /lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll linguist-generated /lib/codeql/rust/elements/Abi.qll linguist-generated +/lib/codeql/rust/elements/Addressable.qll linguist-generated /lib/codeql/rust/elements/ArgList.qll linguist-generated /lib/codeql/rust/elements/ArrayExpr.qll linguist-generated /lib/codeql/rust/elements/ArrayType.qll linguist-generated @@ -169,6 +170,7 @@ /lib/codeql/rust/elements/YieldExpr.qll linguist-generated /lib/codeql/rust/elements/internal/AbiConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/AbiImpl.qll linguist-generated +/lib/codeql/rust/elements/internal/AddressableImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ArgListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ArgListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ArrayExprConstructor.qll linguist-generated @@ -455,6 +457,7 @@ /lib/codeql/rust/elements/internal/YieldExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/YieldExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/generated/Abi.qll linguist-generated +/lib/codeql/rust/elements/internal/generated/Addressable.qll linguist-generated /lib/codeql/rust/elements/internal/generated/ArgList.qll linguist-generated /lib/codeql/rust/elements/internal/generated/ArrayExpr.qll linguist-generated /lib/codeql/rust/elements/internal/generated/ArrayType.qll linguist-generated @@ -1138,7 +1141,9 @@ /test/extractor-tests/generated/UseTreeList/UseTreeList_getUseTree.ql linguist-generated /test/extractor-tests/generated/Variant/Variant.ql linguist-generated /test/extractor-tests/generated/Variant/Variant_getAttr.ql linguist-generated +/test/extractor-tests/generated/Variant/Variant_getCrateOrigin.ql linguist-generated /test/extractor-tests/generated/Variant/Variant_getExpr.ql linguist-generated +/test/extractor-tests/generated/Variant/Variant_getExtendedCanonicalPath.ql linguist-generated /test/extractor-tests/generated/Variant/Variant_getFieldList.ql linguist-generated /test/extractor-tests/generated/Variant/Variant_getName.ql linguist-generated /test/extractor-tests/generated/Variant/Variant_getVisibility.ql linguist-generated diff --git a/rust/ql/lib/codeql/rust/elements.qll b/rust/ql/lib/codeql/rust/elements.qll index b516d8a9d18..0959b104517 100644 --- a/rust/ql/lib/codeql/rust/elements.qll +++ b/rust/ql/lib/codeql/rust/elements.qll @@ -4,6 +4,7 @@ */ import codeql.rust.elements.Abi +import codeql.rust.elements.Addressable import codeql.rust.elements.ArgList import codeql.rust.elements.ArrayExpr import codeql.rust.elements.ArrayType diff --git a/rust/ql/lib/codeql/rust/elements/Addressable.qll b/rust/ql/lib/codeql/rust/elements/Addressable.qll new file mode 100644 index 00000000000..c5edd19adcb --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/Addressable.qll @@ -0,0 +1,14 @@ +// generated by codegen, do not edit +/** + * This module provides the public class `Addressable`. + */ + +private import internal.AddressableImpl +import codeql.rust.elements.AstNode + +/** + * Something that can be addressed by a path. + * + * TODO: This does not yet include all possible cases. + */ +final class Addressable = Impl::Addressable; diff --git a/rust/ql/lib/codeql/rust/elements/Item.qll b/rust/ql/lib/codeql/rust/elements/Item.qll index 838ba32b964..b95620551ba 100644 --- a/rust/ql/lib/codeql/rust/elements/Item.qll +++ b/rust/ql/lib/codeql/rust/elements/Item.qll @@ -4,6 +4,7 @@ */ private import internal.ItemImpl +import codeql.rust.elements.Addressable import codeql.rust.elements.Stmt /** diff --git a/rust/ql/lib/codeql/rust/elements/Variant.qll b/rust/ql/lib/codeql/rust/elements/Variant.qll index 6100928696e..658143dbfa2 100644 --- a/rust/ql/lib/codeql/rust/elements/Variant.qll +++ b/rust/ql/lib/codeql/rust/elements/Variant.qll @@ -4,7 +4,7 @@ */ private import internal.VariantImpl -import codeql.rust.elements.AstNode +import codeql.rust.elements.Addressable import codeql.rust.elements.Attr import codeql.rust.elements.Expr import codeql.rust.elements.FieldList diff --git a/rust/ql/lib/codeql/rust/elements/internal/AddressableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/AddressableImpl.qll new file mode 100644 index 00000000000..b3fe47b294a --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/AddressableImpl.qll @@ -0,0 +1,21 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module provides a hand-modifiable wrapper around the generated class `Addressable`. + * + * INTERNAL: Do not use. + */ + +private import codeql.rust.elements.internal.generated.Addressable + +/** + * INTERNAL: This module contains the customizable definition of `Addressable` and should not + * be referenced directly. + */ +module Impl { + /** + * Something that can be addressed by a path. + * + * TODO: This does not yet include all possible cases. + */ + class Addressable extends Generated::Addressable { } +} diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Addressable.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Addressable.qll new file mode 100644 index 00000000000..9d4ba1e976a --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Addressable.qll @@ -0,0 +1,58 @@ +// generated by codegen, do not edit +/** + * This module provides the generated definition of `Addressable`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.elements.internal.generated.Synth +private import codeql.rust.elements.internal.generated.Raw +import codeql.rust.elements.internal.AstNodeImpl::Impl as AstNodeImpl + +/** + * INTERNAL: This module contains the fully generated definition of `Addressable` and should not + * be referenced directly. + */ +module Generated { + /** + * Something that can be addressed by a path. + * + * TODO: This does not yet include all possible cases. + * INTERNAL: Do not reference the `Generated::Addressable` class directly. + * Use the subclass `Addressable`, where the following predicates are available. + */ + class Addressable extends Synth::TAddressable, AstNodeImpl::AstNode { + /** + * Gets the extended canonical path of this addressable, if it exists. + * + * Either a canonical path (see https://doc.rust-lang.org/reference/paths.html#canonical-paths), + * or `{}::name` for addressable items defined in an anonymous block (and only + * addressable there-in). + * INTERNAL: Do not use. + */ + string getExtendedCanonicalPath() { + result = Synth::convertAddressableToRaw(this).(Raw::Addressable).getExtendedCanonicalPath() + } + + /** + * Holds if `getExtendedCanonicalPath()` exists. + * INTERNAL: Do not use. + */ + final predicate hasExtendedCanonicalPath() { exists(this.getExtendedCanonicalPath()) } + + /** + * Gets the crate origin of this addressable, if it exists. + * + * One of `rustc:`, `repo::` or `lang:`. + * INTERNAL: Do not use. + */ + string getCrateOrigin() { + result = Synth::convertAddressableToRaw(this).(Raw::Addressable).getCrateOrigin() + } + + /** + * Holds if `getCrateOrigin()` exists. + * INTERNAL: Do not use. + */ + final predicate hasCrateOrigin() { exists(this.getCrateOrigin()) } + } +} diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Item.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Item.qll index 429221c7f18..39149c25258 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Item.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Item.qll @@ -6,6 +6,7 @@ private import codeql.rust.elements.internal.generated.Synth private import codeql.rust.elements.internal.generated.Raw +import codeql.rust.elements.internal.AddressableImpl::Impl as AddressableImpl import codeql.rust.elements.internal.StmtImpl::Impl as StmtImpl /** @@ -21,37 +22,5 @@ module Generated { * INTERNAL: Do not reference the `Generated::Item` class directly. * Use the subclass `Item`, where the following predicates are available. */ - class Item extends Synth::TItem, StmtImpl::Stmt { - /** - * Gets the extended canonical path of this item, if it exists. - * - * Either a canonical path (see https://doc.rust-lang.org/reference/paths.html#canonical-paths), - * or `{}::name` for addressable items defined in an anonymous block (and only - * addressable there-in). - * INTERNAL: Do not use. - */ - string getExtendedCanonicalPath() { - result = Synth::convertItemToRaw(this).(Raw::Item).getExtendedCanonicalPath() - } - - /** - * Holds if `getExtendedCanonicalPath()` exists. - * INTERNAL: Do not use. - */ - final predicate hasExtendedCanonicalPath() { exists(this.getExtendedCanonicalPath()) } - - /** - * Gets the crate origin of this item, if it exists. - * - * One of `rustc:`, `repo::` or `lang:`. - * INTERNAL: Do not use. - */ - string getCrateOrigin() { result = Synth::convertItemToRaw(this).(Raw::Item).getCrateOrigin() } - - /** - * Holds if `getCrateOrigin()` exists. - * INTERNAL: Do not use. - */ - final predicate hasCrateOrigin() { exists(this.getCrateOrigin()) } - } + class Item extends Synth::TItem, StmtImpl::Stmt, AddressableImpl::Addressable { } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll index a396da834d4..233de518012 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll @@ -128,6 +128,21 @@ private module Impl { ) } + private Element getImmediateChildOfAddressable( + Addressable e, int index, string partialPredicateCall + ) { + exists(int b, int bAstNode, int n | + b = 0 and + bAstNode = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAstNode(e, i, _)) | i) and + n = bAstNode and + ( + none() + or + result = getImmediateChildOfAstNode(e, index - b, partialPredicateCall) + ) + ) + } + private Element getImmediateChildOfArgList(ArgList e, int index, string partialPredicateCall) { exists(int b, int bAstNode, int n, int nArg | b = 0 and @@ -1117,37 +1132,6 @@ private module Impl { ) } - private Element getImmediateChildOfVariant(Variant e, int index, string partialPredicateCall) { - exists( - int b, int bAstNode, int n, int nAttr, int nExpr, int nFieldList, int nName, int nVisibility - | - b = 0 and - bAstNode = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAstNode(e, i, _)) | i) and - n = bAstNode and - nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and - nExpr = nAttr + 1 and - nFieldList = nExpr + 1 and - nName = nFieldList + 1 and - nVisibility = nName + 1 and - ( - none() - or - result = getImmediateChildOfAstNode(e, index - b, partialPredicateCall) - or - result = e.getAttr(index - n) and - partialPredicateCall = "Attr(" + (index - n).toString() + ")" - or - index = nAttr and result = e.getExpr() and partialPredicateCall = "Expr()" - or - index = nExpr and result = e.getFieldList() and partialPredicateCall = "FieldList()" - or - index = nFieldList and result = e.getName() and partialPredicateCall = "Name()" - or - index = nName and result = e.getVisibility() and partialPredicateCall = "Visibility()" - ) - ) - } - private Element getImmediateChildOfVariantList( VariantList e, int index, string partialPredicateCall ) { @@ -1898,14 +1882,18 @@ private module Impl { } private Element getImmediateChildOfItem(Item e, int index, string partialPredicateCall) { - exists(int b, int bStmt, int n | + exists(int b, int bStmt, int bAddressable, int n | b = 0 and bStmt = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfStmt(e, i, _)) | i) and - n = bStmt and + bAddressable = + bStmt + 1 + max(int i | i = -1 or exists(getImmediateChildOfAddressable(e, i, _)) | i) and + n = bAddressable and ( none() or result = getImmediateChildOfStmt(e, index - b, partialPredicateCall) + or + result = getImmediateChildOfAddressable(e, index - bStmt, partialPredicateCall) ) ) } @@ -2758,6 +2746,39 @@ private module Impl { ) } + private Element getImmediateChildOfVariant(Variant e, int index, string partialPredicateCall) { + exists( + int b, int bAddressable, int n, int nAttr, int nExpr, int nFieldList, int nName, + int nVisibility + | + b = 0 and + bAddressable = + b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAddressable(e, i, _)) | i) and + n = bAddressable and + nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and + nExpr = nAttr + 1 and + nFieldList = nExpr + 1 and + nName = nFieldList + 1 and + nVisibility = nName + 1 and + ( + none() + or + result = getImmediateChildOfAddressable(e, index - b, partialPredicateCall) + or + result = e.getAttr(index - n) and + partialPredicateCall = "Attr(" + (index - n).toString() + ")" + or + index = nAttr and result = e.getExpr() and partialPredicateCall = "Expr()" + or + index = nExpr and result = e.getFieldList() and partialPredicateCall = "FieldList()" + or + index = nFieldList and result = e.getName() and partialPredicateCall = "Name()" + or + index = nName and result = e.getVisibility() and partialPredicateCall = "Visibility()" + ) + ) + } + private Element getImmediateChildOfWhileExpr(WhileExpr e, int index, string partialPredicateCall) { exists(int b, int bExpr, int n, int nAttr, int nCondition, int nLabel, int nLoopBody | b = 0 and @@ -3641,8 +3662,6 @@ private module Impl { or result = getImmediateChildOfUseTreeList(e, index, partialAccessor) or - result = getImmediateChildOfVariant(e, index, partialAccessor) - or result = getImmediateChildOfVariantList(e, index, partialAccessor) or result = getImmediateChildOfVisibility(e, index, partialAccessor) @@ -3795,6 +3814,8 @@ private module Impl { or result = getImmediateChildOfUnderscoreExpr(e, index, partialAccessor) or + result = getImmediateChildOfVariant(e, index, partialAccessor) + or result = getImmediateChildOfWhileExpr(e, index, partialAccessor) or result = getImmediateChildOfWildcardPat(e, index, partialAccessor) diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index efcdd4818dc..851af838871 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -61,6 +61,30 @@ module Raw { string getAbiString() { abi_abi_strings(this, result) } } + /** + * INTERNAL: Do not use. + * Something that can be addressed by a path. + * + * TODO: This does not yet include all possible cases. + */ + class Addressable extends @addressable, AstNode { + /** + * Gets the extended canonical path of this addressable, if it exists. + * + * Either a canonical path (see https://doc.rust-lang.org/reference/paths.html#canonical-paths), + * or `{}::name` for addressable items defined in an anonymous block (and only + * addressable there-in). + */ + string getExtendedCanonicalPath() { addressable_extended_canonical_paths(this, result) } + + /** + * Gets the crate origin of this addressable, if it exists. + * + * One of `rustc:`, `repo::` or `lang:`. + */ + string getCrateOrigin() { addressable_crate_origins(this, result) } + } + /** * INTERNAL: Do not use. * A ArgList. For example: @@ -1048,42 +1072,6 @@ module Raw { UseTree getUseTree(int index) { use_tree_list_use_trees(this, index, result) } } - /** - * INTERNAL: Do not use. - * A Variant. For example: - * ```rust - * todo!() - * ``` - */ - class Variant extends @variant, AstNode { - override string toString() { result = "Variant" } - - /** - * Gets the `index`th attr of this variant (0-based). - */ - Attr getAttr(int index) { variant_attrs(this, index, result) } - - /** - * Gets the expression of this variant, if it exists. - */ - Expr getExpr() { variant_exprs(this, result) } - - /** - * Gets the field list of this variant, if it exists. - */ - FieldList getFieldList() { variant_field_lists(this, result) } - - /** - * Gets the name of this variant, if it exists. - */ - Name getName() { variant_names(this, result) } - - /** - * Gets the visibility of this variant, if it exists. - */ - Visibility getVisibility() { variant_visibilities(this, result) } - } - /** * INTERNAL: Do not use. * A VariantList. For example: @@ -2057,23 +2045,7 @@ module Raw { * todo!() * ``` */ - class Item extends @item, Stmt { - /** - * Gets the extended canonical path of this item, if it exists. - * - * Either a canonical path (see https://doc.rust-lang.org/reference/paths.html#canonical-paths), - * or `{}::name` for addressable items defined in an anonymous block (and only - * addressable there-in). - */ - string getExtendedCanonicalPath() { item_extended_canonical_paths(this, result) } - - /** - * Gets the crate origin of this item, if it exists. - * - * One of `rustc:`, `repo::` or `lang:`. - */ - string getCrateOrigin() { item_crate_origins(this, result) } - } + class Item extends @item, Stmt, Addressable { } /** * INTERNAL: Do not use. @@ -3067,6 +3039,42 @@ module Raw { Attr getAttr(int index) { underscore_expr_attrs(this, index, result) } } + /** + * INTERNAL: Do not use. + * A Variant. For example: + * ```rust + * todo!() + * ``` + */ + class Variant extends @variant, Addressable { + override string toString() { result = "Variant" } + + /** + * Gets the `index`th attr of this variant (0-based). + */ + Attr getAttr(int index) { variant_attrs(this, index, result) } + + /** + * Gets the expression of this variant, if it exists. + */ + Expr getExpr() { variant_exprs(this, result) } + + /** + * Gets the field list of this variant, if it exists. + */ + FieldList getFieldList() { variant_field_lists(this, result) } + + /** + * Gets the name of this variant, if it exists. + */ + Name getName() { variant_names(this, result) } + + /** + * Gets the visibility of this variant, if it exists. + */ + Visibility getVisibility() { variant_visibilities(this, result) } + } + /** * INTERNAL: Do not use. * A WhileExpr. For example: diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll index 927ba1f238d..ed9228e55ca 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll @@ -611,6 +611,11 @@ module Synth { */ TYieldExpr(Raw::YieldExpr id) { constructYieldExpr(id) } + /** + * INTERNAL: Do not use. + */ + class TAddressable = TItem or TVariant; + /** * INTERNAL: Do not use. */ @@ -620,16 +625,16 @@ module Synth { * INTERNAL: Do not use. */ class TAstNode = - TAbi or TArgList or TAssocItem or TAssocItemList or TAttr or TCallable or TClosureBinder or - TExpr or TExternItem or TExternItemList or TFieldList or TFormatArgsArg or TGenericArg or - TGenericArgList or TGenericParam or TGenericParamList or TItemList or TLabel or TLetElse or - TLifetime or TMacroItems or TMacroStmts or TMatchArm or TMatchArmList or TMatchGuard or - TMeta or TName or TNameRef or TParam or TParamList or TPat or TPathSegment or - TRecordExprField or TRecordExprFieldList or TRecordField or TRecordPatField or - TRecordPatFieldList or TRename or TResolvable or TRetType or TReturnTypeSyntax or - TSelfParam or TSourceFile or TStmt or TStmtList or TToken or TTokenTree or TTupleField or - TTypeBound or TTypeBoundList or TTypeRef or TUseTree or TUseTreeList or TVariant or - TVariantList or TVisibility or TWhereClause or TWherePred; + TAbi or TAddressable or TArgList or TAssocItem or TAssocItemList or TAttr or TCallable or + TClosureBinder or TExpr or TExternItem or TExternItemList or TFieldList or TFormatArgsArg or + TGenericArg or TGenericArgList or TGenericParam or TGenericParamList or TItemList or + TLabel or TLetElse or TLifetime or TMacroItems or TMacroStmts or TMatchArm or + TMatchArmList or TMatchGuard or TMeta or TName or TNameRef or TParam or TParamList or + TPat or TPathSegment or TRecordExprField or TRecordExprFieldList or TRecordField or + TRecordPatField or TRecordPatFieldList or TRename or TResolvable or TRetType or + TReturnTypeSyntax or TSelfParam or TSourceFile or TStmt or TStmtList or TToken or + TTokenTree or TTupleField or TTypeBound or TTypeBoundList or TTypeRef or TUseTree or + TUseTreeList or TVariantList or TVisibility or TWhereClause or TWherePred; /** * INTERNAL: Do not use. @@ -1614,6 +1619,16 @@ module Synth { */ TYieldExpr convertYieldExprFromRaw(Raw::Element e) { result = TYieldExpr(e) } + /** + * INTERNAL: Do not use. + * Converts a raw DB element to a synthesized `TAddressable`, if possible. + */ + TAddressable convertAddressableFromRaw(Raw::Element e) { + result = convertItemFromRaw(e) + or + result = convertVariantFromRaw(e) + } + /** * INTERNAL: Do not use. * Converts a raw DB element to a synthesized `TAssocItem`, if possible. @@ -1635,6 +1650,8 @@ module Synth { TAstNode convertAstNodeFromRaw(Raw::Element e) { result = convertAbiFromRaw(e) or + result = convertAddressableFromRaw(e) + or result = convertArgListFromRaw(e) or result = convertAssocItemFromRaw(e) @@ -1739,8 +1756,6 @@ module Synth { or result = convertUseTreeListFromRaw(e) or - result = convertVariantFromRaw(e) - or result = convertVariantListFromRaw(e) or result = convertVisibilityFromRaw(e) @@ -2964,6 +2979,16 @@ module Synth { */ Raw::Element convertYieldExprToRaw(TYieldExpr e) { e = TYieldExpr(result) } + /** + * INTERNAL: Do not use. + * Converts a synthesized `TAddressable` to a raw DB element, if possible. + */ + Raw::Element convertAddressableToRaw(TAddressable e) { + result = convertItemToRaw(e) + or + result = convertVariantToRaw(e) + } + /** * INTERNAL: Do not use. * Converts a synthesized `TAssocItem` to a raw DB element, if possible. @@ -2985,6 +3010,8 @@ module Synth { Raw::Element convertAstNodeToRaw(TAstNode e) { result = convertAbiToRaw(e) or + result = convertAddressableToRaw(e) + or result = convertArgListToRaw(e) or result = convertAssocItemToRaw(e) @@ -3089,8 +3116,6 @@ module Synth { or result = convertUseTreeListToRaw(e) or - result = convertVariantToRaw(e) - or result = convertVariantListToRaw(e) or result = convertVisibilityToRaw(e) diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Variant.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Variant.qll index ec57b2a03da..b78043e0922 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Variant.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Variant.qll @@ -6,7 +6,7 @@ private import codeql.rust.elements.internal.generated.Synth private import codeql.rust.elements.internal.generated.Raw -import codeql.rust.elements.internal.AstNodeImpl::Impl as AstNodeImpl +import codeql.rust.elements.internal.AddressableImpl::Impl as AddressableImpl import codeql.rust.elements.Attr import codeql.rust.elements.Expr import codeql.rust.elements.FieldList @@ -26,7 +26,7 @@ module Generated { * INTERNAL: Do not reference the `Generated::Variant` class directly. * Use the subclass `Variant`, where the following predicates are available. */ - class Variant extends Synth::TVariant, AstNodeImpl::AstNode { + class Variant extends Synth::TVariant, AddressableImpl::Addressable { override string getAPrimaryQlClass() { result = "Variant" } /** diff --git a/rust/ql/lib/rust.dbscheme b/rust/ql/lib/rust.dbscheme index 666a1e2b0e1..074392c176c 100644 --- a/rust/ql/lib/rust.dbscheme +++ b/rust/ql/lib/rust.dbscheme @@ -135,6 +135,7 @@ locatable_locations( @ast_node = @abi +| @addressable | @arg_list | @assoc_item | @assoc_item_list @@ -187,7 +188,6 @@ locatable_locations( | @type_ref | @use_tree | @use_tree_list -| @variant | @variant_list | @visibility | @where_clause @@ -212,6 +212,23 @@ abi_abi_strings( string abi_string: string ref ); +@addressable = + @item +| @variant +; + +#keyset[id] +addressable_extended_canonical_paths( + int id: @addressable ref, + string extended_canonical_path: string ref +); + +#keyset[id] +addressable_crate_origins( + int id: @addressable ref, + string crate_origin: string ref +); + arg_lists( unique int id: @arg_list ); @@ -1053,41 +1070,6 @@ use_tree_list_use_trees( int use_tree: @use_tree ref ); -variants( - unique int id: @variant -); - -#keyset[id, index] -variant_attrs( - int id: @variant ref, - int index: int ref, - int attr: @attr ref -); - -#keyset[id] -variant_exprs( - int id: @variant ref, - int expr: @expr ref -); - -#keyset[id] -variant_field_lists( - int id: @variant ref, - int field_list: @field_list ref -); - -#keyset[id] -variant_names( - int id: @variant ref, - int name: @name ref -); - -#keyset[id] -variant_visibilities( - int id: @variant ref, - int visibility: @visibility ref -); - variant_lists( unique int id: @variant_list ); @@ -1844,18 +1826,6 @@ infer_types( | @use ; -#keyset[id] -item_extended_canonical_paths( - int id: @item ref, - string extended_canonical_path: string ref -); - -#keyset[id] -item_crate_origins( - int id: @item ref, - string crate_origin: string ref -); - let_exprs( unique int id: @let_expr ); @@ -2555,6 +2525,41 @@ underscore_expr_attrs( int attr: @attr ref ); +variants( + unique int id: @variant +); + +#keyset[id, index] +variant_attrs( + int id: @variant ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +variant_exprs( + int id: @variant ref, + int expr: @expr ref +); + +#keyset[id] +variant_field_lists( + int id: @variant ref, + int field_list: @field_list ref +); + +#keyset[id] +variant_names( + int id: @variant ref, + int name: @name ref +); + +#keyset[id] +variant_visibilities( + int id: @variant ref, + int visibility: @visibility ref +); + while_exprs( unique int id: @while_expr ); diff --git a/rust/ql/test/extractor-tests/canonical_path/anonymous.rs b/rust/ql/test/extractor-tests/canonical_path/anonymous.rs new file mode 100644 index 00000000000..81e32169bfb --- /dev/null +++ b/rust/ql/test/extractor-tests/canonical_path/anonymous.rs @@ -0,0 +1,36 @@ +use super::regular::Trait; + +fn canonicals() { + struct OtherStruct; + + trait OtherTrait { + fn g(&self); + } + + impl OtherTrait for OtherStruct { + fn g(&self) {} + } + + impl OtherTrait for crate::regular::Struct { + fn g(&self) {} + } + + impl crate::regular::Trait for OtherStruct { + fn f(&self) {} + } + + fn nested() { + struct OtherStruct; + } + + fn usage() { + let s = OtherStruct {}; + s.f(); + s.g(); + nested(); + } +} + +fn other() { + struct OtherStruct; +} diff --git a/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected b/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected index 622652e091f..3bfa0f4fa83 100644 --- a/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected +++ b/rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected @@ -1,70 +1,89 @@ canonicalPaths -| canonical_paths.rs:1:1:34:1 | Module | repo::test | crate::canonical_paths::a | -| canonical_paths.rs:2:5:3:22 | Struct | repo::test | crate::canonical_paths::a::Struct | -| canonical_paths.rs:5:5:7:5 | Trait | repo::test | crate::canonical_paths::a::Trait | -| canonical_paths.rs:6:9:6:20 | f | repo::test | crate::canonical_paths::a::Trait::f | -| canonical_paths.rs:9:5:11:5 | Impl | None | None | -| canonical_paths.rs:10:9:10:22 | f | repo::test | ::f | -| canonical_paths.rs:13:5:15:5 | Impl | None | None | -| canonical_paths.rs:14:9:14:22 | g | repo::test | ::g | -| canonical_paths.rs:17:5:19:5 | Trait | repo::test | crate::canonical_paths::a::TraitWithBlanketImpl | -| canonical_paths.rs:18:9:18:20 | h | repo::test | crate::canonical_paths::a::TraitWithBlanketImpl::h | -| canonical_paths.rs:21:5:23:5 | Impl | None | None | -| canonical_paths.rs:22:9:22:22 | h | repo::test | <_ as crate::canonical_paths::a::TraitWithBlanketImpl>::h | -| canonical_paths.rs:25:5:25:16 | free | repo::test | crate::canonical_paths::a::free | -| canonical_paths.rs:27:5:33:5 | usage | repo::test | crate::canonical_paths::a::usage | -| canonical_paths.rs:36:1:73:1 | Module | repo::test | crate::canonical_paths::without | -| canonical_paths.rs:37:5:37:24 | Use | None | None | -| canonical_paths.rs:39:5:68:5 | canonicals | repo::test | crate::canonical_paths::without::canonicals | -| canonical_paths.rs:40:9:40:27 | Struct | repo::test | {34}::OtherStruct | -| canonical_paths.rs:42:9:44:9 | Trait | repo::test | {34}::OtherTrait | -| canonical_paths.rs:43:13:43:24 | g | repo::test | {34}::OtherTrait::g | -| canonical_paths.rs:46:9:48:9 | Impl | None | None | -| canonical_paths.rs:47:13:47:26 | g | repo::test | <{34}::OtherStruct as {34}::OtherTrait>::g | -| canonical_paths.rs:50:9:52:9 | Impl | None | None | -| canonical_paths.rs:51:13:51:26 | g | repo::test | ::g | -| canonical_paths.rs:54:9:56:9 | Impl | None | None | -| canonical_paths.rs:55:13:55:26 | f | repo::test | <{34}::OtherStruct as crate::canonical_paths::a::Trait>::f | -| canonical_paths.rs:58:9:60:9 | nested | repo::test | {34}::nested | -| canonical_paths.rs:59:13:59:31 | Struct | repo::test | {35}::OtherStruct | -| canonical_paths.rs:62:9:67:9 | usage | repo::test | {34}::usage | -| canonical_paths.rs:70:5:72:5 | other | repo::test | crate::canonical_paths::without::other | -| canonical_paths.rs:71:9:71:27 | Struct | repo::test | {36}::OtherStruct | -| lib.rs:1:1:1:20 | Module | repo::test | crate::canonical_paths | +| anonymous.rs:1:1:1:26 | Use | None | None | +| anonymous.rs:3:1:32:1 | canonicals | repo::test | crate::anonymous::canonicals | +| anonymous.rs:4:5:4:23 | Struct | repo::test | {0}::OtherStruct | +| anonymous.rs:6:5:8:5 | Trait | repo::test | {0}::OtherTrait | +| anonymous.rs:7:9:7:20 | g | repo::test | {0}::OtherTrait::g | +| anonymous.rs:10:5:12:5 | Impl | None | None | +| anonymous.rs:11:9:11:22 | g | repo::test | <{0}::OtherStruct as {0}::OtherTrait>::g | +| anonymous.rs:14:5:16:5 | Impl | None | None | +| anonymous.rs:15:9:15:22 | g | repo::test | ::g | +| anonymous.rs:18:5:20:5 | Impl | None | None | +| anonymous.rs:19:9:19:22 | f | repo::test | <{0}::OtherStruct as crate::regular::Trait>::f | +| anonymous.rs:22:5:24:5 | nested | repo::test | {0}::nested | +| anonymous.rs:23:9:23:27 | Struct | repo::test | {1}::OtherStruct | +| anonymous.rs:26:5:31:5 | usage | repo::test | {0}::usage | +| anonymous.rs:34:1:36:1 | other | repo::test | crate::anonymous::other | +| anonymous.rs:35:5:35:23 | Struct | repo::test | {36}::OtherStruct | +| lib.rs:1:1:1:14 | Module | repo::test | crate::anonymous | +| lib.rs:2:1:2:12 | Module | repo::test | crate::regular | +| regular.rs:1:1:2:18 | Struct | repo::test | crate::regular::Struct | +| regular.rs:4:1:6:1 | Trait | repo::test | crate::regular::Trait | +| regular.rs:5:5:5:16 | f | repo::test | crate::regular::Trait::f | +| regular.rs:8:1:10:1 | Impl | None | None | +| regular.rs:9:5:9:18 | f | repo::test | ::f | +| regular.rs:12:1:14:1 | Impl | None | None | +| regular.rs:13:5:13:18 | g | repo::test | ::g | +| regular.rs:16:1:18:1 | Trait | repo::test | crate::regular::TraitWithBlanketImpl | +| regular.rs:17:5:17:16 | h | repo::test | crate::regular::TraitWithBlanketImpl::h | +| regular.rs:20:1:22:1 | Impl | None | None | +| regular.rs:21:5:21:18 | h | repo::test | <_ as crate::regular::TraitWithBlanketImpl>::h | +| regular.rs:24:1:24:12 | free | repo::test | crate::regular::free | +| regular.rs:26:1:32:1 | usage | repo::test | crate::regular::usage | +| regular.rs:34:1:38:1 | Enum | repo::test | crate::regular::MyEnum | +| regular.rs:40:1:46:1 | enum_qualified_usage | repo::test | crate::regular::enum_qualified_usage | +| regular.rs:48:1:55:1 | enum_unqualified_usage | repo::test | crate::regular::enum_unqualified_usage | +| regular.rs:51:5:51:18 | Use | None | None | resolvedPaths -| canonical_paths.rs:2:7:2:12 | derive | None | None | -| canonical_paths.rs:9:10:9:14 | Trait | repo::test | crate::canonical_paths::a::Trait | -| canonical_paths.rs:9:20:9:25 | Struct | repo::test | crate::canonical_paths::a::Struct | -| canonical_paths.rs:13:10:13:15 | Struct | repo::test | crate::canonical_paths::a::Struct | -| canonical_paths.rs:21:13:21:14 | Eq | lang:core | crate::cmp::Eq | -| canonical_paths.rs:21:17:21:36 | TraitWithBlanketImpl | repo::test | crate::canonical_paths::a::TraitWithBlanketImpl | -| canonical_paths.rs:21:42:21:42 | T | None | None | -| canonical_paths.rs:28:17:28:22 | Struct | repo::test | crate::canonical_paths::a::Struct | -| canonical_paths.rs:29:9:29:9 | s | None | None | -| canonical_paths.rs:29:9:29:13 | ... .f(...) | repo::test | ::f | -| canonical_paths.rs:30:9:30:9 | s | None | None | -| canonical_paths.rs:30:9:30:13 | ... .g(...) | repo::test | ::g | -| canonical_paths.rs:31:9:31:9 | s | None | None | -| canonical_paths.rs:31:9:31:13 | ... .h(...) | repo::test | <_ as crate::canonical_paths::a::TraitWithBlanketImpl>::h | -| canonical_paths.rs:32:9:32:12 | free | repo::test | crate::canonical_paths::a::free | -| canonical_paths.rs:37:9:37:13 | super | repo::test | crate::canonical_paths | -| canonical_paths.rs:37:9:37:16 | super::a | repo::test | crate::canonical_paths::a | -| canonical_paths.rs:37:9:37:23 | super::a::Trait | repo::test | crate::canonical_paths::a::Trait | -| canonical_paths.rs:46:14:46:23 | OtherTrait | repo::test | {34}::OtherTrait | -| canonical_paths.rs:46:29:46:39 | OtherStruct | repo::test | {34}::OtherStruct | -| canonical_paths.rs:50:14:50:23 | OtherTrait | repo::test | {34}::OtherTrait | -| canonical_paths.rs:50:29:50:33 | crate | None | None | -| canonical_paths.rs:50:29:50:50 | crate::canonical_paths | repo::test | crate::canonical_paths | -| canonical_paths.rs:50:29:50:53 | crate::canonical_paths::a | repo::test | crate::canonical_paths::a | -| canonical_paths.rs:50:29:50:61 | crate::canonical_paths::a::Struct | repo::test | crate::canonical_paths::a::Struct | -| canonical_paths.rs:54:14:54:18 | crate | None | None | -| canonical_paths.rs:54:14:54:35 | crate::canonical_paths | repo::test | crate::canonical_paths | -| canonical_paths.rs:54:14:54:38 | crate::canonical_paths::a | repo::test | crate::canonical_paths::a | -| canonical_paths.rs:54:14:54:45 | crate::canonical_paths::a::Trait | repo::test | crate::canonical_paths::a::Trait | -| canonical_paths.rs:54:51:54:61 | OtherStruct | repo::test | {34}::OtherStruct | -| canonical_paths.rs:63:21:63:31 | OtherStruct | repo::test | {34}::OtherStruct | -| canonical_paths.rs:64:13:64:13 | s | None | None | -| canonical_paths.rs:64:13:64:17 | ... .f(...) | repo::test | <{34}::OtherStruct as crate::canonical_paths::a::Trait>::f | -| canonical_paths.rs:65:13:65:13 | s | None | None | -| canonical_paths.rs:65:13:65:17 | ... .g(...) | repo::test | <{34}::OtherStruct as {34}::OtherTrait>::g | -| canonical_paths.rs:66:13:66:18 | nested | repo::test | {34}::nested | +| anonymous.rs:1:5:1:9 | super | None | None | +| anonymous.rs:1:5:1:18 | super::regular | repo::test | crate::regular | +| anonymous.rs:1:5:1:25 | super::regular::Trait | repo::test | crate::regular::Trait | +| anonymous.rs:10:10:10:19 | OtherTrait | repo::test | {0}::OtherTrait | +| anonymous.rs:10:25:10:35 | OtherStruct | repo::test | {0}::OtherStruct | +| anonymous.rs:14:10:14:19 | OtherTrait | repo::test | {0}::OtherTrait | +| anonymous.rs:14:25:14:29 | crate | None | None | +| anonymous.rs:14:25:14:38 | crate::regular | repo::test | crate::regular | +| anonymous.rs:14:25:14:46 | crate::regular::Struct | repo::test | crate::regular::Struct | +| anonymous.rs:18:10:18:14 | crate | None | None | +| anonymous.rs:18:10:18:23 | crate::regular | repo::test | crate::regular | +| anonymous.rs:18:10:18:30 | crate::regular::Trait | repo::test | crate::regular::Trait | +| anonymous.rs:18:36:18:46 | OtherStruct | repo::test | {0}::OtherStruct | +| anonymous.rs:27:17:27:27 | OtherStruct | repo::test | {0}::OtherStruct | +| anonymous.rs:28:9:28:9 | s | None | None | +| anonymous.rs:28:9:28:13 | ... .f(...) | repo::test | <{0}::OtherStruct as crate::regular::Trait>::f | +| anonymous.rs:29:9:29:9 | s | None | None | +| anonymous.rs:29:9:29:13 | ... .g(...) | repo::test | <{0}::OtherStruct as {0}::OtherTrait>::g | +| anonymous.rs:30:9:30:14 | nested | repo::test | {0}::nested | +| regular.rs:1:3:1:8 | derive | None | None | +| regular.rs:8:6:8:10 | Trait | repo::test | crate::regular::Trait | +| regular.rs:8:16:8:21 | Struct | repo::test | crate::regular::Struct | +| regular.rs:12:6:12:11 | Struct | repo::test | crate::regular::Struct | +| regular.rs:20:9:20:10 | Eq | lang:core | crate::cmp::Eq | +| regular.rs:20:13:20:32 | TraitWithBlanketImpl | repo::test | crate::regular::TraitWithBlanketImpl | +| regular.rs:20:38:20:38 | T | None | None | +| regular.rs:27:13:27:18 | Struct | repo::test | crate::regular::Struct | +| regular.rs:28:5:28:5 | s | None | None | +| regular.rs:28:5:28:9 | ... .f(...) | repo::test | ::f | +| regular.rs:29:5:29:5 | s | None | None | +| regular.rs:29:5:29:9 | ... .g(...) | repo::test | ::g | +| regular.rs:30:5:30:5 | s | None | None | +| regular.rs:30:5:30:9 | ... .h(...) | repo::test | <_ as crate::regular::TraitWithBlanketImpl>::h | +| regular.rs:31:5:31:8 | free | repo::test | crate::regular::free | +| regular.rs:36:14:36:18 | usize | None | None | +| regular.rs:37:19:37:23 | usize | None | None | +| regular.rs:41:9:41:14 | Option | lang:core | crate::option::Option | +| regular.rs:41:9:41:26 | Option::None::<...> | lang:core | crate::option::Option::None | +| regular.rs:42:9:42:14 | Option | lang:core | crate::option::Option | +| regular.rs:42:9:42:20 | Option::Some | lang:core | crate::option::Option::Some | +| regular.rs:43:9:43:14 | MyEnum | repo::test | crate::regular::MyEnum | +| regular.rs:43:9:43:24 | MyEnum::Variant1 | repo::test | crate::regular::MyEnum::Variant1 | +| regular.rs:44:9:44:14 | MyEnum | repo::test | crate::regular::MyEnum | +| regular.rs:44:9:44:24 | MyEnum::Variant2 | repo::test | crate::regular::MyEnum::Variant2 | +| regular.rs:45:9:45:14 | MyEnum | repo::test | crate::regular::MyEnum | +| regular.rs:45:9:45:24 | MyEnum::Variant3 | repo::test | crate::regular::MyEnum::Variant3 | +| regular.rs:49:9:49:18 | None::<...> | lang:core | crate::option::Option::None | +| regular.rs:50:9:50:12 | Some | lang:core | crate::option::Option::Some | +| regular.rs:51:9:51:14 | MyEnum | repo::test | crate::regular::MyEnum | +| regular.rs:52:9:52:16 | Variant1 | repo::test | crate::regular::MyEnum::Variant1 | +| regular.rs:53:9:53:16 | Variant2 | repo::test | crate::regular::MyEnum::Variant2 | +| regular.rs:54:9:54:16 | Variant3 | repo::test | crate::regular::MyEnum::Variant3 | diff --git a/rust/ql/test/extractor-tests/canonical_path/canonical_paths.rs b/rust/ql/test/extractor-tests/canonical_path/canonical_paths.rs deleted file mode 100644 index 7444903dc01..00000000000 --- a/rust/ql/test/extractor-tests/canonical_path/canonical_paths.rs +++ /dev/null @@ -1,73 +0,0 @@ -mod a { - #[derive(Eq, PartialEq)] - pub struct Struct; - - pub trait Trait { - fn f(&self); - } - - impl Trait for Struct { - fn f(&self) {} - } - - impl Struct { - fn g(&self) {} - } - - trait TraitWithBlanketImpl { - fn h(&self); - } - - impl TraitWithBlanketImpl for T { - fn h(&self) {} - } - - fn free() {} - - fn usage() { - let s = Struct {}; - s.f(); - s.g(); - s.h(); - free(); - } -} - -mod without { - use super::a::Trait; - - fn canonicals() { - struct OtherStruct; - - trait OtherTrait { - fn g(&self); - } - - impl OtherTrait for OtherStruct { - fn g(&self) {} - } - - impl OtherTrait for crate::canonical_paths::a::Struct { - fn g(&self) {} - } - - impl crate::canonical_paths::a::Trait for OtherStruct { - fn f(&self) {} - } - - fn nested() { - struct OtherStruct; - } - - fn usage() { - let s = OtherStruct {}; - s.f(); - s.g(); - nested(); - } - } - - fn other() { - struct OtherStruct; - } -} diff --git a/rust/ql/test/extractor-tests/canonical_path/regular.rs b/rust/ql/test/extractor-tests/canonical_path/regular.rs new file mode 100644 index 00000000000..ac06a12d24a --- /dev/null +++ b/rust/ql/test/extractor-tests/canonical_path/regular.rs @@ -0,0 +1,55 @@ +#[derive(Eq, PartialEq)] +pub struct Struct; + +pub trait Trait { + fn f(&self); +} + +impl Trait for Struct { + fn f(&self) {} +} + +impl Struct { + fn g(&self) {} +} + +trait TraitWithBlanketImpl { + fn h(&self); +} + +impl TraitWithBlanketImpl for T { + fn h(&self) {} +} + +fn free() {} + +fn usage() { + let s = Struct {}; + s.f(); + s.g(); + s.h(); + free(); +} + +enum MyEnum { + Variant1, + Variant2(usize), + Variant3 { x: usize }, +} + +fn enum_qualified_usage() { + _ = Option::None::<()>; + _ = Option::Some(0); + _ = MyEnum::Variant1; + _ = MyEnum::Variant2(0); + _ = MyEnum::Variant3 { x: 1 }; +} + +fn enum_unqualified_usage() { + _ = None::<()>; + _ = Some(0); + use MyEnum::*; + _ = Variant1; + _ = Variant2(0); + _ = Variant3 { x: 1 }; +} diff --git a/rust/ql/test/extractor-tests/generated/Variant/Variant.ql b/rust/ql/test/extractor-tests/generated/Variant/Variant.ql index 2cbcd20cbf0..92ebcbe55ee 100644 --- a/rust/ql/test/extractor-tests/generated/Variant/Variant.ql +++ b/rust/ql/test/extractor-tests/generated/Variant/Variant.ql @@ -3,15 +3,22 @@ import codeql.rust.elements import TestUtils from - Variant x, int getNumberOfAttrs, string hasExpr, string hasFieldList, string hasName, - string hasVisibility + Variant x, string hasExtendedCanonicalPath, string hasCrateOrigin, int getNumberOfAttrs, + string hasExpr, string hasFieldList, string hasName, string hasVisibility where toBeTested(x) and not x.isUnknown() and + ( + if x.hasExtendedCanonicalPath() + then hasExtendedCanonicalPath = "yes" + else hasExtendedCanonicalPath = "no" + ) and + (if x.hasCrateOrigin() then hasCrateOrigin = "yes" else hasCrateOrigin = "no") and getNumberOfAttrs = x.getNumberOfAttrs() and (if x.hasExpr() then hasExpr = "yes" else hasExpr = "no") and (if x.hasFieldList() then hasFieldList = "yes" else hasFieldList = "no") and (if x.hasName() then hasName = "yes" else hasName = "no") and if x.hasVisibility() then hasVisibility = "yes" else hasVisibility = "no" -select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasExpr:", hasExpr, "hasFieldList:", hasFieldList, +select x, "hasExtendedCanonicalPath:", hasExtendedCanonicalPath, "hasCrateOrigin:", hasCrateOrigin, + "getNumberOfAttrs:", getNumberOfAttrs, "hasExpr:", hasExpr, "hasFieldList:", hasFieldList, "hasName:", hasName, "hasVisibility:", hasVisibility diff --git a/rust/ql/test/extractor-tests/generated/Variant/Variant_getCrateOrigin.expected b/rust/ql/test/extractor-tests/generated/Variant/Variant_getCrateOrigin.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/rust/ql/test/extractor-tests/generated/Variant/Variant_getCrateOrigin.ql b/rust/ql/test/extractor-tests/generated/Variant/Variant_getCrateOrigin.ql new file mode 100644 index 00000000000..0acfd9827fe --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/Variant/Variant_getCrateOrigin.ql @@ -0,0 +1,7 @@ +// generated by codegen, do not edit +import codeql.rust.elements +import TestUtils + +from Variant x +where toBeTested(x) and not x.isUnknown() +select x, x.getCrateOrigin() diff --git a/rust/ql/test/extractor-tests/generated/Variant/Variant_getExtendedCanonicalPath.expected b/rust/ql/test/extractor-tests/generated/Variant/Variant_getExtendedCanonicalPath.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/rust/ql/test/extractor-tests/generated/Variant/Variant_getExtendedCanonicalPath.ql b/rust/ql/test/extractor-tests/generated/Variant/Variant_getExtendedCanonicalPath.ql new file mode 100644 index 00000000000..ad8aaf86a5c --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/Variant/Variant_getExtendedCanonicalPath.ql @@ -0,0 +1,7 @@ +// generated by codegen, do not edit +import codeql.rust.elements +import TestUtils + +from Variant x +where toBeTested(x) and not x.isUnknown() +select x, x.getExtendedCanonicalPath() diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index 60f67a710d8..51ede77e92e 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -1700,7 +1700,7 @@ class _: """ -@annotate(Variant) +@annotate(Variant, replace_bases={AstNode: Addressable}) class _: """ A Variant. For example: @@ -1809,11 +1809,6 @@ class FormatArgument(Locatable): parent: Format variable: optional[FormatTemplateVariableAccess] | child -@annotate(Item) +@annotate(Item, add_bases=(Addressable,)) class _: - extended_canonical_path: optional[string] | desc(""" - Either a canonical path (see https://doc.rust-lang.org/reference/paths.html#canonical-paths), - or `{}::name` for addressable items defined in an anonymous block (and only - addressable there-in). - """) | rust.detach | ql.internal - crate_origin: optional[string] | desc("One of `rustc:`, `repo::` or `lang:`.") | rust.detach | ql.internal + pass diff --git a/rust/schema/prelude.py b/rust/schema/prelude.py index 60de626e59c..ffd65959b5a 100644 --- a/rust/schema/prelude.py +++ b/rust/schema/prelude.py @@ -73,6 +73,20 @@ class Callable(AstNode): attrs: list["Attr"] | child +class Addressable(AstNode): + """ + Something that can be addressed by a path. + + TODO: This does not yet include all possible cases. + """ + extended_canonical_path: optional[string] | desc(""" + Either a canonical path (see https://doc.rust-lang.org/reference/paths.html#canonical-paths), + or `{}::name` for addressable items defined in an anonymous block (and only + addressable there-in). + """) | rust.detach | ql.internal + crate_origin: optional[string] | desc("One of `rustc:`, `repo::` or `lang:`.") | rust.detach | ql.internal + + class Resolvable(AstNode): """ Either a `Path`, or a `MethodCallExpr`. From 4dab0390c996183967232630bbfea667c50588be Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Fri, 22 Nov 2024 16:10:23 +0000 Subject: [PATCH 206/470] C++: Update expected output --- .../ImplicitFunctionDeclaration.expected | 12 +++---- .../MistypedFunctionArguments.expected | 36 +++++++++---------- .../TooFewArguments.expected | 4 +-- .../TooManyArguments.expected | 4 +-- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.expected index 8547894e769..d3e0ecbd591 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.expected @@ -1,9 +1,9 @@ | test.c:28:3:28:12 | call to undeclared | Function call implicitly declares 'undeclared'. | | test.c:31:3:31:19 | call to not_yet_declared1 | Function call implicitly declares 'not_yet_declared1'. | | test.c:32:3:32:19 | call to not_yet_declared2 | Function call implicitly declares 'not_yet_declared2'. | -| test.c:43:3:43:27 | call to not_declared_defined_with | Function call implicitly declares 'not_declared_defined_with'. | -| test.c:54:3:54:21 | call to defined_with_double | Function call implicitly declares 'defined_with_double'. | -| test.c:66:3:66:22 | call to defined_with_ptr_ptr | Function call implicitly declares 'defined_with_ptr_ptr'. | -| test.c:68:3:68:22 | call to defined_with_ptr_arr | Function call implicitly declares 'defined_with_ptr_arr'. | -| test.c:132:3:132:22 | call to implicit_declaration | Function call implicitly declares 'implicit_declaration'. | -| test.c:133:3:133:30 | call to implicit_declaration_k_and_r | Function call implicitly declares 'implicit_declaration_k_and_r'. | +| test.c:44:3:44:27 | call to not_declared_defined_with | Function call implicitly declares 'not_declared_defined_with'. | +| test.c:55:3:55:21 | call to defined_with_double | Function call implicitly declares 'defined_with_double'. | +| test.c:67:3:67:22 | call to defined_with_ptr_ptr | Function call implicitly declares 'defined_with_ptr_ptr'. | +| test.c:69:3:69:22 | call to defined_with_ptr_arr | Function call implicitly declares 'defined_with_ptr_arr'. | +| test.c:133:3:133:22 | call to implicit_declaration | Function call implicitly declares 'implicit_declaration'. | +| test.c:134:3:134:30 | call to implicit_declaration_k_and_r | Function call implicitly declares 'implicit_declaration_k_and_r'. | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected index b6015dad456..d067430aba9 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected @@ -1,18 +1,18 @@ -| test.c:33:3:33:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:32:3:32:3 | not_yet_declared2 | not_yet_declared2 | test.c:33:21:33:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:76:24:76:26 | (unnamed parameter 0) | int (unnamed parameter 0) | -| test.c:33:3:33:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:76:6:76:22 | not_yet_declared2 | not_yet_declared2 | test.c:33:21:33:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:76:24:76:26 | (unnamed parameter 0) | int (unnamed parameter 0) | -| test.c:40:3:40:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:77:6:77:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:40:31:40:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:77:38:77:38 | x | int x | -| test.c:44:3:44:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:80:6:80:30 | not_declared_defined_with | not_declared_defined_with | test.c:44:29:44:31 | 4 | 4 | file://:0:0:0:0 | long long | long long | test.c:80:36:80:36 | x | int x | -| test.c:44:3:44:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:80:6:80:30 | not_declared_defined_with | not_declared_defined_with | test.c:44:37:44:42 | 2500000000.0 | 2500000000.0 | file://:0:0:0:0 | float | float | test.c:80:50:80:50 | z | int z | -| test.c:47:3:47:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:47:26:47:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:92:34:92:34 | x | int * x | -| test.c:47:3:47:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:47:34:47:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:92:43:92:43 | y | void * y | -| test.c:47:3:47:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:92:6:92:27 | declared_with_pointers | declared_with_pointers | test.c:47:26:47:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:92:34:92:34 | x | int * x | -| test.c:47:3:47:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:92:6:92:27 | declared_with_pointers | declared_with_pointers | test.c:47:34:47:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:92:43:92:43 | y | void * y | -| test.c:49:3:49:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:6:6:6:24 | declared_with_array | declared_with_array | test.c:49:23:49:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:93:31:93:31 | a | char[6] a | -| test.c:49:3:49:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:93:6:93:24 | declared_with_array | declared_with_array | test.c:49:23:49:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:93:31:93:31 | a | char[6] a | -| test.c:51:3:51:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:95:7:95:24 | defined_with_float | defined_with_float | test.c:51:22:51:24 | 2.0 | 2.0 | file://:0:0:0:0 | float | float | test.c:95:32:95:32 | f | float f | -| test.c:52:3:52:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:95:7:95:24 | defined_with_float | defined_with_float | test.c:52:22:52:24 | 2.0 | 2.0 | file://:0:0:0:0 | double | double | test.c:95:32:95:32 | f | float f | -| test.c:55:3:55:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:99:8:99:26 | defined_with_double | defined_with_double | test.c:55:23:55:25 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:99:35:99:35 | d | double d | -| test.c:57:3:57:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:103:11:103:32 | defined_with_long_long | defined_with_long_long | test.c:57:26:57:28 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:103:44:103:45 | ll | long long ll | -| test.c:58:3:58:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:103:11:103:32 | defined_with_long_long | defined_with_long_long | test.c:58:26:58:26 | 3 | 3 | file://:0:0:0:0 | int | int | test.c:103:44:103:45 | ll | long long ll | -| test.c:60:3:60:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:99:8:99:26 | defined_with_double | defined_with_double | test.c:60:23:60:25 | 2 | 2 | file://:0:0:0:0 | long long | long long | test.c:99:35:99:35 | d | double d | -| test.c:61:3:61:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:103:11:103:32 | defined_with_long_long | defined_with_long_long | test.c:61:26:61:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:103:44:103:45 | ll | long long ll | +| test.c:33:3:33:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:32:3:32:3 | not_yet_declared2 | not_yet_declared2 | test.c:33:21:33:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:77:24:77:26 | (unnamed parameter 0) | int (unnamed parameter 0) | +| test.c:33:3:33:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:77:6:77:22 | not_yet_declared2 | not_yet_declared2 | test.c:33:21:33:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:77:24:77:26 | (unnamed parameter 0) | int (unnamed parameter 0) | +| test.c:41:3:41:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:78:6:78:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:41:31:41:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:78:38:78:38 | x | int x | +| test.c:45:3:45:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:81:6:81:30 | not_declared_defined_with | not_declared_defined_with | test.c:45:29:45:31 | 4 | 4 | file://:0:0:0:0 | long long | long long | test.c:81:36:81:36 | x | int x | +| test.c:45:3:45:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:81:6:81:30 | not_declared_defined_with | not_declared_defined_with | test.c:45:37:45:42 | 2500000000.0 | 2500000000.0 | file://:0:0:0:0 | float | float | test.c:81:50:81:50 | z | int z | +| test.c:48:3:48:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:48:26:48:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:93:34:93:34 | x | int * x | +| test.c:48:3:48:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:48:34:48:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:93:43:93:43 | y | void * y | +| test.c:48:3:48:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:93:6:93:27 | declared_with_pointers | declared_with_pointers | test.c:48:26:48:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:93:34:93:34 | x | int * x | +| test.c:48:3:48:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:93:6:93:27 | declared_with_pointers | declared_with_pointers | test.c:48:34:48:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:93:43:93:43 | y | void * y | +| test.c:50:3:50:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:6:6:6:24 | declared_with_array | declared_with_array | test.c:50:23:50:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:94:31:94:31 | a | char[6] a | +| test.c:50:3:50:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:94:6:94:24 | declared_with_array | declared_with_array | test.c:50:23:50:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:94:31:94:31 | a | char[6] a | +| test.c:52:3:52:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:96:7:96:24 | defined_with_float | defined_with_float | test.c:52:22:52:24 | 2.0 | 2.0 | file://:0:0:0:0 | float | float | test.c:96:32:96:32 | f | float f | +| test.c:53:3:53:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:96:7:96:24 | defined_with_float | defined_with_float | test.c:53:22:53:24 | 2.0 | 2.0 | file://:0:0:0:0 | double | double | test.c:96:32:96:32 | f | float f | +| test.c:56:3:56:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:100:8:100:26 | defined_with_double | defined_with_double | test.c:56:23:56:25 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:100:35:100:35 | d | double d | +| test.c:58:3:58:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:104:11:104:32 | defined_with_long_long | defined_with_long_long | test.c:58:26:58:28 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:104:44:104:45 | ll | long long ll | +| test.c:59:3:59:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:104:11:104:32 | defined_with_long_long | defined_with_long_long | test.c:59:26:59:26 | 3 | 3 | file://:0:0:0:0 | int | int | test.c:104:44:104:45 | ll | long long ll | +| test.c:61:3:61:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:100:8:100:26 | defined_with_double | defined_with_double | test.c:61:23:61:25 | 2 | 2 | file://:0:0:0:0 | long long | long long | test.c:100:35:100:35 | d | double d | +| test.c:62:3:62:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:104:11:104:32 | defined_with_long_long | defined_with_long_long | test.c:62:26:62:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:104:44:104:45 | ll | long long ll | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected index 956729115d7..90468d3a9bf 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected @@ -1,2 +1,2 @@ -| test.c:36:3:36:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:77:6:77:32 | declared_empty_defined_with | declared_empty_defined_with | -| test.c:87:10:87:20 | call to dereference | This call has fewer arguments than required by $@. | test.c:90:5:90:15 | dereference | dereference | +| test.c:37:3:37:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:78:6:78:32 | declared_empty_defined_with | declared_empty_defined_with | +| test.c:88:10:88:20 | call to dereference | This call has fewer arguments than required by $@. | test.c:91:5:91:15 | dereference | dereference | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected index bc64434578b..6eff27c3adb 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected @@ -1,2 +1,2 @@ -| test.c:41:3:41:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:77:6:77:32 | declared_empty_defined_with | declared_empty_defined_with | -| test.c:72:3:72:28 | call to declared_and_defined_empty | This call has more arguments than required by $@. | test.c:114:6:114:31 | declared_and_defined_empty | declared_and_defined_empty | +| test.c:42:3:42:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:78:6:78:32 | declared_empty_defined_with | declared_empty_defined_with | +| test.c:73:3:73:28 | call to declared_and_defined_empty | This call has more arguments than required by $@. | test.c:115:6:115:31 | declared_and_defined_empty | declared_and_defined_empty | From b32e578580d707346807ac5408aa1757dac91c8d Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 22 Nov 2024 17:18:32 +0100 Subject: [PATCH 207/470] Rust: accept test changes --- .../FormatArgsExpr/FormatArgsExpr_getTemplate.expected | 2 +- .../security/CWE-089/CONSISTENCY/DataFlowConsistency.expected | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) delete mode 100644 rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getTemplate.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getTemplate.expected index 6c4f7030810..1b201bbf36f 100644 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getTemplate.expected +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getTemplate.expected @@ -3,5 +3,5 @@ | gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | gen_format_args_expr.rs:6:18:6:30 | "{} foo {:?}" | | gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | gen_format_args_expr.rs:7:18:7:32 | "{b} foo {a:?}" | | gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | gen_format_args_expr.rs:9:18:9:27 | "{x}, {y}" | -| gen_format_argument.rs:5:14:5:47 | FormatArgsExpr | gen_format_argument.rs:5:14:5:47 | "Value {value:#width$.precision$}\\n" | +| gen_format_argument.rs:5:14:5:47 | FormatArgsExpr | gen_format_argument.rs:5:14:5:47 | "Value {value:#width$.precisio... | | gen_format_argument.rs:7:14:7:56 | FormatArgsExpr | gen_format_argument.rs:7:14:7:31 | "Value {0:#1$.2$}\\n" | diff --git a/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected deleted file mode 100644 index d9a60435a6f..00000000000 --- a/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/DataFlowConsistency.expected +++ /dev/null @@ -1,3 +0,0 @@ -uniqueNodeToString -| sqlx.rs:154:13:154:81 | (no string representation) | Node should have one toString but has 0. | -| sqlx.rs:156:17:156:86 | (no string representation) | Node should have one toString but has 0. | From d8b58f21c77ac6490dca125a2821d8d0d45621cc Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 16:42:24 +0000 Subject: [PATCH 208/470] Rust: Restrict ReqwestGet by crate origin. --- rust/ql/lib/codeql/rust/frameworks/Reqwest.qll | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll index cb0924f93a1..141f9767eca 100644 --- a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll +++ b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll @@ -9,8 +9,11 @@ private import codeql.rust.Concepts * A call to `reqwest::get` or `reqwest::blocking::get`. */ private class ReqwestGet extends RemoteSource::Range { + CallExpr ce; + ReqwestGet() { - this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = - ["crate::get", "crate::blocking::get"] + this.asExpr().getExpr() = ce and + ce.getExpr().(PathExpr).getPath().getResolvedCrateOrigin().matches("%reqwest") and + ce.getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::get", "crate::blocking::get"] } } From f2f577f86c5cc4b7f38181d754af9821ec9905c2 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 17:09:52 +0000 Subject: [PATCH 209/470] Rust: Fix toString(). --- rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql index 1499784ac0e..85ac4eec698 100644 --- a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql +++ b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql @@ -4,13 +4,13 @@ import codeql.rust.Concepts import utils.InlineFlowTest /** - * Configuration for flow from any threat model source to an argument of a function called `sink`. + * Configuration for flow from any threat model source to an argument of the function `sink`. */ module MyFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ThreatModelSource } predicate isSink(DataFlow::Node sink) { - any(CallExpr call | call.getExpr().(PathExpr).getPath().toString() = "sink") + any(CallExpr call | call.getExpr().(PathExpr).getPath().getResolvedPath() = "crate::test::sink") .getArgList() .getAnArg() = sink.asExpr().getExpr() } From 4c50c083fbdc71db38d5cee8ce64e4e9e0c740cc Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 17:12:09 +0000 Subject: [PATCH 210/470] Rust: Implement good suggestions from ql-for-ql. --- rust/ql/lib/codeql/rust/frameworks/Reqwest.qll | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll index 141f9767eca..2ab11a20ed4 100644 --- a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll +++ b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll @@ -9,11 +9,11 @@ private import codeql.rust.Concepts * A call to `reqwest::get` or `reqwest::blocking::get`. */ private class ReqwestGet extends RemoteSource::Range { - CallExpr ce; - ReqwestGet() { - this.asExpr().getExpr() = ce and - ce.getExpr().(PathExpr).getPath().getResolvedCrateOrigin().matches("%reqwest") and - ce.getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::get", "crate::blocking::get"] + exists(CallExpr ce | + this.asExpr().getExpr() = ce and + ce.getExpr().(PathExpr).getPath().getResolvedCrateOrigin().matches("%reqwest") and + ce.getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::get", "crate::blocking::get"] + ) } } From 7f84cf6d72e23e78192de040aad73c8671e93fc4 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Fri, 22 Nov 2024 18:56:18 +0100 Subject: [PATCH 211/470] Add test case --- .../CWE-327/semmle/tests/MaybeBrokenCryptoAlgorithm.expected | 2 ++ .../security/CWE-327/semmle/tests/WeakHashing.java | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/java/ql/test/query-tests/security/CWE-327/semmle/tests/MaybeBrokenCryptoAlgorithm.expected b/java/ql/test/query-tests/security/CWE-327/semmle/tests/MaybeBrokenCryptoAlgorithm.expected index da6f6312a89..a9365ae398d 100644 --- a/java/ql/test/query-tests/security/CWE-327/semmle/tests/MaybeBrokenCryptoAlgorithm.expected +++ b/java/ql/test/query-tests/security/CWE-327/semmle/tests/MaybeBrokenCryptoAlgorithm.expected @@ -4,9 +4,11 @@ nodes | WeakHashing.java:15:55:15:83 | getProperty(...) | semmle.label | getProperty(...) | | WeakHashing.java:18:56:18:95 | getProperty(...) | semmle.label | getProperty(...) | | WeakHashing.java:21:56:21:91 | getProperty(...) | semmle.label | getProperty(...) | +| WeakHashing.java:30:55:30:64 | "SHA3-512" | semmle.label | "SHA3-512" | subpaths #select | Test.java:34:21:34:53 | new SecretKeySpec(...) | Test.java:34:48:34:52 | "foo" | Test.java:34:48:34:52 | "foo" | Cryptographic algorithm $@ may not be secure, consider using a different algorithm. | Test.java:34:48:34:52 | "foo" | foo | | WeakHashing.java:15:29:15:84 | getInstance(...) | WeakHashing.java:15:55:15:83 | getProperty(...) | WeakHashing.java:15:55:15:83 | getProperty(...) | Cryptographic algorithm $@ may not be secure, consider using a different algorithm. | WeakHashing.java:15:55:15:83 | getProperty(...) | MD5 | | WeakHashing.java:18:30:18:96 | getInstance(...) | WeakHashing.java:18:56:18:95 | getProperty(...) | WeakHashing.java:18:56:18:95 | getProperty(...) | Cryptographic algorithm $@ may not be secure, consider using a different algorithm. | WeakHashing.java:18:56:18:95 | getProperty(...) | MD5 | | WeakHashing.java:21:30:21:92 | getInstance(...) | WeakHashing.java:21:56:21:91 | getProperty(...) | WeakHashing.java:21:56:21:91 | getProperty(...) | Cryptographic algorithm $@ may not be secure, consider using a different algorithm. | WeakHashing.java:21:56:21:91 | getProperty(...) | MD5 | +| WeakHashing.java:30:29:30:65 | getInstance(...) | WeakHashing.java:30:55:30:64 | "SHA3-512" | WeakHashing.java:30:55:30:64 | "SHA3-512" | Cryptographic algorithm $@ may not be secure, consider using a different algorithm. | WeakHashing.java:30:55:30:64 | "SHA3-512" | SHA3-512 | diff --git a/java/ql/test/query-tests/security/CWE-327/semmle/tests/WeakHashing.java b/java/ql/test/query-tests/security/CWE-327/semmle/tests/WeakHashing.java index 6a3565fc141..8858576cb90 100644 --- a/java/ql/test/query-tests/security/CWE-327/semmle/tests/WeakHashing.java +++ b/java/ql/test/query-tests/security/CWE-327/semmle/tests/WeakHashing.java @@ -25,5 +25,8 @@ public class WeakHashing { // OK: Property does not exist and default is secure MessageDigest ok2 = MessageDigest.getInstance(props.getProperty("hashAlg3", "SHA-256")); + + // GOOD: Using a strong hashing algorithm + MessageDigest ok3 = MessageDigest.getInstance("SHA3-512"); } -} \ No newline at end of file +} From c6eaed343d25275580fa228c0c2013dc1a0af206 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Fri, 22 Nov 2024 18:43:48 +0100 Subject: [PATCH 212/470] Java: add SHA3 family to list of secure crypto algorithms --- java/ql/lib/semmle/code/java/security/Encryption.qll | 2 +- java/ql/src/change-notes/2024-11-22-sha3.md | 4 ++++ .../CWE-327/semmle/tests/MaybeBrokenCryptoAlgorithm.expected | 2 -- 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 java/ql/src/change-notes/2024-11-22-sha3.md diff --git a/java/ql/lib/semmle/code/java/security/Encryption.qll b/java/ql/lib/semmle/code/java/security/Encryption.qll index 6fc7f6b7d16..80b41233bde 100644 --- a/java/ql/lib/semmle/code/java/security/Encryption.qll +++ b/java/ql/lib/semmle/code/java/security/Encryption.qll @@ -250,7 +250,7 @@ string getASecureAlgorithmName() { result = [ "RSA", "SHA-?256", "SHA-?512", "CCM", "GCM", "AES(?![^a-zA-Z](ECB|CBC/PKCS[57]Padding))", - "Blowfish", "ECIES" + "Blowfish", "ECIES", "SHA3-(224|256|384|512)" ] } diff --git a/java/ql/src/change-notes/2024-11-22-sha3.md b/java/ql/src/change-notes/2024-11-22-sha3.md new file mode 100644 index 00000000000..61dbc35162e --- /dev/null +++ b/java/ql/src/change-notes/2024-11-22-sha3.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added SHA3 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA3. diff --git a/java/ql/test/query-tests/security/CWE-327/semmle/tests/MaybeBrokenCryptoAlgorithm.expected b/java/ql/test/query-tests/security/CWE-327/semmle/tests/MaybeBrokenCryptoAlgorithm.expected index a9365ae398d..da6f6312a89 100644 --- a/java/ql/test/query-tests/security/CWE-327/semmle/tests/MaybeBrokenCryptoAlgorithm.expected +++ b/java/ql/test/query-tests/security/CWE-327/semmle/tests/MaybeBrokenCryptoAlgorithm.expected @@ -4,11 +4,9 @@ nodes | WeakHashing.java:15:55:15:83 | getProperty(...) | semmle.label | getProperty(...) | | WeakHashing.java:18:56:18:95 | getProperty(...) | semmle.label | getProperty(...) | | WeakHashing.java:21:56:21:91 | getProperty(...) | semmle.label | getProperty(...) | -| WeakHashing.java:30:55:30:64 | "SHA3-512" | semmle.label | "SHA3-512" | subpaths #select | Test.java:34:21:34:53 | new SecretKeySpec(...) | Test.java:34:48:34:52 | "foo" | Test.java:34:48:34:52 | "foo" | Cryptographic algorithm $@ may not be secure, consider using a different algorithm. | Test.java:34:48:34:52 | "foo" | foo | | WeakHashing.java:15:29:15:84 | getInstance(...) | WeakHashing.java:15:55:15:83 | getProperty(...) | WeakHashing.java:15:55:15:83 | getProperty(...) | Cryptographic algorithm $@ may not be secure, consider using a different algorithm. | WeakHashing.java:15:55:15:83 | getProperty(...) | MD5 | | WeakHashing.java:18:30:18:96 | getInstance(...) | WeakHashing.java:18:56:18:95 | getProperty(...) | WeakHashing.java:18:56:18:95 | getProperty(...) | Cryptographic algorithm $@ may not be secure, consider using a different algorithm. | WeakHashing.java:18:56:18:95 | getProperty(...) | MD5 | | WeakHashing.java:21:30:21:92 | getInstance(...) | WeakHashing.java:21:56:21:91 | getProperty(...) | WeakHashing.java:21:56:21:91 | getProperty(...) | Cryptographic algorithm $@ may not be secure, consider using a different algorithm. | WeakHashing.java:21:56:21:91 | getProperty(...) | MD5 | -| WeakHashing.java:30:29:30:65 | getInstance(...) | WeakHashing.java:30:55:30:64 | "SHA3-512" | WeakHashing.java:30:55:30:64 | "SHA3-512" | Cryptographic algorithm $@ may not be secure, consider using a different algorithm. | WeakHashing.java:30:55:30:64 | "SHA3-512" | SHA3-512 | From addef2f1713ed270a56855304e46599e2c2b9d03 Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 22 Nov 2024 22:32:15 +0000 Subject: [PATCH 213/470] Add script and VSCode task for creating change notes Adds a VSCode Task (accessible from the "Run Task" menu) for creating change notes, prompting the user for the language, name, and category of the change. The language options presented are based on the existing occurrences of `change-notes` folders in the repo. There are more such files (in particular every shared library has a `change-notes` directory), but it seemed to me that the language change notes are the ones that are most common, and so in an effort to not clutter the list too much, I only included the languages. The selection of categories is based on existing usage -- more specifically the result of grepping for occurrences of '^category: ' in the repo. It's possible there are more change categories that could be added. Hopefully this should make it more convenient to create change notes from within VSCode. --- .vscode/tasks.json | 52 ++++++++++++++++++++++++++++++ misc/scripts/create-change-note.py | 51 +++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 misc/scripts/create-change-note.py diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 68df2f6f498..9737e18c692 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -38,6 +38,58 @@ "command": "${config:python.pythonPath}", }, "problemMatcher": [] + }, + { + "label": "Create change note", + "type": "process", + "command": "python3", + "args": [ + "misc/scripts/create-change-note.py", + "${input:language}", + "${input:name}", + "${input:category}" + ], + "presentation": { + "reveal": "never", + "close": true + }, + "problemMatcher": [] + } + ], + "inputs": [ + { + "type": "pickString", + "id": "language", + "description": "Language", + "options": + [ + "go", + "java", + "javascript", + "cpp", + "csharp", + "python", + "ruby", + "swift", + ] + }, + { + "type": "promptString", + "id": "name", + "description": "Name" + }, + { + "type": "pickString", + "id": "category", + "description": "Category", + "options": + [ + "minorAnalysis", + "newQuery", + "fix", + "majorAnalysis", + "breaking", + ] } ] } diff --git a/misc/scripts/create-change-note.py b/misc/scripts/create-change-note.py new file mode 100644 index 00000000000..bf82b76a18a --- /dev/null +++ b/misc/scripts/create-change-note.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 + +# Creates a change note and opens it in VSCode for editing. + +# Expects to receive the following arguments: +# - What language the change note is for +# - The name of the change note (in kebab-case) +# - The category of the change. + +# The change note will be created in the `{language}/ql/lib/change-notes` directory. + +# The format of the change note filename is `{current_date}-{change_note_name}.md` with the date in +# the format `YYYY-MM-DD`. + +import sys +import os + +# Read the given arguments +language = sys.argv[1] +change_note_name = sys.argv[2] +change_category = sys.argv[3] + +# Find the root of the repository. The current script should be located in `misc/scripts`. +root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +# Go to the repo root +os.chdir(root) + +# Abort if the output directory doesn't exist +if not os.path.exists(f"{language}/ql/lib/change-notes"): + print(f"Output directory {language}/ql/lib/change-notes does not exist") + sys.exit(1) + +# Get the current date +import datetime +current_date = datetime.datetime.now().strftime("%Y-%m-%d") + +# Create the change note file +change_note_file = f"{language}/ql/lib/change-notes/{current_date}-{change_note_name}.md" + +change_note = f""" +--- +category: {change_category} +--- +* """.lstrip() + +with open(change_note_file, "w") as f: + f.write(change_note) + +# Open the change note file in VSCode, reusing the existing window if possible +os.system(f"code -r {change_note_file}") From 72107867215ab4254b83dbe41499118128f1152c Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Sun, 24 Nov 2024 21:24:24 -0500 Subject: [PATCH 214/470] Subtypes/overrides documentation Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- .../customizing-library-models-for-go.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index bf56447fce1..d5a092d7dcf 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -89,14 +89,14 @@ We need to add a tuple to the ``sinkModel``\(package, type, subtypes, name, sign pack: codeql/go-all extensible: sinkModel data: - - ["database/sql", "DB", False, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] + - ["database/sql", "DB", True, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"] Since we want to add a new sink, we need to add a tuple to the ``sinkModel`` extensible predicate. The first five values identify the function (in this case a method) to be modeled as a sink. - The first value ``database/sql`` is the package name. - The second value ``DB`` is the name of the type that the method is associated with. -- The third value ``False`` is a flag that indicates whether or not the sink also applies to all overrides of the method. +- The third value ``True`` is a flag that indicates whether or not the sink also applies to subtypes. This includes when the subtype embeds the given type, so that the method or field is promoted to be a method or field of the subtype. For interface methods it also includes types which implement the interface type. - The fourth value ``Prepare`` is the method name. - The fifth value ``""`` is the method input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions or methods may have the same name and they need to be distinguished by the number and types of the arguments. @@ -137,7 +137,7 @@ The first five values identify the function to be modeled as a source. - The first value ``net/http`` is the package name. - The second value ``Request`` is the type name, since the function is a method of the ``Request`` type. -- The third value ``True`` is a flag that indicates whether or not the source also applies to all overrides of the method. +- The third value ``True`` is a flag that indicates whether or not the sink also applies to subtypes. This includes when the subtype embeds the given type, so that the method or field is promoted to be a method or field of the subtype. For interface methods it also includes types which implement the interface type. - The fourth value ``FormValue`` is the function name. - The fifth value ``""`` is the function input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions or methods may have the same name and they need to be distinguished by the number and types of the arguments. @@ -183,7 +183,7 @@ These are the same for both of the rows above as we are adding two summaries for - The first value ``strings`` is the package name. - The second value ``""`` is left blank, since the function is not a method of a type. -- The third value ``False`` is a flag that indicates whether or not the summary also applies to all overrides of the method. +- The third value ``False`` is a flag that indicates whether or not the sink also applies to subtypes. This has no effect for non-method functions. - The fourth value ``Join`` is the function name. - The fifth value ``""`` is left blank, since specifying the signature is optional and Go does not allow multiple signature overloads for the same function. @@ -238,7 +238,7 @@ The first five values identify the function (in this case a method) to be modele - The first value ``net/url`` is the package name. - The second value ``URL`` is the receiver type. -- The third value ``True`` is a flag that indicates whether or not the summary also applies to all overrides of the method. +- The third value ``True`` is a flag that indicates whether or not the sink also applies to subtypes. This includes when the subtype embeds the given type, so that the method or field is promoted to be a method or field of the subtype. For interface methods it also includes types which implement the interface type. - The fourth value ``Hostname`` is the method name. - The fifth value ``""`` is left blank, since specifying the signature is optional and Go does not allow multiple signature overloads for the same function. @@ -277,7 +277,7 @@ The first five values identify the field to be modeled as a source. - The first value ``net/http`` is the package name. - The second value ``Request`` is the name of the type that the field is associated with. -- The third value ``True`` is a flag that indicates whether or not the source also applies to all overrides of the field. +- The third value ``True`` is a flag that indicates whether or not the sink also applies to subtypes. For fields this means when the field is accessed as a promoted field in another type. - The fourth value ``Body`` is the field name. - The fifth value ``""`` is blank since it is a field access and field accesses do not have method signatures in Go. From fb04e39935cd1e780a880097302a375d364d5e9c Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Sun, 24 Nov 2024 21:24:53 -0500 Subject: [PATCH 215/470] `ReturnValue[i]` text Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- .../customizing-library-models-for-go.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index d5a092d7dcf..4458613a976 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -246,7 +246,7 @@ The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the summary. - The seventh value is the access path to the input (where data flows from). ``Argument[receiver]`` is the access path to the receiver (``u`` in the example). -- The eighth value ``ReturnValue`` is the access path to the output (where data flows to), in this case ``ReturnValue``, which means that the input flows to the return value. +- The eighth value ``ReturnValue`` is the access path to the output (where data flows to), in this case ``ReturnValue``, which means that the input flows to the return value. When there are multiple return values, use `ReturnValue[i]` to refer to the `i`th return value (starting from 0). - The ninth value ``taint`` is the kind of the flow. ``taint`` means that taint is propagated through the call. - The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. From 940a99db3b63bf0ceb773618a6577982d92d7618 Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Sun, 24 Nov 2024 21:25:09 -0500 Subject: [PATCH 216/470] Fix typo Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- .../customizing-library-models-for-go.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index 4458613a976..08bc8e29e19 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -215,7 +215,7 @@ This example shows how the Go query pack models flow through a method for a simp .. code-block:: go func TaintFlow(u *url.URL) { - host := u.Hostname() // There is taint flow from u to s. + host := u.Hostname() // There is taint flow from u to host. ... } From f8d623e9051fa5b09775d922b431e2fadf1132c0 Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 25 Nov 2024 09:08:51 +0100 Subject: [PATCH 217/470] JS: Bumped TS version to 5.7.2 --- javascript/extractor/lib/typescript/package-lock.json | 8 ++++---- javascript/extractor/lib/typescript/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/javascript/extractor/lib/typescript/package-lock.json b/javascript/extractor/lib/typescript/package-lock.json index 47015f8f6e3..1978e396324 100644 --- a/javascript/extractor/lib/typescript/package-lock.json +++ b/javascript/extractor/lib/typescript/package-lock.json @@ -6,7 +6,7 @@ "": { "name": "typescript-parser-wrapper", "dependencies": { - "typescript": "^5.7.1-rc" + "typescript": "^5.7.2" }, "devDependencies": { "@types/node": "18.15.3" @@ -20,9 +20,9 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "5.7.1-rc", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.1-rc.tgz", - "integrity": "sha512-d6m+HT78uZtyUbXbUyIvuJ6kXCTSJEfy+2pZSUwt9d6JZ0kOMNDwhIILfV5FnaxMwVa48Yfw4sK0ISC4Qyq5tw==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/javascript/extractor/lib/typescript/package.json b/javascript/extractor/lib/typescript/package.json index 730a3b5f53e..9d77f4ab740 100644 --- a/javascript/extractor/lib/typescript/package.json +++ b/javascript/extractor/lib/typescript/package.json @@ -2,7 +2,7 @@ "name": "typescript-parser-wrapper", "private": true, "dependencies": { - "typescript": "^5.7.1-rc" + "typescript": "^5.7.2" }, "scripts": { "build": "tsc --project tsconfig.json", From 3d467b24f8f40f0e0d3f2bdfffbc7249fdd72135 Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 25 Nov 2024 09:30:01 +0100 Subject: [PATCH 218/470] Added change notes --- 2024-11-25-ts57.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 2024-11-25-ts57.md diff --git a/2024-11-25-ts57.md b/2024-11-25-ts57.md new file mode 100644 index 00000000000..3a92872d6d6 --- /dev/null +++ b/2024-11-25-ts57.md @@ -0,0 +1,4 @@ +--- +category: majorAnalysis +--- +* Added support for TypeScript 5.7. From bded7085f0b2c456ea60f1c26e8949bde2c3f215 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 25 Nov 2024 10:01:47 +0000 Subject: [PATCH 219/470] Rust: Effect of toString changes in main. --- .../dataflow/sources/TaintSources.expected | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected index 50336f15571..cebbc00f3a5 100644 --- a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected +++ b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected @@ -1,17 +1,17 @@ -| test.rs:8:10:8:30 | CallExpr | Flow source 'EnvironmentSource' of type environment. | -| test.rs:9:10:9:33 | CallExpr | Flow source 'EnvironmentSource' of type environment. | -| test.rs:11:16:11:36 | CallExpr | Flow source 'EnvironmentSource' of type environment. | -| test.rs:12:16:12:39 | CallExpr | Flow source 'EnvironmentSource' of type environment. | -| test.rs:17:25:17:40 | CallExpr | Flow source 'EnvironmentSource' of type environment. | -| test.rs:22:25:22:43 | CallExpr | Flow source 'EnvironmentSource' of type environment. | -| test.rs:29:29:29:44 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:32:16:32:31 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:33:16:33:34 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:40:16:40:31 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:44:16:44:34 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:50:15:50:37 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:51:15:51:37 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:52:16:52:35 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:60:26:60:70 | CallExpr | Flow source 'RemoteSource' of type remote (DEFAULT). | -| test.rs:63:26:63:70 | CallExpr | Flow source 'RemoteSource' of type remote (DEFAULT). | -| test.rs:66:26:66:60 | CallExpr | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:8:10:8:30 | ...::var(...) | Flow source 'EnvironmentSource' of type environment. | +| test.rs:9:10:9:33 | ...::var_os(...) | Flow source 'EnvironmentSource' of type environment. | +| test.rs:11:16:11:36 | ...::var(...) | Flow source 'EnvironmentSource' of type environment. | +| test.rs:12:16:12:39 | ...::var_os(...) | Flow source 'EnvironmentSource' of type environment. | +| test.rs:17:25:17:40 | ...::vars(...) | Flow source 'EnvironmentSource' of type environment. | +| test.rs:22:25:22:43 | ...::vars_os(...) | Flow source 'EnvironmentSource' of type environment. | +| test.rs:29:29:29:44 | ...::args(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:32:16:32:31 | ...::args(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:33:16:33:34 | ...::args_os(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:40:16:40:31 | ...::args(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:44:16:44:34 | ...::args_os(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:50:15:50:37 | ...::current_dir(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:51:15:51:37 | ...::current_exe(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:52:16:52:35 | ...::home_dir(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:60:26:60:70 | ...::get(...) | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:63:26:63:70 | ...::get(...) | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:66:26:66:60 | ...::get(...) | Flow source 'RemoteSource' of type remote (DEFAULT). | From 68a4ea3be06f87366e80cd250d9b60dfc3eb8f5d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 21 Nov 2024 13:02:52 +0000 Subject: [PATCH 220/470] Rust: New query rust/ctor-initialization (placeholder). undo --- .../security/CWE-696/BadCtorInitialization.ql | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql new file mode 100644 index 00000000000..9d6fa7351e7 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -0,0 +1,16 @@ +/** + * @name Bad 'ctor' initialization + * @description TODO + * @kind path-problem + * @problem.severity error + * @ security-severity TODO + * @ precision TODO + * @id rust/ctor-initialization + * @tags security + * external/cwe/cwe-696 + * external/cwe/cwe-665 + */ + +import rust + +select 0 From 5eb91fd5168ae675bf1c8f6f89ae38641cc4da14 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Mon, 25 Nov 2024 11:25:45 +0100 Subject: [PATCH 221/470] Drop SHA3-224 Drop the 224bits variant as it looks like SHA3-224 may be deprecated soon based on NIST's most recent draft revision of Transitioning the Use of Cryptographic Algorithms and Key Lengths --- java/ql/lib/semmle/code/java/security/Encryption.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/Encryption.qll b/java/ql/lib/semmle/code/java/security/Encryption.qll index 80b41233bde..e6608d85872 100644 --- a/java/ql/lib/semmle/code/java/security/Encryption.qll +++ b/java/ql/lib/semmle/code/java/security/Encryption.qll @@ -250,7 +250,7 @@ string getASecureAlgorithmName() { result = [ "RSA", "SHA-?256", "SHA-?512", "CCM", "GCM", "AES(?![^a-zA-Z](ECB|CBC/PKCS[57]Padding))", - "Blowfish", "ECIES", "SHA3-(224|256|384|512)" + "Blowfish", "ECIES", "SHA3-(256|384|512)" ] } From 178da21fb8868280826e3d1dbec5a1e43f673717 Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 25 Nov 2024 11:53:00 +0100 Subject: [PATCH 222/470] JS: Added test case for CWE-178 RegExp with unknown flags --- .../CWE-178/CaseSensitiveMiddlewarePath.expected | 1 + .../ql/test/query-tests/Security/CWE-178/tst.js | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected index 2195bbf0029..2be1780188a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected @@ -2,6 +2,7 @@ | tst.js:14:5:14:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/FOO/1' will bypass the middleware. | tst.js:14:5:14:28 | new Reg ... (.*)?') | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | case-insensitive path | | tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/FOO/1' will bypass the middleware. | tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | case-insensitive path | | tst.js:64:5:64:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAR/1' will bypass the middleware. | tst.js:64:5:64:28 | new Reg ... (.*)?') | pattern | tst.js:73:1:74:2 | app.get ... ware\\n}) | case-insensitive path | +| tst.js:64:5:64:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAR/1' will bypass the middleware. | tst.js:64:5:64:28 | new Reg ... (.*)?') | pattern | tst.js:107:1:108:2 | app.get ... ware\\n}) | case-insensitive path | | tst.js:76:9:76:20 | /\\/baz\\/bla/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAZ/BLA' will bypass the middleware. | tst.js:76:9:76:20 | /\\/baz\\/bla/ | pattern | tst.js:77:1:79:2 | app.get ... });\\n}) | case-insensitive path | | tst.js:86:9:86:30 | /\\/[Bb] ... 3\\/[a]/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAZ3/A' will bypass the middleware. | tst.js:86:9:86:30 | /\\/[Bb] ... 3\\/[a]/ | pattern | tst.js:87:1:89:2 | app.get ... });\\n}) | case-insensitive path | | tst.js:91:9:91:40 | /\\/summ ... ntGame/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/CURRENTGAME' will bypass the middleware. | tst.js:91:9:91:40 | /\\/summ ... ntGame/ | pattern | tst.js:93:1:95:2 | app.get ... O");\\n}) | case-insensitive path | diff --git a/javascript/ql/test/query-tests/Security/CWE-178/tst.js b/javascript/ql/test/query-tests/Security/CWE-178/tst.js index 5fcc3cc94a0..3dd24029ebe 100644 --- a/javascript/ql/test/query-tests/Security/CWE-178/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-178/tst.js @@ -93,3 +93,16 @@ app.use(/\/summonerByName|\/currentGame/,apiLimit1, apiLimit2); app.get('/currentGame', function (req, res) { res.send("FOO"); }); + +app.get( + new RegExp('^/bar(.*)?', unknownFlag()), // NOT OK - Currently not flagged. + unknown(), + function(req, res, next) { + if (req.params.blah) { + next(); + } + } +); + +app.get('/bar/*', (req, res) => { // OK - not a middleware +}); From e38b63ebcda88f698ab728c8d2aabd12cef06c51 Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 25 Nov 2024 11:56:06 +0100 Subject: [PATCH 223/470] JS: previously js/case-sensitive-middleware-path was not taking into consideration unknown flags --- .../ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql | 2 +- .../Security/CWE-178/CaseSensitiveMiddlewarePath.expected | 1 + javascript/ql/test/query-tests/Security/CWE-178/tst.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql index d16f72d4172..2045d801c70 100644 --- a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql @@ -65,7 +65,7 @@ predicate isCaseSensitiveMiddleware( arg = call.getArgument(0) and regexp.getAReference().flowsTo(arg) and exists(string flags | - flags = regexp.getFlags() and + flags = regexp.tryGetFlags() and not RegExp::isIgnoreCase(flags) ) ) diff --git a/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected index 2be1780188a..cb1720260ef 100644 --- a/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected @@ -6,3 +6,4 @@ | tst.js:76:9:76:20 | /\\/baz\\/bla/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAZ/BLA' will bypass the middleware. | tst.js:76:9:76:20 | /\\/baz\\/bla/ | pattern | tst.js:77:1:79:2 | app.get ... });\\n}) | case-insensitive path | | tst.js:86:9:86:30 | /\\/[Bb] ... 3\\/[a]/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAZ3/A' will bypass the middleware. | tst.js:86:9:86:30 | /\\/[Bb] ... 3\\/[a]/ | pattern | tst.js:87:1:89:2 | app.get ... });\\n}) | case-insensitive path | | tst.js:91:9:91:40 | /\\/summ ... ntGame/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/CURRENTGAME' will bypass the middleware. | tst.js:91:9:91:40 | /\\/summ ... ntGame/ | pattern | tst.js:93:1:95:2 | app.get ... O");\\n}) | case-insensitive path | +| tst.js:98:5:98:43 | new Reg ... Flag()) | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAR/1' will bypass the middleware. | tst.js:98:5:98:43 | new Reg ... Flag()) | pattern | tst.js:107:1:108:2 | app.get ... ware\\n}) | case-insensitive path | diff --git a/javascript/ql/test/query-tests/Security/CWE-178/tst.js b/javascript/ql/test/query-tests/Security/CWE-178/tst.js index 3dd24029ebe..69a203cb8df 100644 --- a/javascript/ql/test/query-tests/Security/CWE-178/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-178/tst.js @@ -95,7 +95,7 @@ app.get('/currentGame', function (req, res) { }); app.get( - new RegExp('^/bar(.*)?', unknownFlag()), // NOT OK - Currently not flagged. + new RegExp('^/bar(.*)?', unknownFlag()), // NOT OK - Might be OK if the unknown flag evaluates to case insensitive one unknown(), function(req, res, next) { if (req.params.blah) { From d6372aebc76cb196665f34e05671b0006bc6445c Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Mon, 25 Nov 2024 12:11:07 +0100 Subject: [PATCH 224/470] Update javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql Co-authored-by: Erik Krogh Kristensen --- .../ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql | 2 +- .../Security/CWE-178/CaseSensitiveMiddlewarePath.expected | 1 - javascript/ql/test/query-tests/Security/CWE-178/tst.js | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql index 2045d801c70..997ee8971a5 100644 --- a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql @@ -66,7 +66,7 @@ predicate isCaseSensitiveMiddleware( regexp.getAReference().flowsTo(arg) and exists(string flags | flags = regexp.tryGetFlags() and - not RegExp::isIgnoreCase(flags) + not RegExp::maybeIgnoreCase(flags) ) ) } diff --git a/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected index cb1720260ef..2be1780188a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected @@ -6,4 +6,3 @@ | tst.js:76:9:76:20 | /\\/baz\\/bla/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAZ/BLA' will bypass the middleware. | tst.js:76:9:76:20 | /\\/baz\\/bla/ | pattern | tst.js:77:1:79:2 | app.get ... });\\n}) | case-insensitive path | | tst.js:86:9:86:30 | /\\/[Bb] ... 3\\/[a]/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAZ3/A' will bypass the middleware. | tst.js:86:9:86:30 | /\\/[Bb] ... 3\\/[a]/ | pattern | tst.js:87:1:89:2 | app.get ... });\\n}) | case-insensitive path | | tst.js:91:9:91:40 | /\\/summ ... ntGame/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/CURRENTGAME' will bypass the middleware. | tst.js:91:9:91:40 | /\\/summ ... ntGame/ | pattern | tst.js:93:1:95:2 | app.get ... O");\\n}) | case-insensitive path | -| tst.js:98:5:98:43 | new Reg ... Flag()) | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAR/1' will bypass the middleware. | tst.js:98:5:98:43 | new Reg ... Flag()) | pattern | tst.js:107:1:108:2 | app.get ... ware\\n}) | case-insensitive path | diff --git a/javascript/ql/test/query-tests/Security/CWE-178/tst.js b/javascript/ql/test/query-tests/Security/CWE-178/tst.js index 69a203cb8df..81bbe993291 100644 --- a/javascript/ql/test/query-tests/Security/CWE-178/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-178/tst.js @@ -95,7 +95,7 @@ app.get('/currentGame', function (req, res) { }); app.get( - new RegExp('^/bar(.*)?', unknownFlag()), // NOT OK - Might be OK if the unknown flag evaluates to case insensitive one + new RegExp('^/bar(.*)?', unknownFlag()), // OK - Might be OK if the unknown flag evaluates to case insensitive one unknown(), function(req, res, next) { if (req.params.blah) { From 37935eea3b9778636d9295023f940c0c5eaf4a8d Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 25 Nov 2024 12:32:11 +0100 Subject: [PATCH 225/470] java: separate bounds onto different lines --- .../library-tests/dataflow/range-analysis-inline/B.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java b/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java index 7cc30479537..4818e93d894 100644 --- a/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java +++ b/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java @@ -27,7 +27,8 @@ public class B { public int forloopexitupd() { int result = 0; - for (; result < 10; result++) { // $ bound="result in [0..9]" bound="result in [0..10]" + for (; result < 10; // $ bound="result in [0..10]" + result++) { // $ bound="result in [0..9]" } return result; // $ bound="result = 10" } @@ -46,7 +47,8 @@ public class B { public int emptyforloop() { int result = 0; - for (int i = 0; i < 0; i++) { // $ bound="i = 0" bound="i in [0..-1]" + for (int i = 0; i < 0; // $ bound="i = 0" + i++) { // $ bound="i in [0..-1]" result = i; // $ bound="i in [0..-1]" } return result; // $ bound="result = 0" From 0d02126f12b469dc292da390ec51fee3c212c1e1 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 25 Nov 2024 14:07:50 +0100 Subject: [PATCH 226/470] Generate ParamBase, superclass of Param and SelfParam --- rust/extractor/src/generated/.generated.list | 2 +- rust/extractor/src/generated/top.rs | 256 +++++++++++------- rust/ql/.generated.list | 27 +- rust/ql/.gitattributes | 3 + .../internal/generated/CfgNodes.qll | 89 +++--- rust/ql/lib/codeql/rust/elements.qll | 1 + rust/ql/lib/codeql/rust/elements/Param.qll | 10 +- .../ql/lib/codeql/rust/elements/ParamBase.qll | 14 + .../ql/lib/codeql/rust/elements/SelfParam.qll | 10 +- .../rust/elements/internal/ParamBaseImpl.qll | 19 ++ .../rust/elements/internal/ParamImpl.qll | 6 +- .../rust/elements/internal/SelfParamImpl.qll | 6 +- .../elements/internal/generated/Param.qll | 41 +-- .../elements/internal/generated/ParamBase.qll | 55 ++++ .../internal/generated/ParentChild.qll | 80 +++--- .../rust/elements/internal/generated/Raw.qll | 108 ++++---- .../elements/internal/generated/SelfParam.qll | 43 +-- .../elements/internal/generated/Synth.qll | 41 ++- rust/ql/lib/rust.dbscheme | 89 +++--- .../generated/.generated_tests.list | 4 +- .../generated/Param/Param.expected | 1 + .../extractor-tests/generated/Param/Param.ql | 8 +- .../generated/Param/Param_getPat.expected | 1 + .../generated/Param/Param_getTy.expected | 1 + .../generated/Param/gen_param.rs | 6 +- .../generated/SelfParam/SelfParam.expected | 1 + .../generated/SelfParam/SelfParam.ql | 10 +- .../SelfParam/SelfParam_getName.expected | 1 + .../generated/SelfParam/gen_self_param.rs | 6 +- rust/schema/annotations.py | 31 ++- 30 files changed, 552 insertions(+), 418 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/elements/ParamBase.qll create mode 100644 rust/ql/lib/codeql/rust/elements/internal/ParamBaseImpl.qll create mode 100644 rust/ql/lib/codeql/rust/elements/internal/generated/ParamBase.qll diff --git a/rust/extractor/src/generated/.generated.list b/rust/extractor/src/generated/.generated.list index 0f781aae8da..3ff79b9b041 100644 --- a/rust/extractor/src/generated/.generated.list +++ b/rust/extractor/src/generated/.generated.list @@ -1,2 +1,2 @@ mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 -top.rs 7a5bbe75eae6069f4f255db13787a3575e706742af1f57122c02d46895de9a1b 7a5bbe75eae6069f4f255db13787a3575e706742af1f57122c02d46895de9a1b +top.rs 4504ceb7e13020d5b19a4b938395fa2d5d804a962743985efe8563903448ae0c 4504ceb7e13020d5b19a4b938395fa2d5d804a962743985efe8563903448ae0c diff --git a/rust/extractor/src/generated/top.rs b/rust/extractor/src/generated/top.rs index eb1f16f8cc6..a3e1d7aac80 100644 --- a/rust/extractor/src/generated/top.rs +++ b/rust/extractor/src/generated/top.rs @@ -1501,57 +1501,35 @@ impl From> for trap::Label { } #[derive(Debug)] -pub struct Param { - pub id: trap::TrapId, - pub attrs: Vec>, - pub pat: Option>, - pub ty: Option>, +pub struct ParamBase { + _unused: () } -impl trap::TrapEntry for Param { - fn extract_id(&mut self) -> trap::TrapId { - std::mem::replace(&mut self.id, trap::TrapId::Star) - } - - fn emit(self, id: trap::Label, out: &mut trap::Writer) { - out.add_tuple("params", vec![id.into()]); - for (i, v) in self.attrs.into_iter().enumerate() { - out.add_tuple("param_attrs", vec![id.into(), i.into(), v.into()]); - } - if let Some(v) = self.pat { - out.add_tuple("param_pats", vec![id.into(), v.into()]); - } - if let Some(v) = self.ty { - out.add_tuple("param_ties", vec![id.into(), v.into()]); - } - } +impl trap::TrapClass for ParamBase { + fn class_name() -> &'static str { "ParamBase" } } -impl trap::TrapClass for Param { - fn class_name() -> &'static str { "Param" } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme Param is a subclass of AstNode +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ParamBase is a subclass of AstNode unsafe { Self::from_untyped(value.as_untyped()) } } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme Param is a subclass of Element +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ParamBase is a subclass of Element unsafe { Self::from_untyped(value.as_untyped()) } } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme Param is a subclass of Locatable +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ParamBase is a subclass of Locatable unsafe { Self::from_untyped(value.as_untyped()) } @@ -2203,72 +2181,6 @@ impl From> for trap::Label { } } -#[derive(Debug)] -pub struct SelfParam { - pub id: trap::TrapId, - pub attrs: Vec>, - pub is_mut: bool, - pub lifetime: Option>, - pub name: Option>, - pub ty: Option>, -} - -impl trap::TrapEntry for SelfParam { - fn extract_id(&mut self) -> trap::TrapId { - std::mem::replace(&mut self.id, trap::TrapId::Star) - } - - fn emit(self, id: trap::Label, out: &mut trap::Writer) { - out.add_tuple("self_params", vec![id.into()]); - for (i, v) in self.attrs.into_iter().enumerate() { - out.add_tuple("self_param_attrs", vec![id.into(), i.into(), v.into()]); - } - if self.is_mut { - out.add_tuple("self_param_is_mut", vec![id.into()]); - } - if let Some(v) = self.lifetime { - out.add_tuple("self_param_lifetimes", vec![id.into(), v.into()]); - } - if let Some(v) = self.name { - out.add_tuple("self_param_names", vec![id.into(), v.into()]); - } - if let Some(v) = self.ty { - out.add_tuple("self_param_ties", vec![id.into(), v.into()]); - } - } -} - -impl trap::TrapClass for SelfParam { - fn class_name() -> &'static str { "SelfParam" } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme SelfParam is a subclass of AstNode - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme SelfParam is a subclass of Element - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme SelfParam is a subclass of Locatable - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - #[derive(Debug)] pub struct SourceFile { pub id: trap::TrapId, @@ -5862,6 +5774,73 @@ impl From> for trap::Label { } } +#[derive(Debug)] +pub struct Param { + pub id: trap::TrapId, + pub attrs: Vec>, + pub ty: Option>, + pub pat: Option>, +} + +impl trap::TrapEntry for Param { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("params", vec![id.into()]); + for (i, v) in self.attrs.into_iter().enumerate() { + out.add_tuple("param_base_attrs", vec![id.into(), i.into(), v.into()]); + } + if let Some(v) = self.ty { + out.add_tuple("param_base_ties", vec![id.into(), v.into()]); + } + if let Some(v) = self.pat { + out.add_tuple("param_pats", vec![id.into(), v.into()]); + } + } +} + +impl trap::TrapClass for Param { + fn class_name() -> &'static str { "Param" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Param is a subclass of AstNode + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Param is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Param is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Param is a subclass of ParamBase + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + #[derive(Debug)] pub struct ParenExpr { pub id: trap::TrapId, @@ -7053,6 +7032,81 @@ impl From> for trap::Label { } } +#[derive(Debug)] +pub struct SelfParam { + pub id: trap::TrapId, + pub attrs: Vec>, + pub ty: Option>, + pub is_mut: bool, + pub lifetime: Option>, + pub name: Option>, +} + +impl trap::TrapEntry for SelfParam { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("self_params", vec![id.into()]); + for (i, v) in self.attrs.into_iter().enumerate() { + out.add_tuple("param_base_attrs", vec![id.into(), i.into(), v.into()]); + } + if let Some(v) = self.ty { + out.add_tuple("param_base_ties", vec![id.into(), v.into()]); + } + if self.is_mut { + out.add_tuple("self_param_is_mut", vec![id.into()]); + } + if let Some(v) = self.lifetime { + out.add_tuple("self_param_lifetimes", vec![id.into(), v.into()]); + } + if let Some(v) = self.name { + out.add_tuple("self_param_names", vec![id.into(), v.into()]); + } + } +} + +impl trap::TrapClass for SelfParam { + fn class_name() -> &'static str { "SelfParam" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme SelfParam is a subclass of AstNode + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme SelfParam is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme SelfParam is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme SelfParam is a subclass of ParamBase + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + #[derive(Debug)] pub struct SlicePat { pub id: trap::TrapId, diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 6c3cf6ea6a0..913bdf1d293 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -1,4 +1,4 @@ -lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll 4005dd5213c45c8f96e12f08d8a6a7532692d68a3cd9e3a0fd55d7f982a92f23 ec753357ac4fc76706acc0cf1d9208e63a0688e480ece52e4314d7dc2a743de5 +lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll e1d6ad3a582c15addb042ce1e054a916f81030f7a10a69408ab929679e9a92ad f1837efe28fb1ae5162437a482d35d24a792e133e10879284202c45e90c62ff6 lib/codeql/rust/elements/Abi.qll 4c973d28b6d628f5959d1f1cc793704572fd0acaae9a97dfce82ff9d73f73476 250f68350180af080f904cd34cb2af481c5c688dc93edf7365fd0ae99855e893 lib/codeql/rust/elements/ArgList.qll 661f5100f5d3ef8351452d9058b663a2a5c720eea8cf11bedd628969741486a2 28e424aac01a90fb58cd6f9f83c7e4cf379eea39e636bc0ba07efc818be71c71 lib/codeql/rust/elements/ArrayExpr.qll a3e6e122632f4011644ec31b37f88b32fe3f2b7e388e7e878a6883309937049f 12ccb5873d95c433da5606fd371d182ef2f71b78d0c53c2d6dec10fa45852bdc @@ -93,7 +93,8 @@ lib/codeql/rust/elements/NameRef.qll f11e33cdbefb3efdd8db6cd1eee593948a16ef5dd13 lib/codeql/rust/elements/NeverType.qll 669823dd60bba0cebac614f9dbad9dc9228405d76e62092e265df57fdd2e04e2 8fe32975ef80d86fb8b218f56962f0a89911008a8d6989e245c3e0362f2c747f lib/codeql/rust/elements/OffsetOfExpr.qll 8f6dd1fe0aad1642e58f5e97620306e4b36cdf01324fead1e2a92e8e60951c41 b192f7a5fae3049a6cac3b7a225a0e590f744e6c5ff6346ffdd1699f83bf718f lib/codeql/rust/elements/OrPat.qll 408b71f51edbfc79bf93b86fb058d01fa79caf2ebfeef37b50ae1da886c71b68 4a3f2b00db33fe26ee0859e35261016312cb491e23c46746cdd6d8bb1f6c88ef -lib/codeql/rust/elements/Param.qll 3108a710214977218421b220d1330793173d6b6b91708b641e3d1275f80faedb 4bb2b80d0a9a4d86f980440851d59ca6fffea681e5518f5d605c521191efd7b4 +lib/codeql/rust/elements/Param.qll d0c0a427c003bbbacaeb0c2f4566f35b997ad0bca4d49f97b50c3a4bd1ddbd71 e654a17dfcb7aaeb589e7944c38f591c4cf922ebceb834071bcb9f9165ee48be +lib/codeql/rust/elements/ParamBase.qll ab8cb39ac313a5dce7d1a6dcd490c5033034d88f0e402f315f4236bb76c2c464 414afc1f34c1df28f76220c5d3255ae3d7629f3df8b870d0949f3a6c87e26d71 lib/codeql/rust/elements/ParamList.qll 33a22ba7de565db4009d3f56eecd5ef809c28d9dce9bbac3fb71b528baae4f70 004375e227d87f76f930322ad3eac274f9b691bf58785ae69977fa319f3dba7e lib/codeql/rust/elements/ParenExpr.qll b635f0e5d300cd9cf3651cfcefd58316c21727295bbfd44b1f5672f9e3de67b6 d81c0034d4ea7ca5829f9b00e0a634ba5b557a6296d99f0b5344b11e1ba705a1 lib/codeql/rust/elements/ParenPat.qll 40d033de6c85ad042223e0da80479adebab35494396ab652da85d3497e435c5a 8f2febe5d5cefcb076d201ae9607d403b9cfe8169d2f4b71d13868e0af43dc25 @@ -126,7 +127,7 @@ lib/codeql/rust/elements/RestPat.qll a898a2c396f974a52424efbc8168174416ac6ed30f9 lib/codeql/rust/elements/RetType.qll 36ea39240a56c504d94d5487ea9679563eef3dfe0e23bf42d992d1ab2b883518 2fe5b6f62a634c6aa30a1ecd620f3446c167669cf1285c8ef8dd5e5a6ef5fc71 lib/codeql/rust/elements/ReturnExpr.qll b87187cff55bc33c8c18558c9b88617179183d1341b322c1cab35ba07167bbdb 892f3a9df2187e745c869e67f33c228ee42754bc9e4f8f4c1718472eb8f8c80f lib/codeql/rust/elements/ReturnTypeSyntax.qll 0aa9125f5ea8864ecf1e4ff6e85f060f1b11fdd603448816145fea1b290f0232 3911819548ad1cf493199aac2ed15652c8e48b532a1e92153388b062191c1e6e -lib/codeql/rust/elements/SelfParam.qll 5c9629e1cd837f5d84bdd79a1aef9cca6fb0acb1fb18671d4a4d28c23a74551a 41eb92527cf4379a2df54a0c9fabc368cb6f9b8d1ac73bd2ab3f13214573e764 +lib/codeql/rust/elements/SelfParam.qll 7d720c99097a340bc7bf6cc27ac6fe291a04af53e9bac23bf070b04b36e6e033 736488794a46ea702dcd3f603134052598207f3953acce3c9237bd6c6a038b23 lib/codeql/rust/elements/SlicePat.qll f48f13bb13378cc68f935d5b09175c316f3e81f50ef6a3ac5fdbfbfb473d6fc1 4c8df0b092274f37028e287a949f1a287f7505b7c2c36ee8d5f47fb8365d278a lib/codeql/rust/elements/SliceType.qll 7e49dba57826c7bb72a88f9e802febdb09adfc49804f6205dc88f2a307fd1f30 6c3ee430f812f1d9fbb1fb1fdd2c47130a4bde7fccf17f09404b8cbc8104678a lib/codeql/rust/elements/SourceFile.qll 5916d550385d618bd3b3d4835fbd3040485822220af8ce52ee1adb649b3d8594 0b79766216649e948fa59de467d64fa752de4666c28e0e503e88740ae27a2aef @@ -292,6 +293,7 @@ lib/codeql/rust/elements/internal/NeverTypeConstructor.qll 6a86bff9d885eddf39a15 lib/codeql/rust/elements/internal/OffsetOfExprConstructor.qll 616e146562adb3ac0fba4d6f55dd6ce60518ed377c0856f1f09ba49593e7bfab 80518ce90fc6d08011d6f5fc2a543958067739e1b0a6a5f2ed90fc9b1db078f0 lib/codeql/rust/elements/internal/OffsetOfExprImpl.qll e52d4596068cc54719438121f7d5afcaab04e0c70168ac5e4df1a3a0969817a6 6ab37e659d79e02fb2685d6802ae124157bf14b6f790b31688f437c87f40f52c lib/codeql/rust/elements/internal/OrPatConstructor.qll 4ef583e07298487c0c4c6d7c76ffcc04b1e5fe58aba0c1da3e2c8446a9e0c92b 980a6bd176ae5e5b11c134569910c5468ba91f480982d846e222d031a6a05f1a +lib/codeql/rust/elements/internal/ParamBaseImpl.qll fe11999c728c443c46c992e9bed7a2b3e23afa16ae99592e70054bc57ae371b8 df86fdb23266bdfb9ed8a8f02558a760b67f173943b9d075b081229eb5844f66 lib/codeql/rust/elements/internal/ParamConstructor.qll b98a2d8969f289fdcc8c0fb11cbd19a3b0c71be038c4a74f5988295a2bae52f0 77d81b31064167945b79b19d9697b57ca24462c3a7cc19e462c4693ce87db532 lib/codeql/rust/elements/internal/ParamListConstructor.qll 3123142ab3cab46fb53d7f3eff6ba2d3ff7a45b78839a53dc1979a9c6a54920e 165f3d777ea257cfcf142cc4ba9a0ebcd1902eb99842b8a6657c87087f3df6fe lib/codeql/rust/elements/internal/ParamListImpl.qll 0ed6e9affe1dc0144641502292c2ddd51958fe3d503419caf15198176e3a4174 92d053cc5fdf40a2d98acb665083b5da15403d7da205779a97a4ee66fac0add4 @@ -338,7 +340,7 @@ lib/codeql/rust/elements/internal/ReturnExprConstructor.qll 57be5afbe20aa8db6e63 lib/codeql/rust/elements/internal/ReturnTypeSyntaxConstructor.qll 8994672e504d1674e5773157d0ad8a0dc3aad3d64ef295e7722e647e78e36c11 abe7df754721f4ff7f3e3bb22d275976b2e9a1ef51436a461fe52ebd2d29cff1 lib/codeql/rust/elements/internal/ReturnTypeSyntaxImpl.qll d47a3dcfcc2b02a6a9eaeefe9a7a4be2074ecd2019da129dda0f218bc3fbd94b 87198db7c0620ed49369da160f09287015e0cd1718784e1ba28ec3ec5a0bb4a8 lib/codeql/rust/elements/internal/SelfParamConstructor.qll a63af1d1ccde6013c09e0397f1247f5ab3efd97f3410dd1b6c15e1fb6cd96e54 0d8977653c074d5010c78144327f8b6c4da07f09d21e5cc3342082cd50107a81 -lib/codeql/rust/elements/internal/SelfParamImpl.qll 5408738c40f070e0cea83a6a38d638ac7a134b5a055ecf0cccc035af58ff9b36 604922319ecf9a9405fdd0fe953169162ee2c8cca36349b49163a2895c53ed40 +lib/codeql/rust/elements/internal/SelfParamImpl.qll def23beb8926f498fc81b7b44489001b35d704da1a2058c84c23b329e8bc2f49 c9be1e8fa2c4e23b314a4d0563be6cffcbab6f03d08b77a366f7638b28a09de4 lib/codeql/rust/elements/internal/SlicePatConstructor.qll 19216ec9e87ca98784d78b29b8b06ea9ac428e2faa468f0717d1c0d0a8e7351c 458e5be76aa51aec579566be39486525ec9d4c73d248cb228da74892e2a56c08 lib/codeql/rust/elements/internal/SlicePatImpl.qll c6176095360e3b23382557242d2d3ff0b5e0f01f8b1c438452518e9c36ff3c70 644ab41a59a619947f69f75e2d0807245d4ddefc247efaeab63b99b4f08c1cc1 lib/codeql/rust/elements/internal/SliceTypeConstructor.qll 643e7a2ae261e8f62de8bc2886efddcc096e0c7e8159c0b9e87b24d0509e10d0 719545abb0ccf6e8a203ec9c9f75109c5ab0593c838e2f90e388858680ec62f7 @@ -504,12 +506,13 @@ lib/codeql/rust/elements/internal/generated/NameRef.qll 4292fc7aa9ba22a7fa5bd638 lib/codeql/rust/elements/internal/generated/NeverType.qll 14dd3c08db1db873b365fc7f0d1cf3f5d6229b1f78bc85100c36c22d1bb8ee40 34257df0ac59cfd982ea5f30ab225c8bfece71d9fd3be84ff79cf1b0bff55060 lib/codeql/rust/elements/internal/generated/OffsetOfExpr.qll bb17a1e1d4332225cf4bbbae4a1bab9302c2d81d191fe835f2f973915d40dd2a f9e73210b81992040a5a5a9ac3ad936159fb3475445f130c7b28f83dfb4170f5 lib/codeql/rust/elements/internal/generated/OrPat.qll ee0487b90849c3e2a836c956ae8837f27515a9dc795bf17287cba2cf7a39d839 35117b6a3dcebab09f12665441332b6863200e206679ee97894170dd9ef7795c -lib/codeql/rust/elements/internal/generated/Param.qll c57bf238123e8337adb1556cf788bde2b2e8841d4afa0799649db9d507b02d85 7cb580219ec9b6257735f7c53260cd2bb5533dbe342bef3b793ec7b6a65e7027 +lib/codeql/rust/elements/internal/generated/Param.qll 4f853cece9ca8d41ef41ff7656a7f291568f1218403bebcd8afbf07e93fab6bf 93a1372f1d129b83470aa0dc481f46649771d1f5b72b114f215a51514ddd641a +lib/codeql/rust/elements/internal/generated/ParamBase.qll 9d9a82643019d2a13f28555dbdd60221cf6dc2e890f6541e7f85a91646585f2c 0e4a3e4c0e069a43d449167cb706c6f5d0d097b4cab2a7ade84c2c1b5528eca7 lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b63a2ca5296b5506bffdeea054893a56cde08f91560 d4599c52231f93e1260fbae7de8891fe4287fa68b1423592b7a1d51c80146dc8 lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60 lib/codeql/rust/elements/internal/generated/ParenPat.qll ce24b8f8ecbf0f204af200317405724063887257460c80cf250c39b2fdf37185 e7c87d37e1a0ca7ea03840017e1aa9ddb7f927f1f3b6396c0305b46aeee33db6 lib/codeql/rust/elements/internal/generated/ParenType.qll 9cc954d73f8330dcac7b475f97748b63af5c8766dee9d2f2872c0a7e4c903537 c07534c8a9c683c4a9b11d490095647e420de0a0bfc23273eaf6f31b00244273 -lib/codeql/rust/elements/internal/generated/ParentChild.qll 52186ab2aead10bbbaab401272afff0b8247b0050064123d0e45d972ec501dee f082318c0da678845763d6070283872b94b59425fbaa305582b5fe72da03e7e6 +lib/codeql/rust/elements/internal/generated/ParentChild.qll ae0288399423b8b69a98a520ff4d2cb53d15ec404696cf62b0ceea965e2258ba aed73c416d74b504c02ee2e9bc2a72881d851ad0819b331b59728a4084e14fdd lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4 lib/codeql/rust/elements/internal/generated/Path.qll 4c1c8e840ed57880e574142b081b11d7a7428a009f10e3aa8f4645e211f6b2e0 989668cf0f1bdee7557e2f97c01e41d2a56848227fed41477833f5fc1e1d35f6 lib/codeql/rust/elements/internal/generated/PathExpr.qll 2096e3c1db22ee488a761690adabfc9cfdea501c99f7c5d96c0019cb113fc506 54245ce0449c4e263173213df01e079d5168a758503a5dbd61b25ad35a311140 @@ -522,7 +525,7 @@ lib/codeql/rust/elements/internal/generated/PtrType.qll 40099c5a4041314b66932dfd lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll efd93730de217cf50dcba5875595263a5eadf9f7e4e1272401342a094d158614 229b251b3d118932e31e78ac4dfb75f48b766f240f20d436062785606d44467b -lib/codeql/rust/elements/internal/generated/Raw.qll b23d3574920376ca7c52858d6ad2ea6670640812422329f9c44f699075c16d89 13c1a199de3e71f012bdab0fa2b982f1c92f95536b07bbbe816e680a0e64ad71 +lib/codeql/rust/elements/internal/generated/Raw.qll ee5642a7a5ad75f48d4db10eccb197b1a11db2fc3432cf2e24a8bcbe83a474e2 134f2e0c87039d052dd31991017fb35597f37f28879abd702b62ec1d880118c6 lib/codeql/rust/elements/internal/generated/RecordExpr.qll eb6cb662e463f9260efae1a6ce874fa781172063b916ef1963f861e9942d308d 1a21cbccc8f3799ff13281e822818ebfb21d81591720a427cac3625512cb9d40 lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1 lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0 @@ -540,7 +543,7 @@ lib/codeql/rust/elements/internal/generated/RestPat.qll b3a4206e68cf67a0310a4667 lib/codeql/rust/elements/internal/generated/RetType.qll a26860cd526b339b9527c089d126c5486e678dd080e88c60ea2fe641e7d661fd a83c1ce32fd043945ad455b892a60c2a9b6a62d7a5aadf121c4b4056d1dfb094 lib/codeql/rust/elements/internal/generated/ReturnExpr.qll c9c05400d326cd8e0da11c3bfa524daa08b2579ecaee80e468076e5dd7911d56 e7694926727220f46a7617b6ca336767450e359c6fa3782e82b1e21d85d37268 lib/codeql/rust/elements/internal/generated/ReturnTypeSyntax.qll 34e32623d2c0e848c57ce1892c16f4bc81ccca7df22dc21dad5eb48969224465 ccb07c205468bce06392ff4a150136c0d8ebacfb15d1d96dd599ab020b353f47 -lib/codeql/rust/elements/internal/generated/SelfParam.qll cf6837c2731b45632f04092079d295eee3e02d19f73c73b3ccbce1abe12203bf 87eaa9d982506904c42030f7173dd01fd52f3edd9d2c8d19b572f6d5454f769b +lib/codeql/rust/elements/internal/generated/SelfParam.qll e1d994dea58a406dbfca3ea0c724ac48be66ac4380e7270e4037ca2714eef722 90f8ebfac723eef259e13d3c8a7ef6b886c2831d4f436a742144b96db6b6fc92 lib/codeql/rust/elements/internal/generated/SlicePat.qll 8b1463758d7b15a0303384c8136a48a8e71ce27da4ba6e421272b9751a988e64 7562d47308f197bc63ade0f114cd23a17e7f60fa696716f6a30fc7b7411642fe lib/codeql/rust/elements/internal/generated/SliceType.qll 98ee8b566be28f392ab9c9507600e8461ad0b48cbbbd422d22548aca691f8330 528d6eabddf49b9dc474971a2f3a6ddb6f2d77dc7f8449140ef54646c1ceb822 lib/codeql/rust/elements/internal/generated/SourceFile.qll 55d44c9f09c5ff28c4f715f779a0db74083e1180acaf0d410e63ca07b90d1cb5 78c0af48b0b64aa377413ea4799dfe977602a111208e1d25e4bdfa920dbd7238 @@ -548,7 +551,7 @@ lib/codeql/rust/elements/internal/generated/Static.qll 5fbd6879858cf356d4bdaa6da lib/codeql/rust/elements/internal/generated/Stmt.qll 8473ff532dd5cc9d7decaddcd174b94d610f6ca0aec8e473cc051dad9f3db917 6ef7d2b5237c2dbdcacbf7d8b39109d4dc100229f2b28b5c9e3e4fbf673ba72b lib/codeql/rust/elements/internal/generated/StmtList.qll a667193e32341e17400867c6e359878c4e645ef9f5f4d97676afc0283a33a026 a320ed678ee359302e2fc1b70a9476705cd616fcfa44a499d32f0c7715627f73 lib/codeql/rust/elements/internal/generated/Struct.qll 4d57f0db12dc7ad3e31e750a24172ef1505406b4dab16386af0674bd18bf8f4b 1a73c83df926b996f629316f74c61ea775be04532ab61b56af904223354f033e -lib/codeql/rust/elements/internal/generated/Synth.qll 0e5767568fd119df13928adf00950586f5f9f355dae520059b2d6daa7a2bda56 219b40f6458fec2cc436dc2cf80bb1dbfb34dfdbe8576606b5e25f78d36d6210 +lib/codeql/rust/elements/internal/generated/Synth.qll db8ffbd55def03f0b0278cafa60274220eb571257da36e185f380e3c5b2caedf 19074971c3e96a43414738976c9625385c4bbac6b01c7eca2f46432034a279b7 lib/codeql/rust/elements/internal/generated/SynthConstructors.qll e929c49ea60810a2bbc19ad38110b8bbaf21db54dae90393b21a3459a54abf6f e929c49ea60810a2bbc19ad38110b8bbaf21db54dae90393b21a3459a54abf6f lib/codeql/rust/elements/internal/generated/Token.qll 77a91a25ca5669703cf3a4353b591cef4d72caa6b0b9db07bb9e005d69c848d1 2fdffc4882ed3a6ca9ac6d1fb5f1ac5a471ca703e2ffdc642885fa558d6e373b lib/codeql/rust/elements/internal/generated/TokenTree.qll 8577c2b097c1be2f0f7daa5acfcf146f78674a424d99563e08a84dd3e6d91b46 d2f30764e84dbfc0a6a5d3d8a5f935cd432413688cb32da9c94e420fbc10665c @@ -583,7 +586,7 @@ lib/codeql/rust/elements/internal/generated/WhileExpr.qll 7edf1f23fbf953a2baabcd lib/codeql/rust/elements/internal/generated/WildcardPat.qll d74b70b57a0a66bfae017a329352a5b27a6b9e73dd5521d627f680e810c6c59e 4b913b548ba27ff3c82fcd32cf996ff329cb57d176d3bebd0fcef394486ea499 lib/codeql/rust/elements/internal/generated/YeetExpr.qll cac328200872a35337b4bcb15c851afb4743f82c080f9738d295571eb01d7392 94af734eea08129b587fed849b643e7572800e8330c0b57d727d41abda47930b lib/codeql/rust/elements/internal/generated/YieldExpr.qll 37e5f0c1e373a22bbc53d8b7f2c0e1f476e5be5080b8437c5e964f4e83fad79a 4a9a68643401637bf48e5c2b2f74a6bf0ddcb4ff76f6bffb61d436b685621e85 -lib/codeql/rust/elements.qll 76fe494d20d2665777bcb5c5ced016a262789a0e6aa874c1a77ce4cb134422b6 76fe494d20d2665777bcb5c5ced016a262789a0e6aa874c1a77ce4cb134422b6 +lib/codeql/rust/elements.qll 83bda9f3bc481aaecc039db9cecb628495e15e469cc843336ca089f0d707f8d6 83bda9f3bc481aaecc039db9cecb628495e15e469cc843336ca089f0d707f8d6 test/extractor-tests/generated/Abi/Abi.ql 7f6e7dc4af86eca3ebdc79b10373988cd0871bd78b51997d3cffd969105e5fdd 2f936b6ca005c6157c755121584410c03e4a3949c23bee302fbe05ee10ce118f test/extractor-tests/generated/Abi/Abi_getAbiString.ql a496762fcec5a0887b87023bbf93e9b650f02e20113e25c44d6e4281ae8f5335 14109c7ce11ba25e3cd6e7f1b3fcb4cb00622f2a4eac91bfe43145c5f366bc52 test/extractor-tests/generated/ArgList/ArgList.ql e412927756e72165d0e7c5c9bd3fca89d08197bbf760db8fb7683c64bb2229bc 043dba8506946fbb87753e22c387987d7eded6ddb963aa067f9e60ef9024d684 @@ -878,7 +881,7 @@ test/extractor-tests/generated/OffsetOfExpr/OffsetOfExpr_getField.ql 6d729fb91de test/extractor-tests/generated/OffsetOfExpr/OffsetOfExpr_getTy.ql b8597637cffd7a492148020b306c4ab1d2f17f919f441f462ebc00d229b038ca 2c7de1df4351929c221b30e3cede4cd6981fe8a2c1861e194489981c65e00f33 test/extractor-tests/generated/OrPat/OrPat.ql 49d881b384acaf68fa79de46da997cacab3e75467641f61150908f4112c47fa4 5d721da23be44e79d7b8a0dd475119836828d6a1edaff2c55decea8da83e65b8 test/extractor-tests/generated/OrPat/OrPat_getPat.ql d56b78287cecebacb25249380647500387e0d9e28be20034b8a12406a999a7c4 cba7bb60afaaed4333ea5ff6d3850fb44a8b42edee67d86fd16df85938454269 -test/extractor-tests/generated/Param/Param.ql 060c53b7e93840ae9cbf0c8fdaea17b16d6825f4b7aaa2eab164a660c5a7ea4d 172f6f4b86a98720f710e5d4342b7d52839c6f3c169ce1debb37629961a702ba +test/extractor-tests/generated/Param/Param.ql ab8d0f8cc3c71f5d24be4aebde1ef7d016519490a9715aca6069e58fd11aeb1c 61197a0c2b8d6f0c5a9cddda39585dcd413644cf80e3ea28b037385142100b27 test/extractor-tests/generated/Param/Param_getAttr.ql e1dcf86540fd2971ced34a33b2959f001c3f654914d82e576caa4534b80fbfbf 987a826bf6dcd25c3426edb603a22f6caa030c82c1cb0e9e11062fdbfed23030 test/extractor-tests/generated/Param/Param_getPat.ql 0c448e8ba8bf3432be08b5eb4a052aa19cccf0eb4596a3239481401dae9d2dc2 c943d4da36e1e734c1a012f092b2f597cb389a7ab33d5371ff8ee9c93e115ffc test/extractor-tests/generated/Param/Param_getTy.ql 134dec0c5562a8df68224069f10ee51c7dcc35e0b44a49c0e2078c305487db87 94fa72a213c37f2f63f03789a33e55fc5a22bd83cf0c1d293281bceffb63bd78 @@ -973,7 +976,7 @@ test/extractor-tests/generated/ReturnExpr/ReturnExpr.ql 8e9eba0837a466255e8e249e test/extractor-tests/generated/ReturnExpr/ReturnExpr_getAttr.ql 9fb7e1c79798e4f42e18785f3af17ea75f901a36abf9beb47a1eede69c613ba9 9cdb7cc4a4742865f6c92357973f84cee9229f55ff28081e5d17b6d57d6d275f test/extractor-tests/generated/ReturnExpr/ReturnExpr_getExpr.ql 7d4562efb0d26d92d11f03a0ef80338eb7d5a0c073f1f09cbb8a826f0cef33de 523ebd51b97f957afaf497e5a4d27929eed18e1d276054e3d5a7c5cfe7285c6e test/extractor-tests/generated/ReturnTypeSyntax/ReturnTypeSyntax.ql 976ce33fe3fd34aae2028a11b4accdee122b6d82d07722488c3239f0d2c14609 906bf8c8e7769a1052196bc78947b655158dd3b2903fef2802e2031cffbc1d78 -test/extractor-tests/generated/SelfParam/SelfParam.ql d051c7a2dd88382e37895f1d691f2702aed7f925d3936f51d49949463e4757c8 37f1f429093be7923a55f8b4f46b37bbf71d0dff3843c4d3686383c2863dee1a +test/extractor-tests/generated/SelfParam/SelfParam.ql 12ad3244a2700e13a84603d6992f0c872572bca68d25515a7a9414b3c96a62e0 70028e344bc4ab2937f391f1fd8afd1549935aa621ce2cb9944da6a1dcf4be27 test/extractor-tests/generated/SelfParam/SelfParam_getAttr.ql 00dd5409c07e9a7b5dc51c1444e24b35d2ac3cab11320396ef70f531a3b65dc0 effbed79ad530a835e85b931389a0c8609a10ee035cb694f2e39b8539f8e54ba test/extractor-tests/generated/SelfParam/SelfParam_getLifetime.ql 0b7c243f609e005dd63fd1b3b9f0096fc13cb98fe113e6f3fefb0d5c414e9a5f f6e06de8bcddfc9bd978c058079e53174edbe7b39f18df3c0bd4e80486808eda test/extractor-tests/generated/SelfParam/SelfParam_getName.ql 69207a57b415ba590e50003d506a64fd1780b27b8832b14f9bd3c909bddb5593 56fa28ba1222f45893237052fa5a9421d960e14fbf1396b2d1049b440c2e5abe diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 6daad6a68c7..afb5cbf6c69 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -96,6 +96,7 @@ /lib/codeql/rust/elements/OffsetOfExpr.qll linguist-generated /lib/codeql/rust/elements/OrPat.qll linguist-generated /lib/codeql/rust/elements/Param.qll linguist-generated +/lib/codeql/rust/elements/ParamBase.qll linguist-generated /lib/codeql/rust/elements/ParamList.qll linguist-generated /lib/codeql/rust/elements/ParenExpr.qll linguist-generated /lib/codeql/rust/elements/ParenPat.qll linguist-generated @@ -294,6 +295,7 @@ /lib/codeql/rust/elements/internal/OffsetOfExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/OffsetOfExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/OrPatConstructor.qll linguist-generated +/lib/codeql/rust/elements/internal/ParamBaseImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ParamConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ParamListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ParamListImpl.qll linguist-generated @@ -507,6 +509,7 @@ /lib/codeql/rust/elements/internal/generated/OffsetOfExpr.qll linguist-generated /lib/codeql/rust/elements/internal/generated/OrPat.qll linguist-generated /lib/codeql/rust/elements/internal/generated/Param.qll linguist-generated +/lib/codeql/rust/elements/internal/generated/ParamBase.qll linguist-generated /lib/codeql/rust/elements/internal/generated/ParamList.qll linguist-generated /lib/codeql/rust/elements/internal/generated/ParenExpr.qll linguist-generated /lib/codeql/rust/elements/internal/generated/ParenPat.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll index b550ecf89b7..8038c0dcee1 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll @@ -1940,12 +1940,14 @@ module MakeCfgNodes Input> { } /** - * A Param. For example: + * A parameter in a function or method. For example `x` in: * ```rust - * todo!() + * fn new(x: T) -> Foo { + * // ... + * } * ``` */ - final class ParamCfgNode extends CfgNodeFinal { + final class ParamCfgNode extends CfgNodeFinal, ParamBaseCfgNode { private Param node; ParamCfgNode() { node = this.getAstNode() } @@ -1953,21 +1955,6 @@ module MakeCfgNodes Input> { /** Gets the underlying `Param`. */ Param getParam() { result = node } - /** - * Gets the `index`th attr of this parameter (0-based). - */ - Attr getAttr(int index) { result = node.getAttr(index) } - - /** - * Gets any of the attrs of this parameter. - */ - Attr getAnAttr() { result = this.getAttr(_) } - - /** - * Gets the number of attrs of this parameter. - */ - int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } - /** * Gets the pat of this parameter, if it exists. */ @@ -1979,9 +1966,40 @@ module MakeCfgNodes Input> { * Holds if `getPat()` exists. */ predicate hasPat() { exists(this.getPat()) } + } + + final private class ParentParamBase extends ParentAstNode, ParamBase { + override predicate relevantChild(AstNode child) { none() } + } + + /** + * A normal parameter, `Param`, or a self parameter `SelfParam`. + */ + final class ParamBaseCfgNode extends CfgNodeFinal { + private ParamBase node; + + ParamBaseCfgNode() { node = this.getAstNode() } + + /** Gets the underlying `ParamBase`. */ + ParamBase getParamBase() { result = node } /** - * Gets the ty of this parameter, if it exists. + * Gets the `index`th attr of this parameter base (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this parameter base. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this parameter base. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the ty of this parameter base, if it exists. */ TypeRef getTy() { result = node.getTy() } @@ -2597,12 +2615,14 @@ module MakeCfgNodes Input> { } /** - * A SelfParam. For example: + * A `self` parameter. For example `self` in: * ```rust - * todo!() + * fn push(&mut self, value: T) { + * // ... + * } * ``` */ - final class SelfParamCfgNode extends CfgNodeFinal { + final class SelfParamCfgNode extends CfgNodeFinal, ParamBaseCfgNode { private SelfParam node; SelfParamCfgNode() { node = this.getAstNode() } @@ -2610,21 +2630,6 @@ module MakeCfgNodes Input> { /** Gets the underlying `SelfParam`. */ SelfParam getSelfParam() { result = node } - /** - * Gets the `index`th attr of this self parameter (0-based). - */ - Attr getAttr(int index) { result = node.getAttr(index) } - - /** - * Gets any of the attrs of this self parameter. - */ - Attr getAnAttr() { result = this.getAttr(_) } - - /** - * Gets the number of attrs of this self parameter. - */ - int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } - /** * Holds if this self parameter is mut. */ @@ -2649,16 +2654,6 @@ module MakeCfgNodes Input> { * Holds if `getName()` exists. */ predicate hasName() { exists(this.getName()) } - - /** - * Gets the ty of this self parameter, if it exists. - */ - TypeRef getTy() { result = node.getTy() } - - /** - * Holds if `getTy()` exists. - */ - predicate hasTy() { exists(this.getTy()) } } final private class ParentSlicePat extends ParentAstNode, SlicePat { diff --git a/rust/ql/lib/codeql/rust/elements.qll b/rust/ql/lib/codeql/rust/elements.qll index 6bb59b42882..7d752c1b9be 100644 --- a/rust/ql/lib/codeql/rust/elements.qll +++ b/rust/ql/lib/codeql/rust/elements.qll @@ -98,6 +98,7 @@ import codeql.rust.elements.NeverType import codeql.rust.elements.OffsetOfExpr import codeql.rust.elements.OrPat import codeql.rust.elements.Param +import codeql.rust.elements.ParamBase import codeql.rust.elements.ParamList import codeql.rust.elements.ParenExpr import codeql.rust.elements.ParenPat diff --git a/rust/ql/lib/codeql/rust/elements/Param.qll b/rust/ql/lib/codeql/rust/elements/Param.qll index eb46d206ba4..74eda683740 100644 --- a/rust/ql/lib/codeql/rust/elements/Param.qll +++ b/rust/ql/lib/codeql/rust/elements/Param.qll @@ -4,15 +4,15 @@ */ private import internal.ParamImpl -import codeql.rust.elements.AstNode -import codeql.rust.elements.Attr +import codeql.rust.elements.ParamBase import codeql.rust.elements.Pat -import codeql.rust.elements.TypeRef /** - * A Param. For example: + * A parameter in a function or method. For example `x` in: * ```rust - * todo!() + * fn new(x: T) -> Foo { + * // ... + * } * ``` */ final class Param = Impl::Param; diff --git a/rust/ql/lib/codeql/rust/elements/ParamBase.qll b/rust/ql/lib/codeql/rust/elements/ParamBase.qll new file mode 100644 index 00000000000..d3a031f4da5 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/ParamBase.qll @@ -0,0 +1,14 @@ +// generated by codegen, do not edit +/** + * This module provides the public class `ParamBase`. + */ + +private import internal.ParamBaseImpl +import codeql.rust.elements.AstNode +import codeql.rust.elements.Attr +import codeql.rust.elements.TypeRef + +/** + * A normal parameter, `Param`, or a self parameter `SelfParam`. + */ +final class ParamBase = Impl::ParamBase; diff --git a/rust/ql/lib/codeql/rust/elements/SelfParam.qll b/rust/ql/lib/codeql/rust/elements/SelfParam.qll index 74d2fb5e2eb..88c1a05d837 100644 --- a/rust/ql/lib/codeql/rust/elements/SelfParam.qll +++ b/rust/ql/lib/codeql/rust/elements/SelfParam.qll @@ -4,16 +4,16 @@ */ private import internal.SelfParamImpl -import codeql.rust.elements.AstNode -import codeql.rust.elements.Attr import codeql.rust.elements.Lifetime import codeql.rust.elements.Name -import codeql.rust.elements.TypeRef +import codeql.rust.elements.ParamBase /** - * A SelfParam. For example: + * A `self` parameter. For example `self` in: * ```rust - * todo!() + * fn push(&mut self, value: T) { + * // ... + * } * ``` */ final class SelfParam = Impl::SelfParam; diff --git a/rust/ql/lib/codeql/rust/elements/internal/ParamBaseImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ParamBaseImpl.qll new file mode 100644 index 00000000000..3b0f82eb6c3 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/ParamBaseImpl.qll @@ -0,0 +1,19 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module provides a hand-modifiable wrapper around the generated class `ParamBase`. + * + * INTERNAL: Do not use. + */ + +private import codeql.rust.elements.internal.generated.ParamBase + +/** + * INTERNAL: This module contains the customizable definition of `ParamBase` and should not + * be referenced directly. + */ +module Impl { + /** + * A normal parameter, `Param`, or a self parameter `SelfParam`. + */ + class ParamBase extends Generated::ParamBase { } +} diff --git a/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll index 33e4f5fee59..02d38d32c38 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ParamImpl.qll @@ -13,9 +13,11 @@ private import codeql.rust.elements.internal.generated.Param module Impl { // the following QLdoc is generated: if you need to edit it, do it in the schema file /** - * A Param. For example: + * A parameter in a function or method. For example `x` in: * ```rust - * todo!() + * fn new(x: T) -> Foo { + * // ... + * } * ``` */ class Param extends Generated::Param { diff --git a/rust/ql/lib/codeql/rust/elements/internal/SelfParamImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/SelfParamImpl.qll index 2be3b75ac47..0d0d23a1e8c 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/SelfParamImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/SelfParamImpl.qll @@ -13,9 +13,11 @@ private import codeql.rust.elements.internal.generated.SelfParam */ module Impl { /** - * A SelfParam. For example: + * A `self` parameter. For example `self` in: * ```rust - * todo!() + * fn push(&mut self, value: T) { + * // ... + * } * ``` */ class SelfParam extends Generated::SelfParam { } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Param.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Param.qll index 1ac10da37d3..2bbbc81b2c9 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Param.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Param.qll @@ -6,10 +6,8 @@ private import codeql.rust.elements.internal.generated.Synth private import codeql.rust.elements.internal.generated.Raw -import codeql.rust.elements.internal.AstNodeImpl::Impl as AstNodeImpl -import codeql.rust.elements.Attr +import codeql.rust.elements.internal.ParamBaseImpl::Impl as ParamBaseImpl import codeql.rust.elements.Pat -import codeql.rust.elements.TypeRef /** * INTERNAL: This module contains the fully generated definition of `Param` and should not @@ -17,33 +15,18 @@ import codeql.rust.elements.TypeRef */ module Generated { /** - * A Param. For example: + * A parameter in a function or method. For example `x` in: * ```rust - * todo!() + * fn new(x: T) -> Foo { + * // ... + * } * ``` * INTERNAL: Do not reference the `Generated::Param` class directly. * Use the subclass `Param`, where the following predicates are available. */ - class Param extends Synth::TParam, AstNodeImpl::AstNode { + class Param extends Synth::TParam, ParamBaseImpl::ParamBase { override string getAPrimaryQlClass() { result = "Param" } - /** - * Gets the `index`th attr of this parameter (0-based). - */ - Attr getAttr(int index) { - result = Synth::convertAttrFromRaw(Synth::convertParamToRaw(this).(Raw::Param).getAttr(index)) - } - - /** - * Gets any of the attrs of this parameter. - */ - final Attr getAnAttr() { result = this.getAttr(_) } - - /** - * Gets the number of attrs of this parameter. - */ - final int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } - /** * Gets the pat of this parameter, if it exists. */ @@ -55,17 +38,5 @@ module Generated { * Holds if `getPat()` exists. */ final predicate hasPat() { exists(this.getPat()) } - - /** - * Gets the ty of this parameter, if it exists. - */ - TypeRef getTy() { - result = Synth::convertTypeRefFromRaw(Synth::convertParamToRaw(this).(Raw::Param).getTy()) - } - - /** - * Holds if `getTy()` exists. - */ - final predicate hasTy() { exists(this.getTy()) } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ParamBase.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ParamBase.qll new file mode 100644 index 00000000000..ea5ef12a64f --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ParamBase.qll @@ -0,0 +1,55 @@ +// generated by codegen, do not edit +/** + * This module provides the generated definition of `ParamBase`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.elements.internal.generated.Synth +private import codeql.rust.elements.internal.generated.Raw +import codeql.rust.elements.internal.AstNodeImpl::Impl as AstNodeImpl +import codeql.rust.elements.Attr +import codeql.rust.elements.TypeRef + +/** + * INTERNAL: This module contains the fully generated definition of `ParamBase` and should not + * be referenced directly. + */ +module Generated { + /** + * A normal parameter, `Param`, or a self parameter `SelfParam`. + * INTERNAL: Do not reference the `Generated::ParamBase` class directly. + * Use the subclass `ParamBase`, where the following predicates are available. + */ + class ParamBase extends Synth::TParamBase, AstNodeImpl::AstNode { + /** + * Gets the `index`th attr of this parameter base (0-based). + */ + Attr getAttr(int index) { + result = + Synth::convertAttrFromRaw(Synth::convertParamBaseToRaw(this).(Raw::ParamBase).getAttr(index)) + } + + /** + * Gets any of the attrs of this parameter base. + */ + final Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this parameter base. + */ + final int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + + /** + * Gets the ty of this parameter base, if it exists. + */ + TypeRef getTy() { + result = + Synth::convertTypeRefFromRaw(Synth::convertParamBaseToRaw(this).(Raw::ParamBase).getTy()) + } + + /** + * Holds if `getTy()` exists. + */ + final predicate hasTy() { exists(this.getTy()) } + } +} diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll index b03310ce263..9f3bbfac30c 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll @@ -602,14 +602,13 @@ private module Impl { ) } - private Element getImmediateChildOfParam(Param e, int index, string partialPredicateCall) { - exists(int b, int bAstNode, int n, int nAttr, int nPat, int nTy | + private Element getImmediateChildOfParamBase(ParamBase e, int index, string partialPredicateCall) { + exists(int b, int bAstNode, int n, int nAttr, int nTy | b = 0 and bAstNode = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAstNode(e, i, _)) | i) and n = bAstNode and nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and - nPat = nAttr + 1 and - nTy = nPat + 1 and + nTy = nAttr + 1 and ( none() or @@ -618,9 +617,7 @@ private module Impl { result = e.getAttr(index - n) and partialPredicateCall = "Attr(" + (index - n).toString() + ")" or - index = nAttr and result = e.getPat() and partialPredicateCall = "Pat()" - or - index = nPat and result = e.getTy() and partialPredicateCall = "Ty()" + index = nAttr and result = e.getTy() and partialPredicateCall = "Ty()" ) ) } @@ -885,32 +882,6 @@ private module Impl { ) } - private Element getImmediateChildOfSelfParam(SelfParam e, int index, string partialPredicateCall) { - exists(int b, int bAstNode, int n, int nAttr, int nLifetime, int nName, int nTy | - b = 0 and - bAstNode = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAstNode(e, i, _)) | i) and - n = bAstNode and - nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and - nLifetime = nAttr + 1 and - nName = nLifetime + 1 and - nTy = nName + 1 and - ( - none() - or - result = getImmediateChildOfAstNode(e, index - b, partialPredicateCall) - or - result = e.getAttr(index - n) and - partialPredicateCall = "Attr(" + (index - n).toString() + ")" - or - index = nAttr and result = e.getLifetime() and partialPredicateCall = "Lifetime()" - or - index = nLifetime and result = e.getName() and partialPredicateCall = "Name()" - or - index = nName and result = e.getTy() and partialPredicateCall = "Ty()" - ) - ) - } - private Element getImmediateChildOfSourceFile(SourceFile e, int index, string partialPredicateCall) { exists(int b, int bAstNode, int n, int nAttr, int nItem | b = 0 and @@ -2137,6 +2108,22 @@ private module Impl { ) } + private Element getImmediateChildOfParam(Param e, int index, string partialPredicateCall) { + exists(int b, int bParamBase, int n, int nPat | + b = 0 and + bParamBase = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfParamBase(e, i, _)) | i) and + n = bParamBase and + nPat = n + 1 and + ( + none() + or + result = getImmediateChildOfParamBase(e, index - b, partialPredicateCall) + or + index = n and result = e.getPat() and partialPredicateCall = "Pat()" + ) + ) + } + private Element getImmediateChildOfParenExpr(ParenExpr e, int index, string partialPredicateCall) { exists(int b, int bExpr, int n, int nAttr, int nExpr | b = 0 and @@ -2487,6 +2474,25 @@ private module Impl { ) } + private Element getImmediateChildOfSelfParam(SelfParam e, int index, string partialPredicateCall) { + exists(int b, int bParamBase, int n, int nLifetime, int nName | + b = 0 and + bParamBase = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfParamBase(e, i, _)) | i) and + n = bParamBase and + nLifetime = n + 1 and + nName = nLifetime + 1 and + ( + none() + or + result = getImmediateChildOfParamBase(e, index - b, partialPredicateCall) + or + index = n and result = e.getLifetime() and partialPredicateCall = "Lifetime()" + or + index = nLifetime and result = e.getName() and partialPredicateCall = "Name()" + ) + ) + } + private Element getImmediateChildOfSlicePat(SlicePat e, int index, string partialPredicateCall) { exists(int b, int bPat, int n, int nPat | b = 0 and @@ -3621,8 +3627,6 @@ private module Impl { or result = getImmediateChildOfNameRef(e, index, partialAccessor) or - result = getImmediateChildOfParam(e, index, partialAccessor) - or result = getImmediateChildOfParamList(e, index, partialAccessor) or result = getImmediateChildOfPathSegment(e, index, partialAccessor) @@ -3643,8 +3647,6 @@ private module Impl { or result = getImmediateChildOfReturnTypeSyntax(e, index, partialAccessor) or - result = getImmediateChildOfSelfParam(e, index, partialAccessor) - or result = getImmediateChildOfSourceFile(e, index, partialAccessor) or result = getImmediateChildOfStmtList(e, index, partialAccessor) @@ -3751,6 +3753,8 @@ private module Impl { or result = getImmediateChildOfOrPat(e, index, partialAccessor) or + result = getImmediateChildOfParam(e, index, partialAccessor) + or result = getImmediateChildOfParenExpr(e, index, partialAccessor) or result = getImmediateChildOfParenPat(e, index, partialAccessor) @@ -3787,6 +3791,8 @@ private module Impl { or result = getImmediateChildOfReturnExpr(e, index, partialAccessor) or + result = getImmediateChildOfSelfParam(e, index, partialAccessor) + or result = getImmediateChildOfSlicePat(e, index, partialAccessor) or result = getImmediateChildOfSliceType(e, index, partialAccessor) diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index 64de46c55bb..01d28fedd7c 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -525,28 +525,18 @@ module Raw { /** * INTERNAL: Do not use. - * A Param. For example: - * ```rust - * todo!() - * ``` + * A normal parameter, `Param`, or a self parameter `SelfParam`. */ - class Param extends @param, AstNode { - override string toString() { result = "Param" } + class ParamBase extends @param_base, AstNode { + /** + * Gets the `index`th attr of this parameter base (0-based). + */ + Attr getAttr(int index) { param_base_attrs(this, index, result) } /** - * Gets the `index`th attr of this parameter (0-based). + * Gets the ty of this parameter base, if it exists. */ - Attr getAttr(int index) { param_attrs(this, index, result) } - - /** - * Gets the pat of this parameter, if it exists. - */ - Pat getPat() { param_pats(this, result) } - - /** - * Gets the ty of this parameter, if it exists. - */ - TypeRef getTy() { param_ties(this, result) } + TypeRef getTy() { param_base_ties(this, result) } } /** @@ -808,42 +798,6 @@ module Raw { override string toString() { result = "ReturnTypeSyntax" } } - /** - * INTERNAL: Do not use. - * A SelfParam. For example: - * ```rust - * todo!() - * ``` - */ - class SelfParam extends @self_param, AstNode { - override string toString() { result = "SelfParam" } - - /** - * Gets the `index`th attr of this self parameter (0-based). - */ - Attr getAttr(int index) { self_param_attrs(this, index, result) } - - /** - * Holds if this self parameter is mut. - */ - predicate isMut() { self_param_is_mut(this) } - - /** - * Gets the lifetime of this self parameter, if it exists. - */ - Lifetime getLifetime() { self_param_lifetimes(this, result) } - - /** - * Gets the name of this self parameter, if it exists. - */ - Name getName() { self_param_names(this, result) } - - /** - * Gets the ty of this self parameter, if it exists. - */ - TypeRef getTy() { self_param_ties(this, result) } - } - /** * INTERNAL: Do not use. * A SourceFile. For example: @@ -2281,6 +2235,24 @@ module Raw { Pat getPat(int index) { or_pat_pats(this, index, result) } } + /** + * INTERNAL: Do not use. + * A parameter in a function or method. For example `x` in: + * ```rust + * fn new(x: T) -> Foo { + * // ... + * } + * ``` + */ + class Param extends @param, ParamBase { + override string toString() { result = "Param" } + + /** + * Gets the pat of this parameter, if it exists. + */ + Pat getPat() { param_pats(this, result) } + } + /** * INTERNAL: Do not use. * A ParenExpr. For example: @@ -2717,6 +2689,34 @@ module Raw { Expr getExpr() { return_expr_exprs(this, result) } } + /** + * INTERNAL: Do not use. + * A `self` parameter. For example `self` in: + * ```rust + * fn push(&mut self, value: T) { + * // ... + * } + * ``` + */ + class SelfParam extends @self_param, ParamBase { + override string toString() { result = "SelfParam" } + + /** + * Holds if this self parameter is mut. + */ + predicate isMut() { self_param_is_mut(this) } + + /** + * Gets the lifetime of this self parameter, if it exists. + */ + Lifetime getLifetime() { self_param_lifetimes(this, result) } + + /** + * Gets the name of this self parameter, if it exists. + */ + Name getName() { self_param_names(this, result) } + } + /** * INTERNAL: Do not use. * A slice pattern. For example: diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/SelfParam.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/SelfParam.qll index 243d04e9bb7..b2cc6e4b0c4 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/SelfParam.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/SelfParam.qll @@ -6,11 +6,9 @@ private import codeql.rust.elements.internal.generated.Synth private import codeql.rust.elements.internal.generated.Raw -import codeql.rust.elements.internal.AstNodeImpl::Impl as AstNodeImpl -import codeql.rust.elements.Attr import codeql.rust.elements.Lifetime import codeql.rust.elements.Name -import codeql.rust.elements.TypeRef +import codeql.rust.elements.internal.ParamBaseImpl::Impl as ParamBaseImpl /** * INTERNAL: This module contains the fully generated definition of `SelfParam` and should not @@ -18,34 +16,18 @@ import codeql.rust.elements.TypeRef */ module Generated { /** - * A SelfParam. For example: + * A `self` parameter. For example `self` in: * ```rust - * todo!() + * fn push(&mut self, value: T) { + * // ... + * } * ``` * INTERNAL: Do not reference the `Generated::SelfParam` class directly. * Use the subclass `SelfParam`, where the following predicates are available. */ - class SelfParam extends Synth::TSelfParam, AstNodeImpl::AstNode { + class SelfParam extends Synth::TSelfParam, ParamBaseImpl::ParamBase { override string getAPrimaryQlClass() { result = "SelfParam" } - /** - * Gets the `index`th attr of this self parameter (0-based). - */ - Attr getAttr(int index) { - result = - Synth::convertAttrFromRaw(Synth::convertSelfParamToRaw(this).(Raw::SelfParam).getAttr(index)) - } - - /** - * Gets any of the attrs of this self parameter. - */ - final Attr getAnAttr() { result = this.getAttr(_) } - - /** - * Gets the number of attrs of this self parameter. - */ - final int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } - /** * Holds if this self parameter is mut. */ @@ -78,18 +60,5 @@ module Generated { * Holds if `getName()` exists. */ final predicate hasName() { exists(this.getName()) } - - /** - * Gets the ty of this self parameter, if it exists. - */ - TypeRef getTy() { - result = - Synth::convertTypeRefFromRaw(Synth::convertSelfParamToRaw(this).(Raw::SelfParam).getTy()) - } - - /** - * Holds if `getTy()` exists. - */ - final predicate hasTy() { exists(this.getTy()) } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll index dda242ffdf9..b6b1a92a01f 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll @@ -624,12 +624,12 @@ module Synth { TExpr or TExternItem or TExternItemList or TFieldList or TFormatArgsArg or TGenericArg or TGenericArgList or TGenericParam or TGenericParamList or TItemList or TLabel or TLetElse or TLifetime or TMacroItems or TMacroStmts or TMatchArm or TMatchArmList or TMatchGuard or - TMeta or TName or TNameRef or TParam or TParamList or TPat or TPathSegment or + TMeta or TName or TNameRef or TParamBase or TParamList or TPat or TPathSegment or TRecordExprField or TRecordExprFieldList or TRecordField or TRecordPatField or TRecordPatFieldList or TRename or TResolvable or TRetType or TReturnTypeSyntax or - TSelfParam or TSourceFile or TStmt or TStmtList or TToken or TTokenTree or TTupleField or - TTypeBound or TTypeBoundList or TTypeRef or TUseTree or TUseTreeList or TVariant or - TVariantList or TVisibility or TWhereClause or TWherePred; + TSourceFile or TStmt or TStmtList or TToken or TTokenTree or TTupleField or TTypeBound or + TTypeBoundList or TTypeRef or TUseTree or TUseTreeList or TVariant or TVariantList or + TVisibility or TWhereClause or TWherePred; /** * INTERNAL: Do not use. @@ -695,6 +695,11 @@ module Synth { */ class TLoopingExpr = TForExpr or TLoopExpr or TWhileExpr; + /** + * INTERNAL: Do not use. + */ + class TParamBase = TParam or TSelfParam; + /** * INTERNAL: Do not use. */ @@ -1699,7 +1704,7 @@ module Synth { or result = convertNameRefFromRaw(e) or - result = convertParamFromRaw(e) + result = convertParamBaseFromRaw(e) or result = convertParamListFromRaw(e) or @@ -1725,8 +1730,6 @@ module Synth { or result = convertReturnTypeSyntaxFromRaw(e) or - result = convertSelfParamFromRaw(e) - or result = convertSourceFileFromRaw(e) or result = convertStmtFromRaw(e) @@ -1984,6 +1987,16 @@ module Synth { result = convertWhileExprFromRaw(e) } + /** + * INTERNAL: Do not use. + * Converts a raw DB element to a synthesized `TParamBase`, if possible. + */ + TParamBase convertParamBaseFromRaw(Raw::Element e) { + result = convertParamFromRaw(e) + or + result = convertSelfParamFromRaw(e) + } + /** * INTERNAL: Do not use. * Converts a raw DB element to a synthesized `TPat`, if possible. @@ -3065,7 +3078,7 @@ module Synth { or result = convertNameRefToRaw(e) or - result = convertParamToRaw(e) + result = convertParamBaseToRaw(e) or result = convertParamListToRaw(e) or @@ -3091,8 +3104,6 @@ module Synth { or result = convertReturnTypeSyntaxToRaw(e) or - result = convertSelfParamToRaw(e) - or result = convertSourceFileToRaw(e) or result = convertStmtToRaw(e) @@ -3350,6 +3361,16 @@ module Synth { result = convertWhileExprToRaw(e) } + /** + * INTERNAL: Do not use. + * Converts a synthesized `TParamBase` to a raw DB element, if possible. + */ + Raw::Element convertParamBaseToRaw(TParamBase e) { + result = convertParamToRaw(e) + or + result = convertSelfParamToRaw(e) + } + /** * INTERNAL: Do not use. * Converts a synthesized `TPat` to a raw DB element, if possible. diff --git a/rust/ql/lib/rust.dbscheme b/rust/ql/lib/rust.dbscheme index c9933b5b5e3..7c2ba7da58c 100644 --- a/rust/ql/lib/rust.dbscheme +++ b/rust/ql/lib/rust.dbscheme @@ -162,7 +162,7 @@ locatable_locations( | @meta | @name | @name_ref -| @param +| @param_base | @param_list | @pat | @path_segment @@ -175,7 +175,6 @@ locatable_locations( | @resolvable | @ret_type | @return_type_syntax -| @self_param | @source_file | @stmt | @stmt_list @@ -582,26 +581,21 @@ name_ref_texts( string text: string ref ); -params( - unique int id: @param -); +@param_base = + @param +| @self_param +; #keyset[id, index] -param_attrs( - int id: @param ref, +param_base_attrs( + int id: @param_base ref, int index: int ref, int attr: @attr ref ); #keyset[id] -param_pats( - int id: @param ref, - int pat: @pat ref -); - -#keyset[id] -param_ties( - int id: @param ref, +param_base_ties( + int id: @param_base ref, int ty: @type_ref ref ); @@ -844,40 +838,6 @@ return_type_syntaxes( unique int id: @return_type_syntax ); -self_params( - unique int id: @self_param -); - -#keyset[id, index] -self_param_attrs( - int id: @self_param ref, - int index: int ref, - int attr: @attr ref -); - -#keyset[id] -self_param_is_mut( - int id: @self_param ref -); - -#keyset[id] -self_param_lifetimes( - int id: @self_param ref, - int lifetime: @lifetime ref -); - -#keyset[id] -self_param_names( - int id: @self_param ref, - int name: @name ref -); - -#keyset[id] -self_param_ties( - int id: @self_param ref, - int ty: @type_ref ref -); - source_files( unique int id: @source_file ); @@ -1986,6 +1946,16 @@ or_pat_pats( int pat: @pat ref ); +params( + unique int id: @param +); + +#keyset[id] +param_pats( + int id: @param ref, + int pat: @pat ref +); + paren_exprs( unique int id: @paren_expr ); @@ -2296,6 +2266,27 @@ return_expr_exprs( int expr: @expr ref ); +self_params( + unique int id: @self_param +); + +#keyset[id] +self_param_is_mut( + int id: @self_param ref +); + +#keyset[id] +self_param_lifetimes( + int id: @self_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +self_param_names( + int id: @self_param ref, + int name: @name ref +); + slice_pats( unique int id: @slice_pat ); diff --git a/rust/ql/test/extractor-tests/generated/.generated_tests.list b/rust/ql/test/extractor-tests/generated/.generated_tests.list index 83affdc7e64..1fe8e805b26 100644 --- a/rust/ql/test/extractor-tests/generated/.generated_tests.list +++ b/rust/ql/test/extractor-tests/generated/.generated_tests.list @@ -75,7 +75,7 @@ NameRef/gen_name_ref.rs 41307c2f7ca82d28217129639e556bd4c91221cf3a4170250b313fd5 NeverType/gen_never_type.rs a5413fab6a45dcfc2ff0ec5c8308b6c515963212ec4aa9edb9a96ec9a7e96830 a5413fab6a45dcfc2ff0ec5c8308b6c515963212ec4aa9edb9a96ec9a7e96830 OffsetOfExpr/gen_offset_of_expr.rs 8e2077b4d7b85c91c17c3630511bc4f929950e9007261cbf0471c4a064c4b934 8e2077b4d7b85c91c17c3630511bc4f929950e9007261cbf0471c4a064c4b934 OrPat/gen_or_pat.rs 71feef6e056bfe4cc8c22c9eb54fa3fecef613606769061d0efd059adbbd6f56 71feef6e056bfe4cc8c22c9eb54fa3fecef613606769061d0efd059adbbd6f56 -Param/gen_param.rs 6c9e4a972b2dc0702dc29ebcbdcbe2c6a433b3cd372ad6924feedcea4698faba 6c9e4a972b2dc0702dc29ebcbdcbe2c6a433b3cd372ad6924feedcea4698faba +Param/gen_param.rs 39f3979d6cb10e4c43e0b5601af2a92b7520a75a104211955bbbb5e6f13e9db9 39f3979d6cb10e4c43e0b5601af2a92b7520a75a104211955bbbb5e6f13e9db9 ParamList/gen_param_list.rs ef2e83d0aed45b969fe78dd717e87ef3c1f848e6179cfb4dc3cb136f1836b998 ef2e83d0aed45b969fe78dd717e87ef3c1f848e6179cfb4dc3cb136f1836b998 ParenExpr/gen_paren_expr.rs dd0c4a21a92e54e8a6151145e013cbec9c9e1cad093d572e293b4f51d6c44aea dd0c4a21a92e54e8a6151145e013cbec9c9e1cad093d572e293b4f51d6c44aea ParenPat/gen_paren_pat.rs c8d18521b9a0b7d39841eb72e3895914aa652b7235dea42ed12a4eb280e3bf0e c8d18521b9a0b7d39841eb72e3895914aa652b7235dea42ed12a4eb280e3bf0e @@ -104,7 +104,7 @@ RestPat/gen_rest_pat.rs e762bf7537225f97da751c5dca6a2cd3836ad7579b68c748b8c6cba6 RetType/gen_ret_type.rs 0947aed0974461b7a5b56bbc5fe36131663bde715c37302345d4eee23b71c825 0947aed0974461b7a5b56bbc5fe36131663bde715c37302345d4eee23b71c825 ReturnExpr/gen_return_expr.rs 4f6ef29d7b3c60d6d71d1a6034a0721671f517428ba21897361a92b01009d38f 4f6ef29d7b3c60d6d71d1a6034a0721671f517428ba21897361a92b01009d38f ReturnTypeSyntax/gen_return_type_syntax.rs 0b11a4cc400f9a2001996f99d61391bdb636e8aea036f587cf18ad6a957fe496 0b11a4cc400f9a2001996f99d61391bdb636e8aea036f587cf18ad6a957fe496 -SelfParam/gen_self_param.rs b7bf9f23fedad6f1a15f02e5fac33fc2c68ec3409b44f24142c2fdec1e5e6f1f b7bf9f23fedad6f1a15f02e5fac33fc2c68ec3409b44f24142c2fdec1e5e6f1f +SelfParam/gen_self_param.rs 9be528c454e2734292d54550f8850ae8e48e1558da46dcf7f06fc7a7a8c3e569 9be528c454e2734292d54550f8850ae8e48e1558da46dcf7f06fc7a7a8c3e569 SlicePat/gen_slice_pat.rs df4a6692f5100aa11dd777561400ce71e37b85f2363b0638c21975a1771b15d5 df4a6692f5100aa11dd777561400ce71e37b85f2363b0638c21975a1771b15d5 SliceType/gen_slice_type.rs 073282f4755994473933db7e4f1e4d34a80363d7e331299ec4ac1a2d6a235b86 073282f4755994473933db7e4f1e4d34a80363d7e331299ec4ac1a2d6a235b86 SourceFile/gen_source_file.rs a7a1d4fa77b53adb6fbc031bf7ab49cf7c8787728ba0a687c348b5eefbb5b9df a7a1d4fa77b53adb6fbc031bf7ab49cf7c8787728ba0a687c348b5eefbb5b9df diff --git a/rust/ql/test/extractor-tests/generated/Param/Param.expected b/rust/ql/test/extractor-tests/generated/Param/Param.expected index e69de29bb2d..e0f54f13583 100644 --- a/rust/ql/test/extractor-tests/generated/Param/Param.expected +++ b/rust/ql/test/extractor-tests/generated/Param/Param.expected @@ -0,0 +1 @@ +| gen_param.rs:5:12:5:15 | ...: T | getNumberOfAttrs: | 0 | hasTy: | yes | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/Param/Param.ql b/rust/ql/test/extractor-tests/generated/Param/Param.ql index 6e022c29db9..1e744bae58b 100644 --- a/rust/ql/test/extractor-tests/generated/Param/Param.ql +++ b/rust/ql/test/extractor-tests/generated/Param/Param.ql @@ -2,11 +2,11 @@ import codeql.rust.elements import TestUtils -from Param x, int getNumberOfAttrs, string hasPat, string hasTy +from Param x, int getNumberOfAttrs, string hasTy, string hasPat where toBeTested(x) and not x.isUnknown() and getNumberOfAttrs = x.getNumberOfAttrs() and - (if x.hasPat() then hasPat = "yes" else hasPat = "no") and - if x.hasTy() then hasTy = "yes" else hasTy = "no" -select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasPat:", hasPat, "hasTy:", hasTy + (if x.hasTy() then hasTy = "yes" else hasTy = "no") and + if x.hasPat() then hasPat = "yes" else hasPat = "no" +select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasTy:", hasTy, "hasPat:", hasPat diff --git a/rust/ql/test/extractor-tests/generated/Param/Param_getPat.expected b/rust/ql/test/extractor-tests/generated/Param/Param_getPat.expected index e69de29bb2d..c42d7ce0b9f 100644 --- a/rust/ql/test/extractor-tests/generated/Param/Param_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/Param/Param_getPat.expected @@ -0,0 +1 @@ +| gen_param.rs:5:12:5:15 | ...: T | gen_param.rs:5:12:5:12 | x | diff --git a/rust/ql/test/extractor-tests/generated/Param/Param_getTy.expected b/rust/ql/test/extractor-tests/generated/Param/Param_getTy.expected index e69de29bb2d..10bf906af5d 100644 --- a/rust/ql/test/extractor-tests/generated/Param/Param_getTy.expected +++ b/rust/ql/test/extractor-tests/generated/Param/Param_getTy.expected @@ -0,0 +1 @@ +| gen_param.rs:5:12:5:15 | ...: T | gen_param.rs:5:15:5:15 | T | diff --git a/rust/ql/test/extractor-tests/generated/Param/gen_param.rs b/rust/ql/test/extractor-tests/generated/Param/gen_param.rs index 5bc96d63219..679943f8aa7 100644 --- a/rust/ql/test/extractor-tests/generated/Param/gen_param.rs +++ b/rust/ql/test/extractor-tests/generated/Param/gen_param.rs @@ -1,6 +1,8 @@ // generated by codegen, do not edit fn test_param() -> () { - // A Param. For example: - todo!() + // A parameter in a function or method. For example `x` in: + fn new(x: T) -> Foo { + // ... + } } diff --git a/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam.expected b/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam.expected index e69de29bb2d..41c5e89e83d 100644 --- a/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam.expected +++ b/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam.expected @@ -0,0 +1 @@ +| gen_self_param.rs:5:13:5:21 | SelfParam | getNumberOfAttrs: | 0 | hasTy: | no | isMut: | yes | hasLifetime: | no | hasName: | yes | diff --git a/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam.ql b/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam.ql index af2fa064a72..579ec7ffa2a 100644 --- a/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam.ql +++ b/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam.ql @@ -3,14 +3,14 @@ import codeql.rust.elements import TestUtils from - SelfParam x, int getNumberOfAttrs, string isMut, string hasLifetime, string hasName, string hasTy + SelfParam x, int getNumberOfAttrs, string hasTy, string isMut, string hasLifetime, string hasName where toBeTested(x) and not x.isUnknown() and getNumberOfAttrs = x.getNumberOfAttrs() and + (if x.hasTy() then hasTy = "yes" else hasTy = "no") and (if x.isMut() then isMut = "yes" else isMut = "no") and (if x.hasLifetime() then hasLifetime = "yes" else hasLifetime = "no") and - (if x.hasName() then hasName = "yes" else hasName = "no") and - if x.hasTy() then hasTy = "yes" else hasTy = "no" -select x, "getNumberOfAttrs:", getNumberOfAttrs, "isMut:", isMut, "hasLifetime:", hasLifetime, - "hasName:", hasName, "hasTy:", hasTy + if x.hasName() then hasName = "yes" else hasName = "no" +select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasTy:", hasTy, "isMut:", isMut, "hasLifetime:", + hasLifetime, "hasName:", hasName diff --git a/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam_getName.expected b/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam_getName.expected index e69de29bb2d..70a9a4a0659 100644 --- a/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam_getName.expected +++ b/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam_getName.expected @@ -0,0 +1 @@ +| gen_self_param.rs:5:13:5:21 | SelfParam | gen_self_param.rs:5:18:5:21 | self | diff --git a/rust/ql/test/extractor-tests/generated/SelfParam/gen_self_param.rs b/rust/ql/test/extractor-tests/generated/SelfParam/gen_self_param.rs index 36f8ffd8baf..6278147a878 100644 --- a/rust/ql/test/extractor-tests/generated/SelfParam/gen_self_param.rs +++ b/rust/ql/test/extractor-tests/generated/SelfParam/gen_self_param.rs @@ -1,6 +1,8 @@ // generated by codegen, do not edit fn test_self_param() -> () { - // A SelfParam. For example: - todo!() + // A `self` parameter. For example `self` in: + fn push(&mut self, value: T) { + // ... + } } diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index 91a6d6add28..e2ab1bf8e56 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -1324,14 +1324,29 @@ class _: """ -@annotate(Param, cfg = True) +class ParamBase(AstNode): + """ + A normal parameter, `Param`, or a self parameter `SelfParam`. + """ + attrs: list["Attr"] | child + ty: optional["TypeRef"] | child + +@annotate(ParamBase, cfg = True) +class _: + pass + +@annotate(Param, replace_bases={AstNode: ParamBase}, cfg = True) class _: """ - A Param. For example: + A parameter in a function or method. For example `x` in: ```rust - todo!() + fn new(x: T) -> Foo { + // ... + } ``` """ + attrs: drop + ty: drop @annotate(ParamList) @@ -1494,14 +1509,18 @@ class _: """ -@annotate(SelfParam, cfg = True) +@annotate(SelfParam, replace_bases={AstNode: ParamBase}, cfg = True) class _: """ - A SelfParam. For example: + A `self` parameter. For example `self` in: ```rust - todo!() + fn push(&mut self, value: T) { + // ... + } ``` """ + attrs: drop + ty: drop @annotate(SliceType) From 0de66586608f8cfefd737cc40efebe5a83f75715 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 25 Nov 2024 14:18:08 +0100 Subject: [PATCH 227/470] Rust: Use `ParamBase` in data flow implementation --- .../rust/dataflow/internal/DataFlowImpl.qll | 28 ++++++------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 1ec8a42ee7e..d5e496c3f0b 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -83,7 +83,7 @@ final class ParameterPosition extends TParameterPosition { result = "self" and this.isSelf() } - AstNode getParameterIn(ParamList ps) { + ParamBase getParameterIn(ParamList ps) { result = ps.getParam(this.getPosition()) or result = ps.getSelfParam() and this.isSelf() @@ -181,28 +181,17 @@ module Node { PatCfgNode getPat() { result = n } } - abstract class ParameterNode extends AstCfgFlowNode { } - /** * The value of a parameter at function entry, viewed as a node in a data * flow graph. */ - final class PositionalParameterNode extends ParameterNode, TParameterNode { - override ParamCfgNode n; + final class ParameterNode extends AstCfgFlowNode, TParameterNode { + override ParamBaseCfgNode n; - PositionalParameterNode() { this = TParameterNode(n) } + ParameterNode() { this = TParameterNode(n) } /** Gets the parameter in the CFG that this node corresponds to. */ - ParamCfgNode getParameter() { result = n } - } - - final class SelfParameterNode extends ParameterNode, TSelfParameterNode { - override SelfParamCfgNode n; - - SelfParameterNode() { this = TSelfParameterNode(n) } - - /** Gets the self parameter in the AST that this node corresponds to. */ - SelfParamCfgNode getSelfParameter() { result = n } + ParamBaseCfgNode getParameter() { result = n } } final class ArgumentNode extends ExprNode { @@ -284,7 +273,7 @@ module SsaFlow { private module SsaFlow = SsaImpl::DataFlowIntegration; private Node::ParameterNode toParameterNode(ParamCfgNode p) { - result.(Node::PositionalParameterNode).getParameter() = p + result.(Node::ParameterNode).getParameter() = p } /** Converts a control flow node into an SSA control flow node. */ @@ -333,7 +322,7 @@ module LocalFlow { nodeFrom.(Node::AstCfgFlowNode).getCfgNode() = nodeTo.(Node::SsaNode).getDefinitionExt().(Ssa::WriteDefinition).getControlFlowNode() or - nodeFrom.(Node::PositionalParameterNode).getParameter().getPat() = + nodeFrom.(Node::ParameterNode).getParameter().(ParamCfgNode).getPat() = nodeTo.(Node::PatNode).getPat() or SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _) @@ -559,8 +548,7 @@ private module Cached { cached newtype TNode = TExprNode(ExprCfgNode n) or - TParameterNode(ParamCfgNode p) or - TSelfParameterNode(SelfParamCfgNode p) or + TParameterNode(ParamBaseCfgNode p) or TPatNode(PatCfgNode p) or TArgumentPostUpdateNode(ExprCfgNode e) { isArgumentForCall(e, _, _) } or TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node) From 03ab74e07db9cea8a47145671ee4b9bb16611e2d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 25 Nov 2024 13:43:20 +0000 Subject: [PATCH 228/470] C++: Add more 'CommandExecutionFunction's. --- cpp/ql/lib/semmle/code/cpp/models/Models.qll | 1 + .../implementations/Win32CommandExecution.qll | 56 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 cpp/ql/lib/semmle/code/cpp/models/implementations/Win32CommandExecution.qll diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll index 1e0b6cd33ed..f6776a623ff 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll @@ -49,3 +49,4 @@ private import implementations.PostgreSql private import implementations.System private import implementations.StructuredExceptionHandling private import implementations.ZMQ +private import implementations.Win32CommandExecution diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Win32CommandExecution.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Win32CommandExecution.qll new file mode 100644 index 00000000000..13d7ffae807 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Win32CommandExecution.qll @@ -0,0 +1,56 @@ +private import semmle.code.cpp.models.interfaces.CommandExecution + +/** The `ShellExecute` family of functions from Win32. */ +class ShellExecute extends Function { + ShellExecute() { this.hasGlobalName("ShellExecute" + ["", "A", "W"]) } +} + +private class ShellExecuteModel extends ShellExecute, CommandExecutionFunction { + override predicate hasCommandArgument(FunctionInput input) { input.isParameterDeref(2) } +} + +/** The `WinExec` function from Win32. */ +class WinExec extends Function { + WinExec() { this.hasGlobalName("WinExec") } +} + +private class WinExecModel extends WinExec, CommandExecutionFunction { + override predicate hasCommandArgument(FunctionInput input) { input.isParameterDeref(0) } +} + +/** The `CreateProcess` family of functions from Win32. */ +class CreateProcess extends Function { + CreateProcess() { this.hasGlobalName("CreateProcess" + ["", "A", "W"]) } +} + +private class CreateProcessModel extends CreateProcess, CommandExecutionFunction { + override predicate hasCommandArgument(FunctionInput input) { input.isParameterDeref(0) } +} + +/** The `CreateProcessAsUser` family of functions from Win32. */ +class CreateProcessAsUser extends Function { + CreateProcessAsUser() { this.hasGlobalName("CreateProcessAsUser" + ["", "A", "W"]) } +} + +private class CreateProcessAsUserModel extends CreateProcessAsUser, CommandExecutionFunction { + override predicate hasCommandArgument(FunctionInput input) { input.isParameterDeref(1) } +} + +/** The `CreateProcessWithLogonW` function from Win32. */ +class CreateProcessWithLogonW extends Function { + CreateProcessWithLogonW() { this.hasGlobalName("CreateProcessWithLogonW") } +} + +private class CreateProcessWithLogonModel extends CreateProcessWithLogonW, CommandExecutionFunction { + override predicate hasCommandArgument(FunctionInput input) { input.isParameterDeref(4) } +} + +/** The `CreateProcessWithTokenW` function from Win32. */ +class CreateProcessWithTokenW extends Function { + CreateProcessWithTokenW() { this.hasGlobalName("CreateProcessWithTokenW") } +} + +private class CreateProcessWithTokenWModel extends CreateProcessWithTokenW, CommandExecutionFunction +{ + override predicate hasCommandArgument(FunctionInput input) { input.isParameterDeref(2) } +} From 25664d0e53c8225407adc06f70d5a1604ed893ba Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 25 Nov 2024 14:48:17 +0100 Subject: [PATCH 229/470] Java: Add support for non-integer bounds in inline expectations --- .../dataflow/range-analysis-inline/B.java | 26 ++++++++ .../dataflow/range-analysis-inline/range.ql | 61 +++++++++++++++---- 2 files changed, 76 insertions(+), 11 deletions(-) diff --git a/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java b/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java index 4818e93d894..22eb7dfcb0f 100644 --- a/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java +++ b/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java @@ -1,4 +1,9 @@ public class B { + + // Use this method to mark non-integer bounds + // that should also be annotated. + static void bound(int b) { } + public int forloop() { int result = 0; for (int i = 0; @@ -91,4 +96,25 @@ public class B { } return result; // $ bound="result = 5" } + + static void arraylength(int[] arr) { + bound(arr.length); + for (int i = 0; + i < arr.length; + i++) { // $ bound="i <= arr.length - 1" + arr[i]++; // $ bound="i <= arr.length - 1" + } + } + + static int varbound(int b) { + bound(b); + int result = 0; + for (int i = 0; + i < b; + i++) { // $ bound="i <= b - 1" + result = i; // $ bound="i <= b - 1" + } + return result; // $ MISSING: bound="result <= b - 1" + } + } \ No newline at end of file diff --git a/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql b/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql index 0e0fa68b07b..263df27d316 100644 --- a/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql +++ b/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql @@ -6,23 +6,49 @@ import java import semmle.code.java.dataflow.RangeAnalysis private import TestUtilities.InlineExpectationsTest as IET +private import semmle.code.java.dataflow.DataFlow module RangeTest implements IET::TestSig { string getARelevantTag() { result = "bound" } predicate hasActualResult(Location location, string element, string tag, string value) { tag = "bound" and - exists(Expr e, int lower, int upper | - constrained(e, lower, upper) and - e instanceof VarRead and - e.getCompilationUnit().fromSource() - | - location = e.getLocation() and - element = e.toString() and - if lower = upper - then value = "\"" + e.toString() + " = " + lower.toString() + "\"" - else - value = "\"" + e.toString() + " in [" + lower.toString() + ".." + upper.toString() + "]\"" + ( + // simple integer bounds (`ZeroBound`s) + exists(Expr e, int lower, int upper | + constrained(e, lower, upper) and + e instanceof VarRead and + e.getCompilationUnit().fromSource() + | + location = e.getLocation() and + element = e.toString() and + if lower = upper + then value = "\"" + e.toString() + " = " + lower.toString() + "\"" + else + value = "\"" + e.toString() + " in [" + lower.toString() + ".." + upper.toString() + "]\"" + ) + or + // advanced bounds + exists( + Expr e, int delta, string deltaStr, boolean upper, string cmp, Bound b, Expr boundExpr + | + annotatedBound(e, b, boundExpr, delta, upper) and + e instanceof VarRead and + e.getCompilationUnit().fromSource() and + ( + if delta = 0 + then deltaStr = "" + else + if delta > 0 + then deltaStr = " + " + delta.toString() + else deltaStr = " - " + delta.abs().toString() + ) and + if upper = true then cmp = "<=" else cmp = ">=" + | + location = e.getLocation() and + element = e.toString() and + value = "\"" + e.toString() + " " + cmp + " " + boundExpr.toString() + deltaStr + "\"" + ) ) } @@ -30,6 +56,19 @@ module RangeTest implements IET::TestSig { bounded(e, any(ZeroBound z), lower, false, _) and bounded(e, any(ZeroBound z), upper, true, _) } + + private predicate annotatedBound(Expr e, Bound b, Expr boundExpr, int delta, boolean upper) { + bounded(e, b, delta, upper, _) and + // the expression for the bound is explicitly requested as being annotated + // via a call such as + // ```java + // bound(expr); + // ``` + boundExpr = b.getExpr() and + exists(Call c | c.getCallee().getName() = "bound" and c.getArgument(0) = boundExpr) and + // non-trivial bound + (DataFlow::localFlow(DataFlow::exprNode(boundExpr), DataFlow::exprNode(e)) implies delta != 0) + } } import IET::MakeTest From 05b6700607e437b363633ed2cb1bdd02a0557351 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Mon, 25 Nov 2024 09:22:37 -0500 Subject: [PATCH 230/470] Java: add SHA384 to list of secure algorithms --- java/ql/lib/semmle/code/java/security/Encryption.qll | 2 +- java/ql/src/change-notes/2024-11-24-sha2.md | 4 ++++ .../security/CWE-327/semmle/tests/WeakHashing.java | 5 ++++- 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 java/ql/src/change-notes/2024-11-24-sha2.md diff --git a/java/ql/lib/semmle/code/java/security/Encryption.qll b/java/ql/lib/semmle/code/java/security/Encryption.qll index dae80b19be1..7c9c5ec60db 100644 --- a/java/ql/lib/semmle/code/java/security/Encryption.qll +++ b/java/ql/lib/semmle/code/java/security/Encryption.qll @@ -246,7 +246,7 @@ string getInsecureAlgorithmRegex() { string getASecureAlgorithmName() { result = [ - "RSA", "SHA-?256", "SHA-?512", "CCM", "GCM", "AES(?![^a-zA-Z](ECB|CBC/PKCS[57]Padding))", + "RSA", "SHA-?(256|384|512)", "CCM", "GCM", "AES(?![^a-zA-Z](ECB|CBC/PKCS[57]Padding))", "Blowfish", "ECIES", "SHA3-(256|384|512)" ] } diff --git a/java/ql/src/change-notes/2024-11-24-sha2.md b/java/ql/src/change-notes/2024-11-24-sha2.md new file mode 100644 index 00000000000..395ea04b782 --- /dev/null +++ b/java/ql/src/change-notes/2024-11-24-sha2.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added SHA-384 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA-384. diff --git a/java/ql/test/query-tests/security/CWE-327/semmle/tests/WeakHashing.java b/java/ql/test/query-tests/security/CWE-327/semmle/tests/WeakHashing.java index 8858576cb90..c79c025a41c 100644 --- a/java/ql/test/query-tests/security/CWE-327/semmle/tests/WeakHashing.java +++ b/java/ql/test/query-tests/security/CWE-327/semmle/tests/WeakHashing.java @@ -19,7 +19,7 @@ public class WeakHashing { // BAD: Using a strong hashing algorithm but with a weak default MessageDigest bad3 = MessageDigest.getInstance(props.getProperty("hashAlg2", "MD5")); - + // GOOD: Using a strong hashing algorithm MessageDigest ok = MessageDigest.getInstance(props.getProperty("hashAlg2")); @@ -28,5 +28,8 @@ public class WeakHashing { // GOOD: Using a strong hashing algorithm MessageDigest ok3 = MessageDigest.getInstance("SHA3-512"); + + // GOOD: Using a strong hashing algorithm + MessageDigest ok4 = MessageDigest.getInstance("SHA384"); } } From f92e8555a684394b37c1be1012be9bbb0eb1b191 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 25 Nov 2024 14:35:12 +0000 Subject: [PATCH 231/470] Rust: update for toString changes in main. --- .../test/query-tests/diagnostics/UnresolvedMacroCalls.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/test/query-tests/diagnostics/UnresolvedMacroCalls.expected b/rust/ql/test/query-tests/diagnostics/UnresolvedMacroCalls.expected index 28fb46e8283..72f78794ab2 100644 --- a/rust/ql/test/query-tests/diagnostics/UnresolvedMacroCalls.expected +++ b/rust/ql/test/query-tests/diagnostics/UnresolvedMacroCalls.expected @@ -1 +1 @@ -| my_macro.rs:17:9:17:27 | MacroCall | Macro call was not resolved to a target. | +| my_macro.rs:17:9:17:27 | myUndefinedMacro!... | Macro call was not resolved to a target. | From d06b5833cf3ba134b84373f353513dd51dcbdd23 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 25 Nov 2024 16:08:26 +0100 Subject: [PATCH 232/470] Rust: Add an additional variables test with a self parameter --- .../test/library-tests/variables/Cfg.expected | 376 +++++++++--------- .../test/library-tests/variables/Ssa.expected | 14 +- .../variables/variables.expected | 52 +-- .../test/library-tests/variables/variables.rs | 10 +- 4 files changed, 231 insertions(+), 221 deletions(-) diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected index 77ea9a8b15b..6b979eac0da 100644 --- a/rust/ql/test/library-tests/variables/Cfg.expected +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -1078,195 +1078,201 @@ edges | variables.rs:483:9:483:24 | ExprStmt | variables.rs:483:16:483:19 | self | | | variables.rs:483:16:483:19 | self | variables.rs:483:16:483:23 | self.val | | | variables.rs:483:16:483:23 | self.val | variables.rs:483:9:483:23 | return ... | | -| variables.rs:487:1:494:1 | enter fn structs | variables.rs:488:5:488:36 | let ... = ... | | -| variables.rs:487:1:494:1 | exit fn structs (normal) | variables.rs:487:1:494:1 | exit fn structs | | -| variables.rs:487:14:494:1 | { ... } | variables.rs:487:1:494:1 | exit fn structs (normal) | | -| variables.rs:488:5:488:36 | let ... = ... | variables.rs:488:33:488:33 | 1 | | -| variables.rs:488:9:488:13 | a | variables.rs:489:5:489:26 | ExprStmt | match | -| variables.rs:488:17:488:35 | MyStruct {...} | variables.rs:488:9:488:13 | a | | -| variables.rs:488:33:488:33 | 1 | variables.rs:488:17:488:35 | MyStruct {...} | | -| variables.rs:489:5:489:13 | print_i64 | variables.rs:489:15:489:15 | a | | -| variables.rs:489:5:489:25 | print_i64(...) | variables.rs:490:5:490:14 | ExprStmt | | -| variables.rs:489:5:489:26 | ExprStmt | variables.rs:489:5:489:13 | print_i64 | | -| variables.rs:489:15:489:15 | a | variables.rs:489:15:489:24 | ... .my_get(...) | | -| variables.rs:489:15:489:24 | ... .my_get(...) | variables.rs:489:5:489:25 | print_i64(...) | | -| variables.rs:490:5:490:5 | a | variables.rs:490:5:490:9 | a.val | | -| variables.rs:490:5:490:9 | a.val | variables.rs:490:13:490:13 | 5 | | -| variables.rs:490:5:490:13 | ... = ... | variables.rs:491:5:491:26 | ExprStmt | | -| variables.rs:490:5:490:14 | ExprStmt | variables.rs:490:5:490:5 | a | | -| variables.rs:490:13:490:13 | 5 | variables.rs:490:5:490:13 | ... = ... | | -| variables.rs:491:5:491:13 | print_i64 | variables.rs:491:15:491:15 | a | | -| variables.rs:491:5:491:25 | print_i64(...) | variables.rs:492:5:492:28 | ExprStmt | | -| variables.rs:491:5:491:26 | ExprStmt | variables.rs:491:5:491:13 | print_i64 | | -| variables.rs:491:15:491:15 | a | variables.rs:491:15:491:24 | ... .my_get(...) | | -| variables.rs:491:15:491:24 | ... .my_get(...) | variables.rs:491:5:491:25 | print_i64(...) | | -| variables.rs:492:5:492:5 | a | variables.rs:492:25:492:25 | 2 | | -| variables.rs:492:5:492:27 | ... = ... | variables.rs:493:5:493:26 | ExprStmt | | -| variables.rs:492:5:492:28 | ExprStmt | variables.rs:492:5:492:5 | a | | -| variables.rs:492:9:492:27 | MyStruct {...} | variables.rs:492:5:492:27 | ... = ... | | -| variables.rs:492:25:492:25 | 2 | variables.rs:492:9:492:27 | MyStruct {...} | | +| variables.rs:486:5:488:5 | enter fn id | variables.rs:486:11:486:14 | self | | +| variables.rs:486:5:488:5 | exit fn id (normal) | variables.rs:486:5:488:5 | exit fn id | | +| variables.rs:486:11:486:14 | SelfParam | variables.rs:487:9:487:12 | self | | +| variables.rs:486:11:486:14 | self | variables.rs:486:11:486:14 | SelfParam | | +| variables.rs:486:25:488:5 | { ... } | variables.rs:486:5:488:5 | exit fn id (normal) | | +| variables.rs:487:9:487:12 | self | variables.rs:486:25:488:5 | { ... } | | +| variables.rs:491:1:498:1 | enter fn structs | variables.rs:492:5:492:36 | let ... = ... | | +| variables.rs:491:1:498:1 | exit fn structs (normal) | variables.rs:491:1:498:1 | exit fn structs | | +| variables.rs:491:14:498:1 | { ... } | variables.rs:491:1:498:1 | exit fn structs (normal) | | +| variables.rs:492:5:492:36 | let ... = ... | variables.rs:492:33:492:33 | 1 | | +| variables.rs:492:9:492:13 | a | variables.rs:493:5:493:26 | ExprStmt | match | +| variables.rs:492:17:492:35 | MyStruct {...} | variables.rs:492:9:492:13 | a | | +| variables.rs:492:33:492:33 | 1 | variables.rs:492:17:492:35 | MyStruct {...} | | | variables.rs:493:5:493:13 | print_i64 | variables.rs:493:15:493:15 | a | | -| variables.rs:493:5:493:25 | print_i64(...) | variables.rs:487:14:494:1 | { ... } | | +| variables.rs:493:5:493:25 | print_i64(...) | variables.rs:494:5:494:14 | ExprStmt | | | variables.rs:493:5:493:26 | ExprStmt | variables.rs:493:5:493:13 | print_i64 | | | variables.rs:493:15:493:15 | a | variables.rs:493:15:493:24 | ... .my_get(...) | | | variables.rs:493:15:493:24 | ... .my_get(...) | variables.rs:493:5:493:25 | print_i64(...) | | -| variables.rs:496:1:503:1 | enter fn ref_arg | variables.rs:497:5:497:15 | let ... = 16 | | -| variables.rs:496:1:503:1 | exit fn ref_arg (normal) | variables.rs:496:1:503:1 | exit fn ref_arg | | -| variables.rs:496:14:503:1 | { ... } | variables.rs:496:1:503:1 | exit fn ref_arg (normal) | | -| variables.rs:497:5:497:15 | let ... = 16 | variables.rs:497:13:497:14 | 16 | | -| variables.rs:497:9:497:9 | x | variables.rs:498:5:498:22 | ExprStmt | match | -| variables.rs:497:13:497:14 | 16 | variables.rs:497:9:497:9 | x | | -| variables.rs:498:5:498:17 | print_i64_ref | variables.rs:498:20:498:20 | x | | -| variables.rs:498:5:498:21 | print_i64_ref(...) | variables.rs:499:5:499:17 | ExprStmt | | -| variables.rs:498:5:498:22 | ExprStmt | variables.rs:498:5:498:17 | print_i64_ref | | -| variables.rs:498:19:498:20 | &x | variables.rs:498:5:498:21 | print_i64_ref(...) | | -| variables.rs:498:20:498:20 | x | variables.rs:498:19:498:20 | &x | | -| variables.rs:499:5:499:13 | print_i64 | variables.rs:499:15:499:15 | x | | -| variables.rs:499:5:499:16 | print_i64(...) | variables.rs:501:5:501:15 | let ... = 17 | | -| variables.rs:499:5:499:17 | ExprStmt | variables.rs:499:5:499:13 | print_i64 | | -| variables.rs:499:15:499:15 | x | variables.rs:499:5:499:16 | print_i64(...) | | -| variables.rs:501:5:501:15 | let ... = 17 | variables.rs:501:13:501:14 | 17 | | -| variables.rs:501:9:501:9 | z | variables.rs:502:5:502:22 | ExprStmt | match | -| variables.rs:501:13:501:14 | 17 | variables.rs:501:9:501:9 | z | | -| variables.rs:502:5:502:17 | print_i64_ref | variables.rs:502:20:502:20 | z | | -| variables.rs:502:5:502:21 | print_i64_ref(...) | variables.rs:496:14:503:1 | { ... } | | +| variables.rs:494:5:494:5 | a | variables.rs:494:5:494:9 | a.val | | +| variables.rs:494:5:494:9 | a.val | variables.rs:494:13:494:13 | 5 | | +| variables.rs:494:5:494:13 | ... = ... | variables.rs:495:5:495:26 | ExprStmt | | +| variables.rs:494:5:494:14 | ExprStmt | variables.rs:494:5:494:5 | a | | +| variables.rs:494:13:494:13 | 5 | variables.rs:494:5:494:13 | ... = ... | | +| variables.rs:495:5:495:13 | print_i64 | variables.rs:495:15:495:15 | a | | +| variables.rs:495:5:495:25 | print_i64(...) | variables.rs:496:5:496:28 | ExprStmt | | +| variables.rs:495:5:495:26 | ExprStmt | variables.rs:495:5:495:13 | print_i64 | | +| variables.rs:495:15:495:15 | a | variables.rs:495:15:495:24 | ... .my_get(...) | | +| variables.rs:495:15:495:24 | ... .my_get(...) | variables.rs:495:5:495:25 | print_i64(...) | | +| variables.rs:496:5:496:5 | a | variables.rs:496:25:496:25 | 2 | | +| variables.rs:496:5:496:27 | ... = ... | variables.rs:497:5:497:26 | ExprStmt | | +| variables.rs:496:5:496:28 | ExprStmt | variables.rs:496:5:496:5 | a | | +| variables.rs:496:9:496:27 | MyStruct {...} | variables.rs:496:5:496:27 | ... = ... | | +| variables.rs:496:25:496:25 | 2 | variables.rs:496:9:496:27 | MyStruct {...} | | +| variables.rs:497:5:497:13 | print_i64 | variables.rs:497:15:497:15 | a | | +| variables.rs:497:5:497:25 | print_i64(...) | variables.rs:491:14:498:1 | { ... } | | +| variables.rs:497:5:497:26 | ExprStmt | variables.rs:497:5:497:13 | print_i64 | | +| variables.rs:497:15:497:15 | a | variables.rs:497:15:497:24 | ... .my_get(...) | | +| variables.rs:497:15:497:24 | ... .my_get(...) | variables.rs:497:5:497:25 | print_i64(...) | | +| variables.rs:500:1:507:1 | enter fn ref_arg | variables.rs:501:5:501:15 | let ... = 16 | | +| variables.rs:500:1:507:1 | exit fn ref_arg (normal) | variables.rs:500:1:507:1 | exit fn ref_arg | | +| variables.rs:500:14:507:1 | { ... } | variables.rs:500:1:507:1 | exit fn ref_arg (normal) | | +| variables.rs:501:5:501:15 | let ... = 16 | variables.rs:501:13:501:14 | 16 | | +| variables.rs:501:9:501:9 | x | variables.rs:502:5:502:22 | ExprStmt | match | +| variables.rs:501:13:501:14 | 16 | variables.rs:501:9:501:9 | x | | +| variables.rs:502:5:502:17 | print_i64_ref | variables.rs:502:20:502:20 | x | | +| variables.rs:502:5:502:21 | print_i64_ref(...) | variables.rs:503:5:503:17 | ExprStmt | | | variables.rs:502:5:502:22 | ExprStmt | variables.rs:502:5:502:17 | print_i64_ref | | -| variables.rs:502:19:502:20 | &z | variables.rs:502:5:502:21 | print_i64_ref(...) | | -| variables.rs:502:20:502:20 | z | variables.rs:502:19:502:20 | &z | | -| variables.rs:510:3:512:3 | enter fn bar | variables.rs:510:15:510:18 | self | | -| variables.rs:510:3:512:3 | exit fn bar (normal) | variables.rs:510:3:512:3 | exit fn bar | | -| variables.rs:510:10:510:18 | SelfParam | variables.rs:511:5:511:32 | ExprStmt | | -| variables.rs:510:15:510:18 | self | variables.rs:510:10:510:18 | SelfParam | | -| variables.rs:510:21:512:3 | { ... } | variables.rs:510:3:512:3 | exit fn bar (normal) | | -| variables.rs:511:5:511:9 | * ... | variables.rs:511:29:511:29 | 3 | | -| variables.rs:511:5:511:31 | ... = ... | variables.rs:510:21:512:3 | { ... } | | -| variables.rs:511:5:511:32 | ExprStmt | variables.rs:511:6:511:9 | self | | -| variables.rs:511:6:511:9 | self | variables.rs:511:5:511:9 | * ... | | -| variables.rs:511:13:511:31 | MyStruct {...} | variables.rs:511:5:511:31 | ... = ... | | -| variables.rs:511:29:511:29 | 3 | variables.rs:511:13:511:31 | MyStruct {...} | | -| variables.rs:515:1:520:1 | enter fn ref_methodcall_receiver | variables.rs:516:3:516:34 | let ... = ... | | -| variables.rs:515:1:520:1 | exit fn ref_methodcall_receiver (normal) | variables.rs:515:1:520:1 | exit fn ref_methodcall_receiver | | -| variables.rs:515:30:520:1 | { ... } | variables.rs:515:1:520:1 | exit fn ref_methodcall_receiver (normal) | | -| variables.rs:516:3:516:34 | let ... = ... | variables.rs:516:31:516:31 | 1 | | -| variables.rs:516:7:516:11 | a | variables.rs:517:3:517:10 | ExprStmt | match | -| variables.rs:516:15:516:33 | MyStruct {...} | variables.rs:516:7:516:11 | a | | -| variables.rs:516:31:516:31 | 1 | variables.rs:516:15:516:33 | MyStruct {...} | | -| variables.rs:517:3:517:3 | a | variables.rs:517:3:517:9 | ... .bar(...) | | -| variables.rs:517:3:517:9 | ... .bar(...) | variables.rs:519:3:519:19 | ExprStmt | | -| variables.rs:517:3:517:10 | ExprStmt | variables.rs:517:3:517:3 | a | | -| variables.rs:519:3:519:11 | print_i64 | variables.rs:519:13:519:13 | a | | -| variables.rs:519:3:519:18 | print_i64(...) | variables.rs:515:30:520:1 | { ... } | | -| variables.rs:519:3:519:19 | ExprStmt | variables.rs:519:3:519:11 | print_i64 | | -| variables.rs:519:13:519:13 | a | variables.rs:519:13:519:17 | a.val | | -| variables.rs:519:13:519:17 | a.val | variables.rs:519:3:519:18 | print_i64(...) | | -| variables.rs:522:1:556:1 | enter fn main | variables.rs:523:5:523:25 | ExprStmt | | -| variables.rs:522:1:556:1 | exit fn main (normal) | variables.rs:522:1:556:1 | exit fn main | | -| variables.rs:522:11:556:1 | { ... } | variables.rs:522:1:556:1 | exit fn main (normal) | | -| variables.rs:523:5:523:22 | immutable_variable | variables.rs:523:5:523:24 | immutable_variable(...) | | -| variables.rs:523:5:523:24 | immutable_variable(...) | variables.rs:524:5:524:23 | ExprStmt | | -| variables.rs:523:5:523:25 | ExprStmt | variables.rs:523:5:523:22 | immutable_variable | | -| variables.rs:524:5:524:20 | mutable_variable | variables.rs:524:5:524:22 | mutable_variable(...) | | -| variables.rs:524:5:524:22 | mutable_variable(...) | variables.rs:525:5:525:40 | ExprStmt | | -| variables.rs:524:5:524:23 | ExprStmt | variables.rs:524:5:524:20 | mutable_variable | | -| variables.rs:525:5:525:37 | mutable_variable_immutable_borrow | variables.rs:525:5:525:39 | mutable_variable_immutable_borrow(...) | | -| variables.rs:525:5:525:39 | mutable_variable_immutable_borrow(...) | variables.rs:526:5:526:23 | ExprStmt | | -| variables.rs:525:5:525:40 | ExprStmt | variables.rs:525:5:525:37 | mutable_variable_immutable_borrow | | -| variables.rs:526:5:526:20 | variable_shadow1 | variables.rs:526:5:526:22 | variable_shadow1(...) | | -| variables.rs:526:5:526:22 | variable_shadow1(...) | variables.rs:527:5:527:23 | ExprStmt | | -| variables.rs:526:5:526:23 | ExprStmt | variables.rs:526:5:526:20 | variable_shadow1 | | -| variables.rs:527:5:527:20 | variable_shadow2 | variables.rs:527:5:527:22 | variable_shadow2(...) | | -| variables.rs:527:5:527:22 | variable_shadow2(...) | variables.rs:528:5:528:19 | ExprStmt | | -| variables.rs:527:5:527:23 | ExprStmt | variables.rs:527:5:527:20 | variable_shadow2 | | -| variables.rs:528:5:528:16 | let_pattern1 | variables.rs:528:5:528:18 | let_pattern1(...) | | -| variables.rs:528:5:528:18 | let_pattern1(...) | variables.rs:529:5:529:19 | ExprStmt | | -| variables.rs:528:5:528:19 | ExprStmt | variables.rs:528:5:528:16 | let_pattern1 | | -| variables.rs:529:5:529:16 | let_pattern2 | variables.rs:529:5:529:18 | let_pattern2(...) | | -| variables.rs:529:5:529:18 | let_pattern2(...) | variables.rs:530:5:530:19 | ExprStmt | | -| variables.rs:529:5:529:19 | ExprStmt | variables.rs:529:5:529:16 | let_pattern2 | | -| variables.rs:530:5:530:16 | let_pattern3 | variables.rs:530:5:530:18 | let_pattern3(...) | | -| variables.rs:530:5:530:18 | let_pattern3(...) | variables.rs:531:5:531:19 | ExprStmt | | -| variables.rs:530:5:530:19 | ExprStmt | variables.rs:530:5:530:16 | let_pattern3 | | -| variables.rs:531:5:531:16 | let_pattern4 | variables.rs:531:5:531:18 | let_pattern4(...) | | -| variables.rs:531:5:531:18 | let_pattern4(...) | variables.rs:532:5:532:21 | ExprStmt | | -| variables.rs:531:5:531:19 | ExprStmt | variables.rs:531:5:531:16 | let_pattern4 | | -| variables.rs:532:5:532:18 | match_pattern1 | variables.rs:532:5:532:20 | match_pattern1(...) | | -| variables.rs:532:5:532:20 | match_pattern1(...) | variables.rs:533:5:533:21 | ExprStmt | | -| variables.rs:532:5:532:21 | ExprStmt | variables.rs:532:5:532:18 | match_pattern1 | | -| variables.rs:533:5:533:18 | match_pattern2 | variables.rs:533:5:533:20 | match_pattern2(...) | | -| variables.rs:533:5:533:20 | match_pattern2(...) | variables.rs:534:5:534:21 | ExprStmt | | -| variables.rs:533:5:533:21 | ExprStmt | variables.rs:533:5:533:18 | match_pattern2 | | -| variables.rs:534:5:534:18 | match_pattern3 | variables.rs:534:5:534:20 | match_pattern3(...) | | -| variables.rs:534:5:534:20 | match_pattern3(...) | variables.rs:535:5:535:21 | ExprStmt | | -| variables.rs:534:5:534:21 | ExprStmt | variables.rs:534:5:534:18 | match_pattern3 | | -| variables.rs:535:5:535:18 | match_pattern4 | variables.rs:535:5:535:20 | match_pattern4(...) | | -| variables.rs:535:5:535:20 | match_pattern4(...) | variables.rs:536:5:536:21 | ExprStmt | | -| variables.rs:535:5:535:21 | ExprStmt | variables.rs:535:5:535:18 | match_pattern4 | | -| variables.rs:536:5:536:18 | match_pattern5 | variables.rs:536:5:536:20 | match_pattern5(...) | | -| variables.rs:536:5:536:20 | match_pattern5(...) | variables.rs:537:5:537:21 | ExprStmt | | -| variables.rs:536:5:536:21 | ExprStmt | variables.rs:536:5:536:18 | match_pattern5 | | -| variables.rs:537:5:537:18 | match_pattern6 | variables.rs:537:5:537:20 | match_pattern6(...) | | -| variables.rs:537:5:537:20 | match_pattern6(...) | variables.rs:538:5:538:21 | ExprStmt | | -| variables.rs:537:5:537:21 | ExprStmt | variables.rs:537:5:537:18 | match_pattern6 | | -| variables.rs:538:5:538:18 | match_pattern7 | variables.rs:538:5:538:20 | match_pattern7(...) | | -| variables.rs:538:5:538:20 | match_pattern7(...) | variables.rs:539:5:539:21 | ExprStmt | | -| variables.rs:538:5:538:21 | ExprStmt | variables.rs:538:5:538:18 | match_pattern7 | | -| variables.rs:539:5:539:18 | match_pattern8 | variables.rs:539:5:539:20 | match_pattern8(...) | | -| variables.rs:539:5:539:20 | match_pattern8(...) | variables.rs:540:5:540:21 | ExprStmt | | -| variables.rs:539:5:539:21 | ExprStmt | variables.rs:539:5:539:18 | match_pattern8 | | -| variables.rs:540:5:540:18 | match_pattern9 | variables.rs:540:5:540:20 | match_pattern9(...) | | -| variables.rs:540:5:540:20 | match_pattern9(...) | variables.rs:541:5:541:36 | ExprStmt | | -| variables.rs:540:5:540:21 | ExprStmt | variables.rs:540:5:540:18 | match_pattern9 | | -| variables.rs:541:5:541:18 | param_pattern1 | variables.rs:541:20:541:22 | "a" | | -| variables.rs:541:5:541:35 | param_pattern1(...) | variables.rs:542:5:542:37 | ExprStmt | | -| variables.rs:541:5:541:36 | ExprStmt | variables.rs:541:5:541:18 | param_pattern1 | | -| variables.rs:541:20:541:22 | "a" | variables.rs:541:26:541:28 | "b" | | -| variables.rs:541:25:541:34 | TupleExpr | variables.rs:541:5:541:35 | param_pattern1(...) | | -| variables.rs:541:26:541:28 | "b" | variables.rs:541:31:541:33 | "c" | | -| variables.rs:541:31:541:33 | "c" | variables.rs:541:25:541:34 | TupleExpr | | -| variables.rs:542:5:542:18 | param_pattern2 | variables.rs:542:20:542:31 | ...::Left | | -| variables.rs:542:5:542:36 | param_pattern2(...) | variables.rs:543:5:543:26 | ExprStmt | | -| variables.rs:542:5:542:37 | ExprStmt | variables.rs:542:5:542:18 | param_pattern2 | | -| variables.rs:542:20:542:31 | ...::Left | variables.rs:542:33:542:34 | 45 | | -| variables.rs:542:20:542:35 | ...::Left(...) | variables.rs:542:5:542:36 | param_pattern2(...) | | -| variables.rs:542:33:542:34 | 45 | variables.rs:542:20:542:35 | ...::Left(...) | | -| variables.rs:543:5:543:23 | destruct_assignment | variables.rs:543:5:543:25 | destruct_assignment(...) | | -| variables.rs:543:5:543:25 | destruct_assignment(...) | variables.rs:544:5:544:23 | ExprStmt | | -| variables.rs:543:5:543:26 | ExprStmt | variables.rs:543:5:543:23 | destruct_assignment | | -| variables.rs:544:5:544:20 | closure_variable | variables.rs:544:5:544:22 | closure_variable(...) | | -| variables.rs:544:5:544:22 | closure_variable(...) | variables.rs:545:5:545:19 | ExprStmt | | -| variables.rs:544:5:544:23 | ExprStmt | variables.rs:544:5:544:20 | closure_variable | | -| variables.rs:545:5:545:16 | for_variable | variables.rs:545:5:545:18 | for_variable(...) | | -| variables.rs:545:5:545:18 | for_variable(...) | variables.rs:546:5:546:17 | ExprStmt | | -| variables.rs:545:5:545:19 | ExprStmt | variables.rs:545:5:545:16 | for_variable | | -| variables.rs:546:5:546:14 | add_assign | variables.rs:546:5:546:16 | add_assign(...) | | -| variables.rs:546:5:546:16 | add_assign(...) | variables.rs:547:5:547:13 | ExprStmt | | -| variables.rs:546:5:546:17 | ExprStmt | variables.rs:546:5:546:14 | add_assign | | -| variables.rs:547:5:547:10 | mutate | variables.rs:547:5:547:12 | mutate(...) | | -| variables.rs:547:5:547:12 | mutate(...) | variables.rs:548:5:548:17 | ExprStmt | | -| variables.rs:547:5:547:13 | ExprStmt | variables.rs:547:5:547:10 | mutate | | -| variables.rs:548:5:548:14 | mutate_arg | variables.rs:548:5:548:16 | mutate_arg(...) | | -| variables.rs:548:5:548:16 | mutate_arg(...) | variables.rs:549:5:549:12 | ExprStmt | | -| variables.rs:548:5:548:17 | ExprStmt | variables.rs:548:5:548:14 | mutate_arg | | -| variables.rs:549:5:549:9 | alias | variables.rs:549:5:549:11 | alias(...) | | -| variables.rs:549:5:549:11 | alias(...) | variables.rs:550:5:550:18 | ExprStmt | | -| variables.rs:549:5:549:12 | ExprStmt | variables.rs:549:5:549:9 | alias | | -| variables.rs:550:5:550:15 | capture_mut | variables.rs:550:5:550:17 | capture_mut(...) | | -| variables.rs:550:5:550:17 | capture_mut(...) | variables.rs:551:5:551:20 | ExprStmt | | -| variables.rs:550:5:550:18 | ExprStmt | variables.rs:550:5:550:15 | capture_mut | | -| variables.rs:551:5:551:17 | capture_immut | variables.rs:551:5:551:19 | capture_immut(...) | | -| variables.rs:551:5:551:19 | capture_immut(...) | variables.rs:552:5:552:26 | ExprStmt | | -| variables.rs:551:5:551:20 | ExprStmt | variables.rs:551:5:551:17 | capture_immut | | -| variables.rs:552:5:552:23 | async_block_capture | variables.rs:552:5:552:25 | async_block_capture(...) | | -| variables.rs:552:5:552:25 | async_block_capture(...) | variables.rs:553:5:553:14 | ExprStmt | | -| variables.rs:552:5:552:26 | ExprStmt | variables.rs:552:5:552:23 | async_block_capture | | -| variables.rs:553:5:553:11 | structs | variables.rs:553:5:553:13 | structs(...) | | -| variables.rs:553:5:553:13 | structs(...) | variables.rs:554:5:554:14 | ExprStmt | | -| variables.rs:553:5:553:14 | ExprStmt | variables.rs:553:5:553:11 | structs | | -| variables.rs:554:5:554:11 | ref_arg | variables.rs:554:5:554:13 | ref_arg(...) | | -| variables.rs:554:5:554:13 | ref_arg(...) | variables.rs:555:5:555:30 | ExprStmt | | -| variables.rs:554:5:554:14 | ExprStmt | variables.rs:554:5:554:11 | ref_arg | | -| variables.rs:555:5:555:27 | ref_methodcall_receiver | variables.rs:555:5:555:29 | ref_methodcall_receiver(...) | | -| variables.rs:555:5:555:29 | ref_methodcall_receiver(...) | variables.rs:522:11:556:1 | { ... } | | -| variables.rs:555:5:555:30 | ExprStmt | variables.rs:555:5:555:27 | ref_methodcall_receiver | | +| variables.rs:502:19:502:20 | &x | variables.rs:502:5:502:21 | print_i64_ref(...) | | +| variables.rs:502:20:502:20 | x | variables.rs:502:19:502:20 | &x | | +| variables.rs:503:5:503:13 | print_i64 | variables.rs:503:15:503:15 | x | | +| variables.rs:503:5:503:16 | print_i64(...) | variables.rs:505:5:505:15 | let ... = 17 | | +| variables.rs:503:5:503:17 | ExprStmt | variables.rs:503:5:503:13 | print_i64 | | +| variables.rs:503:15:503:15 | x | variables.rs:503:5:503:16 | print_i64(...) | | +| variables.rs:505:5:505:15 | let ... = 17 | variables.rs:505:13:505:14 | 17 | | +| variables.rs:505:9:505:9 | z | variables.rs:506:5:506:22 | ExprStmt | match | +| variables.rs:505:13:505:14 | 17 | variables.rs:505:9:505:9 | z | | +| variables.rs:506:5:506:17 | print_i64_ref | variables.rs:506:20:506:20 | z | | +| variables.rs:506:5:506:21 | print_i64_ref(...) | variables.rs:500:14:507:1 | { ... } | | +| variables.rs:506:5:506:22 | ExprStmt | variables.rs:506:5:506:17 | print_i64_ref | | +| variables.rs:506:19:506:20 | &z | variables.rs:506:5:506:21 | print_i64_ref(...) | | +| variables.rs:506:20:506:20 | z | variables.rs:506:19:506:20 | &z | | +| variables.rs:514:3:516:3 | enter fn bar | variables.rs:514:15:514:18 | self | | +| variables.rs:514:3:516:3 | exit fn bar (normal) | variables.rs:514:3:516:3 | exit fn bar | | +| variables.rs:514:10:514:18 | SelfParam | variables.rs:515:5:515:32 | ExprStmt | | +| variables.rs:514:15:514:18 | self | variables.rs:514:10:514:18 | SelfParam | | +| variables.rs:514:21:516:3 | { ... } | variables.rs:514:3:516:3 | exit fn bar (normal) | | +| variables.rs:515:5:515:9 | * ... | variables.rs:515:29:515:29 | 3 | | +| variables.rs:515:5:515:31 | ... = ... | variables.rs:514:21:516:3 | { ... } | | +| variables.rs:515:5:515:32 | ExprStmt | variables.rs:515:6:515:9 | self | | +| variables.rs:515:6:515:9 | self | variables.rs:515:5:515:9 | * ... | | +| variables.rs:515:13:515:31 | MyStruct {...} | variables.rs:515:5:515:31 | ... = ... | | +| variables.rs:515:29:515:29 | 3 | variables.rs:515:13:515:31 | MyStruct {...} | | +| variables.rs:519:1:524:1 | enter fn ref_methodcall_receiver | variables.rs:520:3:520:34 | let ... = ... | | +| variables.rs:519:1:524:1 | exit fn ref_methodcall_receiver (normal) | variables.rs:519:1:524:1 | exit fn ref_methodcall_receiver | | +| variables.rs:519:30:524:1 | { ... } | variables.rs:519:1:524:1 | exit fn ref_methodcall_receiver (normal) | | +| variables.rs:520:3:520:34 | let ... = ... | variables.rs:520:31:520:31 | 1 | | +| variables.rs:520:7:520:11 | a | variables.rs:521:3:521:10 | ExprStmt | match | +| variables.rs:520:15:520:33 | MyStruct {...} | variables.rs:520:7:520:11 | a | | +| variables.rs:520:31:520:31 | 1 | variables.rs:520:15:520:33 | MyStruct {...} | | +| variables.rs:521:3:521:3 | a | variables.rs:521:3:521:9 | ... .bar(...) | | +| variables.rs:521:3:521:9 | ... .bar(...) | variables.rs:523:3:523:19 | ExprStmt | | +| variables.rs:521:3:521:10 | ExprStmt | variables.rs:521:3:521:3 | a | | +| variables.rs:523:3:523:11 | print_i64 | variables.rs:523:13:523:13 | a | | +| variables.rs:523:3:523:18 | print_i64(...) | variables.rs:519:30:524:1 | { ... } | | +| variables.rs:523:3:523:19 | ExprStmt | variables.rs:523:3:523:11 | print_i64 | | +| variables.rs:523:13:523:13 | a | variables.rs:523:13:523:17 | a.val | | +| variables.rs:523:13:523:17 | a.val | variables.rs:523:3:523:18 | print_i64(...) | | +| variables.rs:526:1:560:1 | enter fn main | variables.rs:527:5:527:25 | ExprStmt | | +| variables.rs:526:1:560:1 | exit fn main (normal) | variables.rs:526:1:560:1 | exit fn main | | +| variables.rs:526:11:560:1 | { ... } | variables.rs:526:1:560:1 | exit fn main (normal) | | +| variables.rs:527:5:527:22 | immutable_variable | variables.rs:527:5:527:24 | immutable_variable(...) | | +| variables.rs:527:5:527:24 | immutable_variable(...) | variables.rs:528:5:528:23 | ExprStmt | | +| variables.rs:527:5:527:25 | ExprStmt | variables.rs:527:5:527:22 | immutable_variable | | +| variables.rs:528:5:528:20 | mutable_variable | variables.rs:528:5:528:22 | mutable_variable(...) | | +| variables.rs:528:5:528:22 | mutable_variable(...) | variables.rs:529:5:529:40 | ExprStmt | | +| variables.rs:528:5:528:23 | ExprStmt | variables.rs:528:5:528:20 | mutable_variable | | +| variables.rs:529:5:529:37 | mutable_variable_immutable_borrow | variables.rs:529:5:529:39 | mutable_variable_immutable_borrow(...) | | +| variables.rs:529:5:529:39 | mutable_variable_immutable_borrow(...) | variables.rs:530:5:530:23 | ExprStmt | | +| variables.rs:529:5:529:40 | ExprStmt | variables.rs:529:5:529:37 | mutable_variable_immutable_borrow | | +| variables.rs:530:5:530:20 | variable_shadow1 | variables.rs:530:5:530:22 | variable_shadow1(...) | | +| variables.rs:530:5:530:22 | variable_shadow1(...) | variables.rs:531:5:531:23 | ExprStmt | | +| variables.rs:530:5:530:23 | ExprStmt | variables.rs:530:5:530:20 | variable_shadow1 | | +| variables.rs:531:5:531:20 | variable_shadow2 | variables.rs:531:5:531:22 | variable_shadow2(...) | | +| variables.rs:531:5:531:22 | variable_shadow2(...) | variables.rs:532:5:532:19 | ExprStmt | | +| variables.rs:531:5:531:23 | ExprStmt | variables.rs:531:5:531:20 | variable_shadow2 | | +| variables.rs:532:5:532:16 | let_pattern1 | variables.rs:532:5:532:18 | let_pattern1(...) | | +| variables.rs:532:5:532:18 | let_pattern1(...) | variables.rs:533:5:533:19 | ExprStmt | | +| variables.rs:532:5:532:19 | ExprStmt | variables.rs:532:5:532:16 | let_pattern1 | | +| variables.rs:533:5:533:16 | let_pattern2 | variables.rs:533:5:533:18 | let_pattern2(...) | | +| variables.rs:533:5:533:18 | let_pattern2(...) | variables.rs:534:5:534:19 | ExprStmt | | +| variables.rs:533:5:533:19 | ExprStmt | variables.rs:533:5:533:16 | let_pattern2 | | +| variables.rs:534:5:534:16 | let_pattern3 | variables.rs:534:5:534:18 | let_pattern3(...) | | +| variables.rs:534:5:534:18 | let_pattern3(...) | variables.rs:535:5:535:19 | ExprStmt | | +| variables.rs:534:5:534:19 | ExprStmt | variables.rs:534:5:534:16 | let_pattern3 | | +| variables.rs:535:5:535:16 | let_pattern4 | variables.rs:535:5:535:18 | let_pattern4(...) | | +| variables.rs:535:5:535:18 | let_pattern4(...) | variables.rs:536:5:536:21 | ExprStmt | | +| variables.rs:535:5:535:19 | ExprStmt | variables.rs:535:5:535:16 | let_pattern4 | | +| variables.rs:536:5:536:18 | match_pattern1 | variables.rs:536:5:536:20 | match_pattern1(...) | | +| variables.rs:536:5:536:20 | match_pattern1(...) | variables.rs:537:5:537:21 | ExprStmt | | +| variables.rs:536:5:536:21 | ExprStmt | variables.rs:536:5:536:18 | match_pattern1 | | +| variables.rs:537:5:537:18 | match_pattern2 | variables.rs:537:5:537:20 | match_pattern2(...) | | +| variables.rs:537:5:537:20 | match_pattern2(...) | variables.rs:538:5:538:21 | ExprStmt | | +| variables.rs:537:5:537:21 | ExprStmt | variables.rs:537:5:537:18 | match_pattern2 | | +| variables.rs:538:5:538:18 | match_pattern3 | variables.rs:538:5:538:20 | match_pattern3(...) | | +| variables.rs:538:5:538:20 | match_pattern3(...) | variables.rs:539:5:539:21 | ExprStmt | | +| variables.rs:538:5:538:21 | ExprStmt | variables.rs:538:5:538:18 | match_pattern3 | | +| variables.rs:539:5:539:18 | match_pattern4 | variables.rs:539:5:539:20 | match_pattern4(...) | | +| variables.rs:539:5:539:20 | match_pattern4(...) | variables.rs:540:5:540:21 | ExprStmt | | +| variables.rs:539:5:539:21 | ExprStmt | variables.rs:539:5:539:18 | match_pattern4 | | +| variables.rs:540:5:540:18 | match_pattern5 | variables.rs:540:5:540:20 | match_pattern5(...) | | +| variables.rs:540:5:540:20 | match_pattern5(...) | variables.rs:541:5:541:21 | ExprStmt | | +| variables.rs:540:5:540:21 | ExprStmt | variables.rs:540:5:540:18 | match_pattern5 | | +| variables.rs:541:5:541:18 | match_pattern6 | variables.rs:541:5:541:20 | match_pattern6(...) | | +| variables.rs:541:5:541:20 | match_pattern6(...) | variables.rs:542:5:542:21 | ExprStmt | | +| variables.rs:541:5:541:21 | ExprStmt | variables.rs:541:5:541:18 | match_pattern6 | | +| variables.rs:542:5:542:18 | match_pattern7 | variables.rs:542:5:542:20 | match_pattern7(...) | | +| variables.rs:542:5:542:20 | match_pattern7(...) | variables.rs:543:5:543:21 | ExprStmt | | +| variables.rs:542:5:542:21 | ExprStmt | variables.rs:542:5:542:18 | match_pattern7 | | +| variables.rs:543:5:543:18 | match_pattern8 | variables.rs:543:5:543:20 | match_pattern8(...) | | +| variables.rs:543:5:543:20 | match_pattern8(...) | variables.rs:544:5:544:21 | ExprStmt | | +| variables.rs:543:5:543:21 | ExprStmt | variables.rs:543:5:543:18 | match_pattern8 | | +| variables.rs:544:5:544:18 | match_pattern9 | variables.rs:544:5:544:20 | match_pattern9(...) | | +| variables.rs:544:5:544:20 | match_pattern9(...) | variables.rs:545:5:545:36 | ExprStmt | | +| variables.rs:544:5:544:21 | ExprStmt | variables.rs:544:5:544:18 | match_pattern9 | | +| variables.rs:545:5:545:18 | param_pattern1 | variables.rs:545:20:545:22 | "a" | | +| variables.rs:545:5:545:35 | param_pattern1(...) | variables.rs:546:5:546:37 | ExprStmt | | +| variables.rs:545:5:545:36 | ExprStmt | variables.rs:545:5:545:18 | param_pattern1 | | +| variables.rs:545:20:545:22 | "a" | variables.rs:545:26:545:28 | "b" | | +| variables.rs:545:25:545:34 | TupleExpr | variables.rs:545:5:545:35 | param_pattern1(...) | | +| variables.rs:545:26:545:28 | "b" | variables.rs:545:31:545:33 | "c" | | +| variables.rs:545:31:545:33 | "c" | variables.rs:545:25:545:34 | TupleExpr | | +| variables.rs:546:5:546:18 | param_pattern2 | variables.rs:546:20:546:31 | ...::Left | | +| variables.rs:546:5:546:36 | param_pattern2(...) | variables.rs:547:5:547:26 | ExprStmt | | +| variables.rs:546:5:546:37 | ExprStmt | variables.rs:546:5:546:18 | param_pattern2 | | +| variables.rs:546:20:546:31 | ...::Left | variables.rs:546:33:546:34 | 45 | | +| variables.rs:546:20:546:35 | ...::Left(...) | variables.rs:546:5:546:36 | param_pattern2(...) | | +| variables.rs:546:33:546:34 | 45 | variables.rs:546:20:546:35 | ...::Left(...) | | +| variables.rs:547:5:547:23 | destruct_assignment | variables.rs:547:5:547:25 | destruct_assignment(...) | | +| variables.rs:547:5:547:25 | destruct_assignment(...) | variables.rs:548:5:548:23 | ExprStmt | | +| variables.rs:547:5:547:26 | ExprStmt | variables.rs:547:5:547:23 | destruct_assignment | | +| variables.rs:548:5:548:20 | closure_variable | variables.rs:548:5:548:22 | closure_variable(...) | | +| variables.rs:548:5:548:22 | closure_variable(...) | variables.rs:549:5:549:19 | ExprStmt | | +| variables.rs:548:5:548:23 | ExprStmt | variables.rs:548:5:548:20 | closure_variable | | +| variables.rs:549:5:549:16 | for_variable | variables.rs:549:5:549:18 | for_variable(...) | | +| variables.rs:549:5:549:18 | for_variable(...) | variables.rs:550:5:550:17 | ExprStmt | | +| variables.rs:549:5:549:19 | ExprStmt | variables.rs:549:5:549:16 | for_variable | | +| variables.rs:550:5:550:14 | add_assign | variables.rs:550:5:550:16 | add_assign(...) | | +| variables.rs:550:5:550:16 | add_assign(...) | variables.rs:551:5:551:13 | ExprStmt | | +| variables.rs:550:5:550:17 | ExprStmt | variables.rs:550:5:550:14 | add_assign | | +| variables.rs:551:5:551:10 | mutate | variables.rs:551:5:551:12 | mutate(...) | | +| variables.rs:551:5:551:12 | mutate(...) | variables.rs:552:5:552:17 | ExprStmt | | +| variables.rs:551:5:551:13 | ExprStmt | variables.rs:551:5:551:10 | mutate | | +| variables.rs:552:5:552:14 | mutate_arg | variables.rs:552:5:552:16 | mutate_arg(...) | | +| variables.rs:552:5:552:16 | mutate_arg(...) | variables.rs:553:5:553:12 | ExprStmt | | +| variables.rs:552:5:552:17 | ExprStmt | variables.rs:552:5:552:14 | mutate_arg | | +| variables.rs:553:5:553:9 | alias | variables.rs:553:5:553:11 | alias(...) | | +| variables.rs:553:5:553:11 | alias(...) | variables.rs:554:5:554:18 | ExprStmt | | +| variables.rs:553:5:553:12 | ExprStmt | variables.rs:553:5:553:9 | alias | | +| variables.rs:554:5:554:15 | capture_mut | variables.rs:554:5:554:17 | capture_mut(...) | | +| variables.rs:554:5:554:17 | capture_mut(...) | variables.rs:555:5:555:20 | ExprStmt | | +| variables.rs:554:5:554:18 | ExprStmt | variables.rs:554:5:554:15 | capture_mut | | +| variables.rs:555:5:555:17 | capture_immut | variables.rs:555:5:555:19 | capture_immut(...) | | +| variables.rs:555:5:555:19 | capture_immut(...) | variables.rs:556:5:556:26 | ExprStmt | | +| variables.rs:555:5:555:20 | ExprStmt | variables.rs:555:5:555:17 | capture_immut | | +| variables.rs:556:5:556:23 | async_block_capture | variables.rs:556:5:556:25 | async_block_capture(...) | | +| variables.rs:556:5:556:25 | async_block_capture(...) | variables.rs:557:5:557:14 | ExprStmt | | +| variables.rs:556:5:556:26 | ExprStmt | variables.rs:556:5:556:23 | async_block_capture | | +| variables.rs:557:5:557:11 | structs | variables.rs:557:5:557:13 | structs(...) | | +| variables.rs:557:5:557:13 | structs(...) | variables.rs:558:5:558:14 | ExprStmt | | +| variables.rs:557:5:557:14 | ExprStmt | variables.rs:557:5:557:11 | structs | | +| variables.rs:558:5:558:11 | ref_arg | variables.rs:558:5:558:13 | ref_arg(...) | | +| variables.rs:558:5:558:13 | ref_arg(...) | variables.rs:559:5:559:30 | ExprStmt | | +| variables.rs:558:5:558:14 | ExprStmt | variables.rs:558:5:558:11 | ref_arg | | +| variables.rs:559:5:559:27 | ref_methodcall_receiver | variables.rs:559:5:559:29 | ref_methodcall_receiver(...) | | +| variables.rs:559:5:559:29 | ref_methodcall_receiver(...) | variables.rs:526:11:560:1 | { ... } | | +| variables.rs:559:5:559:30 | ExprStmt | variables.rs:559:5:559:27 | ref_methodcall_receiver | | breakTarget continueTarget diff --git a/rust/ql/test/library-tests/variables/Ssa.expected b/rust/ql/test/library-tests/variables/Ssa.expected index af3c96d9503..832b105837c 100644 --- a/rust/ql/test/library-tests/variables/Ssa.expected +++ b/rust/ql/test/library-tests/variables/Ssa.expected @@ -5,8 +5,8 @@ nonSsaVariable | variables.rs:379:13:379:13 | z | | variables.rs:392:13:392:13 | x | | variables.rs:426:13:426:13 | z | -| variables.rs:488:13:488:13 | a | -| variables.rs:516:11:516:11 | a | +| variables.rs:492:13:492:13 | a | +| variables.rs:520:11:520:11 | a | definition | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | @@ -134,8 +134,8 @@ definition | variables.rs:461:13:461:14 | b1 | variables.rs:461:13:461:14 | b1 | | variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:25 | b2 | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | -| variables.rs:497:9:497:9 | x | variables.rs:497:9:497:9 | x | -| variables.rs:501:9:501:9 | z | variables.rs:501:9:501:9 | z | +| variables.rs:501:9:501:9 | x | variables.rs:501:9:501:9 | x | +| variables.rs:505:9:505:9 | z | variables.rs:505:9:505:9 | z | read | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i | @@ -257,7 +257,7 @@ read | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:466:19:466:19 | x | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:470:19:470:19 | x | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:472:19:472:19 | x | -| variables.rs:497:9:497:9 | x | variables.rs:497:9:497:9 | x | variables.rs:499:15:499:15 | x | +| variables.rs:501:9:501:9 | x | variables.rs:501:9:501:9 | x | variables.rs:503:15:503:15 | x | firstRead | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i | @@ -356,7 +356,7 @@ firstRead | variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:25 | b2 | variables.rs:469:8:469:9 | b2 | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:464:19:464:19 | x | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:466:19:466:19 | x | -| variables.rs:497:9:497:9 | x | variables.rs:497:9:497:9 | x | variables.rs:499:15:499:15 | x | +| variables.rs:501:9:501:9 | x | variables.rs:501:9:501:9 | x | variables.rs:503:15:503:15 | x | lastRead | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i | @@ -456,7 +456,7 @@ lastRead | variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:25 | b2 | variables.rs:469:8:469:9 | b2 | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:470:19:470:19 | x | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:472:19:472:19 | x | -| variables.rs:497:9:497:9 | x | variables.rs:497:9:497:9 | x | variables.rs:499:15:499:15 | x | +| variables.rs:501:9:501:9 | x | variables.rs:501:9:501:9 | x | variables.rs:503:15:503:15 | x | adjacentReads | variables.rs:35:9:35:10 | x3 | variables.rs:35:9:35:10 | x3 | variables.rs:36:15:36:16 | x3 | variables.rs:38:9:38:10 | x3 | | variables.rs:43:9:43:10 | x4 | variables.rs:43:9:43:10 | x4 | variables.rs:44:15:44:16 | x4 | variables.rs:49:15:49:16 | x4 | diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index d888734f3dc..df9cc5e1644 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -95,10 +95,10 @@ variable | variables.rs:461:13:461:14 | b1 | | variables.rs:461:24:461:25 | b2 | | variables.rs:462:9:462:9 | x | -| variables.rs:488:13:488:13 | a | -| variables.rs:497:9:497:9 | x | -| variables.rs:501:9:501:9 | z | -| variables.rs:516:11:516:11 | a | +| variables.rs:492:13:492:13 | a | +| variables.rs:501:9:501:9 | x | +| variables.rs:505:9:505:9 | z | +| variables.rs:520:11:520:11 | a | variableAccess | variables.rs:4:20:4:20 | s | variables.rs:3:14:3:14 | s | | variables.rs:8:20:8:20 | i | variables.rs:7:14:7:14 | i | @@ -246,16 +246,16 @@ variableAccess | variables.rs:469:8:469:9 | b2 | variables.rs:461:24:461:25 | b2 | | variables.rs:470:19:470:19 | x | variables.rs:462:9:462:9 | x | | variables.rs:472:19:472:19 | x | variables.rs:462:9:462:9 | x | -| variables.rs:489:15:489:15 | a | variables.rs:488:13:488:13 | a | -| variables.rs:490:5:490:5 | a | variables.rs:488:13:488:13 | a | -| variables.rs:491:15:491:15 | a | variables.rs:488:13:488:13 | a | -| variables.rs:492:5:492:5 | a | variables.rs:488:13:488:13 | a | -| variables.rs:493:15:493:15 | a | variables.rs:488:13:488:13 | a | -| variables.rs:498:20:498:20 | x | variables.rs:497:9:497:9 | x | -| variables.rs:499:15:499:15 | x | variables.rs:497:9:497:9 | x | -| variables.rs:502:20:502:20 | z | variables.rs:501:9:501:9 | z | -| variables.rs:517:3:517:3 | a | variables.rs:516:11:516:11 | a | -| variables.rs:519:13:519:13 | a | variables.rs:516:11:516:11 | a | +| variables.rs:493:15:493:15 | a | variables.rs:492:13:492:13 | a | +| variables.rs:494:5:494:5 | a | variables.rs:492:13:492:13 | a | +| variables.rs:495:15:495:15 | a | variables.rs:492:13:492:13 | a | +| variables.rs:496:5:496:5 | a | variables.rs:492:13:492:13 | a | +| variables.rs:497:15:497:15 | a | variables.rs:492:13:492:13 | a | +| variables.rs:502:20:502:20 | x | variables.rs:501:9:501:9 | x | +| variables.rs:503:15:503:15 | x | variables.rs:501:9:501:9 | x | +| variables.rs:506:20:506:20 | z | variables.rs:505:9:505:9 | z | +| variables.rs:521:3:521:3 | a | variables.rs:520:11:520:11 | a | +| variables.rs:523:13:523:13 | a | variables.rs:520:11:520:11 | a | variableWriteAccess | variables.rs:23:5:23:6 | x2 | variables.rs:21:13:21:14 | x2 | | variables.rs:30:5:30:5 | x | variables.rs:28:13:28:13 | x | @@ -266,7 +266,7 @@ variableWriteAccess | variables.rs:438:9:438:9 | i | variables.rs:436:13:436:13 | i | | variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x | | variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x | -| variables.rs:492:5:492:5 | a | variables.rs:488:13:488:13 | a | +| variables.rs:496:5:496:5 | a | variables.rs:492:13:492:13 | a | variableReadAccess | variables.rs:4:20:4:20 | s | variables.rs:3:14:3:14 | s | | variables.rs:8:20:8:20 | i | variables.rs:7:14:7:14 | i | @@ -396,13 +396,13 @@ variableReadAccess | variables.rs:469:8:469:9 | b2 | variables.rs:461:24:461:25 | b2 | | variables.rs:470:19:470:19 | x | variables.rs:462:9:462:9 | x | | variables.rs:472:19:472:19 | x | variables.rs:462:9:462:9 | x | -| variables.rs:489:15:489:15 | a | variables.rs:488:13:488:13 | a | -| variables.rs:490:5:490:5 | a | variables.rs:488:13:488:13 | a | -| variables.rs:491:15:491:15 | a | variables.rs:488:13:488:13 | a | -| variables.rs:493:15:493:15 | a | variables.rs:488:13:488:13 | a | -| variables.rs:499:15:499:15 | x | variables.rs:497:9:497:9 | x | -| variables.rs:517:3:517:3 | a | variables.rs:516:11:516:11 | a | -| variables.rs:519:13:519:13 | a | variables.rs:516:11:516:11 | a | +| variables.rs:493:15:493:15 | a | variables.rs:492:13:492:13 | a | +| variables.rs:494:5:494:5 | a | variables.rs:492:13:492:13 | a | +| variables.rs:495:15:495:15 | a | variables.rs:492:13:492:13 | a | +| variables.rs:497:15:497:15 | a | variables.rs:492:13:492:13 | a | +| variables.rs:503:15:503:15 | x | variables.rs:501:9:501:9 | x | +| variables.rs:521:3:521:3 | a | variables.rs:520:11:520:11 | a | +| variables.rs:523:13:523:13 | a | variables.rs:520:11:520:11 | a | variableInitializer | variables.rs:16:9:16:10 | x1 | variables.rs:16:14:16:16 | "a" | | variables.rs:21:13:21:14 | x2 | variables.rs:21:18:21:18 | 4 | @@ -450,10 +450,10 @@ variableInitializer | variables.rs:437:9:437:13 | block | variables.rs:437:17:439:5 | { ... } | | variables.rs:446:13:446:13 | x | variables.rs:446:17:446:17 | 1 | | variables.rs:462:9:462:9 | x | variables.rs:462:13:462:13 | 1 | -| variables.rs:488:13:488:13 | a | variables.rs:488:17:488:35 | MyStruct {...} | -| variables.rs:497:9:497:9 | x | variables.rs:497:13:497:14 | 16 | -| variables.rs:501:9:501:9 | z | variables.rs:501:13:501:14 | 17 | -| variables.rs:516:11:516:11 | a | variables.rs:516:15:516:33 | MyStruct {...} | +| variables.rs:492:13:492:13 | a | variables.rs:492:17:492:35 | MyStruct {...} | +| variables.rs:501:9:501:9 | x | variables.rs:501:13:501:14 | 16 | +| variables.rs:505:9:505:9 | z | variables.rs:505:13:505:14 | 17 | +| variables.rs:520:11:520:11 | a | variables.rs:520:15:520:33 | MyStruct {...} | capturedVariable | variables.rs:400:9:400:9 | x | | variables.rs:410:13:410:13 | x | diff --git a/rust/ql/test/library-tests/variables/variables.rs b/rust/ql/test/library-tests/variables/variables.rs index 8dd00c7ebb2..40f26ab0fc8 100644 --- a/rust/ql/test/library-tests/variables/variables.rs +++ b/rust/ql/test/library-tests/variables/variables.rs @@ -117,7 +117,7 @@ fn match_pattern1() { => { print_i64(y1)// $ read_access=y1_2 - } + } None => print_str("NONE"), } @@ -480,7 +480,11 @@ struct MyStruct { impl MyStruct { fn my_get(&mut self) -> i64 { - return self.val; + return self.val; // $ MISSING: read_access=self + } + + fn id(self) -> Self { + self // $ MISSING: read_access=self } } @@ -508,7 +512,7 @@ trait Bar { impl MyStruct { fn bar(&mut self) { - *self = MyStruct { val: 3 }; + *self = MyStruct { val: 3 }; // MISSING: $ read_access=self } } From 261e0a1a537b0c174638dd92d32c1d273ed009e0 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 25 Nov 2024 17:01:21 +0100 Subject: [PATCH 233/470] Codegen/Rust: allow renaming in QL This adds a `ql.name` codegen pragma to change the name of a property on the QL side. This is useful to give more meaningful names than what we get from the generated rust AST. --- misc/codegen/generators/qlgen.py | 13 +++++---- misc/codegen/lib/schemadefs.py | 27 ++++++++----------- rust/ql/.generated.list | 12 ++++----- rust/ql/.gitattributes | 2 +- .../internal/ControlFlowGraphImpl.qll | 6 ++--- .../internal/generated/CfgNodes.qll | 16 +++++------ .../elements/internal/generated/MatchExpr.qll | 10 ++++--- .../internal/generated/ParentChild.qll | 12 +++++---- .../rust/elements/internal/generated/Raw.qll | 2 +- .../generated/MatchExpr/MatchExpr.expected | 4 +-- .../generated/MatchExpr/MatchExpr.ql | 8 +++--- .../MatchExpr/MatchExpr_getMatched.expected | 2 ++ ...getExpr.ql => MatchExpr_getMatchedExpr.ql} | 2 +- rust/schema/annotations.py | 1 + 14 files changed, 61 insertions(+), 56 deletions(-) create mode 100644 rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatched.expected rename rust/ql/test/extractor-tests/generated/MatchExpr/{MatchExpr_getExpr.ql => MatchExpr_getMatchedExpr.ql} (83%) diff --git a/misc/codegen/generators/qlgen.py b/misc/codegen/generators/qlgen.py index f1a68f6bc01..e42c9d01552 100755 --- a/misc/codegen/generators/qlgen.py +++ b/misc/codegen/generators/qlgen.py @@ -118,17 +118,18 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic type_is_hideable="ql_hideable" in lookup[prop.type].pragmas if prop.type in lookup else False, internal="ql_internal" in prop.pragmas, ) + ql_name = prop.pragmas.get("ql_name", prop.name) if prop.is_single: args.update( - singular=inflection.camelize(prop.name), + singular=inflection.camelize(ql_name), tablename=inflection.tableize(cls.name), tableparams=["this"] + ["result" if p is prop else "_" for p in cls.properties if p.is_single], doc=_get_doc(cls, prop), ) elif prop.is_repeated: args.update( - singular=inflection.singularize(inflection.camelize(prop.name)), - plural=inflection.pluralize(inflection.camelize(prop.name)), + singular=inflection.singularize(inflection.camelize(ql_name)), + plural=inflection.pluralize(inflection.camelize(ql_name)), tablename=inflection.tableize(f"{cls.name}_{prop.name}"), tableparams=["this", "index", "result"] if not prop.is_unordered else ["this", "result"], doc=_get_doc(cls, prop, plural=False), @@ -136,14 +137,14 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic ) elif prop.is_optional: args.update( - singular=inflection.camelize(prop.name), + singular=inflection.camelize(ql_name), tablename=inflection.tableize(f"{cls.name}_{prop.name}"), tableparams=["this", "result"], doc=_get_doc(cls, prop), ) elif prop.is_predicate: args.update( - singular=inflection.camelize(prop.name, uppercase_first_letter=False), + singular=inflection.camelize(ql_name, uppercase_first_letter=False), tablename=inflection.underscore(f"{cls.name}_{prop.name}"), tableparams=["this"], doc=_get_doc(cls, prop), @@ -154,6 +155,8 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic def get_ql_class(cls: schema.Class, lookup: typing.Dict[str, schema.Class]) -> ql.Class: + if "ql_name" in cls.pragmas: + raise Error("ql_name is not supported yet for classes, only for properties") prev_child = "" properties = [] for p in cls.properties: diff --git a/misc/codegen/lib/schemadefs.py b/misc/codegen/lib/schemadefs.py index 32d3a6b85ae..8651240c1a3 100644 --- a/misc/codegen/lib/schemadefs.py +++ b/misc/codegen/lib/schemadefs.py @@ -72,11 +72,11 @@ def include(source: str): @_dataclass class _Namespace: """ simple namespacing mechanism """ - name: str + _name: str def add(self, pragma: "_PragmaBase", key: str | None = None): self.__dict__[pragma.pragma] = pragma - pragma.pragma = key or f"{self.name}_{pragma.pragma}" + pragma.pragma = key or f"{self._name}_{pragma.pragma}" @_dataclass @@ -87,7 +87,7 @@ class _SynthModifier(_schema.PropertyModifier, _Namespace): prop.synth = self.synth def negate(self) -> _schema.PropertyModifier: - return _SynthModifier(self.name, False) + return _SynthModifier(self._name, False) qltest = _Namespace("qltest") @@ -239,6 +239,7 @@ qltest.add(_ParametrizedClassPragma("test_with", inherited=True, factory=_schema ql.add(_ParametrizedClassPragma("default_doc_name", factory=lambda doc: doc)) ql.add(_ClassPragma("hideable", inherited=True)) ql.add(_Pragma("internal")) +ql.add(_ParametrizedPragma("name", factory=lambda name: name)) cpp.add(_Pragma("skip")) @@ -256,30 +257,24 @@ synth.add(_ParametrizedClassPragma("on_arguments", factory=lambda **kwargs: _schema.SynthInfo(on_arguments={k: _schema.get_type_name(t) for k, t in kwargs.items()})), key="synth") +@_dataclass(frozen=True) class _PropertyModifierList(_schema.PropertyModifier): - def __init__(self): - self._mods = [] + _mods: tuple[_schema.PropertyModifier, ...] def __or__(self, other: _schema.PropertyModifier): - self._mods.append(other) - return self + return _PropertyModifierList(self._mods + (other,)) def modify(self, prop: Property): for m in self._mods: m.modify(prop) -class _PropertyAnnotation: - def __or__(self, other: _schema.PropertyModifier): - return _PropertyModifierList() | other - - -_ = _PropertyAnnotation() +_ = _PropertyModifierList(()) drop = object() -def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, replace_bases: _Dict[type, type] | None = None, cfg: bool = False) -> _Callable[[type], _PropertyAnnotation]: +def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, replace_bases: _Dict[type, type] | None = None, cfg: bool = False) -> _Callable[[type], _PropertyModifierList]: """ Add or modify schema annotations after a class has been defined previously. @@ -287,7 +282,7 @@ def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, repl `replace_bases` can be used to replace bases on the annotated class. """ - def decorator(cls: type) -> _PropertyAnnotation: + def decorator(cls: type) -> _PropertyModifierList: if cls.__name__ != "_": raise _schema.Error("Annotation classes must be named _") if cls.__doc__ is not None: @@ -307,7 +302,7 @@ def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, repl del annotated_cls.__annotations__[p] elif p in annotated_cls.__annotations__: annotated_cls.__annotations__[p] |= a - elif isinstance(a, (_PropertyAnnotation, _PropertyModifierList)): + elif isinstance(a, (_PropertyModifierList, _PropertyModifierList)): raise _schema.Error(f"annotated property {p} not present in annotated class " f"{annotated_cls.__name__}") else: diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 913bdf1d293..041e1a565b2 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -1,4 +1,4 @@ -lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll e1d6ad3a582c15addb042ce1e054a916f81030f7a10a69408ab929679e9a92ad f1837efe28fb1ae5162437a482d35d24a792e133e10879284202c45e90c62ff6 +lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll c0438ab3e984fbf7ce2cc4ac64aafa115f36f2be700a819fd81f15d777f363b6 bc57c07b7f9472156cff3f878459872255c7ee4ba0767258129d0258789f98df lib/codeql/rust/elements/Abi.qll 4c973d28b6d628f5959d1f1cc793704572fd0acaae9a97dfce82ff9d73f73476 250f68350180af080f904cd34cb2af481c5c688dc93edf7365fd0ae99855e893 lib/codeql/rust/elements/ArgList.qll 661f5100f5d3ef8351452d9058b663a2a5c720eea8cf11bedd628969741486a2 28e424aac01a90fb58cd6f9f83c7e4cf379eea39e636bc0ba07efc818be71c71 lib/codeql/rust/elements/ArrayExpr.qll a3e6e122632f4011644ec31b37f88b32fe3f2b7e388e7e878a6883309937049f 12ccb5873d95c433da5606fd371d182ef2f71b78d0c53c2d6dec10fa45852bdc @@ -495,7 +495,7 @@ lib/codeql/rust/elements/internal/generated/MacroStmts.qll cb4f3c2721a4d0c8522e5 lib/codeql/rust/elements/internal/generated/MacroType.qll c462824df4a002956c036966d15cd0bce206e664888f8d0c7834dedb38b3c0bf 947480f07c40128ef3d00ad4c3a29a685472b3e20a661680c22f6bb318205ed1 lib/codeql/rust/elements/internal/generated/MatchArm.qll 8fb740a0f2e308782d9cf390672969cd7cf6e698e5b847fb02ae3fa6c205646f 42bfe8dd94fc24ec925fbd44016df111600f99d1216c9a698631373bb6048830 lib/codeql/rust/elements/internal/generated/MatchArmList.qll 13362680c037fe83fef4653562cc10a4429078316b5ec7c47b076336cf4aca2e 41c674293c13eceaca62134ae0c6778541f6a5201cbc5c146f0ba01b898dc267 -lib/codeql/rust/elements/internal/generated/MatchExpr.qll 689d65f690fe05bc262d0a5bfe69bb4f8a142db387c5765fcc4958a9b49989f8 2979cd2017d0538870d17b2b7592c75cc05b706bd36c9de3e5dc38fa3a957e5b +lib/codeql/rust/elements/internal/generated/MatchExpr.qll e1e5bf4623511028a6c2ebc6bb6e3c18ec9fe4f49ef4cd8654e5dc376121088d c0760592040b2df9a571cd766397a0f9c68684d24d72780756cae7a1878d102a lib/codeql/rust/elements/internal/generated/MatchGuard.qll 521a507883963106780f1782084c581fbcf1179863c7c15438c4db79e30e78dd 6226feffaaa8d828a42ece0c693e616cd375672eb987c3b7ff1ca15fa23c116a lib/codeql/rust/elements/internal/generated/Meta.qll 38fca2c9958b4179de311546fe0850319010aca9cd17c97d57e12b521c5d0947 740f99c9d41044ceebfcc9d29baaa22f59c11a40f45502a34aa587d423c018f8 lib/codeql/rust/elements/internal/generated/MethodCallExpr.qll 17bffcc826851a8be32a1900b8fdf777f9bab6aed9f8268d566173c4974c1cf9 134a2860bdf16daafdb3e574c52a69d2598210653db89c2fa062ca25e8f8a649 @@ -512,7 +512,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60 lib/codeql/rust/elements/internal/generated/ParenPat.qll ce24b8f8ecbf0f204af200317405724063887257460c80cf250c39b2fdf37185 e7c87d37e1a0ca7ea03840017e1aa9ddb7f927f1f3b6396c0305b46aeee33db6 lib/codeql/rust/elements/internal/generated/ParenType.qll 9cc954d73f8330dcac7b475f97748b63af5c8766dee9d2f2872c0a7e4c903537 c07534c8a9c683c4a9b11d490095647e420de0a0bfc23273eaf6f31b00244273 -lib/codeql/rust/elements/internal/generated/ParentChild.qll ae0288399423b8b69a98a520ff4d2cb53d15ec404696cf62b0ceea965e2258ba aed73c416d74b504c02ee2e9bc2a72881d851ad0819b331b59728a4084e14fdd +lib/codeql/rust/elements/internal/generated/ParentChild.qll a19adfe192c88023b77f938d91f8539df6e42fa14172389537069decfe8baa7d 6be35ca8755d80c0365eeb9ecc51982fb0e24d2ed53ec6b17a15da4af6fbe6e6 lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4 lib/codeql/rust/elements/internal/generated/Path.qll 4c1c8e840ed57880e574142b081b11d7a7428a009f10e3aa8f4645e211f6b2e0 989668cf0f1bdee7557e2f97c01e41d2a56848227fed41477833f5fc1e1d35f6 lib/codeql/rust/elements/internal/generated/PathExpr.qll 2096e3c1db22ee488a761690adabfc9cfdea501c99f7c5d96c0019cb113fc506 54245ce0449c4e263173213df01e079d5168a758503a5dbd61b25ad35a311140 @@ -525,7 +525,7 @@ lib/codeql/rust/elements/internal/generated/PtrType.qll 40099c5a4041314b66932dfd lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll efd93730de217cf50dcba5875595263a5eadf9f7e4e1272401342a094d158614 229b251b3d118932e31e78ac4dfb75f48b766f240f20d436062785606d44467b -lib/codeql/rust/elements/internal/generated/Raw.qll ee5642a7a5ad75f48d4db10eccb197b1a11db2fc3432cf2e24a8bcbe83a474e2 134f2e0c87039d052dd31991017fb35597f37f28879abd702b62ec1d880118c6 +lib/codeql/rust/elements/internal/generated/Raw.qll f1af475812318f9fbfd1731a1e97ae77783bcc8a7ad45463cd9916e4c46e783a 1e06a7cd87c4c704f76bbc70ba3d7601ca6f1b3dd11f124ee448d8b834f7ce55 lib/codeql/rust/elements/internal/generated/RecordExpr.qll eb6cb662e463f9260efae1a6ce874fa781172063b916ef1963f861e9942d308d 1a21cbccc8f3799ff13281e822818ebfb21d81591720a427cac3625512cb9d40 lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1 lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0 @@ -845,10 +845,10 @@ test/extractor-tests/generated/MatchArm/MatchArm_getPat.ql b346bca229226414b32ac test/extractor-tests/generated/MatchArmList/MatchArmList.ql 14b5e110d48e2b77c85b7a188262e6a98300e0d4d507bb7ed9179c5802251dd6 4d091f06b12fef0fffe1c80a10f74438d8068f2fa09c50d5e240b6d140e60d90 test/extractor-tests/generated/MatchArmList/MatchArmList_getArm.ql 4781d002538a92b7f40fb0ec3d61aeedb6348341ddc354bbdd3ff61b74d59767 ae0da9497a30ce006e03bdb70e0ee24b685df529ac15a7d99a6869b5f7d7b371 test/extractor-tests/generated/MatchArmList/MatchArmList_getAttr.ql 4d7e6d152d2dbeb4c9f594becabea27d3b25fecbde40d791a2907c69cc0c9631 4be9be658bb22e1b764c4ebc8d6b99bf50fd939f35ea44fbb869056c14632bd4 -test/extractor-tests/generated/MatchExpr/MatchExpr.ql ec116bca37079488977a50beeba508c440cf337799947fcb810b6bd7a7605255 42dc7b5f0dd6fd91417d9846a7b4f678cbfcf095791aaf57c8d3b4548ce2dd98 +test/extractor-tests/generated/MatchExpr/MatchExpr.ql 22a3ace49ec98524388ccfb031c180eedc741cbc5b58a4815cc9e52fe292e6b3 5b56c71cbc02ac3aecfcbe93e7bbdb55727aae39d7949a7d8db3d6f93ea7ca80 test/extractor-tests/generated/MatchExpr/MatchExpr_getAttr.ql cb8057372dcf24dfa02896ebf4e60a0b757dc4742b94011edc38f5b898ed4d25 6809695c2d3ac3b92c06049c9b920e8c0e99ee1998a11a7f181f2b0ceb47c197 -test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.ql 7baaa64071cf2666e3b2bc05630d92a7a3b6cf04a026b1f7053c5e2a735bcaa8 d9ba8d8bbff05cfc0461ab41295f921b48429b4376c29adf54428bd5a9aa5298 test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchArmList.ql d97055bcb0431e8b258b5ecdd98aa07cb24ece06b0cd658b697cd71da4ede8fc 5e9c03b2665ef6b2af98897996abb2e0a9c18d54eb64588340b8efbcee9793bd +test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.ql 478585d26c2b301f474f04569deb79728c80b3f67fe5c2536b64f5a29dcccf30 750d24c48dc0f57992265c3fc60fbfa400263f58f74b7951774a383d3ae4ae0a test/extractor-tests/generated/MatchGuard/MatchGuard.ql 23e47ec1b13e2d80e31b57894a46ec789d6ab5ed1eb66bdb6bba9bd5ae71d3ef 7302f4a93108a83228e0ebd5b4a1bc6bccc1f6f0f3272054866fa90378c0dcc4 test/extractor-tests/generated/MatchGuard/MatchGuard_getCondition.ql 8a79dd46798f111f8d0d5a975380b5cebe5e337267752b77b3718b268ba2773d 6691d8fb483f64fc7e3ad3f46e3129e0a1184d7beb9f83a1000acdbb081c8b5e test/extractor-tests/generated/Meta/Meta.ql 16f163f00ba2bbaa0a8c6f3f6710c860a8f61d02d43321c78e05a10a3606e39b ba982c6bb93ddb4fc2c44d24635bd487128a5b1d1f885214044c989a21f4d05a diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index afb5cbf6c69..6b97bf45470 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -849,8 +849,8 @@ /test/extractor-tests/generated/MatchArmList/MatchArmList_getAttr.ql linguist-generated /test/extractor-tests/generated/MatchExpr/MatchExpr.ql linguist-generated /test/extractor-tests/generated/MatchExpr/MatchExpr_getAttr.ql linguist-generated -/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.ql linguist-generated /test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchArmList.ql linguist-generated +/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.ql linguist-generated /test/extractor-tests/generated/MatchGuard/MatchGuard.ql linguist-generated /test/extractor-tests/generated/MatchGuard/MatchGuard_getCondition.ql linguist-generated /test/extractor-tests/generated/Meta/Meta.ql linguist-generated diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index df43d450a50..42487f1689d 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -514,14 +514,14 @@ module ExprTrees { class MatchExprTree extends PostOrderTree instanceof MatchExpr { override predicate propagatesAbnormal(AstNode child) { - child = [super.getExpr(), super.getAnArm().getExpr()] + child = [super.getMatchedExpr(), super.getAnArm().getExpr()] } - override predicate first(AstNode node) { first(super.getExpr(), node) } + override predicate first(AstNode node) { first(super.getMatchedExpr(), node) } override predicate succ(AstNode pred, AstNode succ, Completion c) { // Edge from the scrutinee to the first arm or to the match expression if no arms. - last(super.getExpr(), pred, c) and + last(super.getMatchedExpr(), pred, c) and ( first(super.getArm(0).getPat(), succ) or diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll index 8038c0dcee1..aeebf92e02b 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll @@ -1709,7 +1709,7 @@ module MakeCfgNodes Input> { override predicate relevantChild(AstNode child) { none() or - child = this.getExpr() + child = this.getMatchedExpr() } } @@ -1754,14 +1754,14 @@ module MakeCfgNodes Input> { /** * Gets the expression of this match expression, if it exists. */ - ExprCfgNode getExpr() { - any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + ExprCfgNode getMatchedExpr() { + any(ChildMapping mapping).hasCfgChild(node, node.getMatchedExpr(), this, result) } /** - * Holds if `getExpr()` exists. + * Holds if `getMatchedExpr()` exists. */ - predicate hasExpr() { exists(this.getExpr()) } + predicate hasMatchedExpr() { exists(this.getMatchedExpr()) } /** * Gets the match arm list of this match expression, if it exists. @@ -3451,14 +3451,14 @@ module MakeCfgNodes Input> { cfgNode ) or - pred = "getExpr" and + pred = "getMatchedExpr" and parent = any(Nodes::MatchExprCfgNode cfgNode, MatchExpr astNode | astNode = cfgNode.getMatchExpr() and - child = getDesugared(astNode.getExpr()) and + child = getDesugared(astNode.getMatchedExpr()) and i = -1 and hasCfgNode(child) and - not child = cfgNode.getExpr().getAstNode() + not child = cfgNode.getMatchedExpr().getAstNode() | cfgNode ) diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/MatchExpr.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/MatchExpr.qll index 5b48d8e1854..5c2974c82fe 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/MatchExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/MatchExpr.qll @@ -57,15 +57,17 @@ module Generated { /** * Gets the expression of this match expression, if it exists. */ - Expr getExpr() { + Expr getMatchedExpr() { result = - Synth::convertExprFromRaw(Synth::convertMatchExprToRaw(this).(Raw::MatchExpr).getExpr()) + Synth::convertExprFromRaw(Synth::convertMatchExprToRaw(this) + .(Raw::MatchExpr) + .getMatchedExpr()) } /** - * Holds if `getExpr()` exists. + * Holds if `getMatchedExpr()` exists. */ - final predicate hasExpr() { exists(this.getExpr()) } + final predicate hasMatchedExpr() { exists(this.getMatchedExpr()) } /** * Gets the match arm list of this match expression, if it exists. diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll index 9f3bbfac30c..9dd9eff45eb 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll @@ -2030,13 +2030,13 @@ private module Impl { } private Element getImmediateChildOfMatchExpr(MatchExpr e, int index, string partialPredicateCall) { - exists(int b, int bExpr, int n, int nAttr, int nExpr, int nMatchArmList | + exists(int b, int bExpr, int n, int nAttr, int nMatchedExpr, int nMatchArmList | b = 0 and bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and n = bExpr and nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and - nExpr = nAttr + 1 and - nMatchArmList = nExpr + 1 and + nMatchedExpr = nAttr + 1 and + nMatchArmList = nMatchedExpr + 1 and ( none() or @@ -2045,9 +2045,11 @@ private module Impl { result = e.getAttr(index - n) and partialPredicateCall = "Attr(" + (index - n).toString() + ")" or - index = nAttr and result = e.getExpr() and partialPredicateCall = "Expr()" + index = nAttr and result = e.getMatchedExpr() and partialPredicateCall = "MatchedExpr()" or - index = nExpr and result = e.getMatchArmList() and partialPredicateCall = "MatchArmList()" + index = nMatchedExpr and + result = e.getMatchArmList() and + partialPredicateCall = "MatchArmList()" ) ) } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index 01d28fedd7c..b54d0cba583 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -2172,7 +2172,7 @@ module Raw { /** * Gets the expression of this match expression, if it exists. */ - Expr getExpr() { match_expr_exprs(this, result) } + Expr getMatchedExpr() { match_expr_exprs(this, result) } /** * Gets the match arm list of this match expression, if it exists. diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected index b98c3de696b..f57de7714ad 100644 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected @@ -1,2 +1,2 @@ -| gen_match_expr.rs:5:5:8:5 | match x { ... } | getNumberOfAttrs: | 0 | hasExpr: | yes | hasMatchArmList: | yes | -| gen_match_expr.rs:9:5:12:5 | match x { ... } | getNumberOfAttrs: | 0 | hasExpr: | yes | hasMatchArmList: | yes | +| gen_match_expr.rs:5:5:8:5 | match x { ... } | getNumberOfAttrs: | 0 | hasMatched: | yes | hasMatchArmList: | yes | +| gen_match_expr.rs:9:5:12:5 | match x { ... } | getNumberOfAttrs: | 0 | hasMatched: | yes | hasMatchArmList: | yes | diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.ql b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.ql index b29e333d330..e99d3c70e1b 100644 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.ql +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.ql @@ -2,12 +2,12 @@ import codeql.rust.elements import TestUtils -from MatchExpr x, int getNumberOfAttrs, string hasExpr, string hasMatchArmList +from MatchExpr x, int getNumberOfAttrs, string hasMatchedExpr, string hasMatchArmList where toBeTested(x) and not x.isUnknown() and getNumberOfAttrs = x.getNumberOfAttrs() and - (if x.hasExpr() then hasExpr = "yes" else hasExpr = "no") and + (if x.hasMatchedExpr() then hasMatchedExpr = "yes" else hasMatchedExpr = "no") and if x.hasMatchArmList() then hasMatchArmList = "yes" else hasMatchArmList = "no" -select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasExpr:", hasExpr, "hasMatchArmList:", - hasMatchArmList +select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasMatchedExpr:", hasMatchedExpr, + "hasMatchArmList:", hasMatchArmList diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatched.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatched.expected new file mode 100644 index 00000000000..427af7c6ed0 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatched.expected @@ -0,0 +1,2 @@ +| gen_match_expr.rs:5:5:8:5 | match x { ... } | gen_match_expr.rs:5:11:5:11 | x | +| gen_match_expr.rs:9:5:12:5 | match x { ... } | gen_match_expr.rs:9:11:9:11 | x | diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.ql b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.ql similarity index 83% rename from rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.ql rename to rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.ql index 40dd65afcbc..0a7bb7ae332 100644 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.ql +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.ql @@ -4,4 +4,4 @@ import TestUtils from MatchExpr x where toBeTested(x) and not x.isUnknown() -select x, x.getExpr() +select x, x.getMatchedExpr() diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index e2ab1bf8e56..b93151fec33 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -289,6 +289,7 @@ class _: } ``` """ + expr: _ | ql.name("matched_expr") @annotate(ContinueExpr, cfg = True) From b47e9612eb61ce052915fc6a7dc58af144806e46 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 25 Nov 2024 17:14:05 +0100 Subject: [PATCH 234/470] Rust: fix `MatchExpr.getExpr` renaming --- rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll | 2 +- .../extractor-tests/generated/MatchExpr/MatchExpr.expected | 4 ++-- .../generated/MatchExpr/MatchExpr_getMatchedExpr.expected | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.expected diff --git a/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll index 3ce9aa77310..445c4c86945 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll @@ -29,7 +29,7 @@ module Impl { */ class MatchExpr extends Generated::MatchExpr { override string toString() { - result = "match " + this.getExpr().toAbbreviatedString() + " { ... }" + result = "match " + this.getMatchedExpr().toAbbreviatedString() + " { ... }" } /** diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected index f57de7714ad..68912b3f01a 100644 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected @@ -1,2 +1,2 @@ -| gen_match_expr.rs:5:5:8:5 | match x { ... } | getNumberOfAttrs: | 0 | hasMatched: | yes | hasMatchArmList: | yes | -| gen_match_expr.rs:9:5:12:5 | match x { ... } | getNumberOfAttrs: | 0 | hasMatched: | yes | hasMatchArmList: | yes | +| gen_match_expr.rs:5:5:8:5 | match x { ... } | getNumberOfAttrs: | 0 | hasMatchedExpr: | yes | hasMatchArmList: | yes | +| gen_match_expr.rs:9:5:12:5 | match x { ... } | getNumberOfAttrs: | 0 | hasMatchedExpr: | yes | hasMatchArmList: | yes | diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.expected new file mode 100644 index 00000000000..427af7c6ed0 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.expected @@ -0,0 +1,2 @@ +| gen_match_expr.rs:5:5:8:5 | match x { ... } | gen_match_expr.rs:5:11:5:11 | x | +| gen_match_expr.rs:9:5:12:5 | match x { ... } | gen_match_expr.rs:9:11:9:11 | x | From 269ea7503679db9fe16df6dd74619c69dce9eac5 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 25 Nov 2024 17:21:19 +0100 Subject: [PATCH 235/470] Rust: `matched_expr` -> `scrutinee` --- rust/ql/.generated.list | 12 ++++++------ rust/ql/.gitattributes | 2 +- .../internal/ControlFlowGraphImpl.qll | 6 +++--- .../internal/generated/CfgNodes.qll | 18 +++++++++--------- .../rust/elements/internal/MatchExprImpl.qll | 2 +- .../elements/internal/generated/MatchExpr.qll | 12 +++++------- .../internal/generated/ParentChild.qll | 10 +++++----- .../rust/elements/internal/generated/Raw.qll | 4 ++-- .../generated/MatchExpr/MatchExpr.expected | 4 ++-- .../generated/MatchExpr/MatchExpr.ql | 8 ++++---- .../MatchExpr_getMatchedExpr.expected | 2 -- ...xpected => MatchExpr_getScrutinee.expected} | 0 ...atchedExpr.ql => MatchExpr_getScrutinee.ql} | 2 +- rust/schema/annotations.py | 2 +- 14 files changed, 40 insertions(+), 44 deletions(-) delete mode 100644 rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.expected rename rust/ql/test/extractor-tests/generated/MatchExpr/{MatchExpr_getMatched.expected => MatchExpr_getScrutinee.expected} (100%) rename rust/ql/test/extractor-tests/generated/MatchExpr/{MatchExpr_getMatchedExpr.ql => MatchExpr_getScrutinee.ql} (83%) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 041e1a565b2..36416013959 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -1,4 +1,4 @@ -lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll c0438ab3e984fbf7ce2cc4ac64aafa115f36f2be700a819fd81f15d777f363b6 bc57c07b7f9472156cff3f878459872255c7ee4ba0767258129d0258789f98df +lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll 5e6ce2581b312d74ac8ffde44941b77f643025a7ff2c47799b3834596a513fa4 24dc5d28eb4754f968cf850294ac32057a2a97cf5156a3e90e0924c28e50e810 lib/codeql/rust/elements/Abi.qll 4c973d28b6d628f5959d1f1cc793704572fd0acaae9a97dfce82ff9d73f73476 250f68350180af080f904cd34cb2af481c5c688dc93edf7365fd0ae99855e893 lib/codeql/rust/elements/ArgList.qll 661f5100f5d3ef8351452d9058b663a2a5c720eea8cf11bedd628969741486a2 28e424aac01a90fb58cd6f9f83c7e4cf379eea39e636bc0ba07efc818be71c71 lib/codeql/rust/elements/ArrayExpr.qll a3e6e122632f4011644ec31b37f88b32fe3f2b7e388e7e878a6883309937049f 12ccb5873d95c433da5606fd371d182ef2f71b78d0c53c2d6dec10fa45852bdc @@ -495,7 +495,7 @@ lib/codeql/rust/elements/internal/generated/MacroStmts.qll cb4f3c2721a4d0c8522e5 lib/codeql/rust/elements/internal/generated/MacroType.qll c462824df4a002956c036966d15cd0bce206e664888f8d0c7834dedb38b3c0bf 947480f07c40128ef3d00ad4c3a29a685472b3e20a661680c22f6bb318205ed1 lib/codeql/rust/elements/internal/generated/MatchArm.qll 8fb740a0f2e308782d9cf390672969cd7cf6e698e5b847fb02ae3fa6c205646f 42bfe8dd94fc24ec925fbd44016df111600f99d1216c9a698631373bb6048830 lib/codeql/rust/elements/internal/generated/MatchArmList.qll 13362680c037fe83fef4653562cc10a4429078316b5ec7c47b076336cf4aca2e 41c674293c13eceaca62134ae0c6778541f6a5201cbc5c146f0ba01b898dc267 -lib/codeql/rust/elements/internal/generated/MatchExpr.qll e1e5bf4623511028a6c2ebc6bb6e3c18ec9fe4f49ef4cd8654e5dc376121088d c0760592040b2df9a571cd766397a0f9c68684d24d72780756cae7a1878d102a +lib/codeql/rust/elements/internal/generated/MatchExpr.qll b686842e7000fd61e3a0598bf245fb4e18167b99eca9162fdfdff0b0963def22 00f1743b1b0f1a92c5a687f5260fda02d80cc5871694cad0d5e7d94bac7fe977 lib/codeql/rust/elements/internal/generated/MatchGuard.qll 521a507883963106780f1782084c581fbcf1179863c7c15438c4db79e30e78dd 6226feffaaa8d828a42ece0c693e616cd375672eb987c3b7ff1ca15fa23c116a lib/codeql/rust/elements/internal/generated/Meta.qll 38fca2c9958b4179de311546fe0850319010aca9cd17c97d57e12b521c5d0947 740f99c9d41044ceebfcc9d29baaa22f59c11a40f45502a34aa587d423c018f8 lib/codeql/rust/elements/internal/generated/MethodCallExpr.qll 17bffcc826851a8be32a1900b8fdf777f9bab6aed9f8268d566173c4974c1cf9 134a2860bdf16daafdb3e574c52a69d2598210653db89c2fa062ca25e8f8a649 @@ -512,7 +512,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60 lib/codeql/rust/elements/internal/generated/ParenPat.qll ce24b8f8ecbf0f204af200317405724063887257460c80cf250c39b2fdf37185 e7c87d37e1a0ca7ea03840017e1aa9ddb7f927f1f3b6396c0305b46aeee33db6 lib/codeql/rust/elements/internal/generated/ParenType.qll 9cc954d73f8330dcac7b475f97748b63af5c8766dee9d2f2872c0a7e4c903537 c07534c8a9c683c4a9b11d490095647e420de0a0bfc23273eaf6f31b00244273 -lib/codeql/rust/elements/internal/generated/ParentChild.qll a19adfe192c88023b77f938d91f8539df6e42fa14172389537069decfe8baa7d 6be35ca8755d80c0365eeb9ecc51982fb0e24d2ed53ec6b17a15da4af6fbe6e6 +lib/codeql/rust/elements/internal/generated/ParentChild.qll 78723cac5f2999f91317f39cf53267043fd2a56e98e838f013eae01b6b39929e 26dd29e5fd868f89982269db6b25aa799be942abdbe41ff1a8ffd4dae4385bdc lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4 lib/codeql/rust/elements/internal/generated/Path.qll 4c1c8e840ed57880e574142b081b11d7a7428a009f10e3aa8f4645e211f6b2e0 989668cf0f1bdee7557e2f97c01e41d2a56848227fed41477833f5fc1e1d35f6 lib/codeql/rust/elements/internal/generated/PathExpr.qll 2096e3c1db22ee488a761690adabfc9cfdea501c99f7c5d96c0019cb113fc506 54245ce0449c4e263173213df01e079d5168a758503a5dbd61b25ad35a311140 @@ -525,7 +525,7 @@ lib/codeql/rust/elements/internal/generated/PtrType.qll 40099c5a4041314b66932dfd lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll efd93730de217cf50dcba5875595263a5eadf9f7e4e1272401342a094d158614 229b251b3d118932e31e78ac4dfb75f48b766f240f20d436062785606d44467b -lib/codeql/rust/elements/internal/generated/Raw.qll f1af475812318f9fbfd1731a1e97ae77783bcc8a7ad45463cd9916e4c46e783a 1e06a7cd87c4c704f76bbc70ba3d7601ca6f1b3dd11f124ee448d8b834f7ce55 +lib/codeql/rust/elements/internal/generated/Raw.qll b342060fd7fe2214eea191859f559334a8a64cf6785048f784ed641ea1e616fd 4737f09bbd2e190eee9bb83476a0045887ff2982dd06cd4e6538fc31637ab521 lib/codeql/rust/elements/internal/generated/RecordExpr.qll eb6cb662e463f9260efae1a6ce874fa781172063b916ef1963f861e9942d308d 1a21cbccc8f3799ff13281e822818ebfb21d81591720a427cac3625512cb9d40 lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1 lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0 @@ -845,10 +845,10 @@ test/extractor-tests/generated/MatchArm/MatchArm_getPat.ql b346bca229226414b32ac test/extractor-tests/generated/MatchArmList/MatchArmList.ql 14b5e110d48e2b77c85b7a188262e6a98300e0d4d507bb7ed9179c5802251dd6 4d091f06b12fef0fffe1c80a10f74438d8068f2fa09c50d5e240b6d140e60d90 test/extractor-tests/generated/MatchArmList/MatchArmList_getArm.ql 4781d002538a92b7f40fb0ec3d61aeedb6348341ddc354bbdd3ff61b74d59767 ae0da9497a30ce006e03bdb70e0ee24b685df529ac15a7d99a6869b5f7d7b371 test/extractor-tests/generated/MatchArmList/MatchArmList_getAttr.ql 4d7e6d152d2dbeb4c9f594becabea27d3b25fecbde40d791a2907c69cc0c9631 4be9be658bb22e1b764c4ebc8d6b99bf50fd939f35ea44fbb869056c14632bd4 -test/extractor-tests/generated/MatchExpr/MatchExpr.ql 22a3ace49ec98524388ccfb031c180eedc741cbc5b58a4815cc9e52fe292e6b3 5b56c71cbc02ac3aecfcbe93e7bbdb55727aae39d7949a7d8db3d6f93ea7ca80 +test/extractor-tests/generated/MatchExpr/MatchExpr.ql 2966bf0507c0d45db1b933442ce8f1c4e0a9d4212c53a768791665cd2e0927f0 8af3b87528b6dd4cd3ff4fc6d2d389b1a743f979d9ccacd0aff134b5a4376118 test/extractor-tests/generated/MatchExpr/MatchExpr_getAttr.ql cb8057372dcf24dfa02896ebf4e60a0b757dc4742b94011edc38f5b898ed4d25 6809695c2d3ac3b92c06049c9b920e8c0e99ee1998a11a7f181f2b0ceb47c197 test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchArmList.ql d97055bcb0431e8b258b5ecdd98aa07cb24ece06b0cd658b697cd71da4ede8fc 5e9c03b2665ef6b2af98897996abb2e0a9c18d54eb64588340b8efbcee9793bd -test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.ql 478585d26c2b301f474f04569deb79728c80b3f67fe5c2536b64f5a29dcccf30 750d24c48dc0f57992265c3fc60fbfa400263f58f74b7951774a383d3ae4ae0a +test/extractor-tests/generated/MatchExpr/MatchExpr_getScrutinee.ql 0bfeb8f903fb23356d50b7edd80377f4a67045010ffbed04c835191b5bd62820 7dc8e38730ad72b4cea91c1f023cdbe83057053e8dbd077ff925c59e92744498 test/extractor-tests/generated/MatchGuard/MatchGuard.ql 23e47ec1b13e2d80e31b57894a46ec789d6ab5ed1eb66bdb6bba9bd5ae71d3ef 7302f4a93108a83228e0ebd5b4a1bc6bccc1f6f0f3272054866fa90378c0dcc4 test/extractor-tests/generated/MatchGuard/MatchGuard_getCondition.ql 8a79dd46798f111f8d0d5a975380b5cebe5e337267752b77b3718b268ba2773d 6691d8fb483f64fc7e3ad3f46e3129e0a1184d7beb9f83a1000acdbb081c8b5e test/extractor-tests/generated/Meta/Meta.ql 16f163f00ba2bbaa0a8c6f3f6710c860a8f61d02d43321c78e05a10a3606e39b ba982c6bb93ddb4fc2c44d24635bd487128a5b1d1f885214044c989a21f4d05a diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 6b97bf45470..69c1ecbc2c6 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -850,7 +850,7 @@ /test/extractor-tests/generated/MatchExpr/MatchExpr.ql linguist-generated /test/extractor-tests/generated/MatchExpr/MatchExpr_getAttr.ql linguist-generated /test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchArmList.ql linguist-generated -/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.ql linguist-generated +/test/extractor-tests/generated/MatchExpr/MatchExpr_getScrutinee.ql linguist-generated /test/extractor-tests/generated/MatchGuard/MatchGuard.ql linguist-generated /test/extractor-tests/generated/MatchGuard/MatchGuard_getCondition.ql linguist-generated /test/extractor-tests/generated/Meta/Meta.ql linguist-generated diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 42487f1689d..91eeb75fe39 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -514,14 +514,14 @@ module ExprTrees { class MatchExprTree extends PostOrderTree instanceof MatchExpr { override predicate propagatesAbnormal(AstNode child) { - child = [super.getMatchedExpr(), super.getAnArm().getExpr()] + child = [super.getScrutinee(), super.getAnArm().getExpr()] } - override predicate first(AstNode node) { first(super.getMatchedExpr(), node) } + override predicate first(AstNode node) { first(super.getScrutinee(), node) } override predicate succ(AstNode pred, AstNode succ, Completion c) { // Edge from the scrutinee to the first arm or to the match expression if no arms. - last(super.getMatchedExpr(), pred, c) and + last(super.getScrutinee(), pred, c) and ( first(super.getArm(0).getPat(), succ) or diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll index aeebf92e02b..44024a9d76e 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll @@ -1709,7 +1709,7 @@ module MakeCfgNodes Input> { override predicate relevantChild(AstNode child) { none() or - child = this.getMatchedExpr() + child = this.getScrutinee() } } @@ -1752,16 +1752,16 @@ module MakeCfgNodes Input> { int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } /** - * Gets the expression of this match expression, if it exists. + * Gets the scrutinee (the expression being matched) of this match expression, if it exists. */ - ExprCfgNode getMatchedExpr() { - any(ChildMapping mapping).hasCfgChild(node, node.getMatchedExpr(), this, result) + ExprCfgNode getScrutinee() { + any(ChildMapping mapping).hasCfgChild(node, node.getScrutinee(), this, result) } /** - * Holds if `getMatchedExpr()` exists. + * Holds if `getScrutinee()` exists. */ - predicate hasMatchedExpr() { exists(this.getMatchedExpr()) } + predicate hasScrutinee() { exists(this.getScrutinee()) } /** * Gets the match arm list of this match expression, if it exists. @@ -3451,14 +3451,14 @@ module MakeCfgNodes Input> { cfgNode ) or - pred = "getMatchedExpr" and + pred = "getScrutinee" and parent = any(Nodes::MatchExprCfgNode cfgNode, MatchExpr astNode | astNode = cfgNode.getMatchExpr() and - child = getDesugared(astNode.getMatchedExpr()) and + child = getDesugared(astNode.getScrutinee()) and i = -1 and hasCfgNode(child) and - not child = cfgNode.getMatchedExpr().getAstNode() + not child = cfgNode.getScrutinee().getAstNode() | cfgNode ) diff --git a/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll index 445c4c86945..15fdcf7e73f 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/MatchExprImpl.qll @@ -29,7 +29,7 @@ module Impl { */ class MatchExpr extends Generated::MatchExpr { override string toString() { - result = "match " + this.getMatchedExpr().toAbbreviatedString() + " { ... }" + result = "match " + this.getScrutinee().toAbbreviatedString() + " { ... }" } /** diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/MatchExpr.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/MatchExpr.qll index 5c2974c82fe..8f49407e5f9 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/MatchExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/MatchExpr.qll @@ -55,19 +55,17 @@ module Generated { final int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } /** - * Gets the expression of this match expression, if it exists. + * Gets the scrutinee (the expression being matched) of this match expression, if it exists. */ - Expr getMatchedExpr() { + Expr getScrutinee() { result = - Synth::convertExprFromRaw(Synth::convertMatchExprToRaw(this) - .(Raw::MatchExpr) - .getMatchedExpr()) + Synth::convertExprFromRaw(Synth::convertMatchExprToRaw(this).(Raw::MatchExpr).getScrutinee()) } /** - * Holds if `getMatchedExpr()` exists. + * Holds if `getScrutinee()` exists. */ - final predicate hasMatchedExpr() { exists(this.getMatchedExpr()) } + final predicate hasScrutinee() { exists(this.getScrutinee()) } /** * Gets the match arm list of this match expression, if it exists. diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll index 9dd9eff45eb..970cfb22364 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll @@ -2030,13 +2030,13 @@ private module Impl { } private Element getImmediateChildOfMatchExpr(MatchExpr e, int index, string partialPredicateCall) { - exists(int b, int bExpr, int n, int nAttr, int nMatchedExpr, int nMatchArmList | + exists(int b, int bExpr, int n, int nAttr, int nScrutinee, int nMatchArmList | b = 0 and bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and n = bExpr and nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and - nMatchedExpr = nAttr + 1 and - nMatchArmList = nMatchedExpr + 1 and + nScrutinee = nAttr + 1 and + nMatchArmList = nScrutinee + 1 and ( none() or @@ -2045,9 +2045,9 @@ private module Impl { result = e.getAttr(index - n) and partialPredicateCall = "Attr(" + (index - n).toString() + ")" or - index = nAttr and result = e.getMatchedExpr() and partialPredicateCall = "MatchedExpr()" + index = nAttr and result = e.getScrutinee() and partialPredicateCall = "Scrutinee()" or - index = nMatchedExpr and + index = nScrutinee and result = e.getMatchArmList() and partialPredicateCall = "MatchArmList()" ) diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index b54d0cba583..69aa32d4ad8 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -2170,9 +2170,9 @@ module Raw { Attr getAttr(int index) { match_expr_attrs(this, index, result) } /** - * Gets the expression of this match expression, if it exists. + * Gets the scrutinee (the expression being matched) of this match expression, if it exists. */ - Expr getMatchedExpr() { match_expr_exprs(this, result) } + Expr getScrutinee() { match_expr_exprs(this, result) } /** * Gets the match arm list of this match expression, if it exists. diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected index 68912b3f01a..8c5b0a32a8f 100644 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.expected @@ -1,2 +1,2 @@ -| gen_match_expr.rs:5:5:8:5 | match x { ... } | getNumberOfAttrs: | 0 | hasMatchedExpr: | yes | hasMatchArmList: | yes | -| gen_match_expr.rs:9:5:12:5 | match x { ... } | getNumberOfAttrs: | 0 | hasMatchedExpr: | yes | hasMatchArmList: | yes | +| gen_match_expr.rs:5:5:8:5 | match x { ... } | getNumberOfAttrs: | 0 | hasScrutinee: | yes | hasMatchArmList: | yes | +| gen_match_expr.rs:9:5:12:5 | match x { ... } | getNumberOfAttrs: | 0 | hasScrutinee: | yes | hasMatchArmList: | yes | diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.ql b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.ql index e99d3c70e1b..0847933e937 100644 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.ql +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr.ql @@ -2,12 +2,12 @@ import codeql.rust.elements import TestUtils -from MatchExpr x, int getNumberOfAttrs, string hasMatchedExpr, string hasMatchArmList +from MatchExpr x, int getNumberOfAttrs, string hasScrutinee, string hasMatchArmList where toBeTested(x) and not x.isUnknown() and getNumberOfAttrs = x.getNumberOfAttrs() and - (if x.hasMatchedExpr() then hasMatchedExpr = "yes" else hasMatchedExpr = "no") and + (if x.hasScrutinee() then hasScrutinee = "yes" else hasScrutinee = "no") and if x.hasMatchArmList() then hasMatchArmList = "yes" else hasMatchArmList = "no" -select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasMatchedExpr:", hasMatchedExpr, - "hasMatchArmList:", hasMatchArmList +select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasScrutinee:", hasScrutinee, "hasMatchArmList:", + hasMatchArmList diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.expected deleted file mode 100644 index 427af7c6ed0..00000000000 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.expected +++ /dev/null @@ -1,2 +0,0 @@ -| gen_match_expr.rs:5:5:8:5 | match x { ... } | gen_match_expr.rs:5:11:5:11 | x | -| gen_match_expr.rs:9:5:12:5 | match x { ... } | gen_match_expr.rs:9:11:9:11 | x | diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatched.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getScrutinee.expected similarity index 100% rename from rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatched.expected rename to rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getScrutinee.expected diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.ql b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getScrutinee.ql similarity index 83% rename from rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.ql rename to rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getScrutinee.ql index 0a7bb7ae332..4d29f21fbfb 100644 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getMatchedExpr.ql +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getScrutinee.ql @@ -4,4 +4,4 @@ import TestUtils from MatchExpr x where toBeTested(x) and not x.isUnknown() -select x, x.getMatchedExpr() +select x, x.getScrutinee() diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index b93151fec33..9e857ad7b0f 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -289,7 +289,7 @@ class _: } ``` """ - expr: _ | ql.name("matched_expr") + expr: _ | ql.name("scrutinee") | doc("scrutinee (the expression being matched) of this match expression") @annotate(ContinueExpr, cfg = True) From 511f79151142049cbdfb45012f14a092480296a3 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 22 Nov 2024 14:52:59 +0100 Subject: [PATCH 236/470] Rust: Add more flow tests --- .../dataflow/local/DataFlowStep.expected | 204 ++++++++++++++---- .../dataflow/local/DataFlowStep.ql | 9 +- .../test/library-tests/dataflow/local/main.rs | 152 ++++++++++--- 3 files changed, 299 insertions(+), 66 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 02cc2fdf591..f16bdf9a844 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -1,3 +1,4 @@ +localStep | main.rs:3:11:3:11 | [SSA] i | main.rs:4:12:4:12 | i | | main.rs:3:11:3:11 | i | main.rs:3:11:3:11 | [SSA] i | | main.rs:3:11:3:16 | ...: i64 | main.rs:3:11:3:11 | i | @@ -75,42 +76,171 @@ | main.rs:97:38:97:38 | p | main.rs:97:9:97:34 | Point {...} | | main.rs:104:9:104:10 | [SSA] s1 | main.rs:106:11:106:12 | s1 | | main.rs:104:9:104:10 | s1 | main.rs:104:9:104:10 | [SSA] s1 | -| main.rs:104:14:104:28 | Some(...) | main.rs:104:9:104:10 | s1 | +| main.rs:104:14:104:37 | ...::Some(...) | main.rs:104:9:104:10 | s1 | | main.rs:105:9:105:10 | [SSA] s2 | main.rs:110:11:110:12 | s2 | | main.rs:105:9:105:10 | s2 | main.rs:105:9:105:10 | [SSA] s2 | -| main.rs:105:14:105:20 | Some(...) | main.rs:105:9:105:10 | s2 | -| main.rs:107:14:107:14 | [SSA] n | main.rs:107:25:107:25 | n | -| main.rs:107:14:107:14 | n | main.rs:107:14:107:14 | [SSA] n | -| main.rs:107:20:107:26 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } | -| main.rs:108:17:108:23 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } | -| main.rs:110:5:113:5 | match s2 { ... } | main.rs:103:27:114:1 | { ... } | -| main.rs:111:14:111:14 | [SSA] n | main.rs:111:25:111:25 | n | -| main.rs:111:14:111:14 | n | main.rs:111:14:111:14 | [SSA] n | -| main.rs:111:20:111:26 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } | -| main.rs:112:17:112:23 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } | -| main.rs:117:9:117:9 | [SSA] a | main.rs:118:5:118:5 | a | -| main.rs:117:9:117:9 | a | main.rs:117:9:117:9 | [SSA] a | -| main.rs:117:13:117:17 | { ... } | main.rs:117:9:117:9 | a | -| main.rs:117:15:117:15 | 0 | main.rs:117:13:117:17 | { ... } | -| main.rs:118:5:118:5 | a | main.rs:116:31:119:1 | { ... } | -| main.rs:121:22:121:22 | [SSA] b | main.rs:123:12:123:12 | b | -| main.rs:121:22:121:22 | b | main.rs:121:22:121:22 | [SSA] b | -| main.rs:121:22:121:28 | ...: bool | main.rs:121:22:121:22 | b | -| main.rs:122:9:122:9 | [SSA] a | main.rs:128:5:128:5 | a | -| main.rs:122:9:122:9 | a | main.rs:122:9:122:9 | [SSA] a | -| main.rs:122:13:127:5 | 'block: { ... } | main.rs:122:9:122:9 | a | -| main.rs:124:13:124:26 | break ''block 1 | main.rs:122:13:127:5 | 'block: { ... } | -| main.rs:124:26:124:26 | 1 | main.rs:124:13:124:26 | break ''block 1 | -| main.rs:126:9:126:9 | 2 | main.rs:122:13:127:5 | 'block: { ... } | -| main.rs:128:5:128:5 | a | main.rs:121:38:129:1 | { ... } | -| main.rs:131:22:131:22 | [SSA] b | main.rs:133:12:133:12 | b | -| main.rs:131:22:131:22 | b | main.rs:131:22:131:22 | [SSA] b | -| main.rs:131:22:131:28 | ...: bool | main.rs:131:22:131:22 | b | -| main.rs:132:9:132:9 | [SSA] a | main.rs:138:5:138:5 | a | -| main.rs:132:9:132:9 | a | main.rs:132:9:132:9 | [SSA] a | -| main.rs:132:13:137:5 | 'block: { ... } | main.rs:132:9:132:9 | a | -| main.rs:134:13:134:26 | break ''block 1 | main.rs:132:13:137:5 | 'block: { ... } | -| main.rs:134:26:134:26 | 1 | main.rs:134:13:134:26 | break ''block 1 | -| main.rs:136:9:136:22 | break ''block 2 | main.rs:132:13:137:5 | 'block: { ... } | -| main.rs:136:22:136:22 | 2 | main.rs:136:9:136:22 | break ''block 2 | -| main.rs:138:5:138:5 | a | main.rs:131:38:139:1 | { ... } | +| main.rs:105:14:105:28 | ...::Some(...) | main.rs:105:9:105:10 | s2 | +| main.rs:107:22:107:22 | [SSA] n | main.rs:107:33:107:33 | n | +| main.rs:107:22:107:22 | n | main.rs:107:22:107:22 | [SSA] n | +| main.rs:107:28:107:34 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } | +| main.rs:108:25:108:31 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } | +| main.rs:110:5:113:5 | match s2 { ... } | main.rs:103:37:114:1 | { ... } | +| main.rs:111:22:111:22 | [SSA] n | main.rs:111:33:111:33 | n | +| main.rs:111:22:111:22 | n | main.rs:111:22:111:22 | [SSA] n | +| main.rs:111:28:111:34 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } | +| main.rs:112:25:112:31 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } | +| main.rs:117:9:117:10 | [SSA] s1 | main.rs:119:11:119:12 | s1 | +| main.rs:117:9:117:10 | s1 | main.rs:117:9:117:10 | [SSA] s1 | +| main.rs:117:14:117:29 | Some(...) | main.rs:117:9:117:10 | s1 | +| main.rs:118:9:118:10 | [SSA] s2 | main.rs:123:11:123:12 | s2 | +| main.rs:118:9:118:10 | s2 | main.rs:118:9:118:10 | [SSA] s2 | +| main.rs:118:14:118:20 | Some(...) | main.rs:118:9:118:10 | s2 | +| main.rs:120:14:120:14 | [SSA] n | main.rs:120:25:120:25 | n | +| main.rs:120:14:120:14 | n | main.rs:120:14:120:14 | [SSA] n | +| main.rs:120:20:120:26 | sink(...) | main.rs:119:5:122:5 | match s1 { ... } | +| main.rs:121:17:121:23 | sink(...) | main.rs:119:5:122:5 | match s1 { ... } | +| main.rs:123:5:126:5 | match s2 { ... } | main.rs:116:39:127:1 | { ... } | +| main.rs:124:14:124:14 | [SSA] n | main.rs:124:25:124:25 | n | +| main.rs:124:14:124:14 | n | main.rs:124:14:124:14 | [SSA] n | +| main.rs:124:20:124:26 | sink(...) | main.rs:123:5:126:5 | match s2 { ... } | +| main.rs:125:17:125:23 | sink(...) | main.rs:123:5:126:5 | match s2 { ... } | +| main.rs:135:9:135:10 | [SSA] s1 | main.rs:137:11:137:12 | s1 | +| main.rs:135:9:135:10 | s1 | main.rs:135:9:135:10 | [SSA] s1 | +| main.rs:135:14:135:39 | ...::A(...) | main.rs:135:9:135:10 | s1 | +| main.rs:136:9:136:10 | [SSA] s2 | main.rs:144:11:144:12 | s2 | +| main.rs:136:9:136:10 | s2 | main.rs:136:9:136:10 | [SSA] s2 | +| main.rs:136:14:136:30 | ...::B(...) | main.rs:136:9:136:10 | s2 | +| main.rs:137:11:137:12 | s1 | main.rs:141:11:141:12 | s1 | +| main.rs:138:24:138:24 | [SSA] n | main.rs:138:35:138:35 | n | +| main.rs:138:24:138:24 | n | main.rs:138:24:138:24 | [SSA] n | +| main.rs:138:30:138:36 | sink(...) | main.rs:137:5:140:5 | match s1 { ... } | +| main.rs:139:24:139:24 | [SSA] n | main.rs:139:35:139:35 | n | +| main.rs:139:24:139:24 | n | main.rs:139:24:139:24 | [SSA] n | +| main.rs:139:30:139:36 | sink(...) | main.rs:137:5:140:5 | match s1 { ... } | +| main.rs:142:10:142:46 | [SSA] [match(true)] phi | main.rs:142:57:142:57 | n | +| main.rs:142:25:142:25 | [SSA] [input] [match(true)] phi | main.rs:142:10:142:46 | [SSA] [match(true)] phi | +| main.rs:142:25:142:25 | [SSA] n | main.rs:142:25:142:25 | [SSA] [input] [match(true)] phi | +| main.rs:142:25:142:25 | n | main.rs:142:25:142:25 | [SSA] n | +| main.rs:142:45:142:45 | [SSA] [input] [match(true)] phi | main.rs:142:10:142:46 | [SSA] [match(true)] phi | +| main.rs:142:45:142:45 | [SSA] n | main.rs:142:45:142:45 | [SSA] [input] [match(true)] phi | +| main.rs:142:45:142:45 | n | main.rs:142:45:142:45 | [SSA] n | +| main.rs:142:52:142:58 | sink(...) | main.rs:141:5:143:5 | match s1 { ... } | +| main.rs:144:5:147:5 | match s2 { ... } | main.rs:134:48:148:1 | { ... } | +| main.rs:145:24:145:24 | [SSA] n | main.rs:145:35:145:35 | n | +| main.rs:145:24:145:24 | n | main.rs:145:24:145:24 | [SSA] n | +| main.rs:145:30:145:36 | sink(...) | main.rs:144:5:147:5 | match s2 { ... } | +| main.rs:146:24:146:24 | [SSA] n | main.rs:146:35:146:35 | n | +| main.rs:146:24:146:24 | n | main.rs:146:24:146:24 | [SSA] n | +| main.rs:146:30:146:36 | sink(...) | main.rs:144:5:147:5 | match s2 { ... } | +| main.rs:153:9:153:10 | [SSA] s1 | main.rs:155:11:155:12 | s1 | +| main.rs:153:9:153:10 | s1 | main.rs:153:9:153:10 | [SSA] s1 | +| main.rs:153:14:153:26 | A(...) | main.rs:153:9:153:10 | s1 | +| main.rs:154:9:154:10 | [SSA] s2 | main.rs:162:11:162:12 | s2 | +| main.rs:154:9:154:10 | s2 | main.rs:154:9:154:10 | [SSA] s2 | +| main.rs:154:14:154:17 | B(...) | main.rs:154:9:154:10 | s2 | +| main.rs:155:11:155:12 | s1 | main.rs:159:11:159:12 | s1 | +| main.rs:156:11:156:11 | [SSA] n | main.rs:156:22:156:22 | n | +| main.rs:156:11:156:11 | n | main.rs:156:11:156:11 | [SSA] n | +| main.rs:156:17:156:23 | sink(...) | main.rs:155:5:158:5 | match s1 { ... } | +| main.rs:157:11:157:11 | [SSA] n | main.rs:157:22:157:22 | n | +| main.rs:157:11:157:11 | n | main.rs:157:11:157:11 | [SSA] n | +| main.rs:157:17:157:23 | sink(...) | main.rs:155:5:158:5 | match s1 { ... } | +| main.rs:160:10:160:20 | [SSA] [match(true)] phi | main.rs:160:31:160:31 | n | +| main.rs:160:12:160:12 | [SSA] [input] [match(true)] phi | main.rs:160:10:160:20 | [SSA] [match(true)] phi | +| main.rs:160:12:160:12 | [SSA] n | main.rs:160:12:160:12 | [SSA] [input] [match(true)] phi | +| main.rs:160:12:160:12 | n | main.rs:160:12:160:12 | [SSA] n | +| main.rs:160:19:160:19 | [SSA] [input] [match(true)] phi | main.rs:160:10:160:20 | [SSA] [match(true)] phi | +| main.rs:160:19:160:19 | [SSA] n | main.rs:160:19:160:19 | [SSA] [input] [match(true)] phi | +| main.rs:160:19:160:19 | n | main.rs:160:19:160:19 | [SSA] n | +| main.rs:160:26:160:32 | sink(...) | main.rs:159:5:161:5 | match s1 { ... } | +| main.rs:162:5:165:5 | match s2 { ... } | main.rs:152:50:166:1 | { ... } | +| main.rs:163:11:163:11 | [SSA] n | main.rs:163:22:163:22 | n | +| main.rs:163:11:163:11 | n | main.rs:163:11:163:11 | [SSA] n | +| main.rs:163:17:163:23 | sink(...) | main.rs:162:5:165:5 | match s2 { ... } | +| main.rs:164:11:164:11 | [SSA] n | main.rs:164:22:164:22 | n | +| main.rs:164:11:164:11 | n | main.rs:164:11:164:11 | [SSA] n | +| main.rs:164:17:164:23 | sink(...) | main.rs:162:5:165:5 | match s2 { ... } | +| main.rs:174:9:174:10 | [SSA] s1 | main.rs:178:11:178:12 | s1 | +| main.rs:174:9:174:10 | s1 | main.rs:174:9:174:10 | [SSA] s1 | +| main.rs:174:14:176:5 | ...::C {...} | main.rs:174:9:174:10 | s1 | +| main.rs:177:9:177:10 | [SSA] s2 | main.rs:185:11:185:12 | s2 | +| main.rs:177:9:177:10 | s2 | main.rs:177:9:177:10 | [SSA] s2 | +| main.rs:177:14:177:43 | ...::D {...} | main.rs:177:9:177:10 | s2 | +| main.rs:178:11:178:12 | s1 | main.rs:182:11:182:12 | s1 | +| main.rs:179:36:179:36 | [SSA] n | main.rs:179:48:179:48 | n | +| main.rs:179:36:179:36 | n | main.rs:179:36:179:36 | [SSA] n | +| main.rs:179:43:179:49 | sink(...) | main.rs:178:5:181:5 | match s1 { ... } | +| main.rs:180:36:180:36 | [SSA] n | main.rs:180:48:180:48 | n | +| main.rs:180:36:180:36 | n | main.rs:180:36:180:36 | [SSA] n | +| main.rs:180:43:180:49 | sink(...) | main.rs:178:5:181:5 | match s1 { ... } | +| main.rs:183:10:183:72 | [SSA] [match(true)] phi | main.rs:183:83:183:83 | n | +| main.rs:183:37:183:37 | [SSA] [input] [match(true)] phi | main.rs:183:10:183:72 | [SSA] [match(true)] phi | +| main.rs:183:37:183:37 | [SSA] n | main.rs:183:37:183:37 | [SSA] [input] [match(true)] phi | +| main.rs:183:37:183:37 | n | main.rs:183:37:183:37 | [SSA] n | +| main.rs:183:70:183:70 | [SSA] [input] [match(true)] phi | main.rs:183:10:183:72 | [SSA] [match(true)] phi | +| main.rs:183:70:183:70 | [SSA] n | main.rs:183:70:183:70 | [SSA] [input] [match(true)] phi | +| main.rs:183:70:183:70 | n | main.rs:183:70:183:70 | [SSA] n | +| main.rs:183:78:183:84 | sink(...) | main.rs:182:5:184:5 | match s1 { ... } | +| main.rs:185:5:188:5 | match s2 { ... } | main.rs:173:49:189:1 | { ... } | +| main.rs:186:36:186:36 | [SSA] n | main.rs:186:48:186:48 | n | +| main.rs:186:36:186:36 | n | main.rs:186:36:186:36 | [SSA] n | +| main.rs:186:43:186:49 | sink(...) | main.rs:185:5:188:5 | match s2 { ... } | +| main.rs:187:36:187:36 | [SSA] n | main.rs:187:48:187:48 | n | +| main.rs:187:36:187:36 | n | main.rs:187:36:187:36 | [SSA] n | +| main.rs:187:43:187:49 | sink(...) | main.rs:185:5:188:5 | match s2 { ... } | +| main.rs:194:9:194:10 | [SSA] s1 | main.rs:198:11:198:12 | s1 | +| main.rs:194:9:194:10 | s1 | main.rs:194:9:194:10 | [SSA] s1 | +| main.rs:194:14:196:5 | C {...} | main.rs:194:9:194:10 | s1 | +| main.rs:197:9:197:10 | [SSA] s2 | main.rs:205:11:205:12 | s2 | +| main.rs:197:9:197:10 | s2 | main.rs:197:9:197:10 | [SSA] s2 | +| main.rs:197:14:197:29 | D {...} | main.rs:197:9:197:10 | s2 | +| main.rs:198:11:198:12 | s1 | main.rs:202:11:202:12 | s1 | +| main.rs:199:22:199:22 | [SSA] n | main.rs:199:34:199:34 | n | +| main.rs:199:22:199:22 | n | main.rs:199:22:199:22 | [SSA] n | +| main.rs:199:29:199:35 | sink(...) | main.rs:198:5:201:5 | match s1 { ... } | +| main.rs:200:22:200:22 | [SSA] n | main.rs:200:34:200:34 | n | +| main.rs:200:22:200:22 | n | main.rs:200:22:200:22 | [SSA] n | +| main.rs:200:29:200:35 | sink(...) | main.rs:198:5:201:5 | match s1 { ... } | +| main.rs:203:10:203:44 | [SSA] [match(true)] phi | main.rs:203:55:203:55 | n | +| main.rs:203:23:203:23 | [SSA] [input] [match(true)] phi | main.rs:203:10:203:44 | [SSA] [match(true)] phi | +| main.rs:203:23:203:23 | [SSA] n | main.rs:203:23:203:23 | [SSA] [input] [match(true)] phi | +| main.rs:203:23:203:23 | n | main.rs:203:23:203:23 | [SSA] n | +| main.rs:203:42:203:42 | [SSA] [input] [match(true)] phi | main.rs:203:10:203:44 | [SSA] [match(true)] phi | +| main.rs:203:42:203:42 | [SSA] n | main.rs:203:42:203:42 | [SSA] [input] [match(true)] phi | +| main.rs:203:42:203:42 | n | main.rs:203:42:203:42 | [SSA] n | +| main.rs:203:50:203:56 | sink(...) | main.rs:202:5:204:5 | match s1 { ... } | +| main.rs:205:5:208:5 | match s2 { ... } | main.rs:193:51:209:1 | { ... } | +| main.rs:206:22:206:22 | [SSA] n | main.rs:206:34:206:34 | n | +| main.rs:206:22:206:22 | n | main.rs:206:22:206:22 | [SSA] n | +| main.rs:206:29:206:35 | sink(...) | main.rs:205:5:208:5 | match s2 { ... } | +| main.rs:207:22:207:22 | [SSA] n | main.rs:207:34:207:34 | n | +| main.rs:207:22:207:22 | n | main.rs:207:22:207:22 | [SSA] n | +| main.rs:207:29:207:35 | sink(...) | main.rs:205:5:208:5 | match s2 { ... } | +| main.rs:212:9:212:9 | [SSA] a | main.rs:213:5:213:5 | a | +| main.rs:212:9:212:9 | a | main.rs:212:9:212:9 | [SSA] a | +| main.rs:212:13:212:17 | { ... } | main.rs:212:9:212:9 | a | +| main.rs:212:15:212:15 | 0 | main.rs:212:13:212:17 | { ... } | +| main.rs:213:5:213:5 | a | main.rs:211:31:214:1 | { ... } | +| main.rs:216:22:216:22 | [SSA] b | main.rs:218:12:218:12 | b | +| main.rs:216:22:216:22 | b | main.rs:216:22:216:22 | [SSA] b | +| main.rs:216:22:216:28 | ...: bool | main.rs:216:22:216:22 | b | +| main.rs:217:9:217:9 | [SSA] a | main.rs:223:5:223:5 | a | +| main.rs:217:9:217:9 | a | main.rs:217:9:217:9 | [SSA] a | +| main.rs:217:13:222:5 | 'block: { ... } | main.rs:217:9:217:9 | a | +| main.rs:219:13:219:26 | break ''block 1 | main.rs:217:13:222:5 | 'block: { ... } | +| main.rs:219:26:219:26 | 1 | main.rs:219:13:219:26 | break ''block 1 | +| main.rs:221:9:221:9 | 2 | main.rs:217:13:222:5 | 'block: { ... } | +| main.rs:223:5:223:5 | a | main.rs:216:38:224:1 | { ... } | +| main.rs:226:22:226:22 | [SSA] b | main.rs:228:12:228:12 | b | +| main.rs:226:22:226:22 | b | main.rs:226:22:226:22 | [SSA] b | +| main.rs:226:22:226:28 | ...: bool | main.rs:226:22:226:22 | b | +| main.rs:227:9:227:9 | [SSA] a | main.rs:233:5:233:5 | a | +| main.rs:227:9:227:9 | a | main.rs:227:9:227:9 | [SSA] a | +| main.rs:227:13:232:5 | 'block: { ... } | main.rs:227:9:227:9 | a | +| main.rs:229:13:229:26 | break ''block 1 | main.rs:227:13:232:5 | 'block: { ... } | +| main.rs:229:26:229:26 | 1 | main.rs:229:13:229:26 | break ''block 1 | +| main.rs:231:9:231:22 | break ''block 2 | main.rs:227:13:232:5 | 'block: { ... } | +| main.rs:231:22:231:22 | 2 | main.rs:231:9:231:22 | break ''block 2 | +| main.rs:233:5:233:5 | a | main.rs:226:38:234:1 | { ... } | +storeStep +readStep diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.ql b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.ql index 77147a50573..8bbde28564a 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.ql +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.ql @@ -1,5 +1,8 @@ import codeql.rust.dataflow.DataFlow +import codeql.rust.dataflow.internal.DataFlowImpl -from DataFlow::Node pred, DataFlow::Node succ -where DataFlow::localFlowStep(pred, succ) -select pred, succ +query predicate localStep = DataFlow::localFlowStep/2; + +query predicate storeStep = RustDataFlow::storeStep/3; + +query predicate readStep = RustDataFlow::readStep/3; diff --git a/rust/ql/test/library-tests/dataflow/local/main.rs b/rust/ql/test/library-tests/dataflow/local/main.rs index 50aa4fdb965..b9dcc78c3a8 100644 --- a/rust/ql/test/library-tests/dataflow/local/main.rs +++ b/rust/ql/test/library-tests/dataflow/local/main.rs @@ -16,24 +16,24 @@ fn direct() { } fn variable_usage() { - let s = source(1); - sink(s); // $ hasValueFlow=1 + let s = source(2); + sink(s); // $ hasValueFlow=2 } fn if_expression(cond: bool) { - let a = source(1); + let a = source(3); let b = 2; let c = if cond { a } else { b }; - sink(c); // $ hasValueFlow=1 + sink(c); // $ hasValueFlow=3 } fn match_expression(m: Option) { - let a = source(1); + let a = source(4); let b = match m { Some(_) => a, None => 0, }; - sink(b); // $ hasValueFlow=1 + sink(b); // $ hasValueFlow=4 } fn loop_with_break() { @@ -42,29 +42,29 @@ fn loop_with_break() { }; sink(a); let b = loop { - break source(1); + break source(5); }; - sink(b); // $ hasValueFlow=1 + sink(b); // $ hasValueFlow=5 } fn assignment() { let mut i = 1; sink(i); - i = source(2); - sink(i); // $ hasValueFlow=2 + i = source(6); + sink(i); // $ hasValueFlow=6 } // ----------------------------------------------------------------------------- // Data flow through data structures by writing and reading fn box_deref() { - let i = Box::new(source(1)); - sink(*i); // $ MISSING: hasValueFlow=1 + let i = Box::new(source(7)); + sink(*i); // $ MISSING: hasValueFlow=7 } fn tuple() { - let a = (source(1), 2); - sink(a.0); // $ MISSING: hasValueFlow=1 + let a = (source(8), 2); + sink(a.0); // $ MISSING: hasValueFlow=8 sink(a.1); } @@ -76,13 +76,13 @@ struct Point { fn struct_field() { let p = Point { - x: source(1), + x: source(9), y: 2, - z: source(3), + z: source(10), }; - sink(p.x); // MISSING: hasValueFlow=1 + sink(p.x); // $ MISSING: hasValueFlow=9 sink(p.y); - sink(p.z); // MISSING: hasValueFlow=3 + sink(p.z); // $ MISSING: hasValueFlow=10 } // ----------------------------------------------------------------------------- @@ -90,21 +90,34 @@ fn struct_field() { fn struct_pattern_match() { let p = Point { - x: source(1), + x: source(11), y: 2, - z: source(3), + z: source(12), }; let Point { x: a, y: b, z: c } = p; - sink(a); // MISSING: hasValueFlow=1 + sink(a); // $ MISSING: hasValueFlow=11 sink(b); - sink(c); // MISSING: hasValueFlow=3 + sink(c); // $ MISSING: hasValueFlow=12 } -fn option_pattern_match() { - let s1 = Some(source(1)); +fn option_pattern_match_qualified() { + let s1 = Option::Some(source(13)); + let s2 = Option::Some(2); + match s1 { + Option::Some(n) => sink(n), // $ MISSING: hasValueFlow=13 + Option::None => sink(0), + } + match s2 { + Option::Some(n) => sink(n), + Option::None => sink(0), + } +} + +fn option_pattern_match_unqualified() { + let s1 = Some(source(14)); let s2 = Some(2); match s1 { - Some(n) => sink(n), // MISSING: hasValueFlow=3 + Some(n) => sink(n), // $ MISSING: hasValueFlow=14 None => sink(0), } match s2 { @@ -113,6 +126,88 @@ fn option_pattern_match() { } } +enum MyTupleEnum { + A(i64), + B(i64), +} + +fn custom_tuple_enum_pattern_match_qualified() { + let s1 = MyTupleEnum::A(source(15)); + let s2 = MyTupleEnum::B(2); + match s1 { + MyTupleEnum::A(n) => sink(n), // $ MISSING: hasValueFlow=15 + MyTupleEnum::B(n) => sink(n), + } + match s1 { + (MyTupleEnum::A(n) | MyTupleEnum::B(n)) => sink(n), // $ MISSING: hasValueFlow=15 + } + match s2 { + MyTupleEnum::A(n) => sink(n), + MyTupleEnum::B(n) => sink(n), + } +} + +use crate::MyTupleEnum::*; + +fn custom_tuple_enum_pattern_match_unqualified() { + let s1 = A(source(16)); + let s2 = B(2); + match s1 { + A(n) => sink(n), // $ MISSING: hasValueFlow=16 + B(n) => sink(n), + } + match s1 { + (A(n) | B(n)) => sink(n), // $ MISSING: hasValueFlow=16 + } + match s2 { + A(n) => sink(n), + B(n) => sink(n), + } +} + +enum MyRecordEnum { + C { field_c: i64 }, + D { field_d: i64 }, +} + +fn custom_record_enum_pattern_match_qualified() { + let s1 = MyRecordEnum::C { + field_c: source(17), + }; + let s2 = MyRecordEnum::D { field_d: 2 }; + match s1 { + MyRecordEnum::C { field_c: n } => sink(n), // $ MISSING: hasValueFlow=17 + MyRecordEnum::D { field_d: n } => sink(n), + } + match s1 { + (MyRecordEnum::C { field_c: n } | MyRecordEnum::D { field_d: n }) => sink(n), // $ MISSING: hasValueFlow=17 + } + match s2 { + MyRecordEnum::C { field_c: n } => sink(n), + MyRecordEnum::D { field_d: n } => sink(n), + } +} + +use crate::MyRecordEnum::*; + +fn custom_record_enum_pattern_match_unqualified() { + let s1 = C { + field_c: source(18), + }; + let s2 = D { field_d: 2 }; + match s1 { + C { field_c: n } => sink(n), // $ MISSING: hasValueFlow=18 + D { field_d: n } => sink(n), + } + match s1 { + (C { field_c: n } | D { field_d: n }) => sink(n), // $ MISSING: hasValueFlow=18 + } + match s2 { + C { field_c: n } => sink(n), + D { field_d: n } => sink(n), + } +} + fn block_expression1() -> i64 { let a = { 0 }; a @@ -149,7 +244,12 @@ fn main() { tuple(); struct_field(); struct_pattern_match(); - option_pattern_match(); + option_pattern_match_qualified(); + option_pattern_match_unqualified(); + custom_tuple_enum_pattern_match_qualified(); + custom_tuple_enum_pattern_match_unqualified(); + custom_record_enum_pattern_match_qualified(); + custom_record_enum_pattern_match_unqualified(); block_expression1(); block_expression2(true); block_expression3(true); From 2fb670a27c65f88897bfeb1ebacaf5df8bbf6826 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 22 Nov 2024 14:54:20 +0100 Subject: [PATCH 237/470] Rust: Do not print `unit` type in data flow --- .../rust/dataflow/internal/DataFlowImpl.qll | 4 +- .../dataflow/barrier/inline-flow.expected | 36 +++--- .../dataflow/global/inline-flow.expected | 122 +++++++++--------- .../dataflow/local/inline-flow.expected | 30 ++--- 4 files changed, 97 insertions(+), 95 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 91f8065ab5a..7c78db0588b 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -450,7 +450,9 @@ module RustDataFlow implements InputSig { // NOTE: For now we use the type `Unit` and do not benefit from type // information in the data flow analysis. - final class DataFlowType = Unit; + final class DataFlowType extends Unit { + string toString() { result = "" } + } predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { any() } diff --git a/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected b/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected index 660aee69086..7df553b65a0 100644 --- a/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected @@ -1,29 +1,29 @@ models edges -| main.rs:9:13:9:19 | ...: ... : unit | main.rs:9:30:14:1 | { ... } : unit | provenance | | -| main.rs:21:13:21:21 | source(...) : unit | main.rs:22:10:22:10 | s | provenance | | -| main.rs:26:13:26:21 | source(...) : unit | main.rs:27:22:27:22 | s : unit | provenance | | -| main.rs:27:13:27:23 | sanitize(...) : unit | main.rs:28:10:28:10 | s | provenance | | -| main.rs:27:22:27:22 | s : unit | main.rs:9:13:9:19 | ...: ... : unit | provenance | | -| main.rs:27:22:27:22 | s : unit | main.rs:27:13:27:23 | sanitize(...) : unit | provenance | | -| main.rs:32:13:32:21 | source(...) : unit | main.rs:33:10:33:10 | s | provenance | | +| main.rs:9:13:9:19 | ...: ... | main.rs:9:30:14:1 | { ... } | provenance | | +| main.rs:21:13:21:21 | source(...) | main.rs:22:10:22:10 | s | provenance | | +| main.rs:26:13:26:21 | source(...) | main.rs:27:22:27:22 | s | provenance | | +| main.rs:27:13:27:23 | sanitize(...) | main.rs:28:10:28:10 | s | provenance | | +| main.rs:27:22:27:22 | s | main.rs:9:13:9:19 | ...: ... | provenance | | +| main.rs:27:22:27:22 | s | main.rs:27:13:27:23 | sanitize(...) | provenance | | +| main.rs:32:13:32:21 | source(...) | main.rs:33:10:33:10 | s | provenance | | nodes -| main.rs:9:13:9:19 | ...: ... : unit | semmle.label | ...: ... : unit | -| main.rs:9:30:14:1 | { ... } : unit | semmle.label | { ... } : unit | +| main.rs:9:13:9:19 | ...: ... | semmle.label | ...: ... | +| main.rs:9:30:14:1 | { ... } | semmle.label | { ... } | | main.rs:17:10:17:18 | source(...) | semmle.label | source(...) | -| main.rs:21:13:21:21 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:21:13:21:21 | source(...) | semmle.label | source(...) | | main.rs:22:10:22:10 | s | semmle.label | s | -| main.rs:26:13:26:21 | source(...) : unit | semmle.label | source(...) : unit | -| main.rs:27:13:27:23 | sanitize(...) : unit | semmle.label | sanitize(...) : unit | -| main.rs:27:22:27:22 | s : unit | semmle.label | s : unit | +| main.rs:26:13:26:21 | source(...) | semmle.label | source(...) | +| main.rs:27:13:27:23 | sanitize(...) | semmle.label | sanitize(...) | +| main.rs:27:22:27:22 | s | semmle.label | s | | main.rs:28:10:28:10 | s | semmle.label | s | -| main.rs:32:13:32:21 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:32:13:32:21 | source(...) | semmle.label | source(...) | | main.rs:33:10:33:10 | s | semmle.label | s | subpaths -| main.rs:27:22:27:22 | s : unit | main.rs:9:13:9:19 | ...: ... : unit | main.rs:9:30:14:1 | { ... } : unit | main.rs:27:13:27:23 | sanitize(...) : unit | +| main.rs:27:22:27:22 | s | main.rs:9:13:9:19 | ...: ... | main.rs:9:30:14:1 | { ... } | main.rs:27:13:27:23 | sanitize(...) | testFailures #select | main.rs:17:10:17:18 | source(...) | main.rs:17:10:17:18 | source(...) | main.rs:17:10:17:18 | source(...) | $@ | main.rs:17:10:17:18 | source(...) | source(...) | -| main.rs:22:10:22:10 | s | main.rs:21:13:21:21 | source(...) : unit | main.rs:22:10:22:10 | s | $@ | main.rs:21:13:21:21 | source(...) : unit | source(...) : unit | -| main.rs:28:10:28:10 | s | main.rs:26:13:26:21 | source(...) : unit | main.rs:28:10:28:10 | s | $@ | main.rs:26:13:26:21 | source(...) : unit | source(...) : unit | -| main.rs:33:10:33:10 | s | main.rs:32:13:32:21 | source(...) : unit | main.rs:33:10:33:10 | s | $@ | main.rs:32:13:32:21 | source(...) : unit | source(...) : unit | +| main.rs:22:10:22:10 | s | main.rs:21:13:21:21 | source(...) | main.rs:22:10:22:10 | s | $@ | main.rs:21:13:21:21 | source(...) | source(...) | +| main.rs:28:10:28:10 | s | main.rs:26:13:26:21 | source(...) | main.rs:28:10:28:10 | s | $@ | main.rs:26:13:26:21 | source(...) | source(...) | +| main.rs:33:10:33:10 | s | main.rs:32:13:32:21 | source(...) | main.rs:33:10:33:10 | s | $@ | main.rs:32:13:32:21 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/global/inline-flow.expected b/rust/ql/test/library-tests/dataflow/global/inline-flow.expected index 147fa059c31..89fa0442293 100644 --- a/rust/ql/test/library-tests/dataflow/global/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/global/inline-flow.expected @@ -1,74 +1,74 @@ models edges -| main.rs:12:28:14:1 | { ... } : unit | main.rs:17:13:17:23 | get_data(...) : unit | provenance | | -| main.rs:13:5:13:13 | source(...) : unit | main.rs:12:28:14:1 | { ... } : unit | provenance | | -| main.rs:17:13:17:23 | get_data(...) : unit | main.rs:18:10:18:10 | a | provenance | | -| main.rs:21:12:21:17 | ...: i64 : unit | main.rs:22:10:22:10 | n | provenance | | -| main.rs:26:13:26:21 | source(...) : unit | main.rs:27:13:27:13 | a : unit | provenance | | -| main.rs:27:13:27:13 | a : unit | main.rs:21:12:21:17 | ...: i64 : unit | provenance | | -| main.rs:30:17:30:22 | ...: i64 : unit | main.rs:30:32:32:1 | { ... } : unit | provenance | | -| main.rs:35:13:35:21 | source(...) : unit | main.rs:36:26:36:26 | a : unit | provenance | | -| main.rs:36:13:36:27 | pass_through(...) : unit | main.rs:37:10:37:10 | b | provenance | | -| main.rs:36:26:36:26 | a : unit | main.rs:30:17:30:22 | ...: i64 : unit | provenance | | -| main.rs:36:26:36:26 | a : unit | main.rs:36:13:36:27 | pass_through(...) : unit | provenance | | -| main.rs:41:13:44:6 | pass_through(...) : unit | main.rs:45:10:45:10 | a | provenance | | -| main.rs:41:26:44:5 | { ... } : unit | main.rs:30:17:30:22 | ...: i64 : unit | provenance | | -| main.rs:41:26:44:5 | { ... } : unit | main.rs:41:13:44:6 | pass_through(...) : unit | provenance | | -| main.rs:43:9:43:18 | source(...) : unit | main.rs:41:26:44:5 | { ... } : unit | provenance | | -| main.rs:56:23:56:28 | ...: i64 : unit | main.rs:57:14:57:14 | n | provenance | | -| main.rs:59:31:65:5 | { ... } : unit | main.rs:77:13:77:25 | ... .get_data(...) : unit | provenance | | -| main.rs:63:13:63:21 | source(...) : unit | main.rs:59:31:65:5 | { ... } : unit | provenance | | -| main.rs:66:28:66:33 | ...: i64 : unit | main.rs:66:43:72:5 | { ... } : unit | provenance | | -| main.rs:77:13:77:25 | ... .get_data(...) : unit | main.rs:78:10:78:10 | a | provenance | | -| main.rs:83:13:83:21 | source(...) : unit | main.rs:84:16:84:16 | a : unit | provenance | | -| main.rs:84:16:84:16 | a : unit | main.rs:56:23:56:28 | ...: i64 : unit | provenance | | -| main.rs:89:13:89:21 | source(...) : unit | main.rs:90:29:90:29 | a : unit | provenance | | -| main.rs:90:13:90:30 | ... .data_through(...) : unit | main.rs:91:10:91:10 | b | provenance | | -| main.rs:90:29:90:29 | a : unit | main.rs:66:28:66:33 | ...: i64 : unit | provenance | | -| main.rs:90:29:90:29 | a : unit | main.rs:90:13:90:30 | ... .data_through(...) : unit | provenance | | +| main.rs:12:28:14:1 | { ... } | main.rs:17:13:17:23 | get_data(...) | provenance | | +| main.rs:13:5:13:13 | source(...) | main.rs:12:28:14:1 | { ... } | provenance | | +| main.rs:17:13:17:23 | get_data(...) | main.rs:18:10:18:10 | a | provenance | | +| main.rs:21:12:21:17 | ...: i64 | main.rs:22:10:22:10 | n | provenance | | +| main.rs:26:13:26:21 | source(...) | main.rs:27:13:27:13 | a | provenance | | +| main.rs:27:13:27:13 | a | main.rs:21:12:21:17 | ...: i64 | provenance | | +| main.rs:30:17:30:22 | ...: i64 | main.rs:30:32:32:1 | { ... } | provenance | | +| main.rs:35:13:35:21 | source(...) | main.rs:36:26:36:26 | a | provenance | | +| main.rs:36:13:36:27 | pass_through(...) | main.rs:37:10:37:10 | b | provenance | | +| main.rs:36:26:36:26 | a | main.rs:30:17:30:22 | ...: i64 | provenance | | +| main.rs:36:26:36:26 | a | main.rs:36:13:36:27 | pass_through(...) | provenance | | +| main.rs:41:13:44:6 | pass_through(...) | main.rs:45:10:45:10 | a | provenance | | +| main.rs:41:26:44:5 | { ... } | main.rs:30:17:30:22 | ...: i64 | provenance | | +| main.rs:41:26:44:5 | { ... } | main.rs:41:13:44:6 | pass_through(...) | provenance | | +| main.rs:43:9:43:18 | source(...) | main.rs:41:26:44:5 | { ... } | provenance | | +| main.rs:56:23:56:28 | ...: i64 | main.rs:57:14:57:14 | n | provenance | | +| main.rs:59:31:65:5 | { ... } | main.rs:77:13:77:25 | ... .get_data(...) | provenance | | +| main.rs:63:13:63:21 | source(...) | main.rs:59:31:65:5 | { ... } | provenance | | +| main.rs:66:28:66:33 | ...: i64 | main.rs:66:43:72:5 | { ... } | provenance | | +| main.rs:77:13:77:25 | ... .get_data(...) | main.rs:78:10:78:10 | a | provenance | | +| main.rs:83:13:83:21 | source(...) | main.rs:84:16:84:16 | a | provenance | | +| main.rs:84:16:84:16 | a | main.rs:56:23:56:28 | ...: i64 | provenance | | +| main.rs:89:13:89:21 | source(...) | main.rs:90:29:90:29 | a | provenance | | +| main.rs:90:13:90:30 | ... .data_through(...) | main.rs:91:10:91:10 | b | provenance | | +| main.rs:90:29:90:29 | a | main.rs:66:28:66:33 | ...: i64 | provenance | | +| main.rs:90:29:90:29 | a | main.rs:90:13:90:30 | ... .data_through(...) | provenance | | nodes -| main.rs:12:28:14:1 | { ... } : unit | semmle.label | { ... } : unit | -| main.rs:13:5:13:13 | source(...) : unit | semmle.label | source(...) : unit | -| main.rs:17:13:17:23 | get_data(...) : unit | semmle.label | get_data(...) : unit | +| main.rs:12:28:14:1 | { ... } | semmle.label | { ... } | +| main.rs:13:5:13:13 | source(...) | semmle.label | source(...) | +| main.rs:17:13:17:23 | get_data(...) | semmle.label | get_data(...) | | main.rs:18:10:18:10 | a | semmle.label | a | -| main.rs:21:12:21:17 | ...: i64 : unit | semmle.label | ...: i64 : unit | +| main.rs:21:12:21:17 | ...: i64 | semmle.label | ...: i64 | | main.rs:22:10:22:10 | n | semmle.label | n | -| main.rs:26:13:26:21 | source(...) : unit | semmle.label | source(...) : unit | -| main.rs:27:13:27:13 | a : unit | semmle.label | a : unit | -| main.rs:30:17:30:22 | ...: i64 : unit | semmle.label | ...: i64 : unit | -| main.rs:30:32:32:1 | { ... } : unit | semmle.label | { ... } : unit | -| main.rs:35:13:35:21 | source(...) : unit | semmle.label | source(...) : unit | -| main.rs:36:13:36:27 | pass_through(...) : unit | semmle.label | pass_through(...) : unit | -| main.rs:36:26:36:26 | a : unit | semmle.label | a : unit | +| main.rs:26:13:26:21 | source(...) | semmle.label | source(...) | +| main.rs:27:13:27:13 | a | semmle.label | a | +| main.rs:30:17:30:22 | ...: i64 | semmle.label | ...: i64 | +| main.rs:30:32:32:1 | { ... } | semmle.label | { ... } | +| main.rs:35:13:35:21 | source(...) | semmle.label | source(...) | +| main.rs:36:13:36:27 | pass_through(...) | semmle.label | pass_through(...) | +| main.rs:36:26:36:26 | a | semmle.label | a | | main.rs:37:10:37:10 | b | semmle.label | b | -| main.rs:41:13:44:6 | pass_through(...) : unit | semmle.label | pass_through(...) : unit | -| main.rs:41:26:44:5 | { ... } : unit | semmle.label | { ... } : unit | -| main.rs:43:9:43:18 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:41:13:44:6 | pass_through(...) | semmle.label | pass_through(...) | +| main.rs:41:26:44:5 | { ... } | semmle.label | { ... } | +| main.rs:43:9:43:18 | source(...) | semmle.label | source(...) | | main.rs:45:10:45:10 | a | semmle.label | a | -| main.rs:56:23:56:28 | ...: i64 : unit | semmle.label | ...: i64 : unit | +| main.rs:56:23:56:28 | ...: i64 | semmle.label | ...: i64 | | main.rs:57:14:57:14 | n | semmle.label | n | -| main.rs:59:31:65:5 | { ... } : unit | semmle.label | { ... } : unit | -| main.rs:63:13:63:21 | source(...) : unit | semmle.label | source(...) : unit | -| main.rs:66:28:66:33 | ...: i64 : unit | semmle.label | ...: i64 : unit | -| main.rs:66:43:72:5 | { ... } : unit | semmle.label | { ... } : unit | -| main.rs:77:13:77:25 | ... .get_data(...) : unit | semmle.label | ... .get_data(...) : unit | +| main.rs:59:31:65:5 | { ... } | semmle.label | { ... } | +| main.rs:63:13:63:21 | source(...) | semmle.label | source(...) | +| main.rs:66:28:66:33 | ...: i64 | semmle.label | ...: i64 | +| main.rs:66:43:72:5 | { ... } | semmle.label | { ... } | +| main.rs:77:13:77:25 | ... .get_data(...) | semmle.label | ... .get_data(...) | | main.rs:78:10:78:10 | a | semmle.label | a | -| main.rs:83:13:83:21 | source(...) : unit | semmle.label | source(...) : unit | -| main.rs:84:16:84:16 | a : unit | semmle.label | a : unit | -| main.rs:89:13:89:21 | source(...) : unit | semmle.label | source(...) : unit | -| main.rs:90:13:90:30 | ... .data_through(...) : unit | semmle.label | ... .data_through(...) : unit | -| main.rs:90:29:90:29 | a : unit | semmle.label | a : unit | +| main.rs:83:13:83:21 | source(...) | semmle.label | source(...) | +| main.rs:84:16:84:16 | a | semmle.label | a | +| main.rs:89:13:89:21 | source(...) | semmle.label | source(...) | +| main.rs:90:13:90:30 | ... .data_through(...) | semmle.label | ... .data_through(...) | +| main.rs:90:29:90:29 | a | semmle.label | a | | main.rs:91:10:91:10 | b | semmle.label | b | subpaths -| main.rs:36:26:36:26 | a : unit | main.rs:30:17:30:22 | ...: i64 : unit | main.rs:30:32:32:1 | { ... } : unit | main.rs:36:13:36:27 | pass_through(...) : unit | -| main.rs:41:26:44:5 | { ... } : unit | main.rs:30:17:30:22 | ...: i64 : unit | main.rs:30:32:32:1 | { ... } : unit | main.rs:41:13:44:6 | pass_through(...) : unit | -| main.rs:90:29:90:29 | a : unit | main.rs:66:28:66:33 | ...: i64 : unit | main.rs:66:43:72:5 | { ... } : unit | main.rs:90:13:90:30 | ... .data_through(...) : unit | +| main.rs:36:26:36:26 | a | main.rs:30:17:30:22 | ...: i64 | main.rs:30:32:32:1 | { ... } | main.rs:36:13:36:27 | pass_through(...) | +| main.rs:41:26:44:5 | { ... } | main.rs:30:17:30:22 | ...: i64 | main.rs:30:32:32:1 | { ... } | main.rs:41:13:44:6 | pass_through(...) | +| main.rs:90:29:90:29 | a | main.rs:66:28:66:33 | ...: i64 | main.rs:66:43:72:5 | { ... } | main.rs:90:13:90:30 | ... .data_through(...) | testFailures #select -| main.rs:18:10:18:10 | a | main.rs:13:5:13:13 | source(...) : unit | main.rs:18:10:18:10 | a | $@ | main.rs:13:5:13:13 | source(...) : unit | source(...) : unit | -| main.rs:22:10:22:10 | n | main.rs:26:13:26:21 | source(...) : unit | main.rs:22:10:22:10 | n | $@ | main.rs:26:13:26:21 | source(...) : unit | source(...) : unit | -| main.rs:37:10:37:10 | b | main.rs:35:13:35:21 | source(...) : unit | main.rs:37:10:37:10 | b | $@ | main.rs:35:13:35:21 | source(...) : unit | source(...) : unit | -| main.rs:45:10:45:10 | a | main.rs:43:9:43:18 | source(...) : unit | main.rs:45:10:45:10 | a | $@ | main.rs:43:9:43:18 | source(...) : unit | source(...) : unit | -| main.rs:57:14:57:14 | n | main.rs:83:13:83:21 | source(...) : unit | main.rs:57:14:57:14 | n | $@ | main.rs:83:13:83:21 | source(...) : unit | source(...) : unit | -| main.rs:78:10:78:10 | a | main.rs:63:13:63:21 | source(...) : unit | main.rs:78:10:78:10 | a | $@ | main.rs:63:13:63:21 | source(...) : unit | source(...) : unit | -| main.rs:91:10:91:10 | b | main.rs:89:13:89:21 | source(...) : unit | main.rs:91:10:91:10 | b | $@ | main.rs:89:13:89:21 | source(...) : unit | source(...) : unit | +| main.rs:18:10:18:10 | a | main.rs:13:5:13:13 | source(...) | main.rs:18:10:18:10 | a | $@ | main.rs:13:5:13:13 | source(...) | source(...) | +| main.rs:22:10:22:10 | n | main.rs:26:13:26:21 | source(...) | main.rs:22:10:22:10 | n | $@ | main.rs:26:13:26:21 | source(...) | source(...) | +| main.rs:37:10:37:10 | b | main.rs:35:13:35:21 | source(...) | main.rs:37:10:37:10 | b | $@ | main.rs:35:13:35:21 | source(...) | source(...) | +| main.rs:45:10:45:10 | a | main.rs:43:9:43:18 | source(...) | main.rs:45:10:45:10 | a | $@ | main.rs:43:9:43:18 | source(...) | source(...) | +| main.rs:57:14:57:14 | n | main.rs:83:13:83:21 | source(...) | main.rs:57:14:57:14 | n | $@ | main.rs:83:13:83:21 | source(...) | source(...) | +| main.rs:78:10:78:10 | a | main.rs:63:13:63:21 | source(...) | main.rs:78:10:78:10 | a | $@ | main.rs:63:13:63:21 | source(...) | source(...) | +| main.rs:91:10:91:10 | b | main.rs:89:13:89:21 | source(...) | main.rs:91:10:91:10 | b | $@ | main.rs:89:13:89:21 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index 0932efcf484..f8585809e94 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -1,28 +1,28 @@ models edges -| main.rs:19:13:19:21 | source(...) : unit | main.rs:20:10:20:10 | s | provenance | | -| main.rs:24:13:24:21 | source(...) : unit | main.rs:27:10:27:10 | c | provenance | | -| main.rs:31:13:31:21 | source(...) : unit | main.rs:36:10:36:10 | b | provenance | | -| main.rs:45:15:45:23 | source(...) : unit | main.rs:47:10:47:10 | b | provenance | | -| main.rs:53:9:53:17 | source(...) : unit | main.rs:54:10:54:10 | i | provenance | | +| main.rs:19:13:19:21 | source(...) | main.rs:20:10:20:10 | s | provenance | | +| main.rs:24:13:24:21 | source(...) | main.rs:27:10:27:10 | c | provenance | | +| main.rs:31:13:31:21 | source(...) | main.rs:36:10:36:10 | b | provenance | | +| main.rs:45:15:45:23 | source(...) | main.rs:47:10:47:10 | b | provenance | | +| main.rs:53:9:53:17 | source(...) | main.rs:54:10:54:10 | i | provenance | | nodes | main.rs:15:10:15:18 | source(...) | semmle.label | source(...) | -| main.rs:19:13:19:21 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:19:13:19:21 | source(...) | semmle.label | source(...) | | main.rs:20:10:20:10 | s | semmle.label | s | -| main.rs:24:13:24:21 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:24:13:24:21 | source(...) | semmle.label | source(...) | | main.rs:27:10:27:10 | c | semmle.label | c | -| main.rs:31:13:31:21 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:31:13:31:21 | source(...) | semmle.label | source(...) | | main.rs:36:10:36:10 | b | semmle.label | b | -| main.rs:45:15:45:23 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:45:15:45:23 | source(...) | semmle.label | source(...) | | main.rs:47:10:47:10 | b | semmle.label | b | -| main.rs:53:9:53:17 | source(...) : unit | semmle.label | source(...) : unit | +| main.rs:53:9:53:17 | source(...) | semmle.label | source(...) | | main.rs:54:10:54:10 | i | semmle.label | i | subpaths testFailures #select | main.rs:15:10:15:18 | source(...) | main.rs:15:10:15:18 | source(...) | main.rs:15:10:15:18 | source(...) | $@ | main.rs:15:10:15:18 | source(...) | source(...) | -| main.rs:20:10:20:10 | s | main.rs:19:13:19:21 | source(...) : unit | main.rs:20:10:20:10 | s | $@ | main.rs:19:13:19:21 | source(...) : unit | source(...) : unit | -| main.rs:27:10:27:10 | c | main.rs:24:13:24:21 | source(...) : unit | main.rs:27:10:27:10 | c | $@ | main.rs:24:13:24:21 | source(...) : unit | source(...) : unit | -| main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | source(...) : unit | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | source(...) : unit | source(...) : unit | -| main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | source(...) : unit | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | source(...) : unit | source(...) : unit | -| main.rs:54:10:54:10 | i | main.rs:53:9:53:17 | source(...) : unit | main.rs:54:10:54:10 | i | $@ | main.rs:53:9:53:17 | source(...) : unit | source(...) : unit | +| main.rs:20:10:20:10 | s | main.rs:19:13:19:21 | source(...) | main.rs:20:10:20:10 | s | $@ | main.rs:19:13:19:21 | source(...) | source(...) | +| main.rs:27:10:27:10 | c | main.rs:24:13:24:21 | source(...) | main.rs:27:10:27:10 | c | $@ | main.rs:24:13:24:21 | source(...) | source(...) | +| main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | source(...) | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | source(...) | source(...) | +| main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | source(...) | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | source(...) | source(...) | +| main.rs:54:10:54:10 | i | main.rs:53:9:53:17 | source(...) | main.rs:54:10:54:10 | i | $@ | main.rs:53:9:53:17 | source(...) | source(...) | From 5e7cd461178d756b739700e397784b73b99a6286 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 22 Nov 2024 14:54:39 +0100 Subject: [PATCH 238/470] Rust: Flow through variants --- .../lib/codeql/rust/controlflow/CfgNodes.qll | 36 +- .../rust/controlflow/internal/CfgNodes.qll | 6 + rust/ql/lib/codeql/rust/dataflow/DataFlow.qll | 6 + .../rust/dataflow/internal/DataFlowImpl.qll | 348 ++++++++++++++---- .../dataflow/local/DataFlowStep.expected | 60 +++ .../dataflow/local/inline-flow.expected | 44 +++ .../test/library-tests/dataflow/local/main.rs | 10 +- 7 files changed, 427 insertions(+), 83 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll index 3ee3a3eeb61..07bc8946bc1 100644 --- a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll @@ -187,9 +187,37 @@ final class RecordExprCfgNode extends Nodes::RecordExprCfgNode { RecordExprCfgNode() { node = this.getRecordExpr() } - /** Gets the `i`th record expression. */ - ExprCfgNode getExpr(int i) { - any(ChildMapping mapping) - .hasCfgChild(node, node.getRecordExprFieldList().getField(i).getExpr(), this, result) + /** Gets the record expression for the field `field`. */ + pragma[nomagic] + ExprCfgNode getFieldExpr(string field) { + exists(RecordExprField ref | + ref = node.getRecordExprFieldList().getAField() and + any(ChildMapping mapping).hasCfgChild(node, ref.getExpr(), this, result) and + field = ref.getNameRef().getText() + ) + } +} + +/** + * A record pattern. For example: + * ```rust + * match x { + * Foo { a: 1, b: 2 } => "ok", + * Foo { .. } => "fail", + * } + * ``` + */ +final class RecordPatCfgNode extends Nodes::RecordPatCfgNode { + private RecordPatChildMapping node; + + RecordPatCfgNode() { node = this.getRecordPat() } + + /** Gets the record pattern for the field `field`. */ + PatCfgNode getFieldPat(string field) { + exists(RecordPatField rpf | + rpf = node.getRecordPatFieldList().getAField() and + any(ChildMapping mapping).hasCfgChild(node, rpf.getPat(), this, result) and + field = rpf.getNameRef().getText() + ) } } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll index fc0df95f24a..0f3dee7a9f4 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll @@ -68,6 +68,12 @@ class RecordExprChildMapping extends ParentAstNode, RecordExpr { } } +class RecordPatChildMapping extends ParentAstNode, RecordPat { + override predicate relevantChild(AstNode child) { + child = this.getRecordPatFieldList().getAField().getPat() + } +} + class FormatArgsExprChildMapping extends ParentAstNode, CfgImpl::ExprTrees::FormatArgsExprTree { override predicate relevantChild(AstNode child) { child = this.getChildNode(_) } } diff --git a/rust/ql/lib/codeql/rust/dataflow/DataFlow.qll b/rust/ql/lib/codeql/rust/dataflow/DataFlow.qll index 3a09df2c45d..c0d47f8f6a7 100644 --- a/rust/ql/lib/codeql/rust/dataflow/DataFlow.qll +++ b/rust/ql/lib/codeql/rust/dataflow/DataFlow.qll @@ -19,6 +19,12 @@ module DataFlow { final class PostUpdateNode = Node::PostUpdateNode; + final class Content = DataFlowImpl::Content; + + final class VariantContent = DataFlowImpl::VariantContent; + + final class ContentSet = DataFlowImpl::ContentSet; + /** * Holds if data flows from `nodeFrom` to `nodeTo` in exactly one local * (intra-procedural) step. diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 7c78db0588b..808b410c8d0 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -115,6 +115,11 @@ module Node { */ ExprCfgNode asExpr() { none() } + /** + * Gets the pattern that corresponds to this node, if any. + */ + PatCfgNode asPat() { none() } + /** Gets the enclosing callable. */ DataFlowCallable getEnclosingCallable() { result = TCfgScope(this.getCfgScope()) } @@ -177,8 +182,7 @@ module Node { PatNode() { this = TPatNode(n) } - /** Gets the `PatCfgNode` in the CFG that this node corresponds to. */ - PatCfgNode getPat() { result = n } + override PatCfgNode asPat() { result = n } } /** @@ -322,8 +326,7 @@ module LocalFlow { nodeFrom.(Node::AstCfgFlowNode).getCfgNode() = nodeTo.(Node::SsaNode).getDefinitionExt().(Ssa::WriteDefinition).getControlFlowNode() or - nodeFrom.(Node::ParameterNode).getParameter().(ParamCfgNode).getPat() = - nodeTo.(Node::PatNode).getPat() + nodeFrom.(Node::ParameterNode).getParameter().(ParamCfgNode).getPat() = nodeTo.asPat() or SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _) or @@ -331,18 +334,165 @@ module LocalFlow { a.getRhs() = nodeFrom.getCfgNode() and a.getLhs() = nodeTo.getCfgNode() ) + or + exists(MatchExprCfgNode match | + nodeFrom.asExpr() = match.getScrutinee() and + nodeTo.asPat() = match.getArmPat(_) + ) + or + nodeFrom.asPat().(OrPatCfgNode).getAPat() = nodeTo.asPat() } } -private class DataFlowCallableAlias = DataFlowCallable; +private import codeql.util.Option -private class ReturnKindAlias = ReturnKind; +private class CrateOrigin extends string { + CrateOrigin() { + this = [any(Item i).getCrateOrigin(), any(Resolvable r).getResolvedCrateOrigin()] + } +} -private class DataFlowCallAlias = DataFlowCall; +private class CrateOriginOption = Option::Option; -private class ParameterPositionAlias = ParameterPosition; +pragma[nomagic] +private predicate hasExtendedCanonicalPath(Item i, CrateOriginOption crate, string path) { + path = i.getExtendedCanonicalPath() and + ( + crate.asSome() = i.getCrateOrigin() + or + crate.isNone() and + not i.hasCrateOrigin() + ) +} + +pragma[nomagic] +private predicate variantHasExtendedCanonicalPath( + Enum e, Variant v, CrateOriginOption crate, string path, string name +) { + hasExtendedCanonicalPath(e, crate, path) and + v = e.getVariantList().getAVariant() and + name = v.getName().getText() +} + +pragma[nomagic] +private predicate resolveExtendedCanonicalPath(Resolvable r, CrateOriginOption crate, string path) { + path = r.getResolvedPath() and + ( + crate.asSome() = r.getResolvedCrateOrigin() + or + crate.isNone() and + not r.hasResolvedCrateOrigin() + ) +} + +/** + * A reference contained in an object. For example a field in a struct. + */ +abstract class Content extends TContent { + /** Gets a textual representation of this content. */ + abstract string toString(); +} + +/** A canonical path pointing to an enum variant. */ +private class VariantCanonicalPath extends MkVariantCanonicalPath { + CrateOriginOption crate; + string path; + string name; + + VariantCanonicalPath() { this = MkVariantCanonicalPath(crate, path, name) } + + /** Gets the underlying variant. */ + Variant getVariant() { variantHasExtendedCanonicalPath(_, result, crate, path, name) } + + string toString() { result = name } + + Location getLocation() { result = this.getVariant().getLocation() } +} + +/** + * A variant of an `enum`. In addition to the variant itself, this also includes the + * position (for tuple variants) or the field name (for record variants). + */ +abstract class VariantContent extends Content { } + +/** A tuple variant. */ +private class TupleVariantContent extends VariantContent, TTupleVariantContent { + private VariantCanonicalPath v; + private int pos_; + + TupleVariantContent() { this = TTupleVariantContent(v, pos_) } + + VariantCanonicalPath getVariantCanonicalPath(int pos) { result = v and pos = pos_ } + + final override string toString() { + // only print indices when the arity is > 1 + if exists(TTupleVariantContent(v, 1)) + then result = v.toString() + "(" + pos_ + ")" + else result = v.toString() + } +} + +/** A record variant. */ +private class RecordVariantContent extends VariantContent, TRecordVariantContent { + private VariantCanonicalPath v; + private string field_; + + RecordVariantContent() { this = TRecordVariantContent(v, field_) } + + VariantCanonicalPath getVariantCanonicalPath(string field) { result = v and field = field_ } + + final override string toString() { + // only print field when the arity is > 1 + if strictcount(string f | exists(TRecordVariantContent(v, f))) > 1 + then result = v.toString() + "{" + field_ + "}" + else result = v.toString() + } +} + +/** A value that represents a set of `Content`s. */ +abstract class ContentSet extends TContentSet { + /** Gets a textual representation of this element. */ + abstract string toString(); + + /** Gets a content that may be stored into when storing into this set. */ + abstract Content getAStoreContent(); + + /** Gets a content that may be read from when reading from this set. */ + abstract Content getAReadContent(); +} + +private class SingletonContentSet extends ContentSet, TSingletonContentSet { + private Content c; + + SingletonContentSet() { this = TSingletonContentSet(c) } + + Content getContent() { result = c } + + override string toString() { result = c.toString() } + + override Content getAStoreContent() { result = c } + + override Content getAReadContent() { result = c } +} + +// Defines a set of aliases needed for the `RustDataFlow` module +private module Aliases { + class DataFlowCallableAlias = DataFlowCallable; + + class ReturnKindAlias = ReturnKind; + + class DataFlowCallAlias = DataFlowCall; + + class ParameterPositionAlias = ParameterPosition; + + class ContentAlias = Content; + + class ContentSetAlias = ContentSet; +} module RustDataFlow implements InputSig { + private import Aliases + /** * An element, viewed as a node in a data flow graph. Either an expression * (`ExprNode`) or a parameter (`ParameterNode`). @@ -388,55 +538,22 @@ module RustDataFlow implements InputSig { final class ReturnKind = ReturnKindAlias; - private import codeql.util.Option - - private class CrateOrigin extends string { - CrateOrigin() { - this = [any(Item i).getCrateOrigin(), any(Resolvable r).getResolvedCrateOrigin()] - } - } - - private class CrateOriginOption = Option::Option; - pragma[nomagic] - private predicate hasExtendedCanonicalPath( - DataFlowCallable c, CrateOriginOption crate, string path + private predicate callResolveExtendedCanonicalPath( + CallExprBase call, CrateOriginOption crate, string path ) { - exists(Item i | - i = c.asCfgScope() and - path = i.getExtendedCanonicalPath() - | - crate.asSome() = i.getCrateOrigin() + exists(Resolvable r | resolveExtendedCanonicalPath(r, crate, path) | + r = call.(MethodCallExpr) or - crate.isNone() and - not i.hasCrateOrigin() - ) - } - - pragma[nomagic] - private predicate resolvesExtendedCanonicalPath( - DataFlowCall c, CrateOriginOption crate, string path - ) { - exists(Resolvable r | - path = r.getResolvedPath() and - ( - r = c.asMethodCallExprCfgNode().getExpr() - or - r = c.asCallExprCfgNode().getExpr().(PathExprCfgNode).getPath() - ) - | - crate.asSome() = r.getResolvedCrateOrigin() - or - crate.isNone() and - not r.hasResolvedCrateOrigin() + r = call.(CallExpr).getExpr().(PathExpr).getPath() ) } /** Gets a viable implementation of the target of the given `Call`. */ DataFlowCallable viableCallable(DataFlowCall call) { exists(string path, CrateOriginOption crate | - hasExtendedCanonicalPath(result, crate, path) and - resolvesExtendedCanonicalPath(call, crate, path) + hasExtendedCanonicalPath(result.asCfgScope(), crate, path) and + callResolveExtendedCanonicalPath(call.asCallBaseExprCfgNode().getExpr(), crate, path) ) } @@ -458,24 +575,15 @@ module RustDataFlow implements InputSig { predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() } - final class Content = Void; + class Content = ContentAlias; + + class ContentSet = ContentSetAlias; predicate forceHighPrecision(Content c) { none() } - class ContentSet extends TContentSet { - /** Gets a textual representation of this element. */ - string toString() { result = "ContentSet" } + final class ContentApprox = Content; // todo - /** Gets a content that may be stored into when storing into this set. */ - Content getAStoreContent() { none() } - - /** Gets a content that may be read from when reading from this set. */ - Content getAReadContent() { none() } - } - - final class ContentApprox = Void; - - ContentApprox getContentApprox(Content c) { any() } + ContentApprox getContentApprox(Content c) { result = c } class ParameterPosition = ParameterPositionAlias; @@ -503,19 +611,94 @@ module RustDataFlow implements InputSig { */ predicate jumpStep(Node node1, Node node2) { none() } + /** Holds if path `p` resolves to variant `v`. */ + private predicate pathResolveToVariantCanonicalPath(Path p, VariantCanonicalPath v) { + exists(CrateOriginOption crate, string path | + resolveExtendedCanonicalPath(p.getQualifier(), crate, path) and + v = MkVariantCanonicalPath(crate, path, p.getPart().getNameRef().getText()) + ) + or + // TODO: Remove once library types are extracted + not p.hasQualifier() and + v = MkVariantCanonicalPath(_, "crate::std::option::Option", p.getPart().getNameRef().getText()) + } + + /** Holds if `p` destructs an enum variant `v`. */ + pragma[nomagic] + private predicate tupleVariantDestruction(TupleStructPat p, VariantCanonicalPath v) { + pathResolveToVariantCanonicalPath(p.getPath(), v) + } + + /** Holds if `p` destructs an enum variant `v`. */ + pragma[nomagic] + private predicate recordVariantDestruction(RecordPat p, VariantCanonicalPath v) { + pathResolveToVariantCanonicalPath(p.getPath(), v) + } + /** * Holds if data can flow from `node1` to `node2` via a read of `c`. Thus, * `node1` references an object with a content `c.getAReadContent()` whose * value ends up in `node2`. */ - predicate readStep(Node node1, ContentSet c, Node node2) { none() } + predicate readStep(Node node1, ContentSet cs, Node node2) { + exists(Content c | c = cs.(SingletonContentSet).getContent() | + node1.asPat() = + any(TupleStructPatCfgNode pat, int pos | + tupleVariantDestruction(pat.getPat(), c.(TupleVariantContent).getVariantCanonicalPath(pos)) and + node2.asPat() = pat.getField(pos) + | + pat + ) + or + node1.asPat() = + any(RecordPatCfgNode pat, string field | + recordVariantDestruction(pat.getPat(), + c.(RecordVariantContent).getVariantCanonicalPath(field)) and + node2.asPat() = pat.getFieldPat(field) + | + pat + ) + ) + } + + /** Holds if `ce` constructs an enum value of type `v`. */ + pragma[nomagic] + private predicate tupleVariantConstruction(CallExpr ce, VariantCanonicalPath v) { + pathResolveToVariantCanonicalPath(ce.getExpr().(PathExpr).getPath(), v) + } + + /** Holds if `re` constructs an enum value of type `v`. */ + pragma[nomagic] + private predicate recordVariantConstruction(RecordExpr re, VariantCanonicalPath v) { + pathResolveToVariantCanonicalPath(re.getPath(), v) + } /** * Holds if data can flow from `node1` to `node2` via a store into `c`. Thus, * `node2` references an object with a content `c.getAStoreContent()` that * contains the value of `node1`. */ - predicate storeStep(Node node1, ContentSet c, Node node2) { none() } + predicate storeStep(Node node1, ContentSet cs, Node node2) { + exists(Content c | c = cs.(SingletonContentSet).getContent() | + node2.asExpr() = + any(CallExprCfgNode call, int pos | + tupleVariantConstruction(call.getCallExpr(), + c.(TupleVariantContent).getVariantCanonicalPath(pos)) and + node1.asExpr() = call.getArgument(pos) + | + call + ) + or + node2.asExpr() = + any(RecordExprCfgNode re, string field | + recordVariantConstruction(re.getRecordExpr(), + c.(RecordVariantContent).getVariantCanonicalPath(field)) and + node1.asExpr() = re.getFieldExpr(field) + | + re + ) + ) + } /** * Holds if values stored inside content `c` are cleared at node `n`. For example, @@ -582,8 +765,6 @@ module RustDataFlow implements InputSig { class DataFlowSecondLevelScope = Void; } -final class ContentSet = RustDataFlow::ContentSet; - import MakeImpl /** A collection of cached types and predicates to be evaluated in the same stage. */ @@ -600,14 +781,6 @@ private module Cached { cached newtype TDataFlowCall = TCall(CallExprBaseCfgNode c) - cached - newtype TOptionalContentSet = - TAnyElementContent() or - TAnyContent() - - cached - class TContentSet = TAnyElementContent or TAnyContent; - cached newtype TDataFlowCallable = TCfgScope(CfgScope scope) @@ -623,6 +796,33 @@ private module Cached { i in [0 .. max([any(ParamList l).getNumberOfParams(), any(ArgList l).getNumberOfArgs()]) - 1] } or TSelfParameterPosition() + + cached + newtype TVariantCanonicalPath = + MkVariantCanonicalPath(CrateOriginOption crate, string path, string name) { + variantHasExtendedCanonicalPath(_, _, crate, path, name) + or + // TODO: Remove once library types are extracted + crate.isNone() and + path = "crate::std::option::Option" and + name = "Some" + } + + cached + newtype TContent = + TTupleVariantContent(VariantCanonicalPath v, int pos) { + pos in [0 .. v.getVariant().getFieldList().(TupleFieldList).getNumberOfFields() - 1] + or + // TODO: Remove once library types are extracted + v = MkVariantCanonicalPath(_, "crate::std::option::Option", "Some") and + pos = 0 + } or + TRecordVariantContent(VariantCanonicalPath v, string field) { + field = v.getVariant().getFieldList().(RecordFieldList).getAField().getName().getText() + } + + cached + newtype TContentSet = TSingletonContentSet(Content c) } import Cached diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index f16bdf9a844..a49da751679 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -34,6 +34,8 @@ localStep | main.rs:32:9:32:9 | [SSA] b | main.rs:36:10:36:10 | b | | main.rs:32:9:32:9 | b | main.rs:32:9:32:9 | [SSA] b | | main.rs:32:13:35:5 | match m { ... } | main.rs:32:9:32:9 | b | +| main.rs:32:19:32:19 | m | main.rs:33:9:33:15 | TupleStructPat | +| main.rs:32:19:32:19 | m | main.rs:34:9:34:12 | None | | main.rs:33:20:33:20 | a | main.rs:32:13:35:5 | match m { ... } | | main.rs:34:17:34:17 | 0 | main.rs:32:13:35:5 | match m { ... } | | main.rs:40:9:40:9 | [SSA] a | main.rs:43:10:43:10 | a | @@ -80,11 +82,15 @@ localStep | main.rs:105:9:105:10 | [SSA] s2 | main.rs:110:11:110:12 | s2 | | main.rs:105:9:105:10 | s2 | main.rs:105:9:105:10 | [SSA] s2 | | main.rs:105:14:105:28 | ...::Some(...) | main.rs:105:9:105:10 | s2 | +| main.rs:106:11:106:12 | s1 | main.rs:107:9:107:23 | TupleStructPat | +| main.rs:106:11:106:12 | s1 | main.rs:108:9:108:20 | ...::None | | main.rs:107:22:107:22 | [SSA] n | main.rs:107:33:107:33 | n | | main.rs:107:22:107:22 | n | main.rs:107:22:107:22 | [SSA] n | | main.rs:107:28:107:34 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } | | main.rs:108:25:108:31 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } | | main.rs:110:5:113:5 | match s2 { ... } | main.rs:103:37:114:1 | { ... } | +| main.rs:110:11:110:12 | s2 | main.rs:111:9:111:23 | TupleStructPat | +| main.rs:110:11:110:12 | s2 | main.rs:112:9:112:20 | ...::None | | main.rs:111:22:111:22 | [SSA] n | main.rs:111:33:111:33 | n | | main.rs:111:22:111:22 | n | main.rs:111:22:111:22 | [SSA] n | | main.rs:111:28:111:34 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } | @@ -95,11 +101,15 @@ localStep | main.rs:118:9:118:10 | [SSA] s2 | main.rs:123:11:123:12 | s2 | | main.rs:118:9:118:10 | s2 | main.rs:118:9:118:10 | [SSA] s2 | | main.rs:118:14:118:20 | Some(...) | main.rs:118:9:118:10 | s2 | +| main.rs:119:11:119:12 | s1 | main.rs:120:9:120:15 | TupleStructPat | +| main.rs:119:11:119:12 | s1 | main.rs:121:9:121:12 | None | | main.rs:120:14:120:14 | [SSA] n | main.rs:120:25:120:25 | n | | main.rs:120:14:120:14 | n | main.rs:120:14:120:14 | [SSA] n | | main.rs:120:20:120:26 | sink(...) | main.rs:119:5:122:5 | match s1 { ... } | | main.rs:121:17:121:23 | sink(...) | main.rs:119:5:122:5 | match s1 { ... } | | main.rs:123:5:126:5 | match s2 { ... } | main.rs:116:39:127:1 | { ... } | +| main.rs:123:11:123:12 | s2 | main.rs:124:9:124:15 | TupleStructPat | +| main.rs:123:11:123:12 | s2 | main.rs:125:9:125:12 | None | | main.rs:124:14:124:14 | [SSA] n | main.rs:124:25:124:25 | n | | main.rs:124:14:124:14 | n | main.rs:124:14:124:14 | [SSA] n | | main.rs:124:20:124:26 | sink(...) | main.rs:123:5:126:5 | match s2 { ... } | @@ -110,6 +120,8 @@ localStep | main.rs:136:9:136:10 | [SSA] s2 | main.rs:144:11:144:12 | s2 | | main.rs:136:9:136:10 | s2 | main.rs:136:9:136:10 | [SSA] s2 | | main.rs:136:14:136:30 | ...::B(...) | main.rs:136:9:136:10 | s2 | +| main.rs:137:11:137:12 | s1 | main.rs:138:9:138:25 | TupleStructPat | +| main.rs:137:11:137:12 | s1 | main.rs:139:9:139:25 | TupleStructPat | | main.rs:137:11:137:12 | s1 | main.rs:141:11:141:12 | s1 | | main.rs:138:24:138:24 | [SSA] n | main.rs:138:35:138:35 | n | | main.rs:138:24:138:24 | n | main.rs:138:24:138:24 | [SSA] n | @@ -117,6 +129,9 @@ localStep | main.rs:139:24:139:24 | [SSA] n | main.rs:139:35:139:35 | n | | main.rs:139:24:139:24 | n | main.rs:139:24:139:24 | [SSA] n | | main.rs:139:30:139:36 | sink(...) | main.rs:137:5:140:5 | match s1 { ... } | +| main.rs:141:11:141:12 | s1 | main.rs:142:10:142:46 | ... \| ... | +| main.rs:142:10:142:46 | ... \| ... | main.rs:142:10:142:26 | TupleStructPat | +| main.rs:142:10:142:46 | ... \| ... | main.rs:142:30:142:46 | TupleStructPat | | main.rs:142:10:142:46 | [SSA] [match(true)] phi | main.rs:142:57:142:57 | n | | main.rs:142:25:142:25 | [SSA] [input] [match(true)] phi | main.rs:142:10:142:46 | [SSA] [match(true)] phi | | main.rs:142:25:142:25 | [SSA] n | main.rs:142:25:142:25 | [SSA] [input] [match(true)] phi | @@ -126,6 +141,8 @@ localStep | main.rs:142:45:142:45 | n | main.rs:142:45:142:45 | [SSA] n | | main.rs:142:52:142:58 | sink(...) | main.rs:141:5:143:5 | match s1 { ... } | | main.rs:144:5:147:5 | match s2 { ... } | main.rs:134:48:148:1 | { ... } | +| main.rs:144:11:144:12 | s2 | main.rs:145:9:145:25 | TupleStructPat | +| main.rs:144:11:144:12 | s2 | main.rs:146:9:146:25 | TupleStructPat | | main.rs:145:24:145:24 | [SSA] n | main.rs:145:35:145:35 | n | | main.rs:145:24:145:24 | n | main.rs:145:24:145:24 | [SSA] n | | main.rs:145:30:145:36 | sink(...) | main.rs:144:5:147:5 | match s2 { ... } | @@ -138,6 +155,8 @@ localStep | main.rs:154:9:154:10 | [SSA] s2 | main.rs:162:11:162:12 | s2 | | main.rs:154:9:154:10 | s2 | main.rs:154:9:154:10 | [SSA] s2 | | main.rs:154:14:154:17 | B(...) | main.rs:154:9:154:10 | s2 | +| main.rs:155:11:155:12 | s1 | main.rs:156:9:156:12 | TupleStructPat | +| main.rs:155:11:155:12 | s1 | main.rs:157:9:157:12 | TupleStructPat | | main.rs:155:11:155:12 | s1 | main.rs:159:11:159:12 | s1 | | main.rs:156:11:156:11 | [SSA] n | main.rs:156:22:156:22 | n | | main.rs:156:11:156:11 | n | main.rs:156:11:156:11 | [SSA] n | @@ -145,6 +164,9 @@ localStep | main.rs:157:11:157:11 | [SSA] n | main.rs:157:22:157:22 | n | | main.rs:157:11:157:11 | n | main.rs:157:11:157:11 | [SSA] n | | main.rs:157:17:157:23 | sink(...) | main.rs:155:5:158:5 | match s1 { ... } | +| main.rs:159:11:159:12 | s1 | main.rs:160:10:160:20 | ... \| ... | +| main.rs:160:10:160:20 | ... \| ... | main.rs:160:10:160:13 | TupleStructPat | +| main.rs:160:10:160:20 | ... \| ... | main.rs:160:17:160:20 | TupleStructPat | | main.rs:160:10:160:20 | [SSA] [match(true)] phi | main.rs:160:31:160:31 | n | | main.rs:160:12:160:12 | [SSA] [input] [match(true)] phi | main.rs:160:10:160:20 | [SSA] [match(true)] phi | | main.rs:160:12:160:12 | [SSA] n | main.rs:160:12:160:12 | [SSA] [input] [match(true)] phi | @@ -154,6 +176,8 @@ localStep | main.rs:160:19:160:19 | n | main.rs:160:19:160:19 | [SSA] n | | main.rs:160:26:160:32 | sink(...) | main.rs:159:5:161:5 | match s1 { ... } | | main.rs:162:5:165:5 | match s2 { ... } | main.rs:152:50:166:1 | { ... } | +| main.rs:162:11:162:12 | s2 | main.rs:163:9:163:12 | TupleStructPat | +| main.rs:162:11:162:12 | s2 | main.rs:164:9:164:12 | TupleStructPat | | main.rs:163:11:163:11 | [SSA] n | main.rs:163:22:163:22 | n | | main.rs:163:11:163:11 | n | main.rs:163:11:163:11 | [SSA] n | | main.rs:163:17:163:23 | sink(...) | main.rs:162:5:165:5 | match s2 { ... } | @@ -166,6 +190,8 @@ localStep | main.rs:177:9:177:10 | [SSA] s2 | main.rs:185:11:185:12 | s2 | | main.rs:177:9:177:10 | s2 | main.rs:177:9:177:10 | [SSA] s2 | | main.rs:177:14:177:43 | ...::D {...} | main.rs:177:9:177:10 | s2 | +| main.rs:178:11:178:12 | s1 | main.rs:179:9:179:38 | ...::C {...} | +| main.rs:178:11:178:12 | s1 | main.rs:180:9:180:38 | ...::D {...} | | main.rs:178:11:178:12 | s1 | main.rs:182:11:182:12 | s1 | | main.rs:179:36:179:36 | [SSA] n | main.rs:179:48:179:48 | n | | main.rs:179:36:179:36 | n | main.rs:179:36:179:36 | [SSA] n | @@ -173,6 +199,9 @@ localStep | main.rs:180:36:180:36 | [SSA] n | main.rs:180:48:180:48 | n | | main.rs:180:36:180:36 | n | main.rs:180:36:180:36 | [SSA] n | | main.rs:180:43:180:49 | sink(...) | main.rs:178:5:181:5 | match s1 { ... } | +| main.rs:182:11:182:12 | s1 | main.rs:183:10:183:72 | ... \| ... | +| main.rs:183:10:183:72 | ... \| ... | main.rs:183:10:183:39 | ...::C {...} | +| main.rs:183:10:183:72 | ... \| ... | main.rs:183:43:183:72 | ...::D {...} | | main.rs:183:10:183:72 | [SSA] [match(true)] phi | main.rs:183:83:183:83 | n | | main.rs:183:37:183:37 | [SSA] [input] [match(true)] phi | main.rs:183:10:183:72 | [SSA] [match(true)] phi | | main.rs:183:37:183:37 | [SSA] n | main.rs:183:37:183:37 | [SSA] [input] [match(true)] phi | @@ -182,6 +211,8 @@ localStep | main.rs:183:70:183:70 | n | main.rs:183:70:183:70 | [SSA] n | | main.rs:183:78:183:84 | sink(...) | main.rs:182:5:184:5 | match s1 { ... } | | main.rs:185:5:188:5 | match s2 { ... } | main.rs:173:49:189:1 | { ... } | +| main.rs:185:11:185:12 | s2 | main.rs:186:9:186:38 | ...::C {...} | +| main.rs:185:11:185:12 | s2 | main.rs:187:9:187:38 | ...::D {...} | | main.rs:186:36:186:36 | [SSA] n | main.rs:186:48:186:48 | n | | main.rs:186:36:186:36 | n | main.rs:186:36:186:36 | [SSA] n | | main.rs:186:43:186:49 | sink(...) | main.rs:185:5:188:5 | match s2 { ... } | @@ -194,6 +225,8 @@ localStep | main.rs:197:9:197:10 | [SSA] s2 | main.rs:205:11:205:12 | s2 | | main.rs:197:9:197:10 | s2 | main.rs:197:9:197:10 | [SSA] s2 | | main.rs:197:14:197:29 | D {...} | main.rs:197:9:197:10 | s2 | +| main.rs:198:11:198:12 | s1 | main.rs:199:9:199:24 | C {...} | +| main.rs:198:11:198:12 | s1 | main.rs:200:9:200:24 | D {...} | | main.rs:198:11:198:12 | s1 | main.rs:202:11:202:12 | s1 | | main.rs:199:22:199:22 | [SSA] n | main.rs:199:34:199:34 | n | | main.rs:199:22:199:22 | n | main.rs:199:22:199:22 | [SSA] n | @@ -201,6 +234,9 @@ localStep | main.rs:200:22:200:22 | [SSA] n | main.rs:200:34:200:34 | n | | main.rs:200:22:200:22 | n | main.rs:200:22:200:22 | [SSA] n | | main.rs:200:29:200:35 | sink(...) | main.rs:198:5:201:5 | match s1 { ... } | +| main.rs:202:11:202:12 | s1 | main.rs:203:10:203:44 | ... \| ... | +| main.rs:203:10:203:44 | ... \| ... | main.rs:203:10:203:25 | C {...} | +| main.rs:203:10:203:44 | ... \| ... | main.rs:203:29:203:44 | D {...} | | main.rs:203:10:203:44 | [SSA] [match(true)] phi | main.rs:203:55:203:55 | n | | main.rs:203:23:203:23 | [SSA] [input] [match(true)] phi | main.rs:203:10:203:44 | [SSA] [match(true)] phi | | main.rs:203:23:203:23 | [SSA] n | main.rs:203:23:203:23 | [SSA] [input] [match(true)] phi | @@ -210,6 +246,8 @@ localStep | main.rs:203:42:203:42 | n | main.rs:203:42:203:42 | [SSA] n | | main.rs:203:50:203:56 | sink(...) | main.rs:202:5:204:5 | match s1 { ... } | | main.rs:205:5:208:5 | match s2 { ... } | main.rs:193:51:209:1 | { ... } | +| main.rs:205:11:205:12 | s2 | main.rs:206:9:206:24 | C {...} | +| main.rs:205:11:205:12 | s2 | main.rs:207:9:207:24 | D {...} | | main.rs:206:22:206:22 | [SSA] n | main.rs:206:34:206:34 | n | | main.rs:206:22:206:22 | n | main.rs:206:22:206:22 | [SSA] n | | main.rs:206:29:206:35 | sink(...) | main.rs:205:5:208:5 | match s2 { ... } | @@ -243,4 +281,26 @@ localStep | main.rs:231:22:231:22 | 2 | main.rs:231:9:231:22 | break ''block 2 | | main.rs:233:5:233:5 | a | main.rs:226:38:234:1 | { ... } | storeStep +| main.rs:117:19:117:28 | source(...) | Some | main.rs:117:14:117:29 | Some(...) | +| main.rs:118:19:118:19 | 2 | Some | main.rs:118:14:118:20 | Some(...) | +| main.rs:135:29:135:38 | source(...) | A | main.rs:135:14:135:39 | ...::A(...) | +| main.rs:136:29:136:29 | 2 | B | main.rs:136:14:136:30 | ...::B(...) | +| main.rs:175:18:175:27 | source(...) | C | main.rs:174:14:176:5 | ...::C {...} | +| main.rs:177:41:177:41 | 2 | D | main.rs:177:14:177:43 | ...::D {...} | +| main.rs:240:27:240:27 | 0 | Some | main.rs:240:22:240:28 | Some(...) | readStep +| main.rs:33:9:33:15 | TupleStructPat | Some | main.rs:33:14:33:14 | _ | +| main.rs:120:9:120:15 | TupleStructPat | Some | main.rs:120:14:120:14 | n | +| main.rs:124:9:124:15 | TupleStructPat | Some | main.rs:124:14:124:14 | n | +| main.rs:138:9:138:25 | TupleStructPat | A | main.rs:138:24:138:24 | n | +| main.rs:139:9:139:25 | TupleStructPat | B | main.rs:139:24:139:24 | n | +| main.rs:142:10:142:26 | TupleStructPat | A | main.rs:142:25:142:25 | n | +| main.rs:142:30:142:46 | TupleStructPat | B | main.rs:142:45:142:45 | n | +| main.rs:145:9:145:25 | TupleStructPat | A | main.rs:145:24:145:24 | n | +| main.rs:146:9:146:25 | TupleStructPat | B | main.rs:146:24:146:24 | n | +| main.rs:179:9:179:38 | ...::C {...} | C | main.rs:179:36:179:36 | n | +| main.rs:180:9:180:38 | ...::D {...} | D | main.rs:180:36:180:36 | n | +| main.rs:183:10:183:39 | ...::C {...} | C | main.rs:183:37:183:37 | n | +| main.rs:183:43:183:72 | ...::D {...} | D | main.rs:183:70:183:70 | n | +| main.rs:186:9:186:38 | ...::C {...} | C | main.rs:186:36:186:36 | n | +| main.rs:187:9:187:38 | ...::D {...} | D | main.rs:187:36:187:36 | n | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index f8585809e94..bfafa38c3ff 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -5,6 +5,24 @@ edges | main.rs:31:13:31:21 | source(...) | main.rs:36:10:36:10 | b | provenance | | | main.rs:45:15:45:23 | source(...) | main.rs:47:10:47:10 | b | provenance | | | main.rs:53:9:53:17 | source(...) | main.rs:54:10:54:10 | i | provenance | | +| main.rs:117:14:117:29 | Some(...) [Some] | main.rs:120:9:120:15 | TupleStructPat [Some] | provenance | | +| main.rs:117:19:117:28 | source(...) | main.rs:117:14:117:29 | Some(...) [Some] | provenance | | +| main.rs:120:9:120:15 | TupleStructPat [Some] | main.rs:120:14:120:14 | n | provenance | | +| main.rs:120:14:120:14 | n | main.rs:120:25:120:25 | n | provenance | | +| main.rs:135:14:135:39 | ...::A(...) [A] | main.rs:138:9:138:25 | TupleStructPat [A] | provenance | | +| main.rs:135:14:135:39 | ...::A(...) [A] | main.rs:142:10:142:26 | TupleStructPat [A] | provenance | | +| main.rs:135:29:135:38 | source(...) | main.rs:135:14:135:39 | ...::A(...) [A] | provenance | | +| main.rs:138:9:138:25 | TupleStructPat [A] | main.rs:138:24:138:24 | n | provenance | | +| main.rs:138:24:138:24 | n | main.rs:138:35:138:35 | n | provenance | | +| main.rs:142:10:142:26 | TupleStructPat [A] | main.rs:142:25:142:25 | n | provenance | | +| main.rs:142:25:142:25 | n | main.rs:142:57:142:57 | n | provenance | | +| main.rs:174:14:176:5 | ...::C {...} [C] | main.rs:179:9:179:38 | ...::C {...} [C] | provenance | | +| main.rs:174:14:176:5 | ...::C {...} [C] | main.rs:183:10:183:39 | ...::C {...} [C] | provenance | | +| main.rs:175:18:175:27 | source(...) | main.rs:174:14:176:5 | ...::C {...} [C] | provenance | | +| main.rs:179:9:179:38 | ...::C {...} [C] | main.rs:179:36:179:36 | n | provenance | | +| main.rs:179:36:179:36 | n | main.rs:179:48:179:48 | n | provenance | | +| main.rs:183:10:183:39 | ...::C {...} [C] | main.rs:183:37:183:37 | n | provenance | | +| main.rs:183:37:183:37 | n | main.rs:183:83:183:83 | n | provenance | | nodes | main.rs:15:10:15:18 | source(...) | semmle.label | source(...) | | main.rs:19:13:19:21 | source(...) | semmle.label | source(...) | @@ -17,6 +35,27 @@ nodes | main.rs:47:10:47:10 | b | semmle.label | b | | main.rs:53:9:53:17 | source(...) | semmle.label | source(...) | | main.rs:54:10:54:10 | i | semmle.label | i | +| main.rs:117:14:117:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | +| main.rs:117:19:117:28 | source(...) | semmle.label | source(...) | +| main.rs:120:9:120:15 | TupleStructPat [Some] | semmle.label | TupleStructPat [Some] | +| main.rs:120:14:120:14 | n | semmle.label | n | +| main.rs:120:25:120:25 | n | semmle.label | n | +| main.rs:135:14:135:39 | ...::A(...) [A] | semmle.label | ...::A(...) [A] | +| main.rs:135:29:135:38 | source(...) | semmle.label | source(...) | +| main.rs:138:9:138:25 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | +| main.rs:138:24:138:24 | n | semmle.label | n | +| main.rs:138:35:138:35 | n | semmle.label | n | +| main.rs:142:10:142:26 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | +| main.rs:142:25:142:25 | n | semmle.label | n | +| main.rs:142:57:142:57 | n | semmle.label | n | +| main.rs:174:14:176:5 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:175:18:175:27 | source(...) | semmle.label | source(...) | +| main.rs:179:9:179:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:179:36:179:36 | n | semmle.label | n | +| main.rs:179:48:179:48 | n | semmle.label | n | +| main.rs:183:10:183:39 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:183:37:183:37 | n | semmle.label | n | +| main.rs:183:83:183:83 | n | semmle.label | n | subpaths testFailures #select @@ -26,3 +65,8 @@ testFailures | main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | source(...) | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | source(...) | source(...) | | main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | source(...) | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | source(...) | source(...) | | main.rs:54:10:54:10 | i | main.rs:53:9:53:17 | source(...) | main.rs:54:10:54:10 | i | $@ | main.rs:53:9:53:17 | source(...) | source(...) | +| main.rs:120:25:120:25 | n | main.rs:117:19:117:28 | source(...) | main.rs:120:25:120:25 | n | $@ | main.rs:117:19:117:28 | source(...) | source(...) | +| main.rs:138:35:138:35 | n | main.rs:135:29:135:38 | source(...) | main.rs:138:35:138:35 | n | $@ | main.rs:135:29:135:38 | source(...) | source(...) | +| main.rs:142:57:142:57 | n | main.rs:135:29:135:38 | source(...) | main.rs:142:57:142:57 | n | $@ | main.rs:135:29:135:38 | source(...) | source(...) | +| main.rs:179:48:179:48 | n | main.rs:175:18:175:27 | source(...) | main.rs:179:48:179:48 | n | $@ | main.rs:175:18:175:27 | source(...) | source(...) | +| main.rs:183:83:183:83 | n | main.rs:175:18:175:27 | source(...) | main.rs:183:83:183:83 | n | $@ | main.rs:175:18:175:27 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/local/main.rs b/rust/ql/test/library-tests/dataflow/local/main.rs index b9dcc78c3a8..9a9e6b467e0 100644 --- a/rust/ql/test/library-tests/dataflow/local/main.rs +++ b/rust/ql/test/library-tests/dataflow/local/main.rs @@ -117,7 +117,7 @@ fn option_pattern_match_unqualified() { let s1 = Some(source(14)); let s2 = Some(2); match s1 { - Some(n) => sink(n), // $ MISSING: hasValueFlow=14 + Some(n) => sink(n), // $ hasValueFlow=14 None => sink(0), } match s2 { @@ -135,11 +135,11 @@ fn custom_tuple_enum_pattern_match_qualified() { let s1 = MyTupleEnum::A(source(15)); let s2 = MyTupleEnum::B(2); match s1 { - MyTupleEnum::A(n) => sink(n), // $ MISSING: hasValueFlow=15 + MyTupleEnum::A(n) => sink(n), // $ hasValueFlow=15 MyTupleEnum::B(n) => sink(n), } match s1 { - (MyTupleEnum::A(n) | MyTupleEnum::B(n)) => sink(n), // $ MISSING: hasValueFlow=15 + (MyTupleEnum::A(n) | MyTupleEnum::B(n)) => sink(n), // $ hasValueFlow=15 } match s2 { MyTupleEnum::A(n) => sink(n), @@ -176,11 +176,11 @@ fn custom_record_enum_pattern_match_qualified() { }; let s2 = MyRecordEnum::D { field_d: 2 }; match s1 { - MyRecordEnum::C { field_c: n } => sink(n), // $ MISSING: hasValueFlow=17 + MyRecordEnum::C { field_c: n } => sink(n), // $ hasValueFlow=17 MyRecordEnum::D { field_d: n } => sink(n), } match s1 { - (MyRecordEnum::C { field_c: n } | MyRecordEnum::D { field_d: n }) => sink(n), // $ MISSING: hasValueFlow=17 + (MyRecordEnum::C { field_c: n } | MyRecordEnum::D { field_d: n }) => sink(n), // $ hasValueFlow=17 } match s2 { MyRecordEnum::C { field_c: n } => sink(n), From 9ead2dc03c5d8914f5d654ad511990c7ae076120 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 21 Nov 2024 15:12:09 +0000 Subject: [PATCH 239/470] Rust: Add a query test. --- .../CWE-696/BadCTorInitialization.expected | 1 + .../CWE-696/BadCTorInitialization.qlref | 2 + .../query-tests/security/CWE-696/options.yml | 3 + .../test/query-tests/security/CWE-696/test.rs | 144 ++++++++++++++++++ 4 files changed, 150 insertions(+) create mode 100644 rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected create mode 100644 rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.qlref create mode 100644 rust/ql/test/query-tests/security/CWE-696/options.yml create mode 100644 rust/ql/test/query-tests/security/CWE-696/test.rs diff --git a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected new file mode 100644 index 00000000000..f082a67fcf6 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected @@ -0,0 +1 @@ +| 0 | diff --git a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.qlref b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.qlref new file mode 100644 index 00000000000..2b71705c98b --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.qlref @@ -0,0 +1,2 @@ +query: queries/security/CWE-696/BadCtorInitialization.ql +postprocess: utils/InlineExpectationsTestQuery.ql diff --git a/rust/ql/test/query-tests/security/CWE-696/options.yml b/rust/ql/test/query-tests/security/CWE-696/options.yml new file mode 100644 index 00000000000..1f1a13e589e --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-696/options.yml @@ -0,0 +1,3 @@ +qltest_cargo_check: true +qltest_dependencies: + - ctor = { version = "0.2.9" } diff --git a/rust/ql/test/query-tests/security/CWE-696/test.rs b/rust/ql/test/query-tests/security/CWE-696/test.rs new file mode 100644 index 00000000000..9fb90a018e6 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-696/test.rs @@ -0,0 +1,144 @@ + +// --- attribute variants --- + +use std::io::Write; + +fn harmless1_1() { + // ... +} + +#[ctor::ctor] +fn harmless1_2() { + // ... +} + +#[ctor::dtor] +fn harmless1_3() { + // ... +} + +fn harmless1_4() { + _ = std::io::stdout().write(b"Hello, world!"); +} + +#[rustfmt::skip] +fn harmless1_5() { + _ = std::io::stdout().write(b"Hello, world!"); +} + +#[ctor::ctor] +fn bad1_1() { // $ MISSING: Alert[rust/ctor-initialization] + _ = std::io::stdout().write(b"Hello, world!"); +} + +#[ctor::dtor] +fn bad1_2() { // $ MISSING: Alert[rust/ctor-initialization] + _ = std::io::stdout().write(b"Hello, world!"); +} + +#[rustfmt::skip] +#[ctor::dtor] +#[rustfmt::skip] +fn bad1_3() { // $ MISSING: Alert[rust/ctor-initialization] + _ = std::io::stdout().write(b"Hello, world!"); +} + +// --- code variants --- + +use ctor::ctor; +use std::io::*; + +#[ctor] +fn bad2_1() { // $ MISSING: Alert[rust/ctor-initialization] + _ = stdout().write(b"Hello, world!"); +} + +#[ctor] +fn bad2_2() { // $ MISSING: Alert[rust/ctor-initialization] + _ = stderr().write_all(b"Hello, world!"); +} + +#[ctor] +fn bad2_3() { // $ MISSING: Alert[rust/ctor-initialization] + println!("Hello, world!"); +} + +#[ctor] +fn bad2_4() { // $ MISSING: Alert[rust/ctor-initialization] + let mut buff = String::new(); + _ = std::io::stdin().read_line(&mut buff); +} + +use std::fs; + +#[ctor] +fn bad2_5() { // $ MISSING: Alert[rust/ctor-initialization] + let _buff = fs::File::create("hello.txt").unwrap(); +} + +#[ctor] +fn bad2_6() { // $ MISSING: Alert[rust/ctor-initialization] + let _t = std::time::Instant::now(); +} + +use std::time::Duration; + +const DURATION2_7: Duration = Duration::new(1, 0); + +#[ctor] +fn bad2_7() { // $ MISSING: Alert[rust/ctor-initialization] + std::thread::sleep(DURATION2_7); +} + +use std::process; + +#[ctor] +fn bad2_8() { // $ MISSING: Alert[rust/ctor-initialization] + process::exit(1234); +} + +// --- transitive cases --- + +fn call_target3_1() { + _ = stderr().write_all(b"Hello, world!"); +} + +#[ctor] +fn bad3_1() { // $ MISSING: Alert[rust/ctor-initialization] + call_target3_1(); +} + +fn call_target3_2() { + for _x in 0..10 { + // ... + } +} + +#[ctor] +fn harmless3_2() { + call_target3_2(); +} + +#[ctor] +fn bad3_3() { // $ MISSING: Alert[rust/ctor-initialization] + call_target3_1(); + call_target3_2(); +} + +#[ctor] +fn bad3_4() { // $ MISSING: Alert[rust/ctor-initialization] + bad3_3(); +} + +// --- macros --- + +macro_rules! macro4_1 { + () => { + _ = std::io::stdout().write(b"Hello, world!"); + }; +} + +#[ctor] +fn bad4_1() { // $ MISSING: Alert[rust/ctor-initialization] + macro4_1!(); +} From 88fc7be0a233f8fa26bd13b2c22de6f6ca0e234c Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 21 Nov 2024 22:37:41 +0000 Subject: [PATCH 240/470] Rust: Implement the query. --- .../security/CWE-696/BadCtorInitialization.ql | 24 ++++++++++++++++++- .../CWE-696/BadCTorInitialization.expected | 11 ++++++++- .../test/query-tests/security/CWE-696/test.rs | 20 ++++++++-------- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index 9d6fa7351e7..5999ac0e02e 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -13,4 +13,26 @@ import rust -select 0 +/** + * A `#[ctor]` or `#[dtor]` attribute. + */ +class CtorAttr extends Attr { + CtorAttr() { this.getMeta().getPath().getPart().getNameRef().getText() = ["ctor", "dtor"] } +} + +/** + * A call into the Rust standard library. + */ +class StdCall extends Expr { + StdCall() { + this.(CallExpr).getExpr().(PathExpr).getPath().getResolvedCrateOrigin() = "lang:std" or + this.(MethodCallExpr).getResolvedCrateOrigin() = "lang:std" + } +} + +from CtorAttr ctor, Function f, StdCall call +where + f.getAnAttr() = ctor and + call.getEnclosingCallable() = f +select f.getName(), "This function has the $@ attribute but calls $@ in the standard library.", + ctor, ctor.toString(), call, call.toString() diff --git a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected index f082a67fcf6..36ab89a79bf 100644 --- a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected +++ b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected @@ -1 +1,10 @@ -| 0 | +| test.rs:30:4:30:9 | bad1_1 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:29:1:29:13 | Attr | Attr | test.rs:31:9:31:25 | ...::stdout(...) | ...::stdout(...) | +| test.rs:35:4:35:9 | bad1_2 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:34:1:34:13 | Attr | Attr | test.rs:36:9:36:25 | ...::stdout(...) | ...::stdout(...) | +| test.rs:42:4:42:9 | bad1_3 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:40:1:40:13 | Attr | Attr | test.rs:43:9:43:25 | ...::stdout(...) | ...::stdout(...) | +| test.rs:52:4:52:9 | bad2_1 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:51:1:51:7 | Attr | Attr | test.rs:53:9:53:16 | stdout(...) | stdout(...) | +| test.rs:57:4:57:9 | bad2_2 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:56:1:56:7 | Attr | Attr | test.rs:58:9:58:16 | stderr(...) | stderr(...) | +| test.rs:62:4:62:9 | bad2_3 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:61:1:61:7 | Attr | Attr | test.rs:63:14:63:28 | ...::_print(...) | ...::_print(...) | +| test.rs:67:4:67:9 | bad2_4 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:66:1:66:7 | Attr | Attr | test.rs:69:9:69:24 | ...::stdin(...) | ...::stdin(...) | +| test.rs:89:4:89:9 | bad2_7 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:88:1:88:7 | Attr | Attr | test.rs:90:5:90:35 | ...::sleep(...) | ...::sleep(...) | +| test.rs:96:4:96:9 | bad2_8 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:95:1:95:7 | Attr | Attr | test.rs:97:5:97:23 | ...::exit(...) | ...::exit(...) | +| test.rs:142:4:142:9 | bad4_1 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:141:1:141:7 | Attr | Attr | test.rs:143:5:143:15 | ...::stdout(...) | ...::stdout(...) | diff --git a/rust/ql/test/query-tests/security/CWE-696/test.rs b/rust/ql/test/query-tests/security/CWE-696/test.rs index 9fb90a018e6..4041efcae17 100644 --- a/rust/ql/test/query-tests/security/CWE-696/test.rs +++ b/rust/ql/test/query-tests/security/CWE-696/test.rs @@ -27,19 +27,19 @@ fn harmless1_5() { } #[ctor::ctor] -fn bad1_1() { // $ MISSING: Alert[rust/ctor-initialization] +fn bad1_1() { // $ Alert[rust/ctor-initialization] _ = std::io::stdout().write(b"Hello, world!"); } #[ctor::dtor] -fn bad1_2() { // $ MISSING: Alert[rust/ctor-initialization] +fn bad1_2() { // $ Alert[rust/ctor-initialization] _ = std::io::stdout().write(b"Hello, world!"); } #[rustfmt::skip] #[ctor::dtor] #[rustfmt::skip] -fn bad1_3() { // $ MISSING: Alert[rust/ctor-initialization] +fn bad1_3() { // $ Alert[rust/ctor-initialization] _ = std::io::stdout().write(b"Hello, world!"); } @@ -49,22 +49,22 @@ use ctor::ctor; use std::io::*; #[ctor] -fn bad2_1() { // $ MISSING: Alert[rust/ctor-initialization] +fn bad2_1() { // $ Alert[rust/ctor-initialization] _ = stdout().write(b"Hello, world!"); } #[ctor] -fn bad2_2() { // $ MISSING: Alert[rust/ctor-initialization] +fn bad2_2() { // $ Alert[rust/ctor-initialization] _ = stderr().write_all(b"Hello, world!"); } #[ctor] -fn bad2_3() { // $ MISSING: Alert[rust/ctor-initialization] +fn bad2_3() { // $ Alert[rust/ctor-initialization] println!("Hello, world!"); } #[ctor] -fn bad2_4() { // $ MISSING: Alert[rust/ctor-initialization] +fn bad2_4() { // $ Alert[rust/ctor-initialization] let mut buff = String::new(); _ = std::io::stdin().read_line(&mut buff); } @@ -86,14 +86,14 @@ use std::time::Duration; const DURATION2_7: Duration = Duration::new(1, 0); #[ctor] -fn bad2_7() { // $ MISSING: Alert[rust/ctor-initialization] +fn bad2_7() { // $ Alert[rust/ctor-initialization] std::thread::sleep(DURATION2_7); } use std::process; #[ctor] -fn bad2_8() { // $ MISSING: Alert[rust/ctor-initialization] +fn bad2_8() { // $ Alert[rust/ctor-initialization] process::exit(1234); } @@ -139,6 +139,6 @@ macro_rules! macro4_1 { } #[ctor] -fn bad4_1() { // $ MISSING: Alert[rust/ctor-initialization] +fn bad4_1() { // $ Alert[rust/ctor-initialization] macro4_1!(); } From 82f2c6075f30198bc48be6eeac82824717e1d939 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 25 Nov 2024 12:00:55 +0000 Subject: [PATCH 241/470] Rust: Add qhelp + examples. --- .../CWE-696/BadCtorInitialization.qhelp | 44 +++++++++++++++++++ .../CWE-696/BadCtorInitializationBad.rs | 5 +++ .../CWE-696/BadCtorInitializationGood.rs | 5 +++ 3 files changed, 54 insertions(+) create mode 100644 rust/ql/src/queries/security/CWE-696/BadCtorInitialization.qhelp create mode 100644 rust/ql/src/queries/security/CWE-696/BadCtorInitializationBad.rs create mode 100644 rust/ql/src/queries/security/CWE-696/BadCtorInitializationGood.rs diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.qhelp b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.qhelp new file mode 100644 index 00000000000..60f6e3eb45d --- /dev/null +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.qhelp @@ -0,0 +1,44 @@ + + + + +

    +Calling functions and methods in the Rust std library from a #[ctor] or #[dtor] function is not safe. This is because the std library only guarantees stability and portability between the beginning and end of main, whereas #[ctor] functions are called before main, and #[dtor] functions are called after it. +

    + +
    + + +

    +Do not call any part of the std library from a #[ctor] or #[dtor] function. Instead either: +

    +
      +
    • Move the code to a different location, such as inside your program's main function.
    • +
    • Rewrite the code using an alternative library.
    • +
    + +
    + + +

    +In the following example, a #[ctor] function uses the println! macro which calls std library functions. This may cause unexpected behaviour at runtime. +

    + + + +

    +The issue can be fixed by replacing println! with something that does not rely on the std library. In the fixed code below we use the libc_println! macro from the libc-print library: +

    + + + +
    + + +
  • GitHub: rust-ctor - Warnings.
  • +
  • Rust Programming Language: Crate std - Use before and after main().
  • + +
    +
    diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitializationBad.rs b/rust/ql/src/queries/security/CWE-696/BadCtorInitializationBad.rs new file mode 100644 index 00000000000..2a6c60272d5 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitializationBad.rs @@ -0,0 +1,5 @@ + +#[ctor::ctor] +fn bad_example() { + println!("Hello, world!"); // BAD: the println! macro calls std library functions +} diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitializationGood.rs b/rust/ql/src/queries/security/CWE-696/BadCtorInitializationGood.rs new file mode 100644 index 00000000000..cbb8bc089a3 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitializationGood.rs @@ -0,0 +1,5 @@ + +#[ctor::ctor] +fn good_example() { + libc_print::libc_println!("Hello, world!"); // GOOD: libc-print does not use the std library +} From be5bd1da0a2a82d91688842920cecf56d244f075 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 25 Nov 2024 14:57:30 +0000 Subject: [PATCH 242/470] Rust: Also add the good example and a couple of other cited good cases to the test. --- .../CWE-696/BadCTorInitialization.expected | 2 +- .../query-tests/security/CWE-696/options.yml | 1 + .../test/query-tests/security/CWE-696/test.rs | 23 +++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected index 36ab89a79bf..10313da17a6 100644 --- a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected +++ b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected @@ -7,4 +7,4 @@ | test.rs:67:4:67:9 | bad2_4 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:66:1:66:7 | Attr | Attr | test.rs:69:9:69:24 | ...::stdin(...) | ...::stdin(...) | | test.rs:89:4:89:9 | bad2_7 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:88:1:88:7 | Attr | Attr | test.rs:90:5:90:35 | ...::sleep(...) | ...::sleep(...) | | test.rs:96:4:96:9 | bad2_8 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:95:1:95:7 | Attr | Attr | test.rs:97:5:97:23 | ...::exit(...) | ...::exit(...) | -| test.rs:142:4:142:9 | bad4_1 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:141:1:141:7 | Attr | Attr | test.rs:143:5:143:15 | ...::stdout(...) | ...::stdout(...) | +| test.rs:165:4:165:9 | bad4_1 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:164:1:164:7 | Attr | Attr | test.rs:166:5:166:15 | ...::stdout(...) | ...::stdout(...) | diff --git a/rust/ql/test/query-tests/security/CWE-696/options.yml b/rust/ql/test/query-tests/security/CWE-696/options.yml index 1f1a13e589e..cc3dc0f3519 100644 --- a/rust/ql/test/query-tests/security/CWE-696/options.yml +++ b/rust/ql/test/query-tests/security/CWE-696/options.yml @@ -1,3 +1,4 @@ qltest_cargo_check: true qltest_dependencies: - ctor = { version = "0.2.9" } + - libc-print = { version = "0.1.23" } diff --git a/rust/ql/test/query-tests/security/CWE-696/test.rs b/rust/ql/test/query-tests/security/CWE-696/test.rs index 4041efcae17..2510a833b0f 100644 --- a/rust/ql/test/query-tests/security/CWE-696/test.rs +++ b/rust/ql/test/query-tests/security/CWE-696/test.rs @@ -97,6 +97,29 @@ fn bad2_8() { // $ Alert[rust/ctor-initialization] process::exit(1234); } +#[ctor::ctor] +fn harmless2_9() { + libc_print::libc_println!("Hello, world!"); // does not use the std library +} + +#[ctor::ctor] +fn harmless2_10() { + core::assert!(true); // core library should be OK in this context +} + +extern crate alloc; +use alloc::alloc::{alloc, dealloc, Layout}; + +#[ctor::ctor] +unsafe fn harmless2_11() { + let layout = Layout::new::(); + let ptr = alloc(layout); // alloc library should be OK in this context + + if !ptr.is_null() { + dealloc(ptr, layout); + } +} + // --- transitive cases --- fn call_target3_1() { From 77f51685903a056f2753b61b3fb11f7061fc6f19 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 25 Nov 2024 17:48:42 +0000 Subject: [PATCH 243/470] Rust: Query metadata and path edges. --- .../security/CWE-696/BadCtorInitialization.ql | 42 ++++++--- .../CWE-696/BadCTorInitialization.expected | 32 ++++--- .../test/query-tests/security/CWE-696/test.rs | 86 +++++++++---------- 3 files changed, 96 insertions(+), 64 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index 5999ac0e02e..90a7acc6920 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -1,12 +1,12 @@ /** * @name Bad 'ctor' initialization - * @description TODO + * @description Calling functions in the Rust std library from a ctor or dtor function is not safe. * @kind path-problem * @problem.severity error - * @ security-severity TODO - * @ precision TODO + * @precision high * @id rust/ctor-initialization - * @tags security + * @tags reliability + * correctness * external/cwe/cwe-696 * external/cwe/cwe-665 */ @@ -17,7 +17,14 @@ import rust * A `#[ctor]` or `#[dtor]` attribute. */ class CtorAttr extends Attr { - CtorAttr() { this.getMeta().getPath().getPart().getNameRef().getText() = ["ctor", "dtor"] } + string whichAttr; + + CtorAttr() { + whichAttr = this.getMeta().getPath().getPart().getNameRef().getText() and + whichAttr = ["ctor", "dtor"] + } + + string getWhichAttr() { result = whichAttr } } /** @@ -30,9 +37,22 @@ class StdCall extends Expr { } } -from CtorAttr ctor, Function f, StdCall call -where - f.getAnAttr() = ctor and - call.getEnclosingCallable() = f -select f.getName(), "This function has the $@ attribute but calls $@ in the standard library.", - ctor, ctor.toString(), call, call.toString() +class PathElement = AstNode; + +query predicate edges(PathElement pred, PathElement succ) { + // starting edge + exists(CtorAttr ctor, Function f, StdCall call | + f.getAnAttr() = ctor and + call.getEnclosingCallable() = f and + pred = ctor and // source + succ = call // sink + ) + // or + // transitive edge + // TODO +} + +from CtorAttr ctor, StdCall call +where edges*(ctor, call) +select call, ctor, call, "Call to $@ in a function with the " + ctor.getWhichAttr() + " attribute.", + call, call.toString() diff --git a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected index 10313da17a6..8ad81870e06 100644 --- a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected +++ b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected @@ -1,10 +1,22 @@ -| test.rs:30:4:30:9 | bad1_1 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:29:1:29:13 | Attr | Attr | test.rs:31:9:31:25 | ...::stdout(...) | ...::stdout(...) | -| test.rs:35:4:35:9 | bad1_2 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:34:1:34:13 | Attr | Attr | test.rs:36:9:36:25 | ...::stdout(...) | ...::stdout(...) | -| test.rs:42:4:42:9 | bad1_3 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:40:1:40:13 | Attr | Attr | test.rs:43:9:43:25 | ...::stdout(...) | ...::stdout(...) | -| test.rs:52:4:52:9 | bad2_1 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:51:1:51:7 | Attr | Attr | test.rs:53:9:53:16 | stdout(...) | stdout(...) | -| test.rs:57:4:57:9 | bad2_2 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:56:1:56:7 | Attr | Attr | test.rs:58:9:58:16 | stderr(...) | stderr(...) | -| test.rs:62:4:62:9 | bad2_3 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:61:1:61:7 | Attr | Attr | test.rs:63:14:63:28 | ...::_print(...) | ...::_print(...) | -| test.rs:67:4:67:9 | bad2_4 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:66:1:66:7 | Attr | Attr | test.rs:69:9:69:24 | ...::stdin(...) | ...::stdin(...) | -| test.rs:89:4:89:9 | bad2_7 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:88:1:88:7 | Attr | Attr | test.rs:90:5:90:35 | ...::sleep(...) | ...::sleep(...) | -| test.rs:96:4:96:9 | bad2_8 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:95:1:95:7 | Attr | Attr | test.rs:97:5:97:23 | ...::exit(...) | ...::exit(...) | -| test.rs:165:4:165:9 | bad4_1 | This function has the $@ attribute but calls $@ in the standard library. | test.rs:164:1:164:7 | Attr | Attr | test.rs:166:5:166:15 | ...::stdout(...) | ...::stdout(...) | +#select +| test.rs:31:9:31:25 | ...::stdout(...) | test.rs:29:1:29:13 | Attr | test.rs:31:9:31:25 | ...::stdout(...) | Call to $@ in a function with the ctor attribute. | test.rs:31:9:31:25 | ...::stdout(...) | ...::stdout(...) | +| test.rs:36:9:36:25 | ...::stdout(...) | test.rs:34:1:34:13 | Attr | test.rs:36:9:36:25 | ...::stdout(...) | Call to $@ in a function with the dtor attribute. | test.rs:36:9:36:25 | ...::stdout(...) | ...::stdout(...) | +| test.rs:43:9:43:25 | ...::stdout(...) | test.rs:40:1:40:13 | Attr | test.rs:43:9:43:25 | ...::stdout(...) | Call to $@ in a function with the dtor attribute. | test.rs:43:9:43:25 | ...::stdout(...) | ...::stdout(...) | +| test.rs:53:9:53:16 | stdout(...) | test.rs:51:1:51:7 | Attr | test.rs:53:9:53:16 | stdout(...) | Call to $@ in a function with the ctor attribute. | test.rs:53:9:53:16 | stdout(...) | stdout(...) | +| test.rs:58:9:58:16 | stderr(...) | test.rs:56:1:56:7 | Attr | test.rs:58:9:58:16 | stderr(...) | Call to $@ in a function with the ctor attribute. | test.rs:58:9:58:16 | stderr(...) | stderr(...) | +| test.rs:63:14:63:28 | ...::_print(...) | test.rs:61:1:61:7 | Attr | test.rs:63:14:63:28 | ...::_print(...) | Call to $@ in a function with the ctor attribute. | test.rs:63:14:63:28 | ...::_print(...) | ...::_print(...) | +| test.rs:69:9:69:24 | ...::stdin(...) | test.rs:66:1:66:7 | Attr | test.rs:69:9:69:24 | ...::stdin(...) | Call to $@ in a function with the ctor attribute. | test.rs:69:9:69:24 | ...::stdin(...) | ...::stdin(...) | +| test.rs:90:5:90:35 | ...::sleep(...) | test.rs:88:1:88:7 | Attr | test.rs:90:5:90:35 | ...::sleep(...) | Call to $@ in a function with the ctor attribute. | test.rs:90:5:90:35 | ...::sleep(...) | ...::sleep(...) | +| test.rs:97:5:97:23 | ...::exit(...) | test.rs:95:1:95:7 | Attr | test.rs:97:5:97:23 | ...::exit(...) | Call to $@ in a function with the ctor attribute. | test.rs:97:5:97:23 | ...::exit(...) | ...::exit(...) | +| test.rs:166:5:166:15 | ...::stdout(...) | test.rs:164:1:164:7 | Attr | test.rs:166:5:166:15 | ...::stdout(...) | Call to $@ in a function with the ctor attribute. | test.rs:166:5:166:15 | ...::stdout(...) | ...::stdout(...) | +edges +| test.rs:29:1:29:13 | Attr | test.rs:31:9:31:25 | ...::stdout(...) | +| test.rs:34:1:34:13 | Attr | test.rs:36:9:36:25 | ...::stdout(...) | +| test.rs:40:1:40:13 | Attr | test.rs:43:9:43:25 | ...::stdout(...) | +| test.rs:51:1:51:7 | Attr | test.rs:53:9:53:16 | stdout(...) | +| test.rs:56:1:56:7 | Attr | test.rs:58:9:58:16 | stderr(...) | +| test.rs:61:1:61:7 | Attr | test.rs:63:14:63:28 | ...::_print(...) | +| test.rs:66:1:66:7 | Attr | test.rs:69:9:69:24 | ...::stdin(...) | +| test.rs:88:1:88:7 | Attr | test.rs:90:5:90:35 | ...::sleep(...) | +| test.rs:95:1:95:7 | Attr | test.rs:97:5:97:23 | ...::exit(...) | +| test.rs:164:1:164:7 | Attr | test.rs:166:5:166:15 | ...::stdout(...) | diff --git a/rust/ql/test/query-tests/security/CWE-696/test.rs b/rust/ql/test/query-tests/security/CWE-696/test.rs index 2510a833b0f..87f544be85c 100644 --- a/rust/ql/test/query-tests/security/CWE-696/test.rs +++ b/rust/ql/test/query-tests/security/CWE-696/test.rs @@ -26,21 +26,21 @@ fn harmless1_5() { _ = std::io::stdout().write(b"Hello, world!"); } -#[ctor::ctor] -fn bad1_1() { // $ Alert[rust/ctor-initialization] - _ = std::io::stdout().write(b"Hello, world!"); +#[ctor::ctor] // $ Source=source1_1 +fn bad1_1() { + _ = std::io::stdout().write(b"Hello, world!"); // $ Alert[rust/ctor-initialization]=source1_1 } -#[ctor::dtor] -fn bad1_2() { // $ Alert[rust/ctor-initialization] - _ = std::io::stdout().write(b"Hello, world!"); +#[ctor::dtor] // $ Source=source1_2 +fn bad1_2() { + _ = std::io::stdout().write(b"Hello, world!"); // $ Alert[rust/ctor-initialization]=source1_2 } #[rustfmt::skip] -#[ctor::dtor] +#[ctor::dtor] // $ Source=source1_3 #[rustfmt::skip] -fn bad1_3() { // $ Alert[rust/ctor-initialization] - _ = std::io::stdout().write(b"Hello, world!"); +fn bad1_3() { + _ = std::io::stdout().write(b"Hello, world!"); // $ Alert[rust/ctor-initialization]=source1_3 } // --- code variants --- @@ -48,53 +48,53 @@ fn bad1_3() { // $ Alert[rust/ctor-initialization] use ctor::ctor; use std::io::*; -#[ctor] -fn bad2_1() { // $ Alert[rust/ctor-initialization] - _ = stdout().write(b"Hello, world!"); +#[ctor] // $ Source=source2_1 +fn bad2_1() { + _ = stdout().write(b"Hello, world!"); // $ Alert[rust/ctor-initialization]=source2_1 } -#[ctor] -fn bad2_2() { // $ Alert[rust/ctor-initialization] - _ = stderr().write_all(b"Hello, world!"); +#[ctor] // $ Source=source2_2 +fn bad2_2() { + _ = stderr().write_all(b"Hello, world!"); // $ Alert[rust/ctor-initialization]=source2_2 } -#[ctor] -fn bad2_3() { // $ Alert[rust/ctor-initialization] - println!("Hello, world!"); +#[ctor] // $ Source=source2_3 +fn bad2_3() { + println!("Hello, world!"); // $ Alert[rust/ctor-initialization]=source2_3 } -#[ctor] -fn bad2_4() { // $ Alert[rust/ctor-initialization] +#[ctor] // $ Source=source2_4 +fn bad2_4() { let mut buff = String::new(); - _ = std::io::stdin().read_line(&mut buff); + _ = std::io::stdin().read_line(&mut buff); // $ Alert[rust/ctor-initialization]=source2_4 } use std::fs; -#[ctor] -fn bad2_5() { // $ MISSING: Alert[rust/ctor-initialization] - let _buff = fs::File::create("hello.txt").unwrap(); +#[ctor] // $ MISSING: Source=source2_5 +fn bad2_5() { + let _buff = fs::File::create("hello.txt").unwrap(); // $ MISSING: Alert[rust/ctor-initialization]=source2_5 } -#[ctor] -fn bad2_6() { // $ MISSING: Alert[rust/ctor-initialization] - let _t = std::time::Instant::now(); +#[ctor] // $ MISSING: Source=source2_6 +fn bad2_6() { + let _t = std::time::Instant::now(); // $ MISSING: Alert[rust/ctor-initialization]=source2_6 } use std::time::Duration; const DURATION2_7: Duration = Duration::new(1, 0); -#[ctor] -fn bad2_7() { // $ Alert[rust/ctor-initialization] - std::thread::sleep(DURATION2_7); +#[ctor] // $ Source=source2_7 +fn bad2_7() { + std::thread::sleep(DURATION2_7); // $ Alert[rust/ctor-initialization]=source2_7 } use std::process; -#[ctor] -fn bad2_8() { // $ Alert[rust/ctor-initialization] - process::exit(1234); +#[ctor] // $ Source=source2_8 +fn bad2_8() { + process::exit(1234); // $ Alert[rust/ctor-initialization]=source2_8 } #[ctor::ctor] @@ -123,11 +123,11 @@ unsafe fn harmless2_11() { // --- transitive cases --- fn call_target3_1() { - _ = stderr().write_all(b"Hello, world!"); + _ = stderr().write_all(b"Hello, world!"); // $ MISSING: Alert=source3_1 Alert=source3_3 Alert=source3_4 } -#[ctor] -fn bad3_1() { // $ MISSING: Alert[rust/ctor-initialization] +#[ctor] // $ MISSING: Source=source3_1 +fn bad3_1() { call_target3_1(); } @@ -137,19 +137,19 @@ fn call_target3_2() { } } -#[ctor] +#[ctor] // $ MISSING: Source=source3_2 fn harmless3_2() { call_target3_2(); } #[ctor] -fn bad3_3() { // $ MISSING: Alert[rust/ctor-initialization] +fn bad3_3() { call_target3_1(); call_target3_2(); } -#[ctor] -fn bad3_4() { // $ MISSING: Alert[rust/ctor-initialization] +#[ctor] // $ MISSING: Source=source3_4 +fn bad3_4() { bad3_3(); } @@ -161,7 +161,7 @@ macro_rules! macro4_1 { }; } -#[ctor] -fn bad4_1() { // $ Alert[rust/ctor-initialization] - macro4_1!(); +#[ctor] // $ Source=source4_1 +fn bad4_1() { + macro4_1!(); // $ Alert[rust/ctor-initialization]=source4_1 } From e8981a505d2fb1db293c801b25cbe80f51271a58 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 25 Nov 2024 20:00:22 +0000 Subject: [PATCH 244/470] Rust: Fix qhelp. --- .../ql/src/queries/security/CWE-696/BadCtorInitialization.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.qhelp b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.qhelp index 60f6e3eb45d..3a3b2e48c6d 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.qhelp +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.qhelp @@ -5,7 +5,7 @@

    -Calling functions and methods in the Rust std library from a #[ctor] or #[dtor] function is not safe. This is because the std library only guarantees stability and portability between the beginning and end of main, whereas #[ctor] functions are called before main, and #[dtor] functions are called after it. +Calling functions and methods in the Rust std library from a #[ctor] or #[dtor] function is not safe. This is because the std library only guarantees stability and portability between the beginning and end of main, whereas #[ctor] functions are called before main, and #[dtor] functions are called after it.

    From e6302cae535e38eaca403a1dc868a968d9393a17 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 25 Nov 2024 20:07:47 +0000 Subject: [PATCH 245/470] Rust: Address CI and ql-for-ql issues. --- .../CWE-696/BadCtorInitialization.qhelp | 2 +- .../security/CWE-696/BadCtorInitialization.ql | 3 +-- .../CWE-696/BadCTorInitialization.expected | 20 +++++++++---------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.qhelp b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.qhelp index 3a3b2e48c6d..82683ccfdba 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.qhelp +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.qhelp @@ -12,7 +12,7 @@ Calling functions and methods in the Rust std library from a

    -Do not call any part of the std library from a #[ctor] or #[dtor] function. Instead either: +Do not call any part of the std library from a #[ctor] or #[dtor] function. Instead either:

    • Move the code to a different location, such as inside your program's main function.
    • diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index 90a7acc6920..9d9c698db24 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -54,5 +54,4 @@ query predicate edges(PathElement pred, PathElement succ) { from CtorAttr ctor, StdCall call where edges*(ctor, call) -select call, ctor, call, "Call to $@ in a function with the " + ctor.getWhichAttr() + " attribute.", - call, call.toString() +select call, ctor, call, "Call to " + call.toString() + " in a function with the " + ctor.getWhichAttr() + " attribute." diff --git a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected index 8ad81870e06..508a359b0c0 100644 --- a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected +++ b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected @@ -1,14 +1,14 @@ #select -| test.rs:31:9:31:25 | ...::stdout(...) | test.rs:29:1:29:13 | Attr | test.rs:31:9:31:25 | ...::stdout(...) | Call to $@ in a function with the ctor attribute. | test.rs:31:9:31:25 | ...::stdout(...) | ...::stdout(...) | -| test.rs:36:9:36:25 | ...::stdout(...) | test.rs:34:1:34:13 | Attr | test.rs:36:9:36:25 | ...::stdout(...) | Call to $@ in a function with the dtor attribute. | test.rs:36:9:36:25 | ...::stdout(...) | ...::stdout(...) | -| test.rs:43:9:43:25 | ...::stdout(...) | test.rs:40:1:40:13 | Attr | test.rs:43:9:43:25 | ...::stdout(...) | Call to $@ in a function with the dtor attribute. | test.rs:43:9:43:25 | ...::stdout(...) | ...::stdout(...) | -| test.rs:53:9:53:16 | stdout(...) | test.rs:51:1:51:7 | Attr | test.rs:53:9:53:16 | stdout(...) | Call to $@ in a function with the ctor attribute. | test.rs:53:9:53:16 | stdout(...) | stdout(...) | -| test.rs:58:9:58:16 | stderr(...) | test.rs:56:1:56:7 | Attr | test.rs:58:9:58:16 | stderr(...) | Call to $@ in a function with the ctor attribute. | test.rs:58:9:58:16 | stderr(...) | stderr(...) | -| test.rs:63:14:63:28 | ...::_print(...) | test.rs:61:1:61:7 | Attr | test.rs:63:14:63:28 | ...::_print(...) | Call to $@ in a function with the ctor attribute. | test.rs:63:14:63:28 | ...::_print(...) | ...::_print(...) | -| test.rs:69:9:69:24 | ...::stdin(...) | test.rs:66:1:66:7 | Attr | test.rs:69:9:69:24 | ...::stdin(...) | Call to $@ in a function with the ctor attribute. | test.rs:69:9:69:24 | ...::stdin(...) | ...::stdin(...) | -| test.rs:90:5:90:35 | ...::sleep(...) | test.rs:88:1:88:7 | Attr | test.rs:90:5:90:35 | ...::sleep(...) | Call to $@ in a function with the ctor attribute. | test.rs:90:5:90:35 | ...::sleep(...) | ...::sleep(...) | -| test.rs:97:5:97:23 | ...::exit(...) | test.rs:95:1:95:7 | Attr | test.rs:97:5:97:23 | ...::exit(...) | Call to $@ in a function with the ctor attribute. | test.rs:97:5:97:23 | ...::exit(...) | ...::exit(...) | -| test.rs:166:5:166:15 | ...::stdout(...) | test.rs:164:1:164:7 | Attr | test.rs:166:5:166:15 | ...::stdout(...) | Call to $@ in a function with the ctor attribute. | test.rs:166:5:166:15 | ...::stdout(...) | ...::stdout(...) | +| test.rs:31:9:31:25 | ...::stdout(...) | test.rs:29:1:29:13 | Attr | test.rs:31:9:31:25 | ...::stdout(...) | Call to ...::stdout(...) in a function with the ctor attribute. | +| test.rs:36:9:36:25 | ...::stdout(...) | test.rs:34:1:34:13 | Attr | test.rs:36:9:36:25 | ...::stdout(...) | Call to ...::stdout(...) in a function with the dtor attribute. | +| test.rs:43:9:43:25 | ...::stdout(...) | test.rs:40:1:40:13 | Attr | test.rs:43:9:43:25 | ...::stdout(...) | Call to ...::stdout(...) in a function with the dtor attribute. | +| test.rs:53:9:53:16 | stdout(...) | test.rs:51:1:51:7 | Attr | test.rs:53:9:53:16 | stdout(...) | Call to stdout(...) in a function with the ctor attribute. | +| test.rs:58:9:58:16 | stderr(...) | test.rs:56:1:56:7 | Attr | test.rs:58:9:58:16 | stderr(...) | Call to stderr(...) in a function with the ctor attribute. | +| test.rs:63:14:63:28 | ...::_print(...) | test.rs:61:1:61:7 | Attr | test.rs:63:14:63:28 | ...::_print(...) | Call to ...::_print(...) in a function with the ctor attribute. | +| test.rs:69:9:69:24 | ...::stdin(...) | test.rs:66:1:66:7 | Attr | test.rs:69:9:69:24 | ...::stdin(...) | Call to ...::stdin(...) in a function with the ctor attribute. | +| test.rs:90:5:90:35 | ...::sleep(...) | test.rs:88:1:88:7 | Attr | test.rs:90:5:90:35 | ...::sleep(...) | Call to ...::sleep(...) in a function with the ctor attribute. | +| test.rs:97:5:97:23 | ...::exit(...) | test.rs:95:1:95:7 | Attr | test.rs:97:5:97:23 | ...::exit(...) | Call to ...::exit(...) in a function with the ctor attribute. | +| test.rs:166:5:166:15 | ...::stdout(...) | test.rs:164:1:164:7 | Attr | test.rs:166:5:166:15 | ...::stdout(...) | Call to ...::stdout(...) in a function with the ctor attribute. | edges | test.rs:29:1:29:13 | Attr | test.rs:31:9:31:25 | ...::stdout(...) | | test.rs:34:1:34:13 | Attr | test.rs:36:9:36:25 | ...::stdout(...) | From 28c0e899b7e4ce67e3d1ea7c8ef3e752ba24d5ae Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 25 Nov 2024 20:50:56 +0000 Subject: [PATCH 246/470] Rust: Autoformat. --- rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index 9d9c698db24..8d434b1f6e4 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -54,4 +54,5 @@ query predicate edges(PathElement pred, PathElement succ) { from CtorAttr ctor, StdCall call where edges*(ctor, call) -select call, ctor, call, "Call to " + call.toString() + " in a function with the " + ctor.getWhichAttr() + " attribute." +select call, ctor, call, + "Call to " + call.toString() + " in a function with the " + ctor.getWhichAttr() + " attribute." From 460df89f28d58ae853697a3530b83189aebea7ec Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Mon, 25 Nov 2024 21:56:52 -0500 Subject: [PATCH 247/470] Add ``slices.Max`` example --- .../customizing-library-models-for-go.rst | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index 08bc8e29e19..5e96a2f314d 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -148,6 +148,53 @@ The remaining values are used to define the ``access path``, the ``kind``, and t - The eighth value ``remote`` is the kind of the source. The source kind is used to define the threat model where the source is in scope. ``remote`` applies to many of the security related queries as it means a remote source of untrusted data. As an example the SQL injection query uses ``remote`` sources. For more information, see ":ref:`Threat models `." - The ninth value ``manual`` is the provenance of the source, which is used to identify the origin of the source. +Example: Add flow through the ``Max`` function +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This example shows how the Go query pack models flow through a function for a simple case. +This pattern covers many of the cases where we need to summarize flow through a function that is stored in a library or framework outside the repository. + +.. code-block:: go + + import "slices" + + func ValueFlow { + a := []int{1, 2, 3} + max := slices.Max(a) // There is taint flow from `a` to `max`. + ... + } + +We need to add a tuple to the ``summaryModel``\(package, type, subtypes, name, signature, ext, input, output, kind, provenance) extensible predicate by updating a data extension file: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["slices", "", True, "Max", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + +Since we are adding flow through a method, we need to add tuples to the ``summaryModel`` extensible predicate. +Each tuple defines flow from one argument to the return value. +The first row defines flow from the first argument (``a`` in the example) to the return value (``max`` in the example). + +The first five values identify the function to be modeled as a summary. +These are the same for both of the rows above as we are adding two summaries for the same method. + +- The first value ``slices`` is the package name. +- The second value ``""`` is left blank, since the function is not a method of a type. +- The third value ``False`` is a flag that indicates whether or not the sink also applies to subtypes. This has no effect for non-method functions. +- The fourth value ``Max`` is the function name. +- The fifth value ``""`` is left blank, since specifying the signature is optional and Go does not allow multiple signature overloads for the same function. + +The sixth value should be left empty and is out of scope for this documentation. +The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the summary. + +- The seventh value is the access path to the input (where data flows from). ``Argument[0]`` is the access path to the first argument. +- The eighth value ``ReturnValue`` is the access path to the output (where data flows to), in this case ``ReturnValue``, which means that the input flows to the return value. +- The ninth value ``value`` is the kind of the flow. ``value`` flow indicates an entire value is moved, ``taint`` means that taint is propagated through the call. +- The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. Example: Add flow through the ``Join`` function ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This example shows how the Go query pack models flow through a method for a simple case. From 96a796585f849ee863632741da90255f799e5d3d Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Mon, 25 Nov 2024 21:57:09 -0500 Subject: [PATCH 248/470] fix formatting issue --- .../customizing-library-models-for-go.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index 5e96a2f314d..f02c79b397e 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -293,7 +293,7 @@ The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the summary. - The seventh value is the access path to the input (where data flows from). ``Argument[receiver]`` is the access path to the receiver (``u`` in the example). -- The eighth value ``ReturnValue`` is the access path to the output (where data flows to), in this case ``ReturnValue``, which means that the input flows to the return value. When there are multiple return values, use `ReturnValue[i]` to refer to the `i`th return value (starting from 0). +- The eighth value ``ReturnValue`` is the access path to the output (where data flows to), in this case ``ReturnValue``, which means that the input flows to the return value. When there are multiple return values, use ``ReturnValue[i]`` to refer to the ``i`` th return value (starting from 0). - The ninth value ``taint`` is the kind of the flow. ``taint`` means that taint is propagated through the call. - The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. From 8c6e08c94e83e96d7c687a101790600cdb793fc3 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Mon, 25 Nov 2024 21:57:24 -0500 Subject: [PATCH 249/470] Add ``slices.Concat`` example --- .../customizing-library-models-for-go.rst | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index f02c79b397e..5a200274f4a 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -195,6 +195,56 @@ The remaining values are used to define the ``access path``, the ``kind``, and t - The eighth value ``ReturnValue`` is the access path to the output (where data flows to), in this case ``ReturnValue``, which means that the input flows to the return value. - The ninth value ``value`` is the kind of the flow. ``value`` flow indicates an entire value is moved, ``taint`` means that taint is propagated through the call. - The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. + +Example: Add flow through the ``Concat`` function +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This example shows how the Go query pack models flow through a function for a simple case. +This pattern covers many of the cases where we need to summarize flow through a function that is stored in a library or framework outside the repository. + +.. code-block:: go + + import "slices" + + func ValueFlow { + a := []int{1, 2, 3} + b := []int{4, 5, 6} + c := slices.Concat(a, b) // There is taint flow from `a` and `b` to `c`. + ... + } + +We need to add a tuple to the ``summaryModel``\(package, type, subtypes, name, signature, ext, input, output, kind, provenance) extensible predicate by updating a data extension file: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["slices", "", True, "Concat", "", "", "Argument[0].ArrayElement.ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + +Since we are adding flow through a method, we need to add tuples to the ``summaryModel`` extensible predicate. +Each tuple defines flow from one argument to the return value. +The first row defines flow from the arguments (``a`` and ``b`` in the example) to the return value (``c`` in the example) and the second row defines flow from the second argument (``sep`` in the example) to the return value (``t`` in the example). + +The first five values identify the function to be modeled as a summary. +These are the same for both of the rows above as we are adding two summaries for the same method. + +- The first value ``slices`` is the package name. +- The second value ``""`` is left blank, since the function is not a method of a type. +- The third value ``False`` is a flag that indicates whether or not the sink also applies to subtypes. This has no effect for non-method functions. +- The fourth value ``Max`` is the function name. +- The fifth value ``""`` is left blank, since specifying the signature is optional and Go does not allow multiple signature overloads for the same function. + +The sixth value should be left empty and is out of scope for this documentation. +The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the summary. + +- The seventh value is the access path to the input (where data flows from). ``Argument[0]`` is the access path to the first argument. +- The eighth value ``ReturnValue`` is the access path to the output (where data flows to), in this case ``ReturnValue``, which means that the input flows to the return value. +- The ninth value ``value`` is the kind of the flow. ``value`` flow indicates an entire value is moved, ``taint`` means that taint is propagated through the call. +- The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. + Example: Add flow through the ``Join`` function ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This example shows how the Go query pack models flow through a method for a simple case. From 44b1ad52d98d9909e7d8f28139f4e442ee43a827 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Tue, 26 Nov 2024 09:02:13 +0100 Subject: [PATCH 250/470] Rust: Support self parameters in variable and SSA library --- rust/ql/.generated.list | 1 - rust/ql/.gitattributes | 1 - .../codeql/rust/dataflow/internal/SsaImpl.qll | 4 +- .../rust/elements/internal/ParamListImpl.qll | 9 +- .../rust/elements/internal/VariableImpl.qll | 85 ++++++++++--------- .../test/library-tests/variables/Ssa.expected | 12 +++ .../variables/variables.expected | 9 ++ .../test/library-tests/variables/variables.rs | 6 +- 8 files changed, 79 insertions(+), 48 deletions(-) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 913bdf1d293..502e44e0c50 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -296,7 +296,6 @@ lib/codeql/rust/elements/internal/OrPatConstructor.qll 4ef583e07298487c0c4c6d7c7 lib/codeql/rust/elements/internal/ParamBaseImpl.qll fe11999c728c443c46c992e9bed7a2b3e23afa16ae99592e70054bc57ae371b8 df86fdb23266bdfb9ed8a8f02558a760b67f173943b9d075b081229eb5844f66 lib/codeql/rust/elements/internal/ParamConstructor.qll b98a2d8969f289fdcc8c0fb11cbd19a3b0c71be038c4a74f5988295a2bae52f0 77d81b31064167945b79b19d9697b57ca24462c3a7cc19e462c4693ce87db532 lib/codeql/rust/elements/internal/ParamListConstructor.qll 3123142ab3cab46fb53d7f3eff6ba2d3ff7a45b78839a53dc1979a9c6a54920e 165f3d777ea257cfcf142cc4ba9a0ebcd1902eb99842b8a6657c87087f3df6fe -lib/codeql/rust/elements/internal/ParamListImpl.qll 0ed6e9affe1dc0144641502292c2ddd51958fe3d503419caf15198176e3a4174 92d053cc5fdf40a2d98acb665083b5da15403d7da205779a97a4ee66fac0add4 lib/codeql/rust/elements/internal/ParenExprConstructor.qll 104b67dc3fd53ab52e2a42ffde37f3a3a50647aa7bf35df9ba9528e9670da210 d1f5937756e87a477710c61698d141cdad0ccce8b07ecb51bab00330a1ca9835 lib/codeql/rust/elements/internal/ParenPatConstructor.qll 9aea3c3b677755177d85c63e20234c234f530a16db20ab699de05ca3f1b59787 29f24aed0d880629a53b30550467ade09a0a778dbf88891769c1e11b0b239f98 lib/codeql/rust/elements/internal/ParenTypeConstructor.qll d62e656a4a3c8ffd4eb87d49585a7a3bfb5dbe3826fbcbd11cb87b46f34c19ae febf6535965afa0f6eac4d2b08730f5a07bbb36a7434abe0a7663d7264961a3f diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index afb5cbf6c69..e1cb09559dc 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -298,7 +298,6 @@ /lib/codeql/rust/elements/internal/ParamBaseImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ParamConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ParamListConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/ParamListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ParenExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ParenPatConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ParenTypeConstructor.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll index 6e9032f1dc4..64e2d54722d 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll @@ -24,6 +24,8 @@ predicate variableWrite(AstNode write, Variable v) { not isUnitializedLet(pat, v) ) or + exists(SelfParam self | self = write and self = v.getSelfParam()) + or exists(VariableAccess access | access = write and access.getVariable() = v @@ -477,7 +479,7 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu none() // handled in `DataFlowImpl.qll` instead } - class Parameter = CfgNodes::ParamCfgNode; + class Parameter = CfgNodes::ParamBaseCfgNode; /** Holds if SSA definition `def` initializes parameter `p` at function entry. */ predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) { diff --git a/rust/ql/lib/codeql/rust/elements/internal/ParamListImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ParamListImpl.qll index e31c2734355..297b7f26fad 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ParamListImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ParamListImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `ParamList`. * @@ -12,11 +11,17 @@ private import codeql.rust.elements.internal.generated.ParamList * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A ParamList. For example: * ```rust * todo!() * ``` */ - class ParamList extends Generated::ParamList { } + class ParamList extends Generated::ParamList { + /** + * Gets any of the parameters of this parameter list. + */ + final ParamBase getAParamBase() { result = this.getParam(_) or result = this.getSelfParam() } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index 80c70f6f6fa..d2ae6c48dfc 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -73,24 +73,33 @@ module Impl { * where `definingNode` is the entire `Either::Left(x) | Either::Right(x)` * pattern. */ - private predicate variableDecl(AstNode definingNode, IdentPat p, string name) { - ( - definingNode = getOutermostEnclosingOrPat(p) - or - not exists(getOutermostEnclosingOrPat(p)) and - definingNode = p.getName() - ) and - name = p.getName().getText() and - // exclude for now anything starting with an uppercase character, which may be a reference to - // an enum constant (e.g. `None`). This excludes static and constant variables (UPPERCASE), - // which we don't appear to recognize yet anyway. This also assumes programmers follow the - // naming guidelines, which they generally do, but they're not enforced. - not name.charAt(0).isUppercase() and - // exclude parameters from functions without a body as these are trait method declarations - // without implementations - not exists(Function f | not f.hasBody() and f.getParamList().getAParam().getPat() = p) and - // exclude parameters from function pointer types (e.g. `x` in `fn(x: i32) -> i32`) - not exists(FnPtrType fp | fp.getParamList().getParam(_).getPat() = p) + private predicate variableDecl(AstNode definingNode, AstNode p, string name) { + exists(SelfParam sp | sp = p | + definingNode = sp.getName() and + name = sp.getName().getText() and + // exclude self parameters from functions without a body as these are + // trait method declarations without implementations + not exists(Function f | not f.hasBody() and f.getParamList().getSelfParam() = sp) + ) + or + exists(IdentPat pat | pat = p | + ( + definingNode = getOutermostEnclosingOrPat(pat) + or + not exists(getOutermostEnclosingOrPat(pat)) and definingNode = pat.getName() + ) and + name = pat.getName().getText() and + // exclude for now anything starting with an uppercase character, which may be a reference to + // an enum constant (e.g. `None`). This excludes static and constant variables (UPPERCASE), + // which we don't appear to recognize yet anyway. This also assumes programmers follow the + // naming guidelines, which they generally do, but they're not enforced. + not name.charAt(0).isUppercase() and + // exclude parameters from functions without a body as these are trait method declarations + // without implementations + not exists(Function f | not f.hasBody() and f.getParamList().getAParam().getPat() = pat) and + // exclude parameters from function pointer types (e.g. `x` in `fn(x: i32) -> i32`) + not exists(FnPtrType fp | fp.getParamList().getParam(_).getPat() = pat) + ) } /** A variable. */ @@ -112,8 +121,11 @@ module Impl { /** Gets an access to this variable. */ VariableAccess getAnAccess() { result.getVariable() = this } + /** Gets the `self` parameter that declares this variable, if one exists. */ + SelfParam getSelfParam() { variableDecl(definingNode, result, name) } + /** - * Gets the pattern that declares this variable. + * Gets the pattern that declares this variable, if one exists. * * Normally, the pattern is unique, except when introduced in an or pattern: * @@ -135,7 +147,9 @@ module Impl { predicate isCaptured() { this.getAnAccess().isCapture() } /** Gets the parameter that introduces this variable, if any. */ - Param getParameter() { parameterDeclInScope(result, this, _) } + ParamBase getParameter() { + result = this.getSelfParam() or result = getAVariablePatAncestor(this).getParentNode() + } /** Hold is this variable is mutable. */ predicate isMutable() { this.getPat().isMut() } @@ -144,7 +158,11 @@ module Impl { predicate isImmutable() { not this.isMutable() } } - /** A path expression that may access a local variable. */ + /** + * A path expression that may access a local variable. These are paths that + * only consists of a simple name (i.e., without generic arguments, + * qualifiers, etc.). + */ private class VariableAccessCand extends PathExprBase { string name_; @@ -190,10 +208,7 @@ module Impl { private VariableScope getEnclosingScope(AstNode n) { result = getAnAncestorInVariableScope(n) } private Pat getAVariablePatAncestor(Variable v) { - exists(AstNode definingNode, string name | - v = MkVariable(definingNode, name) and - variableDecl(definingNode, result, name) - ) + result = v.getPat() or exists(Pat mid | mid = getAVariablePatAncestor(v) and @@ -205,20 +220,10 @@ module Impl { * Holds if parameter `p` introduces the variable `v` inside variable scope * `scope`. */ - private predicate parameterDeclInScope(Param p, Variable v, VariableScope scope) { - exists(Pat pat | - pat = getAVariablePatAncestor(v) and - p.getPat() = pat - | - exists(Function f | - f.getParamList().getAParam() = p and - scope = f.getBody() - ) - or - exists(ClosureExpr ce | - ce.getParamList().getAParam() = p and - scope = ce.getBody() - ) + private predicate parameterDeclInScope(Variable v, VariableScope scope) { + exists(Callable f | + v.getParameter() = f.getParamList().getAParamBase() and + scope = [f.(Function).getBody(), f.(ClosureExpr).getBody()] ) } @@ -231,7 +236,7 @@ module Impl { ) { name = v.getName() and ( - parameterDeclInScope(_, v, scope) and + parameterDeclInScope(v, scope) and scope.getLocation().hasLocationFileInfo(_, line, column, _, _) or exists(Pat pat | pat = getAVariablePatAncestor(v) | diff --git a/rust/ql/test/library-tests/variables/Ssa.expected b/rust/ql/test/library-tests/variables/Ssa.expected index 832b105837c..ac6ec176a29 100644 --- a/rust/ql/test/library-tests/variables/Ssa.expected +++ b/rust/ql/test/library-tests/variables/Ssa.expected @@ -134,8 +134,11 @@ definition | variables.rs:461:13:461:14 | b1 | variables.rs:461:13:461:14 | b1 | | variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:25 | b2 | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | +| variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self | +| variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | | variables.rs:501:9:501:9 | x | variables.rs:501:9:501:9 | x | | variables.rs:505:9:505:9 | z | variables.rs:505:9:505:9 | z | +| variables.rs:514:10:514:18 | SelfParam | variables.rs:514:15:514:18 | self | read | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i | @@ -257,7 +260,10 @@ read | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:466:19:466:19 | x | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:470:19:470:19 | x | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:472:19:472:19 | x | +| variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self | variables.rs:483:16:483:19 | self | +| variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | variables.rs:487:9:487:12 | self | | variables.rs:501:9:501:9 | x | variables.rs:501:9:501:9 | x | variables.rs:503:15:503:15 | x | +| variables.rs:514:10:514:18 | SelfParam | variables.rs:514:15:514:18 | self | variables.rs:515:6:515:9 | self | firstRead | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i | @@ -356,7 +362,10 @@ firstRead | variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:25 | b2 | variables.rs:469:8:469:9 | b2 | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:464:19:464:19 | x | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:466:19:466:19 | x | +| variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self | variables.rs:483:16:483:19 | self | +| variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | variables.rs:487:9:487:12 | self | | variables.rs:501:9:501:9 | x | variables.rs:501:9:501:9 | x | variables.rs:503:15:503:15 | x | +| variables.rs:514:10:514:18 | SelfParam | variables.rs:514:15:514:18 | self | variables.rs:515:6:515:9 | self | lastRead | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i | @@ -456,7 +465,10 @@ lastRead | variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:25 | b2 | variables.rs:469:8:469:9 | b2 | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:470:19:470:19 | x | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:472:19:472:19 | x | +| variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self | variables.rs:483:16:483:19 | self | +| variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | variables.rs:487:9:487:12 | self | | variables.rs:501:9:501:9 | x | variables.rs:501:9:501:9 | x | variables.rs:503:15:503:15 | x | +| variables.rs:514:10:514:18 | SelfParam | variables.rs:514:15:514:18 | self | variables.rs:515:6:515:9 | self | adjacentReads | variables.rs:35:9:35:10 | x3 | variables.rs:35:9:35:10 | x3 | variables.rs:36:15:36:16 | x3 | variables.rs:38:9:38:10 | x3 | | variables.rs:43:9:43:10 | x4 | variables.rs:43:9:43:10 | x4 | variables.rs:44:15:44:16 | x4 | variables.rs:49:15:49:16 | x4 | diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index df9cc5e1644..9abee1df82e 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -95,9 +95,12 @@ variable | variables.rs:461:13:461:14 | b1 | | variables.rs:461:24:461:25 | b2 | | variables.rs:462:9:462:9 | x | +| variables.rs:482:20:482:23 | self | +| variables.rs:486:11:486:14 | self | | variables.rs:492:13:492:13 | a | | variables.rs:501:9:501:9 | x | | variables.rs:505:9:505:9 | z | +| variables.rs:514:15:514:18 | self | | variables.rs:520:11:520:11 | a | variableAccess | variables.rs:4:20:4:20 | s | variables.rs:3:14:3:14 | s | @@ -246,6 +249,8 @@ variableAccess | variables.rs:469:8:469:9 | b2 | variables.rs:461:24:461:25 | b2 | | variables.rs:470:19:470:19 | x | variables.rs:462:9:462:9 | x | | variables.rs:472:19:472:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:483:16:483:19 | self | variables.rs:482:20:482:23 | self | +| variables.rs:487:9:487:12 | self | variables.rs:486:11:486:14 | self | | variables.rs:493:15:493:15 | a | variables.rs:492:13:492:13 | a | | variables.rs:494:5:494:5 | a | variables.rs:492:13:492:13 | a | | variables.rs:495:15:495:15 | a | variables.rs:492:13:492:13 | a | @@ -254,6 +259,7 @@ variableAccess | variables.rs:502:20:502:20 | x | variables.rs:501:9:501:9 | x | | variables.rs:503:15:503:15 | x | variables.rs:501:9:501:9 | x | | variables.rs:506:20:506:20 | z | variables.rs:505:9:505:9 | z | +| variables.rs:515:6:515:9 | self | variables.rs:514:15:514:18 | self | | variables.rs:521:3:521:3 | a | variables.rs:520:11:520:11 | a | | variables.rs:523:13:523:13 | a | variables.rs:520:11:520:11 | a | variableWriteAccess @@ -396,11 +402,14 @@ variableReadAccess | variables.rs:469:8:469:9 | b2 | variables.rs:461:24:461:25 | b2 | | variables.rs:470:19:470:19 | x | variables.rs:462:9:462:9 | x | | variables.rs:472:19:472:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:483:16:483:19 | self | variables.rs:482:20:482:23 | self | +| variables.rs:487:9:487:12 | self | variables.rs:486:11:486:14 | self | | variables.rs:493:15:493:15 | a | variables.rs:492:13:492:13 | a | | variables.rs:494:5:494:5 | a | variables.rs:492:13:492:13 | a | | variables.rs:495:15:495:15 | a | variables.rs:492:13:492:13 | a | | variables.rs:497:15:497:15 | a | variables.rs:492:13:492:13 | a | | variables.rs:503:15:503:15 | x | variables.rs:501:9:501:9 | x | +| variables.rs:515:6:515:9 | self | variables.rs:514:15:514:18 | self | | variables.rs:521:3:521:3 | a | variables.rs:520:11:520:11 | a | | variables.rs:523:13:523:13 | a | variables.rs:520:11:520:11 | a | variableInitializer diff --git a/rust/ql/test/library-tests/variables/variables.rs b/rust/ql/test/library-tests/variables/variables.rs index 40f26ab0fc8..4bab6d12aea 100644 --- a/rust/ql/test/library-tests/variables/variables.rs +++ b/rust/ql/test/library-tests/variables/variables.rs @@ -480,11 +480,11 @@ struct MyStruct { impl MyStruct { fn my_get(&mut self) -> i64 { - return self.val; // $ MISSING: read_access=self + return self.val; // $ read_access=self } fn id(self) -> Self { - self // $ MISSING: read_access=self + self // $ read_access=self } } @@ -512,7 +512,7 @@ trait Bar { impl MyStruct { fn bar(&mut self) { - *self = MyStruct { val: 3 }; // MISSING: $ read_access=self + *self = MyStruct { val: 3 }; // $ read_access=self } } From 8252e1da02d25d0b8cf18f31d66b46352b3803ce Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Tue, 26 Nov 2024 09:21:44 +0100 Subject: [PATCH 251/470] Rust: Change &String to &str --- rust/ast-generator/src/main.rs | 38 ++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/rust/ast-generator/src/main.rs b/rust/ast-generator/src/main.rs index 665ffbac6c7..41e6caa6de3 100644 --- a/rust/ast-generator/src/main.rs +++ b/rust/ast-generator/src/main.rs @@ -14,24 +14,26 @@ fn project_root() -> PathBuf { PathBuf::from(dir).parent().unwrap().to_owned() } -fn class_name(type_name: &String) -> String { - match type_name.as_str() { - "BinExpr" => "BinaryExpr".to_owned(), - "ElseBranch" => "Expr".to_owned(), - "Fn" => "Function".to_owned(), - "Literal" => "LiteralExpr".to_owned(), - "Type" => "TypeRef".to_owned(), - _ => type_name.to_owned(), - } +fn class_name(type_name: &str) -> String { + let name = match type_name { + "BinExpr" => "BinaryExpr", + "ElseBranch" => "Expr", + "Fn" => "Function", + "Literal" => "LiteralExpr", + "Type" => "TypeRef", + _ => type_name, + }; + name.to_owned() } -fn property_name(type_name: &String, field_name: &String) -> String { - match (type_name.as_str(), field_name.as_str()) { - ("Path", "segment") => "part".to_owned(), - (_, "then_branch") => "then".to_owned(), - (_, "else_branch") => "else_".to_owned(), - _ => field_name.to_owned(), - } +fn property_name(type_name: &str, field_name: &str) -> String { + let name = match (type_name, field_name) { + ("Path", "segment") => "part", + (_, "then_branch") => "then", + (_, "else_branch") => "else_", + _ => field_name, + }; + name.to_owned() } fn to_lower_snake_case(s: &str) -> String { @@ -61,7 +63,7 @@ fn write_schema( for node in &grammar.enums { let super_classses = if let Some(cls) = super_types.get(&node.name) { - let super_classes: Vec = cls.iter().map(class_name).collect(); + let super_classes: Vec = cls.iter().map(|s| class_name(s)).collect(); super_classes.join(",") } else { "AstNode".to_owned() @@ -76,7 +78,7 @@ fn write_schema( } for node in &grammar.nodes { let super_classses = if let Some(cls) = super_types.get(&node.name) { - let super_classes: Vec = cls.iter().map(class_name).collect(); + let super_classes: Vec = cls.iter().map(|s| class_name(s)).collect(); super_classes.join(",") } else { "AstNode".to_owned() From 8a01161d4a0010e7596c262ce7292b784813c95f Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 26 Nov 2024 10:42:13 +0100 Subject: [PATCH 252/470] Rust: rename `MatchExpr.expr` to `scrutinee` in all layers This doesn't require `ql.name` and is simpler while we don't have to write upgrade scripts. The `ql.name` mechanism might get useful once we do have to write upgrade scripts, as that doesn't change the dbscheme. --- rust/ast-generator/src/main.rs | 1 + rust/extractor/src/generated/.generated.list | 2 +- rust/extractor/src/generated/top.rs | 6 +++--- rust/extractor/src/translate/generated.rs | 4 ++-- rust/ql/.generated.list | 2 +- rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll | 2 +- rust/ql/lib/rust.dbscheme | 4 ++-- rust/schema/annotations.py | 2 +- rust/schema/ast.py | 2 +- 9 files changed, 13 insertions(+), 12 deletions(-) diff --git a/rust/ast-generator/src/main.rs b/rust/ast-generator/src/main.rs index 665ffbac6c7..ff2e820f43b 100644 --- a/rust/ast-generator/src/main.rs +++ b/rust/ast-generator/src/main.rs @@ -28,6 +28,7 @@ fn class_name(type_name: &String) -> String { fn property_name(type_name: &String, field_name: &String) -> String { match (type_name.as_str(), field_name.as_str()) { ("Path", "segment") => "part".to_owned(), + ("MatchExpr", "expr") => "scrutinee".to_owned(), (_, "then_branch") => "then".to_owned(), (_, "else_branch") => "else_".to_owned(), _ => field_name.to_owned(), diff --git a/rust/extractor/src/generated/.generated.list b/rust/extractor/src/generated/.generated.list index 3ff79b9b041..3aeca1d0f9d 100644 --- a/rust/extractor/src/generated/.generated.list +++ b/rust/extractor/src/generated/.generated.list @@ -1,2 +1,2 @@ mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 -top.rs 4504ceb7e13020d5b19a4b938395fa2d5d804a962743985efe8563903448ae0c 4504ceb7e13020d5b19a4b938395fa2d5d804a962743985efe8563903448ae0c +top.rs abab6a736e75f9eabbe31deef4de782fc05f0c053798a01d410fffc859515278 abab6a736e75f9eabbe31deef4de782fc05f0c053798a01d410fffc859515278 diff --git a/rust/extractor/src/generated/top.rs b/rust/extractor/src/generated/top.rs index a3e1d7aac80..5e09dbf71ed 100644 --- a/rust/extractor/src/generated/top.rs +++ b/rust/extractor/src/generated/top.rs @@ -5530,7 +5530,7 @@ impl From> for trap::Label { pub struct MatchExpr { pub id: trap::TrapId, pub attrs: Vec>, - pub expr: Option>, + pub scrutinee: Option>, pub match_arm_list: Option>, } @@ -5544,8 +5544,8 @@ impl trap::TrapEntry for MatchExpr { for (i, v) in self.attrs.into_iter().enumerate() { out.add_tuple("match_expr_attrs", vec![id.into(), i.into(), v.into()]); } - if let Some(v) = self.expr { - out.add_tuple("match_expr_exprs", vec![id.into(), v.into()]); + if let Some(v) = self.scrutinee { + out.add_tuple("match_expr_scrutinees", vec![id.into(), v.into()]); } if let Some(v) = self.match_arm_list { out.add_tuple("match_expr_match_arm_lists", vec![id.into(), v.into()]); diff --git a/rust/extractor/src/translate/generated.rs b/rust/extractor/src/translate/generated.rs index aea607b753d..ee4e693ab73 100644 --- a/rust/extractor/src/translate/generated.rs +++ b/rust/extractor/src/translate/generated.rs @@ -1224,12 +1224,12 @@ impl Translator<'_> { pub(crate) fn emit_match_expr(&mut self, node: ast::MatchExpr) -> Label { let attrs = node.attrs().map(|x| self.emit_attr(x)).collect(); - let expr = node.expr().map(|x| self.emit_expr(x)); + let scrutinee = node.expr().map(|x| self.emit_expr(x)); let match_arm_list = node.match_arm_list().map(|x| self.emit_match_arm_list(x)); let label = self.trap.emit(generated::MatchExpr { id: TrapId::Star, attrs, - expr, + scrutinee, match_arm_list, }); self.emit_location(label, &node); diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 36416013959..7fc34f99492 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -525,7 +525,7 @@ lib/codeql/rust/elements/internal/generated/PtrType.qll 40099c5a4041314b66932dfd lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll efd93730de217cf50dcba5875595263a5eadf9f7e4e1272401342a094d158614 229b251b3d118932e31e78ac4dfb75f48b766f240f20d436062785606d44467b -lib/codeql/rust/elements/internal/generated/Raw.qll b342060fd7fe2214eea191859f559334a8a64cf6785048f784ed641ea1e616fd 4737f09bbd2e190eee9bb83476a0045887ff2982dd06cd4e6538fc31637ab521 +lib/codeql/rust/elements/internal/generated/Raw.qll 9476dd5a6607f722de107b51713c1f529e95429416c7e0d102b78779cf826fe6 b3a4d58fb560c89344ac734cfda3df7f4dcb627c2db79dbe26babd6a67e69dce lib/codeql/rust/elements/internal/generated/RecordExpr.qll eb6cb662e463f9260efae1a6ce874fa781172063b916ef1963f861e9942d308d 1a21cbccc8f3799ff13281e822818ebfb21d81591720a427cac3625512cb9d40 lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1 lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0 diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index 69aa32d4ad8..76d170244d5 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -2172,7 +2172,7 @@ module Raw { /** * Gets the scrutinee (the expression being matched) of this match expression, if it exists. */ - Expr getScrutinee() { match_expr_exprs(this, result) } + Expr getScrutinee() { match_expr_scrutinees(this, result) } /** * Gets the match arm list of this match expression, if it exists. diff --git a/rust/ql/lib/rust.dbscheme b/rust/ql/lib/rust.dbscheme index 7c2ba7da58c..46085a55abf 100644 --- a/rust/ql/lib/rust.dbscheme +++ b/rust/ql/lib/rust.dbscheme @@ -1896,9 +1896,9 @@ match_expr_attrs( ); #keyset[id] -match_expr_exprs( +match_expr_scrutinees( int id: @match_expr ref, - int expr: @expr ref + int scrutinee: @expr ref ); #keyset[id] diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index 9e857ad7b0f..68dae52ab1d 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -289,7 +289,7 @@ class _: } ``` """ - expr: _ | ql.name("scrutinee") | doc("scrutinee (the expression being matched) of this match expression") + scrutinee: _ | doc("scrutinee (the expression being matched) of this match expression") @annotate(ContinueExpr, cfg = True) diff --git a/rust/schema/ast.py b/rust/schema/ast.py index bdbb1990d30..3e9b1b0ead3 100644 --- a/rust/schema/ast.py +++ b/rust/schema/ast.py @@ -364,7 +364,7 @@ class MatchArmList(AstNode): class MatchExpr(Expr): attrs: list["Attr"] | child - expr: optional["Expr"] | child + scrutinee: optional["Expr"] | child match_arm_list: optional["MatchArmList"] | child class MatchGuard(AstNode): From f508f8eb83b79e0ffa508cd24b4bd04baf7acba4 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 26 Nov 2024 11:44:16 +0100 Subject: [PATCH 253/470] Java: address review comments --- .../dataflow/range-analysis-inline/B.java | 64 +++++++++++++++---- .../dataflow/range-analysis-inline/range.ql | 9 +-- 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java b/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java index 22eb7dfcb0f..01c8656deea 100644 --- a/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java +++ b/java/ql/test/library-tests/dataflow/range-analysis-inline/B.java @@ -4,7 +4,7 @@ public class B { // that should also be annotated. static void bound(int b) { } - public int forloop() { + public int forLoop() { int result = 0; for (int i = 0; i < 10; // $ bound="i in [0..10]" @@ -14,7 +14,7 @@ public class B { return result; // $ bound="result in [0..9]" } - public int forloopexit() { + public int forLoopExit() { int result = 0; for (; result < 10;) { // $ bound="result in [0..10]" result += 1; // $ bound="result in [0..9]" @@ -22,7 +22,7 @@ public class B { return result; // $ bound="result = 10" } - public int forloopexitstep() { + public int forLoopExitStep() { int result = 0; for (; result < 10;) { // $ bound="result in [0..12]" result += 3; // $ bound="result in [0..9]" @@ -30,7 +30,7 @@ public class B { return result; // $ bound="result = 12" } - public int forloopexitupd() { + public int forLoopExitUpd() { int result = 0; for (; result < 10; // $ bound="result in [0..10]" result++) { // $ bound="result in [0..9]" @@ -38,7 +38,7 @@ public class B { return result; // $ bound="result = 10" } - public int forloopexitnested() { + public int forLoopExitNested() { int result = 0; for (; result < 10;) { int i = 0; @@ -50,7 +50,7 @@ public class B { return result; // $ MISSING:bound="result = 12" } - public int emptyforloop() { + public int emptyForLoop() { int result = 0; for (int i = 0; i < 0; // $ bound="i = 0" i++) { // $ bound="i in [0..-1]" @@ -59,13 +59,13 @@ public class B { return result; // $ bound="result = 0" } - public int noloop() { + public int noLoop() { int result = 0; result += 1; // $ bound="result = 0" return result; // $ bound="result = 1" } - public int foreachloop() { + public int foreachLoop() { int result = 0; for (int i : new int[] {1, 2, 3, 4, 5}) { result = i; @@ -73,7 +73,7 @@ public class B { return result; } - public int emptyforeachloop() { + public int emptyForeachLoop() { int result = 0; for (int i : new int[] {}) { result = i; @@ -81,7 +81,7 @@ public class B { return result; } - public int whileloop() { + public int whileLoop() { int result = 100; while (result > 5) { // $ bound="result in [4..100]" result = result - 2; // $ bound="result in [6..100]" @@ -89,7 +89,7 @@ public class B { return result; // $ bound="result = 4" } - public int oddwhileloop() { + public int oddWhileLoop() { int result = 101; while (result > 5) { // $ bound="result in [5..101]" result = result - 2; // $ bound="result in [7..101]" @@ -97,7 +97,7 @@ public class B { return result; // $ bound="result = 5" } - static void arraylength(int[] arr) { + static void arrayLength(int[] arr) { bound(arr.length); for (int i = 0; i < arr.length; @@ -106,7 +106,7 @@ public class B { } } - static int varbound(int b) { + static int varBound(int b) { bound(b); int result = 0; for (int i = 0; @@ -114,7 +114,45 @@ public class B { i++) { // $ bound="i <= b - 1" result = i; // $ bound="i <= b - 1" } + return result; // We cannot conclude anything here, since we do not know that b > 0 + } + + static int varBoundPositiveGuard(int b) { + bound(b); + if (b > 0) { + int result = 0; + for (int i = 0; + i < b; + i++) { // $ bound="i <= b - 1" + result = i; // $ bound="i <= b - 1" + } + return result; // $ MISSING: bound="result <= b - 1" + } else { + return 0; + } + } + + static int varBoundPositiveGuardEarlyReturn(int b) { + bound(b); + if (b <= 0) return 0; + int result = 0; + for (int i = 0; + i < b; + i++) { // $ bound="i <= b - 1" + result = i; // $ bound="i <= b - 1" + } return result; // $ MISSING: bound="result <= b - 1" } + static int varBoundPositiveAssert(int b) { + bound(b); + assert b > 0; + int result = 0; + for (int i = 0; + i < b; + i++) { // $ bound="i <= b - 1" + result = i; // $ bound="i <= b - 1" + } + return result; // $ MISSING: bound="result <= b - 1" + } } \ No newline at end of file diff --git a/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql b/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql index 263df27d316..b0fcc1710d4 100644 --- a/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql +++ b/java/ql/test/library-tests/dataflow/range-analysis-inline/range.ql @@ -6,7 +6,6 @@ import java import semmle.code.java.dataflow.RangeAnalysis private import TestUtilities.InlineExpectationsTest as IET -private import semmle.code.java.dataflow.DataFlow module RangeTest implements IET::TestSig { string getARelevantTag() { result = "bound" } @@ -29,10 +28,8 @@ module RangeTest implements IET::TestSig { ) or // advanced bounds - exists( - Expr e, int delta, string deltaStr, boolean upper, string cmp, Bound b, Expr boundExpr - | - annotatedBound(e, b, boundExpr, delta, upper) and + exists(Expr e, int delta, string deltaStr, boolean upper, string cmp, Expr boundExpr | + annotatedBound(e, _, boundExpr, delta, upper) and e instanceof VarRead and e.getCompilationUnit().fromSource() and ( @@ -67,7 +64,7 @@ module RangeTest implements IET::TestSig { boundExpr = b.getExpr() and exists(Call c | c.getCallee().getName() = "bound" and c.getArgument(0) = boundExpr) and // non-trivial bound - (DataFlow::localFlow(DataFlow::exprNode(boundExpr), DataFlow::exprNode(e)) implies delta != 0) + not e = b.getExpr() } } From d9b278de666c03c93ee4c27a341554a0bc6c3148 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 26 Nov 2024 11:45:55 +0100 Subject: [PATCH 254/470] C++: Promote `cpp/guarded-free` --- .../Best Practices/GuardedFree.cpp | 0 .../Best Practices/GuardedFree.qhelp | 18 ++++++++++++++---- .../Best Practices/GuardedFree.ql | 1 - .../GuardedFree/GuardedFree.expected | 0 .../GuardedFree/GuardedFree.qlref | 0 .../Best Practices/GuardedFree/test.cpp | 0 6 files changed, 14 insertions(+), 5 deletions(-) rename cpp/ql/src/{experimental => }/Best Practices/GuardedFree.cpp (100%) rename cpp/ql/src/{experimental => }/Best Practices/GuardedFree.qhelp (66%) rename cpp/ql/src/{experimental => }/Best Practices/GuardedFree.ql (98%) rename cpp/ql/test/{experimental => }/query-tests/Best Practices/GuardedFree/GuardedFree.expected (100%) rename cpp/ql/test/{experimental => }/query-tests/Best Practices/GuardedFree/GuardedFree.qlref (100%) rename cpp/ql/test/{experimental => }/query-tests/Best Practices/GuardedFree/test.cpp (100%) diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.cpp b/cpp/ql/src/Best Practices/GuardedFree.cpp similarity index 100% rename from cpp/ql/src/experimental/Best Practices/GuardedFree.cpp rename to cpp/ql/src/Best Practices/GuardedFree.cpp diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.qhelp b/cpp/ql/src/Best Practices/GuardedFree.qhelp similarity index 66% rename from cpp/ql/src/experimental/Best Practices/GuardedFree.qhelp rename to cpp/ql/src/Best Practices/GuardedFree.qhelp index 77fdd467000..ba78749bef0 100644 --- a/cpp/ql/src/experimental/Best Practices/GuardedFree.qhelp +++ b/cpp/ql/src/Best Practices/GuardedFree.qhelp @@ -1,18 +1,28 @@ - - + + +

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

      + -

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

      +

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

      + + +

      In this example the condition checking the value of foo can be deleted. + +

    • The Open Group Base Specifications Issue 7, 2018 Edition: free - free allocated memory
    • -
      \ No newline at end of file + +
      diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql b/cpp/ql/src/Best Practices/GuardedFree.ql similarity index 98% rename from cpp/ql/src/experimental/Best Practices/GuardedFree.ql rename to cpp/ql/src/Best Practices/GuardedFree.ql index 66c7a31111b..ea81a715828 100644 --- a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql +++ b/cpp/ql/src/Best Practices/GuardedFree.ql @@ -8,7 +8,6 @@ * @id cpp/guarded-free * @tags maintainability * readability - * experimental */ import cpp diff --git a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected b/cpp/ql/test/query-tests/Best Practices/GuardedFree/GuardedFree.expected similarity index 100% rename from cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected rename to cpp/ql/test/query-tests/Best Practices/GuardedFree/GuardedFree.expected diff --git a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.qlref b/cpp/ql/test/query-tests/Best Practices/GuardedFree/GuardedFree.qlref similarity index 100% rename from cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.qlref rename to cpp/ql/test/query-tests/Best Practices/GuardedFree/GuardedFree.qlref diff --git a/cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp b/cpp/ql/test/query-tests/Best Practices/GuardedFree/test.cpp similarity index 100% rename from cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp rename to cpp/ql/test/query-tests/Best Practices/GuardedFree/test.cpp From 47eb407be9fcbd6e6ad40d78c6ab0924d255c5cd Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 26 Nov 2024 12:00:10 +0000 Subject: [PATCH 255/470] Update Go version in stdlib tests --- .../library-tests/semmle/go/frameworks/StdlibTaintFlow/go.mod | 2 +- .../semmle/go/frameworks/StdlibTaintFlow/vendor/modules.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/go.mod b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/go.mod index 1481ec9caf6..4168c0a398b 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/go.mod +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/go.mod @@ -1,6 +1,6 @@ module example.com/m -go 1.20 +go 1.23 require ( golang.org/x/net v0.0.0-20201010224723-4f7140c49acb diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/vendor/modules.txt b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/vendor/modules.txt index fe5007e8ae1..b11be0ff1d2 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/vendor/modules.txt +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/vendor/modules.txt @@ -1,3 +1,3 @@ # golang.org/x/net v0.0.0-20201010224723-4f7140c49acb -## explicit -golang.org/x/net +## explicit; go 1.11 +golang.org/x/net/context From 8c111382adf1e52d11eea78967b182378f9aca7c Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 26 Nov 2024 13:00:59 +0100 Subject: [PATCH 256/470] Address review comments --- .../rust/dataflow/internal/DataFlowImpl.qll | 83 ++++++++++--------- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 808b410c8d0..79b18b9cd0d 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -386,7 +386,7 @@ private predicate resolveExtendedCanonicalPath(Resolvable r, CrateOriginOption c } /** - * A reference contained in an object. For example a field in a struct. + * A path to a value contained in an object. For example a field name of a struct. */ abstract class Content extends TContent { /** Gets a textual representation of this content. */ @@ -416,34 +416,34 @@ private class VariantCanonicalPath extends MkVariantCanonicalPath { abstract class VariantContent extends Content { } /** A tuple variant. */ -private class TupleVariantContent extends VariantContent, TTupleVariantContent { +private class VariantPositionContent extends VariantContent, TVariantPositionContent { private VariantCanonicalPath v; private int pos_; - TupleVariantContent() { this = TTupleVariantContent(v, pos_) } + VariantPositionContent() { this = TVariantPositionContent(v, pos_) } VariantCanonicalPath getVariantCanonicalPath(int pos) { result = v and pos = pos_ } final override string toString() { // only print indices when the arity is > 1 - if exists(TTupleVariantContent(v, 1)) + if exists(TVariantPositionContent(v, 1)) then result = v.toString() + "(" + pos_ + ")" else result = v.toString() } } /** A record variant. */ -private class RecordVariantContent extends VariantContent, TRecordVariantContent { +private class VariantFieldContent extends VariantContent, TVariantFieldContent { private VariantCanonicalPath v; private string field_; - RecordVariantContent() { this = TRecordVariantContent(v, field_) } + VariantFieldContent() { this = TVariantFieldContent(v, field_) } VariantCanonicalPath getVariantCanonicalPath(string field) { result = v and field = field_ } final override string toString() { // only print field when the arity is > 1 - if strictcount(string f | exists(TRecordVariantContent(v, f))) > 1 + if strictcount(string f | exists(TVariantFieldContent(v, f))) > 1 then result = v.toString() + "{" + field_ + "}" else result = v.toString() } @@ -461,7 +461,7 @@ abstract class ContentSet extends TContentSet { abstract Content getAReadContent(); } -private class SingletonContentSet extends ContentSet, TSingletonContentSet { +final private class SingletonContentSet extends ContentSet, TSingletonContentSet { private Content c; SingletonContentSet() { this = TSingletonContentSet(c) } @@ -539,21 +539,18 @@ module RustDataFlow implements InputSig { final class ReturnKind = ReturnKindAlias; pragma[nomagic] - private predicate callResolveExtendedCanonicalPath( - CallExprBase call, CrateOriginOption crate, string path - ) { - exists(Resolvable r | resolveExtendedCanonicalPath(r, crate, path) | - r = call.(MethodCallExpr) - or - r = call.(CallExpr).getExpr().(PathExpr).getPath() - ) + private Resolvable getCallResolvable(CallExprBase call) { + result = call.(MethodCallExpr) + or + result = call.(CallExpr).getExpr().(PathExpr).getPath() } /** Gets a viable implementation of the target of the given `Call`. */ DataFlowCallable viableCallable(DataFlowCall call) { - exists(string path, CrateOriginOption crate | + exists(Resolvable r, string path, CrateOriginOption crate | hasExtendedCanonicalPath(result.asCfgScope(), crate, path) and - callResolveExtendedCanonicalPath(call.asCallBaseExprCfgNode().getExpr(), crate, path) + r = getCallResolvable(call.asCallBaseExprCfgNode().getExpr()) and + resolveExtendedCanonicalPath(r, crate, path) ) } @@ -581,7 +578,7 @@ module RustDataFlow implements InputSig { predicate forceHighPrecision(Content c) { none() } - final class ContentApprox = Content; // todo + final class ContentApprox = Content; // TODO: Implement if needed ContentApprox getContentApprox(Content c) { result = c } @@ -621,6 +618,10 @@ module RustDataFlow implements InputSig { // TODO: Remove once library types are extracted not p.hasQualifier() and v = MkVariantCanonicalPath(_, "crate::std::option::Option", p.getPart().getNameRef().getText()) + or + // TODO: Remove once library types are extracted + not p.hasQualifier() and + v = MkVariantCanonicalPath(_, "crate::std::result::Result", p.getPart().getNameRef().getText()) } /** Holds if `p` destructs an enum variant `v`. */ @@ -642,22 +643,19 @@ module RustDataFlow implements InputSig { */ predicate readStep(Node node1, ContentSet cs, Node node2) { exists(Content c | c = cs.(SingletonContentSet).getContent() | - node1.asPat() = - any(TupleStructPatCfgNode pat, int pos | - tupleVariantDestruction(pat.getPat(), c.(TupleVariantContent).getVariantCanonicalPath(pos)) and - node2.asPat() = pat.getField(pos) - | - pat - ) + exists(TupleStructPatCfgNode pat, int pos | + pat = node1.asPat() and + tupleVariantDestruction(pat.getPat(), + c.(VariantPositionContent).getVariantCanonicalPath(pos)) and + node2.asPat() = pat.getField(pos) + ) or - node1.asPat() = - any(RecordPatCfgNode pat, string field | - recordVariantDestruction(pat.getPat(), - c.(RecordVariantContent).getVariantCanonicalPath(field)) and - node2.asPat() = pat.getFieldPat(field) - | - pat - ) + exists(RecordPatCfgNode pat, string field | + pat = node1.asPat() and + recordVariantDestruction(pat.getPat(), + c.(VariantFieldContent).getVariantCanonicalPath(field)) and + node2.asPat() = pat.getFieldPat(field) + ) ) } @@ -683,7 +681,7 @@ module RustDataFlow implements InputSig { node2.asExpr() = any(CallExprCfgNode call, int pos | tupleVariantConstruction(call.getCallExpr(), - c.(TupleVariantContent).getVariantCanonicalPath(pos)) and + c.(VariantPositionContent).getVariantCanonicalPath(pos)) and node1.asExpr() = call.getArgument(pos) | call @@ -692,7 +690,7 @@ module RustDataFlow implements InputSig { node2.asExpr() = any(RecordExprCfgNode re, string field | recordVariantConstruction(re.getRecordExpr(), - c.(RecordVariantContent).getVariantCanonicalPath(field)) and + c.(VariantFieldContent).getVariantCanonicalPath(field)) and node1.asExpr() = re.getFieldExpr(field) | re @@ -806,18 +804,27 @@ private module Cached { crate.isNone() and path = "crate::std::option::Option" and name = "Some" + or + // TODO: Remove once library types are extracted + crate.isNone() and + path = "crate::std::result::Result" and + name = ["Ok", "Err"] } cached newtype TContent = - TTupleVariantContent(VariantCanonicalPath v, int pos) { + TVariantPositionContent(VariantCanonicalPath v, int pos) { pos in [0 .. v.getVariant().getFieldList().(TupleFieldList).getNumberOfFields() - 1] or // TODO: Remove once library types are extracted v = MkVariantCanonicalPath(_, "crate::std::option::Option", "Some") and pos = 0 + or + // TODO: Remove once library types are extracted + v = MkVariantCanonicalPath(_, "crate::std::result::Result", ["Ok", "Err"]) and + pos = 0 } or - TRecordVariantContent(VariantCanonicalPath v, string field) { + TVariantFieldContent(VariantCanonicalPath v, string field) { field = v.getVariant().getFieldList().(RecordFieldList).getAField().getName().getText() } From 196634ecdba635e222a3ec0866fcedc0059da616 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 26 Nov 2024 12:01:09 +0000 Subject: [PATCH 257/470] Model `slices` package Skipping functions that involve iterators for now. --- go/ql/lib/ext/slices.model.yml | 31 +++ .../go/frameworks/StdlibTaintFlow/Slices.go | 193 ++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 go/ql/lib/ext/slices.model.yml create mode 100644 go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Slices.go diff --git a/go/ql/lib/ext/slices.model.yml b/go/ql/lib/ext/slices.model.yml new file mode 100644 index 00000000000..0c88a5bb62e --- /dev/null +++ b/go/ql/lib/ext/slices.model.yml @@ -0,0 +1,31 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + # All should be modeled when we have a way to model iterators + # AppendSec should be modeled when we have a way to model iterators + # Backward should be modeled when we have a way to model iterators + # Chunk should be modeled when we have a way to model iterators + - ["slices", "", False, "Clip", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["slices", "", False, "Clone", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + # Collect should be modeled when we have a way to model iterators + - ["slices", "", False, "Compact", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["slices", "", False, "CompactFunc", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["slices", "", False, "Concat", "", "", "Argument[0].ArrayElement.ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["slices", "", False, "Delete", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["slices", "", False, "DeleteFunc", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["slices", "", False, "Grow", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["slices", "", False, "Insert", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["slices", "", False, "Insert", "", "", "Argument[2].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["slices", "", False, "Max", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["slices", "", False, "MaxFunc", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["slices", "", False, "Min", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["slices", "", False, "MinFunc", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["slices", "", False, "Repeat", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["slices", "", False, "Replace", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["slices", "", False, "Replace", "", "", "Argument[3].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + # Sorted should be modeled when we have a way to model iterators + # SortedFunc should be modeled when we have a way to model iterators + # SortedStableFunc should be modeled when we have a way to model iterators + # Vales should be modeled when we have a way to model iterators diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Slices.go b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Slices.go new file mode 100644 index 00000000000..6ecc98c0a2d --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Slices.go @@ -0,0 +1,193 @@ +package main + +import ( + "cmp" + "slices" + "strings" +) + +func TaintStepTest_SlicesClip(fromStringSlice []string) []string { + toStringSlice := slices.Clip(fromStringSlice) + return toStringSlice +} + +func TaintStepTest_SlicesClone(fromStringSlice []string) []string { + toStringSlice := slices.Clone(fromStringSlice) + return toStringSlice +} + +func TaintStepTest_SlicesCompact(fromStringSlice []string) []string { + toStringSlice := slices.Compact(fromStringSlice) + return toStringSlice +} + +func TaintStepTest_SlicesCompactFunc(fromStringSlice []string) []string { + toStringSlice := slices.CompactFunc(fromStringSlice, strings.EqualFold) + return toStringSlice +} + +func TaintStepTest_SlicesConcat0(fromStringSlice []string) []string { + toStringSlice := slices.Concat(fromStringSlice, []string{"a", "b", "c"}) + return toStringSlice +} + +func TaintStepTest_SlicesConcat1(fromStringSlice []string) []string { + toStringSlice := slices.Concat([]string{"a", "b", "c"}, fromStringSlice) + return toStringSlice +} + +func TaintStepTest_SlicesDelete(fromStringSlice []string) []string { + toStringSlice := slices.Delete(fromStringSlice, 0, 1) + return toStringSlice +} + +func TaintStepTest_SlicesDeleteFunc(fromStringSlice []string) []string { + deleteEmptyString := func(str string) bool { + return str == "" + } + toStringSlice := slices.DeleteFunc(fromStringSlice, deleteEmptyString) + return toStringSlice +} + +func TaintStepTest_SlicesGrow(fromStringSlice []string) []string { + toStringSlice := slices.Grow(fromStringSlice, 1) + return toStringSlice +} + +func TaintStepTest_SlicesInsert0(fromStringSlice []string) []string { + toStringSlice := slices.Insert(fromStringSlice, 1, "a", "b") + return toStringSlice +} + +func TaintStepTest_SlicesInsert2(fromString string) []string { + toStringSlice := slices.Insert([]string{}, 0, fromString, "b") + return toStringSlice +} + +func TaintStepTest_SlicesMax(fromStringSlice []string) string { + toString := slices.Max(fromStringSlice) + return toString +} + +func TaintStepTest_SlicesMaxFunc(fromStringSlice []string) string { + toString := slices.MaxFunc(fromStringSlice, cmp.Compare) + return toString +} + +func TaintStepTest_SlicesMin(fromStringSlice []string) string { + toString := slices.Min(fromStringSlice) + return toString +} + +func TaintStepTest_SlicesMinFunc(fromStringSlice []string) string { + toString := slices.MinFunc(fromStringSlice, cmp.Compare) + return toString +} + +func TaintStepTest_SlicesRepeat(fromStringSlice []string) []string { + toStringSlice := slices.Repeat(fromStringSlice, 2) + return toStringSlice +} + +func TaintStepTest_SlicesReplace0(fromStringSlice []string) []string { + toStringSlice := slices.Replace(fromStringSlice, 1, 2, "a") + return toStringSlice +} + +func TaintStepTest_SlicesReplace3(fromString string) []string { + toStringSlice := slices.Replace([]string{}, 1, 3, fromString, "b") + return toStringSlice +} + +func RunAllTaints_Slices() { + { + source := []string{newSource(0).(string)} + out := TaintStepTest_SlicesClip(source) + sink(0, out[0]) + } + { + source := []string{newSource(1).(string)} + out := TaintStepTest_SlicesClone(source) + sink(1, out[0]) + } + { + source := []string{newSource(2).(string)} + out := TaintStepTest_SlicesCompact(source) + sink(2, out[0]) + } + { + source := []string{newSource(3).(string)} + out := TaintStepTest_SlicesCompactFunc(source) + sink(3, out[0]) + } + { + source := []string{newSource(4).(string)} + out := TaintStepTest_SlicesConcat0(source) + sink(4, out[0]) + } + { + source := []string{newSource(5).(string)} + out := TaintStepTest_SlicesConcat1(source) + sink(5, out[0]) + } + { + source := []string{newSource(6).(string)} + out := TaintStepTest_SlicesDelete(source) + sink(6, out[0]) + } + { + source := []string{newSource(7).(string)} + out := TaintStepTest_SlicesDeleteFunc(source) + sink(7, out[0]) + } + { + source := []string{newSource(8).(string)} + out := TaintStepTest_SlicesGrow(source) + sink(8, out[0]) + } + { + source := []string{newSource(9).(string)} + out := TaintStepTest_SlicesInsert0(source) + sink(9, out[0]) + } + { + source := newSource(10).(string) + out := TaintStepTest_SlicesInsert2(source) + sink(10, out[0]) + } + { + source := []string{newSource(11).(string)} + out := TaintStepTest_SlicesMax(source) + sink(11, out) + } + { + source := []string{newSource(12).(string)} + out := TaintStepTest_SlicesMaxFunc(source) + sink(12, out) + } + { + source := []string{newSource(13).(string)} + out := TaintStepTest_SlicesMin(source) + sink(13, out) + } + { + source := []string{newSource(14).(string)} + out := TaintStepTest_SlicesMinFunc(source) + sink(14, out) + } + { + source := []string{newSource(15).(string)} + out := TaintStepTest_SlicesRepeat(source) + sink(15, out[0]) + } + { + source := []string{newSource(16).(string)} + out := TaintStepTest_SlicesReplace0(source) + sink(16, out[0]) + } + { + source := newSource(17).(string) + out := TaintStepTest_SlicesReplace3(source) + sink(17, out[0]) + } +} From bcc89ecb7c545562fef3f1fd4812578554a12ab8 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 26 Nov 2024 12:07:32 +0000 Subject: [PATCH 258/470] Add change note --- go/ql/src/change-notes/2024-11-26-model-slices-package.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 go/ql/src/change-notes/2024-11-26-model-slices-package.md diff --git a/go/ql/src/change-notes/2024-11-26-model-slices-package.md b/go/ql/src/change-notes/2024-11-26-model-slices-package.md new file mode 100644 index 00000000000..5a3141c8075 --- /dev/null +++ b/go/ql/src/change-notes/2024-11-26-model-slices-package.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added value flow models for functions in the `slices` package which do not involve the `iter` package. From 7f86f8cac71aa4adee3e364cfdb467d4335ab017 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 4 Nov 2024 11:21:42 +0100 Subject: [PATCH 259/470] Java: Prepare TypeFlow for separate instantiation of universal flow. --- .../semmle/code/java/dataflow/TypeFlow.qll | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll b/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll index c548c5db38b..f9046b1b65e 100644 --- a/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll @@ -13,24 +13,25 @@ private import semmle.code.java.dispatch.VirtualDispatch private import semmle.code.java.dataflow.internal.BaseSSA private import semmle.code.java.controlflow.Guards private import codeql.typeflow.TypeFlow +private import codeql.typeflow.UniversalFlow as UniversalFlow -private module Input implements TypeFlowInput { - private newtype TTypeFlowNode = +/** Gets `t` if it is a `RefType` or the boxed type if `t` is a primitive type. */ +private RefType boxIfNeeded(J::Type t) { + t.(PrimitiveType).getBoxedType() = result or + result = t +} + +module FlowStepsInput implements UniversalFlow::UniversalFlowInput { + private newtype TFlowNode = TField(Field f) { not f.getType() instanceof PrimitiveType } or TSsa(BaseSsaVariable ssa) { not ssa.getSourceVariable().getType() instanceof PrimitiveType } or TExpr(Expr e) or TMethod(Method m) { not m.getReturnType() instanceof PrimitiveType } - /** Gets `t` if it is a `RefType` or the boxed type if `t` is a primitive type. */ - private RefType boxIfNeeded(J::Type t) { - t.(PrimitiveType).getBoxedType() = result or - result = t - } - /** * A `Field`, `BaseSsaVariable`, `Expr`, or `Method`. */ - class TypeFlowNode extends TTypeFlowNode { + class FlowNode extends TFlowNode { string toString() { result = this.asField().toString() or result = this.asSsa().toString() or @@ -61,8 +62,6 @@ private module Input implements TypeFlowInput { } } - class Type = RefType; - private SrcCallable viableCallable_v1(Call c) { result = viableImpl_v1(c) or @@ -88,7 +87,7 @@ private module Input implements TypeFlowInput { * * For a given `n2`, this predicate must include all possible `n1` that can flow to `n2`. */ - predicate step(TypeFlowNode n1, TypeFlowNode n2) { + predicate step(FlowNode n1, FlowNode n2) { n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr() or exists(Field f, Expr e | @@ -134,7 +133,7 @@ private module Input implements TypeFlowInput { /** * Holds if `null` is the only value that flows to `n`. */ - predicate isNullValue(TypeFlowNode n) { + predicate isNullValue(FlowNode n) { n.asExpr() instanceof NullLiteral or exists(LocalVariableDeclExpr decl | @@ -144,11 +143,21 @@ private module Input implements TypeFlowInput { ) } - predicate isExcludedFromNullAnalysis(TypeFlowNode n) { + predicate isExcludedFromNullAnalysis(FlowNode n) { // Fields that are never assigned a non-null value are probably set by // reflection and are thus not always null. exists(n.asField()) } +} + +private module Input implements TypeFlowInput { + import FlowStepsInput + + class TypeFlowNode = FlowNode; + + predicate isExcludedFromNullAnalysis = FlowStepsInput::isExcludedFromNullAnalysis/1; + + class Type = RefType; predicate exactTypeBase(TypeFlowNode n, RefType t) { exists(ClassInstanceExpr e | From 6f32c4129d074a6087d7a6002293c1b8de3a213d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 4 Nov 2024 14:09:36 +0100 Subject: [PATCH 260/470] Java: Add a default taint sanitizer for contains-checks on lists of constants. --- .../semmle/code/java/dataflow/FlowSteps.qll | 6 + .../dataflow/internal/TaintTrackingUtil.qll | 1 + .../security/ListOfConstantsSanitizer.qll | 259 ++++++++++++++++++ 3 files changed, 266 insertions(+) create mode 100644 java/ql/lib/semmle/code/java/security/ListOfConstantsSanitizer.qll diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll index e7d34d166b1..c931817e00b 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll @@ -28,6 +28,7 @@ private module Frameworks { private import semmle.code.java.frameworks.ThreadLocal private import semmle.code.java.frameworks.ratpack.RatpackExec private import semmle.code.java.frameworks.stapler.Stapler + private import semmle.code.java.security.ListOfConstantsSanitizer } /** @@ -189,3 +190,8 @@ private class NumberTaintPreservingCallable extends TaintPreservingCallable { * map-key and map-value content, so that e.g. a tainted `Map` is assumed to have tainted keys and values. */ abstract class TaintInheritingContent extends DataFlow::Content { } + +/** + * A sanitizer in all global taint flow configurations but not in local taint. + */ +abstract class DefaultTaintSanitizer extends DataFlow::Node { } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index ad770b75a3e..1c7db851a2c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -161,6 +161,7 @@ private module Cached { */ cached predicate defaultTaintSanitizer(DataFlow::Node node) { + node instanceof DefaultTaintSanitizer or // Ignore paths through test code. node.getEnclosingCallable().getDeclaringType() instanceof NonSecurityTestClass or node.asExpr() instanceof ValidatedVariableAccess diff --git a/java/ql/lib/semmle/code/java/security/ListOfConstantsSanitizer.qll b/java/ql/lib/semmle/code/java/security/ListOfConstantsSanitizer.qll new file mode 100644 index 00000000000..0b6e3441802 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/ListOfConstantsSanitizer.qll @@ -0,0 +1,259 @@ +/** + * Provides a default taint sanitizer identifying comparisons against lists of + * compile-time constants. + */ + +import java +private import codeql.typeflow.UniversalFlow as UniversalFlow +private import semmle.code.java.Collections +private import semmle.code.java.controlflow.Guards +private import semmle.code.java.dataflow.internal.BaseSSA +private import semmle.code.java.dataflow.TaintTracking +private import semmle.code.java.dataflow.TypeFlow +private import semmle.code.java.dispatch.VirtualDispatch + +private class FlowNode = FlowStepsInput::FlowNode; + +/** + * Holds if `n2` is an unmodifiable collection constructed from input `n1`, + * which is either another collection or a number of elements. + */ +private predicate unmodifiableCollectionStep(FlowNode n1, FlowNode n2) { + exists(Call c, Callable tgt | + n2.asExpr() = c and + n1.asExpr() = c.getAnArgument() and + c.getCallee().getSourceDeclaration() = tgt + | + tgt.hasQualifiedName("java.util", "Collections", + ["unmodifiableCollection", "unmodifiableList", "unmodifiableSet"]) + or + tgt.hasQualifiedName("java.util", ["List", "Set"], ["copyOf", "of"]) + or + tgt.hasQualifiedName("com.google.common.collect", ["ImmutableList", "ImmutableSet"], + ["copyOf", "of"]) + ) +} + +/** + * Holds if `n2` is a collection or array constructed from input `n1`, which is + * either a collection, an array, or a number of elements. + */ +private predicate collectionStep(FlowNode n1, FlowNode n2) { + n2.asExpr().(ArrayInit).getAnInit() = n1.asExpr() + or + n2.asExpr().(ArrayCreationExpr).getInit() = n1.asExpr() + or + unmodifiableCollectionStep(n1, n2) + or + exists(Call c, Callable tgt | + n2.asExpr() = c and + n1.asExpr() = c.getAnArgument() and + c.getCallee().getSourceDeclaration() = tgt + | + tgt.hasQualifiedName("java.util", "Arrays", "asList") + or + tgt.isStatic() and + tgt.hasName(["copyOf", "of"]) and + tgt.getDeclaringType().getASourceSupertype+().hasQualifiedName("java.util", "Collection") + or + tgt instanceof Constructor and + tgt.getNumberOfParameters() = 1 and + tgt.getParameterType(0) instanceof CollectionType and + tgt.getDeclaringType() instanceof CollectionType + ) +} + +private module BaseUniversalFlow = UniversalFlow::Make; + +private module UnmodifiableProp implements BaseUniversalFlow::NullaryPropertySig { + predicate hasPropertyBase(FlowNode n) { unmodifiableCollectionStep(_, n) } +} + +/** Holds if the given node is an unmodifiable collection. */ +private predicate unmodifiableCollection = + BaseUniversalFlow::FlowNullary::hasProperty/1; + +/** + * Holds if `v` is a collection or array with an access, `coll`, at which the + * element `e` gets added. + */ +private predicate collectionAddition(Variable v, VarAccess coll, Expr e) { + exists(MethodCall mc, Method m, int arg | + mc.getMethod().getSourceDeclaration().overridesOrInstantiates*(m) and + mc.getQualifier() = coll and + v.getAnAccess() = coll and + mc.getArgument(arg) = e + | + m.hasQualifiedName("java.util", "Collection", ["add", "addAll"]) and + m.getNumberOfParameters() = 1 and + arg = 0 + or + m.hasQualifiedName("java.util", "List", ["add", "addAll"]) and + m.getNumberOfParameters() = 2 and + arg = 1 + ) + or + v.getAnAccess() = coll and + exists(Assignment assign | assign.getSource() = e | + coll = assign.getDest().(ArrayAccess).getArray() + ) +} + +/** + * Holds if `n` represents a definition of `v` and `v` is a collection or + * array that has additions occurring as side-effects after its definition. + */ +private predicate nodeWithAddition(FlowNode n, Variable v) { + collectionAddition(v, _, _) and + ( + n.asField() = v + or + n.asSsa().getSourceVariable().getVariable() = v and + (n.asSsa() instanceof BaseSsaUpdate or n.asSsa().(BaseSsaImplicitInit).isParameterDefinition(_)) + ) +} + +/** Holds if `c` does not add elements to the given collection. */ +private predicate safeCallable(Callable c) { + c instanceof CollectionQueryMethod + or + c instanceof CollectionMethod and + c.hasName(["clear", "remove", "removeAll", "stream", "iterator", "toArray"]) + or + c.hasQualifiedName("org.apache.commons.lang3", "StringUtils", "join") +} + +/** + * Holds if `n` might be mutated in ways that adds elements that are not + * tracked by the `collectionAddition` predicate. + */ +private predicate collectionWithPossibleMutation(FlowNode n) { + not unmodifiableCollection(n) and + ( + exists(Expr e | + n.asExpr() = e and + (e.getType() instanceof CollectionType or e.getType() instanceof Array) and + not collectionAddition(_, e, _) and + not collectionStep(n, _) + | + exists(ArrayAccess aa | e = aa.getArray()) + or + exists(Call c, Callable tgt | c.getAnArgument() = e or c.getQualifier() = e | + tgt = c.getCallee().getSourceDeclaration() and + not safeCallable(tgt) + ) + ) + or + exists(FlowNode mid | + FlowStepsInput::step(n, mid) and + collectionWithPossibleMutation(mid) + ) + ) +} + +/** + * A collection constructor that constructs an empty mutable collection. + */ +private class EmptyCollectionConstructor extends Constructor { + EmptyCollectionConstructor() { + this.getDeclaringType() instanceof CollectionType and + forall(Type t | t = this.getAParamType() | t instanceof PrimitiveType) + } +} + +private module CollectionFlowStepsInput implements UniversalFlow::UniversalFlowInput { + import FlowStepsInput + + /** + * Holds if `n2` is a collection/array/constant whose value(s) are + * determined completely from the range of `n1` nodes. + */ + predicate step(FlowNode n1, FlowNode n2) { + // Exclude the regular input constraints for those nodes that are covered + // completely by `collectionStep`. + FlowStepsInput::step(n1, n2) and + not collectionStep(_, n2) + or + // For collections with side-effects in the form of additions, we add the + // sources of those additions as additional input that need to originate + // from constants. + exists(Variable v | + nodeWithAddition(n2, v) and + collectionAddition(v, _, n1.asExpr()) + ) + or + // Include various forms of collection transformation. + collectionStep(n1, n2) + } + + predicate isExcludedFromNullAnalysis = FlowStepsInput::isExcludedFromNullAnalysis/1; +} + +private module CollectionUniversalFlow = UniversalFlow::Make; + +private module ConstantCollectionProp implements CollectionUniversalFlow::NullaryPropertySig { + /** + * Holds if `n` forms the base case for finding collections of constants. + * These are individual constants and empty collections. + */ + predicate hasPropertyBase(FlowNode n) { + n.asExpr().isCompileTimeConstant() or + n.asExpr().(ConstructorCall).getConstructor() instanceof EmptyCollectionConstructor + } + + predicate barrier = collectionWithPossibleMutation/1; +} + +/** + * Holds if the given node is either a constant or a collection/array of + * constants. + */ +private predicate constantCollection = + CollectionUniversalFlow::FlowNullary::hasProperty/1; + +/** Gets the result of a case normalization call of `arg`. */ +private MethodCall normalizeCaseCall(Expr arg) { + exists(Method changecase | result.getMethod() = changecase | + changecase.hasName(["toUpperCase", "toLowerCase"]) and + changecase.getDeclaringType() instanceof TypeString and + arg = result.getQualifier() + or + changecase + .hasQualifiedName(["org.apache.commons.lang", "org.apache.commons.lang3"], "StringUtils", + ["lowerCase", "upperCase"]) and + arg = result.getArgument(0) + or + changecase + .hasQualifiedName("org.apache.hadoop.util", "StringUtils", ["toLowerCase", "toUpperCase"]) and + arg = result.getArgument(0) + ) +} + +/** + * Holds if the guard `g` ensures that the expression `e` is one of a set of + * known constants upon evaluating to `branch`. + */ +private predicate constantCollectionContainsCheck(Guard g, Expr e, boolean branch) { + exists(MethodCall mc, Method m, FlowNode n, Expr checked | + g = mc and + mc.getMethod().getSourceDeclaration().overridesOrInstantiates*(m) and + m.hasQualifiedName("java.util", "Collection", "contains") and + n.asExpr() = mc.getQualifier() and + constantCollection(n) and + checked = mc.getAnArgument() and + branch = true + | + checked = e or + checked = normalizeCaseCall(e) + ) +} + +/** + * A comparison against a list of compile-time constants, sanitizing taint by + * restricting to a set of known values. + */ +private class ListOfConstantsComparisonSanitizerGuard extends TaintTracking::DefaultTaintSanitizer { + ListOfConstantsComparisonSanitizerGuard() { + this = DataFlow::BarrierGuard::getABarrierNode() + } +} From 5a4b7203220d8342d59c2aa94f6b411c85ef0e50 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 4 Nov 2024 14:11:35 +0100 Subject: [PATCH 261/470] Java: Add change note. --- .../change-notes/2024-11-04-list-of-constants-sanitizer.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2024-11-04-list-of-constants-sanitizer.md diff --git a/java/ql/lib/change-notes/2024-11-04-list-of-constants-sanitizer.md b/java/ql/lib/change-notes/2024-11-04-list-of-constants-sanitizer.md new file mode 100644 index 00000000000..dea1e7ff81e --- /dev/null +++ b/java/ql/lib/change-notes/2024-11-04-list-of-constants-sanitizer.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Calling `coll.contains(x)` is now a taint sanitizer (for any query) for the value `x`, where `coll` is a collection of constants. From 2b1caa8a350a8ee7f4e8332511808b8cdd749f4d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 4 Nov 2024 15:10:22 +0100 Subject: [PATCH 262/470] Java: Add test. --- .../test/library-tests/listofconstants/A.java | 35 +++++++++++++++++++ .../listofconstants/test.expected | 3 ++ .../library-tests/listofconstants/test.ql | 5 +++ 3 files changed, 43 insertions(+) create mode 100644 java/ql/test/library-tests/listofconstants/A.java create mode 100644 java/ql/test/library-tests/listofconstants/test.expected create mode 100644 java/ql/test/library-tests/listofconstants/test.ql diff --git a/java/ql/test/library-tests/listofconstants/A.java b/java/ql/test/library-tests/listofconstants/A.java new file mode 100644 index 00000000000..74129692d71 --- /dev/null +++ b/java/ql/test/library-tests/listofconstants/A.java @@ -0,0 +1,35 @@ +import java.util.*; + +public class A { + private static final Set SEPARATORS = + Collections.unmodifiableSet( + new HashSet<>(Arrays.asList("\t", "\n", ";"))); + + public static void sink(String s) { } + + private void checkSeparator(String separator) { + if (SEPARATORS.contains(separator)) { + sink(separator); + } + } + + public static final String URI1 = "yarn.io/gpu"; + public static final String URI2 = "yarn.io/fpga"; + + public static final Set SCHEMAS = Set.of(URI1, URI2, "s3a", "wasb"); + + private void checkSchema(String schema) { + if (SCHEMAS.contains(schema)) { + sink(schema); + } + } + + private void testAdd(String inp) { + Set s = new HashSet<>(); + s.add("AA"); + s.add("BB"); + if (s.contains(inp.toUpperCase())) { + sink(inp); + } + } +} diff --git a/java/ql/test/library-tests/listofconstants/test.expected b/java/ql/test/library-tests/listofconstants/test.expected new file mode 100644 index 00000000000..203d64cd46d --- /dev/null +++ b/java/ql/test/library-tests/listofconstants/test.expected @@ -0,0 +1,3 @@ +| A.java:12:12:12:20 | separator | +| A.java:23:12:23:17 | schema | +| A.java:32:12:32:14 | inp | diff --git a/java/ql/test/library-tests/listofconstants/test.ql b/java/ql/test/library-tests/listofconstants/test.ql new file mode 100644 index 00000000000..f56dfc0f11f --- /dev/null +++ b/java/ql/test/library-tests/listofconstants/test.ql @@ -0,0 +1,5 @@ +import java +import semmle.code.java.dataflow.FlowSteps + +from DefaultTaintSanitizer e +select e From 0d45f0efb26f1eee875c36afabb536507bc73541 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 6 Nov 2024 14:13:31 +0100 Subject: [PATCH 263/470] Java: Accept consistency check result. --- .../listofconstants/CONSISTENCY/typeParametersInScope.expected | 1 + 1 file changed, 1 insertion(+) create mode 100644 java/ql/test/library-tests/listofconstants/CONSISTENCY/typeParametersInScope.expected diff --git a/java/ql/test/library-tests/listofconstants/CONSISTENCY/typeParametersInScope.expected b/java/ql/test/library-tests/listofconstants/CONSISTENCY/typeParametersInScope.expected new file mode 100644 index 00000000000..1ea902154a6 --- /dev/null +++ b/java/ql/test/library-tests/listofconstants/CONSISTENCY/typeParametersInScope.expected @@ -0,0 +1 @@ +| Type A uses out-of-scope type variable E. Note the Java extractor is known to sometimes do this; the Kotlin extractor should not. | From 408a38d9fb866e61dff69695fba7409354a70f37 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 22 Nov 2024 10:35:43 +0100 Subject: [PATCH 264/470] Java: Address review comment, include addFirst,addLast. --- .../semmle/code/java/security/ListOfConstantsSanitizer.qll | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/ql/lib/semmle/code/java/security/ListOfConstantsSanitizer.qll b/java/ql/lib/semmle/code/java/security/ListOfConstantsSanitizer.qll index 0b6e3441802..cc57fbce648 100644 --- a/java/ql/lib/semmle/code/java/security/ListOfConstantsSanitizer.qll +++ b/java/ql/lib/semmle/code/java/security/ListOfConstantsSanitizer.qll @@ -91,6 +91,10 @@ private predicate collectionAddition(Variable v, VarAccess coll, Expr e) { m.hasQualifiedName("java.util", "List", ["add", "addAll"]) and m.getNumberOfParameters() = 2 and arg = 1 + or + m.hasQualifiedName("java.util", "SequencedCollection", ["addFirst", "addLast"]) and + m.getNumberOfParameters() = 1 and + arg = 0 ) or v.getAnAccess() = coll and From 2ff2d257847723c30d4634bf3ef60abdb1343d38 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 22 Nov 2024 10:36:36 +0100 Subject: [PATCH 265/470] Java: Cherry-pick test from https://github.com/github/codeql/pull/17051 --- .../AllowListSanitizerWithJavaUtilList.java | 306 ++++++++++++++++++ .../AllowListSanitizerWithJavaUtilSet.java | 305 +++++++++++++++++ .../semmle/examples/SqlConcatenated.expected | 52 +++ .../semmle/examples/SqlTainted.expected | 144 +++++++++ 4 files changed, 807 insertions(+) create mode 100644 java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilList.java create mode 100644 java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilSet.java diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilList.java b/java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilList.java new file mode 100644 index 00000000000..8f97f022a71 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilList.java @@ -0,0 +1,306 @@ +// Test cases for CWE-089 (SQL injection and Java Persistence query injection) +// http://cwe.mitre.org/data/definitions/89.html +package test.cwe089.semmle.tests; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; + +class AllowListSanitizerWithJavaUtilList { + public static Connection connection; + public static final List goodAllowList1 = List.of("allowed1", "allowed2", "allowed3"); + public static final List goodAllowList2 = Collections.unmodifiableList(Arrays.asList("allowed1")); + public static final List goodAllowList3; + public static final List goodAllowList4; + public static final List badAllowList1 = List.of("allowed1", "allowed2", getNonConstantString()); + public static final List badAllowList2 = Collections.unmodifiableList(Arrays.asList("allowed1", getNonConstantString())); + public static final List badAllowList3; + public static final List badAllowList4; + public static final List badAllowList5; + public static List badAllowList6 = List.of("allowed1", "allowed2", "allowed3"); + public final List badAllowList7 = List.of("allowed1", "allowed2", "allowed3"); + + static { + goodAllowList3 = List.of("allowed1", "allowed2", "allowed3"); + goodAllowList4 = Collections.unmodifiableList(Arrays.asList("allowed1", "allowed2")); + badAllowList3 = List.of(getNonConstantString(), "allowed2", "allowed3"); + badAllowList4 = Collections.unmodifiableList(Arrays.asList("allowed1", getNonConstantString())); + badAllowList5 = new ArrayList(); + badAllowList5.add("allowed1"); + badAllowList5.add("allowed2"); + badAllowList5.add("allowed3"); + } + + public static String getNonConstantString() { + return String.valueOf(System.currentTimeMillis()); + } + + public static void main(String[] args) throws IOException, SQLException { + badAllowList6 = List.of("allowed1", getNonConstantString(), "allowed3"); + testStaticFields(args); + testLocal(args); + var x = new AllowListSanitizerWithJavaUtilList(); + x.testNonStaticFields(args); + testMultipleSources(args); + testEscape(args); + } + + private static void testStaticFields(String[] args) throws IOException, SQLException { + String tainted = args[1]; + // GOOD: an allowlist is used with constant strings + if(goodAllowList1.contains(tainted.toLowerCase())){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // GOOD: an allowlist is used with constant strings + if(goodAllowList2.contains(tainted.toUpperCase())){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // GOOD: an allowlist is used with constant strings + if(goodAllowList3.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // GOOD: an allowlist is used with constant strings + if(goodAllowList4.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // BAD: an allowlist is used with constant strings + if(badAllowList1.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // BAD: an allowlist is used with constant strings + if(badAllowList2.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // BAD: an allowlist is used with constant strings + if(badAllowList3.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // BAD: an allowlist is used with constant strings + if(badAllowList4.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // BAD: an allowlist is used with constant strings + if(badAllowList5.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // BAD: the allowlist is in a non-final field + if(badAllowList6.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + + private void testNonStaticFields(String[] args) throws IOException, SQLException { + String tainted = args[0]; + // BAD: the allowlist is in a non-static field + if(badAllowList7.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + + private static void testLocal(String[] args) throws IOException, SQLException { + String tainted = args[1]; + // GOOD: an allowlist is used with constant strings + { + List allowlist = List.of("allowed1", "allowed2", "allowed3"); + if(allowlist.contains(tainted.toLowerCase())){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // BAD: an allowlist is used but one of the entries is not a compile-time constant + { + List allowlist = List.of("allowed1", "allowed2", args[2]); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // GOOD: an allowlist is used with constant strings + { + String[] allowedArray = {"allowed1", "allowed2", "allowed3"}; + List allowlist = List.of(allowedArray); + if(allowlist.contains(tainted.toUpperCase())){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // BAD: an allowlist is used but one of the entries is not a compile-time constant + { + String[] allowedArray = {"allowed1", "allowed2", args[2]}; + List allowlist = List.of(allowedArray); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // GOOD: an allowlist is used with constant strings + { + List allowlist = Collections.unmodifiableList(Arrays.asList("allowed1")); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // BAD: an allowlist is used but one of the entries is not a compile-time constant + { + List allowlist = Collections.unmodifiableList(Arrays.asList("allowed1", "allowed2", args[2])); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // GOOD: an allowlist is used with constant strings + { + String[] allowedArray = {"allowed1", "allowed2", "allowed3"}; + List allowlist = Collections.unmodifiableList(Arrays.asList(allowedArray)); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // BAD: an allowlist is used but one of the entries is not a compile-time constant + { + String[] allowedArray = {"allowed1", "allowed2", args[2]}; + List allowlist = Collections.unmodifiableList(Arrays.asList(allowedArray)); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // GOOD: an allowlist is used with constant string + { + List allowlist = new ArrayList(); + allowlist.add("allowed1"); + allowlist.add("allowed2"); + allowlist.add("allowed3"); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // BAD: an allowlist is used but one of the entries is not a compile-time constant + { + List allowlist = new ArrayList(); + allowlist.add("allowed1"); + allowlist.add(getNonConstantString()); + allowlist.add("allowed3"); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // BAD: an allowlist is used but it contains a non-compile-time constant element + { + List allowlist = new ArrayList(); + allowlist.add("allowed1"); + addNonConstantStringDirectly(allowlist); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + } + + private static void testMultipleSources(String[] args) throws IOException, SQLException { + String tainted = args[1]; + boolean b = args[2] == "True"; + { + // BAD: an allowlist is used which might contain constant strings + List allowlist = new ArrayList(); + allowlist.add("allowed1"); + if (b) { + allowlist.add(getNonConstantString()); + } + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + { + // BAD: an allowlist is used which might contain constant strings + List allowlist = b ? goodAllowList1 : badAllowList1; + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + { + // BAD: an allowlist is used which might contain constant strings + List allowlist = b ? goodAllowList1 : List.of("allowed1", "allowed2", args[2]);; + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + } + + private static void testEscape(String[] args) throws IOException, SQLException { + String tainted = args[1]; + boolean b = args[2] == "True"; + { + // BAD: an allowlist is used which contains constant strings + List allowlist = new ArrayList(); + addNonConstantStringViaLambda(e -> allowlist.add(e)); + if(allowlist.contains(tainted)){ // missing result + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + } + + private static void addNonConstantStringDirectly(List list) { + list.add(getNonConstantString()); + } + + private static void addNonConstantStringViaLambda(Consumer adder) { + adder.accept(getNonConstantString()); + } + +} diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilSet.java b/java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilSet.java new file mode 100644 index 00000000000..a9e1e0f99e5 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilSet.java @@ -0,0 +1,305 @@ +// Test cases for CWE-089 (SQL injection and Java Persistence query injection) +// http://cwe.mitre.org/data/definitions/89.html +package test.cwe089.semmle.tests; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.HashSet; +import java.util.List; +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; +import java.util.function.Consumer; + +class AllowListSanitizerWithJavaUtilSet { + public static Connection connection; + public static final Set goodAllowList1 = Set.of("allowed1", "allowed2", "allowed3"); + public static final Set goodAllowList2 = Collections.unmodifiableSet(new HashSet(Arrays.asList("allowed1","allowed2"))); + public static final Set goodAllowList3; + public static final Set goodAllowList4; + public static final Set badAllowList1 = Set.of("allowed1", "allowed2", getNonConstantString()); + public static final Set badAllowList2 = Collections.unmodifiableSet(new HashSet(Arrays.asList("allowed1", getNonConstantString()))); + public static final Set badAllowList3; + public static final Set badAllowList4; + public static final Set badAllowList5; + public static Set badAllowList6 = Set.of("allowed1", "allowed2", "allowed3"); + public final Set badAllowList7 = Set.of("allowed1", "allowed2", "allowed3"); + + static { + goodAllowList3 = Set.of("allowed1", "allowed2", "allowed3"); + goodAllowList4 = Collections.unmodifiableSet(new HashSet(Arrays.asList("allowed1", "allowed2"))); + badAllowList3 = Set.of(getNonConstantString(), "allowed2", "allowed3"); + badAllowList4 = Collections.unmodifiableSet(new HashSet(Arrays.asList("allowed1", getNonConstantString()))); + badAllowList5 = new HashSet(); + badAllowList5.add("allowed1"); + badAllowList5.add("allowed2"); + badAllowList5.add("allowed3"); + } + + public static String getNonConstantString() { + return String.valueOf(System.currentTimeMillis()); + } + + public static void main(String[] args) throws IOException, SQLException { + badAllowList6 = Set.of("allowed1", getNonConstantString(), "allowed3"); + testStaticFields(args); + testLocal(args); + var x = new AllowListSanitizerWithJavaUtilSet(); + x.testNonStaticFields(args); + testMultipleSources(args); + testEscape(args); + } + + private static void testStaticFields(String[] args) throws IOException, SQLException { + String tainted = args[1]; + // GOOD: an allowlist is used with constant strings + if(goodAllowList1.contains(tainted.toLowerCase())){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // GOOD: an allowlist is used with constant strings + if(goodAllowList2.contains(tainted.toUpperCase())){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // GOOD: an allowlist is used with constant strings + if(goodAllowList3.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // GOOD: an allowlist is used with constant strings + if(goodAllowList4.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // BAD: an allowlist is used with constant strings + if(badAllowList1.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // BAD: an allowlist is used with constant strings + if(badAllowList2.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // BAD: an allowlist is used with constant strings + if(badAllowList3.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // BAD: an allowlist is used with constant strings + if(badAllowList4.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // BAD: an allowlist is used with constant strings + if(badAllowList5.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + // BAD: the allowlist is in a non-final field + if(badAllowList6.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + + private void testNonStaticFields(String[] args) throws IOException, SQLException { + String tainted = args[1]; + // BAD: the allowlist is in a non-static field + if(badAllowList7.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + + private static void testLocal(String[] args) throws IOException, SQLException { + String tainted = args[1]; + // GOOD: an allowlist is used with constant strings + { + Set allowlist = Set.of("allowed1", "allowed2", "allowed3"); + if(allowlist.contains(tainted.toLowerCase())){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // BAD: an allowlist is used but one of the entries is not a compile-time constant + { + Set allowlist = Set.of("allowed1", "allowed2", args[2]); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // GOOD: an allowlist is used with constant strings + { + String[] allowedArray = {"allowed1", "allowed2", "allowed3"}; + Set allowlist = Set.of(allowedArray); + if(allowlist.contains(tainted.toUpperCase())){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // BAD: an allowlist is used but one of the entries is not a compile-time constant + { + String[] allowedArray = {"allowed1", "allowed2", args[2]}; + Set allowlist = Set.of(allowedArray); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // GOOD: an allowlist is used with constant strings + { + Set allowlist = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("allowed1"))); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // BAD: an allowlist is used but one of the entries is not a compile-time constant + { + Set allowlist = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("allowed1", "allowed2", args[2]))); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // GOOD: an allowlist is used with constant strings + { + String[] allowedArray = {"allowed1", "allowed2", "allowed3"}; + Set allowlist = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(allowedArray))); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // BAD: an allowlist is used but one of the entries is not a compile-time constant + { + String[] allowedArray = {"allowed1", "allowed2", args[2]}; + Set allowlist = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(allowedArray))); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // GOOD: an allowlist is used with constant string + { + Set allowlist = new HashSet(); + allowlist.add("allowed1"); + allowlist.add("allowed2"); + allowlist.add("allowed3"); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // BAD: an allowlist is used but one of the entries is not a compile-time constant + { + Set allowlist = new HashSet(); + allowlist.add("allowed1"); + allowlist.add(getNonConstantString()); + allowlist.add("allowed3"); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + // BAD: an allowlist is used but it contains a non-compile-time constant element + { + Set allowlist = new HashSet(); + allowlist.add("allowed1"); + addNonConstantStringDirectly(allowlist); + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + } + + private static void testMultipleSources(String[] args) throws IOException, SQLException { + String tainted = args[1]; + boolean b = args[2] == "True"; + { + // BAD: an allowlist is used which might contain constant strings + Set allowlist = new HashSet(); + allowlist.add("allowed1"); + if (b) { + allowlist.add(getNonConstantString()); + } + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + { + // BAD: an allowlist is used which might contain constant strings + Set allowlist = b ? goodAllowList1 : badAllowList1; + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + { + // BAD: an allowlist is used which might contain constant strings + Set allowlist = b ? goodAllowList1 : Set.of("allowed1", "allowed2", args[2]);; + if(allowlist.contains(tainted)){ + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + } + + private static void testEscape(String[] args) throws IOException, SQLException { + String tainted = args[1]; + boolean b = args[2] == "True"; + { + // BAD: an allowlist is used which contains constant strings + Set allowlist = new HashSet(); + addNonConstantStringViaLambda(e -> allowlist.add(e)); + if(allowlist.contains(tainted)){ // missing result + String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + tainted + "' ORDER BY PRICE"; + ResultSet results = connection.createStatement().executeQuery(query); + } + } + } + + private static void addNonConstantStringDirectly(Set set) { + set.add(getNonConstantString()); + } + + private static void addNonConstantStringViaLambda(Consumer adder) { + adder.accept(getNonConstantString()); + } + +} diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlConcatenated.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlConcatenated.expected index fc1d87f06b1..1e560f03c3b 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlConcatenated.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlConcatenated.expected @@ -1,3 +1,55 @@ +| AllowListSanitizerWithJavaUtilList.java:64:66:64:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:63:8:63:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:70:66:70:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:69:8:69:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:76:66:76:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:75:8:75:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:82:66:82:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:81:8:81:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:87:8:87:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:93:8:93:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:99:8:99:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:105:8:105:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:112:66:112:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:111:8:111:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:117:8:117:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:128:66:128:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:127:8:127:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:140:67:140:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:139:9:139:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:148:9:148:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:159:67:159:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:158:9:158:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:168:9:168:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:178:67:178:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:177:9:177:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:186:9:186:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:197:67:197:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:196:9:196:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:206:9:206:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:219:67:219:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:218:9:218:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:230:9:230:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:241:9:241:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:259:9:259:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:268:9:268:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:277:9:277:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:292:9:292:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:63:66:63:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:62:8:62:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:69:66:69:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:68:8:68:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:75:66:75:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:74:8:74:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:81:66:81:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:80:8:80:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:86:8:86:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:92:8:92:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:98:8:98:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:104:8:104:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:111:66:111:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:110:8:110:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:116:8:116:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:127:66:127:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:126:8:126:14 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:139:67:139:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:138:9:138:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:147:9:147:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:158:67:158:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:157:9:157:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:167:9:167:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:177:67:177:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:176:9:176:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:185:9:185:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:196:67:196:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:195:9:195:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:205:9:205:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:218:67:218:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:217:9:217:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:229:9:229:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:240:9:240:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:258:9:258:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:267:9:267:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:276:9:276:15 | tainted | this expression | +| AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:291:9:291:15 | tainted | this expression | | Test.java:36:47:36:52 | query1 | Query built by concatenation with $@, which may be untrusted. | Test.java:35:8:35:15 | category | this expression | | Test.java:42:57:42:62 | query2 | Query built by concatenation with $@, which may be untrusted. | Test.java:41:51:41:52 | id | this expression | | Test.java:50:62:50:67 | query3 | Query built by concatenation with $@, which may be untrusted. | Test.java:49:8:49:15 | category | this expression | diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTainted.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTainted.expected index d54bbdaec05..82c17206b14 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTainted.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTainted.expected @@ -1,4 +1,38 @@ #select +| AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:112:66:112:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:112:66:112:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:128:66:128:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:128:66:128:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:111:66:111:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:111:66:111:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:127:66:127:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:127:66:127:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | +| AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | | Mongo.java:17:45:17:67 | parse(...) | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:17:45:17:67 | parse(...) | This query depends on a $@. | Mongo.java:10:29:10:41 | args | user-provided value | | Mongo.java:21:49:21:52 | json | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:21:49:21:52 | json | This query depends on a $@. | Mongo.java:10:29:10:41 | args | user-provided value | | Test.java:36:47:36:52 | query1 | Test.java:227:26:227:38 | args : String[] | Test.java:36:47:36:52 | query1 | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value | @@ -10,6 +44,60 @@ | Test.java:209:47:209:68 | queryWithUserTableName | Test.java:227:26:227:38 | args : String[] | Test.java:209:47:209:68 | queryWithUserTableName | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value | | Test.java:221:81:221:111 | ... + ... | Test.java:227:26:227:38 | args : String[] | Test.java:221:81:221:111 | ... + ... | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value | edges +| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:50:20:50:23 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:51:13:51:16 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:53:25:53:28 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:54:23:54:26 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:55:14:55:17 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilList.java:50:20:50:23 | args : String[] | AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilList.java:51:13:51:16 | args : String[] | AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilList.java:53:25:53:28 | args : String[] | AllowListSanitizerWithJavaUtilList.java:122:35:122:47 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilList.java:54:23:54:26 | args : String[] | AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilList.java:55:14:55:17 | args : String[] | AllowListSanitizerWithJavaUtilList.java:283:33:283:45 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:112:66:112:70 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:122:35:122:47 | args : String[] | AllowListSanitizerWithJavaUtilList.java:128:66:128:70 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:283:33:283:45 | args : String[] | AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:49:20:49:23 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:50:13:50:16 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:52:25:52:28 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:53:23:53:26 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:54:14:54:17 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilSet.java:49:20:49:23 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilSet.java:50:13:50:16 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilSet.java:52:25:52:28 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:121:35:121:47 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilSet.java:53:23:53:26 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilSet.java:54:14:54:17 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:282:33:282:45 | args : String[] | provenance | | +| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:111:66:111:70 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:121:35:121:47 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:127:66:127:70 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:282:33:282:45 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | provenance | Sink:MaD:6 | | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:17:56:17:66 | stringQuery : String | provenance | | | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:21:49:21:52 | json | provenance | | | Mongo.java:17:56:17:66 | stringQuery : String | Mongo.java:17:45:17:67 | parse(...) | provenance | Config | @@ -40,6 +128,62 @@ models | 6 | Summary: java.lang; AbstractStringBuilder; true; append; ; ; Argument[0]; Argument[this]; taint; manual | | 7 | Summary: java.lang; CharSequence; true; toString; ; ; Argument[this]; ReturnValue; taint; manual | nodes +| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilList.java:50:20:50:23 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilList.java:51:13:51:16 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilList.java:53:25:53:28 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilList.java:54:23:54:26 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilList.java:55:14:55:17 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:112:66:112:70 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:122:35:122:47 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilList.java:128:66:128:70 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilList.java:283:33:283:45 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilSet.java:49:20:49:23 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilSet.java:50:13:50:16 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilSet.java:52:25:52:28 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilSet.java:53:23:53:26 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilSet.java:54:14:54:17 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:111:66:111:70 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:121:35:121:47 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilSet.java:127:66:127:70 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | semmle.label | query | +| AllowListSanitizerWithJavaUtilSet.java:282:33:282:45 | args : String[] | semmle.label | args : String[] | +| AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | semmle.label | query | | Mongo.java:10:29:10:41 | args : String[] | semmle.label | args : String[] | | Mongo.java:17:45:17:67 | parse(...) | semmle.label | parse(...) | | Mongo.java:17:56:17:66 | stringQuery : String | semmle.label | stringQuery : String | From 38eb3e49528f07d21c530513dfd5f084c4996081 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 22 Nov 2024 10:45:27 +0100 Subject: [PATCH 266/470] Java: Adjust expected output. --- .../AllowListSanitizerWithJavaUtilList.java | 20 +++++++++---------- .../AllowListSanitizerWithJavaUtilSet.java | 20 +++++++++---------- .../semmle/examples/SqlTainted.expected | 20 ------------------- 3 files changed, 20 insertions(+), 40 deletions(-) diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilList.java b/java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilList.java index 8f97f022a71..285f9bc49cb 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilList.java +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilList.java @@ -22,23 +22,23 @@ class AllowListSanitizerWithJavaUtilList { public static final List goodAllowList2 = Collections.unmodifiableList(Arrays.asList("allowed1")); public static final List goodAllowList3; public static final List goodAllowList4; + public static final List goodAllowList5; public static final List badAllowList1 = List.of("allowed1", "allowed2", getNonConstantString()); public static final List badAllowList2 = Collections.unmodifiableList(Arrays.asList("allowed1", getNonConstantString())); public static final List badAllowList3; public static final List badAllowList4; - public static final List badAllowList5; public static List badAllowList6 = List.of("allowed1", "allowed2", "allowed3"); - public final List badAllowList7 = List.of("allowed1", "allowed2", "allowed3"); + public final List goodAllowList7 = List.of("allowed1", "allowed2", "allowed3"); static { goodAllowList3 = List.of("allowed1", "allowed2", "allowed3"); goodAllowList4 = Collections.unmodifiableList(Arrays.asList("allowed1", "allowed2")); badAllowList3 = List.of(getNonConstantString(), "allowed2", "allowed3"); badAllowList4 = Collections.unmodifiableList(Arrays.asList("allowed1", getNonConstantString())); - badAllowList5 = new ArrayList(); - badAllowList5.add("allowed1"); - badAllowList5.add("allowed2"); - badAllowList5.add("allowed3"); + goodAllowList5 = new ArrayList(); + goodAllowList5.add("allowed1"); + goodAllowList5.add("allowed2"); + goodAllowList5.add("allowed3"); } public static String getNonConstantString() { @@ -105,8 +105,8 @@ class AllowListSanitizerWithJavaUtilList { + tainted + "' ORDER BY PRICE"; ResultSet results = connection.createStatement().executeQuery(query); } - // BAD: an allowlist is used with constant strings - if(badAllowList5.contains(tainted)){ + // GOOD: an allowlist is used with constant strings + if(goodAllowList5.contains(tainted)){ String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + tainted + "' ORDER BY PRICE"; ResultSet results = connection.createStatement().executeQuery(query); @@ -121,8 +121,8 @@ class AllowListSanitizerWithJavaUtilList { private void testNonStaticFields(String[] args) throws IOException, SQLException { String tainted = args[0]; - // BAD: the allowlist is in a non-static field - if(badAllowList7.contains(tainted)){ + // GOOD: the allowlist is in a non-static field + if(goodAllowList7.contains(tainted)){ String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + tainted + "' ORDER BY PRICE"; ResultSet results = connection.createStatement().executeQuery(query); diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilSet.java b/java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilSet.java index a9e1e0f99e5..e1a5f889c6f 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilSet.java +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/AllowListSanitizerWithJavaUtilSet.java @@ -21,23 +21,23 @@ class AllowListSanitizerWithJavaUtilSet { public static final Set goodAllowList2 = Collections.unmodifiableSet(new HashSet(Arrays.asList("allowed1","allowed2"))); public static final Set goodAllowList3; public static final Set goodAllowList4; + public static final Set goodAllowList5; public static final Set badAllowList1 = Set.of("allowed1", "allowed2", getNonConstantString()); public static final Set badAllowList2 = Collections.unmodifiableSet(new HashSet(Arrays.asList("allowed1", getNonConstantString()))); public static final Set badAllowList3; public static final Set badAllowList4; - public static final Set badAllowList5; public static Set badAllowList6 = Set.of("allowed1", "allowed2", "allowed3"); - public final Set badAllowList7 = Set.of("allowed1", "allowed2", "allowed3"); + public final Set goodAllowList7 = Set.of("allowed1", "allowed2", "allowed3"); static { goodAllowList3 = Set.of("allowed1", "allowed2", "allowed3"); goodAllowList4 = Collections.unmodifiableSet(new HashSet(Arrays.asList("allowed1", "allowed2"))); badAllowList3 = Set.of(getNonConstantString(), "allowed2", "allowed3"); badAllowList4 = Collections.unmodifiableSet(new HashSet(Arrays.asList("allowed1", getNonConstantString()))); - badAllowList5 = new HashSet(); - badAllowList5.add("allowed1"); - badAllowList5.add("allowed2"); - badAllowList5.add("allowed3"); + goodAllowList5 = new HashSet(); + goodAllowList5.add("allowed1"); + goodAllowList5.add("allowed2"); + goodAllowList5.add("allowed3"); } public static String getNonConstantString() { @@ -104,8 +104,8 @@ class AllowListSanitizerWithJavaUtilSet { + tainted + "' ORDER BY PRICE"; ResultSet results = connection.createStatement().executeQuery(query); } - // BAD: an allowlist is used with constant strings - if(badAllowList5.contains(tainted)){ + // GOOD: an allowlist is used with constant strings + if(goodAllowList5.contains(tainted)){ String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + tainted + "' ORDER BY PRICE"; ResultSet results = connection.createStatement().executeQuery(query); @@ -120,8 +120,8 @@ class AllowListSanitizerWithJavaUtilSet { private void testNonStaticFields(String[] args) throws IOException, SQLException { String tainted = args[1]; - // BAD: the allowlist is in a non-static field - if(badAllowList7.contains(tainted)){ + // GOOD: the allowlist is in a non-static field + if(goodAllowList7.contains(tainted)){ String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + tainted + "' ORDER BY PRICE"; ResultSet results = connection.createStatement().executeQuery(query); diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTainted.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTainted.expected index 82c17206b14..6d1e99e2afb 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTainted.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTainted.expected @@ -3,9 +3,7 @@ | AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | | AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | | AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | -| AllowListSanitizerWithJavaUtilList.java:112:66:112:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:112:66:112:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | | AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | -| AllowListSanitizerWithJavaUtilList.java:128:66:128:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:128:66:128:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | | AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | | AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | | AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value | @@ -20,9 +18,7 @@ | AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | | AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | | AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | -| AllowListSanitizerWithJavaUtilSet.java:111:66:111:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:111:66:111:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | | AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | -| AllowListSanitizerWithJavaUtilSet.java:127:66:127:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:127:66:127:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | | AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | | AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | | AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value | @@ -46,21 +42,17 @@ edges | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:50:20:50:23 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:51:13:51:16 | args : String[] | provenance | | -| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:53:25:53:28 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:54:23:54:26 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:55:14:55:17 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilList.java:50:20:50:23 | args : String[] | AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilList.java:51:13:51:16 | args : String[] | AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | provenance | | -| AllowListSanitizerWithJavaUtilList.java:53:25:53:28 | args : String[] | AllowListSanitizerWithJavaUtilList.java:122:35:122:47 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilList.java:54:23:54:26 | args : String[] | AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilList.java:55:14:55:17 | args : String[] | AllowListSanitizerWithJavaUtilList.java:283:33:283:45 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:112:66:112:70 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:122:35:122:47 | args : String[] | AllowListSanitizerWithJavaUtilList.java:128:66:128:70 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | provenance | Sink:MaD:6 | @@ -73,21 +65,17 @@ edges | AllowListSanitizerWithJavaUtilList.java:283:33:283:45 | args : String[] | AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:49:20:49:23 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:50:13:50:16 | args : String[] | provenance | | -| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:52:25:52:28 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:53:23:53:26 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:54:14:54:17 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilSet.java:49:20:49:23 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilSet.java:50:13:50:16 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | provenance | | -| AllowListSanitizerWithJavaUtilSet.java:52:25:52:28 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:121:35:121:47 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilSet.java:53:23:53:26 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilSet.java:54:14:54:17 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:282:33:282:45 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:111:66:111:70 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:121:35:121:47 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:127:66:127:70 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | provenance | Sink:MaD:6 | | AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | provenance | Sink:MaD:6 | @@ -131,7 +119,6 @@ nodes | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | semmle.label | args : String[] | | AllowListSanitizerWithJavaUtilList.java:50:20:50:23 | args : String[] | semmle.label | args : String[] | | AllowListSanitizerWithJavaUtilList.java:51:13:51:16 | args : String[] | semmle.label | args : String[] | -| AllowListSanitizerWithJavaUtilList.java:53:25:53:28 | args : String[] | semmle.label | args : String[] | | AllowListSanitizerWithJavaUtilList.java:54:23:54:26 | args : String[] | semmle.label | args : String[] | | AllowListSanitizerWithJavaUtilList.java:55:14:55:17 | args : String[] | semmle.label | args : String[] | | AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | semmle.label | args : String[] | @@ -139,10 +126,7 @@ nodes | AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | semmle.label | query | | AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | semmle.label | query | | AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | semmle.label | query | -| AllowListSanitizerWithJavaUtilList.java:112:66:112:70 | query | semmle.label | query | | AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | semmle.label | query | -| AllowListSanitizerWithJavaUtilList.java:122:35:122:47 | args : String[] | semmle.label | args : String[] | -| AllowListSanitizerWithJavaUtilList.java:128:66:128:70 | query | semmle.label | query | | AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | semmle.label | args : String[] | | AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | semmle.label | query | | AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | semmle.label | query | @@ -159,7 +143,6 @@ nodes | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | semmle.label | args : String[] | | AllowListSanitizerWithJavaUtilSet.java:49:20:49:23 | args : String[] | semmle.label | args : String[] | | AllowListSanitizerWithJavaUtilSet.java:50:13:50:16 | args : String[] | semmle.label | args : String[] | -| AllowListSanitizerWithJavaUtilSet.java:52:25:52:28 | args : String[] | semmle.label | args : String[] | | AllowListSanitizerWithJavaUtilSet.java:53:23:53:26 | args : String[] | semmle.label | args : String[] | | AllowListSanitizerWithJavaUtilSet.java:54:14:54:17 | args : String[] | semmle.label | args : String[] | | AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | semmle.label | args : String[] | @@ -167,10 +150,7 @@ nodes | AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | semmle.label | query | | AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | semmle.label | query | | AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | semmle.label | query | -| AllowListSanitizerWithJavaUtilSet.java:111:66:111:70 | query | semmle.label | query | | AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | semmle.label | query | -| AllowListSanitizerWithJavaUtilSet.java:121:35:121:47 | args : String[] | semmle.label | args : String[] | -| AllowListSanitizerWithJavaUtilSet.java:127:66:127:70 | query | semmle.label | query | | AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | semmle.label | args : String[] | | AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | semmle.label | query | | AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | semmle.label | query | From a6fc41ec4b8b703c9082cc94bfdb8c6f3a1243e6 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 22 Nov 2024 10:48:45 +0100 Subject: [PATCH 267/470] Java: Accept consistency failure. --- .../semmle/examples/CONSISTENCY/typeParametersInScope.expected | 1 + 1 file changed, 1 insertion(+) create mode 100644 java/ql/test/query-tests/security/CWE-089/semmle/examples/CONSISTENCY/typeParametersInScope.expected diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/CONSISTENCY/typeParametersInScope.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/CONSISTENCY/typeParametersInScope.expected new file mode 100644 index 00000000000..1f8028eff60 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/CONSISTENCY/typeParametersInScope.expected @@ -0,0 +1 @@ +| Type AllowListSanitizerWithJavaUtilSet uses out-of-scope type variable E. Note the Java extractor is known to sometimes do this; the Kotlin extractor should not. | From adbd4d35edcc1e953432f96e0e1a50556d6bb32c Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 26 Nov 2024 12:38:16 +0000 Subject: [PATCH 268/470] Add support for both query and library change notes --- .vscode/tasks.json | 53 +++++++++++++++++++++++++----- misc/scripts/create-change-note.py | 14 +++++--- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9737e18c692..5d9a735d379 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -40,14 +40,32 @@ "problemMatcher": [] }, { - "label": "Create change note", + "label": "Create query change note", "type": "process", "command": "python3", "args": [ "misc/scripts/create-change-note.py", "${input:language}", + "src", "${input:name}", - "${input:category}" + "${input:categoryQuery}" + ], + "presentation": { + "reveal": "never", + "close": true + }, + "problemMatcher": [] + }, + { + "label": "Create library change note", + "type": "process", + "command": "python3", + "args": [ + "misc/scripts/create-change-note.py", + "${input:language}", + "lib", + "${input:name}", + "${input:categoryLibrary}" ], "presentation": { "reveal": "never", @@ -70,25 +88,42 @@ "csharp", "python", "ruby", + "rust", "swift", ] }, { "type": "promptString", "id": "name", - "description": "Name" + "description": "Short name (kebab-case)" }, { "type": "pickString", - "id": "category", - "description": "Category", + "id": "categoryQuery", + "description": "Category (query change)", "options": [ - "minorAnalysis", - "newQuery", - "fix", - "majorAnalysis", "breaking", + "deprecated", + "newQuery", + "queryMetadata", + "majorAnalysis", + "minorAnalysis", + "fix", + ] + }, + { + "type": "pickString", + "id": "categoryLibrary", + "description": "Category (library change)", + "options": + [ + "breaking", + "deprecated", + "feature", + "majorAnalysis", + "minorAnalysis", + "fix", ] } ] diff --git a/misc/scripts/create-change-note.py b/misc/scripts/create-change-note.py index bf82b76a18a..a7a64e76f4c 100644 --- a/misc/scripts/create-change-note.py +++ b/misc/scripts/create-change-note.py @@ -4,6 +4,7 @@ # Expects to receive the following arguments: # - What language the change note is for +# - Whether it's a query or library change (the string `src` or `lib`) # - The name of the change note (in kebab-case) # - The category of the change. @@ -17,8 +18,9 @@ import os # Read the given arguments language = sys.argv[1] -change_note_name = sys.argv[2] -change_category = sys.argv[3] +subdir = sys.argv[2] +change_note_name = sys.argv[3] +change_category = sys.argv[4] # Find the root of the repository. The current script should be located in `misc/scripts`. root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) @@ -26,9 +28,11 @@ root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__) # Go to the repo root os.chdir(root) +output_dir = f"{language}/ql/{subdir}/change-notes" + # Abort if the output directory doesn't exist -if not os.path.exists(f"{language}/ql/lib/change-notes"): - print(f"Output directory {language}/ql/lib/change-notes does not exist") +if not os.path.exists(output_dir): + print(f"Output directory {output_dir} does not exist") sys.exit(1) # Get the current date @@ -36,7 +40,7 @@ import datetime current_date = datetime.datetime.now().strftime("%Y-%m-%d") # Create the change note file -change_note_file = f"{language}/ql/lib/change-notes/{current_date}-{change_note_name}.md" +change_note_file = f"{output_dir}/{current_date}-{change_note_name}.md" change_note = f""" --- From 5279857d060ade6146b984cf0738162cb2114229 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 26 Nov 2024 12:48:20 +0000 Subject: [PATCH 269/470] Fix comment --- misc/scripts/create-change-note.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/scripts/create-change-note.py b/misc/scripts/create-change-note.py index a7a64e76f4c..548fa4e87fb 100644 --- a/misc/scripts/create-change-note.py +++ b/misc/scripts/create-change-note.py @@ -8,7 +8,7 @@ # - The name of the change note (in kebab-case) # - The category of the change. -# The change note will be created in the `{language}/ql/lib/change-notes` directory. +# The change note will be created in the `{language}/ql/{subdir}/change-notes` directory, where `subdir` is either `src` or `lib`. # The format of the change note filename is `{current_date}-{change_note_name}.md` with the date in # the format `YYYY-MM-DD`. From e1f70a0dec525d020bd9a6ef0bc4aa51f94a0a16 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 26 Nov 2024 13:50:09 +0100 Subject: [PATCH 270/470] C++: Add missing `

      ` to qlhelp --- cpp/ql/src/Best Practices/GuardedFree.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Best Practices/GuardedFree.qhelp b/cpp/ql/src/Best Practices/GuardedFree.qhelp index ba78749bef0..15e78197cfd 100644 --- a/cpp/ql/src/Best Practices/GuardedFree.qhelp +++ b/cpp/ql/src/Best Practices/GuardedFree.qhelp @@ -14,7 +14,7 @@ -

      In this example the condition checking the value of foo can be deleted. +

      In this example the condition checking the value of foo can be deleted.

      From fc6c327ab7f9a561c9cdd73a3e03c800ac6ae8dd Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 26 Nov 2024 13:55:30 +0100 Subject: [PATCH 271/470] C++: Add change note --- cpp/ql/src/change-notes/2014-11-26-guarded-free.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/src/change-notes/2014-11-26-guarded-free.md diff --git a/cpp/ql/src/change-notes/2014-11-26-guarded-free.md b/cpp/ql/src/change-notes/2014-11-26-guarded-free.md new file mode 100644 index 00000000000..4280025a04f --- /dev/null +++ b/cpp/ql/src/change-notes/2014-11-26-guarded-free.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new high-precision quality query, `cpp/guarded-free`, which detects useless NULL pointer checks before calls to `free`. A variation of this query was originally contributed as an [experimental query by @mario-campos](https://github.com/github/codeql/pull/16331). From 6aa7c93af2977184c0b2e1d83ac3c3c74f0deb9f Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 26 Nov 2024 13:58:54 +0100 Subject: [PATCH 272/470] C++: More qlhelp fixes --- cpp/ql/src/Best Practices/GuardedFree.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Best Practices/GuardedFree.qhelp b/cpp/ql/src/Best Practices/GuardedFree.qhelp index 15e78197cfd..6327354aded 100644 --- a/cpp/ql/src/Best Practices/GuardedFree.qhelp +++ b/cpp/ql/src/Best Practices/GuardedFree.qhelp @@ -1,7 +1,7 @@ - +

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

      From f65f11b40410460e8ce09474df9382b442d689f3 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 26 Nov 2024 13:43:42 +0000 Subject: [PATCH 273/470] C++: Add a test for a somewhat embarrasing bug: MaD didn't check the function name in some cases. --- cpp/ql/test/library-tests/dataflow/taint-tests/format.cpp | 6 ++++++ .../library-tests/dataflow/taint-tests/localTaint.expected | 3 +++ cpp/ql/test/library-tests/dataflow/taint-tests/stl.h | 5 +++++ .../dataflow/taint-tests/test_mad-signatures.expected | 4 ++++ 4 files changed, 18 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/format.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/format.cpp index d123ed5cc15..4f4267eccd5 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/format.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/format.cpp @@ -164,4 +164,10 @@ void test_format() { auto s2 = std::format(string::source()); sink(s2); // $ ir MISSING: ast +} + +void test(std::format_string s) { + int x = source(); + int y = std::same_signature_as_format_but_different_name(s, x); + sink(y); // $ SPURIOUS: ir } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 7de6914e8aa..b5ddf84747a 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -451,6 +451,9 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | format.cpp:162:24:162:27 | {} | format.cpp:162:24:162:27 | call to basic_format_string | TAINT | | format.cpp:165:13:165:23 | call to format | format.cpp:166:8:166:9 | s2 | | | format.cpp:165:25:165:38 | call to source | format.cpp:165:25:165:40 | call to basic_format_string | TAINT | +| format.cpp:169:30:169:30 | s | format.cpp:171:60:171:60 | s | | +| format.cpp:170:11:170:16 | call to source | format.cpp:171:63:171:63 | x | | +| format.cpp:171:11:171:58 | call to same_signature_as_format_but_different_name | format.cpp:172:8:172:8 | y | | | map.cpp:21:28:21:28 | call to pair | map.cpp:23:2:23:2 | a | | | map.cpp:21:28:21:28 | call to pair | map.cpp:24:7:24:7 | a | | | map.cpp:21:28:21:28 | call to pair | map.cpp:25:7:25:7 | a | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h b/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h index 9647f41cb7c..01e5f3b929b 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h @@ -676,4 +676,9 @@ namespace std { using format_string = basic_format_string; // simplified from `char, std::type_identity_t...` template string format( format_string fmt, Args&&... args ); + + // This function has the same signature as `format`, but a different name. It should NOT be able to use + // the model for `format`. + template + int same_signature_as_format_but_different_name(format_string, Args &&...args); } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected index 0d27fdaf0fd..26031f42c0a 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected @@ -265,6 +265,8 @@ signatureMatches | stl.h:678:33:678:38 | format | (format_string,Args &&) | | format | 0 | | stl.h:678:33:678:38 | format | (format_string,Args &&) | | format | 1 | | stl.h:678:33:678:38 | format | (format_string,Args &&) | | format | 1 | +| stl.h:683:6:683:48 | same_signature_as_format_but_different_name | (format_string,Args &&) | | format | 0 | +| stl.h:683:6:683:48 | same_signature_as_format_but_different_name | (format_string,Args &&) | | format | 1 | getSignatureParameterName | (InputIt,InputIt) | deque | assign | 0 | func:0 | | (InputIt,InputIt) | deque | assign | 1 | func:0 | @@ -729,6 +731,8 @@ getParameterTypeName | stl.h:678:33:678:38 | format | 0 | format_string | | stl.h:678:33:678:38 | format | 1 | func:0 && | | stl.h:678:33:678:38 | format | 1 | func:0 && | +| stl.h:683:6:683:48 | same_signature_as_format_but_different_name | 0 | format_string | +| stl.h:683:6:683:48 | same_signature_as_format_but_different_name | 1 | func:0 && | | stringstream.cpp:18:6:18:9 | sink | 0 | const basic_ostream> & | | stringstream.cpp:21:6:21:9 | sink | 0 | const basic_istream> & | | stringstream.cpp:24:6:24:9 | sink | 0 | const basic_iostream> & | From f7cf5af7201a28bcc84f7df5467fbe1a5a10801a Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 26 Nov 2024 13:56:22 +0000 Subject: [PATCH 274/470] C++: Actually check the function name. --- cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll index 07cb2670858..93e091ca5d3 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll @@ -794,6 +794,7 @@ private Element interpretElement0( ( // Non-member functions elementSpec(namespace, type, subtypes, name, signature, _) and + funcHasQualifiedName(result, namespace, name) and subtypes = false and type = "" and ( From 39b61598e9f1c1fd9cb2bb1e09bcc4c1b922933e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 26 Nov 2024 13:47:47 +0000 Subject: [PATCH 275/470] C++: Accept test changes. --- cpp/ql/test/library-tests/dataflow/taint-tests/format.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/format.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/format.cpp index 4f4267eccd5..b69a0b3d58f 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/format.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/format.cpp @@ -169,5 +169,5 @@ void test_format() { void test(std::format_string s) { int x = source(); int y = std::same_signature_as_format_but_different_name(s, x); - sink(y); // $ SPURIOUS: ir + sink(y); // clean } \ No newline at end of file From e42c7452ef4d5cdc5de39b2cce0bd30aa5dd1c4d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 26 Nov 2024 13:57:51 +0000 Subject: [PATCH 276/470] C++: Cleanup conjuncts. This doesn't change any behavior. --- .../lib/semmle/code/cpp/dataflow/ExternalFlow.qll | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll index 93e091ca5d3..49610b7c85b 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll @@ -793,7 +793,6 @@ private Element interpretElement0( ) { ( // Non-member functions - elementSpec(namespace, type, subtypes, name, signature, _) and funcHasQualifiedName(result, namespace, name) and subtypes = false and type = "" and @@ -801,21 +800,20 @@ private Element interpretElement0( elementSpecMatchesSignature(result, namespace, type, subtypes, name, signature) or signature = "" and - elementSpec(namespace, type, subtypes, name, "", _) and - funcHasQualifiedName(result, namespace, name) + elementSpec(namespace, type, subtypes, name, signature, _) ) or // Member functions exists(Class namedClass, Class classWithMethod | + hasClassAndName(classWithMethod, result, name) and + classHasQualifiedName(namedClass, namespace, type) + | ( - elementSpecMatchesSignature(result, namespace, type, subtypes, name, signature) and - hasClassAndName(classWithMethod, result, name) + elementSpecMatchesSignature(result, namespace, type, subtypes, name, signature) or signature = "" and - elementSpec(namespace, type, subtypes, name, "", _) and - hasClassAndName(classWithMethod, result, name) + elementSpec(namespace, type, subtypes, name, "", _) ) and - classHasQualifiedName(namedClass, namespace, type) and ( // member declared in the named type or a subtype of it subtypes = true and From d30f3e282245e8bb9639fe8facd0af7492662f56 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Tue, 26 Nov 2024 15:22:14 +0100 Subject: [PATCH 277/470] Rust: Renamed `expr` on `CallExpr` and `LetExpr` --- rust/ast-generator/src/main.rs | 4 ++- rust/extractor/src/generated/.generated.list | 2 +- rust/extractor/src/generated/top.rs | 12 +++---- rust/extractor/src/translate/generated.rs | 8 ++--- rust/ql/.generated.list | 18 +++++----- rust/ql/.gitattributes | 4 +-- .../internal/ControlFlowGraphImpl.qll | 4 +-- .../internal/generated/CfgNodes.qll | 36 +++++++++---------- .../rust/dataflow/internal/DataFlowImpl.qll | 2 +- .../rust/elements/internal/CallExprImpl.qll | 2 +- .../rust/elements/internal/LetExprImpl.qll | 2 +- .../elements/internal/generated/CallExpr.qll | 10 +++--- .../elements/internal/generated/LetExpr.qll | 11 +++--- .../internal/generated/ParentChild.qll | 16 ++++----- .../rust/elements/internal/generated/Raw.qll | 8 ++--- .../ql/lib/codeql/rust/frameworks/Reqwest.qll | 5 +-- .../lib/codeql/rust/frameworks/stdlib/Env.qll | 6 ++-- .../lib/codeql/rust/internal/CachedStages.qll | 2 +- rust/ql/lib/rust.dbscheme | 8 ++--- .../generated/CallExpr/CallExpr.expected | 8 ++--- .../generated/CallExpr/CallExpr.ql | 7 ++-- .../CallExpr/CallExpr_getFunction.expected | 4 +++ ...xpr_getExpr.ql => CallExpr_getFunction.ql} | 2 +- .../generated/LetExpr/LetExpr.expected | 2 +- .../generated/LetExpr/LetExpr.ql | 6 ++-- .../LetExpr/LetExpr_getScrutinee.expected | 1 + ...xpr_getExpr.ql => LetExpr_getScrutinee.ql} | 2 +- .../dataflow/sources/InlineFlow.ql | 6 ++-- rust/ql/test/utils/InlineFlowTest.qll | 2 +- rust/schema/ast.py | 4 +-- 30 files changed, 107 insertions(+), 97 deletions(-) create mode 100644 rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getFunction.expected rename rust/ql/test/extractor-tests/generated/CallExpr/{CallExpr_getExpr.ql => CallExpr_getFunction.ql} (84%) create mode 100644 rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getScrutinee.expected rename rust/ql/test/extractor-tests/generated/LetExpr/{LetExpr_getExpr.ql => LetExpr_getScrutinee.ql} (83%) diff --git a/rust/ast-generator/src/main.rs b/rust/ast-generator/src/main.rs index 6330eef8824..dbc9686a90f 100644 --- a/rust/ast-generator/src/main.rs +++ b/rust/ast-generator/src/main.rs @@ -28,8 +28,10 @@ fn class_name(type_name: &str) -> String { fn property_name(type_name: &str, field_name: &str) -> String { let name = match (type_name, field_name) { - ("Path", "segment") => "part", + ("CallExpr", "expr") => "function", + ("LetExpr", "expr") => "scrutinee", ("MatchExpr", "expr") => "scrutinee", + ("Path", "segment") => "part", (_, "then_branch") => "then", (_, "else_branch") => "else_", _ => field_name, diff --git a/rust/extractor/src/generated/.generated.list b/rust/extractor/src/generated/.generated.list index 3aeca1d0f9d..d12d55ec803 100644 --- a/rust/extractor/src/generated/.generated.list +++ b/rust/extractor/src/generated/.generated.list @@ -1,2 +1,2 @@ mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 -top.rs abab6a736e75f9eabbe31deef4de782fc05f0c053798a01d410fffc859515278 abab6a736e75f9eabbe31deef4de782fc05f0c053798a01d410fffc859515278 +top.rs c7e0a93f979fe21773c7dcea1aab0c16e919f171e417bfe36b41dfd411a280f8 c7e0a93f979fe21773c7dcea1aab0c16e919f171e417bfe36b41dfd411a280f8 diff --git a/rust/extractor/src/generated/top.rs b/rust/extractor/src/generated/top.rs index 5e09dbf71ed..22b7324e0b4 100644 --- a/rust/extractor/src/generated/top.rs +++ b/rust/extractor/src/generated/top.rs @@ -4963,7 +4963,7 @@ impl From> for trap::Label { pub struct LetExpr { pub id: trap::TrapId, pub attrs: Vec>, - pub expr: Option>, + pub scrutinee: Option>, pub pat: Option>, } @@ -4977,8 +4977,8 @@ impl trap::TrapEntry for LetExpr { for (i, v) in self.attrs.into_iter().enumerate() { out.add_tuple("let_expr_attrs", vec![id.into(), i.into(), v.into()]); } - if let Some(v) = self.expr { - out.add_tuple("let_expr_exprs", vec![id.into(), v.into()]); + if let Some(v) = self.scrutinee { + out.add_tuple("let_expr_scrutinees", vec![id.into(), v.into()]); } if let Some(v) = self.pat { out.add_tuple("let_expr_pats", vec![id.into(), v.into()]); @@ -8066,7 +8066,7 @@ pub struct CallExpr { pub id: trap::TrapId, pub arg_list: Option>, pub attrs: Vec>, - pub expr: Option>, + pub function: Option>, } impl trap::TrapEntry for CallExpr { @@ -8082,8 +8082,8 @@ impl trap::TrapEntry for CallExpr { for (i, v) in self.attrs.into_iter().enumerate() { out.add_tuple("call_expr_base_attrs", vec![id.into(), i.into(), v.into()]); } - if let Some(v) = self.expr { - out.add_tuple("call_expr_exprs", vec![id.into(), v.into()]); + if let Some(v) = self.function { + out.add_tuple("call_expr_functions", vec![id.into(), v.into()]); } } } diff --git a/rust/extractor/src/translate/generated.rs b/rust/extractor/src/translate/generated.rs index ee4e693ab73..8e4a7986fbf 100644 --- a/rust/extractor/src/translate/generated.rs +++ b/rust/extractor/src/translate/generated.rs @@ -397,12 +397,12 @@ impl Translator<'_> { pub(crate) fn emit_call_expr(&mut self, node: ast::CallExpr) -> Label { let arg_list = node.arg_list().map(|x| self.emit_arg_list(x)); let attrs = node.attrs().map(|x| self.emit_attr(x)).collect(); - let expr = node.expr().map(|x| self.emit_expr(x)); + let function = node.expr().map(|x| self.emit_expr(x)); let label = self.trap.emit(generated::CallExpr { id: TrapId::Star, arg_list, attrs, - expr, + function, }); self.emit_location(label, &node); emit_detached!(CallExpr, self, node, label); @@ -958,12 +958,12 @@ impl Translator<'_> { pub(crate) fn emit_let_expr(&mut self, node: ast::LetExpr) -> Label { let attrs = node.attrs().map(|x| self.emit_attr(x)).collect(); - let expr = node.expr().map(|x| self.emit_expr(x)); + let scrutinee = node.expr().map(|x| self.emit_expr(x)); let pat = node.pat().map(|x| self.emit_pat(x)); let label = self.trap.emit(generated::LetExpr { id: TrapId::Star, attrs, - expr, + scrutinee, pat, }); self.emit_location(label, &node); diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 7fc34f99492..90b5852aed3 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -1,4 +1,4 @@ -lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll 5e6ce2581b312d74ac8ffde44941b77f643025a7ff2c47799b3834596a513fa4 24dc5d28eb4754f968cf850294ac32057a2a97cf5156a3e90e0924c28e50e810 +lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll a8e083c7d8c4dea6459c5e128e2123f5cf8fd14c076f2256ebda508c13d553cd 16fcc0d34097b0b37a0041281515ca028d2702eec6d9c1d03c39a1158883bdef lib/codeql/rust/elements/Abi.qll 4c973d28b6d628f5959d1f1cc793704572fd0acaae9a97dfce82ff9d73f73476 250f68350180af080f904cd34cb2af481c5c688dc93edf7365fd0ae99855e893 lib/codeql/rust/elements/ArgList.qll 661f5100f5d3ef8351452d9058b663a2a5c720eea8cf11bedd628969741486a2 28e424aac01a90fb58cd6f9f83c7e4cf379eea39e636bc0ba07efc818be71c71 lib/codeql/rust/elements/ArrayExpr.qll a3e6e122632f4011644ec31b37f88b32fe3f2b7e388e7e878a6883309937049f 12ccb5873d95c433da5606fd371d182ef2f71b78d0c53c2d6dec10fa45852bdc @@ -428,7 +428,7 @@ lib/codeql/rust/elements/internal/generated/BinaryExpr.qll 64e9bd9c571edd6e5f3e7 lib/codeql/rust/elements/internal/generated/BlockExpr.qll 5a5ddbe34bc478a7bd9b0d07d3b6f017c2d1f20581d859251a963314e6514d1f 9804c30b8b279038b864c52557535f854bd012bacdfe8e5840f1f777c74e52df lib/codeql/rust/elements/internal/generated/BoxPat.qll ec946a3e671ab7417e04b0207967adad004df512c570c4f0780ca5816d12d75f b0e64860855c4e85914042b1a51034899ff7cd1b2c6857188de89310a2726ea3 lib/codeql/rust/elements/internal/generated/BreakExpr.qll 0f428a8b2f4209b134c2ffc3e1c93c30bc6b0e9c9172f140cefa88c1f77d8690 957b39f38ff6befe9061f55bc0b403c2f1c366dd0cf63b874bae6f8216576d76 -lib/codeql/rust/elements/internal/generated/CallExpr.qll 23ee64e3bf643cd5e6ff705181d2bb31e1aeaffecb5bdce73836172dbf15f12f 34b280139b1f8f70d78e1432392f03c971be392e8cb68d014eb325d0c101bddd +lib/codeql/rust/elements/internal/generated/CallExpr.qll f1b8dae487077cc9d1dccf8c3cd61fd17afe860585f17ce8b860be4859be7ca4 6034fc03778e38802cdf3a6e460364b74e92912622581b31e6179951022bbbd6 lib/codeql/rust/elements/internal/generated/CallExprBase.qll cce796e36847249f416629bacf3ea146313084de3374587412e66c10d2917b83 c219aa2174321c161a4a742ca0605521687ca9a5ca32db453a5c62db6f7784cc lib/codeql/rust/elements/internal/generated/Callable.qll b0502b5263b7bcd18e740f284f992c0e600e37d68556e3e0ba54a2ac42b94934 bda3e1eea11cacf5a9b932cd72efc2de6105103e8c575880fcd0cd89daadf068 lib/codeql/rust/elements/internal/generated/CastExpr.qll d6fbf02e9e202254666082a9116634d0eb933177866ac4c0a57b5e9c4bb4b383 477f67773492e3b82695461d56327c9db05a7d1a67e8d192406265f2ce369670 @@ -475,7 +475,7 @@ lib/codeql/rust/elements/internal/generated/ItemList.qll 73c8398a96d4caa47a2dc11 lib/codeql/rust/elements/internal/generated/Label.qll 6630fe16e9d2de6c759ff2684f5b9950bc8566a1525c835c131ebb26f3eea63e 671143775e811fd88ec90961837a6c0ee4db96e54f42efd80c5ae2571661f108 lib/codeql/rust/elements/internal/generated/LabelableExpr.qll 896fd165b438b60d7169e8f30fa2a94946490c4d284e1bbadfec4253b909ee6c 5c6b029ea0b22cf096df2b15fe6f9384ad3e65b50b253cae7f19a2e5ffb04a58 lib/codeql/rust/elements/internal/generated/LetElse.qll 7ca556118b5446bfc85abba8f0edd4970e029b30d414ea824a1b5f568310a76c a403540881336f9d0269cbcdb4b87107a17ab234a985247dc52a380f150a1641 -lib/codeql/rust/elements/internal/generated/LetExpr.qll 9af0f89b294c8a0a751317e7074fe370339563d36c1df4911d1ea082a4df77fd 68272593d1feb88990bfbd0b8c222776f085e49694894384fc6d96e9464ba734 +lib/codeql/rust/elements/internal/generated/LetExpr.qll 6f831be1d0f76258d5f74c847636e070a819dee5aa090be0c52a971f261eaff3 e85a48e7492862f738e184f5f1512c2d18d33a0cfb516e269334acf7448b508a lib/codeql/rust/elements/internal/generated/LetStmt.qll aa1852db86ec29f857a90677f0c6b4a07f0fd965fc193d4141be95ce15862fca 40f32a37c0cc161b099fe0b4c7d713da928781d3e2c3de90db991df1d9062647 lib/codeql/rust/elements/internal/generated/Lifetime.qll 90d01c76188ce0c053122c62b41e47f27c4c7717ca5a4999a76797360043da0d 7b9feb202da5a06cd17f7770bb66742fd9e7cff0d410fefc7ffaafe710ac16d6 lib/codeql/rust/elements/internal/generated/LifetimeArg.qll 7c1a44e3d480e75142b171eb51382c9492d393043833c0ab4a4036eba19043b8 7d8273b62794268dab6938ba1e3a3560a80a2c49cd9a9717345785dacd311059 @@ -512,7 +512,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60 lib/codeql/rust/elements/internal/generated/ParenPat.qll ce24b8f8ecbf0f204af200317405724063887257460c80cf250c39b2fdf37185 e7c87d37e1a0ca7ea03840017e1aa9ddb7f927f1f3b6396c0305b46aeee33db6 lib/codeql/rust/elements/internal/generated/ParenType.qll 9cc954d73f8330dcac7b475f97748b63af5c8766dee9d2f2872c0a7e4c903537 c07534c8a9c683c4a9b11d490095647e420de0a0bfc23273eaf6f31b00244273 -lib/codeql/rust/elements/internal/generated/ParentChild.qll 78723cac5f2999f91317f39cf53267043fd2a56e98e838f013eae01b6b39929e 26dd29e5fd868f89982269db6b25aa799be942abdbe41ff1a8ffd4dae4385bdc +lib/codeql/rust/elements/internal/generated/ParentChild.qll 081ee90ffd9906609d8ab9e08a3fdc1b10049838efe4c87d711d73f5a19e32e0 9a57d3cab79fa4bcfb85dd2c1e79def0e262b333b402a30dcbc114eb19718819 lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4 lib/codeql/rust/elements/internal/generated/Path.qll 4c1c8e840ed57880e574142b081b11d7a7428a009f10e3aa8f4645e211f6b2e0 989668cf0f1bdee7557e2f97c01e41d2a56848227fed41477833f5fc1e1d35f6 lib/codeql/rust/elements/internal/generated/PathExpr.qll 2096e3c1db22ee488a761690adabfc9cfdea501c99f7c5d96c0019cb113fc506 54245ce0449c4e263173213df01e079d5168a758503a5dbd61b25ad35a311140 @@ -525,7 +525,7 @@ lib/codeql/rust/elements/internal/generated/PtrType.qll 40099c5a4041314b66932dfd lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll efd93730de217cf50dcba5875595263a5eadf9f7e4e1272401342a094d158614 229b251b3d118932e31e78ac4dfb75f48b766f240f20d436062785606d44467b -lib/codeql/rust/elements/internal/generated/Raw.qll 9476dd5a6607f722de107b51713c1f529e95429416c7e0d102b78779cf826fe6 b3a4d58fb560c89344ac734cfda3df7f4dcb627c2db79dbe26babd6a67e69dce +lib/codeql/rust/elements/internal/generated/Raw.qll 30bb4ea5dea28ad11a4c76021ab95a4d564b93761771bdcdf46c46e1c0a1f443 8f1519f1e3a60a859239abf33033da23f6243d32291c230a4d1ecd300b697d89 lib/codeql/rust/elements/internal/generated/RecordExpr.qll eb6cb662e463f9260efae1a6ce874fa781172063b916ef1963f861e9942d308d 1a21cbccc8f3799ff13281e822818ebfb21d81591720a427cac3625512cb9d40 lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1 lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0 @@ -632,10 +632,10 @@ test/extractor-tests/generated/BreakExpr/BreakExpr.ql cdde2855d98f658187c60b9edc test/extractor-tests/generated/BreakExpr/BreakExpr_getAttr.ql c7690a9aab1923bf3c2fb06f0a1d441d480b3c91ee1df3a868bbbd96c4042053 c592dd077fb6e22b2d6ddcaec37da2c5a26ba92d84f5d1ae4c78a615b9013765 test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.ql 0358f4fe6a66da56177703cf0e991042729c5e34ae8b6dccbb827f95fe936c72 1cb2dd778c50e19fe04c5fdf3a08a502635ea8303e71ff38d03aa7dc53213986 test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.ql ad83cc0db3c0f959fef6bb7ce0938d241a877e8cf84d15fb63879be2fe47238c 240b2fe2156b763d3a82fc64159615872db65b65ffb9ba2f3fd5d1ebd6c60f34 -test/extractor-tests/generated/CallExpr/CallExpr.ql 69d88b3c799f6e81fe53fe04724ed6c1cbfbfcc21023dd62aed3a3f852c6a2aa 0caa94802919d30bf2749d8a1c58545163e2b1cad5490f19158b5e5063806443 +test/extractor-tests/generated/CallExpr/CallExpr.ql ffb0cf1cb359a6dcbdf792a570c281e2d300779dca2dbc0f324990652adb972f 978a9e6c82758f9e8b334a682a02d6b893a6bf1db3cd85e9535839a9696b09b4 test/extractor-tests/generated/CallExpr/CallExpr_getArgList.ql b022e7b6b6db9932e787e37b7760c6a09c91140a0368940374a2c919688e0488 c20849c96b53c96f6f717efff5e8b4c0e900c0ef5d715cfbaf7101c7056ad8f4 test/extractor-tests/generated/CallExpr/CallExpr_getAttr.ql 1ace458070875b9ff2c671c2ee18392ea7bf6e51b68ee98d412c8606e8eb8d33 4c35da8255d2975cef4adee15623662441bb8f2e1d73582e4c193d1bc11cc1b5 -test/extractor-tests/generated/CallExpr/CallExpr_getExpr.ql f680f04423ece282c459d5908e5aa0bc43ca072ff0e605587dfa94210da1d06d f8a709015b8317b8e2dcf3b3ee9370e2c3a655ef7e3c6034b1b90f4d75ebdda2 +test/extractor-tests/generated/CallExpr/CallExpr_getFunction.ql 060a6c8b5b85c839b14fe96f9e50291a7a0e5662a945f4f337070f782ec76715 e9a1e44433936146d87be939aa160848b9a7d7333c36da601fb7d1a66d71eb59 test/extractor-tests/generated/CastExpr/CastExpr.ql 2ffb22ebc6e47953a49162488b3605d36b9d89330b1e71187066e7bbc40a22ad 7621a39d49f573b9862b9a4e1021d53205670ee59b49e4d81128637926f76485 test/extractor-tests/generated/CastExpr/CastExpr_getAttr.ql 5d5d98172e495cdb8b5cea9d6588c4c245107b441464e3ffd6c27668af11ab4e 5820bf083aaa4c3275004a2cd9eeecc4b45ab96916cbc0655a1b42611c540715 test/extractor-tests/generated/CastExpr/CastExpr_getExpr.ql c37186b8f3e3dab8ae28c0da7263ff7272c40501beb16736ec0fb8990d285e22 59d50d7349234afcf84986b7570db9dcd342e16812f7c46199d4736cdfa5462d @@ -777,10 +777,10 @@ test/extractor-tests/generated/Label/Label.ql 6a92a27d615dd9c380cb9d889eecf827fc test/extractor-tests/generated/Label/Label_getLifetime.ql 3d6ddc3b44182e6432e938d5c1c95e0281575e320d517e431f6bad7748efb93e 56d07e485cb5e4263443eb5a0d62d7d4456bb0c2748331b371e519bfe14d3b81 test/extractor-tests/generated/LetElse/LetElse.ql bdf2b17d5efe6b9cb5bb4fcfe854a5fcd72443d39ae1e7981d2a0459c481e394 a14a611d0783ae38d631600c2bde7409f4e739ba2f284314b90ec9a21c23ab3a test/extractor-tests/generated/LetElse/LetElse_getBlockExpr.ql 32c21ad843884944738a735f01e272032a347d1860fa6d27d17652c549f941b0 2bfd8a5e3d42eb1c73eb679ada847dd29f2f0657a0ad8ef15da126e54fff5ef5 -test/extractor-tests/generated/LetExpr/LetExpr.ql a25072a00cfe1242dc846b38199c000ed7217d33fdd50d2763237fdfda7b9449 8c9367af79d9fbc98ed2fe62450929fa876512f1c999615b5c1ecff082fdc7bc +test/extractor-tests/generated/LetExpr/LetExpr.ql c76a0c4aaa73f4064207dacc8d2c649d3a5f8046c0f6e1aae985d2402a342e73 c5abe3845d4975d05c98ee6496732da384cdaca60ed49235776338e6dbe80b3d test/extractor-tests/generated/LetExpr/LetExpr_getAttr.ql 911b143afebaa0a487b13d533f089c5b0eaf336a44a4cab42147c284338484ba 625c91fb6d8c2e3a9f13e5679cc0cd29329c6c2b213d2e1191e23db2b65841dd -test/extractor-tests/generated/LetExpr/LetExpr_getExpr.ql ccabfaa15cfc8685e86cb950cb62b7f2fec278f28906ab34deb97b308f160cc4 e0574537d47a77f1be85090970f3e1263858174479002fd4de3f85b777ee4336 test/extractor-tests/generated/LetExpr/LetExpr_getPat.ql bc0363f77bc2ba583619ab7d309293ace0ed6a851bfb9b886f75729f96eb40a8 bc0cd9233b7904d8cc7f9021377120f5f4bcc5c7aa28b1b55f17bc738c434d78 +test/extractor-tests/generated/LetExpr/LetExpr_getScrutinee.ql ee33d3bbaf0ee7cdf9bd7b800e9684b5ac7ce8cf1939378cd460cb0c5ea11742 5d69e727b3e9d1ab4ce9eef702a7b1911515469625056bce87fac1d27ba863e6 test/extractor-tests/generated/LetStmt/LetStmt.ql 02db64303bfe87a11a85663e4c79bdabd9ca13693f146c7923b47c4c92850fcc 9ec1326b8bc58b270b178a4c02621b1650d107de7c02a9408d97c59f0d8a6178 test/extractor-tests/generated/LetStmt/LetStmt_getAttr.ql 68f69c4c054514140c0f0833a170e9f3facf950bd7af663ac9019f6c88ba0ea7 ca54d25cc052289458c7e34e40f0304bca2c412cecfb407f31279262bd74c15a test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.ql 6a5f0eed3ce3e8cbc57be6ec2b4eed732f00e084108d21a61d9ab28b65e494ca a48b426b97a6c347ad04fe2e592cd25b5c66b2a6a299cbf8c0da03e14304fd70 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 69c1ecbc2c6..c5bfc6f9c52 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -637,7 +637,7 @@ /test/extractor-tests/generated/CallExpr/CallExpr.ql linguist-generated /test/extractor-tests/generated/CallExpr/CallExpr_getArgList.ql linguist-generated /test/extractor-tests/generated/CallExpr/CallExpr_getAttr.ql linguist-generated -/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.ql linguist-generated +/test/extractor-tests/generated/CallExpr/CallExpr_getFunction.ql linguist-generated /test/extractor-tests/generated/CastExpr/CastExpr.ql linguist-generated /test/extractor-tests/generated/CastExpr/CastExpr_getAttr.ql linguist-generated /test/extractor-tests/generated/CastExpr/CastExpr_getExpr.ql linguist-generated @@ -781,8 +781,8 @@ /test/extractor-tests/generated/LetElse/LetElse_getBlockExpr.ql linguist-generated /test/extractor-tests/generated/LetExpr/LetExpr.ql linguist-generated /test/extractor-tests/generated/LetExpr/LetExpr_getAttr.ql linguist-generated -/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.ql linguist-generated /test/extractor-tests/generated/LetExpr/LetExpr_getPat.ql linguist-generated +/test/extractor-tests/generated/LetExpr/LetExpr_getScrutinee.ql linguist-generated /test/extractor-tests/generated/LetStmt/LetStmt.ql linguist-generated /test/extractor-tests/generated/LetStmt/LetStmt_getAttr.ql linguist-generated /test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.ql linguist-generated diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 91eeb75fe39..0b78b44f180 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -313,7 +313,7 @@ module ExprTrees { class CallExprTree extends StandardPostOrderTree instanceof CallExpr { override AstNode getChildNode(int i) { - i = 0 and result = super.getExpr() + i = 0 and result = super.getFunction() or result = super.getArgList().getArg(i - 1) } @@ -410,7 +410,7 @@ module ExprTrees { class LetExprTree extends StandardPreOrderTree, LetExpr { override AstNode getChildNode(int i) { i = 0 and - result = this.getExpr() + result = this.getScrutinee() or i = 1 and result = this.getPat() diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll index 44024a9d76e..1c3afbc83b0 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll @@ -570,7 +570,7 @@ module MakeCfgNodes Input> { override predicate relevantChild(AstNode child) { none() or - child = this.getExpr() + child = this.getFunction() } } @@ -592,16 +592,16 @@ module MakeCfgNodes Input> { CallExpr getCallExpr() { result = node } /** - * Gets the expression of this call expression, if it exists. + * Gets the function of this call expression, if it exists. */ - ExprCfgNode getExpr() { - any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + ExprCfgNode getFunction() { + any(ChildMapping mapping).hasCfgChild(node, node.getFunction(), this, result) } /** - * Holds if `getExpr()` exists. + * Holds if `getFunction()` exists. */ - predicate hasExpr() { exists(this.getExpr()) } + predicate hasFunction() { exists(this.getFunction()) } } final private class ParentCallExprBase extends ParentAstNode, CallExprBase { @@ -1245,7 +1245,7 @@ module MakeCfgNodes Input> { override predicate relevantChild(AstNode child) { none() or - child = this.getExpr() + child = this.getScrutinee() or child = this.getPat() } @@ -1283,16 +1283,16 @@ module MakeCfgNodes Input> { int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } /** - * Gets the expression of this let expression, if it exists. + * Gets the scrutinee of this let expression, if it exists. */ - ExprCfgNode getExpr() { - any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result) + ExprCfgNode getScrutinee() { + any(ChildMapping mapping).hasCfgChild(node, node.getScrutinee(), this, result) } /** - * Holds if `getExpr()` exists. + * Holds if `getScrutinee()` exists. */ - predicate hasExpr() { exists(this.getExpr()) } + predicate hasScrutinee() { exists(this.getScrutinee()) } /** * Gets the pat of this let expression, if it exists. @@ -3211,14 +3211,14 @@ module MakeCfgNodes Input> { cfgNode ) or - pred = "getExpr" and + pred = "getFunction" and parent = any(Nodes::CallExprCfgNode cfgNode, CallExpr astNode | astNode = cfgNode.getCallExpr() and - child = getDesugared(astNode.getExpr()) and + child = getDesugared(astNode.getFunction()) and i = -1 and hasCfgNode(child) and - not child = cfgNode.getExpr().getAstNode() + not child = cfgNode.getFunction().getAstNode() | cfgNode ) @@ -3355,14 +3355,14 @@ module MakeCfgNodes Input> { cfgNode ) or - pred = "getExpr" and + pred = "getScrutinee" and parent = any(Nodes::LetExprCfgNode cfgNode, LetExpr astNode | astNode = cfgNode.getLetExpr() and - child = getDesugared(astNode.getExpr()) and + child = getDesugared(astNode.getScrutinee()) and i = -1 and hasCfgNode(child) and - not child = cfgNode.getExpr().getAstNode() + not child = cfgNode.getScrutinee().getAstNode() | cfgNode ) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 91f8065ab5a..cbf61e005e0 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -422,7 +422,7 @@ module RustDataFlow implements InputSig { ( r = c.asMethodCallExprCfgNode().getExpr() or - r = c.asCallExprCfgNode().getExpr().(PathExprCfgNode).getPath() + r = c.asCallExprCfgNode().getFunction().(PathExprCfgNode).getPath() ) | crate.asSome() = r.getResolvedCrateOrigin() diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll index 3da29db7df1..53e4c2de2cc 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll @@ -23,6 +23,6 @@ module Impl { * ``` */ class CallExpr extends Generated::CallExpr { - override string toString() { result = this.getExpr().toAbbreviatedString() + "(...)" } + override string toString() { result = this.getFunction().toAbbreviatedString() + "(...)" } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/LetExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LetExprImpl.qll index 5b8bd7ec963..b690f2b044b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LetExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LetExprImpl.qll @@ -28,7 +28,7 @@ module Impl { or index = 1 and result = this.getPat().toAbbreviatedString() or - index = 2 and result = "= " + this.getExpr().toAbbreviatedString() + index = 2 and result = "= " + this.getScrutinee().toAbbreviatedString() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/CallExpr.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/CallExpr.qll index 2e41b664a4e..829de70510b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/CallExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/CallExpr.qll @@ -29,16 +29,16 @@ module Generated { override string getAPrimaryQlClass() { result = "CallExpr" } /** - * Gets the expression of this call expression, if it exists. + * Gets the function of this call expression, if it exists. */ - Expr getExpr() { + Expr getFunction() { result = - Synth::convertExprFromRaw(Synth::convertCallExprToRaw(this).(Raw::CallExpr).getExpr()) + Synth::convertExprFromRaw(Synth::convertCallExprToRaw(this).(Raw::CallExpr).getFunction()) } /** - * Holds if `getExpr()` exists. + * Holds if `getFunction()` exists. */ - final predicate hasExpr() { exists(this.getExpr()) } + final predicate hasFunction() { exists(this.getFunction()) } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/LetExpr.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/LetExpr.qll index b53dc1c8c67..c887afa603d 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/LetExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/LetExpr.qll @@ -48,16 +48,17 @@ module Generated { final int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } /** - * Gets the expression of this let expression, if it exists. + * Gets the scrutinee of this let expression, if it exists. */ - Expr getExpr() { - result = Synth::convertExprFromRaw(Synth::convertLetExprToRaw(this).(Raw::LetExpr).getExpr()) + Expr getScrutinee() { + result = + Synth::convertExprFromRaw(Synth::convertLetExprToRaw(this).(Raw::LetExpr).getScrutinee()) } /** - * Holds if `getExpr()` exists. + * Holds if `getScrutinee()` exists. */ - final predicate hasExpr() { exists(this.getExpr()) } + final predicate hasScrutinee() { exists(this.getScrutinee()) } /** * Gets the pat of this let expression, if it exists. diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll index 970cfb22364..4c2e74f5c36 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll @@ -1848,13 +1848,13 @@ private module Impl { } private Element getImmediateChildOfLetExpr(LetExpr e, int index, string partialPredicateCall) { - exists(int b, int bExpr, int n, int nAttr, int nExpr, int nPat | + exists(int b, int bExpr, int n, int nAttr, int nScrutinee, int nPat | b = 0 and bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and n = bExpr and nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and - nExpr = nAttr + 1 and - nPat = nExpr + 1 and + nScrutinee = nAttr + 1 and + nPat = nScrutinee + 1 and ( none() or @@ -1863,9 +1863,9 @@ private module Impl { result = e.getAttr(index - n) and partialPredicateCall = "Attr(" + (index - n).toString() + ")" or - index = nAttr and result = e.getExpr() and partialPredicateCall = "Expr()" + index = nAttr and result = e.getScrutinee() and partialPredicateCall = "Scrutinee()" or - index = nExpr and result = e.getPat() and partialPredicateCall = "Pat()" + index = nScrutinee and result = e.getPat() and partialPredicateCall = "Pat()" ) ) } @@ -2786,18 +2786,18 @@ private module Impl { } private Element getImmediateChildOfCallExpr(CallExpr e, int index, string partialPredicateCall) { - exists(int b, int bCallExprBase, int n, int nExpr | + exists(int b, int bCallExprBase, int n, int nFunction | b = 0 and bCallExprBase = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfCallExprBase(e, i, _)) | i) and n = bCallExprBase and - nExpr = n + 1 and + nFunction = n + 1 and ( none() or result = getImmediateChildOfCallExprBase(e, index - b, partialPredicateCall) or - index = n and result = e.getExpr() and partialPredicateCall = "Expr()" + index = n and result = e.getFunction() and partialPredicateCall = "Function()" ) ) } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index 76d170244d5..52542844c29 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -1955,9 +1955,9 @@ module Raw { Attr getAttr(int index) { let_expr_attrs(this, index, result) } /** - * Gets the expression of this let expression, if it exists. + * Gets the scrutinee of this let expression, if it exists. */ - Expr getExpr() { let_expr_exprs(this, result) } + Expr getScrutinee() { let_expr_scrutinees(this, result) } /** * Gets the pat of this let expression, if it exists. @@ -3064,9 +3064,9 @@ module Raw { override string toString() { result = "CallExpr" } /** - * Gets the expression of this call expression, if it exists. + * Gets the function of this call expression, if it exists. */ - Expr getExpr() { call_expr_exprs(this, result) } + Expr getFunction() { call_expr_functions(this, result) } } /** diff --git a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll index 2ab11a20ed4..f46c12feab9 100644 --- a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll +++ b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll @@ -12,8 +12,9 @@ private class ReqwestGet extends RemoteSource::Range { ReqwestGet() { exists(CallExpr ce | this.asExpr().getExpr() = ce and - ce.getExpr().(PathExpr).getPath().getResolvedCrateOrigin().matches("%reqwest") and - ce.getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::get", "crate::blocking::get"] + ce.getFunction().(PathExpr).getPath().getResolvedCrateOrigin().matches("%reqwest") and + ce.getFunction().(PathExpr).getPath().getResolvedPath() = + ["crate::get", "crate::blocking::get"] ) } } diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll b/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll index 69658d5fec5..3e769ae84d4 100644 --- a/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll @@ -10,7 +10,7 @@ private import codeql.rust.Concepts */ private class StdEnvArgs extends CommandLineArgsSource::Range { StdEnvArgs() { - this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = + this.asExpr().getExpr().(CallExpr).getFunction().(PathExpr).getPath().getResolvedPath() = ["crate::env::args", "crate::env::args_os"] } } @@ -20,7 +20,7 @@ private class StdEnvArgs extends CommandLineArgsSource::Range { */ private class StdEnvDir extends CommandLineArgsSource::Range { StdEnvDir() { - this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = + this.asExpr().getExpr().(CallExpr).getFunction().(PathExpr).getPath().getResolvedPath() = ["crate::env::current_dir", "crate::env::current_exe", "crate::env::home_dir"] } } @@ -30,7 +30,7 @@ private class StdEnvDir extends CommandLineArgsSource::Range { */ private class StdEnvVar extends EnvironmentSource::Range { StdEnvVar() { - this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = + this.asExpr().getExpr().(CallExpr).getFunction().(PathExpr).getPath().getResolvedPath() = ["crate::env::var", "crate::env::var_os", "crate::env::vars", "crate::env::vars_os"] } } diff --git a/rust/ql/lib/codeql/rust/internal/CachedStages.qll b/rust/ql/lib/codeql/rust/internal/CachedStages.qll index 3defe0b8168..1fdd3c2a9b8 100644 --- a/rust/ql/lib/codeql/rust/internal/CachedStages.qll +++ b/rust/ql/lib/codeql/rust/internal/CachedStages.qll @@ -95,7 +95,7 @@ module Stages { or exists(AstCfgNode n) or - exists(CallExprCfgNode n | exists(n.getExpr())) + exists(CallExprCfgNode n | exists(n.getFunction())) } } } diff --git a/rust/ql/lib/rust.dbscheme b/rust/ql/lib/rust.dbscheme index 46085a55abf..629ea072ea3 100644 --- a/rust/ql/lib/rust.dbscheme +++ b/rust/ql/lib/rust.dbscheme @@ -1748,9 +1748,9 @@ let_expr_attrs( ); #keyset[id] -let_expr_exprs( +let_expr_scrutinees( int id: @let_expr ref, - int expr: @expr ref + int scrutinee: @expr ref ); #keyset[id] @@ -2533,9 +2533,9 @@ call_exprs( ); #keyset[id] -call_expr_exprs( +call_expr_functions( int id: @call_expr ref, - int expr: @expr ref + int function: @expr ref ); consts( diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected index a3f108b5584..ebe6eeda104 100644 --- a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected @@ -1,4 +1,4 @@ -| gen_call_expr.rs:5:5:5:11 | foo(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | -| gen_call_expr.rs:6:5:6:23 | foo::<...>(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | -| gen_call_expr.rs:7:5:7:14 | ...(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | -| gen_call_expr.rs:8:5:8:10 | foo(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes | +| gen_call_expr.rs:5:5:5:11 | foo(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasFunction: | yes | +| gen_call_expr.rs:6:5:6:23 | foo::<...>(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasFunction: | yes | +| gen_call_expr.rs:7:5:7:14 | ...(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasFunction: | yes | +| gen_call_expr.rs:8:5:8:10 | foo(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasFunction: | yes | diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.ql b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.ql index b44136c4942..cd043e88d1d 100644 --- a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.ql +++ b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.ql @@ -2,11 +2,12 @@ import codeql.rust.elements import TestUtils -from CallExpr x, string hasArgList, int getNumberOfAttrs, string hasExpr +from CallExpr x, string hasArgList, int getNumberOfAttrs, string hasFunction where toBeTested(x) and not x.isUnknown() and (if x.hasArgList() then hasArgList = "yes" else hasArgList = "no") and getNumberOfAttrs = x.getNumberOfAttrs() and - if x.hasExpr() then hasExpr = "yes" else hasExpr = "no" -select x, "hasArgList:", hasArgList, "getNumberOfAttrs:", getNumberOfAttrs, "hasExpr:", hasExpr + if x.hasFunction() then hasFunction = "yes" else hasFunction = "no" +select x, "hasArgList:", hasArgList, "getNumberOfAttrs:", getNumberOfAttrs, "hasFunction:", + hasFunction diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getFunction.expected b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getFunction.expected new file mode 100644 index 00000000000..ecaaf15cebb --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getFunction.expected @@ -0,0 +1,4 @@ +| gen_call_expr.rs:5:5:5:11 | foo(...) | gen_call_expr.rs:5:5:5:7 | foo | +| gen_call_expr.rs:6:5:6:23 | foo::<...>(...) | gen_call_expr.rs:6:5:6:19 | foo::<...> | +| gen_call_expr.rs:7:5:7:14 | ...(...) | gen_call_expr.rs:7:5:7:10 | foo[0] | +| gen_call_expr.rs:8:5:8:10 | foo(...) | gen_call_expr.rs:8:5:8:7 | foo | diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.ql b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getFunction.ql similarity index 84% rename from rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.ql rename to rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getFunction.ql index d09819fc1fd..61196bcd14d 100644 --- a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.ql +++ b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr_getFunction.ql @@ -4,4 +4,4 @@ import TestUtils from CallExpr x where toBeTested(x) and not x.isUnknown() -select x, x.getExpr() +select x, x.getFunction() diff --git a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.expected b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.expected index 7ff5ad393e1..115493214ea 100644 --- a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.expected +++ b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.expected @@ -1 +1 @@ -| gen_let_expr.rs:5:8:5:31 | let ... = maybe_some | getNumberOfAttrs: | 0 | hasExpr: | yes | hasPat: | yes | +| gen_let_expr.rs:5:8:5:31 | let ... = maybe_some | getNumberOfAttrs: | 0 | hasScrutinee: | yes | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.ql b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.ql index 1b7648a5668..60aa8b90892 100644 --- a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.ql +++ b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr.ql @@ -2,11 +2,11 @@ import codeql.rust.elements import TestUtils -from LetExpr x, int getNumberOfAttrs, string hasExpr, string hasPat +from LetExpr x, int getNumberOfAttrs, string hasScrutinee, string hasPat where toBeTested(x) and not x.isUnknown() and getNumberOfAttrs = x.getNumberOfAttrs() and - (if x.hasExpr() then hasExpr = "yes" else hasExpr = "no") and + (if x.hasScrutinee() then hasScrutinee = "yes" else hasScrutinee = "no") and if x.hasPat() then hasPat = "yes" else hasPat = "no" -select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasExpr:", hasExpr, "hasPat:", hasPat +select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasScrutinee:", hasScrutinee, "hasPat:", hasPat diff --git a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getScrutinee.expected b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getScrutinee.expected new file mode 100644 index 00000000000..0080ab4ee6e --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getScrutinee.expected @@ -0,0 +1 @@ +| gen_let_expr.rs:5:8:5:31 | let ... = maybe_some | gen_let_expr.rs:5:22:5:31 | maybe_some | diff --git a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.ql b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getScrutinee.ql similarity index 83% rename from rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.ql rename to rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getScrutinee.ql index 0f9e8088b46..2c144c2ac3c 100644 --- a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.ql +++ b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getScrutinee.ql @@ -4,4 +4,4 @@ import TestUtils from LetExpr x where toBeTested(x) and not x.isUnknown() -select x, x.getExpr() +select x, x.getScrutinee() diff --git a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql index 85ac4eec698..2b08aeea63f 100644 --- a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql +++ b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql @@ -10,9 +10,9 @@ module MyFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ThreatModelSource } predicate isSink(DataFlow::Node sink) { - any(CallExpr call | call.getExpr().(PathExpr).getPath().getResolvedPath() = "crate::test::sink") - .getArgList() - .getAnArg() = sink.asExpr().getExpr() + any(CallExpr call | + call.getFunction().(PathExpr).getPath().getResolvedPath() = "crate::test::sink" + ).getArgList().getAnArg() = sink.asExpr().getExpr() } } diff --git a/rust/ql/test/utils/InlineFlowTest.qll b/rust/ql/test/utils/InlineFlowTest.qll index ad196871273..dcf8ad8c445 100644 --- a/rust/ql/test/utils/InlineFlowTest.qll +++ b/rust/ql/test/utils/InlineFlowTest.qll @@ -13,7 +13,7 @@ private import internal.InlineExpectationsTestImpl as InlineExpectationsTestImpl // Holds if the target expression of `call` is a path and the string representation of the path is `name`. private predicate callTargetName(CallExprCfgNode call, string name) { - call.getExpr().(PathExprCfgNode).toString() = name + call.getFunction().(PathExprCfgNode).toString() = name } private module FlowTestImpl implements InputSig { diff --git a/rust/schema/ast.py b/rust/schema/ast.py index 3e9b1b0ead3..1f5a35d7bc2 100644 --- a/rust/schema/ast.py +++ b/rust/schema/ast.py @@ -103,7 +103,7 @@ class BreakExpr(Expr): class CallExpr(Expr): arg_list: optional["ArgList"] | child attrs: list["Attr"] | child - expr: optional["Expr"] | child + function: optional["Expr"] | child class CastExpr(Expr): attrs: list["Attr"] | child @@ -285,7 +285,7 @@ class LetElse(AstNode): class LetExpr(Expr): attrs: list["Attr"] | child - expr: optional["Expr"] | child + scrutinee: optional["Expr"] | child pat: optional["Pat"] | child class LetStmt(Stmt): From 8d591596917a47d1de65c1cf06391418288a03c2 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 26 Nov 2024 15:35:52 +0100 Subject: [PATCH 278/470] C++: Fix qlref file --- .../query-tests/Best Practices/GuardedFree/GuardedFree.qlref | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/test/query-tests/Best Practices/GuardedFree/GuardedFree.qlref b/cpp/ql/test/query-tests/Best Practices/GuardedFree/GuardedFree.qlref index e28bdae3991..d64671f08c3 100644 --- a/cpp/ql/test/query-tests/Best Practices/GuardedFree/GuardedFree.qlref +++ b/cpp/ql/test/query-tests/Best Practices/GuardedFree/GuardedFree.qlref @@ -1 +1 @@ -experimental/Best Practices/GuardedFree.ql +Best Practices/GuardedFree.ql From 7ab5663fa6a9bcd48f89c9dd9acaf47d30554630 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Tue, 26 Nov 2024 15:42:19 +0100 Subject: [PATCH 279/470] Rust: Address PR feedback --- .../rust/elements/internal/VariableImpl.qll | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index d2ae6c48dfc..a9758c455b9 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -74,32 +74,34 @@ module Impl { * pattern. */ private predicate variableDecl(AstNode definingNode, AstNode p, string name) { - exists(SelfParam sp | sp = p | - definingNode = sp.getName() and - name = sp.getName().getText() and - // exclude self parameters from functions without a body as these are - // trait method declarations without implementations - not exists(Function f | not f.hasBody() and f.getParamList().getSelfParam() = sp) - ) + p = + any(SelfParam sp | + definingNode = sp.getName() and + name = sp.getName().getText() and + // exclude self parameters from functions without a body as these are + // trait method declarations without implementations + not exists(Function f | not f.hasBody() and f.getParamList().getSelfParam() = sp) + ) or - exists(IdentPat pat | pat = p | - ( - definingNode = getOutermostEnclosingOrPat(pat) - or - not exists(getOutermostEnclosingOrPat(pat)) and definingNode = pat.getName() - ) and - name = pat.getName().getText() and - // exclude for now anything starting with an uppercase character, which may be a reference to - // an enum constant (e.g. `None`). This excludes static and constant variables (UPPERCASE), - // which we don't appear to recognize yet anyway. This also assumes programmers follow the - // naming guidelines, which they generally do, but they're not enforced. - not name.charAt(0).isUppercase() and - // exclude parameters from functions without a body as these are trait method declarations - // without implementations - not exists(Function f | not f.hasBody() and f.getParamList().getAParam().getPat() = pat) and - // exclude parameters from function pointer types (e.g. `x` in `fn(x: i32) -> i32`) - not exists(FnPtrType fp | fp.getParamList().getParam(_).getPat() = pat) - ) + p = + any(IdentPat pat | + ( + definingNode = getOutermostEnclosingOrPat(pat) + or + not exists(getOutermostEnclosingOrPat(pat)) and definingNode = pat.getName() + ) and + name = pat.getName().getText() and + // exclude for now anything starting with an uppercase character, which may be a reference to + // an enum constant (e.g. `None`). This excludes static and constant variables (UPPERCASE), + // which we don't appear to recognize yet anyway. This also assumes programmers follow the + // naming guidelines, which they generally do, but they're not enforced. + not name.charAt(0).isUppercase() and + // exclude parameters from functions without a body as these are trait method declarations + // without implementations + not exists(Function f | not f.hasBody() and f.getParamList().getAParam().getPat() = pat) and + // exclude parameters from function pointer types (e.g. `x` in `fn(x: i32) -> i32`) + not exists(FnPtrType fp | fp.getParamList().getParam(_).getPat() = pat) + ) } /** A variable. */ @@ -125,7 +127,7 @@ module Impl { SelfParam getSelfParam() { variableDecl(definingNode, result, name) } /** - * Gets the pattern that declares this variable, if one exists. + * Gets the pattern that declares this variable, if any. * * Normally, the pattern is unique, except when introduced in an or pattern: * @@ -148,7 +150,7 @@ module Impl { /** Gets the parameter that introduces this variable, if any. */ ParamBase getParameter() { - result = this.getSelfParam() or result = getAVariablePatAncestor(this).getParentNode() + result = this.getSelfParam() or result.(Param).getPat() = getAVariablePatAncestor(this) } /** Hold is this variable is mutable. */ @@ -217,8 +219,7 @@ module Impl { } /** - * Holds if parameter `p` introduces the variable `v` inside variable scope - * `scope`. + * Holds if a parameter declares the variable `v` inside variable scope `scope`. */ private predicate parameterDeclInScope(Variable v, VariableScope scope) { exists(Callable f | From 141259c003da23a07fdfcaeada65f523bbe1a7cc Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:48:20 +0000 Subject: [PATCH 280/470] Update go/ql/lib/ext/slices.model.yml Co-authored-by: Chris Smowton --- go/ql/lib/ext/slices.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/ql/lib/ext/slices.model.yml b/go/ql/lib/ext/slices.model.yml index 0c88a5bb62e..2023aeb3db2 100644 --- a/go/ql/lib/ext/slices.model.yml +++ b/go/ql/lib/ext/slices.model.yml @@ -28,4 +28,4 @@ extensions: # Sorted should be modeled when we have a way to model iterators # SortedFunc should be modeled when we have a way to model iterators # SortedStableFunc should be modeled when we have a way to model iterators - # Vales should be modeled when we have a way to model iterators + # Values should be modeled when we have a way to model iterators From 24eb65692f616cb1b3f1f8f0b5bad6bd10071ceb Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 26 Nov 2024 15:57:18 +0100 Subject: [PATCH 281/470] Rust: add some performance diagnostics This outputs some duration counts for various parts of the extraction process in the database in the form of telemetry diagnostics. The diagnostics format was preferred to putting things in the relational database as that will scale better to code scanning and is more flexible as for the data we can put into it without passing through the dbscheme. Also, although it's not the case yet, it will be possible to output diagnostics even if creation of the database fails. --- Cargo.lock | 6 +- MODULE.bazel | 2 +- .../tree_sitter_extractors_deps/BUILD.bazel | 2 +- .../BUILD.cargo_metadata-0.18.1.bazel | 2 +- .../BUILD.ra_ap_proc_macro_api-0.0.232.bazel | 2 +- .../BUILD.ra_ap_project_model-0.0.232.bazel | 2 +- ...2.bazel => BUILD.serde_json-1.0.133.bazel} | 6 +- .../tree_sitter_extractors_deps/defs.bzl | 16 +- rust/extractor/Cargo.toml | 2 + rust/extractor/src/config.rs | 1 + rust/extractor/src/diagnostics.rs | 258 ++++++++++++++++++ rust/extractor/src/main.rs | 90 ++++-- rust/ql/integration-tests/conftest.py | 9 + .../hello-project/diagnostics.expected | 101 +++++++ .../hello-project/test_project.py | 4 +- .../diagnostics.cargo.expected | 97 +++++++ .../diagnostics.rust-project.expected | 93 +++++++ .../hello-workspace/test_workspace.py | 6 +- 18 files changed, 656 insertions(+), 43 deletions(-) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.serde_json-1.0.132.bazel => BUILD.serde_json-1.0.133.bazel} (97%) create mode 100644 rust/extractor/src/diagnostics.rs create mode 100644 rust/ql/integration-tests/hello-project/diagnostics.expected create mode 100644 rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected create mode 100644 rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected diff --git a/Cargo.lock b/Cargo.lock index 1d5b8824c84..b0af4387f2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -381,6 +381,7 @@ version = "0.1.0" dependencies = [ "anyhow", "argfile", + "chrono", "clap", "codeql-extractor", "figment", @@ -404,6 +405,7 @@ dependencies = [ "ra_ap_vfs", "rust-extractor-macros", "serde", + "serde_json", "serde_with", "stderrlog", "triomphe", @@ -2034,9 +2036,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", diff --git a/MODULE.bazel b/MODULE.bazel index 13c801520b0..311d0908832 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -68,7 +68,7 @@ use_repo(py_deps, "vendor__anyhow-1.0.44", "vendor__cc-1.0.70", "vendor__clap-2. # deps for ruby+rust # keep in sync by running `misc/bazel/3rdparty/update_cargo_deps.sh` tree_sitter_extractors_deps = use_extension("//misc/bazel/3rdparty:tree_sitter_extractors_extension.bzl", "r") -use_repo(tree_sitter_extractors_deps, "vendor__anyhow-1.0.93", "vendor__argfile-0.2.1", "vendor__chrono-0.4.38", "vendor__clap-4.5.20", "vendor__encoding-0.2.33", "vendor__figment-0.10.19", "vendor__flate2-1.0.34", "vendor__glob-0.3.1", "vendor__globset-0.4.15", "vendor__itertools-0.10.5", "vendor__itertools-0.13.0", "vendor__lazy_static-1.5.0", "vendor__log-0.4.22", "vendor__num-traits-0.2.19", "vendor__num_cpus-1.16.0", "vendor__proc-macro2-1.0.89", "vendor__quote-1.0.37", "vendor__ra_ap_base_db-0.0.232", "vendor__ra_ap_cfg-0.0.232", "vendor__ra_ap_hir-0.0.232", "vendor__ra_ap_hir_def-0.0.232", "vendor__ra_ap_hir_expand-0.0.232", "vendor__ra_ap_ide_db-0.0.232", "vendor__ra_ap_intern-0.0.232", "vendor__ra_ap_load-cargo-0.0.232", "vendor__ra_ap_parser-0.0.232", "vendor__ra_ap_paths-0.0.232", "vendor__ra_ap_project_model-0.0.232", "vendor__ra_ap_span-0.0.232", "vendor__ra_ap_syntax-0.0.232", "vendor__ra_ap_vfs-0.0.232", "vendor__rand-0.8.5", "vendor__rayon-1.10.0", "vendor__regex-1.11.1", "vendor__serde-1.0.214", "vendor__serde_json-1.0.132", "vendor__serde_with-3.11.0", "vendor__stderrlog-0.6.0", "vendor__syn-2.0.87", "vendor__tracing-0.1.40", "vendor__tracing-subscriber-0.3.18", "vendor__tree-sitter-0.24.4", "vendor__tree-sitter-embedded-template-0.23.2", "vendor__tree-sitter-json-0.24.8", "vendor__tree-sitter-ql-0.23.1", "vendor__tree-sitter-ruby-0.23.1", "vendor__triomphe-0.1.14", "vendor__ungrammar-1.16.1") +use_repo(tree_sitter_extractors_deps, "vendor__anyhow-1.0.93", "vendor__argfile-0.2.1", "vendor__chrono-0.4.38", "vendor__clap-4.5.20", "vendor__encoding-0.2.33", "vendor__figment-0.10.19", "vendor__flate2-1.0.34", "vendor__glob-0.3.1", "vendor__globset-0.4.15", "vendor__itertools-0.10.5", "vendor__itertools-0.13.0", "vendor__lazy_static-1.5.0", "vendor__log-0.4.22", "vendor__num-traits-0.2.19", "vendor__num_cpus-1.16.0", "vendor__proc-macro2-1.0.89", "vendor__quote-1.0.37", "vendor__ra_ap_base_db-0.0.232", "vendor__ra_ap_cfg-0.0.232", "vendor__ra_ap_hir-0.0.232", "vendor__ra_ap_hir_def-0.0.232", "vendor__ra_ap_hir_expand-0.0.232", "vendor__ra_ap_ide_db-0.0.232", "vendor__ra_ap_intern-0.0.232", "vendor__ra_ap_load-cargo-0.0.232", "vendor__ra_ap_parser-0.0.232", "vendor__ra_ap_paths-0.0.232", "vendor__ra_ap_project_model-0.0.232", "vendor__ra_ap_span-0.0.232", "vendor__ra_ap_syntax-0.0.232", "vendor__ra_ap_vfs-0.0.232", "vendor__rand-0.8.5", "vendor__rayon-1.10.0", "vendor__regex-1.11.1", "vendor__serde-1.0.214", "vendor__serde_json-1.0.133", "vendor__serde_with-3.11.0", "vendor__stderrlog-0.6.0", "vendor__syn-2.0.87", "vendor__tracing-0.1.40", "vendor__tracing-subscriber-0.3.18", "vendor__tree-sitter-0.24.4", "vendor__tree-sitter-embedded-template-0.23.2", "vendor__tree-sitter-json-0.24.8", "vendor__tree-sitter-ql-0.23.1", "vendor__tree-sitter-ruby-0.23.1", "vendor__triomphe-0.1.14", "vendor__ungrammar-1.16.1") dotnet = use_extension("@rules_dotnet//dotnet:extensions.bzl", "dotnet") dotnet.toolchain(dotnet_version = "9.0.100") diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel index 844d385f8a4..6208d66c5d9 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel @@ -243,7 +243,7 @@ alias( alias( name = "serde_json", - actual = "@vendor__serde_json-1.0.132//:serde_json", + actual = "@vendor__serde_json-1.0.133//:serde_json", tags = ["manual"], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo_metadata-0.18.1.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo_metadata-0.18.1.bazel index e31c61cfac7..9ad331aa5f7 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo_metadata-0.18.1.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo_metadata-0.18.1.bazel @@ -86,7 +86,7 @@ rust_library( "@vendor__cargo-platform-0.1.8//:cargo_platform", "@vendor__semver-1.0.23//:semver", "@vendor__serde-1.0.214//:serde", - "@vendor__serde_json-1.0.132//:serde_json", + "@vendor__serde_json-1.0.133//:serde_json", "@vendor__thiserror-1.0.69//:thiserror", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_proc_macro_api-0.0.232.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_proc_macro_api-0.0.232.bazel index d1f5d480d71..fa3b71f570c 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_proc_macro_api-0.0.232.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_proc_macro_api-0.0.232.bazel @@ -96,7 +96,7 @@ rust_library( "@vendor__ra_ap_tt-0.0.232//:ra_ap_tt", "@vendor__rustc-hash-1.1.0//:rustc_hash", "@vendor__serde-1.0.214//:serde", - "@vendor__serde_json-1.0.132//:serde_json", + "@vendor__serde_json-1.0.133//:serde_json", "@vendor__tracing-0.1.40//:tracing", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_project_model-0.0.232.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_project_model-0.0.232.bazel index 6f6f3bb303a..5608e6dd6b0 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_project_model-0.0.232.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_project_model-0.0.232.bazel @@ -102,7 +102,7 @@ rust_library( "@vendor__rustc-hash-1.1.0//:rustc_hash", "@vendor__semver-1.0.23//:semver", "@vendor__serde-1.0.214//:serde", - "@vendor__serde_json-1.0.132//:serde_json", + "@vendor__serde_json-1.0.133//:serde_json", "@vendor__tracing-0.1.40//:tracing", "@vendor__triomphe-0.1.14//:triomphe", ], diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.132.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.133.bazel similarity index 97% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.132.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.133.bazel index ecbae32eeaf..710772e4f37 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.132.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.133.bazel @@ -83,13 +83,13 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-none": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "1.0.132", + version = "1.0.133", deps = [ "@vendor__itoa-1.0.11//:itoa", "@vendor__memchr-2.7.4//:memchr", "@vendor__ryu-1.0.18//:ryu", "@vendor__serde-1.0.214//:serde", - "@vendor__serde_json-1.0.132//:build_script_build", + "@vendor__serde_json-1.0.133//:build_script_build", ], ) @@ -143,7 +143,7 @@ cargo_build_script( "noclippy", "norustfmt", ], - version = "1.0.132", + version = "1.0.133", visibility = ["//visibility:private"], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl b/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl index 1d0b825c235..927736b56b2 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl @@ -320,6 +320,7 @@ _NORMAL_DEPENDENCIES = { _COMMON_CONDITION: { "anyhow": Label("@vendor__anyhow-1.0.93//:anyhow"), "argfile": Label("@vendor__argfile-0.2.1//:argfile"), + "chrono": Label("@vendor__chrono-0.4.38//:chrono"), "clap": Label("@vendor__clap-4.5.20//:clap"), "figment": Label("@vendor__figment-0.10.19//:figment"), "glob": Label("@vendor__glob-0.3.1//:glob"), @@ -341,6 +342,7 @@ _NORMAL_DEPENDENCIES = { "ra_ap_syntax": Label("@vendor__ra_ap_syntax-0.0.232//:ra_ap_syntax"), "ra_ap_vfs": Label("@vendor__ra_ap_vfs-0.0.232//:ra_ap_vfs"), "serde": Label("@vendor__serde-1.0.214//:serde"), + "serde_json": Label("@vendor__serde_json-1.0.133//:serde_json"), "serde_with": Label("@vendor__serde_with-3.11.0//:serde_with"), "stderrlog": Label("@vendor__stderrlog-0.6.0//:stderrlog"), "triomphe": Label("@vendor__triomphe-0.1.14//:triomphe"), @@ -363,7 +365,7 @@ _NORMAL_DEPENDENCIES = { "rayon": Label("@vendor__rayon-1.10.0//:rayon"), "regex": Label("@vendor__regex-1.11.1//:regex"), "serde": Label("@vendor__serde-1.0.214//:serde"), - "serde_json": Label("@vendor__serde_json-1.0.132//:serde_json"), + "serde_json": Label("@vendor__serde_json-1.0.133//:serde_json"), "tracing": Label("@vendor__tracing-0.1.40//:tracing"), "tracing-subscriber": Label("@vendor__tracing-subscriber-0.3.18//:tracing_subscriber"), "tree-sitter": Label("@vendor__tree-sitter-0.24.4//:tree_sitter"), @@ -2508,12 +2510,12 @@ def crate_repositories(): maybe( http_archive, - name = "vendor__serde_json-1.0.132", - sha256 = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03", + name = "vendor__serde_json-1.0.133", + sha256 = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377", type = "tar.gz", - urls = ["https://static.crates.io/crates/serde_json/1.0.132/download"], - strip_prefix = "serde_json-1.0.132", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_json-1.0.132.bazel"), + urls = ["https://static.crates.io/crates/serde_json/1.0.133/download"], + strip_prefix = "serde_json-1.0.133", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_json-1.0.133.bazel"), ) maybe( @@ -3341,7 +3343,7 @@ def crate_repositories(): struct(repo = "vendor__rayon-1.10.0", is_dev_dep = False), struct(repo = "vendor__regex-1.11.1", is_dev_dep = False), struct(repo = "vendor__serde-1.0.214", is_dev_dep = False), - struct(repo = "vendor__serde_json-1.0.132", is_dev_dep = False), + struct(repo = "vendor__serde_json-1.0.133", is_dev_dep = False), struct(repo = "vendor__serde_with-3.11.0", is_dev_dep = False), struct(repo = "vendor__stderrlog-0.6.0", is_dev_dep = False), struct(repo = "vendor__syn-2.0.87", is_dev_dep = False), diff --git a/rust/extractor/Cargo.toml b/rust/extractor/Cargo.toml index 8b58898d3cf..591df3480cd 100644 --- a/rust/extractor/Cargo.toml +++ b/rust/extractor/Cargo.toml @@ -33,3 +33,5 @@ codeql-extractor = { path = "../../shared/tree-sitter-extractor" } rust-extractor-macros = { path = "macros" } itertools = "0.13.0" glob = "0.3.1" +chrono = { version = "0.4.38", features = ["serde"] } +serde_json = "1.0.133" diff --git a/rust/extractor/src/config.rs b/rust/extractor/src/config.rs index 70c390b9949..0e92e82a58c 100644 --- a/rust/extractor/src/config.rs +++ b/rust/extractor/src/config.rs @@ -45,6 +45,7 @@ pub struct Config { pub scratch_dir: PathBuf, pub trap_dir: PathBuf, pub source_archive_dir: PathBuf, + pub diagnostic_dir: PathBuf, pub cargo_target_dir: Option, pub cargo_target: Option, pub cargo_features: Vec, diff --git a/rust/extractor/src/diagnostics.rs b/rust/extractor/src/diagnostics.rs new file mode 100644 index 00000000000..21b3619a207 --- /dev/null +++ b/rust/extractor/src/diagnostics.rs @@ -0,0 +1,258 @@ +use crate::config::Config; +use anyhow::Context; +use chrono::{DateTime, Utc}; +use log::{debug, info}; +use ra_ap_project_model::ProjectManifest; +use serde::Serialize; +use std::fmt::Display; +use std::fs::File; +use std::path::{Path, PathBuf}; +use std::time::Instant; + +#[derive(Default, Debug, Clone, Copy, Serialize)] +#[serde(rename_all = "camelCase")] +#[allow(dead_code)] +enum Severity { + #[default] + Note, + Warning, + Error, +} + +#[derive(Default, Debug, Clone, Copy, Serialize)] +#[serde(rename_all = "camelCase")] +struct Visibility { + status_page: bool, + cli_summary_table: bool, + telemetry: bool, +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +#[allow(dead_code)] +enum Message { + TextMessage(String), + MarkdownMessage(String), +} + +impl Default for Message { + fn default() -> Self { + Message::TextMessage("".to_string()) + } +} + +#[derive(Default, Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +struct Source { + id: String, + name: String, + extractor_name: String, +} + +#[derive(Default, Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +struct Location { + file: PathBuf, + start_line: u32, + start_column: u32, + end_line: u32, + end_column: u32, +} + +#[derive(Default, Debug, Clone, Serialize)] +pub struct Diagnostics { + source: Source, + visibility: Visibility, + severity: Severity, + #[serde(flatten)] + message: Message, + timestamp: DateTime, + #[serde(skip_serializing_if = "Option::is_none")] + location: Option, + attributes: T, +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +enum ExtractionStepTarget { + LoadManifest(PathBuf), + FetchFile(PathBuf), + Parse(PathBuf), + Extract(PathBuf), +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct ExtractionStep { + #[serde(flatten)] + target: ExtractionStepTarget, + ms: u128, +} + +impl ExtractionStep { + fn new(start: Instant, target: ExtractionStepTarget) -> Self { + let ret = ExtractionStep { + target, + ms: start.elapsed().as_millis(), + }; + debug!("{ret:?}"); + ret + } + + pub fn load_manifest(start: Instant, target: &ProjectManifest) -> Self { + Self::new( + start, + ExtractionStepTarget::LoadManifest(PathBuf::from(target.manifest_path())), + ) + } + + pub fn parse(start: Instant, target: &Path) -> Self { + Self::new(start, ExtractionStepTarget::Parse(PathBuf::from(target))) + } + + pub fn extract(start: Instant, target: &Path) -> Self { + Self::new(start, ExtractionStepTarget::Extract(PathBuf::from(target))) + } + + pub fn fetch_file(start: Instant, target: &Path) -> Self { + Self::new( + start, + ExtractionStepTarget::FetchFile(PathBuf::from(target)), + ) + } +} + +#[derive(Debug, Default, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +struct HumanReadableDuration { + ms: u128, + pretty: String, +} + +impl HumanReadableDuration { + pub fn new(ms: u128) -> Self { + let seconds = ms / 1000; + let minutes = seconds / 60; + let hours = minutes / 60; + let pretty = format!( + "{hours}:{minutes:02}:{seconds:02}.{milliseconds:03}", + minutes = minutes % 60, + seconds = seconds % 60, + milliseconds = ms % 1000, + ); + Self { ms, pretty } + } +} + +impl From for HumanReadableDuration { + fn from(val: u128) -> Self { + HumanReadableDuration::new(val) + } +} + +impl Display for HumanReadableDuration { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}ms ({})", self.ms, self.pretty) + } +} + +#[derive(Debug, Default, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +struct ExtractionSummary { + number_of_manifests: usize, + number_of_files: usize, + total_load_duration: HumanReadableDuration, + total_fetch_file_duration: HumanReadableDuration, + total_parse_duration: HumanReadableDuration, + total_extract_duration: HumanReadableDuration, + total_duration: HumanReadableDuration, +} + +#[derive(Debug, Default, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +struct ExtractionAttributes { + steps: Vec, + summary: ExtractionSummary, +} + +type ExtractionDiagnostics = Diagnostics; + +fn summary(start: Instant, steps: &[ExtractionStep]) -> ExtractionSummary { + let mut number_of_manifests = 0; + let mut number_of_files = 0; + let mut total_load_duration = 0; + let mut total_parse_duration = 0; + let mut total_extract_duration = 0; + let mut total_fetch_file_duration: u128 = 0; + for step in steps { + match &step.target { + ExtractionStepTarget::LoadManifest(_) => { + number_of_manifests += 1; + total_load_duration += step.ms; + } + ExtractionStepTarget::FetchFile(_) => { + number_of_files += 1; + total_fetch_file_duration += step.ms; + } + ExtractionStepTarget::Parse(_) => { + total_parse_duration += step.ms; + } + ExtractionStepTarget::Extract(_) => { + total_extract_duration += step.ms; + } + } + } + let ret = ExtractionSummary { + number_of_manifests, + number_of_files, + total_load_duration: total_load_duration.into(), + total_fetch_file_duration: total_fetch_file_duration.into(), + total_parse_duration: total_parse_duration.into(), + total_extract_duration: total_extract_duration.into(), + total_duration: start.elapsed().as_millis().into(), + }; + info!("total loadimg duration: {}", ret.total_load_duration); + info!( + "total file fetching duration: {}", + ret.total_fetch_file_duration + ); + info!("total parsing duration: {}", ret.total_parse_duration); + info!("total extracting duration: {}", ret.total_extract_duration); + info!("total duration: {}", ret.total_duration); + ret +} + +pub fn emit_extraction_diagnostics( + start: Instant, + config: &Config, + steps: Vec, +) -> anyhow::Result<()> { + let summary = summary(start, &steps); + let diagnostics = ExtractionDiagnostics { + source: Source { + id: "rust/extractor/telemetry".to_owned(), + name: "telemetry".to_string(), + extractor_name: "rust".to_string(), + }, + visibility: Visibility { + telemetry: true, + ..Default::default() + }, + timestamp: Utc::now(), + attributes: ExtractionAttributes { steps, summary }, + ..Default::default() + }; + + std::fs::create_dir_all(&config.diagnostic_dir).with_context(|| { + format!( + "creating diagnostics directory {}", + config.diagnostic_dir.display() + ) + })?; + let target = config.diagnostic_dir.join("extraction.jsonc"); + let mut output = File::create(&target) + .with_context(|| format!("creating diagnostics file {}", target.display()))?; + serde_json::to_writer_pretty(&mut output, &diagnostics) + .with_context(|| format!("writing to diagnostics file {}", target.display()))?; + Ok(()) +} diff --git a/rust/extractor/src/main.rs b/rust/extractor/src/main.rs index ecbdc965f8e..f00e94e9ba4 100644 --- a/rust/extractor/src/main.rs +++ b/rust/extractor/src/main.rs @@ -1,3 +1,4 @@ +use crate::diagnostics::{emit_extraction_diagnostics, ExtractionStep}; use crate::rust_analyzer::path_to_file_id; use anyhow::Context; use archive::Archiver; @@ -5,9 +6,10 @@ use log::info; use ra_ap_hir::Semantics; use ra_ap_ide_db::line_index::{LineCol, LineIndex}; use ra_ap_ide_db::RootDatabase; -use ra_ap_project_model::ProjectManifest; +use ra_ap_project_model::{CargoConfig, ProjectManifest}; use ra_ap_vfs::Vfs; use rust_analyzer::{ParseResult, RustAnalyzer}; +use std::time::Instant; use std::{ collections::HashMap, path::{Path, PathBuf}, @@ -15,6 +17,7 @@ use std::{ mod archive; mod config; +mod diagnostics; pub mod generated; mod qltest; mod rust_analyzer; @@ -24,18 +27,31 @@ pub mod trap; struct Extractor<'a> { archiver: &'a Archiver, traps: &'a trap::TrapFileProvider, + steps: Vec, } -impl Extractor<'_> { - fn extract(&self, rust_analyzer: &rust_analyzer::RustAnalyzer, file: &std::path::Path) { +impl<'a> Extractor<'a> { + pub fn new(archiver: &'a Archiver, traps: &'a trap::TrapFileProvider) -> Self { + Self { + archiver, + traps, + steps: Vec::new(), + } + } + + fn extract(&mut self, rust_analyzer: &rust_analyzer::RustAnalyzer, file: &std::path::Path) { self.archiver.archive(file); + let before_parse = Instant::now(); let ParseResult { ast, text, errors, semantics_info, } = rust_analyzer.parse(file); + self.steps.push(ExtractionStep::parse(before_parse, file)); + + let before_extract = Instant::now(); let line_index = LineIndex::new(text.as_ref()); let display_path = file.to_string_lossy(); let mut trap = self.traps.create("source", file); @@ -73,22 +89,63 @@ impl Extractor<'_> { err.to_string() ) }); + self.steps + .push(ExtractionStep::extract(before_extract, file)); } pub fn extract_with_semantics( - &self, + &mut self, file: &Path, semantics: &Semantics<'_, RootDatabase>, vfs: &Vfs, ) { self.extract(&RustAnalyzer::new(vfs, semantics), file); } - pub fn extract_without_semantics(&self, file: &Path, reason: &str) { + + pub fn extract_without_semantics(&mut self, file: &Path, reason: &str) { self.extract(&RustAnalyzer::WithoutSemantics { reason }, file); } + + pub fn load_manifest( + &mut self, + project: &ProjectManifest, + config: &CargoConfig, + ) -> Option<(RootDatabase, Vfs)> { + let before = Instant::now(); + let ret = RustAnalyzer::load_workspace(project, config); + self.steps + .push(ExtractionStep::load_manifest(before, project)); + ret + } + + pub fn fetch_file( + &mut self, + file: &Path, + semantics: &Semantics<'_, RootDatabase>, + vfs: &Vfs, + ) -> Result<(), String> { + let before = Instant::now(); + let Some(id) = path_to_file_id(file, vfs) else { + return Err("not included in files loaded from manifest".to_string()); + }; + if semantics.file_to_module_def(id).is_none() { + return Err("not included as a module".to_string()); + } + self.steps.push(ExtractionStep::fetch_file(before, file)); + Ok(()) + } + + pub fn emit_extraction_diagnostics( + self, + start: Instant, + cfg: &config::Config, + ) -> anyhow::Result<()> { + emit_extraction_diagnostics(start, cfg, self.steps) + } } fn main() -> anyhow::Result<()> { + let start = Instant::now(); let mut cfg = config::Config::extract().context("failed to load configuration")?; stderrlog::new() .module(module_path!()) @@ -103,10 +160,7 @@ fn main() -> anyhow::Result<()> { let archiver = archive::Archiver { root: cfg.source_archive_dir.clone(), }; - let extractor = Extractor { - archiver: &archiver, - traps: &traps, - }; + let mut extractor = Extractor::new(&archiver, &traps); let files: Vec = cfg .inputs .iter() @@ -132,21 +186,13 @@ fn main() -> anyhow::Result<()> { } let cargo_config = cfg.to_cargo_config(); for (manifest, files) in map.values().filter(|(_, files)| !files.is_empty()) { - if let Some((ref db, ref vfs)) = RustAnalyzer::load_workspace(manifest, &cargo_config) { + if let Some((ref db, ref vfs)) = extractor.load_manifest(manifest, &cargo_config) { let semantics = Semantics::new(db); for file in files { - let Some(id) = path_to_file_id(file, vfs) else { - extractor.extract_without_semantics( - file, - "not included in files loaded from manifest", - ); - continue; + match extractor.fetch_file(file, &semantics, vfs) { + Ok(()) => extractor.extract_with_semantics(file, &semantics, vfs), + Err(reason) => extractor.extract_without_semantics(file, &reason), }; - if semantics.file_to_module_def(id).is_none() { - extractor.extract_without_semantics(file, "not included as a module"); - continue; - } - extractor.extract_with_semantics(file, &semantics, vfs); } } else { for file in files { @@ -155,5 +201,5 @@ fn main() -> anyhow::Result<()> { } } - Ok(()) + extractor.emit_extraction_diagnostics(start, &cfg) } diff --git a/rust/ql/integration-tests/conftest.py b/rust/ql/integration-tests/conftest.py index 08b17f106f8..9967339f2d2 100644 --- a/rust/ql/integration-tests/conftest.py +++ b/rust/ql/integration-tests/conftest.py @@ -13,3 +13,12 @@ class _Manifests: @pytest.fixture def manifests(cwd): return _Manifests(cwd) + +@pytest.fixture +def rust_check_diagnostics(check_diagnostics): + check_diagnostics.replacements += [ + (r'"ms"\s*:\s*[0-9]+', '"ms": "REDACTED"'), + (r'"pretty"\s*:\s*"[0-9]+:[0-9]{2}:[0-9]{2}.[0-9]{3}"', '"pretty": "REDACTED"'), + (r'Cargo.toml|rust-project.json', ""), + ] + return check_diagnostics diff --git a/rust/ql/integration-tests/hello-project/diagnostics.expected b/rust/ql/integration-tests/hello-project/diagnostics.expected new file mode 100644 index 00000000000..165fd263990 --- /dev/null +++ b/rust/ql/integration-tests/hello-project/diagnostics.expected @@ -0,0 +1,101 @@ +{ + "attributes": { + "steps": [ + { + "loadManifest": "/", + "ms": "REDACTED" + }, + { + "fetchFile": "/src/directory_module/mod.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/src/directory_module/mod.rs" + }, + { + "extract": "/src/directory_module/mod.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/src/directory_module/nested_module.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/src/directory_module/nested_module.rs" + }, + { + "extract": "/src/directory_module/nested_module.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/src/directory_module/not_loaded.rs" + }, + { + "extract": "/src/directory_module/not_loaded.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/src/file_module.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/src/file_module.rs" + }, + { + "extract": "/src/file_module.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/src/main.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/src/main.rs" + }, + { + "extract": "/src/main.rs", + "ms": "REDACTED" + } + ], + "summary": { + "numberOfFiles": 4, + "numberOfManifests": 1, + "totalDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalExtractDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalFetchFileDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalLoadDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalParseDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + } + } + }, + "severity": "note", + "source": { + "extractorName": "rust", + "id": "rust/extractor/telemetry", + "name": "telemetry" + }, + "visibility": { + "cliSummaryTable": false, + "statusPage": false, + "telemetry": true + } +} diff --git a/rust/ql/integration-tests/hello-project/test_project.py b/rust/ql/integration-tests/hello-project/test_project.py index d03c4f67e26..2cbac0ffdb8 100644 --- a/rust/ql/integration-tests/hello-project/test_project.py +++ b/rust/ql/integration-tests/hello-project/test_project.py @@ -1,7 +1,7 @@ -def test_cargo(codeql, rust, manifests, check_source_archive): +def test_cargo(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): manifests.select("Cargo.toml") codeql.database.create() -def test_rust_project(codeql, rust, manifests, check_source_archive): +def test_rust_project(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): manifests.select("rust-project.json") codeql.database.create() diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected new file mode 100644 index 00000000000..42e7859a4e8 --- /dev/null +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected @@ -0,0 +1,97 @@ +{ + "attributes": { + "steps": [ + { + "loadManifest": "/lib/", + "ms": "REDACTED" + }, + { + "fetchFile": "/lib/src/a_module/mod.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/lib/src/a_module/mod.rs" + }, + { + "extract": "/lib/src/a_module/mod.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/lib/src/lib.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/lib/src/lib.rs" + }, + { + "extract": "/lib/src/lib.rs", + "ms": "REDACTED" + }, + { + "loadManifest": "/exe/", + "ms": "REDACTED" + }, + { + "fetchFile": "/exe/src/a_module.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/exe/src/a_module.rs" + }, + { + "extract": "/exe/src/a_module.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/exe/src/main.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/exe/src/main.rs" + }, + { + "extract": "/exe/src/main.rs", + "ms": "REDACTED" + } + ], + "summary": { + "numberOfFiles": 4, + "numberOfManifests": 2, + "totalDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalExtractDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalFetchFileDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalLoadDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalParseDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + } + } + }, + "severity": "note", + "source": { + "extractorName": "rust", + "id": "rust/extractor/telemetry", + "name": "telemetry" + }, + "visibility": { + "cliSummaryTable": false, + "statusPage": false, + "telemetry": true + } +} diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected new file mode 100644 index 00000000000..7df7b52cdee --- /dev/null +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected @@ -0,0 +1,93 @@ +{ + "attributes": { + "steps": [ + { + "loadManifest": "/", + "ms": "REDACTED" + }, + { + "fetchFile": "/exe/src/a_module.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/exe/src/a_module.rs" + }, + { + "extract": "/exe/src/a_module.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/exe/src/main.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/exe/src/main.rs" + }, + { + "extract": "/exe/src/main.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/lib/src/a_module/mod.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/lib/src/a_module/mod.rs" + }, + { + "extract": "/lib/src/a_module/mod.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/lib/src/lib.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/lib/src/lib.rs" + }, + { + "extract": "/lib/src/lib.rs", + "ms": "REDACTED" + } + ], + "summary": { + "numberOfFiles": 4, + "numberOfManifests": 1, + "totalDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalExtractDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalFetchFileDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalLoadDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalParseDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + } + } + }, + "severity": "note", + "source": { + "extractorName": "rust", + "id": "rust/extractor/telemetry", + "name": "telemetry" + }, + "visibility": { + "cliSummaryTable": false, + "statusPage": false, + "telemetry": true + } +} diff --git a/rust/ql/integration-tests/hello-workspace/test_workspace.py b/rust/ql/integration-tests/hello-workspace/test_workspace.py index f3503e7cefa..5c95031466f 100644 --- a/rust/ql/integration-tests/hello-workspace/test_workspace.py +++ b/rust/ql/integration-tests/hello-workspace/test_workspace.py @@ -3,10 +3,12 @@ import pytest # currently the DB-check fails on actions because of loading files multiple times and assiging multiple locations # see https://github.com/github/codeql-team/issues/3365 @pytest.mark.ql_test("DB-CHECK", xfail="maybe") -def test_cargo(codeql, rust, manifests, check_source_archive): +def test_cargo(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): + rust_check_diagnostics.expected_suffix = ".cargo.expected" manifests.select("Cargo.toml") codeql.database.create() -def test_rust_project(codeql, rust, manifests, check_source_archive): +def test_rust_project(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): + rust_check_diagnostics.expected_suffix = ".rust-project.expected" manifests.select("rust-project.json") codeql.database.create() From d779ae5c3e97f8d9ec71c4cc901fba73071997b5 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 26 Nov 2024 15:39:15 +0000 Subject: [PATCH 282/470] Python: Add change note for CFG pruning fix ... And also bump the extractor version. --- python/extractor/semmle/util.py | 2 +- .../ql/lib/change-notes/2024-11-26-fix-match-cfg-pruning.md | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 python/ql/lib/change-notes/2024-11-26-fix-match-cfg-pruning.md diff --git a/python/extractor/semmle/util.py b/python/extractor/semmle/util.py index 1763d24e99e..e0720a86312 100644 --- a/python/extractor/semmle/util.py +++ b/python/extractor/semmle/util.py @@ -10,7 +10,7 @@ from io import BytesIO #Semantic version of extractor. #Update this if any changes are made -VERSION = "7.1.1" +VERSION = "7.1.2" PY_EXTENSIONS = ".py", ".pyw" diff --git a/python/ql/lib/change-notes/2024-11-26-fix-match-cfg-pruning.md b/python/ql/lib/change-notes/2024-11-26-fix-match-cfg-pruning.md new file mode 100644 index 00000000000..3ee1094c13b --- /dev/null +++ b/python/ql/lib/change-notes/2024-11-26-fix-match-cfg-pruning.md @@ -0,0 +1,5 @@ +--- +category: fix +--- + +- Fixed a problem with the control-flow graph construction, where writing `case True:` or `case False:` would cause parts of the graph to be pruned by mistake. From 8abd3c4707b527cf70e05f29eea88cb4ca608a2b Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 26 Nov 2024 16:48:49 +0100 Subject: [PATCH 283/470] Rust: Remove windows difference from diagnostics --- rust/ql/integration-tests/conftest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/ql/integration-tests/conftest.py b/rust/ql/integration-tests/conftest.py index 9967339f2d2..13cecd478d7 100644 --- a/rust/ql/integration-tests/conftest.py +++ b/rust/ql/integration-tests/conftest.py @@ -20,5 +20,6 @@ def rust_check_diagnostics(check_diagnostics): (r'"ms"\s*:\s*[0-9]+', '"ms": "REDACTED"'), (r'"pretty"\s*:\s*"[0-9]+:[0-9]{2}:[0-9]{2}.[0-9]{3}"', '"pretty": "REDACTED"'), (r'Cargo.toml|rust-project.json', ""), + (r'"//\?/', '"'), # remove windows `//?/` long path syntax ] return check_diagnostics From 556774edc7d68546ee41f7738f80f50db4502ce9 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 26 Nov 2024 18:00:15 +0100 Subject: [PATCH 284/470] Rust: do not put extraction steps in the expected diagnostics --- rust/ql/integration-tests/conftest.py | 5 +- .../hello-project/diagnostics.expected | 62 ------------------- .../diagnostics.cargo.expected | 58 ----------------- .../diagnostics.rust-project.expected | 54 ---------------- 4 files changed, 3 insertions(+), 176 deletions(-) diff --git a/rust/ql/integration-tests/conftest.py b/rust/ql/integration-tests/conftest.py index 13cecd478d7..f05b1f5c98a 100644 --- a/rust/ql/integration-tests/conftest.py +++ b/rust/ql/integration-tests/conftest.py @@ -19,7 +19,8 @@ def rust_check_diagnostics(check_diagnostics): check_diagnostics.replacements += [ (r'"ms"\s*:\s*[0-9]+', '"ms": "REDACTED"'), (r'"pretty"\s*:\s*"[0-9]+:[0-9]{2}:[0-9]{2}.[0-9]{3}"', '"pretty": "REDACTED"'), - (r'Cargo.toml|rust-project.json', ""), - (r'"//\?/', '"'), # remove windows `//?/` long path syntax + ] + check_diagnostics.skip += [ + "attributes.steps", # the order of the steps is not stable ] return check_diagnostics diff --git a/rust/ql/integration-tests/hello-project/diagnostics.expected b/rust/ql/integration-tests/hello-project/diagnostics.expected index 165fd263990..1c46a0a9f99 100644 --- a/rust/ql/integration-tests/hello-project/diagnostics.expected +++ b/rust/ql/integration-tests/hello-project/diagnostics.expected @@ -1,67 +1,5 @@ { "attributes": { - "steps": [ - { - "loadManifest": "/", - "ms": "REDACTED" - }, - { - "fetchFile": "/src/directory_module/mod.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/src/directory_module/mod.rs" - }, - { - "extract": "/src/directory_module/mod.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/src/directory_module/nested_module.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/src/directory_module/nested_module.rs" - }, - { - "extract": "/src/directory_module/nested_module.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/src/directory_module/not_loaded.rs" - }, - { - "extract": "/src/directory_module/not_loaded.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/src/file_module.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/src/file_module.rs" - }, - { - "extract": "/src/file_module.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/src/main.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/src/main.rs" - }, - { - "extract": "/src/main.rs", - "ms": "REDACTED" - } - ], "summary": { "numberOfFiles": 4, "numberOfManifests": 1, diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected index 42e7859a4e8..48ae4a51e04 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected @@ -1,63 +1,5 @@ { "attributes": { - "steps": [ - { - "loadManifest": "/lib/", - "ms": "REDACTED" - }, - { - "fetchFile": "/lib/src/a_module/mod.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/lib/src/a_module/mod.rs" - }, - { - "extract": "/lib/src/a_module/mod.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/lib/src/lib.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/lib/src/lib.rs" - }, - { - "extract": "/lib/src/lib.rs", - "ms": "REDACTED" - }, - { - "loadManifest": "/exe/", - "ms": "REDACTED" - }, - { - "fetchFile": "/exe/src/a_module.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/exe/src/a_module.rs" - }, - { - "extract": "/exe/src/a_module.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/exe/src/main.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/exe/src/main.rs" - }, - { - "extract": "/exe/src/main.rs", - "ms": "REDACTED" - } - ], "summary": { "numberOfFiles": 4, "numberOfManifests": 2, diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected index 7df7b52cdee..1c46a0a9f99 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected @@ -1,59 +1,5 @@ { "attributes": { - "steps": [ - { - "loadManifest": "/", - "ms": "REDACTED" - }, - { - "fetchFile": "/exe/src/a_module.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/exe/src/a_module.rs" - }, - { - "extract": "/exe/src/a_module.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/exe/src/main.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/exe/src/main.rs" - }, - { - "extract": "/exe/src/main.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/lib/src/a_module/mod.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/lib/src/a_module/mod.rs" - }, - { - "extract": "/lib/src/a_module/mod.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/lib/src/lib.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/lib/src/lib.rs" - }, - { - "extract": "/lib/src/lib.rs", - "ms": "REDACTED" - } - ], "summary": { "numberOfFiles": 4, "numberOfManifests": 1, From 86c7a492645a2786f15055ebfdee24793e7f229c Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Tue, 26 Nov 2024 13:12:16 -0500 Subject: [PATCH 285/470] Apply suggestions from code review Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- .../customizing-library-models-for-go.rst | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst index 5a200274f4a..c5b74ccd73a 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst @@ -98,7 +98,7 @@ The first five values identify the function (in this case a method) to be modele - The second value ``DB`` is the name of the type that the method is associated with. - The third value ``True`` is a flag that indicates whether or not the sink also applies to subtypes. This includes when the subtype embeds the given type, so that the method or field is promoted to be a method or field of the subtype. For interface methods it also includes types which implement the interface type. - The fourth value ``Prepare`` is the method name. -- The fifth value ``""`` is the method input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions or methods may have the same name and they need to be distinguished by the number and types of the arguments. +- The fifth value ``""`` is the input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions may have the same name and they need to be distinguished by the number and types of the arguments. The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the sink. @@ -139,7 +139,7 @@ The first five values identify the function to be modeled as a source. - The second value ``Request`` is the type name, since the function is a method of the ``Request`` type. - The third value ``True`` is a flag that indicates whether or not the sink also applies to subtypes. This includes when the subtype embeds the given type, so that the method or field is promoted to be a method or field of the subtype. For interface methods it also includes types which implement the interface type. - The fourth value ``FormValue`` is the function name. -- The fifth value ``""`` is the function input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions or methods may have the same name and they need to be distinguished by the number and types of the arguments. +- The fifth value ``""`` is the input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions may have the same name and they need to be distinguished by the number and types of the arguments. The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the source. @@ -156,11 +156,9 @@ This pattern covers many of the cases where we need to summarize flow through a .. code-block:: go - import "slices" - func ValueFlow { a := []int{1, 2, 3} - max := slices.Max(a) // There is taint flow from `a` to `max`. + max := slices.Max(a) // There is value flow from the elements of `a` to `max`. ... } @@ -173,25 +171,23 @@ We need to add a tuple to the ``summaryModel``\(package, type, subtypes, name, s pack: codeql/go-all extensible: summaryModel data: - - ["slices", "", True, "Max", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["slices", "", False, "Max", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] Since we are adding flow through a method, we need to add tuples to the ``summaryModel`` extensible predicate. -Each tuple defines flow from one argument to the return value. The first row defines flow from the first argument (``a`` in the example) to the return value (``max`` in the example). The first five values identify the function to be modeled as a summary. -These are the same for both of the rows above as we are adding two summaries for the same method. - The first value ``slices`` is the package name. - The second value ``""`` is left blank, since the function is not a method of a type. - The third value ``False`` is a flag that indicates whether or not the sink also applies to subtypes. This has no effect for non-method functions. - The fourth value ``Max`` is the function name. -- The fifth value ``""`` is left blank, since specifying the signature is optional and Go does not allow multiple signature overloads for the same function. +- The fifth value ``""`` is the input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions may have the same name and they need to be distinguished by the number and types of the arguments. The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the summary. -- The seventh value is the access path to the input (where data flows from). ``Argument[0]`` is the access path to the first argument. +- The seventh value is the access path to the input (where data flows from). ``Argument[0].ArrayElement`` is the access path to the array elements of the first argument (the elements of the slice in the example). - The eighth value ``ReturnValue`` is the access path to the output (where data flows to), in this case ``ReturnValue``, which means that the input flows to the return value. - The ninth value ``value`` is the kind of the flow. ``value`` flow indicates an entire value is moved, ``taint`` means that taint is propagated through the call. - The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. @@ -204,8 +200,6 @@ This pattern covers many of the cases where we need to summarize flow through a .. code-block:: go - import "slices" - func ValueFlow { a := []int{1, 2, 3} b := []int{4, 5, 6} @@ -222,26 +216,24 @@ We need to add a tuple to the ``summaryModel``\(package, type, subtypes, name, s pack: codeql/go-all extensible: summaryModel data: - - ["slices", "", True, "Concat", "", "", "Argument[0].ArrayElement.ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["slices", "", False, "Concat", "", "", "Argument[0].ArrayElement.ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] Since we are adding flow through a method, we need to add tuples to the ``summaryModel`` extensible predicate. -Each tuple defines flow from one argument to the return value. -The first row defines flow from the arguments (``a`` and ``b`` in the example) to the return value (``c`` in the example) and the second row defines flow from the second argument (``sep`` in the example) to the return value (``t`` in the example). +The first row defines flow from the arguments (``a`` and ``b`` in the example) to the return value (``c`` in the example). The first five values identify the function to be modeled as a summary. -These are the same for both of the rows above as we are adding two summaries for the same method. - The first value ``slices`` is the package name. - The second value ``""`` is left blank, since the function is not a method of a type. - The third value ``False`` is a flag that indicates whether or not the sink also applies to subtypes. This has no effect for non-method functions. - The fourth value ``Max`` is the function name. -- The fifth value ``""`` is left blank, since specifying the signature is optional and Go does not allow multiple signature overloads for the same function. +- The fifth value ``""`` is the input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions may have the same name and they need to be distinguished by the number and types of the arguments. The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the summary. -- The seventh value is the access path to the input (where data flows from). ``Argument[0]`` is the access path to the first argument. -- The eighth value ``ReturnValue`` is the access path to the output (where data flows to), in this case ``ReturnValue``, which means that the input flows to the return value. +- The seventh value is the access path to the input (where data flows from). ``Argument[0].ArrayElement.ArrayElement`` is the access path to the array elements of the array elements of the first argument. Note that a variadic parameter of type `...T` is treated as if it has type `[]T` and arguments corresponding to the variadic parameter are accessed as elements of this slice. +- The eighth value ``ReturnValue.ArrayElement`` is the access path to the output (where data flows to), in this case ``ReturnValue.ArrayElement``, which means that the input flows to the array elements of the return value. - The ninth value ``value`` is the kind of the flow. ``value`` flow indicates an entire value is moved, ``taint`` means that taint is propagated through the call. - The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary. @@ -282,7 +274,7 @@ These are the same for both of the rows above as we are adding two summaries for - The second value ``""`` is left blank, since the function is not a method of a type. - The third value ``False`` is a flag that indicates whether or not the sink also applies to subtypes. This has no effect for non-method functions. - The fourth value ``Join`` is the function name. -- The fifth value ``""`` is left blank, since specifying the signature is optional and Go does not allow multiple signature overloads for the same function. +- The fifth value ``""`` is the input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions may have the same name and they need to be distinguished by the number and types of the arguments. The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the summary. @@ -337,7 +329,7 @@ The first five values identify the function (in this case a method) to be modele - The second value ``URL`` is the receiver type. - The third value ``True`` is a flag that indicates whether or not the sink also applies to subtypes. This includes when the subtype embeds the given type, so that the method or field is promoted to be a method or field of the subtype. For interface methods it also includes types which implement the interface type. - The fourth value ``Hostname`` is the method name. -- The fifth value ``""`` is left blank, since specifying the signature is optional and Go does not allow multiple signature overloads for the same function. +- The fifth value ``""`` is the input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions may have the same name and they need to be distinguished by the number and types of the arguments. The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the summary. @@ -376,7 +368,7 @@ The first five values identify the field to be modeled as a source. - The second value ``Request`` is the name of the type that the field is associated with. - The third value ``True`` is a flag that indicates whether or not the sink also applies to subtypes. For fields this means when the field is accessed as a promoted field in another type. - The fourth value ``Body`` is the field name. -- The fifth value ``""`` is blank since it is a field access and field accesses do not have method signatures in Go. +- The fifth value ``""`` is the input type signature. For Go it should always be an empty string. It is needed for other languages where multiple functions may have the same name and they need to be distinguished by the number and types of the arguments. The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the source. From 593896b40e06f09d883347c6e8c9dd4bd0000f4d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 8 Nov 2024 12:32:00 +0000 Subject: [PATCH 286/470] Add test showing promoted field bug NCField should be promoted to EmbedsNameClash. Currently it isn't because its embedded parent pkg2.NameClash is not a promoted field in EmbedsNameClash (because of a name clash with pkg1.NameClash), but this should not make a difference. --- .../semmle/go/Types/Field_getPackage.expected | 27 +++++++------ .../go/Types/Field_hasQualifiedName2.expected | 38 ++++++++++--------- .../go/Types/Field_hasQualifiedName3.expected | 38 ++++++++++--------- .../semmle/go/Types/MethodCount.expected | 4 ++ .../semmle/go/Types/MethodTypes.expected | 7 ++-- .../Types/Method_hasQualifiedName2.expected | 11 ++++-- .../Types/Method_hasQualifiedName3.expected | 11 ++++-- .../semmle/go/Types/Methods.expected | 20 ++++++---- .../semmle/go/Types/QualifiedNames.expected | 15 +++++--- .../SignatureType_getNumParameter.expected | 13 ++++--- .../Types/SignatureType_getNumResult.expected | 13 ++++--- .../semmle/go/Types/StructFields.expected | 38 ++++++++++--------- .../semmle/go/Types/Types.expected | 15 +++++--- .../library-tests/semmle/go/Types/main.go | 10 ++++- .../library-tests/semmle/go/Types/pkg1/tst.go | 6 +++ .../library-tests/semmle/go/Types/pkg2/tst.go | 6 +++ 16 files changed, 165 insertions(+), 107 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/Types/Field_getPackage.expected b/go/ql/test/library-tests/semmle/go/Types/Field_getPackage.expected index 485a42b185e..432eaf7997a 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Field_getPackage.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Field_getPackage.expected @@ -26,6 +26,7 @@ | generic.go:21:2:21:9 | mapField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | generic.go:25:2:25:12 | structField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | generic.go:29:2:29:13 | pointerField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | +| main.go:18:7:18:15 | NameClash | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | pkg1/embedding.go:19:23:19:26 | base | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | | pkg1/embedding.go:22:27:22:30 | base | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | | pkg1/embedding.go:25:24:25:31 | embedder | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | @@ -36,20 +37,22 @@ | pkg1/promotedStructs.go:14:2:14:7 | PField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | | pkg1/promotedStructs.go:22:22:22:22 | S | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | | pkg1/promotedStructs.go:25:22:25:22 | P | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:4:2:4:2 | f | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:5:2:5:4 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:6:2:6:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:10:2:10:4 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:11:2:11:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:15:3:15:5 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:16:3:16:5 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:20:3:20:5 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:21:2:21:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:25:2:25:4 | val | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:26:2:26:5 | flag | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:30:2:30:5 | flag | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:6:2:6:2 | f | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:7:2:7:4 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:8:2:8:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:12:2:12:4 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:13:2:13:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:17:3:17:5 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:18:3:18:5 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:22:3:22:5 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:23:2:23:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:27:2:27:4 | val | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:28:2:28:5 | flag | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:32:2:32:5 | flag | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:62:7:62:15 | NameClash | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | | pkg2/tst.go:4:2:4:2 | g | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | | pkg2/tst.go:8:2:8:2 | g | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | +| pkg2/tst.go:17:2:17:8 | NCField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | | struct_tags.go:4:2:4:7 | field1 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | struct_tags.go:5:2:5:7 | field2 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | struct_tags.go:9:2:9:7 | field1 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | diff --git a/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName2.expected b/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName2.expected index c8575332f6f..6d14516813d 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName2.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName2.expected @@ -33,6 +33,7 @@ | generic.go:21:2:21:9 | mapField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct2 | mapField | | generic.go:25:2:25:12 | structField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct2b | structField | | generic.go:29:2:29:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.CircularGenericStruct2 | pointerField | +| main.go:18:7:18:15 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsNameClash | NameClash | | pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder | base | | pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder2 | base | | pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder3 | base | @@ -49,27 +50,30 @@ | pkg1/promotedStructs.go:14:2:14:7 | PField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedP | PField | | pkg1/promotedStructs.go:22:22:22:22 | S | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedS | S | | pkg1/promotedStructs.go:25:22:25:22 | P | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedP | P | -| pkg1/tst.go:4:2:4:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | f | -| pkg1/tst.go:5:2:5:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | Foo | -| pkg1/tst.go:6:2:6:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | Bar | -| pkg1/tst.go:10:2:10:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | Foo | -| pkg1/tst.go:11:2:11:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | Bar | -| pkg1/tst.go:15:3:15:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | Foo | -| pkg1/tst.go:16:3:16:5 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | Bar | -| pkg1/tst.go:20:3:20:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | Foo | -| pkg1/tst.go:21:2:21:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | Bar | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | val | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | val | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | val | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | val | -| pkg1/tst.go:26:2:26:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | flag | -| pkg1/tst.go:26:2:26:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | flag | -| pkg1/tst.go:30:2:30:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Bar | flag | -| pkg1/tst.go:30:2:30:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | flag | +| pkg1/tst.go:6:2:6:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | f | +| pkg1/tst.go:7:2:7:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | Foo | +| pkg1/tst.go:8:2:8:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | Bar | +| pkg1/tst.go:12:2:12:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | Foo | +| pkg1/tst.go:13:2:13:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | Bar | +| pkg1/tst.go:17:3:17:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | Foo | +| pkg1/tst.go:18:3:18:5 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | Bar | +| pkg1/tst.go:22:3:22:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | Foo | +| pkg1/tst.go:23:2:23:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | Bar | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | val | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | val | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | val | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | val | +| pkg1/tst.go:28:2:28:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | flag | +| pkg1/tst.go:28:2:28:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | flag | +| pkg1/tst.go:32:2:32:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Bar | flag | +| pkg1/tst.go:32:2:32:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | flag | +| pkg1/tst.go:62:7:62:15 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.NameClash | NameClash | | pkg2/tst.go:4:2:4:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.G | g | | pkg2/tst.go:4:2:4:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.T | g | | pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.G | g | | pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.T | g | +| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.NameClash | NCField | +| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.NameClash | NCField | | struct_tags.go:4:2:4:7 | field1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S1 | field1 | | struct_tags.go:5:2:5:7 | field2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S1 | field2 | | struct_tags.go:9:2:9:7 | field1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S2 | field1 | diff --git a/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName3.expected b/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName3.expected index 56176082d9a..7a97a6d8405 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName3.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName3.expected @@ -33,6 +33,7 @@ | generic.go:21:2:21:9 | mapField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct2 | mapField | | generic.go:25:2:25:12 | structField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct2b | structField | | generic.go:29:2:29:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | CircularGenericStruct2 | pointerField | +| main.go:18:7:18:15 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsNameClash | NameClash | | pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder | base | | pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | base | | pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder3 | base | @@ -49,27 +50,30 @@ | pkg1/promotedStructs.go:14:2:14:7 | PField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedP | PField | | pkg1/promotedStructs.go:22:22:22:22 | S | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedS | S | | pkg1/promotedStructs.go:25:22:25:22 | P | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedP | P | -| pkg1/tst.go:4:2:4:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | f | -| pkg1/tst.go:5:2:5:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | Foo | -| pkg1/tst.go:6:2:6:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | Bar | -| pkg1/tst.go:10:2:10:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | Foo | -| pkg1/tst.go:11:2:11:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | Bar | -| pkg1/tst.go:15:3:15:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | Foo | -| pkg1/tst.go:16:3:16:5 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | Bar | -| pkg1/tst.go:20:3:20:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | Foo | -| pkg1/tst.go:21:2:21:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | Bar | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | val | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | val | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | val | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | val | -| pkg1/tst.go:26:2:26:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | flag | -| pkg1/tst.go:26:2:26:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | flag | -| pkg1/tst.go:30:2:30:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Bar | flag | -| pkg1/tst.go:30:2:30:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | flag | +| pkg1/tst.go:6:2:6:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | f | +| pkg1/tst.go:7:2:7:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | Foo | +| pkg1/tst.go:8:2:8:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | Bar | +| pkg1/tst.go:12:2:12:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | Foo | +| pkg1/tst.go:13:2:13:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | Bar | +| pkg1/tst.go:17:3:17:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | Foo | +| pkg1/tst.go:18:3:18:5 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | Bar | +| pkg1/tst.go:22:3:22:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | Foo | +| pkg1/tst.go:23:2:23:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | Bar | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | val | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | val | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | val | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | val | +| pkg1/tst.go:28:2:28:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | flag | +| pkg1/tst.go:28:2:28:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | flag | +| pkg1/tst.go:32:2:32:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Bar | flag | +| pkg1/tst.go:32:2:32:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | flag | +| pkg1/tst.go:62:7:62:15 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | NameClash | NameClash | | pkg2/tst.go:4:2:4:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | G | g | | pkg2/tst.go:4:2:4:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | T | g | | pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | G | g | | pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | T | g | +| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | NameClash | NCField | +| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | NameClash | NCField | | struct_tags.go:4:2:4:7 | field1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | S1 | field1 | | struct_tags.go:5:2:5:7 | field2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | S1 | field2 | | struct_tags.go:9:2:9:7 | field1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | S2 | field1 | diff --git a/go/ql/test/library-tests/semmle/go/Types/MethodCount.expected b/go/ql/test/library-tests/semmle/go/Types/MethodCount.expected index 9d576b0f4f6..351b29c6222 100644 --- a/go/ql/test/library-tests/semmle/go/Types/MethodCount.expected +++ b/go/ql/test/library-tests/semmle/go/Types/MethodCount.expected @@ -1,4 +1,6 @@ +| * EmbedsNameClash | 1 | | * Foo | 1 | +| * NameClash | 1 | | * P | 1 | | * S | 1 | | * SEmbedP | 1 | @@ -19,10 +21,12 @@ | AExtended | 2 | | B | 2 | | C | 2 | +| EmbedsNameClash | 1 | | Foo | 1 | | GenericInterface | 1 | | MixedExportedAndNot | 2 | | MyInterface | 17 | +| NameClash | 1 | | S | 1 | | SEmbedS | 1 | | T | 1 | diff --git a/go/ql/test/library-tests/semmle/go/Types/MethodTypes.expected b/go/ql/test/library-tests/semmle/go/Types/MethodTypes.expected index 326debd2f80..e02208761bf 100644 --- a/go/ql/test/library-tests/semmle/go/Types/MethodTypes.expected +++ b/go/ql/test/library-tests/semmle/go/Types/MethodTypes.expected @@ -51,8 +51,9 @@ | pkg1/interfaces.go:35:6:35:24 | MixedExportedAndNot | Exported | func() | | pkg1/interfaces.go:35:6:35:24 | MixedExportedAndNot | notExported | func() | | pkg1/promotedStructs.go:22:6:22:12 | SEmbedS | SMethod | func() interface { } | -| pkg1/tst.go:3:6:3:6 | T | half | func() Foo | -| pkg1/tst.go:14:6:14:7 | T3 | half | func() Foo | -| pkg1/tst.go:19:6:19:7 | T4 | half | func() Foo | +| pkg1/tst.go:5:6:5:6 | T | half | func() Foo | +| pkg1/tst.go:16:6:16:7 | T3 | half | func() Foo | +| pkg1/tst.go:21:6:21:7 | T4 | half | func() Foo | +| pkg1/tst.go:61:6:61:14 | NameClash | NCMethod | func() | | pkg2/tst.go:11:6:11:24 | MixedExportedAndNot | Exported | func() | | pkg2/tst.go:11:6:11:24 | MixedExportedAndNot | notExported | func() | diff --git a/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.expected b/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.expected index 1f893728e30..3929e1d98d5 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.expected @@ -59,9 +59,12 @@ | pkg1/promotedStructs.go:8:12:8:18 | SMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedS | SMethod | | pkg1/promotedStructs.go:17:13:17:19 | PMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.P | PMethod | | pkg1/promotedStructs.go:17:13:17:19 | PMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedP | PMethod | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | half | | pkg2/tst.go:12:2:12:9 | Exported | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.MixedExportedAndNot | Exported | | pkg2/tst.go:13:2:13:12 | notExported | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.MixedExportedAndNot | notExported | +| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsNameClash | NCMethod | +| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.NameClash | NCMethod | +| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.NameClash | NCMethod | diff --git a/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName3.expected b/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName3.expected index 59a298e4b5f..9699ba3f382 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName3.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName3.expected @@ -59,9 +59,12 @@ | pkg1/promotedStructs.go:8:12:8:18 | SMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedS | SMethod | | pkg1/promotedStructs.go:17:13:17:19 | PMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | P | PMethod | | pkg1/promotedStructs.go:17:13:17:19 | PMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedP | PMethod | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | half | | pkg2/tst.go:12:2:12:9 | Exported | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | MixedExportedAndNot | Exported | | pkg2/tst.go:13:2:13:12 | notExported | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | MixedExportedAndNot | notExported | +| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsNameClash | NCMethod | +| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | NameClash | NCMethod | +| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | NameClash | NCMethod | diff --git a/go/ql/test/library-tests/semmle/go/Types/Methods.expected b/go/ql/test/library-tests/semmle/go/Types/Methods.expected index 2c17013c186..c75b336543a 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Methods.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Methods.expected @@ -1,11 +1,13 @@ -| * Foo | half | pkg1/tst.go:33:16:33:19 | half | +| * EmbedsNameClash | NCMethod | pkg2/tst.go:20:20:20:27 | NCMethod | +| * Foo | half | pkg1/tst.go:35:16:35:19 | half | +| * NameClash | NCMethod | pkg2/tst.go:20:20:20:27 | NCMethod | | * P | PMethod | pkg1/promotedStructs.go:17:13:17:19 | PMethod | | * S | SMethod | pkg1/promotedStructs.go:8:12:8:18 | SMethod | | * SEmbedP | PMethod | pkg1/promotedStructs.go:17:13:17:19 | PMethod | | * SEmbedS | SMethod | pkg1/promotedStructs.go:8:12:8:18 | SMethod | -| * T | half | pkg1/tst.go:33:16:33:19 | half | -| * T3 | half | pkg1/tst.go:33:16:33:19 | half | -| * T4 | half | pkg1/tst.go:33:16:33:19 | half | +| * T | half | pkg1/tst.go:35:16:35:19 | half | +| * T3 | half | pkg1/tst.go:35:16:35:19 | half | +| * T4 | half | pkg1/tst.go:35:16:35:19 | half | | * base | f | pkg1/embedding.go:10:13:10:13 | f | | * base | g | pkg1/embedding.go:14:14:14:14 | g | | * embedder | f | pkg1/embedding.go:10:13:10:13 | f | @@ -29,7 +31,8 @@ | B | n | pkg1/interfaces.go:9:2:9:2 | n | | C | n | pkg1/interfaces.go:13:2:13:2 | n | | C | o | pkg1/interfaces.go:14:2:14:2 | o | -| Foo | half | pkg1/tst.go:33:16:33:19 | half | +| EmbedsNameClash | NCMethod | pkg2/tst.go:20:20:20:27 | NCMethod | +| Foo | half | pkg1/tst.go:35:16:35:19 | half | | GenericInterface | GetT | generic.go:33:2:33:5 | GetT | | MixedExportedAndNot | Exported | pkg1/interfaces.go:36:2:36:9 | Exported | | MixedExportedAndNot | Exported | pkg2/tst.go:12:2:12:9 | Exported | @@ -52,11 +55,12 @@ | MyInterface | dummy18 | generic.go:62:2:62:8 | dummy18 | | MyInterface | dummy19 | generic.go:63:2:63:8 | dummy19 | | MyInterface | dummy20 | generic.go:64:2:64:8 | dummy20 | +| NameClash | NCMethod | pkg2/tst.go:20:20:20:27 | NCMethod | | S | SMethod | pkg1/promotedStructs.go:8:12:8:18 | SMethod | | SEmbedS | SMethod | pkg1/promotedStructs.go:8:12:8:18 | SMethod | -| T | half | pkg1/tst.go:33:16:33:19 | half | -| T3 | half | pkg1/tst.go:33:16:33:19 | half | -| T4 | half | pkg1/tst.go:33:16:33:19 | half | +| T | half | pkg1/tst.go:35:16:35:19 | half | +| T3 | half | pkg1/tst.go:35:16:35:19 | half | +| T4 | half | pkg1/tst.go:35:16:35:19 | half | | base | f | pkg1/embedding.go:10:13:10:13 | f | | embedder | f | pkg1/embedding.go:10:13:10:13 | f | | embedder2 | f | pkg1/embedding.go:10:13:10:13 | f | diff --git a/go/ql/test/library-tests/semmle/go/Types/QualifiedNames.expected b/go/ql/test/library-tests/semmle/go/Types/QualifiedNames.expected index 660209effbb..53e16bdef63 100644 --- a/go/ql/test/library-tests/semmle/go/Types/QualifiedNames.expected +++ b/go/ql/test/library-tests/semmle/go/Types/QualifiedNames.expected @@ -77,6 +77,7 @@ | interface.go:136:6:136:21 | testComparable21 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable21 | | interface.go:137:6:137:21 | testComparable22 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable22 | | interface.go:138:6:138:21 | testComparable23 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable23 | +| main.go:17:6:17:20 | EmbedsNameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsNameClash | | pkg1/embedding.go:8:6:8:9 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.base | | pkg1/embedding.go:19:6:19:13 | embedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder | | pkg1/embedding.go:22:6:22:16 | ptrembedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.ptrembedder | @@ -95,14 +96,16 @@ | pkg1/promotedStructs.go:13:6:13:6 | P | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.P | | pkg1/promotedStructs.go:22:6:22:12 | SEmbedS | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedS | | pkg1/promotedStructs.go:25:6:25:12 | SEmbedP | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedP | -| pkg1/tst.go:3:6:3:6 | T | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | -| pkg1/tst.go:9:6:9:7 | T2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | -| pkg1/tst.go:14:6:14:7 | T3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | -| pkg1/tst.go:19:6:19:7 | T4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | -| pkg1/tst.go:24:6:24:8 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | -| pkg1/tst.go:29:6:29:8 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Bar | +| pkg1/tst.go:5:6:5:6 | T | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | +| pkg1/tst.go:11:6:11:7 | T2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | +| pkg1/tst.go:16:6:16:7 | T3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | +| pkg1/tst.go:21:6:21:7 | T4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | +| pkg1/tst.go:26:6:26:8 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | +| pkg1/tst.go:31:6:31:8 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Bar | +| pkg1/tst.go:61:6:61:14 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.NameClash | | pkg2/tst.go:3:6:3:6 | T | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.T | | pkg2/tst.go:7:6:7:6 | G | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.G | | pkg2/tst.go:11:6:11:24 | MixedExportedAndNot | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.MixedExportedAndNot | +| pkg2/tst.go:16:6:16:14 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.NameClash | | struct_tags.go:3:6:3:7 | S1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S1 | | struct_tags.go:8:6:8:7 | S2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S2 | diff --git a/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumParameter.expected b/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumParameter.expected index faedd5aa0de..5831152884b 100644 --- a/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumParameter.expected +++ b/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumParameter.expected @@ -4,18 +4,19 @@ | depth.go:22:1:25:1 | function declaration | 0 | | generic.go:70:1:72:1 | function declaration | 1 | | generic.go:74:1:80:1 | function declaration | 1 | -| main.go:5:1:5:30 | function declaration | 1 | -| main.go:7:1:9:1 | function declaration | 2 | -| main.go:11:1:11:14 | function declaration | 0 | +| main.go:9:1:9:30 | function declaration | 1 | +| main.go:11:1:13:1 | function declaration | 2 | +| main.go:15:1:15:14 | function declaration | 0 | | pkg1/embedding.go:10:1:12:1 | function declaration | 0 | | pkg1/embedding.go:14:1:16:1 | function declaration | 0 | | pkg1/embedding.go:30:1:32:1 | function declaration | 0 | | pkg1/embedding.go:40:1:61:1 | function declaration | 0 | | pkg1/promotedStructs.go:8:1:10:1 | function declaration | 0 | | pkg1/promotedStructs.go:17:1:19:1 | function declaration | 0 | -| pkg1/tst.go:33:1:35:1 | function declaration | 0 | -| pkg1/tst.go:37:1:37:26 | function declaration | 1 | -| pkg1/tst.go:39:1:57:1 | function declaration | 2 | +| pkg1/tst.go:35:1:37:1 | function declaration | 0 | +| pkg1/tst.go:39:1:39:26 | function declaration | 1 | +| pkg1/tst.go:41:1:59:1 | function declaration | 2 | +| pkg2/tst.go:20:1:20:32 | function declaration | 0 | | promoted.go:7:1:10:1 | function declaration | 1 | | promoted.go:12:1:15:1 | function declaration | 1 | | promoted.go:17:1:20:1 | function declaration | 1 | diff --git a/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumResult.expected b/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumResult.expected index 513ad56bd3c..960a272f73c 100644 --- a/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumResult.expected +++ b/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumResult.expected @@ -4,18 +4,19 @@ | depth.go:22:1:25:1 | function declaration | 0 | | generic.go:70:1:72:1 | function declaration | 1 | | generic.go:74:1:80:1 | function declaration | 0 | -| main.go:5:1:5:30 | function declaration | 0 | -| main.go:7:1:9:1 | function declaration | 2 | -| main.go:11:1:11:14 | function declaration | 0 | +| main.go:9:1:9:30 | function declaration | 0 | +| main.go:11:1:13:1 | function declaration | 2 | +| main.go:15:1:15:14 | function declaration | 0 | | pkg1/embedding.go:10:1:12:1 | function declaration | 1 | | pkg1/embedding.go:14:1:16:1 | function declaration | 1 | | pkg1/embedding.go:30:1:32:1 | function declaration | 1 | | pkg1/embedding.go:40:1:61:1 | function declaration | 0 | | pkg1/promotedStructs.go:8:1:10:1 | function declaration | 1 | | pkg1/promotedStructs.go:17:1:19:1 | function declaration | 1 | -| pkg1/tst.go:33:1:35:1 | function declaration | 1 | -| pkg1/tst.go:37:1:37:26 | function declaration | 0 | -| pkg1/tst.go:39:1:57:1 | function declaration | 0 | +| pkg1/tst.go:35:1:37:1 | function declaration | 1 | +| pkg1/tst.go:39:1:39:26 | function declaration | 0 | +| pkg1/tst.go:41:1:59:1 | function declaration | 0 | +| pkg2/tst.go:20:1:20:32 | function declaration | 0 | | promoted.go:7:1:10:1 | function declaration | 0 | | promoted.go:12:1:15:1 | function declaration | 0 | | promoted.go:17:1:20:1 | function declaration | 0 | diff --git a/go/ql/test/library-tests/semmle/go/Types/StructFields.expected b/go/ql/test/library-tests/semmle/go/Types/StructFields.expected index 502b4fa07ad..bafbc2afd09 100644 --- a/go/ql/test/library-tests/semmle/go/Types/StructFields.expected +++ b/go/ql/test/library-tests/semmle/go/Types/StructFields.expected @@ -33,6 +33,7 @@ | generic.go:19:6:19:19 | GenericStruct2 | generic.go:19:42:22:1 | struct type | structField | GenericStruct1 | | generic.go:24:6:24:20 | GenericStruct2b | generic.go:24:39:26:1 | struct type | structField | GenericStruct2 | | generic.go:28:6:28:27 | CircularGenericStruct2 | generic.go:28:39:30:1 | struct type | pointerField | * CircularGenericStruct2 | +| main.go:17:6:17:20 | EmbedsNameClash | main.go:17:22:19:1 | struct type | NameClash | NameClash | | pkg1/embedding.go:19:6:19:13 | embedder | pkg1/embedding.go:19:15:19:28 | struct type | base | base | | pkg1/embedding.go:22:6:22:16 | ptrembedder | pkg1/embedding.go:22:18:22:32 | struct type | base | * base | | pkg1/embedding.go:25:6:25:14 | embedder2 | pkg1/embedding.go:25:16:25:33 | struct type | base | base | @@ -51,27 +52,30 @@ | pkg1/promotedStructs.go:22:6:22:12 | SEmbedS | pkg1/promotedStructs.go:22:14:22:24 | struct type | SField | string | | pkg1/promotedStructs.go:25:6:25:12 | SEmbedP | pkg1/promotedStructs.go:25:14:25:24 | struct type | P | P | | pkg1/promotedStructs.go:25:6:25:12 | SEmbedP | pkg1/promotedStructs.go:25:14:25:24 | struct type | PField | string | -| pkg1/tst.go:3:6:3:6 | T | pkg1/tst.go:3:8:7:1 | struct type | Bar | Bar | -| pkg1/tst.go:3:6:3:6 | T | pkg1/tst.go:3:8:7:1 | struct type | Foo | Foo | -| pkg1/tst.go:3:6:3:6 | T | pkg1/tst.go:3:8:7:1 | struct type | f | int | -| pkg1/tst.go:3:6:3:6 | T | pkg1/tst.go:3:8:7:1 | struct type | val | int | -| pkg1/tst.go:9:6:9:7 | T2 | pkg1/tst.go:9:9:12:1 | struct type | Bar | Bar | -| pkg1/tst.go:9:6:9:7 | T2 | pkg1/tst.go:9:9:12:1 | struct type | Foo | Foo | -| pkg1/tst.go:9:6:9:7 | T2 | pkg1/tst.go:9:9:12:1 | struct type | flag | bool | -| pkg1/tst.go:14:6:14:7 | T3 | pkg1/tst.go:14:9:17:1 | struct type | Bar | * Bar | -| pkg1/tst.go:14:6:14:7 | T3 | pkg1/tst.go:14:9:17:1 | struct type | Foo | * Foo | -| pkg1/tst.go:14:6:14:7 | T3 | pkg1/tst.go:14:9:17:1 | struct type | val | int | -| pkg1/tst.go:19:6:19:7 | T4 | pkg1/tst.go:19:9:22:1 | struct type | Bar | Bar | -| pkg1/tst.go:19:6:19:7 | T4 | pkg1/tst.go:19:9:22:1 | struct type | Foo | * Foo | -| pkg1/tst.go:19:6:19:7 | T4 | pkg1/tst.go:19:9:22:1 | struct type | flag | bool | -| pkg1/tst.go:19:6:19:7 | T4 | pkg1/tst.go:19:9:22:1 | struct type | val | int | -| pkg1/tst.go:24:6:24:8 | Foo | pkg1/tst.go:24:10:27:1 | struct type | flag | bool | -| pkg1/tst.go:24:6:24:8 | Foo | pkg1/tst.go:24:10:27:1 | struct type | val | int | -| pkg1/tst.go:29:6:29:8 | Bar | pkg1/tst.go:29:10:31:1 | struct type | flag | bool | +| pkg1/tst.go:5:6:5:6 | T | pkg1/tst.go:5:8:9:1 | struct type | Bar | Bar | +| pkg1/tst.go:5:6:5:6 | T | pkg1/tst.go:5:8:9:1 | struct type | Foo | Foo | +| pkg1/tst.go:5:6:5:6 | T | pkg1/tst.go:5:8:9:1 | struct type | f | int | +| pkg1/tst.go:5:6:5:6 | T | pkg1/tst.go:5:8:9:1 | struct type | val | int | +| pkg1/tst.go:11:6:11:7 | T2 | pkg1/tst.go:11:9:14:1 | struct type | Bar | Bar | +| pkg1/tst.go:11:6:11:7 | T2 | pkg1/tst.go:11:9:14:1 | struct type | Foo | Foo | +| pkg1/tst.go:11:6:11:7 | T2 | pkg1/tst.go:11:9:14:1 | struct type | flag | bool | +| pkg1/tst.go:16:6:16:7 | T3 | pkg1/tst.go:16:9:19:1 | struct type | Bar | * Bar | +| pkg1/tst.go:16:6:16:7 | T3 | pkg1/tst.go:16:9:19:1 | struct type | Foo | * Foo | +| pkg1/tst.go:16:6:16:7 | T3 | pkg1/tst.go:16:9:19:1 | struct type | val | int | +| pkg1/tst.go:21:6:21:7 | T4 | pkg1/tst.go:21:9:24:1 | struct type | Bar | Bar | +| pkg1/tst.go:21:6:21:7 | T4 | pkg1/tst.go:21:9:24:1 | struct type | Foo | * Foo | +| pkg1/tst.go:21:6:21:7 | T4 | pkg1/tst.go:21:9:24:1 | struct type | flag | bool | +| pkg1/tst.go:21:6:21:7 | T4 | pkg1/tst.go:21:9:24:1 | struct type | val | int | +| pkg1/tst.go:26:6:26:8 | Foo | pkg1/tst.go:26:10:29:1 | struct type | flag | bool | +| pkg1/tst.go:26:6:26:8 | Foo | pkg1/tst.go:26:10:29:1 | struct type | val | int | +| pkg1/tst.go:31:6:31:8 | Bar | pkg1/tst.go:31:10:33:1 | struct type | flag | bool | +| pkg1/tst.go:61:6:61:14 | NameClash | pkg1/tst.go:61:16:63:1 | struct type | NCField | string | +| pkg1/tst.go:61:6:61:14 | NameClash | pkg1/tst.go:61:16:63:1 | struct type | NameClash | NameClash | | pkg2/tst.go:3:6:3:6 | T | pkg2/tst.go:3:8:5:1 | struct type | g | int | | pkg2/tst.go:3:6:3:6 | T | pkg2/tst.go:7:8:9:1 | struct type | g | int | | pkg2/tst.go:7:6:7:6 | G | pkg2/tst.go:3:8:5:1 | struct type | g | int | | pkg2/tst.go:7:6:7:6 | G | pkg2/tst.go:7:8:9:1 | struct type | g | int | +| pkg2/tst.go:16:6:16:14 | NameClash | pkg2/tst.go:16:16:18:1 | struct type | NCField | string | | struct_tags.go:3:6:3:7 | S1 | struct_tags.go:3:9:6:1 | struct type | field1 | int | | struct_tags.go:3:6:3:7 | S1 | struct_tags.go:3:9:6:1 | struct type | field2 | int | | struct_tags.go:8:6:8:7 | S2 | struct_tags.go:8:9:11:1 | struct type | field1 | int | diff --git a/go/ql/test/library-tests/semmle/go/Types/Types.expected b/go/ql/test/library-tests/semmle/go/Types/Types.expected index 9c04442d7aa..b18388cc31f 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Types.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Types.expected @@ -77,6 +77,7 @@ | interface.go:136:6:136:21 | testComparable21 | testComparable21 | | interface.go:137:6:137:21 | testComparable22 | testComparable22 | | interface.go:138:6:138:21 | testComparable23 | testComparable23 | +| main.go:17:6:17:20 | EmbedsNameClash | EmbedsNameClash | | pkg1/embedding.go:8:6:8:9 | base | base | | pkg1/embedding.go:19:6:19:13 | embedder | embedder | | pkg1/embedding.go:22:6:22:16 | ptrembedder | ptrembedder | @@ -95,14 +96,16 @@ | pkg1/promotedStructs.go:13:6:13:6 | P | P | | pkg1/promotedStructs.go:22:6:22:12 | SEmbedS | SEmbedS | | pkg1/promotedStructs.go:25:6:25:12 | SEmbedP | SEmbedP | -| pkg1/tst.go:3:6:3:6 | T | T | -| pkg1/tst.go:9:6:9:7 | T2 | T2 | -| pkg1/tst.go:14:6:14:7 | T3 | T3 | -| pkg1/tst.go:19:6:19:7 | T4 | T4 | -| pkg1/tst.go:24:6:24:8 | Foo | Foo | -| pkg1/tst.go:29:6:29:8 | Bar | Bar | +| pkg1/tst.go:5:6:5:6 | T | T | +| pkg1/tst.go:11:6:11:7 | T2 | T2 | +| pkg1/tst.go:16:6:16:7 | T3 | T3 | +| pkg1/tst.go:21:6:21:7 | T4 | T4 | +| pkg1/tst.go:26:6:26:8 | Foo | Foo | +| pkg1/tst.go:31:6:31:8 | Bar | Bar | +| pkg1/tst.go:61:6:61:14 | NameClash | NameClash | | pkg2/tst.go:3:6:3:6 | T | T | | pkg2/tst.go:7:6:7:6 | G | G | | pkg2/tst.go:11:6:11:24 | MixedExportedAndNot | MixedExportedAndNot | +| pkg2/tst.go:16:6:16:14 | NameClash | NameClash | | struct_tags.go:3:6:3:7 | S1 | S1 | | struct_tags.go:8:6:8:7 | S2 | S2 | diff --git a/go/ql/test/library-tests/semmle/go/Types/main.go b/go/ql/test/library-tests/semmle/go/Types/main.go index 1c7e1684725..de11cbd152f 100644 --- a/go/ql/test/library-tests/semmle/go/Types/main.go +++ b/go/ql/test/library-tests/semmle/go/Types/main.go @@ -1,6 +1,10 @@ package main -import "regexp" +import ( + "regexp" + + "github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1" +) func test(r *regexp.Regexp) {} @@ -9,3 +13,7 @@ func swap(x int, y int) (int, int) { } func main() {} + +type EmbedsNameClash struct { + pkg1.NameClash +} diff --git a/go/ql/test/library-tests/semmle/go/Types/pkg1/tst.go b/go/ql/test/library-tests/semmle/go/Types/pkg1/tst.go index 1b1920ff33a..598e711ff2c 100644 --- a/go/ql/test/library-tests/semmle/go/Types/pkg1/tst.go +++ b/go/ql/test/library-tests/semmle/go/Types/pkg1/tst.go @@ -1,5 +1,7 @@ package pkg1 +import "github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2" + type T struct { f int Foo @@ -55,3 +57,7 @@ func test(t T, t2 T2) { // methods of T2 // illegal: t2.half() } + +type NameClash struct { + pkg2.NameClash +} diff --git a/go/ql/test/library-tests/semmle/go/Types/pkg2/tst.go b/go/ql/test/library-tests/semmle/go/Types/pkg2/tst.go index af91e514b77..d1634851b6b 100644 --- a/go/ql/test/library-tests/semmle/go/Types/pkg2/tst.go +++ b/go/ql/test/library-tests/semmle/go/Types/pkg2/tst.go @@ -12,3 +12,9 @@ type MixedExportedAndNot interface { Exported() notExported() } + +type NameClash struct { + NCField string +} + +func (t NameClash) NCMethod() {} From 8dc0688b6f30961036a254a9961af072da1a3346 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Sun, 17 Nov 2024 13:26:49 +0000 Subject: [PATCH 287/470] Fix bug --- go/ql/lib/semmle/go/Types.qll | 8 ++++++-- .../semmle/go/Types/Field_getPackage.expected | 4 ++-- .../semmle/go/Types/Field_hasQualifiedName2.expected | 6 ++++-- .../semmle/go/Types/Field_hasQualifiedName3.expected | 6 ++++-- .../semmle/go/Types/ImplementsComparable.expected | 2 +- .../library-tests/semmle/go/Types/MethodTypes.expected | 1 + .../library-tests/semmle/go/Types/QualifiedNames.expected | 2 +- .../semmle/go/Types/SignatureType_isVariadic.expected | 2 +- .../library-tests/semmle/go/Types/StructFields.expected | 6 ++++-- go/ql/test/library-tests/semmle/go/Types/Types.expected | 2 +- go/ql/test/library-tests/semmle/go/Types/embedded.go | 1 - 11 files changed, 25 insertions(+), 15 deletions(-) diff --git a/go/ql/lib/semmle/go/Types.qll b/go/ql/lib/semmle/go/Types.qll index 1b09ea466cc..c05c5442061 100644 --- a/go/ql/lib/semmle/go/Types.qll +++ b/go/ql/lib/semmle/go/Types.qll @@ -523,8 +523,12 @@ class StructType extends @structtype, CompositeType { private predicate hasFieldCand(string name, Field f, int depth, boolean isEmbedded) { f = this.getOwnField(name, isEmbedded) and depth = 0 or - not this.hasOwnField(_, name, _, _) and - f = this.getFieldOfEmbedded(_, name, depth, isEmbedded) + f = this.getFieldOfEmbedded(_, name, depth, isEmbedded) and + // If this is a cyclic field and this is not the first time we see this embedded field + // then don't include it as a field candidate to avoid non-termination. + not exists(Type t | lookThroughPointerType(t) = lookThroughPointerType(f.getType()) | + this.hasOwnField(_, name, t, _) + ) } private predicate hasMethodCand(string name, Method m, int depth) { diff --git a/go/ql/test/library-tests/semmle/go/Types/Field_getPackage.expected b/go/ql/test/library-tests/semmle/go/Types/Field_getPackage.expected index 432eaf7997a..8a527e3d4f7 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Field_getPackage.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Field_getPackage.expected @@ -13,8 +13,8 @@ | depth.go:19:2:19:2 | f | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | embedded.go:4:2:4:2 | A | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | embedded.go:8:3:8:5 | Baz | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | -| embedded.go:13:2:13:4 | Qux | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | -| embedded.go:14:2:14:4 | Baz | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | +| embedded.go:12:2:12:4 | Qux | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | +| embedded.go:13:2:13:4 | Baz | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | generic.go:4:2:4:11 | valueField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | generic.go:5:2:5:13 | pointerField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | generic.go:6:2:6:11 | arrayField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | diff --git a/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName2.expected b/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName2.expected index 6d14516813d..e7ffe6bc1ba 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName2.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName2.expected @@ -18,10 +18,11 @@ | depth.go:19:2:19:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.c | f | | depth.go:19:2:19:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.d | f | | embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Baz | A | +| embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | A | | embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Qux | A | | embedded.go:8:3:8:5 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Qux | Baz | -| embedded.go:13:2:13:4 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | Qux | -| embedded.go:14:2:14:4 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | Baz | +| embedded.go:12:2:12:4 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | Qux | +| embedded.go:13:2:13:4 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | Baz | | generic.go:4:2:4:11 | valueField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | valueField | | generic.go:5:2:5:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | pointerField | | generic.go:6:2:6:11 | arrayField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | arrayField | @@ -72,6 +73,7 @@ | pkg2/tst.go:4:2:4:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.T | g | | pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.G | g | | pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.T | g | +| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsNameClash | NCField | | pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.NameClash | NCField | | pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.NameClash | NCField | | struct_tags.go:4:2:4:7 | field1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S1 | field1 | diff --git a/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName3.expected b/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName3.expected index 7a97a6d8405..03b93b37c74 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName3.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName3.expected @@ -18,10 +18,11 @@ | depth.go:19:2:19:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | c | f | | depth.go:19:2:19:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | d | f | | embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | Baz | A | +| embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | A | | embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | Qux | A | | embedded.go:8:3:8:5 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | Qux | Baz | -| embedded.go:13:2:13:4 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | Qux | -| embedded.go:14:2:14:4 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | Baz | +| embedded.go:12:2:12:4 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | Qux | +| embedded.go:13:2:13:4 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | Baz | | generic.go:4:2:4:11 | valueField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct1 | valueField | | generic.go:5:2:5:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct1 | pointerField | | generic.go:6:2:6:11 | arrayField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct1 | arrayField | @@ -72,6 +73,7 @@ | pkg2/tst.go:4:2:4:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | T | g | | pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | G | g | | pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | T | g | +| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsNameClash | NCField | | pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | NameClash | NCField | | pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | NameClash | NCField | | struct_tags.go:4:2:4:7 | field1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | S1 | field1 | diff --git a/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected b/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected index 48de9172b36..8ec8033d086 100644 --- a/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected +++ b/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected @@ -1,2 +1,2 @@ -failures testFailures +failures diff --git a/go/ql/test/library-tests/semmle/go/Types/MethodTypes.expected b/go/ql/test/library-tests/semmle/go/Types/MethodTypes.expected index e02208761bf..d143fb3121e 100644 --- a/go/ql/test/library-tests/semmle/go/Types/MethodTypes.expected +++ b/go/ql/test/library-tests/semmle/go/Types/MethodTypes.expected @@ -30,6 +30,7 @@ | interface.go:95:6:95:8 | i18 | StringA | func() string | | interface.go:101:6:101:8 | i19 | StringB | func() string | | interface.go:105:6:105:8 | i20 | StringB | func() string | +| main.go:17:6:17:20 | EmbedsNameClash | NCMethod | func() | | pkg1/embedding.go:19:6:19:13 | embedder | f | func() int | | pkg1/embedding.go:22:6:22:16 | ptrembedder | f | func() int | | pkg1/embedding.go:22:6:22:16 | ptrembedder | g | func() int | diff --git a/go/ql/test/library-tests/semmle/go/Types/QualifiedNames.expected b/go/ql/test/library-tests/semmle/go/Types/QualifiedNames.expected index 53e16bdef63..dd6e9021a4f 100644 --- a/go/ql/test/library-tests/semmle/go/Types/QualifiedNames.expected +++ b/go/ql/test/library-tests/semmle/go/Types/QualifiedNames.expected @@ -9,7 +9,7 @@ | depth.go:18:6:18:6 | d | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.d | | embedded.go:3:6:3:8 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Baz | | embedded.go:7:6:7:8 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Qux | -| embedded.go:12:6:12:14 | EmbedsBaz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | +| embedded.go:11:6:11:14 | EmbedsBaz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | | generic.go:3:6:3:19 | GenericStruct1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | | generic.go:11:6:11:27 | CircularGenericStruct1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.CircularGenericStruct1 | | generic.go:15:6:15:31 | UsesCircularGenericStruct1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.UsesCircularGenericStruct1 | diff --git a/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected b/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected index 48de9172b36..8ec8033d086 100644 --- a/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected +++ b/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected @@ -1,2 +1,2 @@ -failures testFailures +failures diff --git a/go/ql/test/library-tests/semmle/go/Types/StructFields.expected b/go/ql/test/library-tests/semmle/go/Types/StructFields.expected index bafbc2afd09..1757e0cdaf9 100644 --- a/go/ql/test/library-tests/semmle/go/Types/StructFields.expected +++ b/go/ql/test/library-tests/semmle/go/Types/StructFields.expected @@ -20,8 +20,9 @@ | embedded.go:3:6:3:8 | Baz | embedded.go:3:10:5:1 | struct type | A | string | | embedded.go:7:6:7:8 | Qux | embedded.go:7:10:9:1 | struct type | A | string | | embedded.go:7:6:7:8 | Qux | embedded.go:7:10:9:1 | struct type | Baz | * Baz | -| embedded.go:12:6:12:14 | EmbedsBaz | embedded.go:12:16:15:1 | struct type | Baz | string | -| embedded.go:12:6:12:14 | EmbedsBaz | embedded.go:12:16:15:1 | struct type | Qux | Qux | +| embedded.go:11:6:11:14 | EmbedsBaz | embedded.go:11:16:14:1 | struct type | A | string | +| embedded.go:11:6:11:14 | EmbedsBaz | embedded.go:11:16:14:1 | struct type | Baz | string | +| embedded.go:11:6:11:14 | EmbedsBaz | embedded.go:11:16:14:1 | struct type | Qux | Qux | | generic.go:3:6:3:19 | GenericStruct1 | generic.go:3:28:9:1 | struct type | arrayField | [10]T | | generic.go:3:6:3:19 | GenericStruct1 | generic.go:3:28:9:1 | struct type | mapField | [string]T | | generic.go:3:6:3:19 | GenericStruct1 | generic.go:3:28:9:1 | struct type | pointerField | * T | @@ -33,6 +34,7 @@ | generic.go:19:6:19:19 | GenericStruct2 | generic.go:19:42:22:1 | struct type | structField | GenericStruct1 | | generic.go:24:6:24:20 | GenericStruct2b | generic.go:24:39:26:1 | struct type | structField | GenericStruct2 | | generic.go:28:6:28:27 | CircularGenericStruct2 | generic.go:28:39:30:1 | struct type | pointerField | * CircularGenericStruct2 | +| main.go:17:6:17:20 | EmbedsNameClash | main.go:17:22:19:1 | struct type | NCField | string | | main.go:17:6:17:20 | EmbedsNameClash | main.go:17:22:19:1 | struct type | NameClash | NameClash | | pkg1/embedding.go:19:6:19:13 | embedder | pkg1/embedding.go:19:15:19:28 | struct type | base | base | | pkg1/embedding.go:22:6:22:16 | ptrembedder | pkg1/embedding.go:22:18:22:32 | struct type | base | * base | diff --git a/go/ql/test/library-tests/semmle/go/Types/Types.expected b/go/ql/test/library-tests/semmle/go/Types/Types.expected index b18388cc31f..ab34dd4d8ee 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Types.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Types.expected @@ -9,7 +9,7 @@ | depth.go:18:6:18:6 | d | d | | embedded.go:3:6:3:8 | Baz | Baz | | embedded.go:7:6:7:8 | Qux | Qux | -| embedded.go:12:6:12:14 | EmbedsBaz | EmbedsBaz | +| embedded.go:11:6:11:14 | EmbedsBaz | EmbedsBaz | | generic.go:3:6:3:19 | GenericStruct1 | GenericStruct1 | | generic.go:11:6:11:27 | CircularGenericStruct1 | CircularGenericStruct1 | | generic.go:15:6:15:31 | UsesCircularGenericStruct1 | UsesCircularGenericStruct1 | diff --git a/go/ql/test/library-tests/semmle/go/Types/embedded.go b/go/ql/test/library-tests/semmle/go/Types/embedded.go index c9c2cf46c2b..413290dbf1a 100644 --- a/go/ql/test/library-tests/semmle/go/Types/embedded.go +++ b/go/ql/test/library-tests/semmle/go/Types/embedded.go @@ -8,7 +8,6 @@ type Qux struct { *Baz } -// EmbedsBaz should have a field A but does not type EmbedsBaz struct { Qux Baz string From 4990f16ba5e9bdfdf5518028d365e15b28f5f4cb Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 8 Nov 2024 13:36:27 +0000 Subject: [PATCH 288/470] Refactor struct field predicate to remove redundancy --- go/ql/lib/semmle/go/Types.qll | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/go/ql/lib/semmle/go/Types.qll b/go/ql/lib/semmle/go/Types.qll index c05c5442061..54f5357199c 100644 --- a/go/ql/lib/semmle/go/Types.qll +++ b/go/ql/lib/semmle/go/Types.qll @@ -545,15 +545,7 @@ class StructType extends @structtype, CompositeType { predicate hasField(string name, Type tp) { exists(int mindepth | mindepth = min(int depth | this.hasFieldCand(name, _, depth, _)) and - tp = unique(Field f | f = this.getFieldCand(name, mindepth, _)).getType() - ) - } - - private Field getFieldCand(string name, int depth, boolean isEmbedded) { - result = this.getOwnField(name, isEmbedded) and depth = 0 - or - exists(Type embedded | this.hasEmbeddedField(embedded, depth - 1) | - result = embedded.getUnderlyingType().(StructType).getOwnField(name, isEmbedded) + tp = unique(Field f | this.hasFieldCand(name, f, mindepth, _)).getType() ) } @@ -568,9 +560,9 @@ class StructType extends @structtype, CompositeType { * The depth of a field `f` declared in this type is zero. */ Field getFieldAtDepth(string name, int depth) { - depth = min(int depthCand | exists(this.getFieldCand(name, depthCand, _))) and - result = this.getFieldCand(name, depth, _) and - strictcount(this.getFieldCand(name, depth, _)) = 1 + depth = min(int depthCand | exists(Field f | this.hasFieldCand(name, f, depthCand, _))) and + this.hasFieldCand(name, result, depth, _) and + strictcount(Field f | this.hasFieldCand(name, f, depth, _)) = 1 } Method getMethodAtDepth(string name, int depth) { From 1bc1472b0bf2d5a7d658faf4d27fb766ba77d7ef Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Sun, 17 Nov 2024 22:36:46 +0000 Subject: [PATCH 289/470] Add change note --- ...1-17-fix-missing-promoted-fields-and-methods-name-clash.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md diff --git a/go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md b/go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md new file mode 100644 index 00000000000..8b1ee9b60b2 --- /dev/null +++ b/go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed a bug which meant that promoted fields and methods were missing when the embedded parent was not promoted due to a name clash. From 2cba97e87d98f2a79a2205fce91428962d5c5517 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 22 Nov 2024 00:02:28 +0000 Subject: [PATCH 290/470] Small stylistic improvement --- go/ql/lib/semmle/go/Types.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/ql/lib/semmle/go/Types.qll b/go/ql/lib/semmle/go/Types.qll index 54f5357199c..f3c07cef966 100644 --- a/go/ql/lib/semmle/go/Types.qll +++ b/go/ql/lib/semmle/go/Types.qll @@ -560,7 +560,7 @@ class StructType extends @structtype, CompositeType { * The depth of a field `f` declared in this type is zero. */ Field getFieldAtDepth(string name, int depth) { - depth = min(int depthCand | exists(Field f | this.hasFieldCand(name, f, depthCand, _))) and + depth = min(int depthCand | this.hasFieldCand(name, _, depthCand, _)) and this.hasFieldCand(name, result, depth, _) and strictcount(Field f | this.hasFieldCand(name, f, depth, _)) = 1 } From 0e94ee81aeef06a1b38651fd99bd869f7a435a1a Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 26 Nov 2024 12:27:30 +0000 Subject: [PATCH 291/470] Don't getUnderlyingType before looking through pointer type If `T` is the type of an embedded field, it is invalid for `T` to be a named type defined to be a pointer type (`type T *S`). It is also invalid for `T` to be a type parameter. So this `getUnderlyingType()` is redundant. --- go/ql/lib/semmle/go/Types.qll | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/go/ql/lib/semmle/go/Types.qll b/go/ql/lib/semmle/go/Types.qll index f3c07cef966..1f1234aa1de 100644 --- a/go/ql/lib/semmle/go/Types.qll +++ b/go/ql/lib/semmle/go/Types.qll @@ -496,14 +496,15 @@ class StructType extends @structtype, CompositeType { Field getFieldOfEmbedded(Field embeddedParent, string name, int depth, boolean isEmbedded) { // embeddedParent is a field of 'this' at depth 'depth - 1' this.hasFieldCand(_, embeddedParent, depth - 1, true) and - // embeddedParent's type has the result field - exists(StructType embeddedType, Type fieldType | - fieldType = embeddedParent.getType().getUnderlyingType() and - pragma[only_bind_into](embeddedType) = - [fieldType, fieldType.(PointerType).getBaseType().getUnderlyingType()] - | - result = embeddedType.getOwnField(name, isEmbedded) - ) + // embeddedParent's type has the result field. Note that it is invalid Go + // to have an embedded field with a named type whose underlying type is a + // pointer, so we don't have to have + // `lookThroughPointerType(embeddedParent.getType().getUnderlyingType())`. + result = + lookThroughPointerType(embeddedParent.getType()) + .getUnderlyingType() + .(StructType) + .getOwnField(name, isEmbedded) } /** From 89b2a6b72637686b087a909990a2f279d1881b95 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Nov 2024 00:21:55 +0000 Subject: [PATCH 292/470] Add changed framework coverage reports --- go/documentation/library-coverage/coverage.csv | 1 + go/documentation/library-coverage/coverage.rst | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go/documentation/library-coverage/coverage.csv b/go/documentation/library-coverage/coverage.csv index 21127e396a2..cf5a8b715b0 100644 --- a/go/documentation/library-coverage/coverage.csv +++ b/go/documentation/library-coverage/coverage.csv @@ -130,6 +130,7 @@ os,29,11,6,3,,,,,26,,,,,,,,,,,7,3,,1,6, path,,,18,,,,,,,,,,,,,,,,,,,,,18, reflect,,,37,,,,,,,,,,,,,,,,,,,,,37, regexp,10,,20,,,,,,,3,3,4,,,,,,,,,,,,20, +slices,,,17,,,,,,,,,,,,,,,,,,,,,,17 sort,,,1,,,,,,,,,,,,,,,,,,,,,1, strconv,,,9,,,,,,,,,,,,,,,,,,,,,9, strings,,,34,,,,,,,,,,,,,,,,,,,,,34, diff --git a/go/documentation/library-coverage/coverage.rst b/go/documentation/library-coverage/coverage.rst index 87ac3e6f1cc..48f24355a33 100644 --- a/go/documentation/library-coverage/coverage.rst +++ b/go/documentation/library-coverage/coverage.rst @@ -26,7 +26,7 @@ Go framework & library support `Macaron `_,``gopkg.in/macaron*``,12,1,1 `Revel `_,"``github.com/revel/revel*``, ``github.com/robfig/revel*``",46,20,4 `SendGrid `_,``github.com/sendgrid/sendgrid-go*``,,1, - `Standard library `_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``",33,587,104 + `Standard library `_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``",33,604,104 `XPath `_,``github.com/antchfx/xpath*``,,,4 `appleboy/gin-jwt `_,``github.com/appleboy/gin-jwt*``,,,1 `beego `_,"``github.com/astaxie/beego*``, ``github.com/beego/beego*``",63,63,213 @@ -61,5 +61,5 @@ Go framework & library support `yaml `_,``gopkg.in/yaml*``,,9, `zap `_,``go.uber.org/zap*``,,11,33 Others,"``github.com/Masterminds/squirrel``, ``github.com/caarlos0/env``, ``github.com/go-gorm/gorm``, ``github.com/go-xorm/xorm``, ``github.com/gobuffalo/envy``, ``github.com/gogf/gf/database/gdb``, ``github.com/hashicorp/go-envparse``, ``github.com/jinzhu/gorm``, ``github.com/jmoiron/sqlx``, ``github.com/joho/godotenv``, ``github.com/kelseyhightower/envconfig``, ``github.com/lann/squirrel``, ``github.com/raindog308/gorqlite``, ``github.com/rqlite/gorqlite``, ``github.com/uptrace/bun``, ``go.mongodb.org/mongo-driver/mongo``, ``gopkg.in/Masterminds/squirrel``, ``gorm.io/gorm``, ``xorm.io/xorm``",23,2,391 - Totals,,307,911,1532 + Totals,,307,928,1532 From 216d298780eb02425238dc3f4250b235f8d3b8c5 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 26 Nov 2024 22:29:43 -0500 Subject: [PATCH 293/470] Microsoft.JSInterop models --- csharp/ql/lib/ext/Microsoft.JSInterop.model.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 csharp/ql/lib/ext/Microsoft.JSInterop.model.yml diff --git a/csharp/ql/lib/ext/Microsoft.JSInterop.model.yml b/csharp/ql/lib/ext/Microsoft.JSInterop.model.yml new file mode 100644 index 00000000000..486768ce25d --- /dev/null +++ b/csharp/ql/lib/ext/Microsoft.JSInterop.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/csharp-all + extensible: sinkModel + data: + - ["Microsoft.JSInterop", "JSRuntimeExtensions", True, "InvokeAsync", "", "", "Argument[1]", "js-injection", "manual"] + - ["Microsoft.JSInterop", "JSRuntimeExtensions", True, "InvokeVoidAsync", "", "", "Argument[1]", "js-injection", "manual"] From b820b324bd3bac187ee17894f9c00af01d50f454 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 26 Nov 2024 22:32:45 -0500 Subject: [PATCH 294/470] Change note --- .../2024-11-26-model-microsoft.jsinterop.ijsruntime.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 csharp/ql/lib/change-notes/2024-11-26-model-microsoft.jsinterop.ijsruntime.md diff --git a/csharp/ql/lib/change-notes/2024-11-26-model-microsoft.jsinterop.ijsruntime.md b/csharp/ql/lib/change-notes/2024-11-26-model-microsoft.jsinterop.ijsruntime.md new file mode 100644 index 00000000000..a99f9c8e0fd --- /dev/null +++ b/csharp/ql/lib/change-notes/2024-11-26-model-microsoft.jsinterop.ijsruntime.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Added `js-interop` sinks for the `InvokeAsync` and `InvokeVoidAsync` methods of `Microsoft.JSInterop.IJSRuntime`, which can run arbitrary JavaScript. + From a4b2ee1205e6bf0f477e30a30d966a1e55801413 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 26 Nov 2024 22:42:13 -0500 Subject: [PATCH 295/470] Fix generic --- csharp/ql/lib/ext/Microsoft.JSInterop.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/lib/ext/Microsoft.JSInterop.model.yml b/csharp/ql/lib/ext/Microsoft.JSInterop.model.yml index 486768ce25d..78f5c0964c1 100644 --- a/csharp/ql/lib/ext/Microsoft.JSInterop.model.yml +++ b/csharp/ql/lib/ext/Microsoft.JSInterop.model.yml @@ -3,5 +3,5 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["Microsoft.JSInterop", "JSRuntimeExtensions", True, "InvokeAsync", "", "", "Argument[1]", "js-injection", "manual"] + - ["Microsoft.JSInterop", "JSRuntimeExtensions", True, "InvokeAsync", "", "", "Argument[1]", "js-injection", "manual"] - ["Microsoft.JSInterop", "JSRuntimeExtensions", True, "InvokeVoidAsync", "", "", "Argument[1]", "js-injection", "manual"] From 2b0c7a209b6f9261f5df77a4563e58cf233100cd Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 26 Nov 2024 22:42:24 -0500 Subject: [PATCH 296/470] Fix test results --- .../library-tests/dataflow/library/FlowSummaries.expected | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index 7b6e623288f..efb6d30e660 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -256,6 +256,12 @@ sink | Microsoft.EntityFrameworkCore;RelationalDatabaseFacadeExtensions;ExecuteSqlRawAsync;(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade,System.String,System.Object[]);Argument[1];sql-injection;manual | | Microsoft.EntityFrameworkCore;RelationalDatabaseFacadeExtensions;ExecuteSqlRawAsync;(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade,System.String,System.Threading.CancellationToken);Argument[1];sql-injection;manual | | Microsoft.EntityFrameworkCore;RelationalQueryableExtensions;FromSqlRaw;(Microsoft.EntityFrameworkCore.DbSet,System.String,System.Object[]);Argument[1];sql-injection;manual | +| Microsoft.JSInterop;JSRuntimeExtensions;InvokeAsync;(Microsoft.JSInterop.IJSRuntime,System.String,System.Object[]);Argument[1];js-injection;manual | +| Microsoft.JSInterop;JSRuntimeExtensions;InvokeAsync;(Microsoft.JSInterop.IJSRuntime,System.String,System.Threading.CancellationToken,System.Object[]);Argument[1];js-injection;manual | +| Microsoft.JSInterop;JSRuntimeExtensions;InvokeAsync;(Microsoft.JSInterop.IJSRuntime,System.String,System.TimeSpan,System.Object[]);Argument[1];js-injection;manual | +| Microsoft.JSInterop;JSRuntimeExtensions;InvokeVoidAsync;(Microsoft.JSInterop.IJSRuntime,System.String,System.Object[]);Argument[1];js-injection;manual | +| Microsoft.JSInterop;JSRuntimeExtensions;InvokeVoidAsync;(Microsoft.JSInterop.IJSRuntime,System.String,System.Threading.CancellationToken,System.Object[]);Argument[1];js-injection;manual | +| Microsoft.JSInterop;JSRuntimeExtensions;InvokeVoidAsync;(Microsoft.JSInterop.IJSRuntime,System.String,System.TimeSpan,System.Object[]);Argument[1];js-injection;manual | | ServiceStack.Messaging;BackgroundMqClient;SendAllOneWay;(System.Collections.Generic.IEnumerable);Argument[1].Element;file-content-store;manual | | ServiceStack.Messaging;BackgroundMqClient;SendOneWay;(System.Object);Argument[0];file-content-store;manual | | ServiceStack.Messaging;BackgroundMqClient;SendOneWay;(System.String,System.Object);Argument[1];file-content-store;manual | From 85778f7fea72ecac608466dbc47bfe00733e99bb Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 27 Nov 2024 08:53:41 +0100 Subject: [PATCH 297/470] Java: Fix semantic merge conflict in expected file. --- .../semmle/examples/SqlTainted.expected | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTainted.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTainted.expected index 6d1e99e2afb..a45f58bd54d 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTainted.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTainted.expected @@ -48,21 +48,21 @@ edges | AllowListSanitizerWithJavaUtilList.java:51:13:51:16 | args : String[] | AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilList.java:54:23:54:26 | args : String[] | AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilList.java:55:14:55:17 | args : String[] | AllowListSanitizerWithJavaUtilList.java:283:33:283:45 | args : String[] | provenance | | -| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilList.java:283:33:283:45 | args : String[] | AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilList.java:283:33:283:45 | args : String[] | AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | provenance | Sink:MaD:4 | | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:49:20:49:23 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:50:13:50:16 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:53:23:53:26 | args : String[] | provenance | | @@ -71,21 +71,21 @@ edges | AllowListSanitizerWithJavaUtilSet.java:50:13:50:16 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilSet.java:53:23:53:26 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | provenance | | | AllowListSanitizerWithJavaUtilSet.java:54:14:54:17 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:282:33:282:45 | args : String[] | provenance | | -| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | provenance | Sink:MaD:6 | -| AllowListSanitizerWithJavaUtilSet.java:282:33:282:45 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | provenance | Sink:MaD:6 | +| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | provenance | Sink:MaD:4 | +| AllowListSanitizerWithJavaUtilSet.java:282:33:282:45 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | provenance | Sink:MaD:4 | | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:17:56:17:66 | stringQuery : String | provenance | | | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:21:49:21:52 | json | provenance | | | Mongo.java:17:56:17:66 | stringQuery : String | Mongo.java:17:45:17:67 | parse(...) | provenance | Config | From 7402276ec7be327b4bec3c0c6bc2907a26f3bde0 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 26 Nov 2024 14:44:18 +0100 Subject: [PATCH 298/470] Data flow: Move more logic into `DataFlowImplCommon` --- .../cpp/ir/dataflow/internal/ProductFlow.qll | 4 +- .../codeql/dataflow/internal/DataFlowImpl.qll | 76 +++------ .../dataflow/internal/DataFlowImplCommon.qll | 160 +++++++++++++----- .../dataflow/internal/FlowSummaryImpl.qll | 2 +- .../internal/ModelGeneratorImpl.qll | 6 +- 5 files changed, 148 insertions(+), 100 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ProductFlow.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ProductFlow.qll index 0c474b0e75d..ff5f3e46e64 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ProductFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ProductFlow.qll @@ -545,7 +545,7 @@ module ProductFlow { private predicate outImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) { Flow1::PathGraph::edges(pred1, succ1, _, _) and exists(ReturnKindExt returnKind | - succ1.getNode() = returnKind.getAnOutNode(call) and + succ1.getNode() = getAnOutNodeExt(call, returnKind) and returnKind = getParamReturnPosition(_, pred1.asParameterReturnNode()).getKind() ) } @@ -573,7 +573,7 @@ module ProductFlow { private predicate outImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) { Flow2::PathGraph::edges(pred2, succ2, _, _) and exists(ReturnKindExt returnKind | - succ2.getNode() = returnKind.getAnOutNode(call) and + succ2.getNode() = getAnOutNodeExt(call, returnKind) and returnKind = getParamReturnPosition(_, pred2.asParameterReturnNode()).getKind() ) } diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index d4c73c234be..c67d21fb1ac 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -343,7 +343,7 @@ module MakeImpl Lang> { bindingset[n, cc] pragma[inline_late] private predicate isUnreachableInCall1(NodeEx n, LocalCallContextSpecificCall cc) { - cc.unreachable(n.asNode()) + cc.unreachable(n) } /** @@ -423,7 +423,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate readSetEx(NodeEx node1, ContentSet c, NodeEx node2) { - readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and + readEx(node1, c, node2) and stepFilter(node1, node2) or exists(Node n | @@ -450,20 +450,19 @@ module MakeImpl Lang> { bindingset[c] private predicate expectsContentEx(NodeEx n, Content c) { exists(ContentSet cs | - expectsContentCached(n.asNode(), cs) and + expectsContentSet(n, cs) and pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent() ) } pragma[nomagic] - private predicate notExpectsContent(NodeEx n) { not expectsContentCached(n.asNode(), _) } + private predicate notExpectsContent(NodeEx n) { not expectsContentSet(n, _) } pragma[nomagic] private predicate storeExUnrestricted( NodeEx node1, Content c, NodeEx node2, DataFlowType contentType, DataFlowType containerType ) { - store(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode()), - contentType, containerType) and + storeEx(node1, c, node2, contentType, containerType) and stepFilter(node1, node2) } @@ -471,23 +470,13 @@ module MakeImpl Lang> { private predicate hasReadStep(Content c) { read(_, c, _) } pragma[nomagic] - private predicate storeEx( + private predicate storeExRestricted( NodeEx node1, Content c, NodeEx node2, DataFlowType contentType, DataFlowType containerType ) { storeExUnrestricted(node1, c, node2, contentType, containerType) and hasReadStep(c) } - pragma[nomagic] - private predicate viableReturnPosOutEx(DataFlowCall call, ReturnPosition pos, NodeEx out) { - viableReturnPosOut(call, pos, out.asNode()) - } - - pragma[nomagic] - private predicate viableParamArgEx(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg) { - viableParamArg(call, p.asNode(), arg.asNode()) - } - /** * Holds if field flow should be used for the given configuration. */ @@ -520,7 +509,7 @@ module MakeImpl Lang> { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p.asNode()) + allowParameterReturnInSelfEx(p) ) } @@ -558,7 +547,7 @@ module MakeImpl Lang> { exists(NodeEx mid | useFieldFlow() and fwdFlow(mid, cc) and - storeEx(mid, _, node, _, _) + storeExRestricted(mid, _, node, _, _) ) or // read @@ -653,7 +642,7 @@ module MakeImpl Lang> { not fullBarrier(node) and useFieldFlow() and fwdFlow(mid, _) and - storeEx(mid, c, node, _, _) + storeExRestricted(mid, c, node, _, _) ) } @@ -796,7 +785,7 @@ module MakeImpl Lang> { exists(NodeEx mid | revFlow(mid, toReturn) and fwdFlowConsCand(c) and - storeEx(node, c, mid, _, _) + storeExRestricted(node, c, mid, _, _) ) } @@ -893,7 +882,7 @@ module MakeImpl Lang> { ) { revFlowIsReadAndStored(c) and revFlow(node2) and - storeEx(node1, c, node2, contentType, containerType) and + storeExRestricted(node1, c, node2, contentType, containerType) and exists(ap1) } @@ -1152,7 +1141,7 @@ module MakeImpl Lang> { flowOutOfCallNodeCand1(call, ret, _, out) and c = ret.getEnclosingCallable() | - scope = getSecondLevelScopeCached(ret.asNode()) + scope = getSecondLevelScopeEx(ret) or ret = TParamReturnNode(_, scope) ) @@ -1496,7 +1485,7 @@ module MakeImpl Lang> { PrevStage::revFlow(node, state, apa) and filter(node, state, t0, ap, t) and ( - if castingNodeEx(node) + if node instanceof CastingNodeEx then ap instanceof ApNil or compatibleContainer(getHeadContent(ap), node.getDataFlowType()) or @@ -2627,10 +2616,7 @@ module MakeImpl Lang> { FlowCheckNode() { revFlow(this, _, _) and ( - castNode(this.asNode()) or - clearsContentCached(this.asNode(), _) or - expectsContentCached(this.asNode(), _) or - neverSkipInPathGraph(this.asNode()) or + flowCheckNode(this) or Config::neverSkip(this.asNode()) ) } @@ -2665,7 +2651,7 @@ module MakeImpl Lang> { or node instanceof ParamNodeEx or - node.asNode() instanceof OutNodeExt + node instanceof OutNodeEx or storeStepCand(_, _, _, node, _, _) or @@ -2899,15 +2885,9 @@ module MakeImpl Lang> { predicate isHidden() { not Config::includeHiddenNodes() and - ( - hiddenNode(this.getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.getNodeEx() instanceof TNodeImplicitRead - or - hiddenNode(this.getNodeEx().asParamReturnNode()) - ) + hiddenNode(this.getNodeEx()) and + not this.isSource() and + not this instanceof PathNodeSink } /** Gets a textual representation of this element. */ @@ -3770,11 +3750,6 @@ module MakeImpl Lang> { private module Stage2 = MkStage::Stage; - pragma[nomagic] - private predicate castingNodeEx(NodeEx node) { - node.asNode() instanceof CastingNode or exists(node.asParamReturnNode()) - } - private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; @@ -3888,7 +3863,7 @@ module MakeImpl Lang> { bindingset[node, t0] private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) { - if castingNodeEx(node) + if node instanceof CastingNodeEx then exists(DataFlowType nt | nt = node.getDataFlowType() | if typeStrongerThanFilter(nt, t0) @@ -3945,7 +3920,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c) { PrevStage::revFlow(node) and - clearsContentCached(node.asNode(), c) + clearsContentSet(node, c) } pragma[nomagic] @@ -5024,7 +4999,7 @@ module MakeImpl Lang> { bindingset[c] private predicate clearsContentEx(NodeEx n, Content c) { exists(ContentSet cs | - clearsContentCached(n.asNode(), cs) and + clearsContentSet(n, cs) and pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent() ) } @@ -5442,9 +5417,8 @@ module MakeImpl Lang> { PartialAccessPath ap ) { exists(ReturnKindExt kind, DataFlowCall call | - partialPathOutOfCallable1(mid, call, kind, state, cc, t, ap) - | - out.asNode() = kind.getAnOutNode(call) + partialPathOutOfCallable1(mid, call, kind, state, cc, t, ap) and + out = kind.getAnOutNodeEx(call) ) } @@ -5529,7 +5503,7 @@ module MakeImpl Lang> { ) { exists(DataFlowCall call, ReturnKindExt kind | partialPathThroughCallable0(call, mid, kind, state, cc, t, ap) and - out.asNode() = kind.getAnOutNode(call) + out = kind.getAnOutNodeEx(call) ) } @@ -5745,7 +5719,7 @@ module MakeImpl Lang> { ) { exists(DataFlowCall call, ArgumentPosition pos | revPartialPathThroughCallable0(call, mid, pos, state, ap) and - node.asNode().(ArgNode).argumentOf(call, pos) + node.argumentOf(call, pos) ) } diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll index e477913a59b..75d68cf247c 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll @@ -286,7 +286,7 @@ module MakeImplCommon Lang> { ) { revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and not expectsContent(node, _) and - if castNode(node) or node instanceof ArgNode or node instanceof ReturnNode + if node instanceof CastNode or node instanceof ArgNode or node instanceof ReturnNode then compatibleTypesFilter(t, getNodeDataFlowType(node)) else any() } @@ -372,7 +372,7 @@ module MakeImplCommon Lang> { ) { revLambdaFlow(lambdaCall, kind, out, t, _, toJump, lastCall) and exists(ReturnKindExt rk | - out = rk.getAnOutNode(call) and + out = getAnOutNodeExt(call, rk) and lambdaCall(call, _, _) ) } @@ -901,20 +901,36 @@ module MakeImplCommon Lang> { Location getLocation() { result = this.projectToNode().getLocation() } } - final class ArgNodeEx extends NodeEx { - ArgNodeEx() { this.asNode() instanceof ArgNode } + /** + * A `Node` at which a cast can occur such that the type should be checked. + */ + final class CastingNodeEx extends NodeEx { + CastingNodeEx() { castingNodeEx(this) } + } - DataFlowCall getCall() { this.asNode().(ArgNode).argumentOf(result, _) } + final class ArgNodeEx extends NodeEx { + private DataFlowCall call_; + private ArgumentPosition pos_; + + ArgNodeEx() { this.asNode().(ArgNode).argumentOf(call_, pos_) } + + predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { + call = call_ and + pos = pos_ + } + + DataFlowCall getCall() { result = call_ } } final class ParamNodeEx extends NodeEx { - ParamNodeEx() { this.asNode() instanceof ParamNode } + private DataFlowCallable c_; + private ParameterPosition pos_; - predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { - this.asNode().(ParamNode).isParameterOf(c, pos) - } + ParamNodeEx() { this.asNode().(ParamNode).isParameterOf(c_, pos_) } - ParameterPosition getPosition() { this.isParameterOf(_, result) } + predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { c = c_ and pos = pos_ } + + ParameterPosition getPosition() { result = pos_ } } /** @@ -931,6 +947,18 @@ module MakeImplCommon Lang> { ReturnKindExt getKind() { result = pos.getKind() } } + final class OutNodeEx extends NodeEx { + OutNodeEx() { this.asNode() instanceof OutNodeExt } + } + + pragma[nomagic] + private SndLevelScopeOption getSecondLevelScope0(Node n) { + result = SndLevelScopeOption::some(getSecondLevelScope(n)) + or + result instanceof SndLevelScopeOption::None and + not exists(getSecondLevelScope(n)) + } + cached private module Cached { /** @@ -942,11 +970,8 @@ module MakeImplCommon Lang> { predicate forceCachingInSameStage() { any() } cached - SndLevelScopeOption getSecondLevelScopeCached(Node n) { - result = SndLevelScopeOption::some(getSecondLevelScope(n)) - or - result instanceof SndLevelScopeOption::None and - not exists(getSecondLevelScope(n)) + SndLevelScopeOption getSecondLevelScopeEx(NodeEx n) { + result = getSecondLevelScope0(n.asNode()) } cached @@ -978,11 +1003,14 @@ module MakeImplCommon Lang> { predicate jumpStepCached(Node node1, Node node2) { jumpStep(node1, node2) } cached - predicate clearsContentCached(Node n, ContentSet c) { clearsContent(n, c) } + predicate clearsContentSet(NodeEx n, ContentSet c) { clearsContent(n.asNode(), c) } cached predicate expectsContentCached(Node n, ContentSet c) { expectsContent(n, c) } + cached + predicate expectsContentSet(NodeEx n, ContentSet c) { expectsContent(n.asNode(), c) } + cached predicate isUnreachableInCallCached(NodeRegion nr, DataFlowCall call) { isUnreachableInCall(nr, call) @@ -996,16 +1024,15 @@ module MakeImplCommon Lang> { } cached - predicate hiddenNode(Node n) { nodeIsHidden(n) } + predicate hiddenNode(NodeEx n) { + nodeIsHidden([n.asNode(), n.asParamReturnNode()]) + or + n instanceof TNodeImplicitRead + } cached - OutNodeExt getAnOutNodeExt(DataFlowCall call, ReturnKindExt k) { - result = getAnOutNode(call, k.(ValueReturnKind).getKind()) - or - exists(ArgNode arg | - result.(PostUpdateNode).getPreUpdateNode() = arg and - arg.argumentOf(call, k.(ParamUpdateReturnKind).getAMatchingArgumentPosition()) - ) + OutNodeEx getAnOutNodeEx(DataFlowCall call, ReturnKindExt k) { + result.asNode() = getAnOutNodeExt(call, k) } pragma[nomagic] @@ -1016,22 +1043,22 @@ module MakeImplCommon Lang> { parameterValueFlowsToPreUpdate(p, n) and p.isParameterOf(_, pos) and k = TParamUpdate(pos) and - scope = getSecondLevelScopeCached(n) + scope = getSecondLevelScope0(n) ) } cached - predicate castNode(Node n) { n instanceof CastNode } + predicate flowCheckNode(NodeEx n) { + n.asNode() instanceof CastNode or + clearsContentSet(n, _) or + expectsContentSet(n, _) or + neverSkipInPathGraph(n.asNode()) + } cached - predicate castingNode(Node n) { - castNode(n) or - n instanceof ParamNode or - n instanceof OutNodeExt or - // For reads, `x.f`, we want to check that the tracked type after the read (which - // is obtained by popping the head of the access path stack) is compatible with - // the type of `x.f`. - readSet(_, _, n) + predicate castingNodeEx(NodeEx n) { + n.asNode() instanceof CastingNode or + exists(n.asParamReturnNode()) } cached @@ -1208,6 +1235,15 @@ module MakeImplCommon Lang> { ) } + /** + * Holds if `arg` is a possible argument to `p` in `call`, taking virtual + * dispatch into account. + */ + cached + predicate viableParamArgEx(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg) { + viableParamArg(call, p.asNode(), arg.asNode()) + } + pragma[nomagic] private ReturnPosition viableReturnPos(DataFlowCall call, ReturnKindExt kind) { viableCallableExt(call) = result.getCallable() and @@ -1219,13 +1255,22 @@ module MakeImplCommon Lang> { * taking virtual dispatch into account. */ cached - predicate viableReturnPosOut(DataFlowCall call, ReturnPosition pos, Node out) { + predicate viableReturnPosOut(DataFlowCall call, ReturnPosition pos, OutNodeExt out) { exists(ReturnKindExt kind | pos = viableReturnPos(call, kind) and - out = kind.getAnOutNode(call) + out = getAnOutNodeExt(call, kind) ) } + /** + * Holds if a value at return position `pos` can be returned to `out` via `call`, + * taking virtual dispatch into account. + */ + cached + predicate viableReturnPosOutEx(DataFlowCall call, ReturnPosition pos, OutNodeEx out) { + viableReturnPosOut(call, pos, out.asNode()) + } + /** Provides predicates for calculating flow-through summaries. */ private module FlowThrough { /** @@ -1559,6 +1604,11 @@ module MakeImplCommon Lang> { cached predicate readSet(Node node1, ContentSet c, Node node2) { readStep(node1, c, node2) } + cached + predicate readEx(NodeEx node1, ContentSet c, NodeEx node2) { + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) + } + cached predicate storeSet( Node node1, ContentSet c, Node node2, DataFlowType contentType, DataFlowType containerType @@ -1587,11 +1637,13 @@ module MakeImplCommon Lang> { * been stored into, in order to handle cases like `x.f1.f2 = y`. */ cached - predicate store( - Node node1, Content c, Node node2, DataFlowType contentType, DataFlowType containerType + predicate storeEx( + NodeEx node1, Content c, NodeEx node2, DataFlowType contentType, DataFlowType containerType ) { exists(ContentSet cs | - c = cs.getAStoreContent() and storeSet(node1, cs, node2, contentType, containerType) + c = cs.getAStoreContent() and + storeSet(pragma[only_bind_into](node1.asNode()), cs, pragma[only_bind_into](node2.asNode()), + contentType, containerType) ) } @@ -1627,7 +1679,7 @@ module MakeImplCommon Lang> { } cached - predicate allowParameterReturnInSelfCached(ParamNode p) { allowParameterReturnInSelf(p) } + predicate allowParameterReturnInSelfEx(ParamNodeEx p) { allowParameterReturnInSelf(p.asNode()) } cached predicate paramMustFlow(ParamNode p, ArgNode arg) { localMustFlowStep+(p, arg) } @@ -1657,7 +1709,9 @@ module MakeImplCommon Lang> { string toString() { result = "Unreachable" } cached - predicate contains(Node n) { exists(NodeRegion nr | super.contains(nr) and nr.contains(n)) } + predicate contains(NodeEx n) { + exists(NodeRegion nr | super.contains(nr) and nr.contains(n.asNode())) + } cached DataFlowCallable getEnclosingCallable() { @@ -2209,7 +2263,15 @@ module MakeImplCommon Lang> { * A `Node` at which a cast can occur such that the type should be checked. */ class CastingNode extends NodeFinal { - CastingNode() { castingNode(this) } + CastingNode() { + this instanceof CastNode or + this instanceof ParamNode or + this instanceof OutNodeExt or + // For reads, `x.f`, we want to check that the tracked type after the read (which + // is obtained by popping the head of the access path stack) is compatible with + // the type of `x.f`. + readSet(_, _, this) + } } private predicate readStepWithTypes( @@ -2266,7 +2328,7 @@ module MakeImplCommon Lang> { } /** Holds if this call context makes `n` unreachable. */ - predicate unreachable(Node n) { ns.contains(n) } + predicate unreachable(NodeEx n) { ns.contains(n) } } private DataFlowCallable getNodeRegionEnclosingCallable(NodeRegion nr) { @@ -2307,6 +2369,16 @@ module MakeImplCommon Lang> { OutNodeExt() { outNodeExt(this) } } + pragma[nomagic] + OutNodeExt getAnOutNodeExt(DataFlowCall call, ReturnKindExt k) { + result = getAnOutNode(call, k.(ValueReturnKind).getKind()) + or + exists(ArgNode arg | + result.(PostUpdateNode).getPreUpdateNode() = arg and + arg.argumentOf(call, k.(ParamUpdateReturnKind).getAMatchingArgumentPosition()) + ) + } + /** * An extended return kind. A return kind describes how data can be returned * from a callable. This can either be through a returned value or an updated @@ -2317,7 +2389,7 @@ module MakeImplCommon Lang> { abstract string toString(); /** Gets a node corresponding to data flow out of `call`. */ - final OutNodeExt getAnOutNode(DataFlowCall call) { result = getAnOutNodeExt(call, this) } + final OutNodeEx getAnOutNodeEx(DataFlowCall call) { result = getAnOutNodeEx(call, this) } } class ValueReturnKind extends ReturnKindExt, TValueReturn { diff --git a/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll b/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll index 4f6a88b6b28..e7e588ff9eb 100644 --- a/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll @@ -1355,7 +1355,7 @@ module Make< exists(DataFlowCall call, ReturnKindExt rk | result = summaryArgParam(call, arg, sc) and summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and - out = pragma[only_bind_into](rk).getAnOutNode(call) + out = getAnOutNodeExt(call, pragma[only_bind_into](rk)) ) } diff --git a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll index 2e22ae2c2ba..5b53943ff83 100644 --- a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll +++ b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll @@ -464,8 +464,10 @@ module MakeModelGenerator< predicate isAdditionalFlowStep( DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 ) { - exists(DataFlow::ContentSet c | - DataFlow::store(node1, c.getAStoreContent(), node2, _, _) and + exists(DataFlow::NodeEx n1, DataFlow::NodeEx n2, DataFlow::ContentSet c | + node1 = n1.asNode() and + node2 = n2.asNode() and + DataFlow::storeEx(n1, c.getAStoreContent(), n2, _, _) and isRelevantContent0(c) and ( state1 instanceof TaintRead and state2.(TaintStore).getStep() = 1 From 5ef496dd1b2fdc9511a68844f06186608c7b09ae Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 27 Nov 2024 09:07:35 +0100 Subject: [PATCH 299/470] Java: Add more qldoc. --- java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll | 8 ++++++++ .../ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll b/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll index f9046b1b65e..9e05b69db4a 100644 --- a/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll @@ -21,6 +21,7 @@ private RefType boxIfNeeded(J::Type t) { result = t } +/** Provides the input types and predicates for instantiation of `UniversalFlow`. */ module FlowStepsInput implements UniversalFlow::UniversalFlowInput { private newtype TFlowNode = TField(Field f) { not f.getType() instanceof PrimitiveType } or @@ -32,6 +33,7 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput { * A `Field`, `BaseSsaVariable`, `Expr`, or `Method`. */ class FlowNode extends TFlowNode { + /** Gets a textual representation of this element. */ string toString() { result = this.asField().toString() or result = this.asSsa().toString() or @@ -39,6 +41,7 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput { result = this.asMethod().toString() } + /** Gets the source location for this element. */ Location getLocation() { result = this.asField().getLocation() or result = this.asSsa().getLocation() or @@ -46,14 +49,19 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput { result = this.asMethod().getLocation() } + /** Gets the field corresponding to this node, if any. */ Field asField() { this = TField(result) } + /** Gets the SSA variable corresponding to this node, if any. */ BaseSsaVariable asSsa() { this = TSsa(result) } + /** Gets the expression corresponding to this node, if any. */ Expr asExpr() { this = TExpr(result) } + /** Gets the method corresponding to this node, if any. */ Method asMethod() { this = TMethod(result) } + /** Gets the type of this node. */ RefType getType() { result = this.asField().getType() or result = this.asSsa().getSourceVariable().getType() or diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll b/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll index f33a6d7195f..79f12e57f6a 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll @@ -38,6 +38,7 @@ class BaseSsaSourceVariable extends TBaseSsaSourceVariable { /** Gets the `Callable` in which this `BaseSsaSourceVariable` is defined. */ Callable getEnclosingCallable() { this = TLocalVar(result, _) } + /** Gets a textual representation of this element. */ string toString() { exists(LocalScopeVariable v, Callable c | this = TLocalVar(c, v) | if c = v.getCallable() @@ -46,6 +47,7 @@ class BaseSsaSourceVariable extends TBaseSsaSourceVariable { ) } + /** Gets the source location for this element. */ Location getLocation() { exists(LocalScopeVariable v | this = TLocalVar(_, v) and result = v.getLocation()) } @@ -482,8 +484,10 @@ class BaseSsaVariable extends TBaseSsaVariable { this = TSsaEntryDef(_, result) } + /** Gets a textual representation of this element. */ string toString() { none() } + /** Gets the source location for this element. */ Location getLocation() { result = this.getCfgNode().getLocation() } /** Gets the `BasicBlock` in which this SSA variable is defined. */ From 9ec9d79b4f9ae9a26628e34f7df57f35bbf821da Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 27 Nov 2024 10:02:28 +0100 Subject: [PATCH 300/470] Rust: Add additional tests for flow through structs --- .../dataflow/local/DataFlowStep.expected | 542 ++++++++++-------- .../dataflow/local/inline-flow.expected | 88 +-- .../test/library-tests/dataflow/local/main.rs | 154 +++-- 3 files changed, 455 insertions(+), 329 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index a49da751679..63666e3dec6 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -54,253 +54,301 @@ localStep | main.rs:53:5:53:5 | [SSA] i | main.rs:54:10:54:10 | i | | main.rs:53:5:53:5 | i | main.rs:53:5:53:5 | [SSA] i | | main.rs:53:9:53:17 | source(...) | main.rs:53:5:53:5 | i | -| main.rs:61:9:61:9 | [SSA] i | main.rs:62:11:62:11 | i | -| main.rs:61:9:61:9 | i | main.rs:61:9:61:9 | [SSA] i | -| main.rs:61:13:61:31 | ...::new(...) | main.rs:61:9:61:9 | i | -| main.rs:66:9:66:9 | [SSA] a | main.rs:67:10:67:10 | a | -| main.rs:66:9:66:9 | a | main.rs:66:9:66:9 | [SSA] a | -| main.rs:66:13:66:26 | TupleExpr | main.rs:66:9:66:9 | a | -| main.rs:67:10:67:10 | a | main.rs:68:10:68:10 | a | -| main.rs:78:9:78:9 | [SSA] p | main.rs:83:10:83:10 | p | -| main.rs:78:9:78:9 | p | main.rs:78:9:78:9 | [SSA] p | -| main.rs:78:13:82:5 | Point {...} | main.rs:78:9:78:9 | p | -| main.rs:83:10:83:10 | p | main.rs:84:10:84:10 | p | -| main.rs:84:10:84:10 | p | main.rs:85:10:85:10 | p | -| main.rs:92:9:92:9 | [SSA] p | main.rs:97:38:97:38 | p | -| main.rs:92:9:92:9 | p | main.rs:92:9:92:9 | [SSA] p | -| main.rs:92:13:96:5 | Point {...} | main.rs:92:9:92:9 | p | -| main.rs:97:20:97:20 | [SSA] a | main.rs:98:10:98:10 | a | -| main.rs:97:20:97:20 | a | main.rs:97:20:97:20 | [SSA] a | -| main.rs:97:26:97:26 | [SSA] b | main.rs:99:10:99:10 | b | -| main.rs:97:26:97:26 | b | main.rs:97:26:97:26 | [SSA] b | -| main.rs:97:32:97:32 | [SSA] c | main.rs:100:10:100:10 | c | -| main.rs:97:32:97:32 | c | main.rs:97:32:97:32 | [SSA] c | -| main.rs:97:38:97:38 | p | main.rs:97:9:97:34 | Point {...} | -| main.rs:104:9:104:10 | [SSA] s1 | main.rs:106:11:106:12 | s1 | -| main.rs:104:9:104:10 | s1 | main.rs:104:9:104:10 | [SSA] s1 | -| main.rs:104:14:104:37 | ...::Some(...) | main.rs:104:9:104:10 | s1 | -| main.rs:105:9:105:10 | [SSA] s2 | main.rs:110:11:110:12 | s2 | -| main.rs:105:9:105:10 | s2 | main.rs:105:9:105:10 | [SSA] s2 | -| main.rs:105:14:105:28 | ...::Some(...) | main.rs:105:9:105:10 | s2 | -| main.rs:106:11:106:12 | s1 | main.rs:107:9:107:23 | TupleStructPat | -| main.rs:106:11:106:12 | s1 | main.rs:108:9:108:20 | ...::None | -| main.rs:107:22:107:22 | [SSA] n | main.rs:107:33:107:33 | n | -| main.rs:107:22:107:22 | n | main.rs:107:22:107:22 | [SSA] n | -| main.rs:107:28:107:34 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } | -| main.rs:108:25:108:31 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } | -| main.rs:110:5:113:5 | match s2 { ... } | main.rs:103:37:114:1 | { ... } | -| main.rs:110:11:110:12 | s2 | main.rs:111:9:111:23 | TupleStructPat | -| main.rs:110:11:110:12 | s2 | main.rs:112:9:112:20 | ...::None | -| main.rs:111:22:111:22 | [SSA] n | main.rs:111:33:111:33 | n | -| main.rs:111:22:111:22 | n | main.rs:111:22:111:22 | [SSA] n | -| main.rs:111:28:111:34 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } | -| main.rs:112:25:112:31 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } | -| main.rs:117:9:117:10 | [SSA] s1 | main.rs:119:11:119:12 | s1 | -| main.rs:117:9:117:10 | s1 | main.rs:117:9:117:10 | [SSA] s1 | -| main.rs:117:14:117:29 | Some(...) | main.rs:117:9:117:10 | s1 | -| main.rs:118:9:118:10 | [SSA] s2 | main.rs:123:11:123:12 | s2 | -| main.rs:118:9:118:10 | s2 | main.rs:118:9:118:10 | [SSA] s2 | -| main.rs:118:14:118:20 | Some(...) | main.rs:118:9:118:10 | s2 | -| main.rs:119:11:119:12 | s1 | main.rs:120:9:120:15 | TupleStructPat | -| main.rs:119:11:119:12 | s1 | main.rs:121:9:121:12 | None | -| main.rs:120:14:120:14 | [SSA] n | main.rs:120:25:120:25 | n | -| main.rs:120:14:120:14 | n | main.rs:120:14:120:14 | [SSA] n | -| main.rs:120:20:120:26 | sink(...) | main.rs:119:5:122:5 | match s1 { ... } | -| main.rs:121:17:121:23 | sink(...) | main.rs:119:5:122:5 | match s1 { ... } | -| main.rs:123:5:126:5 | match s2 { ... } | main.rs:116:39:127:1 | { ... } | -| main.rs:123:11:123:12 | s2 | main.rs:124:9:124:15 | TupleStructPat | -| main.rs:123:11:123:12 | s2 | main.rs:125:9:125:12 | None | -| main.rs:124:14:124:14 | [SSA] n | main.rs:124:25:124:25 | n | -| main.rs:124:14:124:14 | n | main.rs:124:14:124:14 | [SSA] n | -| main.rs:124:20:124:26 | sink(...) | main.rs:123:5:126:5 | match s2 { ... } | -| main.rs:125:17:125:23 | sink(...) | main.rs:123:5:126:5 | match s2 { ... } | -| main.rs:135:9:135:10 | [SSA] s1 | main.rs:137:11:137:12 | s1 | -| main.rs:135:9:135:10 | s1 | main.rs:135:9:135:10 | [SSA] s1 | -| main.rs:135:14:135:39 | ...::A(...) | main.rs:135:9:135:10 | s1 | -| main.rs:136:9:136:10 | [SSA] s2 | main.rs:144:11:144:12 | s2 | -| main.rs:136:9:136:10 | s2 | main.rs:136:9:136:10 | [SSA] s2 | -| main.rs:136:14:136:30 | ...::B(...) | main.rs:136:9:136:10 | s2 | -| main.rs:137:11:137:12 | s1 | main.rs:138:9:138:25 | TupleStructPat | -| main.rs:137:11:137:12 | s1 | main.rs:139:9:139:25 | TupleStructPat | -| main.rs:137:11:137:12 | s1 | main.rs:141:11:141:12 | s1 | -| main.rs:138:24:138:24 | [SSA] n | main.rs:138:35:138:35 | n | -| main.rs:138:24:138:24 | n | main.rs:138:24:138:24 | [SSA] n | -| main.rs:138:30:138:36 | sink(...) | main.rs:137:5:140:5 | match s1 { ... } | -| main.rs:139:24:139:24 | [SSA] n | main.rs:139:35:139:35 | n | -| main.rs:139:24:139:24 | n | main.rs:139:24:139:24 | [SSA] n | -| main.rs:139:30:139:36 | sink(...) | main.rs:137:5:140:5 | match s1 { ... } | -| main.rs:141:11:141:12 | s1 | main.rs:142:10:142:46 | ... \| ... | -| main.rs:142:10:142:46 | ... \| ... | main.rs:142:10:142:26 | TupleStructPat | -| main.rs:142:10:142:46 | ... \| ... | main.rs:142:30:142:46 | TupleStructPat | -| main.rs:142:10:142:46 | [SSA] [match(true)] phi | main.rs:142:57:142:57 | n | -| main.rs:142:25:142:25 | [SSA] [input] [match(true)] phi | main.rs:142:10:142:46 | [SSA] [match(true)] phi | -| main.rs:142:25:142:25 | [SSA] n | main.rs:142:25:142:25 | [SSA] [input] [match(true)] phi | -| main.rs:142:25:142:25 | n | main.rs:142:25:142:25 | [SSA] n | -| main.rs:142:45:142:45 | [SSA] [input] [match(true)] phi | main.rs:142:10:142:46 | [SSA] [match(true)] phi | -| main.rs:142:45:142:45 | [SSA] n | main.rs:142:45:142:45 | [SSA] [input] [match(true)] phi | -| main.rs:142:45:142:45 | n | main.rs:142:45:142:45 | [SSA] n | -| main.rs:142:52:142:58 | sink(...) | main.rs:141:5:143:5 | match s1 { ... } | -| main.rs:144:5:147:5 | match s2 { ... } | main.rs:134:48:148:1 | { ... } | -| main.rs:144:11:144:12 | s2 | main.rs:145:9:145:25 | TupleStructPat | -| main.rs:144:11:144:12 | s2 | main.rs:146:9:146:25 | TupleStructPat | -| main.rs:145:24:145:24 | [SSA] n | main.rs:145:35:145:35 | n | -| main.rs:145:24:145:24 | n | main.rs:145:24:145:24 | [SSA] n | -| main.rs:145:30:145:36 | sink(...) | main.rs:144:5:147:5 | match s2 { ... } | -| main.rs:146:24:146:24 | [SSA] n | main.rs:146:35:146:35 | n | -| main.rs:146:24:146:24 | n | main.rs:146:24:146:24 | [SSA] n | -| main.rs:146:30:146:36 | sink(...) | main.rs:144:5:147:5 | match s2 { ... } | -| main.rs:153:9:153:10 | [SSA] s1 | main.rs:155:11:155:12 | s1 | -| main.rs:153:9:153:10 | s1 | main.rs:153:9:153:10 | [SSA] s1 | -| main.rs:153:14:153:26 | A(...) | main.rs:153:9:153:10 | s1 | -| main.rs:154:9:154:10 | [SSA] s2 | main.rs:162:11:162:12 | s2 | -| main.rs:154:9:154:10 | s2 | main.rs:154:9:154:10 | [SSA] s2 | -| main.rs:154:14:154:17 | B(...) | main.rs:154:9:154:10 | s2 | -| main.rs:155:11:155:12 | s1 | main.rs:156:9:156:12 | TupleStructPat | -| main.rs:155:11:155:12 | s1 | main.rs:157:9:157:12 | TupleStructPat | -| main.rs:155:11:155:12 | s1 | main.rs:159:11:159:12 | s1 | -| main.rs:156:11:156:11 | [SSA] n | main.rs:156:22:156:22 | n | -| main.rs:156:11:156:11 | n | main.rs:156:11:156:11 | [SSA] n | -| main.rs:156:17:156:23 | sink(...) | main.rs:155:5:158:5 | match s1 { ... } | -| main.rs:157:11:157:11 | [SSA] n | main.rs:157:22:157:22 | n | -| main.rs:157:11:157:11 | n | main.rs:157:11:157:11 | [SSA] n | -| main.rs:157:17:157:23 | sink(...) | main.rs:155:5:158:5 | match s1 { ... } | -| main.rs:159:11:159:12 | s1 | main.rs:160:10:160:20 | ... \| ... | -| main.rs:160:10:160:20 | ... \| ... | main.rs:160:10:160:13 | TupleStructPat | -| main.rs:160:10:160:20 | ... \| ... | main.rs:160:17:160:20 | TupleStructPat | -| main.rs:160:10:160:20 | [SSA] [match(true)] phi | main.rs:160:31:160:31 | n | -| main.rs:160:12:160:12 | [SSA] [input] [match(true)] phi | main.rs:160:10:160:20 | [SSA] [match(true)] phi | -| main.rs:160:12:160:12 | [SSA] n | main.rs:160:12:160:12 | [SSA] [input] [match(true)] phi | -| main.rs:160:12:160:12 | n | main.rs:160:12:160:12 | [SSA] n | -| main.rs:160:19:160:19 | [SSA] [input] [match(true)] phi | main.rs:160:10:160:20 | [SSA] [match(true)] phi | -| main.rs:160:19:160:19 | [SSA] n | main.rs:160:19:160:19 | [SSA] [input] [match(true)] phi | -| main.rs:160:19:160:19 | n | main.rs:160:19:160:19 | [SSA] n | -| main.rs:160:26:160:32 | sink(...) | main.rs:159:5:161:5 | match s1 { ... } | -| main.rs:162:5:165:5 | match s2 { ... } | main.rs:152:50:166:1 | { ... } | -| main.rs:162:11:162:12 | s2 | main.rs:163:9:163:12 | TupleStructPat | -| main.rs:162:11:162:12 | s2 | main.rs:164:9:164:12 | TupleStructPat | -| main.rs:163:11:163:11 | [SSA] n | main.rs:163:22:163:22 | n | -| main.rs:163:11:163:11 | n | main.rs:163:11:163:11 | [SSA] n | -| main.rs:163:17:163:23 | sink(...) | main.rs:162:5:165:5 | match s2 { ... } | -| main.rs:164:11:164:11 | [SSA] n | main.rs:164:22:164:22 | n | -| main.rs:164:11:164:11 | n | main.rs:164:11:164:11 | [SSA] n | -| main.rs:164:17:164:23 | sink(...) | main.rs:162:5:165:5 | match s2 { ... } | -| main.rs:174:9:174:10 | [SSA] s1 | main.rs:178:11:178:12 | s1 | -| main.rs:174:9:174:10 | s1 | main.rs:174:9:174:10 | [SSA] s1 | -| main.rs:174:14:176:5 | ...::C {...} | main.rs:174:9:174:10 | s1 | -| main.rs:177:9:177:10 | [SSA] s2 | main.rs:185:11:185:12 | s2 | -| main.rs:177:9:177:10 | s2 | main.rs:177:9:177:10 | [SSA] s2 | -| main.rs:177:14:177:43 | ...::D {...} | main.rs:177:9:177:10 | s2 | -| main.rs:178:11:178:12 | s1 | main.rs:179:9:179:38 | ...::C {...} | -| main.rs:178:11:178:12 | s1 | main.rs:180:9:180:38 | ...::D {...} | -| main.rs:178:11:178:12 | s1 | main.rs:182:11:182:12 | s1 | -| main.rs:179:36:179:36 | [SSA] n | main.rs:179:48:179:48 | n | -| main.rs:179:36:179:36 | n | main.rs:179:36:179:36 | [SSA] n | -| main.rs:179:43:179:49 | sink(...) | main.rs:178:5:181:5 | match s1 { ... } | -| main.rs:180:36:180:36 | [SSA] n | main.rs:180:48:180:48 | n | -| main.rs:180:36:180:36 | n | main.rs:180:36:180:36 | [SSA] n | -| main.rs:180:43:180:49 | sink(...) | main.rs:178:5:181:5 | match s1 { ... } | -| main.rs:182:11:182:12 | s1 | main.rs:183:10:183:72 | ... \| ... | -| main.rs:183:10:183:72 | ... \| ... | main.rs:183:10:183:39 | ...::C {...} | -| main.rs:183:10:183:72 | ... \| ... | main.rs:183:43:183:72 | ...::D {...} | -| main.rs:183:10:183:72 | [SSA] [match(true)] phi | main.rs:183:83:183:83 | n | -| main.rs:183:37:183:37 | [SSA] [input] [match(true)] phi | main.rs:183:10:183:72 | [SSA] [match(true)] phi | -| main.rs:183:37:183:37 | [SSA] n | main.rs:183:37:183:37 | [SSA] [input] [match(true)] phi | -| main.rs:183:37:183:37 | n | main.rs:183:37:183:37 | [SSA] n | -| main.rs:183:70:183:70 | [SSA] [input] [match(true)] phi | main.rs:183:10:183:72 | [SSA] [match(true)] phi | -| main.rs:183:70:183:70 | [SSA] n | main.rs:183:70:183:70 | [SSA] [input] [match(true)] phi | -| main.rs:183:70:183:70 | n | main.rs:183:70:183:70 | [SSA] n | -| main.rs:183:78:183:84 | sink(...) | main.rs:182:5:184:5 | match s1 { ... } | -| main.rs:185:5:188:5 | match s2 { ... } | main.rs:173:49:189:1 | { ... } | -| main.rs:185:11:185:12 | s2 | main.rs:186:9:186:38 | ...::C {...} | -| main.rs:185:11:185:12 | s2 | main.rs:187:9:187:38 | ...::D {...} | -| main.rs:186:36:186:36 | [SSA] n | main.rs:186:48:186:48 | n | -| main.rs:186:36:186:36 | n | main.rs:186:36:186:36 | [SSA] n | -| main.rs:186:43:186:49 | sink(...) | main.rs:185:5:188:5 | match s2 { ... } | -| main.rs:187:36:187:36 | [SSA] n | main.rs:187:48:187:48 | n | -| main.rs:187:36:187:36 | n | main.rs:187:36:187:36 | [SSA] n | -| main.rs:187:43:187:49 | sink(...) | main.rs:185:5:188:5 | match s2 { ... } | -| main.rs:194:9:194:10 | [SSA] s1 | main.rs:198:11:198:12 | s1 | -| main.rs:194:9:194:10 | s1 | main.rs:194:9:194:10 | [SSA] s1 | -| main.rs:194:14:196:5 | C {...} | main.rs:194:9:194:10 | s1 | -| main.rs:197:9:197:10 | [SSA] s2 | main.rs:205:11:205:12 | s2 | -| main.rs:197:9:197:10 | s2 | main.rs:197:9:197:10 | [SSA] s2 | -| main.rs:197:14:197:29 | D {...} | main.rs:197:9:197:10 | s2 | -| main.rs:198:11:198:12 | s1 | main.rs:199:9:199:24 | C {...} | -| main.rs:198:11:198:12 | s1 | main.rs:200:9:200:24 | D {...} | -| main.rs:198:11:198:12 | s1 | main.rs:202:11:202:12 | s1 | -| main.rs:199:22:199:22 | [SSA] n | main.rs:199:34:199:34 | n | -| main.rs:199:22:199:22 | n | main.rs:199:22:199:22 | [SSA] n | -| main.rs:199:29:199:35 | sink(...) | main.rs:198:5:201:5 | match s1 { ... } | -| main.rs:200:22:200:22 | [SSA] n | main.rs:200:34:200:34 | n | -| main.rs:200:22:200:22 | n | main.rs:200:22:200:22 | [SSA] n | -| main.rs:200:29:200:35 | sink(...) | main.rs:198:5:201:5 | match s1 { ... } | -| main.rs:202:11:202:12 | s1 | main.rs:203:10:203:44 | ... \| ... | -| main.rs:203:10:203:44 | ... \| ... | main.rs:203:10:203:25 | C {...} | -| main.rs:203:10:203:44 | ... \| ... | main.rs:203:29:203:44 | D {...} | -| main.rs:203:10:203:44 | [SSA] [match(true)] phi | main.rs:203:55:203:55 | n | -| main.rs:203:23:203:23 | [SSA] [input] [match(true)] phi | main.rs:203:10:203:44 | [SSA] [match(true)] phi | -| main.rs:203:23:203:23 | [SSA] n | main.rs:203:23:203:23 | [SSA] [input] [match(true)] phi | -| main.rs:203:23:203:23 | n | main.rs:203:23:203:23 | [SSA] n | -| main.rs:203:42:203:42 | [SSA] [input] [match(true)] phi | main.rs:203:10:203:44 | [SSA] [match(true)] phi | -| main.rs:203:42:203:42 | [SSA] n | main.rs:203:42:203:42 | [SSA] [input] [match(true)] phi | -| main.rs:203:42:203:42 | n | main.rs:203:42:203:42 | [SSA] n | -| main.rs:203:50:203:56 | sink(...) | main.rs:202:5:204:5 | match s1 { ... } | -| main.rs:205:5:208:5 | match s2 { ... } | main.rs:193:51:209:1 | { ... } | -| main.rs:205:11:205:12 | s2 | main.rs:206:9:206:24 | C {...} | -| main.rs:205:11:205:12 | s2 | main.rs:207:9:207:24 | D {...} | -| main.rs:206:22:206:22 | [SSA] n | main.rs:206:34:206:34 | n | -| main.rs:206:22:206:22 | n | main.rs:206:22:206:22 | [SSA] n | -| main.rs:206:29:206:35 | sink(...) | main.rs:205:5:208:5 | match s2 { ... } | -| main.rs:207:22:207:22 | [SSA] n | main.rs:207:34:207:34 | n | -| main.rs:207:22:207:22 | n | main.rs:207:22:207:22 | [SSA] n | -| main.rs:207:29:207:35 | sink(...) | main.rs:205:5:208:5 | match s2 { ... } | -| main.rs:212:9:212:9 | [SSA] a | main.rs:213:5:213:5 | a | -| main.rs:212:9:212:9 | a | main.rs:212:9:212:9 | [SSA] a | -| main.rs:212:13:212:17 | { ... } | main.rs:212:9:212:9 | a | -| main.rs:212:15:212:15 | 0 | main.rs:212:13:212:17 | { ... } | -| main.rs:213:5:213:5 | a | main.rs:211:31:214:1 | { ... } | -| main.rs:216:22:216:22 | [SSA] b | main.rs:218:12:218:12 | b | -| main.rs:216:22:216:22 | b | main.rs:216:22:216:22 | [SSA] b | -| main.rs:216:22:216:28 | ...: bool | main.rs:216:22:216:22 | b | -| main.rs:217:9:217:9 | [SSA] a | main.rs:223:5:223:5 | a | -| main.rs:217:9:217:9 | a | main.rs:217:9:217:9 | [SSA] a | -| main.rs:217:13:222:5 | 'block: { ... } | main.rs:217:9:217:9 | a | -| main.rs:219:13:219:26 | break ''block 1 | main.rs:217:13:222:5 | 'block: { ... } | -| main.rs:219:26:219:26 | 1 | main.rs:219:13:219:26 | break ''block 1 | -| main.rs:221:9:221:9 | 2 | main.rs:217:13:222:5 | 'block: { ... } | -| main.rs:223:5:223:5 | a | main.rs:216:38:224:1 | { ... } | -| main.rs:226:22:226:22 | [SSA] b | main.rs:228:12:228:12 | b | -| main.rs:226:22:226:22 | b | main.rs:226:22:226:22 | [SSA] b | -| main.rs:226:22:226:28 | ...: bool | main.rs:226:22:226:22 | b | -| main.rs:227:9:227:9 | [SSA] a | main.rs:233:5:233:5 | a | -| main.rs:227:9:227:9 | a | main.rs:227:9:227:9 | [SSA] a | -| main.rs:227:13:232:5 | 'block: { ... } | main.rs:227:9:227:9 | a | -| main.rs:229:13:229:26 | break ''block 1 | main.rs:227:13:232:5 | 'block: { ... } | -| main.rs:229:26:229:26 | 1 | main.rs:229:13:229:26 | break ''block 1 | -| main.rs:231:9:231:22 | break ''block 2 | main.rs:227:13:232:5 | 'block: { ... } | -| main.rs:231:22:231:22 | 2 | main.rs:231:9:231:22 | break ''block 2 | -| main.rs:233:5:233:5 | a | main.rs:226:38:234:1 | { ... } | +| main.rs:58:9:58:9 | [SSA] a | main.rs:59:5:59:5 | a | +| main.rs:58:9:58:9 | a | main.rs:58:9:58:9 | [SSA] a | +| main.rs:58:13:58:17 | { ... } | main.rs:58:9:58:9 | a | +| main.rs:58:15:58:15 | 0 | main.rs:58:13:58:17 | { ... } | +| main.rs:59:5:59:5 | a | main.rs:57:31:60:1 | { ... } | +| main.rs:62:22:62:22 | [SSA] b | main.rs:64:12:64:12 | b | +| main.rs:62:22:62:22 | b | main.rs:62:22:62:22 | [SSA] b | +| main.rs:62:22:62:28 | ...: bool | main.rs:62:22:62:22 | b | +| main.rs:63:9:63:9 | [SSA] a | main.rs:69:5:69:5 | a | +| main.rs:63:9:63:9 | a | main.rs:63:9:63:9 | [SSA] a | +| main.rs:63:13:68:5 | 'block: { ... } | main.rs:63:9:63:9 | a | +| main.rs:65:13:65:26 | break ''block 1 | main.rs:63:13:68:5 | 'block: { ... } | +| main.rs:65:26:65:26 | 1 | main.rs:65:13:65:26 | break ''block 1 | +| main.rs:67:9:67:9 | 2 | main.rs:63:13:68:5 | 'block: { ... } | +| main.rs:69:5:69:5 | a | main.rs:62:38:70:1 | { ... } | +| main.rs:72:22:72:22 | [SSA] b | main.rs:74:12:74:12 | b | +| main.rs:72:22:72:22 | b | main.rs:72:22:72:22 | [SSA] b | +| main.rs:72:22:72:28 | ...: bool | main.rs:72:22:72:22 | b | +| main.rs:73:9:73:9 | [SSA] a | main.rs:79:5:79:5 | a | +| main.rs:73:9:73:9 | a | main.rs:73:9:73:9 | [SSA] a | +| main.rs:73:13:78:5 | 'block: { ... } | main.rs:73:9:73:9 | a | +| main.rs:75:13:75:26 | break ''block 1 | main.rs:73:13:78:5 | 'block: { ... } | +| main.rs:75:26:75:26 | 1 | main.rs:75:13:75:26 | break ''block 1 | +| main.rs:77:9:77:22 | break ''block 2 | main.rs:73:13:78:5 | 'block: { ... } | +| main.rs:77:22:77:22 | 2 | main.rs:77:9:77:22 | break ''block 2 | +| main.rs:79:5:79:5 | a | main.rs:72:38:80:1 | { ... } | +| main.rs:86:9:86:9 | [SSA] i | main.rs:87:11:87:11 | i | +| main.rs:86:9:86:9 | i | main.rs:86:9:86:9 | [SSA] i | +| main.rs:86:13:86:31 | ...::new(...) | main.rs:86:9:86:9 | i | +| main.rs:94:9:94:9 | [SSA] a | main.rs:95:10:95:10 | a | +| main.rs:94:9:94:9 | a | main.rs:94:9:94:9 | [SSA] a | +| main.rs:94:13:94:26 | TupleExpr | main.rs:94:9:94:9 | a | +| main.rs:95:10:95:10 | a | main.rs:96:10:96:10 | a | +| main.rs:100:9:100:9 | [SSA] a | main.rs:101:24:101:24 | a | +| main.rs:100:9:100:9 | a | main.rs:100:9:100:9 | [SSA] a | +| main.rs:100:13:100:30 | TupleExpr | main.rs:100:9:100:9 | a | +| main.rs:101:10:101:11 | [SSA] a0 | main.rs:102:10:102:11 | a0 | +| main.rs:101:10:101:11 | a0 | main.rs:101:10:101:11 | [SSA] a0 | +| main.rs:101:14:101:15 | [SSA] a1 | main.rs:103:10:103:11 | a1 | +| main.rs:101:14:101:15 | a1 | main.rs:101:14:101:15 | [SSA] a1 | +| main.rs:101:18:101:19 | [SSA] a2 | main.rs:104:10:104:11 | a2 | +| main.rs:101:18:101:19 | a2 | main.rs:101:18:101:19 | [SSA] a2 | +| main.rs:101:24:101:24 | a | main.rs:101:9:101:20 | TuplePat | +| main.rs:108:9:108:13 | [SSA] a | main.rs:109:10:109:10 | a | +| main.rs:108:9:108:13 | a | main.rs:108:9:108:13 | [SSA] a | +| main.rs:108:17:108:31 | TupleExpr | main.rs:108:9:108:13 | a | +| main.rs:109:10:109:10 | a | main.rs:110:10:110:10 | a | +| main.rs:110:10:110:10 | a | main.rs:111:5:111:5 | a | +| main.rs:111:5:111:5 | a | main.rs:112:5:112:5 | a | +| main.rs:111:11:111:11 | 2 | main.rs:111:5:111:7 | a.1 | +| main.rs:112:5:112:5 | a | main.rs:113:10:113:10 | a | +| main.rs:112:11:112:20 | source(...) | main.rs:112:5:112:7 | a.0 | +| main.rs:113:10:113:10 | a | main.rs:114:10:114:10 | a | +| main.rs:118:9:118:9 | [SSA] a | main.rs:119:14:119:14 | a | +| main.rs:118:9:118:9 | a | main.rs:118:9:118:9 | [SSA] a | +| main.rs:118:13:118:27 | TupleExpr | main.rs:118:9:118:9 | a | +| main.rs:119:9:119:9 | [SSA] b | main.rs:120:10:120:10 | b | +| main.rs:119:9:119:9 | b | main.rs:119:9:119:9 | [SSA] b | +| main.rs:119:13:119:18 | TupleExpr | main.rs:119:9:119:9 | b | +| main.rs:120:10:120:10 | b | main.rs:121:10:121:10 | b | +| main.rs:121:10:121:10 | b | main.rs:122:10:122:10 | b | +| main.rs:134:9:134:9 | [SSA] p | main.rs:138:10:138:10 | p | +| main.rs:134:9:134:9 | p | main.rs:134:9:134:9 | [SSA] p | +| main.rs:134:13:137:5 | Point {...} | main.rs:134:9:134:9 | p | +| main.rs:138:10:138:10 | p | main.rs:139:10:139:10 | p | +| main.rs:143:9:143:13 | [SSA] p | main.rs:147:10:147:10 | p | +| main.rs:143:9:143:13 | p | main.rs:143:9:143:13 | [SSA] p | +| main.rs:143:17:146:5 | Point {...} | main.rs:143:9:143:13 | p | +| main.rs:147:10:147:10 | p | main.rs:148:5:148:5 | p | +| main.rs:148:5:148:5 | p | main.rs:149:10:149:10 | p | +| main.rs:148:11:148:20 | source(...) | main.rs:148:5:148:7 | p.y | +| main.rs:153:9:153:9 | [SSA] p | main.rs:157:32:157:32 | p | +| main.rs:153:9:153:9 | p | main.rs:153:9:153:9 | [SSA] p | +| main.rs:153:13:156:5 | Point {...} | main.rs:153:9:153:9 | p | +| main.rs:157:20:157:20 | [SSA] a | main.rs:158:10:158:10 | a | +| main.rs:157:20:157:20 | a | main.rs:157:20:157:20 | [SSA] a | +| main.rs:157:26:157:26 | [SSA] b | main.rs:159:10:159:10 | b | +| main.rs:157:26:157:26 | b | main.rs:157:26:157:26 | [SSA] b | +| main.rs:157:32:157:32 | p | main.rs:157:9:157:28 | Point {...} | +| main.rs:168:9:168:9 | [SSA] p | main.rs:175:10:175:10 | p | +| main.rs:168:9:168:9 | p | main.rs:168:9:168:9 | [SSA] p | +| main.rs:168:13:174:5 | Point3D {...} | main.rs:168:9:168:9 | p | +| main.rs:175:10:175:10 | p | main.rs:176:10:176:10 | p | +| main.rs:176:10:176:10 | p | main.rs:177:10:177:10 | p | +| main.rs:181:9:181:9 | [SSA] p | main.rs:188:11:188:11 | p | +| main.rs:181:9:181:9 | p | main.rs:181:9:181:9 | [SSA] p | +| main.rs:181:13:187:5 | Point3D {...} | main.rs:181:9:181:9 | p | +| main.rs:188:5:194:5 | match p { ... } | main.rs:180:26:195:1 | { ... } | +| main.rs:188:11:188:11 | p | main.rs:189:9:189:45 | Point3D {...} | +| main.rs:189:34:189:34 | [SSA] x | main.rs:190:18:190:18 | x | +| main.rs:189:34:189:34 | x | main.rs:189:34:189:34 | [SSA] x | +| main.rs:189:37:189:37 | [SSA] y | main.rs:191:18:191:18 | y | +| main.rs:189:37:189:37 | y | main.rs:189:37:189:37 | [SSA] y | +| main.rs:189:42:189:42 | [SSA] z | main.rs:192:18:192:18 | z | +| main.rs:189:42:189:42 | z | main.rs:189:42:189:42 | [SSA] z | +| main.rs:189:50:193:9 | { ... } | main.rs:188:5:194:5 | match p { ... } | +| main.rs:201:9:201:10 | [SSA] s1 | main.rs:203:11:203:12 | s1 | +| main.rs:201:9:201:10 | s1 | main.rs:201:9:201:10 | [SSA] s1 | +| main.rs:201:14:201:37 | ...::Some(...) | main.rs:201:9:201:10 | s1 | +| main.rs:202:9:202:10 | [SSA] s2 | main.rs:207:11:207:12 | s2 | +| main.rs:202:9:202:10 | s2 | main.rs:202:9:202:10 | [SSA] s2 | +| main.rs:202:14:202:28 | ...::Some(...) | main.rs:202:9:202:10 | s2 | +| main.rs:203:11:203:12 | s1 | main.rs:204:9:204:23 | TupleStructPat | +| main.rs:203:11:203:12 | s1 | main.rs:205:9:205:20 | ...::None | +| main.rs:204:22:204:22 | [SSA] n | main.rs:204:33:204:33 | n | +| main.rs:204:22:204:22 | n | main.rs:204:22:204:22 | [SSA] n | +| main.rs:204:28:204:34 | sink(...) | main.rs:203:5:206:5 | match s1 { ... } | +| main.rs:205:25:205:31 | sink(...) | main.rs:203:5:206:5 | match s1 { ... } | +| main.rs:207:5:210:5 | match s2 { ... } | main.rs:200:37:211:1 | { ... } | +| main.rs:207:11:207:12 | s2 | main.rs:208:9:208:23 | TupleStructPat | +| main.rs:207:11:207:12 | s2 | main.rs:209:9:209:20 | ...::None | +| main.rs:208:22:208:22 | [SSA] n | main.rs:208:33:208:33 | n | +| main.rs:208:22:208:22 | n | main.rs:208:22:208:22 | [SSA] n | +| main.rs:208:28:208:34 | sink(...) | main.rs:207:5:210:5 | match s2 { ... } | +| main.rs:209:25:209:31 | sink(...) | main.rs:207:5:210:5 | match s2 { ... } | +| main.rs:214:9:214:10 | [SSA] s1 | main.rs:216:11:216:12 | s1 | +| main.rs:214:9:214:10 | s1 | main.rs:214:9:214:10 | [SSA] s1 | +| main.rs:214:14:214:29 | Some(...) | main.rs:214:9:214:10 | s1 | +| main.rs:215:9:215:10 | [SSA] s2 | main.rs:220:11:220:12 | s2 | +| main.rs:215:9:215:10 | s2 | main.rs:215:9:215:10 | [SSA] s2 | +| main.rs:215:14:215:20 | Some(...) | main.rs:215:9:215:10 | s2 | +| main.rs:216:11:216:12 | s1 | main.rs:217:9:217:15 | TupleStructPat | +| main.rs:216:11:216:12 | s1 | main.rs:218:9:218:12 | None | +| main.rs:217:14:217:14 | [SSA] n | main.rs:217:25:217:25 | n | +| main.rs:217:14:217:14 | n | main.rs:217:14:217:14 | [SSA] n | +| main.rs:217:20:217:26 | sink(...) | main.rs:216:5:219:5 | match s1 { ... } | +| main.rs:218:17:218:23 | sink(...) | main.rs:216:5:219:5 | match s1 { ... } | +| main.rs:220:5:223:5 | match s2 { ... } | main.rs:213:39:224:1 | { ... } | +| main.rs:220:11:220:12 | s2 | main.rs:221:9:221:15 | TupleStructPat | +| main.rs:220:11:220:12 | s2 | main.rs:222:9:222:12 | None | +| main.rs:221:14:221:14 | [SSA] n | main.rs:221:25:221:25 | n | +| main.rs:221:14:221:14 | n | main.rs:221:14:221:14 | [SSA] n | +| main.rs:221:20:221:26 | sink(...) | main.rs:220:5:223:5 | match s2 { ... } | +| main.rs:222:17:222:23 | sink(...) | main.rs:220:5:223:5 | match s2 { ... } | +| main.rs:232:9:232:10 | [SSA] s1 | main.rs:234:11:234:12 | s1 | +| main.rs:232:9:232:10 | s1 | main.rs:232:9:232:10 | [SSA] s1 | +| main.rs:232:14:232:39 | ...::A(...) | main.rs:232:9:232:10 | s1 | +| main.rs:233:9:233:10 | [SSA] s2 | main.rs:241:11:241:12 | s2 | +| main.rs:233:9:233:10 | s2 | main.rs:233:9:233:10 | [SSA] s2 | +| main.rs:233:14:233:30 | ...::B(...) | main.rs:233:9:233:10 | s2 | +| main.rs:234:11:234:12 | s1 | main.rs:235:9:235:25 | TupleStructPat | +| main.rs:234:11:234:12 | s1 | main.rs:236:9:236:25 | TupleStructPat | +| main.rs:234:11:234:12 | s1 | main.rs:238:11:238:12 | s1 | +| main.rs:235:24:235:24 | [SSA] n | main.rs:235:35:235:35 | n | +| main.rs:235:24:235:24 | n | main.rs:235:24:235:24 | [SSA] n | +| main.rs:235:30:235:36 | sink(...) | main.rs:234:5:237:5 | match s1 { ... } | +| main.rs:236:24:236:24 | [SSA] n | main.rs:236:35:236:35 | n | +| main.rs:236:24:236:24 | n | main.rs:236:24:236:24 | [SSA] n | +| main.rs:236:30:236:36 | sink(...) | main.rs:234:5:237:5 | match s1 { ... } | +| main.rs:238:11:238:12 | s1 | main.rs:239:9:239:45 | ... \| ... | +| main.rs:239:9:239:45 | ... \| ... | main.rs:239:9:239:25 | TupleStructPat | +| main.rs:239:9:239:45 | ... \| ... | main.rs:239:29:239:45 | TupleStructPat | +| main.rs:239:9:239:45 | [SSA] [match(true)] phi | main.rs:239:55:239:55 | n | +| main.rs:239:24:239:24 | [SSA] [input] [match(true)] phi | main.rs:239:9:239:45 | [SSA] [match(true)] phi | +| main.rs:239:24:239:24 | [SSA] n | main.rs:239:24:239:24 | [SSA] [input] [match(true)] phi | +| main.rs:239:24:239:24 | n | main.rs:239:24:239:24 | [SSA] n | +| main.rs:239:44:239:44 | [SSA] [input] [match(true)] phi | main.rs:239:9:239:45 | [SSA] [match(true)] phi | +| main.rs:239:44:239:44 | [SSA] n | main.rs:239:44:239:44 | [SSA] [input] [match(true)] phi | +| main.rs:239:44:239:44 | n | main.rs:239:44:239:44 | [SSA] n | +| main.rs:239:50:239:56 | sink(...) | main.rs:238:5:240:5 | match s1 { ... } | +| main.rs:241:5:244:5 | match s2 { ... } | main.rs:231:48:245:1 | { ... } | +| main.rs:241:11:241:12 | s2 | main.rs:242:9:242:25 | TupleStructPat | +| main.rs:241:11:241:12 | s2 | main.rs:243:9:243:25 | TupleStructPat | +| main.rs:242:24:242:24 | [SSA] n | main.rs:242:35:242:35 | n | +| main.rs:242:24:242:24 | n | main.rs:242:24:242:24 | [SSA] n | +| main.rs:242:30:242:36 | sink(...) | main.rs:241:5:244:5 | match s2 { ... } | +| main.rs:243:24:243:24 | [SSA] n | main.rs:243:35:243:35 | n | +| main.rs:243:24:243:24 | n | main.rs:243:24:243:24 | [SSA] n | +| main.rs:243:30:243:36 | sink(...) | main.rs:241:5:244:5 | match s2 { ... } | +| main.rs:250:9:250:10 | [SSA] s1 | main.rs:252:11:252:12 | s1 | +| main.rs:250:9:250:10 | s1 | main.rs:250:9:250:10 | [SSA] s1 | +| main.rs:250:14:250:26 | A(...) | main.rs:250:9:250:10 | s1 | +| main.rs:251:9:251:10 | [SSA] s2 | main.rs:259:11:259:12 | s2 | +| main.rs:251:9:251:10 | s2 | main.rs:251:9:251:10 | [SSA] s2 | +| main.rs:251:14:251:17 | B(...) | main.rs:251:9:251:10 | s2 | +| main.rs:252:11:252:12 | s1 | main.rs:253:9:253:12 | TupleStructPat | +| main.rs:252:11:252:12 | s1 | main.rs:254:9:254:12 | TupleStructPat | +| main.rs:252:11:252:12 | s1 | main.rs:256:11:256:12 | s1 | +| main.rs:253:11:253:11 | [SSA] n | main.rs:253:22:253:22 | n | +| main.rs:253:11:253:11 | n | main.rs:253:11:253:11 | [SSA] n | +| main.rs:253:17:253:23 | sink(...) | main.rs:252:5:255:5 | match s1 { ... } | +| main.rs:254:11:254:11 | [SSA] n | main.rs:254:22:254:22 | n | +| main.rs:254:11:254:11 | n | main.rs:254:11:254:11 | [SSA] n | +| main.rs:254:17:254:23 | sink(...) | main.rs:252:5:255:5 | match s1 { ... } | +| main.rs:256:11:256:12 | s1 | main.rs:257:9:257:19 | ... \| ... | +| main.rs:257:9:257:19 | ... \| ... | main.rs:257:9:257:12 | TupleStructPat | +| main.rs:257:9:257:19 | ... \| ... | main.rs:257:16:257:19 | TupleStructPat | +| main.rs:257:9:257:19 | [SSA] [match(true)] phi | main.rs:257:29:257:29 | n | +| main.rs:257:11:257:11 | [SSA] [input] [match(true)] phi | main.rs:257:9:257:19 | [SSA] [match(true)] phi | +| main.rs:257:11:257:11 | [SSA] n | main.rs:257:11:257:11 | [SSA] [input] [match(true)] phi | +| main.rs:257:11:257:11 | n | main.rs:257:11:257:11 | [SSA] n | +| main.rs:257:18:257:18 | [SSA] [input] [match(true)] phi | main.rs:257:9:257:19 | [SSA] [match(true)] phi | +| main.rs:257:18:257:18 | [SSA] n | main.rs:257:18:257:18 | [SSA] [input] [match(true)] phi | +| main.rs:257:18:257:18 | n | main.rs:257:18:257:18 | [SSA] n | +| main.rs:257:24:257:30 | sink(...) | main.rs:256:5:258:5 | match s1 { ... } | +| main.rs:259:5:262:5 | match s2 { ... } | main.rs:249:50:263:1 | { ... } | +| main.rs:259:11:259:12 | s2 | main.rs:260:9:260:12 | TupleStructPat | +| main.rs:259:11:259:12 | s2 | main.rs:261:9:261:12 | TupleStructPat | +| main.rs:260:11:260:11 | [SSA] n | main.rs:260:22:260:22 | n | +| main.rs:260:11:260:11 | n | main.rs:260:11:260:11 | [SSA] n | +| main.rs:260:17:260:23 | sink(...) | main.rs:259:5:262:5 | match s2 { ... } | +| main.rs:261:11:261:11 | [SSA] n | main.rs:261:22:261:22 | n | +| main.rs:261:11:261:11 | n | main.rs:261:11:261:11 | [SSA] n | +| main.rs:261:17:261:23 | sink(...) | main.rs:259:5:262:5 | match s2 { ... } | +| main.rs:271:9:271:10 | [SSA] s1 | main.rs:275:11:275:12 | s1 | +| main.rs:271:9:271:10 | s1 | main.rs:271:9:271:10 | [SSA] s1 | +| main.rs:271:14:273:5 | ...::C {...} | main.rs:271:9:271:10 | s1 | +| main.rs:274:9:274:10 | [SSA] s2 | main.rs:282:11:282:12 | s2 | +| main.rs:274:9:274:10 | s2 | main.rs:274:9:274:10 | [SSA] s2 | +| main.rs:274:14:274:43 | ...::D {...} | main.rs:274:9:274:10 | s2 | +| main.rs:275:11:275:12 | s1 | main.rs:276:9:276:38 | ...::C {...} | +| main.rs:275:11:275:12 | s1 | main.rs:277:9:277:38 | ...::D {...} | +| main.rs:275:11:275:12 | s1 | main.rs:279:11:279:12 | s1 | +| main.rs:276:36:276:36 | [SSA] n | main.rs:276:48:276:48 | n | +| main.rs:276:36:276:36 | n | main.rs:276:36:276:36 | [SSA] n | +| main.rs:276:43:276:49 | sink(...) | main.rs:275:5:278:5 | match s1 { ... } | +| main.rs:277:36:277:36 | [SSA] n | main.rs:277:48:277:48 | n | +| main.rs:277:36:277:36 | n | main.rs:277:36:277:36 | [SSA] n | +| main.rs:277:43:277:49 | sink(...) | main.rs:275:5:278:5 | match s1 { ... } | +| main.rs:279:11:279:12 | s1 | main.rs:280:9:280:71 | ... \| ... | +| main.rs:280:9:280:71 | ... \| ... | main.rs:280:9:280:38 | ...::C {...} | +| main.rs:280:9:280:71 | ... \| ... | main.rs:280:42:280:71 | ...::D {...} | +| main.rs:280:9:280:71 | [SSA] [match(true)] phi | main.rs:280:81:280:81 | n | +| main.rs:280:36:280:36 | [SSA] [input] [match(true)] phi | main.rs:280:9:280:71 | [SSA] [match(true)] phi | +| main.rs:280:36:280:36 | [SSA] n | main.rs:280:36:280:36 | [SSA] [input] [match(true)] phi | +| main.rs:280:36:280:36 | n | main.rs:280:36:280:36 | [SSA] n | +| main.rs:280:69:280:69 | [SSA] [input] [match(true)] phi | main.rs:280:9:280:71 | [SSA] [match(true)] phi | +| main.rs:280:69:280:69 | [SSA] n | main.rs:280:69:280:69 | [SSA] [input] [match(true)] phi | +| main.rs:280:69:280:69 | n | main.rs:280:69:280:69 | [SSA] n | +| main.rs:280:76:280:82 | sink(...) | main.rs:279:5:281:5 | match s1 { ... } | +| main.rs:282:5:285:5 | match s2 { ... } | main.rs:270:49:286:1 | { ... } | +| main.rs:282:11:282:12 | s2 | main.rs:283:9:283:38 | ...::C {...} | +| main.rs:282:11:282:12 | s2 | main.rs:284:9:284:38 | ...::D {...} | +| main.rs:283:36:283:36 | [SSA] n | main.rs:283:48:283:48 | n | +| main.rs:283:36:283:36 | n | main.rs:283:36:283:36 | [SSA] n | +| main.rs:283:43:283:49 | sink(...) | main.rs:282:5:285:5 | match s2 { ... } | +| main.rs:284:36:284:36 | [SSA] n | main.rs:284:48:284:48 | n | +| main.rs:284:36:284:36 | n | main.rs:284:36:284:36 | [SSA] n | +| main.rs:284:43:284:49 | sink(...) | main.rs:282:5:285:5 | match s2 { ... } | +| main.rs:291:9:291:10 | [SSA] s1 | main.rs:295:11:295:12 | s1 | +| main.rs:291:9:291:10 | s1 | main.rs:291:9:291:10 | [SSA] s1 | +| main.rs:291:14:293:5 | C {...} | main.rs:291:9:291:10 | s1 | +| main.rs:294:9:294:10 | [SSA] s2 | main.rs:302:11:302:12 | s2 | +| main.rs:294:9:294:10 | s2 | main.rs:294:9:294:10 | [SSA] s2 | +| main.rs:294:14:294:29 | D {...} | main.rs:294:9:294:10 | s2 | +| main.rs:295:11:295:12 | s1 | main.rs:296:9:296:24 | C {...} | +| main.rs:295:11:295:12 | s1 | main.rs:297:9:297:24 | D {...} | +| main.rs:295:11:295:12 | s1 | main.rs:299:11:299:12 | s1 | +| main.rs:296:22:296:22 | [SSA] n | main.rs:296:34:296:34 | n | +| main.rs:296:22:296:22 | n | main.rs:296:22:296:22 | [SSA] n | +| main.rs:296:29:296:35 | sink(...) | main.rs:295:5:298:5 | match s1 { ... } | +| main.rs:297:22:297:22 | [SSA] n | main.rs:297:34:297:34 | n | +| main.rs:297:22:297:22 | n | main.rs:297:22:297:22 | [SSA] n | +| main.rs:297:29:297:35 | sink(...) | main.rs:295:5:298:5 | match s1 { ... } | +| main.rs:299:11:299:12 | s1 | main.rs:300:9:300:43 | ... \| ... | +| main.rs:300:9:300:43 | ... \| ... | main.rs:300:9:300:24 | C {...} | +| main.rs:300:9:300:43 | ... \| ... | main.rs:300:28:300:43 | D {...} | +| main.rs:300:9:300:43 | [SSA] [match(true)] phi | main.rs:300:53:300:53 | n | +| main.rs:300:22:300:22 | [SSA] [input] [match(true)] phi | main.rs:300:9:300:43 | [SSA] [match(true)] phi | +| main.rs:300:22:300:22 | [SSA] n | main.rs:300:22:300:22 | [SSA] [input] [match(true)] phi | +| main.rs:300:22:300:22 | n | main.rs:300:22:300:22 | [SSA] n | +| main.rs:300:41:300:41 | [SSA] [input] [match(true)] phi | main.rs:300:9:300:43 | [SSA] [match(true)] phi | +| main.rs:300:41:300:41 | [SSA] n | main.rs:300:41:300:41 | [SSA] [input] [match(true)] phi | +| main.rs:300:41:300:41 | n | main.rs:300:41:300:41 | [SSA] n | +| main.rs:300:48:300:54 | sink(...) | main.rs:299:5:301:5 | match s1 { ... } | +| main.rs:302:5:305:5 | match s2 { ... } | main.rs:290:51:306:1 | { ... } | +| main.rs:302:11:302:12 | s2 | main.rs:303:9:303:24 | C {...} | +| main.rs:302:11:302:12 | s2 | main.rs:304:9:304:24 | D {...} | +| main.rs:303:22:303:22 | [SSA] n | main.rs:303:34:303:34 | n | +| main.rs:303:22:303:22 | n | main.rs:303:22:303:22 | [SSA] n | +| main.rs:303:29:303:35 | sink(...) | main.rs:302:5:305:5 | match s2 { ... } | +| main.rs:304:22:304:22 | [SSA] n | main.rs:304:34:304:34 | n | +| main.rs:304:22:304:22 | n | main.rs:304:22:304:22 | [SSA] n | +| main.rs:304:29:304:35 | sink(...) | main.rs:302:5:305:5 | match s2 { ... } | storeStep -| main.rs:117:19:117:28 | source(...) | Some | main.rs:117:14:117:29 | Some(...) | -| main.rs:118:19:118:19 | 2 | Some | main.rs:118:14:118:20 | Some(...) | -| main.rs:135:29:135:38 | source(...) | A | main.rs:135:14:135:39 | ...::A(...) | -| main.rs:136:29:136:29 | 2 | B | main.rs:136:14:136:30 | ...::B(...) | -| main.rs:175:18:175:27 | source(...) | C | main.rs:174:14:176:5 | ...::C {...} | -| main.rs:177:41:177:41 | 2 | D | main.rs:177:14:177:43 | ...::D {...} | -| main.rs:240:27:240:27 | 0 | Some | main.rs:240:22:240:28 | Some(...) | +| main.rs:214:19:214:28 | source(...) | Some | main.rs:214:14:214:29 | Some(...) | +| main.rs:215:19:215:19 | 2 | Some | main.rs:215:14:215:20 | Some(...) | +| main.rs:232:29:232:38 | source(...) | A | main.rs:232:14:232:39 | ...::A(...) | +| main.rs:233:29:233:29 | 2 | B | main.rs:233:14:233:30 | ...::B(...) | +| main.rs:272:18:272:27 | source(...) | C | main.rs:271:14:273:5 | ...::C {...} | +| main.rs:274:41:274:41 | 2 | D | main.rs:274:14:274:43 | ...::D {...} | +| main.rs:312:27:312:27 | 0 | Some | main.rs:312:22:312:28 | Some(...) | readStep | main.rs:33:9:33:15 | TupleStructPat | Some | main.rs:33:14:33:14 | _ | -| main.rs:120:9:120:15 | TupleStructPat | Some | main.rs:120:14:120:14 | n | -| main.rs:124:9:124:15 | TupleStructPat | Some | main.rs:124:14:124:14 | n | -| main.rs:138:9:138:25 | TupleStructPat | A | main.rs:138:24:138:24 | n | -| main.rs:139:9:139:25 | TupleStructPat | B | main.rs:139:24:139:24 | n | -| main.rs:142:10:142:26 | TupleStructPat | A | main.rs:142:25:142:25 | n | -| main.rs:142:30:142:46 | TupleStructPat | B | main.rs:142:45:142:45 | n | -| main.rs:145:9:145:25 | TupleStructPat | A | main.rs:145:24:145:24 | n | -| main.rs:146:9:146:25 | TupleStructPat | B | main.rs:146:24:146:24 | n | -| main.rs:179:9:179:38 | ...::C {...} | C | main.rs:179:36:179:36 | n | -| main.rs:180:9:180:38 | ...::D {...} | D | main.rs:180:36:180:36 | n | -| main.rs:183:10:183:39 | ...::C {...} | C | main.rs:183:37:183:37 | n | -| main.rs:183:43:183:72 | ...::D {...} | D | main.rs:183:70:183:70 | n | -| main.rs:186:9:186:38 | ...::C {...} | C | main.rs:186:36:186:36 | n | -| main.rs:187:9:187:38 | ...::D {...} | D | main.rs:187:36:187:36 | n | +| main.rs:217:9:217:15 | TupleStructPat | Some | main.rs:217:14:217:14 | n | +| main.rs:221:9:221:15 | TupleStructPat | Some | main.rs:221:14:221:14 | n | +| main.rs:235:9:235:25 | TupleStructPat | A | main.rs:235:24:235:24 | n | +| main.rs:236:9:236:25 | TupleStructPat | B | main.rs:236:24:236:24 | n | +| main.rs:239:9:239:25 | TupleStructPat | A | main.rs:239:24:239:24 | n | +| main.rs:239:29:239:45 | TupleStructPat | B | main.rs:239:44:239:44 | n | +| main.rs:242:9:242:25 | TupleStructPat | A | main.rs:242:24:242:24 | n | +| main.rs:243:9:243:25 | TupleStructPat | B | main.rs:243:24:243:24 | n | +| main.rs:276:9:276:38 | ...::C {...} | C | main.rs:276:36:276:36 | n | +| main.rs:277:9:277:38 | ...::D {...} | D | main.rs:277:36:277:36 | n | +| main.rs:280:9:280:38 | ...::C {...} | C | main.rs:280:36:280:36 | n | +| main.rs:280:42:280:71 | ...::D {...} | D | main.rs:280:69:280:69 | n | +| main.rs:283:9:283:38 | ...::C {...} | C | main.rs:283:36:283:36 | n | +| main.rs:284:9:284:38 | ...::D {...} | D | main.rs:284:36:284:36 | n | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index bfafa38c3ff..d9a10521997 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -5,24 +5,24 @@ edges | main.rs:31:13:31:21 | source(...) | main.rs:36:10:36:10 | b | provenance | | | main.rs:45:15:45:23 | source(...) | main.rs:47:10:47:10 | b | provenance | | | main.rs:53:9:53:17 | source(...) | main.rs:54:10:54:10 | i | provenance | | -| main.rs:117:14:117:29 | Some(...) [Some] | main.rs:120:9:120:15 | TupleStructPat [Some] | provenance | | -| main.rs:117:19:117:28 | source(...) | main.rs:117:14:117:29 | Some(...) [Some] | provenance | | -| main.rs:120:9:120:15 | TupleStructPat [Some] | main.rs:120:14:120:14 | n | provenance | | -| main.rs:120:14:120:14 | n | main.rs:120:25:120:25 | n | provenance | | -| main.rs:135:14:135:39 | ...::A(...) [A] | main.rs:138:9:138:25 | TupleStructPat [A] | provenance | | -| main.rs:135:14:135:39 | ...::A(...) [A] | main.rs:142:10:142:26 | TupleStructPat [A] | provenance | | -| main.rs:135:29:135:38 | source(...) | main.rs:135:14:135:39 | ...::A(...) [A] | provenance | | -| main.rs:138:9:138:25 | TupleStructPat [A] | main.rs:138:24:138:24 | n | provenance | | -| main.rs:138:24:138:24 | n | main.rs:138:35:138:35 | n | provenance | | -| main.rs:142:10:142:26 | TupleStructPat [A] | main.rs:142:25:142:25 | n | provenance | | -| main.rs:142:25:142:25 | n | main.rs:142:57:142:57 | n | provenance | | -| main.rs:174:14:176:5 | ...::C {...} [C] | main.rs:179:9:179:38 | ...::C {...} [C] | provenance | | -| main.rs:174:14:176:5 | ...::C {...} [C] | main.rs:183:10:183:39 | ...::C {...} [C] | provenance | | -| main.rs:175:18:175:27 | source(...) | main.rs:174:14:176:5 | ...::C {...} [C] | provenance | | -| main.rs:179:9:179:38 | ...::C {...} [C] | main.rs:179:36:179:36 | n | provenance | | -| main.rs:179:36:179:36 | n | main.rs:179:48:179:48 | n | provenance | | -| main.rs:183:10:183:39 | ...::C {...} [C] | main.rs:183:37:183:37 | n | provenance | | -| main.rs:183:37:183:37 | n | main.rs:183:83:183:83 | n | provenance | | +| main.rs:214:14:214:29 | Some(...) [Some] | main.rs:217:9:217:15 | TupleStructPat [Some] | provenance | | +| main.rs:214:19:214:28 | source(...) | main.rs:214:14:214:29 | Some(...) [Some] | provenance | | +| main.rs:217:9:217:15 | TupleStructPat [Some] | main.rs:217:14:217:14 | n | provenance | | +| main.rs:217:14:217:14 | n | main.rs:217:25:217:25 | n | provenance | | +| main.rs:232:14:232:39 | ...::A(...) [A] | main.rs:235:9:235:25 | TupleStructPat [A] | provenance | | +| main.rs:232:14:232:39 | ...::A(...) [A] | main.rs:239:9:239:25 | TupleStructPat [A] | provenance | | +| main.rs:232:29:232:38 | source(...) | main.rs:232:14:232:39 | ...::A(...) [A] | provenance | | +| main.rs:235:9:235:25 | TupleStructPat [A] | main.rs:235:24:235:24 | n | provenance | | +| main.rs:235:24:235:24 | n | main.rs:235:35:235:35 | n | provenance | | +| main.rs:239:9:239:25 | TupleStructPat [A] | main.rs:239:24:239:24 | n | provenance | | +| main.rs:239:24:239:24 | n | main.rs:239:55:239:55 | n | provenance | | +| main.rs:271:14:273:5 | ...::C {...} [C] | main.rs:276:9:276:38 | ...::C {...} [C] | provenance | | +| main.rs:271:14:273:5 | ...::C {...} [C] | main.rs:280:9:280:38 | ...::C {...} [C] | provenance | | +| main.rs:272:18:272:27 | source(...) | main.rs:271:14:273:5 | ...::C {...} [C] | provenance | | +| main.rs:276:9:276:38 | ...::C {...} [C] | main.rs:276:36:276:36 | n | provenance | | +| main.rs:276:36:276:36 | n | main.rs:276:48:276:48 | n | provenance | | +| main.rs:280:9:280:38 | ...::C {...} [C] | main.rs:280:36:280:36 | n | provenance | | +| main.rs:280:36:280:36 | n | main.rs:280:81:280:81 | n | provenance | | nodes | main.rs:15:10:15:18 | source(...) | semmle.label | source(...) | | main.rs:19:13:19:21 | source(...) | semmle.label | source(...) | @@ -35,27 +35,27 @@ nodes | main.rs:47:10:47:10 | b | semmle.label | b | | main.rs:53:9:53:17 | source(...) | semmle.label | source(...) | | main.rs:54:10:54:10 | i | semmle.label | i | -| main.rs:117:14:117:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | -| main.rs:117:19:117:28 | source(...) | semmle.label | source(...) | -| main.rs:120:9:120:15 | TupleStructPat [Some] | semmle.label | TupleStructPat [Some] | -| main.rs:120:14:120:14 | n | semmle.label | n | -| main.rs:120:25:120:25 | n | semmle.label | n | -| main.rs:135:14:135:39 | ...::A(...) [A] | semmle.label | ...::A(...) [A] | -| main.rs:135:29:135:38 | source(...) | semmle.label | source(...) | -| main.rs:138:9:138:25 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | -| main.rs:138:24:138:24 | n | semmle.label | n | -| main.rs:138:35:138:35 | n | semmle.label | n | -| main.rs:142:10:142:26 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | -| main.rs:142:25:142:25 | n | semmle.label | n | -| main.rs:142:57:142:57 | n | semmle.label | n | -| main.rs:174:14:176:5 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | -| main.rs:175:18:175:27 | source(...) | semmle.label | source(...) | -| main.rs:179:9:179:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | -| main.rs:179:36:179:36 | n | semmle.label | n | -| main.rs:179:48:179:48 | n | semmle.label | n | -| main.rs:183:10:183:39 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | -| main.rs:183:37:183:37 | n | semmle.label | n | -| main.rs:183:83:183:83 | n | semmle.label | n | +| main.rs:214:14:214:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | +| main.rs:214:19:214:28 | source(...) | semmle.label | source(...) | +| main.rs:217:9:217:15 | TupleStructPat [Some] | semmle.label | TupleStructPat [Some] | +| main.rs:217:14:217:14 | n | semmle.label | n | +| main.rs:217:25:217:25 | n | semmle.label | n | +| main.rs:232:14:232:39 | ...::A(...) [A] | semmle.label | ...::A(...) [A] | +| main.rs:232:29:232:38 | source(...) | semmle.label | source(...) | +| main.rs:235:9:235:25 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | +| main.rs:235:24:235:24 | n | semmle.label | n | +| main.rs:235:35:235:35 | n | semmle.label | n | +| main.rs:239:9:239:25 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | +| main.rs:239:24:239:24 | n | semmle.label | n | +| main.rs:239:55:239:55 | n | semmle.label | n | +| main.rs:271:14:273:5 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:272:18:272:27 | source(...) | semmle.label | source(...) | +| main.rs:276:9:276:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:276:36:276:36 | n | semmle.label | n | +| main.rs:276:48:276:48 | n | semmle.label | n | +| main.rs:280:9:280:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:280:36:280:36 | n | semmle.label | n | +| main.rs:280:81:280:81 | n | semmle.label | n | subpaths testFailures #select @@ -65,8 +65,8 @@ testFailures | main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | source(...) | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | source(...) | source(...) | | main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | source(...) | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | source(...) | source(...) | | main.rs:54:10:54:10 | i | main.rs:53:9:53:17 | source(...) | main.rs:54:10:54:10 | i | $@ | main.rs:53:9:53:17 | source(...) | source(...) | -| main.rs:120:25:120:25 | n | main.rs:117:19:117:28 | source(...) | main.rs:120:25:120:25 | n | $@ | main.rs:117:19:117:28 | source(...) | source(...) | -| main.rs:138:35:138:35 | n | main.rs:135:29:135:38 | source(...) | main.rs:138:35:138:35 | n | $@ | main.rs:135:29:135:38 | source(...) | source(...) | -| main.rs:142:57:142:57 | n | main.rs:135:29:135:38 | source(...) | main.rs:142:57:142:57 | n | $@ | main.rs:135:29:135:38 | source(...) | source(...) | -| main.rs:179:48:179:48 | n | main.rs:175:18:175:27 | source(...) | main.rs:179:48:179:48 | n | $@ | main.rs:175:18:175:27 | source(...) | source(...) | -| main.rs:183:83:183:83 | n | main.rs:175:18:175:27 | source(...) | main.rs:183:83:183:83 | n | $@ | main.rs:175:18:175:27 | source(...) | source(...) | +| main.rs:217:25:217:25 | n | main.rs:214:19:214:28 | source(...) | main.rs:217:25:217:25 | n | $@ | main.rs:214:19:214:28 | source(...) | source(...) | +| main.rs:235:35:235:35 | n | main.rs:232:29:232:38 | source(...) | main.rs:235:35:235:35 | n | $@ | main.rs:232:29:232:38 | source(...) | source(...) | +| main.rs:239:55:239:55 | n | main.rs:232:29:232:38 | source(...) | main.rs:239:55:239:55 | n | $@ | main.rs:232:29:232:38 | source(...) | source(...) | +| main.rs:276:48:276:48 | n | main.rs:272:18:272:27 | source(...) | main.rs:276:48:276:48 | n | $@ | main.rs:272:18:272:27 | source(...) | source(...) | +| main.rs:280:81:280:81 | n | main.rs:272:18:272:27 | source(...) | main.rs:280:81:280:81 | n | $@ | main.rs:272:18:272:27 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/local/main.rs b/rust/ql/test/library-tests/dataflow/local/main.rs index 9a9e6b467e0..89482c86db4 100644 --- a/rust/ql/test/library-tests/dataflow/local/main.rs +++ b/rust/ql/test/library-tests/dataflow/local/main.rs @@ -54,52 +54,149 @@ fn assignment() { sink(i); // $ hasValueFlow=6 } +fn block_expression1() -> i64 { + let a = { 0 }; + a +} + +fn block_expression2(b: bool) -> i64 { + let a = 'block: { + if b { + break 'block 1; + }; + 2 + }; + a +} + +fn block_expression3(b: bool) -> i64 { + let a = 'block: { + if b { + break 'block 1; + } + break 'block 2; + }; + a +} + // ----------------------------------------------------------------------------- -// Data flow through data structures by writing and reading +// Data flow through `Box` fn box_deref() { let i = Box::new(source(7)); sink(*i); // $ MISSING: hasValueFlow=7 } +// ----------------------------------------------------------------------------- +// Data flow through tuples + fn tuple() { let a = (source(8), 2); sink(a.0); // $ MISSING: hasValueFlow=8 sink(a.1); } +fn tuple_match() { + let a = (2, source(38), 2); + let (a0, a1, a2) = a; + sink(a0); + sink(a1); // $ MISSING: hasValueFlow=38 + sink(a2); +} + +fn tuple_mutation() { + let mut a = (2, source(38)); + sink(a.0); + sink(a.1); // $ MISSING: hasValueFlow=38 + a.1 = 2; + a.0 = source(70); + sink(a.0); // $ MISSING: hasValueFlow=70 + sink(a.1); +} + +fn tuple_nested() { + let a = (source(59), 3); + let b = (a, 3); + sink(b.0.0); + sink(b.0.1); // $ MISSING: hasValueFlow=59 + sink(b.1); +} + +// ----------------------------------------------------------------------------- +// Data flow through structs + struct Point { x: i64, y: i64, - z: i64, } fn struct_field() { let p = Point { x: source(9), y: 2, - z: source(10), }; sink(p.x); // $ MISSING: hasValueFlow=9 sink(p.y); - sink(p.z); // $ MISSING: hasValueFlow=10 } -// ----------------------------------------------------------------------------- -// Data flow through data structures by pattern matching +fn struct_mutation() { + let mut p = Point { + x: source(9), + y: 2, + }; + sink(p.y); + p.y = source(54); + sink(p.y); // $ MISSING: hasValueFlow=54 +} fn struct_pattern_match() { let p = Point { x: source(11), y: 2, - z: source(12), }; - let Point { x: a, y: b, z: c } = p; + let Point { x: a, y: b } = p; sink(a); // $ MISSING: hasValueFlow=11 sink(b); - sink(c); // $ MISSING: hasValueFlow=12 } +struct Point3D { + plane: Point, + z: i64 +} + +fn struct_nested_field() { + let p = Point3D { + plane: Point { + x: 2, + y: source(77), + }, + z: 4 + }; + sink(p.plane.x); + sink(p.plane.y); // $ MISSING: hasValueFlow=77 + sink(p.z); +} + +fn struct_nested_match() { + let p = Point3D { + plane: Point { + x: 2, + y: source(93), + }, + z: 4 + }; + match p { + Point3D { plane: Point { x, y }, z, } => { + sink(x); + sink(y); // MISSING: hasValueFlow=93 + sink(z); + } + } +} + +// ----------------------------------------------------------------------------- +// Data flow through enums + fn option_pattern_match_qualified() { let s1 = Option::Some(source(13)); let s2 = Option::Some(2); @@ -139,7 +236,7 @@ fn custom_tuple_enum_pattern_match_qualified() { MyTupleEnum::B(n) => sink(n), } match s1 { - (MyTupleEnum::A(n) | MyTupleEnum::B(n)) => sink(n), // $ hasValueFlow=15 + MyTupleEnum::A(n) | MyTupleEnum::B(n) => sink(n), // $ hasValueFlow=15 } match s2 { MyTupleEnum::A(n) => sink(n), @@ -157,7 +254,7 @@ fn custom_tuple_enum_pattern_match_unqualified() { B(n) => sink(n), } match s1 { - (A(n) | B(n)) => sink(n), // $ MISSING: hasValueFlow=16 + A(n) | B(n) => sink(n), // $ MISSING: hasValueFlow=16 } match s2 { A(n) => sink(n), @@ -180,7 +277,7 @@ fn custom_record_enum_pattern_match_qualified() { MyRecordEnum::D { field_d: n } => sink(n), } match s1 { - (MyRecordEnum::C { field_c: n } | MyRecordEnum::D { field_d: n }) => sink(n), // $ hasValueFlow=17 + MyRecordEnum::C { field_c: n } | MyRecordEnum::D { field_d: n } => sink(n), // $ hasValueFlow=17 } match s2 { MyRecordEnum::C { field_c: n } => sink(n), @@ -200,7 +297,7 @@ fn custom_record_enum_pattern_match_unqualified() { D { field_d: n } => sink(n), } match s1 { - (C { field_c: n } | D { field_d: n }) => sink(n), // $ MISSING: hasValueFlow=18 + C { field_c: n } | D { field_d: n } => sink(n), // $ MISSING: hasValueFlow=18 } match s2 { C { field_c: n } => sink(n), @@ -208,31 +305,6 @@ fn custom_record_enum_pattern_match_unqualified() { } } -fn block_expression1() -> i64 { - let a = { 0 }; - a -} - -fn block_expression2(b: bool) -> i64 { - let a = 'block: { - if b { - break 'block 1; - }; - 2 - }; - a -} - -fn block_expression3(b: bool) -> i64 { - let a = 'block: { - if b { - break 'block 1; - } - break 'block 2; - }; - a -} - fn main() { direct(); variable_usage(); @@ -242,8 +314,14 @@ fn main() { assignment(); box_deref(); tuple(); + tuple_match(); + tuple_mutation(); + tuple_nested(); struct_field(); + struct_mutation(); struct_pattern_match(); + struct_nested_field(); + struct_nested_match(); option_pattern_match_qualified(); option_pattern_match_unqualified(); custom_tuple_enum_pattern_match_qualified(); From e96f15d9b4640db0f1bd12a4290af805b9610bb8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 13:12:46 +0000 Subject: [PATCH 301/470] Rust: Add a test exposing SQL Injection sinks directly. --- .../security/CWE-089/SqlSinks.expected | 2 + .../query-tests/security/CWE-089/SqlSinks.ql | 19 +++ .../test/query-tests/security/CWE-089/sqlx.rs | 112 +++++++++--------- 3 files changed, 77 insertions(+), 56 deletions(-) create mode 100644 rust/ql/test/query-tests/security/CWE-089/SqlSinks.expected create mode 100644 rust/ql/test/query-tests/security/CWE-089/SqlSinks.ql diff --git a/rust/ql/test/query-tests/security/CWE-089/SqlSinks.expected b/rust/ql/test/query-tests/security/CWE-089/SqlSinks.expected new file mode 100644 index 00000000000..8ec8033d086 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-089/SqlSinks.expected @@ -0,0 +1,2 @@ +testFailures +failures diff --git a/rust/ql/test/query-tests/security/CWE-089/SqlSinks.ql b/rust/ql/test/query-tests/security/CWE-089/SqlSinks.ql new file mode 100644 index 00000000000..d1cae882e68 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-089/SqlSinks.ql @@ -0,0 +1,19 @@ +import rust +import codeql.rust.security.SqlInjectionExtensions +import utils.InlineExpectationsTest + +module SqlSinksTest implements TestSig { + string getARelevantTag() { result = ["sql-sink"] } + + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(SqlInjection::Sink sink | + location = sink.getLocation() and + location.getFile().getBaseName() != "" and + element = sink.toString() and + tag = "sql-sink" and + value = "" + ) + } +} + +import MakeTest diff --git a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs index b5cc25000f9..d4039200b4f 100644 --- a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs +++ b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs @@ -44,8 +44,8 @@ async fn test_sqlx_mysql(url: &str, enable_remote: bool) -> Result<(), sqlx::Err // construct queries (with extra variants) let const_string = String::from("Alice"); - let arg_string = std::env::args().nth(1).unwrap_or(String::from("Alice")); // $ MISSING Source=args1 - let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING Source=remote1 + let arg_string = std::env::args().nth(1).unwrap_or(String::from("Alice")); // $ MISSING: Source=args1 + let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING: Source=remote1 let remote_number = remote_string.parse::().unwrap_or(0); let safe_query_1 = String::from("SELECT * FROM people WHERE firstname='Alice'"); let safe_query_2 = String::from("SELECT * FROM people WHERE firstname='") + &const_string + "'"; @@ -57,31 +57,31 @@ async fn test_sqlx_mysql(url: &str, enable_remote: bool) -> Result<(), sqlx::Err let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe) // direct execution - let _ = conn.execute(safe_query_1.as_str()).await?; - let _ = conn.execute(safe_query_2.as_str()).await?; - let _ = conn.execute(safe_query_3.as_str()).await?; - let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ MISSING Alert[sql-injection]=args1 + let _ = conn.execute(safe_query_1.as_str()).await?; // $ MISSING: sql-sink + let _ = conn.execute(safe_query_2.as_str()).await?; // $ MISSING: sql-sink + let _ = conn.execute(safe_query_3.as_str()).await?; // $ MISSING: sql-sink + let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ MISSING: sql-sink Alert[sql-injection]=args1 if enable_remote { - let _ = conn.execute(unsafe_query_2.as_str()).await?; // $ MISSING Alert[sql-injection]=remote1 - let _ = conn.execute(unsafe_query_3.as_str()).await?; // $ MISSING Alert[sql-injection]=remote1 - let _ = conn.execute(unsafe_query_4.as_str()).await?; // $ MISSING Alert[sql-injection]=remote1 + let _ = conn.execute(unsafe_query_2.as_str()).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote1 + let _ = conn.execute(unsafe_query_3.as_str()).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote1 + let _ = conn.execute(unsafe_query_4.as_str()).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote1 } // prepared queries - let _ = sqlx::query(safe_query_1.as_str()).execute(&pool).await?; - let _ = sqlx::query(safe_query_2.as_str()).execute(&pool).await?; - let _ = sqlx::query(safe_query_3.as_str()).execute(&pool).await?; - let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ MISSING Alert[sql-injection]=args1 + let _ = sqlx::query(safe_query_1.as_str()).execute(&pool).await?; // $ MISSING: sql-sink + let _ = sqlx::query(safe_query_2.as_str()).execute(&pool).await?; // $ MISSING: sql-sink + let _ = sqlx::query(safe_query_3.as_str()).execute(&pool).await?; // $ MISSING: sql-sink + let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ MISSING: sql-sink Alert[sql-injection]=args1 if enable_remote { - let _ = sqlx::query(unsafe_query_2.as_str()).execute(&pool).await?; // $ MISSING Alert[sql-injection]=remote1 - let _ = sqlx::query(unsafe_query_3.as_str()).execute(&pool).await?; // $ MISSING Alert[sql-injection]=remote1 - let _ = sqlx::query(unsafe_query_4.as_str()).execute(&pool).await?; // $ MISSING Alert[sql-injection]=remote1 + let _ = sqlx::query(unsafe_query_2.as_str()).execute(&pool).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote1 + let _ = sqlx::query(unsafe_query_3.as_str()).execute(&pool).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote1 + let _ = sqlx::query(unsafe_query_4.as_str()).execute(&pool).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote1 } - let _ = sqlx::query(prepared_query_1.as_str()).bind(const_string).execute(&pool).await?; - let _ = sqlx::query(prepared_query_1.as_str()).bind(arg_string).execute(&pool).await?; + let _ = sqlx::query(prepared_query_1.as_str()).bind(const_string).execute(&pool).await?; // $ MISSING: sql-sink + let _ = sqlx::query(prepared_query_1.as_str()).bind(arg_string).execute(&pool).await?; // $ MISSING: sql-sink if enable_remote { - let _ = sqlx::query(prepared_query_1.as_str()).bind(remote_string).execute(&pool).await?; - let _ = sqlx::query(prepared_query_1.as_str()).bind(remote_number).execute(&pool).await?; + let _ = sqlx::query(prepared_query_1.as_str()).bind(remote_string).execute(&pool).await?; // $ MISSING: sql-sink + let _ = sqlx::query(prepared_query_1.as_str()).bind(remote_number).execute(&pool).await?; // $ MISSING: sql-sink } Ok(()) @@ -93,67 +93,67 @@ async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Er // construct queries let const_string = String::from("Alice"); - let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING Source=remote2 + let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING: Source=remote2 let safe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &const_string + "'"; let unsafe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'"; let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe) // direct execution (with extra variants) - let _ = conn.execute(safe_query_1.as_str()).await?; + let _ = conn.execute(safe_query_1.as_str()).await?; // $ MISSING: sql-sink if enable_remote { - let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ MISSING Alert[sql-injection]=remote2 + let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote2 } // ... - let _ = sqlx::raw_sql(safe_query_1.as_str()).execute(&mut conn).await?; + let _ = sqlx::raw_sql(safe_query_1.as_str()).execute(&mut conn).await?; // $ MISSING: ql-sink if enable_remote { - let _ = sqlx::raw_sql(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ MISSING Alert[sql-injection]=remote2 + let _ = sqlx::raw_sql(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote2 } // prepared queries (with extra variants) - let _ = sqlx::query(safe_query_1.as_str()).execute(&mut conn).await?; - let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).execute(&mut conn).await?; + let _ = sqlx::query(safe_query_1.as_str()).execute(&mut conn).await?; // $ MISSING: sql-sink + let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).execute(&mut conn).await?; // $ MISSING: sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ MISSING Alert[sql-injection]=remote2 - let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).execute(&mut conn).await?; + let _ = sqlx::query(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote2 + let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).execute(&mut conn).await?; // $ MISSING: sql-sink } // ... - let _ = sqlx::query(safe_query_1.as_str()).fetch(&mut conn); - let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).fetch(&mut conn); + let _ = sqlx::query(safe_query_1.as_str()).fetch(&mut conn); // $ MISSING: sql-sink + let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).fetch(&mut conn); // $ MISSING: sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).fetch(&mut conn); // $ MISSING Alert[sql-injection]=remote2 - let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).fetch(&mut conn); + let _ = sqlx::query(unsafe_query_1.as_str()).fetch(&mut conn); // $ MISSING: ql-sink Alert[sql-injection]=remote2 + let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).fetch(&mut conn); // $ MISSING: sql-sink } // ... - let row1: (i64, String, String) = sqlx::query_as(safe_query_1.as_str()).fetch_one(&mut conn).await?; + let row1: (i64, String, String) = sqlx::query_as(safe_query_1.as_str()).fetch_one(&mut conn).await?; // $ MISSING: sql-sink println!(" row1 = {:?}", row1); - let row2: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&const_string).fetch_one(&mut conn).await?; + let row2: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&const_string).fetch_one(&mut conn).await?; // $ MISSING: sql-sink println!(" row2 = {:?}", row2); if enable_remote { - let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_one(&mut conn).await?; // $ MISSING Alert[sql-injection]=remote2 - let _: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&remote_string).fetch_one(&mut conn).await?; + let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_one(&mut conn).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote2 + let _: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&remote_string).fetch_one(&mut conn).await?; // $ MISSING: sql-sink } // ... - let row3: (i64, String, String) = sqlx::query_as(safe_query_1.as_str()).fetch_optional(&mut conn).await?.expect("no data"); + let row3: (i64, String, String) = sqlx::query_as(safe_query_1.as_str()).fetch_optional(&mut conn).await?.expect("no data"); // $ MISSING: sql-sink println!(" row3 = {:?}", row3); - let row4: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&const_string).fetch_optional(&mut conn).await?.expect("no data"); + let row4: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&const_string).fetch_optional(&mut conn).await?.expect("no data"); // $ MISSING: sql-sink println!(" row4 = {:?}", row4); if enable_remote { - let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_optional(&mut conn).await?.expect("no data"); // $ MISSING Alert[sql-injection]=remote2 - let _: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&remote_string).fetch_optional(&mut conn).await?.expect("no data"); + let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_optional(&mut conn).await?.expect("no data"); // $ MISSING: sql-sink Alert[sql-injection]=remote2 + let _: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&remote_string).fetch_optional(&mut conn).await?.expect("no data"); // $ MISSING: sql-sink } // ... - let _ = sqlx::query(safe_query_1.as_str()).fetch_all(&mut conn).await?; - let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).fetch_all(&mut conn).await?; - let _ = sqlx::query("SELECT * FROM people WHERE firstname=?").bind(&const_string).fetch_all(&mut conn).await?; + let _ = sqlx::query(safe_query_1.as_str()).fetch_all(&mut conn).await?; // $ MISSING: sql-sink + let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).fetch_all(&mut conn).await?; // $ MISSING: sql-sink + let _ = sqlx::query("SELECT * FROM people WHERE firstname=?").bind(&const_string).fetch_all(&mut conn).await?; // $ MISSING: sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).fetch_all(&mut conn).await?; // $ MISSING Alert[sql-injection]=remote2 - let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).fetch_all(&mut conn).await?; - let _ = sqlx::query("SELECT * FROM people WHERE firstname=?").bind(&remote_string).fetch_all(&mut conn).await?; + let _ = sqlx::query(unsafe_query_1.as_str()).fetch_all(&mut conn).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote2 + let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).fetch_all(&mut conn).await?; // $ MISSING: sql-sink + let _ = sqlx::query("SELECT * FROM people WHERE firstname=?").bind(&remote_string).fetch_all(&mut conn).await?; // $ MISSING: sql-sink } // ... - let _ = sqlx::query!("SELECT * FROM people WHERE firstname=$1", const_string).fetch_all(&mut conn).await?; // (only takes string literals, so can't be vulnerable) + let _ = sqlx::query!("SELECT * FROM people WHERE firstname=$1", const_string).fetch_all(&mut conn).await?; // $ MISSING: sql-sink (only takes string literals, so can't be vulnerable) if enable_remote { - let _ = sqlx::query!("SELECT * FROM people WHERE firstname=$1", remote_string).fetch_all(&mut conn).await?; + let _ = sqlx::query!("SELECT * FROM people WHERE firstname=$1", remote_string).fetch_all(&mut conn).await?; // $ MISSING: sql-sink } Ok(()) @@ -166,23 +166,23 @@ async fn test_sqlx_postgres(url: &str, enable_remote: bool) -> Result<(), sqlx:: // construct queries let const_string = String::from("Alice"); - let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING Source=remote3 + let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING: Source=remote3 let safe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &const_string + "'"; let unsafe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'"; let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=$1"); // (prepared arguments are safe) // direct execution - let _ = conn.execute(safe_query_1.as_str()).await?; + let _ = conn.execute(safe_query_1.as_str()).await?; // $ MISSING: sql-sink if enable_remote { - let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ MISSING Alert[sql-injection]=remote3 + let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote3 } // prepared queries - let _ = sqlx::query(safe_query_1.as_str()).execute(&pool).await?; - let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).execute(&pool).await?; + let _ = sqlx::query(safe_query_1.as_str()).execute(&pool).await?; // $ MISSING: sql-sink + let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).execute(&pool).await?; // $ MISSING: sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ MISSING Alert[sql-injection]=remote3 - let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).execute(&pool).await?; + let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote3 + let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).execute(&pool).await?; // $ MISSING: sql-sink } Ok(()) From ba560f2fe97bb811bd25dd16848c4ebf666a60fc Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 15:04:57 +0000 Subject: [PATCH 302/470] Rust: Model SQLx. --- rust/ql/lib/codeql/rust/Frameworks.qll | 1 + rust/ql/lib/codeql/rust/frameworks/Sqlx.qll | 40 +++++++ .../test/query-tests/security/CWE-089/sqlx.rs | 100 +++++++++--------- 3 files changed, 91 insertions(+), 50 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/frameworks/Sqlx.qll diff --git a/rust/ql/lib/codeql/rust/Frameworks.qll b/rust/ql/lib/codeql/rust/Frameworks.qll index 601e87ef6eb..0c6fc573d0f 100644 --- a/rust/ql/lib/codeql/rust/Frameworks.qll +++ b/rust/ql/lib/codeql/rust/Frameworks.qll @@ -4,3 +4,4 @@ private import codeql.rust.frameworks.Reqwest private import codeql.rust.frameworks.stdlib.Env +private import codeql.rust.frameworks.Sqlx diff --git a/rust/ql/lib/codeql/rust/frameworks/Sqlx.qll b/rust/ql/lib/codeql/rust/frameworks/Sqlx.qll new file mode 100644 index 00000000000..65361eae814 --- /dev/null +++ b/rust/ql/lib/codeql/rust/frameworks/Sqlx.qll @@ -0,0 +1,40 @@ +/** + * Provides modeling for the `SQLx` library. + */ + +private import rust +private import codeql.rust.Concepts +private import codeql.rust.dataflow.DataFlow + +/** + * A call to `sqlx::query` and variations. + */ +private class SqlxQuery extends SqlConstruction::Range { + CallExpr call; + + SqlxQuery() { + this.asExpr().getExpr() = call and + call.getExpr().(PathExpr).getPath().getResolvedPath() = + [ + "crate::query::query", "crate::query_as::query_as", "crate::query_with::query_with", + "crate::query_as_with::query_as_with", "crate::query_scalar::query_scalar", + "crate::query_scalar_with::query_scalar_with", "crate::raw_sql::raw_sql" + ] + } + + override DataFlow::Node getSql() { result.asExpr().getExpr() = call.getArgList().getArg(0) } +} + +/** + * A call to `sqlx::Executor::execute`. + */ +private class SqlxExecute extends SqlConstruction::Range { + MethodCallExpr call; + + SqlxExecute() { + this.asExpr().getExpr() = call and + call.(Resolvable).getResolvedPath() = "crate::executor::Executor::execute" + } + + override DataFlow::Node getSql() { result.asExpr().getExpr() = call.getArgList().getArg(0) } +} diff --git a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs index d4039200b4f..9f6e9c08f0c 100644 --- a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs +++ b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs @@ -57,31 +57,31 @@ async fn test_sqlx_mysql(url: &str, enable_remote: bool) -> Result<(), sqlx::Err let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe) // direct execution - let _ = conn.execute(safe_query_1.as_str()).await?; // $ MISSING: sql-sink - let _ = conn.execute(safe_query_2.as_str()).await?; // $ MISSING: sql-sink - let _ = conn.execute(safe_query_3.as_str()).await?; // $ MISSING: sql-sink - let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ MISSING: sql-sink Alert[sql-injection]=args1 + let _ = conn.execute(safe_query_1.as_str()).await?; // $ sql-sink + let _ = conn.execute(safe_query_2.as_str()).await?; // $ sql-sink + let _ = conn.execute(safe_query_3.as_str()).await?; // $ sql-sink + let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ sql-sink AMISSING: lert[sql-injection]=args1 if enable_remote { - let _ = conn.execute(unsafe_query_2.as_str()).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote1 - let _ = conn.execute(unsafe_query_3.as_str()).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote1 - let _ = conn.execute(unsafe_query_4.as_str()).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote1 + let _ = conn.execute(unsafe_query_2.as_str()).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote1 + let _ = conn.execute(unsafe_query_3.as_str()).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote1 + let _ = conn.execute(unsafe_query_4.as_str()).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote1 } // prepared queries - let _ = sqlx::query(safe_query_1.as_str()).execute(&pool).await?; // $ MISSING: sql-sink - let _ = sqlx::query(safe_query_2.as_str()).execute(&pool).await?; // $ MISSING: sql-sink - let _ = sqlx::query(safe_query_3.as_str()).execute(&pool).await?; // $ MISSING: sql-sink - let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ MISSING: sql-sink Alert[sql-injection]=args1 + let _ = sqlx::query(safe_query_1.as_str()).execute(&pool).await?; // $ sql-sink + let _ = sqlx::query(safe_query_2.as_str()).execute(&pool).await?; // $ sql-sink + let _ = sqlx::query(safe_query_3.as_str()).execute(&pool).await?; // $ sql-sink + let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[sql-injection]=args1 if enable_remote { - let _ = sqlx::query(unsafe_query_2.as_str()).execute(&pool).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote1 - let _ = sqlx::query(unsafe_query_3.as_str()).execute(&pool).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote1 - let _ = sqlx::query(unsafe_query_4.as_str()).execute(&pool).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote1 + let _ = sqlx::query(unsafe_query_2.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote1 + let _ = sqlx::query(unsafe_query_3.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote1 + let _ = sqlx::query(unsafe_query_4.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote1 } - let _ = sqlx::query(prepared_query_1.as_str()).bind(const_string).execute(&pool).await?; // $ MISSING: sql-sink - let _ = sqlx::query(prepared_query_1.as_str()).bind(arg_string).execute(&pool).await?; // $ MISSING: sql-sink + let _ = sqlx::query(prepared_query_1.as_str()).bind(const_string).execute(&pool).await?; // $ sql-sink + let _ = sqlx::query(prepared_query_1.as_str()).bind(arg_string).execute(&pool).await?; // $ sql-sink if enable_remote { - let _ = sqlx::query(prepared_query_1.as_str()).bind(remote_string).execute(&pool).await?; // $ MISSING: sql-sink - let _ = sqlx::query(prepared_query_1.as_str()).bind(remote_number).execute(&pool).await?; // $ MISSING: sql-sink + let _ = sqlx::query(prepared_query_1.as_str()).bind(remote_string).execute(&pool).await?; // $ sql-sink + let _ = sqlx::query(prepared_query_1.as_str()).bind(remote_number).execute(&pool).await?; // $ sql-sink } Ok(()) @@ -99,56 +99,56 @@ async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Er let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe) // direct execution (with extra variants) - let _ = conn.execute(safe_query_1.as_str()).await?; // $ MISSING: sql-sink + let _ = conn.execute(safe_query_1.as_str()).await?; // $ sql-sink if enable_remote { - let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote2 + let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote2 } // ... - let _ = sqlx::raw_sql(safe_query_1.as_str()).execute(&mut conn).await?; // $ MISSING: ql-sink + let _ = sqlx::raw_sql(safe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink if enable_remote { - let _ = sqlx::raw_sql(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote2 + let _ = sqlx::raw_sql(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote2 } // prepared queries (with extra variants) - let _ = sqlx::query(safe_query_1.as_str()).execute(&mut conn).await?; // $ MISSING: sql-sink - let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).execute(&mut conn).await?; // $ MISSING: sql-sink + let _ = sqlx::query(safe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink + let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).execute(&mut conn).await?; // $ sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote2 - let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).execute(&mut conn).await?; // $ MISSING: sql-sink + let _ = sqlx::query(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote2 + let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).execute(&mut conn).await?; // $ sql-sink } // ... - let _ = sqlx::query(safe_query_1.as_str()).fetch(&mut conn); // $ MISSING: sql-sink - let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).fetch(&mut conn); // $ MISSING: sql-sink + let _ = sqlx::query(safe_query_1.as_str()).fetch(&mut conn); // $ sql-sink + let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).fetch(&mut conn); // $ sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).fetch(&mut conn); // $ MISSING: ql-sink Alert[sql-injection]=remote2 - let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).fetch(&mut conn); // $ MISSING: sql-sink + let _ = sqlx::query(unsafe_query_1.as_str()).fetch(&mut conn); // $ sql-sink MISSING: Alert[sql-injection]=remote2 + let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).fetch(&mut conn); // $ sql-sink } // ... - let row1: (i64, String, String) = sqlx::query_as(safe_query_1.as_str()).fetch_one(&mut conn).await?; // $ MISSING: sql-sink + let row1: (i64, String, String) = sqlx::query_as(safe_query_1.as_str()).fetch_one(&mut conn).await?; // $ sql-sink println!(" row1 = {:?}", row1); - let row2: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&const_string).fetch_one(&mut conn).await?; // $ MISSING: sql-sink + let row2: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&const_string).fetch_one(&mut conn).await?; // $ sql-sink println!(" row2 = {:?}", row2); if enable_remote { - let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_one(&mut conn).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote2 - let _: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&remote_string).fetch_one(&mut conn).await?; // $ MISSING: sql-sink + let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_one(&mut conn).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote2 + let _: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&remote_string).fetch_one(&mut conn).await?; // $ sql-sink } // ... - let row3: (i64, String, String) = sqlx::query_as(safe_query_1.as_str()).fetch_optional(&mut conn).await?.expect("no data"); // $ MISSING: sql-sink + let row3: (i64, String, String) = sqlx::query_as(safe_query_1.as_str()).fetch_optional(&mut conn).await?.expect("no data"); // $ sql-sink println!(" row3 = {:?}", row3); - let row4: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&const_string).fetch_optional(&mut conn).await?.expect("no data"); // $ MISSING: sql-sink + let row4: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&const_string).fetch_optional(&mut conn).await?.expect("no data"); // $ sql-sink println!(" row4 = {:?}", row4); if enable_remote { - let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_optional(&mut conn).await?.expect("no data"); // $ MISSING: sql-sink Alert[sql-injection]=remote2 - let _: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&remote_string).fetch_optional(&mut conn).await?.expect("no data"); // $ MISSING: sql-sink + let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_optional(&mut conn).await?.expect("no data"); // $ sql-sink $ MISSING: Alert[sql-injection]=remote2 + let _: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&remote_string).fetch_optional(&mut conn).await?.expect("no data"); // $ sql-sink } // ... - let _ = sqlx::query(safe_query_1.as_str()).fetch_all(&mut conn).await?; // $ MISSING: sql-sink - let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).fetch_all(&mut conn).await?; // $ MISSING: sql-sink - let _ = sqlx::query("SELECT * FROM people WHERE firstname=?").bind(&const_string).fetch_all(&mut conn).await?; // $ MISSING: sql-sink + let _ = sqlx::query(safe_query_1.as_str()).fetch_all(&mut conn).await?; // $ sql-sink + let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).fetch_all(&mut conn).await?; // $ sql-sink + let _ = sqlx::query("SELECT * FROM people WHERE firstname=?").bind(&const_string).fetch_all(&mut conn).await?; // $ sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).fetch_all(&mut conn).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote2 - let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).fetch_all(&mut conn).await?; // $ MISSING: sql-sink - let _ = sqlx::query("SELECT * FROM people WHERE firstname=?").bind(&remote_string).fetch_all(&mut conn).await?; // $ MISSING: sql-sink + let _ = sqlx::query(unsafe_query_1.as_str()).fetch_all(&mut conn).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote2 + let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).fetch_all(&mut conn).await?; // $ sql-sink + let _ = sqlx::query("SELECT * FROM people WHERE firstname=?").bind(&remote_string).fetch_all(&mut conn).await?; // $ sql-sink } // ... let _ = sqlx::query!("SELECT * FROM people WHERE firstname=$1", const_string).fetch_all(&mut conn).await?; // $ MISSING: sql-sink (only takes string literals, so can't be vulnerable) @@ -172,17 +172,17 @@ async fn test_sqlx_postgres(url: &str, enable_remote: bool) -> Result<(), sqlx:: let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=$1"); // (prepared arguments are safe) // direct execution - let _ = conn.execute(safe_query_1.as_str()).await?; // $ MISSING: sql-sink + let _ = conn.execute(safe_query_1.as_str()).await?; // $ sql-sink if enable_remote { - let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote3 + let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote3 } // prepared queries - let _ = sqlx::query(safe_query_1.as_str()).execute(&pool).await?; // $ MISSING: sql-sink - let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).execute(&pool).await?; // $ MISSING: sql-sink + let _ = sqlx::query(safe_query_1.as_str()).execute(&pool).await?; // $ sql-sink + let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).execute(&pool).await?; // $ sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ MISSING: sql-sink Alert[sql-injection]=remote3 - let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).execute(&pool).await?; // $ MISSING: sql-sink + let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote3 + let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).execute(&pool).await?; // $ sql-sink } Ok(()) From 60c212bb10afc1132e00f3f7e333543cd5c825a8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 27 Nov 2024 10:42:24 +0000 Subject: [PATCH 303/470] Rust: Update for changes on main. --- rust/ql/lib/codeql/rust/frameworks/Sqlx.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/Sqlx.qll b/rust/ql/lib/codeql/rust/frameworks/Sqlx.qll index 65361eae814..701cafd277a 100644 --- a/rust/ql/lib/codeql/rust/frameworks/Sqlx.qll +++ b/rust/ql/lib/codeql/rust/frameworks/Sqlx.qll @@ -14,7 +14,7 @@ private class SqlxQuery extends SqlConstruction::Range { SqlxQuery() { this.asExpr().getExpr() = call and - call.getExpr().(PathExpr).getPath().getResolvedPath() = + call.getFunction().(PathExpr).getPath().getResolvedPath() = [ "crate::query::query", "crate::query_as::query_as", "crate::query_with::query_with", "crate::query_as_with::query_as_with", "crate::query_scalar::query_scalar", From c113a0b5a1f69a614d24792d4b7593874b583175 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 27 Nov 2024 10:51:42 +0000 Subject: [PATCH 304/470] Rust: Fix typo. --- rust/ql/test/query-tests/security/CWE-089/sqlx.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs index 9f6e9c08f0c..173f6c730b2 100644 --- a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs +++ b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs @@ -60,7 +60,7 @@ async fn test_sqlx_mysql(url: &str, enable_remote: bool) -> Result<(), sqlx::Err let _ = conn.execute(safe_query_1.as_str()).await?; // $ sql-sink let _ = conn.execute(safe_query_2.as_str()).await?; // $ sql-sink let _ = conn.execute(safe_query_3.as_str()).await?; // $ sql-sink - let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ sql-sink AMISSING: lert[sql-injection]=args1 + let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ sql-sink MISSING: Alert[sql-injection]=args1 if enable_remote { let _ = conn.execute(unsafe_query_2.as_str()).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote1 let _ = conn.execute(unsafe_query_3.as_str()).await?; // $ sql-sink MISSING: Alert[sql-injection]=remote1 From 27738eaaccc54b1ef19e62a3cc6de23eb166cb03 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 27 Nov 2024 12:03:32 +0100 Subject: [PATCH 305/470] Rust: reorganize perf diagnostics --- rust/extractor/src/diagnostics.rs | 146 +++++++++--------- rust/extractor/src/main.rs | 6 +- rust/ql/integration-tests/conftest.py | 4 +- .../hello-project/diagnostics.expected | 20 +-- .../diagnostics.cargo.expected | 44 +++--- .../diagnostics.rust-project.expected | 44 +++--- 6 files changed, 136 insertions(+), 128 deletions(-) diff --git a/rust/extractor/src/diagnostics.rs b/rust/extractor/src/diagnostics.rs index 21b3619a207..d4b60211bbf 100644 --- a/rust/extractor/src/diagnostics.rs +++ b/rust/extractor/src/diagnostics.rs @@ -3,7 +3,9 @@ use anyhow::Context; use chrono::{DateTime, Utc}; use log::{debug, info}; use ra_ap_project_model::ProjectManifest; +use serde::ser::SerializeMap; use serde::Serialize; +use std::collections::HashMap; use std::fmt::Display; use std::fs::File; use std::path::{Path, PathBuf}; @@ -72,27 +74,29 @@ pub struct Diagnostics { attributes: T, } -#[derive(Debug, Clone, Serialize)] +#[derive(Default, Debug, Clone, Copy, Serialize, PartialEq, Eq, Hash)] #[serde(rename_all = "camelCase")] -enum ExtractionStepTarget { - LoadManifest(PathBuf), - FetchFile(PathBuf), - Parse(PathBuf), - Extract(PathBuf), +enum ExtractionStepKind { + #[default] + LoadManifest, + LoadSource, + Parse, + Extract, } #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] pub struct ExtractionStep { - #[serde(flatten)] - target: ExtractionStepTarget, + action: ExtractionStepKind, + file: PathBuf, ms: u128, } impl ExtractionStep { - fn new(start: Instant, target: ExtractionStepTarget) -> Self { + fn new(start: Instant, action: ExtractionStepKind, file: PathBuf) -> Self { let ret = ExtractionStep { - target, + action, + file, ms: start.elapsed().as_millis(), }; debug!("{ret:?}"); @@ -102,70 +106,84 @@ impl ExtractionStep { pub fn load_manifest(start: Instant, target: &ProjectManifest) -> Self { Self::new( start, - ExtractionStepTarget::LoadManifest(PathBuf::from(target.manifest_path())), + ExtractionStepKind::LoadManifest, + PathBuf::from(target.manifest_path()), ) } pub fn parse(start: Instant, target: &Path) -> Self { - Self::new(start, ExtractionStepTarget::Parse(PathBuf::from(target))) + Self::new(start, ExtractionStepKind::Parse, PathBuf::from(target)) } pub fn extract(start: Instant, target: &Path) -> Self { - Self::new(start, ExtractionStepTarget::Extract(PathBuf::from(target))) + Self::new(start, ExtractionStepKind::Extract, PathBuf::from(target)) } - pub fn fetch_file(start: Instant, target: &Path) -> Self { - Self::new( - start, - ExtractionStepTarget::FetchFile(PathBuf::from(target)), - ) + pub fn load_source(start: Instant, target: &Path) -> Self { + Self::new(start, ExtractionStepKind::LoadSource, PathBuf::from(target)) } } -#[derive(Debug, Default, Clone, Serialize)] -#[serde(rename_all = "camelCase")] -struct HumanReadableDuration { - ms: u128, - pretty: String, +#[derive(Debug, Default, Clone)] +struct HumanReadableDuration(u128); + +impl Serialize for HumanReadableDuration { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(Some(2))?; + map.serialize_entry("ms", &self.0)?; + map.serialize_entry("pretty", &self.pretty())?; + map.end() + } } impl HumanReadableDuration { - pub fn new(ms: u128) -> Self { - let seconds = ms / 1000; - let minutes = seconds / 60; + pub fn add(&mut self, other: u128) { + self.0 += other; + } + + pub fn pretty(&self) -> String { + let milliseconds = self.0 % 1000; + let mut seconds = self.0 / 1000; + if seconds < 60 { + return format!("{seconds}.{milliseconds:03}s"); + } + let mut minutes = seconds / 60; + seconds %= 60; + if minutes < 60 { + return format!("{minutes}min{seconds:02}.{milliseconds:03}s"); + } let hours = minutes / 60; - let pretty = format!( - "{hours}:{minutes:02}:{seconds:02}.{milliseconds:03}", - minutes = minutes % 60, - seconds = seconds % 60, - milliseconds = ms % 1000, - ); - Self { ms, pretty } + minutes %= 60; + format!("{hours}h{minutes:02}min{seconds:02}.{milliseconds:03}s") } } impl From for HumanReadableDuration { fn from(val: u128) -> Self { - HumanReadableDuration::new(val) + HumanReadableDuration(val) } } impl Display for HumanReadableDuration { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{}ms ({})", self.ms, self.pretty) + f.write_str(&self.pretty()) } } +#[derive(Debug, Default, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +struct DurationsSummary { + #[serde(flatten)] + durations: HashMap, + total: HumanReadableDuration, +} + #[derive(Debug, Default, Clone, Serialize)] #[serde(rename_all = "camelCase")] struct ExtractionSummary { number_of_manifests: usize, number_of_files: usize, - total_load_duration: HumanReadableDuration, - total_fetch_file_duration: HumanReadableDuration, - total_parse_duration: HumanReadableDuration, - total_extract_duration: HumanReadableDuration, - total_duration: HumanReadableDuration, + durations: DurationsSummary, } #[derive(Debug, Default, Clone, Serialize)] @@ -180,46 +198,32 @@ type ExtractionDiagnostics = Diagnostics; fn summary(start: Instant, steps: &[ExtractionStep]) -> ExtractionSummary { let mut number_of_manifests = 0; let mut number_of_files = 0; - let mut total_load_duration = 0; - let mut total_parse_duration = 0; - let mut total_extract_duration = 0; - let mut total_fetch_file_duration: u128 = 0; + let mut durations = HashMap::new(); for step in steps { - match &step.target { - ExtractionStepTarget::LoadManifest(_) => { + match &step.action { + ExtractionStepKind::LoadManifest => { number_of_manifests += 1; - total_load_duration += step.ms; } - ExtractionStepTarget::FetchFile(_) => { + ExtractionStepKind::Parse => { number_of_files += 1; - total_fetch_file_duration += step.ms; - } - ExtractionStepTarget::Parse(_) => { - total_parse_duration += step.ms; - } - ExtractionStepTarget::Extract(_) => { - total_extract_duration += step.ms; } + _ => {} } + durations + .entry(step.action) + .or_insert(HumanReadableDuration(0)) + .add(step.ms); } - let ret = ExtractionSummary { + let total = start.elapsed().as_millis().into(); + for (key, value) in &durations { + info!("total duration ({key:?}): {value}"); + } + info!("total duration: {total}"); + ExtractionSummary { number_of_manifests, number_of_files, - total_load_duration: total_load_duration.into(), - total_fetch_file_duration: total_fetch_file_duration.into(), - total_parse_duration: total_parse_duration.into(), - total_extract_duration: total_extract_duration.into(), - total_duration: start.elapsed().as_millis().into(), - }; - info!("total loadimg duration: {}", ret.total_load_duration); - info!( - "total file fetching duration: {}", - ret.total_fetch_file_duration - ); - info!("total parsing duration: {}", ret.total_parse_duration); - info!("total extracting duration: {}", ret.total_extract_duration); - info!("total duration: {}", ret.total_duration); - ret + durations: DurationsSummary { durations, total }, + } } pub fn emit_extraction_diagnostics( diff --git a/rust/extractor/src/main.rs b/rust/extractor/src/main.rs index f00e94e9ba4..19239cf9dd4 100644 --- a/rust/extractor/src/main.rs +++ b/rust/extractor/src/main.rs @@ -118,7 +118,7 @@ impl<'a> Extractor<'a> { ret } - pub fn fetch_file( + pub fn load_source( &mut self, file: &Path, semantics: &Semantics<'_, RootDatabase>, @@ -131,7 +131,7 @@ impl<'a> Extractor<'a> { if semantics.file_to_module_def(id).is_none() { return Err("not included as a module".to_string()); } - self.steps.push(ExtractionStep::fetch_file(before, file)); + self.steps.push(ExtractionStep::load_source(before, file)); Ok(()) } @@ -189,7 +189,7 @@ fn main() -> anyhow::Result<()> { if let Some((ref db, ref vfs)) = extractor.load_manifest(manifest, &cargo_config) { let semantics = Semantics::new(db); for file in files { - match extractor.fetch_file(file, &semantics, vfs) { + match extractor.load_source(file, &semantics, vfs) { Ok(()) => extractor.extract_with_semantics(file, &semantics, vfs), Err(reason) => extractor.extract_without_semantics(file, &reason), }; diff --git a/rust/ql/integration-tests/conftest.py b/rust/ql/integration-tests/conftest.py index f05b1f5c98a..895650183c8 100644 --- a/rust/ql/integration-tests/conftest.py +++ b/rust/ql/integration-tests/conftest.py @@ -17,8 +17,8 @@ def manifests(cwd): @pytest.fixture def rust_check_diagnostics(check_diagnostics): check_diagnostics.replacements += [ - (r'"ms"\s*:\s*[0-9]+', '"ms": "REDACTED"'), - (r'"pretty"\s*:\s*"[0-9]+:[0-9]{2}:[0-9]{2}.[0-9]{3}"', '"pretty": "REDACTED"'), + (r'"ms"\s*:\s*[0-9]+', '"ms": "__REDACTED__"'), + (r'"pretty"\s*:\s*"[^"]*"', '"pretty": "__REDACTED__"'), ] check_diagnostics.skip += [ "attributes.steps", # the order of the steps is not stable diff --git a/rust/ql/integration-tests/hello-project/diagnostics.expected b/rust/ql/integration-tests/hello-project/diagnostics.expected index 1c46a0a9f99..c19e46a88cd 100644 --- a/rust/ql/integration-tests/hello-project/diagnostics.expected +++ b/rust/ql/integration-tests/hello-project/diagnostics.expected @@ -4,24 +4,24 @@ "numberOfFiles": 4, "numberOfManifests": 1, "totalDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, "totalExtractDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, "totalFetchFileDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, "totalLoadDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, "totalParseDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" + "ms": "__REDACTED__", + "pretty": "__REDACTED__" } } }, diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected index 48ae4a51e04..052fe3e7839 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected @@ -1,28 +1,30 @@ { "attributes": { "summary": { + "durations": { + "extract": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "loadManifest": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "loadSource": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "parse": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "total": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + } + }, "numberOfFiles": 4, - "numberOfManifests": 2, - "totalDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalExtractDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalFetchFileDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalLoadDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalParseDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - } + "numberOfManifests": 2 } }, "severity": "note", diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected index 1c46a0a9f99..3c4fc9bf431 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected @@ -1,28 +1,30 @@ { "attributes": { "summary": { + "durations": { + "extract": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "loadManifest": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "loadSource": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "parse": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "total": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + } + }, "numberOfFiles": 4, - "numberOfManifests": 1, - "totalDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalExtractDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalFetchFileDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalLoadDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalParseDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - } + "numberOfManifests": 1 } }, "severity": "note", From 5251dc2058cb684b617cb0ba72f6531b133f3976 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 27 Nov 2024 10:20:31 +0100 Subject: [PATCH 306/470] Rust: use `check_diagnostics` improvements --- rust/ql/integration-tests/conftest.py | 10 +- .../hello-project/diagnostics.expected | 115 +++++++++++++++--- .../diagnostics.cargo.expected | 72 +++++++++++ .../diagnostics.rust-project.expected | 67 ++++++++++ 4 files changed, 242 insertions(+), 22 deletions(-) diff --git a/rust/ql/integration-tests/conftest.py b/rust/ql/integration-tests/conftest.py index 895650183c8..cbace615805 100644 --- a/rust/ql/integration-tests/conftest.py +++ b/rust/ql/integration-tests/conftest.py @@ -17,10 +17,12 @@ def manifests(cwd): @pytest.fixture def rust_check_diagnostics(check_diagnostics): check_diagnostics.replacements += [ - (r'"ms"\s*:\s*[0-9]+', '"ms": "__REDACTED__"'), - (r'"pretty"\s*:\s*"[^"]*"', '"pretty": "__REDACTED__"'), + ("Cargo.toml|rust-project.json", ""), ] - check_diagnostics.skip += [ - "attributes.steps", # the order of the steps is not stable + check_diagnostics.redact += [ + "attributes.summary.durations.*.ms", + "attributes.summary.durations.*.pretty", + "attributes.steps.ms", ] + check_diagnostics.sort = True # the order of the steps is not stable return check_diagnostics diff --git a/rust/ql/integration-tests/hello-project/diagnostics.expected b/rust/ql/integration-tests/hello-project/diagnostics.expected index c19e46a88cd..5f6821ffb10 100644 --- a/rust/ql/integration-tests/hello-project/diagnostics.expected +++ b/rust/ql/integration-tests/hello-project/diagnostics.expected @@ -1,28 +1,107 @@ { "attributes": { - "summary": { - "numberOfFiles": 4, - "numberOfManifests": 1, - "totalDuration": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" + "steps": [ + { + "action": "extract", + "file": "/src/directory_module/mod.rs", + "ms": "__REDACTED__" }, - "totalExtractDuration": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" + { + "action": "extract", + "file": "/src/directory_module/nested_module.rs", + "ms": "__REDACTED__" }, - "totalFetchFileDuration": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" + { + "action": "extract", + "file": "/src/directory_module/not_loaded.rs", + "ms": "__REDACTED__" }, - "totalLoadDuration": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" + { + "action": "extract", + "file": "/src/file_module.rs", + "ms": "__REDACTED__" }, - "totalParseDuration": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" + { + "action": "extract", + "file": "/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadManifest", + "file": "/", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/src/directory_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/src/directory_module/nested_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/src/file_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/src/directory_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/src/directory_module/nested_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/src/directory_module/not_loaded.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/src/file_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/src/main.rs", + "ms": "__REDACTED__" } + ], + "summary": { + "durations": { + "extract": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "loadManifest": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "loadSource": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "parse": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "total": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + } + }, + "numberOfFiles": 5, + "numberOfManifests": 1 } }, "severity": "note", diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected index 052fe3e7839..7d484623087 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected @@ -1,5 +1,77 @@ { "attributes": { + "steps": [ + { + "action": "extract", + "file": "/exe/src/a_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "extract", + "file": "/exe/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "extract", + "file": "/lib/src/a_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "extract", + "file": "/lib/src/lib.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadManifest", + "file": "/exe/", + "ms": "__REDACTED__" + }, + { + "action": "loadManifest", + "file": "/lib/", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/exe/src/a_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/exe/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/lib/src/a_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/lib/src/lib.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/exe/src/a_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/exe/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/lib/src/a_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/lib/src/lib.rs", + "ms": "__REDACTED__" + } + ], "summary": { "durations": { "extract": { diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected index 3c4fc9bf431..8ab17e9fe73 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected @@ -1,5 +1,72 @@ { "attributes": { + "steps": [ + { + "action": "extract", + "file": "/exe/src/a_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "extract", + "file": "/exe/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "extract", + "file": "/lib/src/a_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "extract", + "file": "/lib/src/lib.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadManifest", + "file": "/", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/exe/src/a_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/exe/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/lib/src/a_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/lib/src/lib.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/exe/src/a_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/exe/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/lib/src/a_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/lib/src/lib.rs", + "ms": "__REDACTED__" + } + ], "summary": { "durations": { "extract": { From d89678f49f46e79421a4da65111de531dc80f6de Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 27 Nov 2024 14:26:25 +0100 Subject: [PATCH 307/470] Rust: Data flow through tuple and struct fields --- .../rust/dataflow/internal/DataFlowImpl.qll | 152 +++++++++++++++--- .../dataflow/local/DataFlowStep.expected | 45 +++++- .../dataflow/local/inline-flow.expected | 40 +++++ .../test/library-tests/dataflow/local/main.rs | 12 +- 4 files changed, 220 insertions(+), 29 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 6fcb878c8ea..84f1805a649 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -252,10 +252,10 @@ module Node { * Nodes corresponding to AST elements, for example `ExprNode`, usually refer * to the value before the update. */ - final class PostUpdateNode extends Node, TArgumentPostUpdateNode { + final class PostUpdateNode extends Node, TExprPostUpdateNode { private ExprCfgNode n; - PostUpdateNode() { this = TArgumentPostUpdateNode(n) } + PostUpdateNode() { this = TExprPostUpdateNode(n) } /** Gets the node before the state update. */ Node getPreUpdateNode() { result = TExprNode(n) } @@ -449,6 +449,49 @@ private class VariantFieldContent extends VariantContent, TVariantFieldContent { } } +/** A canonical path pointing to a struct. */ +private class StructCanonicalPath extends MkStructCanonicalPath { + CrateOriginOption crate; + string path; + + StructCanonicalPath() { this = MkStructCanonicalPath(crate, path) } + + /** Gets the underlying struct. */ + Struct getStruct() { hasExtendedCanonicalPath(result, crate, path) } + + string toString() { result = this.getStruct().getName().getText() } + + Location getLocation() { result = this.getStruct().getLocation() } +} + +/** Content stored in a field on a struct. */ +private class StructFieldContent extends VariantContent, TStructFieldContent { + private StructCanonicalPath s; + private string field_; + + StructFieldContent() { this = TStructFieldContent(s, field_) } + + StructCanonicalPath getStructCanonicalPath(string field) { result = s and field = field_ } + + override string toString() { result = s.toString() + "." + field_.toString() } +} + +/** + * Content stored at a position in a tuple. + * + * NOTE: Unlike `struct`s and `enum`s tuples are structural and not nominal, + * hence we don't store a canonical path for them. + */ +private class TuplePositionContent extends VariantContent, TTuplePositionContent { + private int pos; + + TuplePositionContent() { this = TTuplePositionContent(pos) } + + int getPosition() { result = pos } + + override string toString() { result = "tuple." + pos.toString() } +} + /** A value that represents a set of `Content`s. */ abstract class ContentSet extends TContentSet { /** Gets a textual representation of this element. */ @@ -608,6 +651,14 @@ module RustDataFlow implements InputSig { */ predicate jumpStep(Node node1, Node node2) { none() } + /** Holds if path `p` resolves to struct `s`. */ + private predicate pathResolveToStructCanonicalPath(Path p, StructCanonicalPath s) { + exists(CrateOriginOption crate, string path | + resolveExtendedCanonicalPath(p, crate, path) and + s = MkStructCanonicalPath(crate, path) + ) + } + /** Holds if path `p` resolves to variant `v`. */ private predicate pathResolveToVariantCanonicalPath(Path p, VariantCanonicalPath v) { exists(CrateOriginOption crate, string path | @@ -636,6 +687,12 @@ module RustDataFlow implements InputSig { pathResolveToVariantCanonicalPath(p.getPath(), v) } + /** Holds if `p` destructs an struct `s`. */ + pragma[nomagic] + private predicate structDestruction(RecordPat p, StructCanonicalPath s) { + pathResolveToStructCanonicalPath(p.getPath(), s) + } + /** * Holds if data can flow from `node1` to `node2` via a read of `c`. Thus, * `node1` references an object with a content `c.getAReadContent()` whose @@ -652,10 +709,24 @@ module RustDataFlow implements InputSig { or exists(RecordPatCfgNode pat, string field | pat = node1.asPat() and - recordVariantDestruction(pat.getPat(), - c.(VariantFieldContent).getVariantCanonicalPath(field)) and + ( + // Pattern destructs a struct-like variant. + recordVariantDestruction(pat.getPat(), + c.(VariantFieldContent).getVariantCanonicalPath(field)) + or + // Pattern destructs a struct. + structDestruction(pat.getPat(), c.(StructFieldContent).getStructCanonicalPath(field)) + ) and node2.asPat() = pat.getFieldPat(field) ) + or + exists(FieldExprCfgNode access | + // Read of a tuple entry + access.getNameRef().getText().toInt() = c.(TuplePositionContent).getPosition() and + // TODO: Handle read of a struct field. + node1.asExpr() = access.getExpr() and + node2.asExpr() = access + ) ) } @@ -671,6 +742,12 @@ module RustDataFlow implements InputSig { pathResolveToVariantCanonicalPath(re.getPath(), v) } + /** Holds if `re` constructs a struct value of type `v`. */ + pragma[nomagic] + private predicate structConstruction(RecordExpr re, StructCanonicalPath s) { + pathResolveToStructCanonicalPath(re.getPath(), s) + } + /** * Holds if data can flow from `node1` to `node2` via a store into `c`. Thus, * `node2` references an object with a content `c.getAStoreContent()` that @@ -678,23 +755,31 @@ module RustDataFlow implements InputSig { */ predicate storeStep(Node node1, ContentSet cs, Node node2) { exists(Content c | c = cs.(SingletonContentSet).getContent() | - node2.asExpr() = - any(CallExprCfgNode call, int pos | - tupleVariantConstruction(call.getCallExpr(), - c.(VariantPositionContent).getVariantCanonicalPath(pos)) and - node1.asExpr() = call.getArgument(pos) - | - call - ) + exists(CallExprCfgNode call, int pos | + tupleVariantConstruction(call.getCallExpr(), + c.(VariantPositionContent).getVariantCanonicalPath(pos)) and + node1.asExpr() = call.getArgument(pos) and + node2.asExpr() = call + ) or - node2.asExpr() = - any(RecordExprCfgNode re, string field | + exists(RecordExprCfgNode re, string field | + ( + // Expression is for a struct-like enum variant. recordVariantConstruction(re.getRecordExpr(), - c.(VariantFieldContent).getVariantCanonicalPath(field)) and - node1.asExpr() = re.getFieldExpr(field) - | - re - ) + c.(VariantFieldContent).getVariantCanonicalPath(field)) + or + // Expression is for a struct. + structConstruction(re.getRecordExpr(), + c.(StructFieldContent).getStructCanonicalPath(field)) + ) and + node1.asExpr() = re.getFieldExpr(field) and + node2.asExpr() = re + ) + or + exists(TupleExprCfgNode tuple | + node1.asExpr() = tuple.getField(c.(TuplePositionContent).getPosition()) and + node2.asExpr() = tuple + ) ) } @@ -703,7 +788,14 @@ module RustDataFlow implements InputSig { * any value stored inside `f` is cleared at the pre-update node associated with `x` * in `x.f = newValue`. */ - predicate clearsContent(Node n, ContentSet c) { none() } + predicate clearsContent(Node n, ContentSet c) { + exists(AssignmentExprCfgNode assignment, FieldExprCfgNode access | + assignment.getLhs() = access and + n.asExpr() = access.getExpr() and + access.getNameRef().getText().toInt() = + c.(SingletonContentSet).getContent().(TuplePositionContent).getPosition() + ) + } /** * Holds if the value that is being tracked is expected to be stored inside content `c` @@ -773,7 +865,9 @@ private module Cached { TExprNode(ExprCfgNode n) or TParameterNode(ParamBaseCfgNode p) or TPatNode(PatCfgNode p) or - TArgumentPostUpdateNode(ExprCfgNode e) { isArgumentForCall(e, _, _) } or + TExprPostUpdateNode(ExprCfgNode e) { + isArgumentForCall(e, _, _) or e = any(FieldExprCfgNode access).getExpr() + } or TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node) cached @@ -811,6 +905,12 @@ private module Cached { name = ["Ok", "Err"] } + cached + newtype TStructCanonicalPath = + MkStructCanonicalPath(CrateOriginOption crate, string path) { + exists(Struct s | hasExtendedCanonicalPath(s, crate, path)) + } + cached newtype TContent = TVariantPositionContent(VariantCanonicalPath v, int pos) { @@ -826,6 +926,16 @@ private module Cached { } or TVariantFieldContent(VariantCanonicalPath v, string field) { field = v.getVariant().getFieldList().(RecordFieldList).getAField().getName().getText() + } or + TTuplePositionContent(int pos) { + pos in [0 .. max([ + any(TuplePat pat).getNumberOfFields(), + any(FieldExpr access).getNameRef().getText().toInt() + ] + )] + } or + TStructFieldContent(StructCanonicalPath s, string field) { + field = s.getStruct().getFieldList().(RecordFieldList).getAField().getName().getText() } cached diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 63666e3dec6..1f8464c8152 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -103,9 +103,9 @@ localStep | main.rs:109:10:109:10 | a | main.rs:110:10:110:10 | a | | main.rs:110:10:110:10 | a | main.rs:111:5:111:5 | a | | main.rs:111:5:111:5 | a | main.rs:112:5:112:5 | a | -| main.rs:111:11:111:11 | 2 | main.rs:111:5:111:7 | a.1 | +| main.rs:111:11:111:20 | source(...) | main.rs:111:5:111:7 | a.0 | | main.rs:112:5:112:5 | a | main.rs:113:10:113:10 | a | -| main.rs:112:11:112:20 | source(...) | main.rs:112:5:112:7 | a.0 | +| main.rs:112:11:112:11 | 2 | main.rs:112:5:112:7 | a.1 | | main.rs:113:10:113:10 | a | main.rs:114:10:114:10 | a | | main.rs:118:9:118:9 | [SSA] a | main.rs:119:14:119:14 | a | | main.rs:118:9:118:9 | a | main.rs:118:9:118:9 | [SSA] a | @@ -329,6 +329,31 @@ localStep | main.rs:304:22:304:22 | n | main.rs:304:22:304:22 | [SSA] n | | main.rs:304:29:304:35 | sink(...) | main.rs:302:5:305:5 | match s2 { ... } | storeStep +| main.rs:94:14:94:22 | source(...) | tuple.0 | main.rs:94:13:94:26 | TupleExpr | +| main.rs:94:25:94:25 | 2 | tuple.1 | main.rs:94:13:94:26 | TupleExpr | +| main.rs:100:14:100:14 | 2 | tuple.0 | main.rs:100:13:100:30 | TupleExpr | +| main.rs:100:17:100:26 | source(...) | tuple.1 | main.rs:100:13:100:30 | TupleExpr | +| main.rs:100:29:100:29 | 2 | tuple.2 | main.rs:100:13:100:30 | TupleExpr | +| main.rs:108:18:108:18 | 2 | tuple.0 | main.rs:108:17:108:31 | TupleExpr | +| main.rs:108:21:108:30 | source(...) | tuple.1 | main.rs:108:17:108:31 | TupleExpr | +| main.rs:118:14:118:14 | 3 | tuple.0 | main.rs:118:13:118:27 | TupleExpr | +| main.rs:118:17:118:26 | source(...) | tuple.1 | main.rs:118:13:118:27 | TupleExpr | +| main.rs:119:14:119:14 | a | tuple.0 | main.rs:119:13:119:18 | TupleExpr | +| main.rs:119:17:119:17 | 3 | tuple.1 | main.rs:119:13:119:18 | TupleExpr | +| main.rs:135:12:135:20 | source(...) | Point.x | main.rs:134:13:137:5 | Point {...} | +| main.rs:136:12:136:12 | 2 | Point.y | main.rs:134:13:137:5 | Point {...} | +| main.rs:144:12:144:20 | source(...) | Point.x | main.rs:143:17:146:5 | Point {...} | +| main.rs:145:12:145:12 | 2 | Point.y | main.rs:143:17:146:5 | Point {...} | +| main.rs:154:12:154:21 | source(...) | Point.x | main.rs:153:13:156:5 | Point {...} | +| main.rs:155:12:155:12 | 2 | Point.y | main.rs:153:13:156:5 | Point {...} | +| main.rs:169:16:172:9 | Point {...} | Point3D.plane | main.rs:168:13:174:5 | Point3D {...} | +| main.rs:170:16:170:16 | 2 | Point.x | main.rs:169:16:172:9 | Point {...} | +| main.rs:171:16:171:25 | source(...) | Point.y | main.rs:169:16:172:9 | Point {...} | +| main.rs:173:12:173:12 | 4 | Point3D.z | main.rs:168:13:174:5 | Point3D {...} | +| main.rs:182:16:185:9 | Point {...} | Point3D.plane | main.rs:181:13:187:5 | Point3D {...} | +| main.rs:183:16:183:16 | 2 | Point.x | main.rs:182:16:185:9 | Point {...} | +| main.rs:184:16:184:25 | source(...) | Point.y | main.rs:182:16:185:9 | Point {...} | +| main.rs:186:12:186:12 | 4 | Point3D.z | main.rs:181:13:187:5 | Point3D {...} | | main.rs:214:19:214:28 | source(...) | Some | main.rs:214:14:214:29 | Some(...) | | main.rs:215:19:215:19 | 2 | Some | main.rs:215:14:215:20 | Some(...) | | main.rs:232:29:232:38 | source(...) | A | main.rs:232:14:232:39 | ...::A(...) | @@ -338,6 +363,22 @@ storeStep | main.rs:312:27:312:27 | 0 | Some | main.rs:312:22:312:28 | Some(...) | readStep | main.rs:33:9:33:15 | TupleStructPat | Some | main.rs:33:14:33:14 | _ | +| main.rs:95:10:95:10 | a | tuple.0 | main.rs:95:10:95:12 | a.0 | +| main.rs:96:10:96:10 | a | tuple.1 | main.rs:96:10:96:12 | a.1 | +| main.rs:109:10:109:10 | a | tuple.0 | main.rs:109:10:109:12 | a.0 | +| main.rs:110:10:110:10 | a | tuple.1 | main.rs:110:10:110:12 | a.1 | +| main.rs:111:5:111:5 | a | tuple.0 | main.rs:111:5:111:7 | a.0 | +| main.rs:112:5:112:5 | a | tuple.1 | main.rs:112:5:112:7 | a.1 | +| main.rs:113:10:113:10 | a | tuple.0 | main.rs:113:10:113:12 | a.0 | +| main.rs:114:10:114:10 | a | tuple.1 | main.rs:114:10:114:12 | a.1 | +| main.rs:120:10:120:10 | b | tuple.0 | main.rs:120:10:120:12 | b.0 | +| main.rs:120:10:120:12 | b.0 | tuple.0 | main.rs:120:10:120:14 | ... .0 | +| main.rs:121:10:121:10 | b | tuple.0 | main.rs:121:10:121:12 | b.0 | +| main.rs:121:10:121:12 | b.0 | tuple.1 | main.rs:121:10:121:14 | ... .1 | +| main.rs:122:10:122:10 | b | tuple.1 | main.rs:122:10:122:12 | b.1 | +| main.rs:157:9:157:28 | Point {...} | Point.x | main.rs:157:20:157:20 | a | +| main.rs:157:9:157:28 | Point {...} | Point.y | main.rs:157:26:157:26 | b | +| main.rs:189:9:189:45 | Point3D {...} | Point3D.plane | main.rs:189:26:189:39 | Point {...} | | main.rs:217:9:217:15 | TupleStructPat | Some | main.rs:217:14:217:14 | n | | main.rs:221:9:221:15 | TupleStructPat | Some | main.rs:221:14:221:14 | n | | main.rs:235:9:235:25 | TupleStructPat | A | main.rs:235:24:235:24 | n | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index d9a10521997..24aadadc589 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -5,6 +5,22 @@ edges | main.rs:31:13:31:21 | source(...) | main.rs:36:10:36:10 | b | provenance | | | main.rs:45:15:45:23 | source(...) | main.rs:47:10:47:10 | b | provenance | | | main.rs:53:9:53:17 | source(...) | main.rs:54:10:54:10 | i | provenance | | +| main.rs:94:13:94:26 | TupleExpr [tuple.0] | main.rs:95:10:95:10 | a [tuple.0] | provenance | | +| main.rs:94:14:94:22 | source(...) | main.rs:94:13:94:26 | TupleExpr [tuple.0] | provenance | | +| main.rs:95:10:95:10 | a [tuple.0] | main.rs:95:10:95:12 | a.0 | provenance | | +| main.rs:108:17:108:31 | TupleExpr [tuple.1] | main.rs:110:10:110:10 | a [tuple.1] | provenance | | +| main.rs:108:21:108:30 | source(...) | main.rs:108:17:108:31 | TupleExpr [tuple.1] | provenance | | +| main.rs:110:10:110:10 | a [tuple.1] | main.rs:110:10:110:12 | a.1 | provenance | | +| main.rs:118:13:118:27 | TupleExpr [tuple.1] | main.rs:119:14:119:14 | a [tuple.1] | provenance | | +| main.rs:118:17:118:26 | source(...) | main.rs:118:13:118:27 | TupleExpr [tuple.1] | provenance | | +| main.rs:119:13:119:18 | TupleExpr [tuple.0, tuple.1] | main.rs:121:10:121:10 | b [tuple.0, tuple.1] | provenance | | +| main.rs:119:14:119:14 | a [tuple.1] | main.rs:119:13:119:18 | TupleExpr [tuple.0, tuple.1] | provenance | | +| main.rs:121:10:121:10 | b [tuple.0, tuple.1] | main.rs:121:10:121:12 | b.0 [tuple.1] | provenance | | +| main.rs:121:10:121:12 | b.0 [tuple.1] | main.rs:121:10:121:14 | ... .1 | provenance | | +| main.rs:153:13:156:5 | Point {...} [Point.x] | main.rs:157:9:157:28 | Point {...} [Point.x] | provenance | | +| main.rs:154:12:154:21 | source(...) | main.rs:153:13:156:5 | Point {...} [Point.x] | provenance | | +| main.rs:157:9:157:28 | Point {...} [Point.x] | main.rs:157:20:157:20 | a | provenance | | +| main.rs:157:20:157:20 | a | main.rs:158:10:158:10 | a | provenance | | | main.rs:214:14:214:29 | Some(...) [Some] | main.rs:217:9:217:15 | TupleStructPat [Some] | provenance | | | main.rs:214:19:214:28 | source(...) | main.rs:214:14:214:29 | Some(...) [Some] | provenance | | | main.rs:217:9:217:15 | TupleStructPat [Some] | main.rs:217:14:217:14 | n | provenance | | @@ -35,6 +51,26 @@ nodes | main.rs:47:10:47:10 | b | semmle.label | b | | main.rs:53:9:53:17 | source(...) | semmle.label | source(...) | | main.rs:54:10:54:10 | i | semmle.label | i | +| main.rs:94:13:94:26 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] | +| main.rs:94:14:94:22 | source(...) | semmle.label | source(...) | +| main.rs:95:10:95:10 | a [tuple.0] | semmle.label | a [tuple.0] | +| main.rs:95:10:95:12 | a.0 | semmle.label | a.0 | +| main.rs:108:17:108:31 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] | +| main.rs:108:21:108:30 | source(...) | semmle.label | source(...) | +| main.rs:110:10:110:10 | a [tuple.1] | semmle.label | a [tuple.1] | +| main.rs:110:10:110:12 | a.1 | semmle.label | a.1 | +| main.rs:118:13:118:27 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] | +| main.rs:118:17:118:26 | source(...) | semmle.label | source(...) | +| main.rs:119:13:119:18 | TupleExpr [tuple.0, tuple.1] | semmle.label | TupleExpr [tuple.0, tuple.1] | +| main.rs:119:14:119:14 | a [tuple.1] | semmle.label | a [tuple.1] | +| main.rs:121:10:121:10 | b [tuple.0, tuple.1] | semmle.label | b [tuple.0, tuple.1] | +| main.rs:121:10:121:12 | b.0 [tuple.1] | semmle.label | b.0 [tuple.1] | +| main.rs:121:10:121:14 | ... .1 | semmle.label | ... .1 | +| main.rs:153:13:156:5 | Point {...} [Point.x] | semmle.label | Point {...} [Point.x] | +| main.rs:154:12:154:21 | source(...) | semmle.label | source(...) | +| main.rs:157:9:157:28 | Point {...} [Point.x] | semmle.label | Point {...} [Point.x] | +| main.rs:157:20:157:20 | a | semmle.label | a | +| main.rs:158:10:158:10 | a | semmle.label | a | | main.rs:214:14:214:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | | main.rs:214:19:214:28 | source(...) | semmle.label | source(...) | | main.rs:217:9:217:15 | TupleStructPat [Some] | semmle.label | TupleStructPat [Some] | @@ -65,6 +101,10 @@ testFailures | main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | source(...) | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | source(...) | source(...) | | main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | source(...) | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | source(...) | source(...) | | main.rs:54:10:54:10 | i | main.rs:53:9:53:17 | source(...) | main.rs:54:10:54:10 | i | $@ | main.rs:53:9:53:17 | source(...) | source(...) | +| main.rs:95:10:95:12 | a.0 | main.rs:94:14:94:22 | source(...) | main.rs:95:10:95:12 | a.0 | $@ | main.rs:94:14:94:22 | source(...) | source(...) | +| main.rs:110:10:110:12 | a.1 | main.rs:108:21:108:30 | source(...) | main.rs:110:10:110:12 | a.1 | $@ | main.rs:108:21:108:30 | source(...) | source(...) | +| main.rs:121:10:121:14 | ... .1 | main.rs:118:17:118:26 | source(...) | main.rs:121:10:121:14 | ... .1 | $@ | main.rs:118:17:118:26 | source(...) | source(...) | +| main.rs:158:10:158:10 | a | main.rs:154:12:154:21 | source(...) | main.rs:158:10:158:10 | a | $@ | main.rs:154:12:154:21 | source(...) | source(...) | | main.rs:217:25:217:25 | n | main.rs:214:19:214:28 | source(...) | main.rs:217:25:217:25 | n | $@ | main.rs:214:19:214:28 | source(...) | source(...) | | main.rs:235:35:235:35 | n | main.rs:232:29:232:38 | source(...) | main.rs:235:35:235:35 | n | $@ | main.rs:232:29:232:38 | source(...) | source(...) | | main.rs:239:55:239:55 | n | main.rs:232:29:232:38 | source(...) | main.rs:239:55:239:55 | n | $@ | main.rs:232:29:232:38 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/local/main.rs b/rust/ql/test/library-tests/dataflow/local/main.rs index 89482c86db4..7110d6072c1 100644 --- a/rust/ql/test/library-tests/dataflow/local/main.rs +++ b/rust/ql/test/library-tests/dataflow/local/main.rs @@ -92,7 +92,7 @@ fn box_deref() { fn tuple() { let a = (source(8), 2); - sink(a.0); // $ MISSING: hasValueFlow=8 + sink(a.0); // $ hasValueFlow=8 sink(a.1); } @@ -107,18 +107,18 @@ fn tuple_match() { fn tuple_mutation() { let mut a = (2, source(38)); sink(a.0); - sink(a.1); // $ MISSING: hasValueFlow=38 - a.1 = 2; + sink(a.1); // $ hasValueFlow=38 a.0 = source(70); + a.1 = 2; sink(a.0); // $ MISSING: hasValueFlow=70 sink(a.1); } fn tuple_nested() { - let a = (source(59), 3); + let a = (3, source(59)); let b = (a, 3); sink(b.0.0); - sink(b.0.1); // $ MISSING: hasValueFlow=59 + sink(b.0.1); // $ hasValueFlow=59 sink(b.1); } @@ -155,7 +155,7 @@ fn struct_pattern_match() { y: 2, }; let Point { x: a, y: b } = p; - sink(a); // $ MISSING: hasValueFlow=11 + sink(a); // $ hasValueFlow=11 sink(b); } From 4e7115538bf8f63788c19694c1ea0b430b4fbe17 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 27 Nov 2024 14:55:46 +0100 Subject: [PATCH 308/470] Rust: move steps breakdown from JSON diagnostics to the DB --- rust/extractor/src/diagnostics.rs | 23 ++-- rust/extractor/src/main.rs | 24 +++- rust/extractor/src/trap.rs | 4 +- rust/prefix.dbscheme | 7 ++ rust/ql/integration-tests/conftest.py | 9 +- .../hello-project/diagnostics.expected | 117 +++--------------- .../hello-project/steps.cargo.expected | 15 +++ .../integration-tests/hello-project/steps.ql | 4 + .../hello-project/steps.rust-project.expected | 15 +++ .../hello-project/test_project.py | 5 + .../diagnostics.cargo.expected | 112 +++-------------- .../diagnostics.rust-project.expected | 107 +++------------- .../hello-workspace/steps.cargo.expected | 14 +++ .../hello-workspace/steps.ql | 4 + .../steps.rust-project.expected | 13 ++ .../hello-workspace/test_workspace.py | 6 +- .../codeql/rust/internal/ExtractorStep.qll | 46 +++++++ rust/ql/lib/rust.dbscheme | 7 ++ 18 files changed, 224 insertions(+), 308 deletions(-) create mode 100644 rust/ql/integration-tests/hello-project/steps.cargo.expected create mode 100644 rust/ql/integration-tests/hello-project/steps.ql create mode 100644 rust/ql/integration-tests/hello-project/steps.rust-project.expected create mode 100644 rust/ql/integration-tests/hello-workspace/steps.cargo.expected create mode 100644 rust/ql/integration-tests/hello-workspace/steps.ql create mode 100644 rust/ql/integration-tests/hello-workspace/steps.rust-project.expected create mode 100644 rust/ql/lib/codeql/rust/internal/ExtractorStep.qll diff --git a/rust/extractor/src/diagnostics.rs b/rust/extractor/src/diagnostics.rs index d4b60211bbf..92743a923d4 100644 --- a/rust/extractor/src/diagnostics.rs +++ b/rust/extractor/src/diagnostics.rs @@ -76,7 +76,7 @@ pub struct Diagnostics { #[derive(Default, Debug, Clone, Copy, Serialize, PartialEq, Eq, Hash)] #[serde(rename_all = "camelCase")] -enum ExtractionStepKind { +pub enum ExtractionStepKind { #[default] LoadManifest, LoadSource, @@ -87,9 +87,9 @@ enum ExtractionStepKind { #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] pub struct ExtractionStep { - action: ExtractionStepKind, - file: PathBuf, - ms: u128, + pub action: ExtractionStepKind, + pub file: PathBuf, + pub ms: u128, } impl ExtractionStep { @@ -186,14 +186,7 @@ struct ExtractionSummary { durations: DurationsSummary, } -#[derive(Debug, Default, Clone, Serialize)] -#[serde(rename_all = "camelCase")] -struct ExtractionAttributes { - steps: Vec, - summary: ExtractionSummary, -} - -type ExtractionDiagnostics = Diagnostics; +type ExtractionDiagnostics = Diagnostics; fn summary(start: Instant, steps: &[ExtractionStep]) -> ExtractionSummary { let mut number_of_manifests = 0; @@ -229,9 +222,9 @@ fn summary(start: Instant, steps: &[ExtractionStep]) -> ExtractionSummary { pub fn emit_extraction_diagnostics( start: Instant, config: &Config, - steps: Vec, + steps: &[ExtractionStep], ) -> anyhow::Result<()> { - let summary = summary(start, &steps); + let summary = summary(start, steps); let diagnostics = ExtractionDiagnostics { source: Source { id: "rust/extractor/telemetry".to_owned(), @@ -243,7 +236,7 @@ pub fn emit_extraction_diagnostics( ..Default::default() }, timestamp: Utc::now(), - attributes: ExtractionAttributes { steps, summary }, + attributes: summary, ..Default::default() }; diff --git a/rust/extractor/src/main.rs b/rust/extractor/src/main.rs index 19239cf9dd4..a3258f16d09 100644 --- a/rust/extractor/src/main.rs +++ b/rust/extractor/src/main.rs @@ -2,7 +2,7 @@ use crate::diagnostics::{emit_extraction_diagnostics, ExtractionStep}; use crate::rust_analyzer::path_to_file_id; use anyhow::Context; use archive::Archiver; -use log::info; +use log::{info, warn}; use ra_ap_hir::Semantics; use ra_ap_ide_db::line_index::{LineCol, LineIndex}; use ra_ap_ide_db::RootDatabase; @@ -140,7 +140,27 @@ impl<'a> Extractor<'a> { start: Instant, cfg: &config::Config, ) -> anyhow::Result<()> { - emit_extraction_diagnostics(start, cfg, self.steps) + emit_extraction_diagnostics(start, cfg, &self.steps)?; + let mut trap = self.traps.create("diagnostics", "extraction"); + for step in self.steps { + let file_label = trap.emit_file(&step.file); + let step_label = trap.writer.fresh_id(); + let ms = usize::try_from(step.ms).unwrap_or_else(|_e| { + warn!("extraction step duration overflowed ({step:?})"); + i32::MAX as usize + }); + trap.writer.add_tuple( + "extractor_steps", + vec![ + step_label.into(), + format!("{:?}", step.action).into(), + file_label.into(), + ms.into(), + ], + ); + } + trap.commit()?; + Ok(()) } } diff --git a/rust/extractor/src/trap.rs b/rust/extractor/src/trap.rs index 58f56fb2b1e..c993fa046a7 100644 --- a/rust/extractor/src/trap.rs +++ b/rust/extractor/src/trap.rs @@ -243,8 +243,8 @@ impl TrapFileProvider { }) } - pub fn create(&self, category: &str, key: &Path) -> TrapFile { - let path = file_paths::path_for(&self.trap_dir.join(category), key, "trap"); + pub fn create(&self, category: &str, key: impl AsRef) -> TrapFile { + let path = file_paths::path_for(&self.trap_dir.join(category), key.as_ref(), "trap"); debug!("creating trap file {}", path.display()); let mut writer = trap::Writer::new(); extractor::populate_empty_location(&mut writer); diff --git a/rust/prefix.dbscheme b/rust/prefix.dbscheme index 4810e11069d..5ccbd3438d1 100644 --- a/rust/prefix.dbscheme +++ b/rust/prefix.dbscheme @@ -3,3 +3,10 @@ locatable_locations( int id: @locatable ref, int location: @location_default ref ); + +extractor_steps( + unique int id: @extractor_step, + string action: string ref, + int file: @file ref, + int duration_ms: int ref +) diff --git a/rust/ql/integration-tests/conftest.py b/rust/ql/integration-tests/conftest.py index cbace615805..79c899c97fc 100644 --- a/rust/ql/integration-tests/conftest.py +++ b/rust/ql/integration-tests/conftest.py @@ -16,13 +16,8 @@ def manifests(cwd): @pytest.fixture def rust_check_diagnostics(check_diagnostics): - check_diagnostics.replacements += [ - ("Cargo.toml|rust-project.json", ""), - ] check_diagnostics.redact += [ - "attributes.summary.durations.*.ms", - "attributes.summary.durations.*.pretty", - "attributes.steps.ms", + "attributes.durations.*.ms", + "attributes.durations.*.pretty", ] - check_diagnostics.sort = True # the order of the steps is not stable return check_diagnostics diff --git a/rust/ql/integration-tests/hello-project/diagnostics.expected b/rust/ql/integration-tests/hello-project/diagnostics.expected index 5f6821ffb10..f938b5b8ab5 100644 --- a/rust/ql/integration-tests/hello-project/diagnostics.expected +++ b/rust/ql/integration-tests/hello-project/diagnostics.expected @@ -1,108 +1,29 @@ { "attributes": { - "steps": [ - { - "action": "extract", - "file": "/src/directory_module/mod.rs", - "ms": "__REDACTED__" + "durations": { + "extract": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/src/directory_module/nested_module.rs", - "ms": "__REDACTED__" + "loadManifest": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/src/directory_module/not_loaded.rs", - "ms": "__REDACTED__" + "loadSource": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/src/file_module.rs", - "ms": "__REDACTED__" + "parse": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/src/main.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadManifest", - "file": "/", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/src/directory_module/mod.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/src/directory_module/nested_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/src/file_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/src/main.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/src/directory_module/mod.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/src/directory_module/nested_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/src/directory_module/not_loaded.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/src/file_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/src/main.rs", - "ms": "__REDACTED__" + "total": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" } - ], - "summary": { - "durations": { - "extract": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "loadManifest": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "loadSource": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "parse": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "total": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - } - }, - "numberOfFiles": 5, - "numberOfManifests": 1 - } + }, + "numberOfFiles": 5, + "numberOfManifests": 1 }, "severity": "note", "source": { diff --git a/rust/ql/integration-tests/hello-project/steps.cargo.expected b/rust/ql/integration-tests/hello-project/steps.cargo.expected new file mode 100644 index 00000000000..61987aa564b --- /dev/null +++ b/rust/ql/integration-tests/hello-project/steps.cargo.expected @@ -0,0 +1,15 @@ +| Cargo.toml:0:0:0:0 | LoadManifest(Cargo.toml) | +| src/directory_module/mod.rs:0:0:0:0 | Extract(src/directory_module/mod.rs) | +| src/directory_module/mod.rs:0:0:0:0 | LoadSource(src/directory_module/mod.rs) | +| src/directory_module/mod.rs:0:0:0:0 | Parse(src/directory_module/mod.rs) | +| src/directory_module/nested_module.rs:0:0:0:0 | Extract(src/directory_module/nested_module.rs) | +| src/directory_module/nested_module.rs:0:0:0:0 | LoadSource(src/directory_module/nested_module.rs) | +| src/directory_module/nested_module.rs:0:0:0:0 | Parse(src/directory_module/nested_module.rs) | +| src/directory_module/not_loaded.rs:0:0:0:0 | Extract(src/directory_module/not_loaded.rs) | +| src/directory_module/not_loaded.rs:0:0:0:0 | Parse(src/directory_module/not_loaded.rs) | +| src/file_module.rs:0:0:0:0 | Extract(src/file_module.rs) | +| src/file_module.rs:0:0:0:0 | LoadSource(src/file_module.rs) | +| src/file_module.rs:0:0:0:0 | Parse(src/file_module.rs) | +| src/main.rs:0:0:0:0 | Extract(src/main.rs) | +| src/main.rs:0:0:0:0 | LoadSource(src/main.rs) | +| src/main.rs:0:0:0:0 | Parse(src/main.rs) | diff --git a/rust/ql/integration-tests/hello-project/steps.ql b/rust/ql/integration-tests/hello-project/steps.ql new file mode 100644 index 00000000000..eb8f9a05adb --- /dev/null +++ b/rust/ql/integration-tests/hello-project/steps.ql @@ -0,0 +1,4 @@ +import codeql.rust.internal.ExtractorStep + +from ExtractorStep step +select step diff --git a/rust/ql/integration-tests/hello-project/steps.rust-project.expected b/rust/ql/integration-tests/hello-project/steps.rust-project.expected new file mode 100644 index 00000000000..d1d2e9ddee3 --- /dev/null +++ b/rust/ql/integration-tests/hello-project/steps.rust-project.expected @@ -0,0 +1,15 @@ +| rust-project.json:0:0:0:0 | LoadManifest(rust-project.json) | +| src/directory_module/mod.rs:0:0:0:0 | Extract(src/directory_module/mod.rs) | +| src/directory_module/mod.rs:0:0:0:0 | LoadSource(src/directory_module/mod.rs) | +| src/directory_module/mod.rs:0:0:0:0 | Parse(src/directory_module/mod.rs) | +| src/directory_module/nested_module.rs:0:0:0:0 | Extract(src/directory_module/nested_module.rs) | +| src/directory_module/nested_module.rs:0:0:0:0 | LoadSource(src/directory_module/nested_module.rs) | +| src/directory_module/nested_module.rs:0:0:0:0 | Parse(src/directory_module/nested_module.rs) | +| src/directory_module/not_loaded.rs:0:0:0:0 | Extract(src/directory_module/not_loaded.rs) | +| src/directory_module/not_loaded.rs:0:0:0:0 | Parse(src/directory_module/not_loaded.rs) | +| src/file_module.rs:0:0:0:0 | Extract(src/file_module.rs) | +| src/file_module.rs:0:0:0:0 | LoadSource(src/file_module.rs) | +| src/file_module.rs:0:0:0:0 | Parse(src/file_module.rs) | +| src/main.rs:0:0:0:0 | Extract(src/main.rs) | +| src/main.rs:0:0:0:0 | LoadSource(src/main.rs) | +| src/main.rs:0:0:0:0 | Parse(src/main.rs) | diff --git a/rust/ql/integration-tests/hello-project/test_project.py b/rust/ql/integration-tests/hello-project/test_project.py index 2cbac0ffdb8..64988bef7a9 100644 --- a/rust/ql/integration-tests/hello-project/test_project.py +++ b/rust/ql/integration-tests/hello-project/test_project.py @@ -1,7 +1,12 @@ +import pytest + + +@pytest.mark.ql_test("steps.ql", expected=".cargo.expected") def test_cargo(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): manifests.select("Cargo.toml") codeql.database.create() +@pytest.mark.ql_test("steps.ql", expected=".rust-project.expected") def test_rust_project(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): manifests.select("rust-project.json") codeql.database.create() diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected index 7d484623087..7d44256db5a 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected @@ -1,103 +1,29 @@ { "attributes": { - "steps": [ - { - "action": "extract", - "file": "/exe/src/a_module.rs", - "ms": "__REDACTED__" + "durations": { + "extract": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/exe/src/main.rs", - "ms": "__REDACTED__" + "loadManifest": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/lib/src/a_module/mod.rs", - "ms": "__REDACTED__" + "loadSource": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/lib/src/lib.rs", - "ms": "__REDACTED__" + "parse": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "loadManifest", - "file": "/exe/", - "ms": "__REDACTED__" - }, - { - "action": "loadManifest", - "file": "/lib/", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/exe/src/a_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/exe/src/main.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/lib/src/a_module/mod.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/lib/src/lib.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/exe/src/a_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/exe/src/main.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/lib/src/a_module/mod.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/lib/src/lib.rs", - "ms": "__REDACTED__" + "total": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" } - ], - "summary": { - "durations": { - "extract": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "loadManifest": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "loadSource": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "parse": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "total": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - } - }, - "numberOfFiles": 4, - "numberOfManifests": 2 - } + }, + "numberOfFiles": 4, + "numberOfManifests": 2 }, "severity": "note", "source": { diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected index 8ab17e9fe73..4c5dbc75d84 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected @@ -1,98 +1,29 @@ { "attributes": { - "steps": [ - { - "action": "extract", - "file": "/exe/src/a_module.rs", - "ms": "__REDACTED__" + "durations": { + "extract": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/exe/src/main.rs", - "ms": "__REDACTED__" + "loadManifest": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/lib/src/a_module/mod.rs", - "ms": "__REDACTED__" + "loadSource": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/lib/src/lib.rs", - "ms": "__REDACTED__" + "parse": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "loadManifest", - "file": "/", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/exe/src/a_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/exe/src/main.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/lib/src/a_module/mod.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/lib/src/lib.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/exe/src/a_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/exe/src/main.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/lib/src/a_module/mod.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/lib/src/lib.rs", - "ms": "__REDACTED__" + "total": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" } - ], - "summary": { - "durations": { - "extract": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "loadManifest": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "loadSource": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "parse": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "total": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - } - }, - "numberOfFiles": 4, - "numberOfManifests": 1 - } + }, + "numberOfFiles": 4, + "numberOfManifests": 1 }, "severity": "note", "source": { diff --git a/rust/ql/integration-tests/hello-workspace/steps.cargo.expected b/rust/ql/integration-tests/hello-workspace/steps.cargo.expected new file mode 100644 index 00000000000..138bd77b690 --- /dev/null +++ b/rust/ql/integration-tests/hello-workspace/steps.cargo.expected @@ -0,0 +1,14 @@ +| exe/Cargo.toml:0:0:0:0 | LoadManifest(exe/Cargo.toml) | +| exe/src/a_module.rs:0:0:0:0 | Extract(exe/src/a_module.rs) | +| exe/src/a_module.rs:0:0:0:0 | LoadSource(exe/src/a_module.rs) | +| exe/src/a_module.rs:0:0:0:0 | Parse(exe/src/a_module.rs) | +| exe/src/main.rs:0:0:0:0 | Extract(exe/src/main.rs) | +| exe/src/main.rs:0:0:0:0 | LoadSource(exe/src/main.rs) | +| exe/src/main.rs:0:0:0:0 | Parse(exe/src/main.rs) | +| lib/Cargo.toml:0:0:0:0 | LoadManifest(lib/Cargo.toml) | +| lib/src/a_module/mod.rs:0:0:0:0 | Extract(lib/src/a_module/mod.rs) | +| lib/src/a_module/mod.rs:0:0:0:0 | LoadSource(lib/src/a_module/mod.rs) | +| lib/src/a_module/mod.rs:0:0:0:0 | Parse(lib/src/a_module/mod.rs) | +| lib/src/lib.rs:0:0:0:0 | Extract(lib/src/lib.rs) | +| lib/src/lib.rs:0:0:0:0 | LoadSource(lib/src/lib.rs) | +| lib/src/lib.rs:0:0:0:0 | Parse(lib/src/lib.rs) | diff --git a/rust/ql/integration-tests/hello-workspace/steps.ql b/rust/ql/integration-tests/hello-workspace/steps.ql new file mode 100644 index 00000000000..eb8f9a05adb --- /dev/null +++ b/rust/ql/integration-tests/hello-workspace/steps.ql @@ -0,0 +1,4 @@ +import codeql.rust.internal.ExtractorStep + +from ExtractorStep step +select step diff --git a/rust/ql/integration-tests/hello-workspace/steps.rust-project.expected b/rust/ql/integration-tests/hello-workspace/steps.rust-project.expected new file mode 100644 index 00000000000..09620925ce9 --- /dev/null +++ b/rust/ql/integration-tests/hello-workspace/steps.rust-project.expected @@ -0,0 +1,13 @@ +| exe/src/a_module.rs:0:0:0:0 | Extract(exe/src/a_module.rs) | +| exe/src/a_module.rs:0:0:0:0 | LoadSource(exe/src/a_module.rs) | +| exe/src/a_module.rs:0:0:0:0 | Parse(exe/src/a_module.rs) | +| exe/src/main.rs:0:0:0:0 | Extract(exe/src/main.rs) | +| exe/src/main.rs:0:0:0:0 | LoadSource(exe/src/main.rs) | +| exe/src/main.rs:0:0:0:0 | Parse(exe/src/main.rs) | +| lib/src/a_module/mod.rs:0:0:0:0 | Extract(lib/src/a_module/mod.rs) | +| lib/src/a_module/mod.rs:0:0:0:0 | LoadSource(lib/src/a_module/mod.rs) | +| lib/src/a_module/mod.rs:0:0:0:0 | Parse(lib/src/a_module/mod.rs) | +| lib/src/lib.rs:0:0:0:0 | Extract(lib/src/lib.rs) | +| lib/src/lib.rs:0:0:0:0 | LoadSource(lib/src/lib.rs) | +| lib/src/lib.rs:0:0:0:0 | Parse(lib/src/lib.rs) | +| rust-project.json:0:0:0:0 | LoadManifest(rust-project.json) | diff --git a/rust/ql/integration-tests/hello-workspace/test_workspace.py b/rust/ql/integration-tests/hello-workspace/test_workspace.py index 5c95031466f..3dd49991aaa 100644 --- a/rust/ql/integration-tests/hello-workspace/test_workspace.py +++ b/rust/ql/integration-tests/hello-workspace/test_workspace.py @@ -1,13 +1,13 @@ import pytest -# currently the DB-check fails on actions because of loading files multiple times and assiging multiple locations -# see https://github.com/github/codeql-team/issues/3365 -@pytest.mark.ql_test("DB-CHECK", xfail="maybe") + +@pytest.mark.ql_test("steps.ql", expected=".cargo.expected") def test_cargo(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): rust_check_diagnostics.expected_suffix = ".cargo.expected" manifests.select("Cargo.toml") codeql.database.create() +@pytest.mark.ql_test("steps.ql", expected=".rust-project.expected") def test_rust_project(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): rust_check_diagnostics.expected_suffix = ".rust-project.expected" manifests.select("rust-project.json") diff --git a/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll b/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll new file mode 100644 index 00000000000..55505be1d59 --- /dev/null +++ b/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll @@ -0,0 +1,46 @@ +import codeql.files.FileSystem + +/** + * An extractor step, usable for debugging and diagnostics reasons. + * + * INTERNAL: Do not use. + */ +class ExtractorStep extends @extractor_step { + /** + * The string representation of this extractor step. + */ + string toString() { + exists(File file, string action | + extractor_steps(this, action, file, _) and + result = action + "(" + file.getAbsolutePath() + ")" + ) + } + + /** + * The action this extractor step carried out. + */ + string getAction() { extractor_steps(this, result, _, _) } + + /** + * The file the extractor step was carried out on. + */ + File getFile() { extractor_steps(this, _, result, _) } + + /** + * The duration of the extractor step in milliseconds. + */ + int getDurationMs() { extractor_steps(this, _, _, result) } + + /** + * Provides location information for this step. + */ + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + this.getFile().getAbsolutePath() = filepath and + startline = 0 and + startcolumn = 0 and + endline = 0 and + endcolumn = 0 + } +} diff --git a/rust/ql/lib/rust.dbscheme b/rust/ql/lib/rust.dbscheme index 46085a55abf..26a22063d6d 100644 --- a/rust/ql/lib/rust.dbscheme +++ b/rust/ql/lib/rust.dbscheme @@ -116,6 +116,13 @@ locatable_locations( int location: @location_default ref ); +extractor_steps( + unique int id: @extractor_step, + string action: string ref, + int file: @file ref, + int duration_ms: int ref +) + // from schema From 2bc89900fb60af30bd046945ea88e8f748ae30ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20San=20Jos=C3=A9?= Date: Wed, 27 Nov 2024 16:16:45 +0100 Subject: [PATCH 309/470] Update codespaces default config to ubuntu 24 --- .devcontainer/devcontainer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 0b718747d9d..a51284e3a1f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,4 +1,5 @@ { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04", "extensions": [ "rust-lang.rust-analyzer", "bungcip.better-toml", From 5790f5d5dce75df9b45bdb851d6e76d38c6fd152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20San=20Jos=C3=A9?= Date: Wed, 27 Nov 2024 18:37:12 +0100 Subject: [PATCH 310/470] Include paths on pull_request event trigger for compile-queries.yml workflow --- .github/workflows/compile-queries.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/compile-queries.yml b/.github/workflows/compile-queries.yml index dfd99f6b806..aea37cdbe83 100644 --- a/.github/workflows/compile-queries.yml +++ b/.github/workflows/compile-queries.yml @@ -7,6 +7,11 @@ on: - "rc/*" - "codeql-cli-*" pull_request: + paths: + - '*.ql' + - '*.qll' + - '**/qlpack.yml' + - '*.dbscheme' permissions: contents: read From 1a0442c5a6ff6b18234986f67ae4f9d502290921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20San=20Jos=C3=A9?= Date: Wed, 27 Nov 2024 19:34:34 +0100 Subject: [PATCH 311/470] Adding correct wildcard --- .github/workflows/compile-queries.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/compile-queries.yml b/.github/workflows/compile-queries.yml index aea37cdbe83..945515c0c53 100644 --- a/.github/workflows/compile-queries.yml +++ b/.github/workflows/compile-queries.yml @@ -8,10 +8,10 @@ on: - "codeql-cli-*" pull_request: paths: - - '*.ql' - - '*.qll' + - '**.ql' + - '**.qll' - '**/qlpack.yml' - - '*.dbscheme' + - '**.dbscheme' permissions: contents: read From e8ddb6b1806db976497a122764aee80c7ae82e94 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 28 Nov 2024 10:44:57 +0100 Subject: [PATCH 312/470] Rust: Add `getStaticTarget` to `CallExprBase` --- rust/ql/.generated.list | 2 -- rust/ql/.gitattributes | 2 -- .../rust/dataflow/internal/DataFlowImpl.qll | 13 +---------- .../elements/internal/CallExprBaseImpl.qll | 22 +++++++++++++++++-- .../rust/elements/internal/ResolvableImpl.qll | 20 +++++++++++++++-- 5 files changed, 39 insertions(+), 20 deletions(-) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index f556bcb5df3..b0c71e3ef01 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -193,7 +193,6 @@ lib/codeql/rust/elements/internal/BlockExprConstructor.qll 438337c807645e98a0144 lib/codeql/rust/elements/internal/BlockExprImpl.qll 36ac09e4a6eeeec22919b62b1d004bdb5bb2527e67932c308aec383a770768d6 3b4b2a2014f6fe075c63a2d633b297566b548ef2e4343cadf067a9edbcadc876 lib/codeql/rust/elements/internal/BoxPatConstructor.qll 153f110ba25fd6c889092bfd16f73bb610fa60d6e0c8965d5f44d2446fcd48a2 9324cf0d8aa29945551bf8ab64801d598f57aab8cd4e19bcd4e9ef8a4a4e06eb lib/codeql/rust/elements/internal/BreakExprConstructor.qll 356be043c28e0b34fdf925a119c945632ee883c6f5ebb9a27003c6a8d250afd9 bb77e66b04bb9489340e7506931559b94285c6904b6f9d2f83b214cba4f3cfd5 -lib/codeql/rust/elements/internal/CallExprBaseImpl.qll d2749cc1a9d7ee8bf7f34b6c3e0238a576a68e439a8c10a503c164ff45ffcbeb ffc7b0a8841945fe6736b0e1aed7d9ed69185db03dee2b16da121325b39397c7 lib/codeql/rust/elements/internal/CallExprConstructor.qll 742b38e862e2cf82fd1ecc4d4fc5b4782a9c7c07f031452b2bae7aa59d5aa13a cad6e0a8be21d91b20ac2ec16cab9c30eae810b452c0f1992ed87d5c7f4144dc lib/codeql/rust/elements/internal/CallableImpl.qll 917a7d298583e15246428f32fba4cde6fc57a1790262731be27a96baddd8cf5e c5c0848024e0fe3fbb775e7750cf1a2c2dfa454a5aef0df55fec3d0a6fe99190 lib/codeql/rust/elements/internal/CastExprConstructor.qll f3d6e10c4731f38a384675aeab3fba47d17b9e15648293787092bb3247ed808d d738a7751dbadb70aa1dcffcf8af7fa61d4cf8029798369a7e8620013afff4ed @@ -333,7 +332,6 @@ lib/codeql/rust/elements/internal/RefTypeConstructor.qll e1952aa69586b440f878400 lib/codeql/rust/elements/internal/RefTypeImpl.qll f72b760a8a26be21170435da2cb2981638513617fd82742f45f38bc437d9f2c4 f32df49f0b6df85ca5fc4393ccd341ac4304b4947a282ccea48468a26837ef3d lib/codeql/rust/elements/internal/RenameConstructor.qll 65fa2e938978d154701e6cac05b56320b176ee014ef5c20a7b66f3e94fd5c4a7 dfc0ff4606b8e1c14003cc93a0811f4d62ec993b07ff3c1aa0776746577ed103 lib/codeql/rust/elements/internal/RenameImpl.qll 4f5943fbda4ec772203e651ed4b7dd1fb072219ddc0cb208c0a0951af5e72bd6 b9854cdcf02e70ee372330a4e0bfdb03012bc81af79dd12af2a567fd7fc4672b -lib/codeql/rust/elements/internal/ResolvableImpl.qll 7599625454fe81c3490a122943363a2a2522a7877b78a80649e93155a418fedd 442072c3d70bdaababd7de8bc6c9382f4a50bab41d13759dcd1a5bee9ea32e49 lib/codeql/rust/elements/internal/RestPatConstructor.qll 45430925ddf08fba70ede44c7f413ddb41b3113c149b7efc276e0c2bf72507b4 25c678898d72446e7a975bb8b7f2fde51e55b59dbd42f2cca997c833b1a995f1 lib/codeql/rust/elements/internal/RetTypeConstructor.qll a96d803c6e4b40be49cfed0853a3e04ae917c47351e5c880fcab06eddf1af9cc d06a0a191cb14c270c0441ffc3d289263808170dcbe05e01847a35ac9d61dfb3 lib/codeql/rust/elements/internal/RetTypeImpl.qll 0e96f1075ccade28ce5664ab0f5c2e98984ae1d0ed708bc02e40e882672d9e2f 350725d16bcb1e8911bfdd87d9dd21be73ec66d23c2a35827c8c8525c48dc885 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 26c3d123a37..c75ea349c0d 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -195,7 +195,6 @@ /lib/codeql/rust/elements/internal/BlockExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/BoxPatConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/BreakExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/CallExprBaseImpl.qll linguist-generated /lib/codeql/rust/elements/internal/CallExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/CallableImpl.qll linguist-generated /lib/codeql/rust/elements/internal/CastExprConstructor.qll linguist-generated @@ -335,7 +334,6 @@ /lib/codeql/rust/elements/internal/RefTypeImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RenameConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/RenameImpl.qll linguist-generated -/lib/codeql/rust/elements/internal/ResolvableImpl.qll linguist-generated /lib/codeql/rust/elements/internal/RestPatConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/RetTypeConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/RetTypeImpl.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 6fcb878c8ea..4de9842d54f 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -538,20 +538,9 @@ module RustDataFlow implements InputSig { final class ReturnKind = ReturnKindAlias; - pragma[nomagic] - private Resolvable getCallResolvable(CallExprBase call) { - result = call.(MethodCallExpr) - or - result = call.(CallExpr).getFunction().(PathExpr).getPath() - } - /** Gets a viable implementation of the target of the given `Call`. */ DataFlowCallable viableCallable(DataFlowCall call) { - exists(Resolvable r, string path, CrateOriginOption crate | - hasExtendedCanonicalPath(result.asCfgScope(), crate, path) and - r = getCallResolvable(call.asCallBaseExprCfgNode().getExpr()) and - resolveExtendedCanonicalPath(r, crate, path) - ) + result.asCfgScope() = call.asCallBaseExprCfgNode().getCallExprBase().getStaticTarget() } /** diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallExprBaseImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallExprBaseImpl.qll index 332ba0fb6b3..d0e4049a05d 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CallExprBaseImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CallExprBaseImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `CallExprBase`. * @@ -12,8 +11,27 @@ private import codeql.rust.elements.internal.generated.CallExprBase * be referenced directly. */ module Impl { + private import codeql.rust.elements.internal.CallableImpl::Impl + private import codeql.rust.elements.internal.MethodCallExprImpl::Impl + private import codeql.rust.elements.internal.CallExprImpl::Impl + private import codeql.rust.elements.internal.PathExprImpl::Impl + + pragma[nomagic] + private Resolvable getCallResolvable(CallExprBase call) { + result = call.(MethodCallExpr) + or + result = call.(CallExpr).getFunction().(PathExpr).getPath() + } + + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A function or method call expression. See `CallExpr` and `MethodCallExpr` for further details. */ - class CallExprBase extends Generated::CallExprBase { } + class CallExprBase extends Generated::CallExprBase { + /** + * Gets the target callable of this call, if a unique such target can + * be statically resolved. + */ + Callable getStaticTarget() { getCallResolvable(this).resolvesAsItem(result) } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ResolvableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ResolvableImpl.qll index c6f1f2e7a69..fafb86d46c0 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ResolvableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ResolvableImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `Resolvable`. * @@ -12,8 +11,25 @@ private import codeql.rust.elements.internal.generated.Resolvable * be referenced directly. */ module Impl { + private import codeql.rust.elements.internal.ItemImpl::Impl + + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * Either a `Path`, or a `MethodCallExpr`. */ - class Resolvable extends Generated::Resolvable { } + class Resolvable extends Generated::Resolvable { + /** + * Holds if this resolvable and the item `i` resolves to the same canonical + * path in the same crate + */ + pragma[nomagic] + predicate resolvesAsItem(Item i) { + this.getResolvedPath() = i.getExtendedCanonicalPath() and + ( + this.getResolvedCrateOrigin() = i.getCrateOrigin() + or + not this.hasResolvedCrateOrigin() and not i.hasCrateOrigin() + ) + } + } } From 5727fda07a1962cf7b170e14bd917b7f4d215164 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 28 Nov 2024 11:02:35 +0100 Subject: [PATCH 313/470] C#: Exclude `get`-only property accesses from `CallTargetStats` --- csharp/ql/src/Telemetry/DatabaseQuality.qll | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/csharp/ql/src/Telemetry/DatabaseQuality.qll b/csharp/ql/src/Telemetry/DatabaseQuality.qll index 9ef132710ab..b5961767db9 100644 --- a/csharp/ql/src/Telemetry/DatabaseQuality.qll +++ b/csharp/ql/src/Telemetry/DatabaseQuality.qll @@ -32,6 +32,14 @@ module ReportStats { } } +private predicate isNoSetterPropertyCallInConstructor(PropertyCall c) { + exists(Property p | + p = c.getProperty() and + not exists(Setter a | a = p.getAnAccessor()) and + c.getEnclosingCallable().(Constructor).getDeclaringType().getASubType*() = p.getDeclaringType() + ) +} + module CallTargetStats implements StatsSig { int getNumberOfOk() { result = count(Call c | exists(c.getTarget())) } @@ -40,7 +48,8 @@ module CallTargetStats implements StatsSig { count(Call c | not exists(c.getTarget()) and not c instanceof DelegateCall and - not c instanceof DynamicExpr + not c instanceof DynamicExpr and + not isNoSetterPropertyCallInConstructor(c) ) } From 41f21d429ba46b16aa3285f75482e5fbb1228a00 Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 26 Nov 2024 09:18:51 +0100 Subject: [PATCH 314/470] JS: Added test case which is not flagged but should be abusing new RegExp with global flag --- .../Security/CWE-116/IncompleteSanitization/tst.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js index dbd04664a52..1a10415a317 100644 --- a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js @@ -327,4 +327,8 @@ function incompleteComplexSanitizers() { if (str === "\"") return """; }) + '"'; -} \ No newline at end of file +} + +function typicalBadHtmlSanitizers(s) { + s().replace(new RegExp("[<>]", "g"),''); // NOT OK -- should be not okay, but is not flagged +} From 38be0e4c0a0b7368c8d3f43785f48fe257f6b702 Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 26 Nov 2024 09:20:34 +0100 Subject: [PATCH 315/470] JS: Now BadHtmlSanitizers also flags new RegExp as potential issue --- .../javascript/security/IncompleteBlacklistSanitizer.qll | 2 +- .../IncompleteBlacklistSanitizer.expected | 3 +++ .../query-tests/Security/CWE-116/IncompleteSanitization/tst.js | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/IncompleteBlacklistSanitizer.qll b/javascript/ql/lib/semmle/javascript/security/IncompleteBlacklistSanitizer.qll index 6b05e2c754d..5864d8ca7c8 100644 --- a/javascript/ql/lib/semmle/javascript/security/IncompleteBlacklistSanitizer.qll +++ b/javascript/ql/lib/semmle/javascript/security/IncompleteBlacklistSanitizer.qll @@ -74,7 +74,7 @@ private StringReplaceCall getAStringReplaceMethodCall(StringReplaceCall n) { module HtmlSanitization { private predicate fixedGlobalReplacement(StringReplaceCallSequence chain) { forall(StringReplaceCall member | member = chain.getAMember() | - member.isGlobal() and member.getArgument(0) instanceof DataFlow::RegExpLiteralNode + member.isGlobal() and member.getArgument(0) instanceof DataFlow::RegExpCreationNode ) } diff --git a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteBlacklistSanitizer.expected b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteBlacklistSanitizer.expected index 4223a4224d3..00d07f97657 100644 --- a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteBlacklistSanitizer.expected +++ b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteBlacklistSanitizer.expected @@ -65,3 +65,6 @@ | tst.js:305:10:305:34 | s().rep ... ]/g,'') | This HTML sanitizer does not sanitize double quotes | | tst.js:309:10:318:3 | s().rep ... ;";\\n\\t}) | This HTML sanitizer does not sanitize single quotes | | tst.js:320:9:329:3 | s().rep ... ;";\\n\\t}) | This HTML sanitizer does not sanitize single quotes | +| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize ampersands | +| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize double quotes | +| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize single quotes | diff --git a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js index 1a10415a317..af75382662b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js @@ -330,5 +330,5 @@ function incompleteComplexSanitizers() { } function typicalBadHtmlSanitizers(s) { - s().replace(new RegExp("[<>]", "g"),''); // NOT OK -- should be not okay, but is not flagged + s().replace(new RegExp("[<>]", "g"),''); // NOT OK } From 89f3b6f8d34027d6ba35b0ab9816970134896ce0 Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 26 Nov 2024 09:35:27 +0100 Subject: [PATCH 316/470] JS: Added test case for bad sanitizer with unknown flags, currently not flagged. --- .../Security/CWE-116/IncompleteSanitization/tst.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js index af75382662b..d15351e2860 100644 --- a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js @@ -332,3 +332,7 @@ function incompleteComplexSanitizers() { function typicalBadHtmlSanitizers(s) { s().replace(new RegExp("[<>]", "g"),''); // NOT OK } + +function typicalBadHtmlSanitizers(s) { + s().replace(new RegExp("[<>]", unknown()),''); // NOT OK -- should be flagged, because it is st ill a bad sanitizer +} From 18c7b18f82c4fd1fb795e983f032c4fb0feb7f6f Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 26 Nov 2024 09:37:57 +0100 Subject: [PATCH 317/470] JS: Now BadHtmlSanitizers new RegExp with unknown flags is also flagged. --- javascript/ql/lib/semmle/javascript/StandardLibrary.qll | 8 ++++++++ .../javascript/security/IncompleteBlacklistSanitizer.qll | 2 +- .../IncompleteBlacklistSanitizer.expected | 3 +++ .../Security/CWE-116/IncompleteSanitization/tst.js | 2 +- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/StandardLibrary.qll b/javascript/ql/lib/semmle/javascript/StandardLibrary.qll index b40f10d9369..db21d883fc1 100644 --- a/javascript/ql/lib/semmle/javascript/StandardLibrary.qll +++ b/javascript/ql/lib/semmle/javascript/StandardLibrary.qll @@ -117,6 +117,14 @@ class StringReplaceCall extends DataFlow::MethodCallNode { */ predicate isGlobal() { this.getRegExp().isGlobal() or this.getMethodName() = "replaceAll" } + /** + * Holds if this is a global replacement, that is, the first argument is a regular expression + * with the `g` flag, or this is a call to `.replaceAll()`. + */ + predicate maybeGlobal() { + RegExp::maybeGlobal(this.getRegExp().tryGetFlags()) or this.getMethodName() = "replaceAll" + } + /** * Holds if this call to `replace` replaces `old` with `new`. */ diff --git a/javascript/ql/lib/semmle/javascript/security/IncompleteBlacklistSanitizer.qll b/javascript/ql/lib/semmle/javascript/security/IncompleteBlacklistSanitizer.qll index 5864d8ca7c8..13d5033458a 100644 --- a/javascript/ql/lib/semmle/javascript/security/IncompleteBlacklistSanitizer.qll +++ b/javascript/ql/lib/semmle/javascript/security/IncompleteBlacklistSanitizer.qll @@ -74,7 +74,7 @@ private StringReplaceCall getAStringReplaceMethodCall(StringReplaceCall n) { module HtmlSanitization { private predicate fixedGlobalReplacement(StringReplaceCallSequence chain) { forall(StringReplaceCall member | member = chain.getAMember() | - member.isGlobal() and member.getArgument(0) instanceof DataFlow::RegExpCreationNode + member.maybeGlobal() and member.getArgument(0) instanceof DataFlow::RegExpCreationNode ) } diff --git a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteBlacklistSanitizer.expected b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteBlacklistSanitizer.expected index 00d07f97657..379ffbdc9c3 100644 --- a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteBlacklistSanitizer.expected +++ b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteBlacklistSanitizer.expected @@ -68,3 +68,6 @@ | tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize ampersands | | tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize double quotes | | tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize single quotes | +| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize ampersands | +| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize double quotes | +| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize single quotes | diff --git a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js index d15351e2860..f2972f0be76 100644 --- a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/tst.js @@ -334,5 +334,5 @@ function typicalBadHtmlSanitizers(s) { } function typicalBadHtmlSanitizers(s) { - s().replace(new RegExp("[<>]", unknown()),''); // NOT OK -- should be flagged, because it is st ill a bad sanitizer + s().replace(new RegExp("[<>]", unknown()),''); // NOT OK } From 41fef0f2b331ecbc0a1fe043e084cb670475cee9 Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 26 Nov 2024 11:30:20 +0100 Subject: [PATCH 318/470] JS: Added test cases which cover new RegExp creation with replace on protytpe pulluting --- .../PrototypePollutingAssignment.expected | 20 +++++++++++++++++++ .../PrototypePollutingAssignment/tst.js | 7 +++++++ 2 files changed, 27 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected index 891aeff4221..bad75ffe924 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected @@ -190,6 +190,16 @@ nodes | tst.js:105:5:105:17 | object[taint] | | tst.js:105:5:105:17 | object[taint] | | tst.js:105:12:105:16 | taint | +| tst.js:130:5:130:53 | obj[req ... ), '')] | +| tst.js:130:5:130:53 | obj[req ... ), '')] | +| tst.js:130:9:130:19 | req.query.x | +| tst.js:130:9:130:19 | req.query.x | +| tst.js:130:9:130:52 | req.que ... '), '') | +| tst.js:131:5:131:65 | obj[req ... ), '')] | +| tst.js:131:5:131:65 | obj[req ... ), '')] | +| tst.js:131:9:131:19 | req.query.x | +| tst.js:131:9:131:19 | req.query.x | +| tst.js:131:9:131:64 | req.que ... )), '') | edges | lib.js:1:38:1:40 | obj | lib.js:6:7:6:9 | obj | | lib.js:1:38:1:40 | obj | lib.js:6:7:6:9 | obj | @@ -366,6 +376,14 @@ edges | tst.js:102:24:102:37 | req.query.data | tst.js:102:17:102:38 | String( ... y.data) | | tst.js:105:12:105:16 | taint | tst.js:105:5:105:17 | object[taint] | | tst.js:105:12:105:16 | taint | tst.js:105:5:105:17 | object[taint] | +| tst.js:130:9:130:19 | req.query.x | tst.js:130:9:130:52 | req.que ... '), '') | +| tst.js:130:9:130:19 | req.query.x | tst.js:130:9:130:52 | req.que ... '), '') | +| tst.js:130:9:130:52 | req.que ... '), '') | tst.js:130:5:130:53 | obj[req ... ), '')] | +| tst.js:130:9:130:52 | req.que ... '), '') | tst.js:130:5:130:53 | obj[req ... ), '')] | +| tst.js:131:9:131:19 | req.query.x | tst.js:131:9:131:64 | req.que ... )), '') | +| tst.js:131:9:131:19 | req.query.x | tst.js:131:9:131:64 | req.que ... )), '') | +| tst.js:131:9:131:64 | req.que ... )), '') | tst.js:131:5:131:65 | obj[req ... ), '')] | +| tst.js:131:9:131:64 | req.que ... )), '') | tst.js:131:5:131:65 | obj[req ... ), '')] | #select | lib.js:6:7:6:9 | obj | lib.js:1:43:1:46 | path | lib.js:6:7:6:9 | obj | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:1:43:1:46 | path | library input | | lib.js:15:3:15:14 | obj[path[0]] | lib.js:14:38:14:41 | path | lib.js:15:3:15:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:14:38:14:41 | path | library input | @@ -394,3 +412,5 @@ edges | tst.js:94:5:94:37 | obj[req ... ', '')] | tst.js:94:9:94:19 | req.query.x | tst.js:94:5:94:37 | obj[req ... ', '')] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:94:9:94:19 | req.query.x | user controlled input | | tst.js:97:5:97:46 | obj[req ... g, '')] | tst.js:97:9:97:19 | req.query.x | tst.js:97:5:97:46 | obj[req ... g, '')] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:97:9:97:19 | req.query.x | user controlled input | | tst.js:105:5:105:17 | object[taint] | tst.js:102:24:102:37 | req.query.data | tst.js:105:5:105:17 | object[taint] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:102:24:102:37 | req.query.data | user controlled input | +| tst.js:130:5:130:53 | obj[req ... ), '')] | tst.js:130:9:130:19 | req.query.x | tst.js:130:5:130:53 | obj[req ... ), '')] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:130:9:130:19 | req.query.x | user controlled input | +| tst.js:131:5:131:65 | obj[req ... ), '')] | tst.js:131:9:131:19 | req.query.x | tst.js:131:5:131:65 | obj[req ... ), '')] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:131:9:131:19 | req.query.x | user controlled input | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/tst.js b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/tst.js index d301fe40bf6..1cc830d0d2d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/tst.js @@ -123,3 +123,10 @@ app.get('/assign', (req, res) => { Object.assign(dest, plainObj[taint]); dest[taint] = taint; // OK - 'dest' is not Object.prototype itself (but possibly a copy) }); + +app.get('/foo', (req, res) => { + let obj = {}; + obj[req.query.x.replace(new RegExp('_', 'g'), '')].x = 'foo'; // OK + obj[req.query.x.replace(new RegExp('_', ''), '')].x = 'foo'; // NOT OK + obj[req.query.x.replace(new RegExp('_', unknownFlags()), '')].x = 'foo'; // OK -- Might be okay but it is currently flagged as a problem +}); From faef9dd8774358c6bdca232bbbb7220cb0556ae4 Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 26 Nov 2024 11:32:15 +0100 Subject: [PATCH 319/470] JS: protyte poluting now treats unknownFlags as potentially good sanitization. --- .../dataflow/PrototypePollutingAssignmentQuery.qll | 2 +- .../PrototypePollutingAssignment.expected | 10 ---------- .../CWE-915/PrototypePollutingAssignment/tst.js | 2 +- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll index 0ba2f26b24c..197b8594244 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll @@ -46,7 +46,7 @@ class Configuration extends TaintTracking::Configuration { // Replacing with "_" is likely to be exploitable not replace.getRawReplacement().getStringValue() = "_" and ( - replace.isGlobal() + replace.maybeGlobal() or // Non-global replace with a non-empty string can also prevent __proto__ by // inserting a chunk of text that doesn't fit anywhere in __proto__ diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected index bad75ffe924..50262859441 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected @@ -195,11 +195,6 @@ nodes | tst.js:130:9:130:19 | req.query.x | | tst.js:130:9:130:19 | req.query.x | | tst.js:130:9:130:52 | req.que ... '), '') | -| tst.js:131:5:131:65 | obj[req ... ), '')] | -| tst.js:131:5:131:65 | obj[req ... ), '')] | -| tst.js:131:9:131:19 | req.query.x | -| tst.js:131:9:131:19 | req.query.x | -| tst.js:131:9:131:64 | req.que ... )), '') | edges | lib.js:1:38:1:40 | obj | lib.js:6:7:6:9 | obj | | lib.js:1:38:1:40 | obj | lib.js:6:7:6:9 | obj | @@ -380,10 +375,6 @@ edges | tst.js:130:9:130:19 | req.query.x | tst.js:130:9:130:52 | req.que ... '), '') | | tst.js:130:9:130:52 | req.que ... '), '') | tst.js:130:5:130:53 | obj[req ... ), '')] | | tst.js:130:9:130:52 | req.que ... '), '') | tst.js:130:5:130:53 | obj[req ... ), '')] | -| tst.js:131:9:131:19 | req.query.x | tst.js:131:9:131:64 | req.que ... )), '') | -| tst.js:131:9:131:19 | req.query.x | tst.js:131:9:131:64 | req.que ... )), '') | -| tst.js:131:9:131:64 | req.que ... )), '') | tst.js:131:5:131:65 | obj[req ... ), '')] | -| tst.js:131:9:131:64 | req.que ... )), '') | tst.js:131:5:131:65 | obj[req ... ), '')] | #select | lib.js:6:7:6:9 | obj | lib.js:1:43:1:46 | path | lib.js:6:7:6:9 | obj | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:1:43:1:46 | path | library input | | lib.js:15:3:15:14 | obj[path[0]] | lib.js:14:38:14:41 | path | lib.js:15:3:15:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:14:38:14:41 | path | library input | @@ -413,4 +404,3 @@ edges | tst.js:97:5:97:46 | obj[req ... g, '')] | tst.js:97:9:97:19 | req.query.x | tst.js:97:5:97:46 | obj[req ... g, '')] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:97:9:97:19 | req.query.x | user controlled input | | tst.js:105:5:105:17 | object[taint] | tst.js:102:24:102:37 | req.query.data | tst.js:105:5:105:17 | object[taint] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:102:24:102:37 | req.query.data | user controlled input | | tst.js:130:5:130:53 | obj[req ... ), '')] | tst.js:130:9:130:19 | req.query.x | tst.js:130:5:130:53 | obj[req ... ), '')] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:130:9:130:19 | req.query.x | user controlled input | -| tst.js:131:5:131:65 | obj[req ... ), '')] | tst.js:131:9:131:19 | req.query.x | tst.js:131:5:131:65 | obj[req ... ), '')] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:131:9:131:19 | req.query.x | user controlled input | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/tst.js b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/tst.js index 1cc830d0d2d..a622a891390 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/tst.js @@ -128,5 +128,5 @@ app.get('/foo', (req, res) => { let obj = {}; obj[req.query.x.replace(new RegExp('_', 'g'), '')].x = 'foo'; // OK obj[req.query.x.replace(new RegExp('_', ''), '')].x = 'foo'; // NOT OK - obj[req.query.x.replace(new RegExp('_', unknownFlags()), '')].x = 'foo'; // OK -- Might be okay but it is currently flagged as a problem + obj[req.query.x.replace(new RegExp('_', unknownFlags()), '')].x = 'foo'; // OK }); From 7db6f7c7215183cbee297797e246fb54b5b22ee2 Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 26 Nov 2024 12:27:11 +0100 Subject: [PATCH 320/470] JS: Added test cases with new RegExp for Tainted paths, currently works only with literals --- .../dataflow/TaintedPathCustomizations.qll | 6 +- .../CWE-022/TaintedPath/Consistency.expected | 1 + .../CWE-022/TaintedPath/TaintedPath.expected | 313 ++++++++++++++++++ .../CWE-022/TaintedPath/TaintedPath.js | 9 + 4 files changed, 326 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll index c24ea7f6110..e6f1a5203d7 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll @@ -221,10 +221,10 @@ module TaintedPath { this instanceof StringReplaceCall and input = this.getReceiver() and output = this and - not exists(RegExpLiteral literal, RegExpTerm term | - this.(StringReplaceCall).getRegExp().asExpr() = literal and + not exists(DataFlow::RegExpCreationNode regexp, RegExpTerm term | + this.(StringReplaceCall).getRegExp() = regexp and this.(StringReplaceCall).isGlobal() and - literal.getRoot() = term + regexp.getRoot() = term | term.getAMatchedString() = "/" or term.getAMatchedString() = "." or diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected index e69de29bb2d..81656a2af72 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected @@ -0,0 +1 @@ +| TaintedPath.js:207 | did not expect an alert, but found an alert for TaintedPath | OK -- Might be okay depending on what unknownFlags evaluates to. | | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected index 0022ca69c6b..4fdd33dcbba 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected @@ -1517,6 +1517,141 @@ nodes | TaintedPath.js:198:35:198:38 | path | | TaintedPath.js:198:35:198:38 | path | | TaintedPath.js:198:35:198:38 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:24:202:30 | req.url | +| TaintedPath.js:202:24:202:30 | req.url | +| TaintedPath.js:202:24:202:30 | req.url | +| TaintedPath.js:202:24:202:30 | req.url | +| TaintedPath.js:202:24:202:30 | req.url | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | | examples/TaintedPath.js:8:7:8:52 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | @@ -6680,6 +6815,182 @@ edges | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:195:14:195:37 | url.par ... , true) | | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:195:14:195:37 | url.par ... , true) | | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:195:14:195:37 | url.par ... , true) | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | +| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | | examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | @@ -10499,6 +10810,8 @@ edges | TaintedPath.js:196:31:196:34 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:196:31:196:34 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | | TaintedPath.js:197:45:197:48 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:197:45:197:48 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | | TaintedPath.js:198:35:198:38 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:198:35:198:38 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:206:29:206:85 | path.re ... '), '') | This path depends on a $@. | TaintedPath.js:202:24:202:30 | req.url | user-provided value | +| TaintedPath.js:207:29:207:97 | path.re ... )), '') | TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:207:29:207:97 | path.re ... )), '') | This path depends on a $@. | TaintedPath.js:202:24:202:30 | req.url | user-provided value | | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | This path depends on a $@. | examples/TaintedPath.js:8:28:8:34 | req.url | user-provided value | | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | This path depends on a $@. | express.js:8:20:8:32 | req.query.bar | user-provided value | | handlebars.js:11:32:11:39 | filePath | handlebars.js:29:46:29:60 | req.params.path | handlebars.js:11:32:11:39 | filePath | This path depends on a $@. | handlebars.js:29:46:29:60 | req.params.path | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js index d28549da0ec..13948fc431a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js @@ -197,3 +197,12 @@ var server = http.createServer(function(req, res) { cp.execFileSync("foobar", ["args"], {cwd: path}); // NOT OK cp.execFileSync("foobar", {cwd: path}); // NOT OK }); + +var server = http.createServer(function(req, res) { + let path = url.parse(req.url, true).query.path; + + // Removal of forward-slash or dots. + res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", 'g'), ''))); // OK + res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", ''), ''))); // NOT OK. + res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", unknownFlags()), ''))); // OK -- Might be okay depending on what unknownFlags evaluates to. +}); From eca7a8861555695c7330c7d0cd48f9e234e049c7 Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 26 Nov 2024 12:41:59 +0100 Subject: [PATCH 321/470] JS: Fixed docs description --- javascript/ql/lib/semmle/javascript/StandardLibrary.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/StandardLibrary.qll b/javascript/ql/lib/semmle/javascript/StandardLibrary.qll index db21d883fc1..e886ff50eb4 100644 --- a/javascript/ql/lib/semmle/javascript/StandardLibrary.qll +++ b/javascript/ql/lib/semmle/javascript/StandardLibrary.qll @@ -119,7 +119,7 @@ class StringReplaceCall extends DataFlow::MethodCallNode { /** * Holds if this is a global replacement, that is, the first argument is a regular expression - * with the `g` flag, or this is a call to `.replaceAll()`. + * with the `g` flag or unknown flags, or this is a call to `.replaceAll()`. */ predicate maybeGlobal() { RegExp::maybeGlobal(this.getRegExp().tryGetFlags()) or this.getMethodName() = "replaceAll" From 23b18aeca9618acc31ffb996f2deb77268247896 Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 26 Nov 2024 14:20:04 +0100 Subject: [PATCH 322/470] JS: Now unknown flags are not flagged in taint paths --- .../dataflow/TaintedPathCustomizations.qll | 2 +- .../CWE-022/TaintedPath/Consistency.expected | 1 - .../CWE-022/TaintedPath/TaintedPath.expected | 82 ------------------- 3 files changed, 1 insertion(+), 84 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll index e6f1a5203d7..f2dd4a95cf0 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll @@ -223,7 +223,7 @@ module TaintedPath { output = this and not exists(DataFlow::RegExpCreationNode regexp, RegExpTerm term | this.(StringReplaceCall).getRegExp() = regexp and - this.(StringReplaceCall).isGlobal() and + this.(StringReplaceCall).maybeGlobal() and regexp.getRoot() = term | term.getAMatchedString() = "/" or diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected index 81656a2af72..e69de29bb2d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected @@ -1 +0,0 @@ -| TaintedPath.js:207 | did not expect an alert, but found an alert for TaintedPath | OK -- Might be okay depending on what unknownFlags evaluates to. | | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected index 4fdd33dcbba..5fa027c40da 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected @@ -1619,39 +1619,6 @@ nodes | TaintedPath.js:206:29:206:85 | path.re ... '), '') | | TaintedPath.js:206:29:206:85 | path.re ... '), '') | | TaintedPath.js:206:29:206:85 | path.re ... '), '') | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | | examples/TaintedPath.js:8:7:8:52 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | @@ -6831,22 +6798,6 @@ edges | TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | | TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | | TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | -| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:207:29:207:32 | path | | TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | | TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | | TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | @@ -6959,38 +6910,6 @@ edges | TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | | TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | | TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | -| TaintedPath.js:207:29:207:32 | path | TaintedPath.js:207:29:207:97 | path.re ... )), '') | | examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | @@ -10811,7 +10730,6 @@ edges | TaintedPath.js:197:45:197:48 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:197:45:197:48 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | | TaintedPath.js:198:35:198:38 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:198:35:198:38 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | | TaintedPath.js:206:29:206:85 | path.re ... '), '') | TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:206:29:206:85 | path.re ... '), '') | This path depends on a $@. | TaintedPath.js:202:24:202:30 | req.url | user-provided value | -| TaintedPath.js:207:29:207:97 | path.re ... )), '') | TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:207:29:207:97 | path.re ... )), '') | This path depends on a $@. | TaintedPath.js:202:24:202:30 | req.url | user-provided value | | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | This path depends on a $@. | examples/TaintedPath.js:8:28:8:34 | req.url | user-provided value | | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | This path depends on a $@. | express.js:8:20:8:32 | req.query.bar | user-provided value | | handlebars.js:11:32:11:39 | filePath | handlebars.js:29:46:29:60 | req.params.path | handlebars.js:11:32:11:39 | filePath | This path depends on a $@. | handlebars.js:29:46:29:60 | req.params.path | user-provided value | From 155f1fca85d146acb44fe8cb7d0d91d1b53c78f9 Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 26 Nov 2024 15:22:32 +0100 Subject: [PATCH 323/470] JS: Added test cases for unsafe shell command sanitization with RegExpr Object, instead of literal --- .../Security/CWE-078/Consistency.expected | 1 + .../UnsafeShellCommandConstruction.expected | 36 +++++++++++++++++++ .../UnsafeShellCommandConstruction/lib/lib.js | 11 ++++++ 3 files changed, 48 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-078/Consistency.expected b/javascript/ql/test/query-tests/Security/CWE-078/Consistency.expected index e69de29bb2d..5844d8d221d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/Consistency.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/Consistency.expected @@ -0,0 +1 @@ +| UnsafeShellCommandConstruction/lib/lib.js:640 | did not expect an alert, but found an alert for UnsafeShellCommandConstruction | OK -- Currently this is flagged as a bad sanitization, but it is not certain that it is bad. | ComandInjection | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected index b4022c8550c..83c4a471854 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected @@ -319,6 +319,22 @@ nodes | lib/lib.js:626:29:626:32 | name | | lib/lib.js:629:25:629:28 | name | | lib/lib.js:629:25:629:28 | name | +| lib/lib.js:632:38:632:41 | name | +| lib/lib.js:632:38:632:41 | name | +| lib/lib.js:633:6:633:68 | sanitized | +| lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" | +| lib/lib.js:633:24:633:27 | name | +| lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | +| lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | +| lib/lib.js:634:22:634:30 | sanitized | +| lib/lib.js:634:22:634:30 | sanitized | +| lib/lib.js:639:6:639:84 | sanitized | +| lib/lib.js:639:18:639:84 | "'" + n ... ) + "'" | +| lib/lib.js:639:24:639:27 | name | +| lib/lib.js:639:24:639:78 | name.re ... '\\\\''") | +| lib/lib.js:639:24:639:78 | name.re ... '\\\\''") | +| lib/lib.js:640:22:640:30 | sanitized | +| lib/lib.js:640:22:640:30 | sanitized | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | | lib/subLib2/compiled-file.ts:4:25:4:28 | name | @@ -749,6 +765,22 @@ edges | lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | | lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | | lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | +| lib/lib.js:632:38:632:41 | name | lib/lib.js:633:24:633:27 | name | +| lib/lib.js:632:38:632:41 | name | lib/lib.js:633:24:633:27 | name | +| lib/lib.js:632:38:632:41 | name | lib/lib.js:639:24:639:27 | name | +| lib/lib.js:632:38:632:41 | name | lib/lib.js:639:24:639:27 | name | +| lib/lib.js:633:6:633:68 | sanitized | lib/lib.js:634:22:634:30 | sanitized | +| lib/lib.js:633:6:633:68 | sanitized | lib/lib.js:634:22:634:30 | sanitized | +| lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" | lib/lib.js:633:6:633:68 | sanitized | +| lib/lib.js:633:24:633:27 | name | lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | +| lib/lib.js:633:24:633:27 | name | lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | +| lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" | +| lib/lib.js:639:6:639:84 | sanitized | lib/lib.js:640:22:640:30 | sanitized | +| lib/lib.js:639:6:639:84 | sanitized | lib/lib.js:640:22:640:30 | sanitized | +| lib/lib.js:639:18:639:84 | "'" + n ... ) + "'" | lib/lib.js:639:6:639:84 | sanitized | +| lib/lib.js:639:24:639:27 | name | lib/lib.js:639:24:639:78 | name.re ... '\\\\''") | +| lib/lib.js:639:24:639:27 | name | lib/lib.js:639:24:639:78 | name.re ... '\\\\''") | +| lib/lib.js:639:24:639:78 | name.re ... '\\\\''") | lib/lib.js:639:18:639:84 | "'" + n ... ) + "'" | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | @@ -879,6 +911,10 @@ edges | lib/lib.js:609:10:609:25 | "rm -rf " + name | lib/lib.js:608:42:608:45 | name | lib/lib.js:609:22:609:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:608:42:608:45 | name | library input | lib/lib.js:609:2:609:26 | cp.exec ... + name) | shell command | | lib/lib.js:626:17:626:32 | "rm -rf " + name | lib/lib.js:608:42:608:45 | name | lib/lib.js:626:29:626:32 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:608:42:608:45 | name | library input | lib/lib.js:626:9:626:33 | cp.exec ... + name) | shell command | | lib/lib.js:629:13:629:28 | "rm -rf " + name | lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:608:42:608:45 | name | library input | lib/lib.js:629:5:629:29 | cp.exec ... + name) | shell command | +| lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" | lib/lib.js:632:38:632:41 | name | lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:632:38:632:41 | name | library input | lib/lib.js:634:2:634:31 | cp.exec ... itized) | shell command | +| lib/lib.js:634:10:634:30 | "rm -rf ... nitized | lib/lib.js:632:38:632:41 | name | lib/lib.js:634:22:634:30 | sanitized | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:632:38:632:41 | name | library input | lib/lib.js:634:2:634:31 | cp.exec ... itized) | shell command | +| lib/lib.js:639:18:639:84 | "'" + n ... ) + "'" | lib/lib.js:632:38:632:41 | name | lib/lib.js:639:24:639:78 | name.re ... '\\\\''") | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:632:38:632:41 | name | library input | lib/lib.js:640:2:640:31 | cp.exec ... itized) | shell command | +| lib/lib.js:640:10:640:30 | "rm -rf ... nitized | lib/lib.js:632:38:632:41 | name | lib/lib.js:640:22:640:30 | sanitized | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:632:38:632:41 | name | library input | lib/lib.js:640:2:640:31 | cp.exec ... itized) | shell command | | lib/subLib2/compiled-file.ts:4:13:4:28 | "rm -rf " + name | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib2/compiled-file.ts:3:26:3:29 | name | library input | lib/subLib2/compiled-file.ts:4:5:4:29 | cp.exec ... + name) | shell command | | lib/subLib2/special-file.js:4:10:4:25 | "rm -rf " + name | lib/subLib2/special-file.js:3:28:3:31 | name | lib/subLib2/special-file.js:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib2/special-file.js:3:28:3:31 | name | library input | lib/subLib2/special-file.js:4:2:4:26 | cp.exec ... + name) | shell command | | lib/subLib3/my-file.ts:4:10:4:25 | "rm -rf " + name | lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib3/my-file.ts:3:28:3:31 | name | library input | lib/subLib3/my-file.ts:4:2:4:26 | cp.exec ... + name) | shell command | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/lib.js b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/lib.js index 504de998c1c..d3190ceb646 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/lib.js +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/lib.js @@ -628,3 +628,14 @@ module.exports.veryIndeirect = function (name) { cp.exec("rm -rf " + name); // NOT OK } + +module.exports.sanitizer = function (name) { + var sanitized = "'" + name.replace(new RegExp("\'"), "'\\''") + "'" + cp.exec("rm -rf " + sanitized); // NOT OK + + var sanitized = "'" + name.replace(new RegExp("\'", 'g'), "'\\''") + "'" + cp.exec("rm -rf " + sanitized); // OK + + var sanitized = "'" + name.replace(new RegExp("\'", unknownFlags()), "'\\''") + "'" + cp.exec("rm -rf " + sanitized); // OK -- Currently this is flagged as a bad sanitization, but it is not certain that it is bad. +} From a0df33c3ac53b0e2722e661bc2a35e2f6e90b864 Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 26 Nov 2024 15:27:33 +0100 Subject: [PATCH 324/470] JS: UnsafeShellCommand Using unknown flags in the RegExp object is no longer flagged as bad sanitization to reduce false positives. --- ...feShellCommandConstructionCustomizations.qll | 2 +- .../Security/CWE-078/Consistency.expected | 1 - .../UnsafeShellCommandConstruction.expected | 17 ----------------- .../UnsafeShellCommandConstruction/lib/lib.js | 2 +- 4 files changed, 2 insertions(+), 20 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll index 77625874df9..8e753a5ef63 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll @@ -245,7 +245,7 @@ module UnsafeShellCommandConstruction { class ReplaceQuotesSanitizer extends Sanitizer, StringReplaceCall { ReplaceQuotesSanitizer() { this.getAReplacedString() = "'" and - this.isGlobal() and + this.maybeGlobal() and this.getRawReplacement().mayHaveStringValue(["'\\''", ""]) } } diff --git a/javascript/ql/test/query-tests/Security/CWE-078/Consistency.expected b/javascript/ql/test/query-tests/Security/CWE-078/Consistency.expected index 5844d8d221d..e69de29bb2d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/Consistency.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/Consistency.expected @@ -1 +0,0 @@ -| UnsafeShellCommandConstruction/lib/lib.js:640 | did not expect an alert, but found an alert for UnsafeShellCommandConstruction | OK -- Currently this is flagged as a bad sanitization, but it is not certain that it is bad. | ComandInjection | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected index 83c4a471854..f2fa354a305 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected @@ -328,13 +328,6 @@ nodes | lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | | lib/lib.js:634:22:634:30 | sanitized | | lib/lib.js:634:22:634:30 | sanitized | -| lib/lib.js:639:6:639:84 | sanitized | -| lib/lib.js:639:18:639:84 | "'" + n ... ) + "'" | -| lib/lib.js:639:24:639:27 | name | -| lib/lib.js:639:24:639:78 | name.re ... '\\\\''") | -| lib/lib.js:639:24:639:78 | name.re ... '\\\\''") | -| lib/lib.js:640:22:640:30 | sanitized | -| lib/lib.js:640:22:640:30 | sanitized | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | | lib/subLib2/compiled-file.ts:4:25:4:28 | name | @@ -767,20 +760,12 @@ edges | lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | | lib/lib.js:632:38:632:41 | name | lib/lib.js:633:24:633:27 | name | | lib/lib.js:632:38:632:41 | name | lib/lib.js:633:24:633:27 | name | -| lib/lib.js:632:38:632:41 | name | lib/lib.js:639:24:639:27 | name | -| lib/lib.js:632:38:632:41 | name | lib/lib.js:639:24:639:27 | name | | lib/lib.js:633:6:633:68 | sanitized | lib/lib.js:634:22:634:30 | sanitized | | lib/lib.js:633:6:633:68 | sanitized | lib/lib.js:634:22:634:30 | sanitized | | lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" | lib/lib.js:633:6:633:68 | sanitized | | lib/lib.js:633:24:633:27 | name | lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | | lib/lib.js:633:24:633:27 | name | lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | | lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" | -| lib/lib.js:639:6:639:84 | sanitized | lib/lib.js:640:22:640:30 | sanitized | -| lib/lib.js:639:6:639:84 | sanitized | lib/lib.js:640:22:640:30 | sanitized | -| lib/lib.js:639:18:639:84 | "'" + n ... ) + "'" | lib/lib.js:639:6:639:84 | sanitized | -| lib/lib.js:639:24:639:27 | name | lib/lib.js:639:24:639:78 | name.re ... '\\\\''") | -| lib/lib.js:639:24:639:27 | name | lib/lib.js:639:24:639:78 | name.re ... '\\\\''") | -| lib/lib.js:639:24:639:78 | name.re ... '\\\\''") | lib/lib.js:639:18:639:84 | "'" + n ... ) + "'" | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | @@ -913,8 +898,6 @@ edges | lib/lib.js:629:13:629:28 | "rm -rf " + name | lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:608:42:608:45 | name | library input | lib/lib.js:629:5:629:29 | cp.exec ... + name) | shell command | | lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" | lib/lib.js:632:38:632:41 | name | lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:632:38:632:41 | name | library input | lib/lib.js:634:2:634:31 | cp.exec ... itized) | shell command | | lib/lib.js:634:10:634:30 | "rm -rf ... nitized | lib/lib.js:632:38:632:41 | name | lib/lib.js:634:22:634:30 | sanitized | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:632:38:632:41 | name | library input | lib/lib.js:634:2:634:31 | cp.exec ... itized) | shell command | -| lib/lib.js:639:18:639:84 | "'" + n ... ) + "'" | lib/lib.js:632:38:632:41 | name | lib/lib.js:639:24:639:78 | name.re ... '\\\\''") | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:632:38:632:41 | name | library input | lib/lib.js:640:2:640:31 | cp.exec ... itized) | shell command | -| lib/lib.js:640:10:640:30 | "rm -rf ... nitized | lib/lib.js:632:38:632:41 | name | lib/lib.js:640:22:640:30 | sanitized | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:632:38:632:41 | name | library input | lib/lib.js:640:2:640:31 | cp.exec ... itized) | shell command | | lib/subLib2/compiled-file.ts:4:13:4:28 | "rm -rf " + name | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib2/compiled-file.ts:3:26:3:29 | name | library input | lib/subLib2/compiled-file.ts:4:5:4:29 | cp.exec ... + name) | shell command | | lib/subLib2/special-file.js:4:10:4:25 | "rm -rf " + name | lib/subLib2/special-file.js:3:28:3:31 | name | lib/subLib2/special-file.js:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib2/special-file.js:3:28:3:31 | name | library input | lib/subLib2/special-file.js:4:2:4:26 | cp.exec ... + name) | shell command | | lib/subLib3/my-file.ts:4:10:4:25 | "rm -rf " + name | lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib3/my-file.ts:3:28:3:31 | name | library input | lib/subLib3/my-file.ts:4:2:4:26 | cp.exec ... + name) | shell command | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/lib.js b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/lib.js index d3190ceb646..09488f0a887 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/lib.js +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/lib.js @@ -637,5 +637,5 @@ module.exports.sanitizer = function (name) { cp.exec("rm -rf " + sanitized); // OK var sanitized = "'" + name.replace(new RegExp("\'", unknownFlags()), "'\\''") + "'" - cp.exec("rm -rf " + sanitized); // OK -- Currently this is flagged as a bad sanitization, but it is not certain that it is bad. + cp.exec("rm -rf " + sanitized); // OK -- Most likely should be okay and not flagged to reduce false positives. } From aa557cf950fa1204208b7673d2069e19fb859e72 Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 27 Nov 2024 08:29:02 +0100 Subject: [PATCH 325/470] JS: Added tests for DotRemovingReplaceCall with RegExp Object. --- .../CWE-022/TaintedPath/Consistency.expected | 1 + .../CWE-022/TaintedPath/TaintedPath.expected | 119 ++++++++++++++++++ .../CWE-022/TaintedPath/TaintedPath.js | 13 ++ 3 files changed, 133 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected index e69de29bb2d..8396f55ff16 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected @@ -0,0 +1 @@ +| TaintedPath.js:213 | expected an alert, but found none | NOT OK (can be absolute) | | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected index 5fa027c40da..c196425a5ca 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected @@ -1619,6 +1619,60 @@ nodes | TaintedPath.js:206:29:206:85 | path.re ... '), '') | | TaintedPath.js:206:29:206:85 | path.re ... '), '') | | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:24:211:30 | req.url | +| TaintedPath.js:211:24:211:30 | req.url | +| TaintedPath.js:211:24:211:30 | req.url | +| TaintedPath.js:211:24:211:30 | req.url | +| TaintedPath.js:211:24:211:30 | req.url | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | | examples/TaintedPath.js:8:7:8:52 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | @@ -6910,6 +6964,70 @@ edges | TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | | TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | | TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | | examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | @@ -10730,6 +10848,7 @@ edges | TaintedPath.js:197:45:197:48 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:197:45:197:48 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | | TaintedPath.js:198:35:198:38 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:198:35:198:38 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | | TaintedPath.js:206:29:206:85 | path.re ... '), '') | TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:206:29:206:85 | path.re ... '), '') | This path depends on a $@. | TaintedPath.js:202:24:202:30 | req.url | user-provided value | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:216:31:216:69 | path.re ... '), '') | This path depends on a $@. | TaintedPath.js:211:24:211:30 | req.url | user-provided value | | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | This path depends on a $@. | examples/TaintedPath.js:8:28:8:34 | req.url | user-provided value | | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | This path depends on a $@. | express.js:8:20:8:32 | req.query.bar | user-provided value | | handlebars.js:11:32:11:39 | filePath | handlebars.js:29:46:29:60 | req.params.path | handlebars.js:11:32:11:39 | filePath | This path depends on a $@. | handlebars.js:29:46:29:60 | req.params.path | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js index 13948fc431a..924aec029e9 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js @@ -206,3 +206,16 @@ var server = http.createServer(function(req, res) { res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", ''), ''))); // NOT OK. res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", unknownFlags()), ''))); // OK -- Might be okay depending on what unknownFlags evaluates to. }); + +var server = http.createServer(function(req, res) { + let path = url.parse(req.url, true).query.path; + + res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // NOT OK (can be absolute) -- Currently not flagged because it is not a literal + + if (!pathModule.isAbsolute(path)) { + res.write(fs.readFileSync(path.replace(new RegExp("[.]", ''), ''))); // NOT OK + res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // OK + res.write(fs.readFileSync(path.replace(new RegExp("[.]", unknownFlags()), ''))); // OK + } +}); + From 875478c1c6c9a01587f35f2777648d8bef55baf4 Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 27 Nov 2024 08:55:21 +0100 Subject: [PATCH 326/470] JS: Fixed path query not flagging new RegExp with DotRemovingReplaceCall --- .../dataflow/TaintedPathCustomizations.qll | 6 +- .../CWE-022/TaintedPath/Consistency.expected | 1 - .../CWE-022/TaintedPath/TaintedPath.expected | 110 ++++++++++++++++++ .../CWE-022/TaintedPath/TaintedPath.js | 2 +- 4 files changed, 114 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll index f2dd4a95cf0..8798c926086 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll @@ -305,9 +305,9 @@ module TaintedPath { input = this.getReceiver() and output = this and this.isGlobal() and - exists(RegExpLiteral literal, RegExpTerm term | - this.getRegExp().asExpr() = literal and - literal.getRoot() = term and + exists(DataFlow::RegExpCreationNode regexp, RegExpTerm term | + this.getRegExp() = regexp and + regexp.getRoot() = term and not term.getAMatchedString() = "/" | term.getAMatchedString() = "." or diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected index 8396f55ff16..e69de29bb2d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.expected @@ -1 +0,0 @@ -| TaintedPath.js:213 | expected an alert, but found none | NOT OK (can be absolute) | | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected index c196425a5ca..6a45147a4e2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected @@ -1627,6 +1627,22 @@ nodes | TaintedPath.js:211:7:211:48 | path | | TaintedPath.js:211:7:211:48 | path | | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | | TaintedPath.js:211:14:211:37 | url.par ... , true) | | TaintedPath.js:211:14:211:37 | url.par ... , true) | | TaintedPath.js:211:14:211:37 | url.par ... , true) | @@ -1643,6 +1659,22 @@ nodes | TaintedPath.js:211:14:211:43 | url.par ... ).query | | TaintedPath.js:211:14:211:43 | url.par ... ).query | | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | | TaintedPath.js:211:14:211:48 | url.par ... ry.path | | TaintedPath.js:211:14:211:48 | url.par ... ry.path | | TaintedPath.js:211:14:211:48 | url.par ... ry.path | @@ -1656,6 +1688,19 @@ nodes | TaintedPath.js:211:24:211:30 | req.url | | TaintedPath.js:211:24:211:30 | req.url | | TaintedPath.js:211:24:211:30 | req.url | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:68 | path.re ... '), '') | | TaintedPath.js:216:31:216:34 | path | | TaintedPath.js:216:31:216:34 | path | | TaintedPath.js:216:31:216:34 | path | @@ -6964,6 +7009,14 @@ edges | TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | | TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | | TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | | TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | | TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | | TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | @@ -6980,6 +7033,14 @@ edges | TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | | TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | | TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | | TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | | TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | | TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | @@ -6988,6 +7049,22 @@ edges | TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | | TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | | TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | | TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | | TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | | TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | @@ -7012,6 +7089,38 @@ edges | TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | | TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | | TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | | TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | | TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | | TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | @@ -10848,6 +10957,7 @@ edges | TaintedPath.js:197:45:197:48 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:197:45:197:48 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | | TaintedPath.js:198:35:198:38 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:198:35:198:38 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | | TaintedPath.js:206:29:206:85 | path.re ... '), '') | TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:206:29:206:85 | path.re ... '), '') | This path depends on a $@. | TaintedPath.js:202:24:202:30 | req.url | user-provided value | +| TaintedPath.js:213:29:213:68 | path.re ... '), '') | TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:213:29:213:68 | path.re ... '), '') | This path depends on a $@. | TaintedPath.js:211:24:211:30 | req.url | user-provided value | | TaintedPath.js:216:31:216:69 | path.re ... '), '') | TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:216:31:216:69 | path.re ... '), '') | This path depends on a $@. | TaintedPath.js:211:24:211:30 | req.url | user-provided value | | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | This path depends on a $@. | examples/TaintedPath.js:8:28:8:34 | req.url | user-provided value | | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | This path depends on a $@. | express.js:8:20:8:32 | req.query.bar | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js index 924aec029e9..fd768fecfff 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js @@ -210,7 +210,7 @@ var server = http.createServer(function(req, res) { var server = http.createServer(function(req, res) { let path = url.parse(req.url, true).query.path; - res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // NOT OK (can be absolute) -- Currently not flagged because it is not a literal + res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // NOT OK (can be absolute) if (!pathModule.isAbsolute(path)) { res.write(fs.readFileSync(path.replace(new RegExp("[.]", ''), ''))); // NOT OK From 9c2366a660654de149b26ec03a3b1cd5cd474abe Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 27 Nov 2024 09:42:43 +0100 Subject: [PATCH 327/470] JS: Added tests for ReDos with unknownFlags, everything seems to be good --- .../CWE-400/ReDoS/PolynomialBackTracking.expected | 3 +++ .../CWE-400/ReDoS/PolynomialReDoS.expected | 15 +++++++++++++++ .../Security/CWE-400/ReDoS/polynomial-redos.js | 4 ++++ 3 files changed, 22 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected index 9a03bdcd34e..106b143111f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected @@ -130,6 +130,9 @@ | polynomial-redos.js:133:22:133:23 | f+ | Strings starting with 'f' and with many repetitions of 'f' can start matching anywhere after the start of the preceeding ff+G | | polynomial-redos.js:136:25:136:26 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I | | polynomial-redos.js:138:322:138:323 | .* | Strings starting with 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' can start matching anywhere after the start of the preceeding (AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)C.*X | +| polynomial-redos.js:140:33:140:34 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I | +| polynomial-redos.js:141:33:141:34 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I | +| polynomial-redos.js:142:33:142:34 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I | | regexplib/address.js:27:3:27:5 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{4}\\)?(\\s*\|-)\\d{3}(\\s*\|-)\\d{3}\\s*) | | regexplib/address.js:27:48:27:50 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{3}\\)?(\\s*\|-)\\d{3}(\\s*\|-)\\d{4}\\s*) | | regexplib/address.js:27:93:27:95 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*(7\|8)(\\d{7}\|\\d{3}(\\-\|\\s{1})\\d{4})\\s*) | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected index 4c534fffe13..f9504944160 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected @@ -249,6 +249,12 @@ nodes | polynomial-redos.js:136:5:136:13 | modified3 | | polynomial-redos.js:138:5:138:11 | tainted | | polynomial-redos.js:138:5:138:11 | tainted | +| polynomial-redos.js:140:2:140:10 | modified3 | +| polynomial-redos.js:140:2:140:10 | modified3 | +| polynomial-redos.js:141:2:141:10 | modified3 | +| polynomial-redos.js:141:2:141:10 | modified3 | +| polynomial-redos.js:142:2:142:10 | modified3 | +| polynomial-redos.js:142:2:142:10 | modified3 | edges | lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x | | lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x | @@ -489,6 +495,12 @@ edges | polynomial-redos.js:132:18:132:50 | tainted ... g, "e") | polynomial-redos.js:132:6:132:50 | modified2 | | polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:136:5:136:13 | modified3 | | polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:136:5:136:13 | modified3 | +| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:140:2:140:10 | modified3 | +| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:140:2:140:10 | modified3 | +| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:141:2:141:10 | modified3 | +| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:141:2:141:10 | modified3 | +| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:142:2:142:10 | modified3 | +| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:142:2:142:10 | modified3 | | polynomial-redos.js:135:21:135:27 | tainted | polynomial-redos.js:135:21:135:47 | tainted ... /g, "") | | polynomial-redos.js:135:21:135:47 | tainted ... /g, "") | polynomial-redos.js:135:9:135:47 | modified3 | #select @@ -590,3 +602,6 @@ edges | polynomial-redos.js:133:2:133:32 | modifie ... g, "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:133:2:133:10 | modified2 | This $@ that depends on $@ may run slow on strings starting with 'f' and with many repetitions of 'f'. | polynomial-redos.js:133:22:133:23 | f+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:136:5:136:35 | modifie ... g, "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:136:5:136:13 | modified3 | This $@ that depends on $@ may run slow on strings starting with 'h' and with many repetitions of 'h'. | polynomial-redos.js:136:25:136:26 | h+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:138:5:138:326 | tainted ... )C.*X/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:138:5:138:11 | tainted | This $@ that depends on $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | polynomial-redos.js:138:322:138:323 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:140:2:140:48 | modifie ... ), "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:140:2:140:10 | modified3 | This $@ that depends on $@ may run slow on strings starting with 'h' and with many repetitions of 'h'. | polynomial-redos.js:140:33:140:34 | h+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:141:2:141:59 | modifie ... ), "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:141:2:141:10 | modified3 | This $@ that depends on $@ may run slow on strings starting with 'h' and with many repetitions of 'h'. | polynomial-redos.js:141:33:141:34 | h+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:142:2:142:47 | modifie ... ), "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:142:2:142:10 | modified3 | This $@ that depends on $@ may run slow on strings starting with 'h' and with many repetitions of 'h'. | polynomial-redos.js:142:33:142:34 | h+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/polynomial-redos.js b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/polynomial-redos.js index fc0ddde66b2..860472428ff 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/polynomial-redos.js +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/polynomial-redos.js @@ -136,4 +136,8 @@ app.use(function(req, res) { modified3.replace(/hh+I/g, "b"); // NOT OK tainted.match(/(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)C.*X/); // NOT OK + + modified3.replace(new RegExp("hh+I", "g"), "b"); // NOT OK + modified3.replace(new RegExp("hh+I", unknownFlags()), "b"); // NOT OK + modified3.replace(new RegExp("hh+I", ""), "b"); // NOT OK }); From 76318035ffd61035f5a448f2d73aae5985645ca4 Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 27 Nov 2024 10:53:43 +0100 Subject: [PATCH 328/470] JS: Add test cases for RegExp object usage in replace within incomplete sanitization --- ...ompleteMultiCharacterSanitization.expected | 1 + .../CWE-116/IncompleteSanitization/tst.js | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteMultiCharacterSanitization.expected b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteMultiCharacterSanitization.expected index 32400608814..96a48fec6cb 100644 --- a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteMultiCharacterSanitization.expected +++ b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteMultiCharacterSanitization.expected @@ -39,3 +39,4 @@ | tst-multi-character-sanitization.js:145:13:145:90 | content ... /g, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:145:30:145:30 | < |