From df406b4fca88a73d345fc8d34ce7b59b3d5876dd Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Fri, 2 Feb 2024 10:14:17 +0100 Subject: [PATCH 001/347] python: Start modelling using MaD - empty models for now - `summaryModel` of `codeql/python-all` will be added to shortly. --- python/ql/lib/ext/StdLib.model.yml | 30 ++++++++++++++++++++++++++++++ python/ql/lib/qlpack.yml | 2 ++ 2 files changed, 32 insertions(+) create mode 100644 python/ql/lib/ext/StdLib.model.yml diff --git a/python/ql/lib/ext/StdLib.model.yml b/python/ql/lib/ext/StdLib.model.yml new file mode 100644 index 000000000000..6c1f0ec89908 --- /dev/null +++ b/python/ql/lib/ext/StdLib.model.yml @@ -0,0 +1,30 @@ +extensions: + - addsTo: + pack: codeql/python-all + extensible: sourceModel + data: [] + + - addsTo: + pack: codeql/python-all + extensible: sinkModel + data: [] + + - addsTo: + pack: codeql/python-all + extensible: summaryModel + data: [] + + - addsTo: + pack: codeql/python-all + extensible: neutralModel + data: [] + + - addsTo: + pack: codeql/python-all + extensible: typeModel + data: [] + + - addsTo: + pack: codeql/python-all + extensible: typeVariableModel + data: [] diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 36d43473f2a6..765cdb11c2e1 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -15,4 +15,6 @@ dependencies: codeql/yaml: ${workspace} dataExtensions: - semmle/python/frameworks/**/*.model.yml + - ext/*.model.yml + - ext/generated/*.model.yml warnOnImplicitThis: true From 281ac05868d722e514ead85373da9de4c27168be Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Fri, 8 Mar 2024 11:12:33 +0100 Subject: [PATCH 002/347] python: add modelling for `urlib.parse` - `quote` together with `re.compile` recover regex injection alerts on haiwen/seahub - `quote_plus` recovers the URL redirection alert on DemocracyClub/EveryElection - `unquote` recovers path injection alerts on `cloudera/hue` - it was tedious finding justifications for the rest.. --- python/ql/lib/ext/StdLib.model.yml | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/ext/StdLib.model.yml b/python/ql/lib/ext/StdLib.model.yml index 6c1f0ec89908..16f62bd77481 100644 --- a/python/ql/lib/ext/StdLib.model.yml +++ b/python/ql/lib/ext/StdLib.model.yml @@ -12,8 +12,26 @@ extensions: - addsTo: pack: codeql/python-all extensible: summaryModel - data: [] - + data: + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote + - ["urllib", "Member[parse].Member[quote]", "Argument[0,string:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote_plus + - ["urllib", "Member[parse].Member[quote_plus]", "Argument[0,string:]", "ReturnValue", "taint"] + # See https://epydoc.sourceforge.net/stdlib/urllib-module.html + - ["urllib", "Member[parse].Member[splitquery]", "Argument[0,url:]", "ReturnValue.TupleElement[0]", "taint"] + - ["urllib", "Member[parse].Member[splitquery]", "Argument[0,url:]", "ReturnValue.TupleElement[1]", "taint"] + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.unquote + - ["urllib", "Member[parse].Member[unquote]", "Argument[0,string:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.unquote_plus + - ["urllib", "Member[parse].Member[unquote_plus]", "Argument[0,string:]", "ReturnValue", "taint"] + # We could consider a more precise source than the first argument, namely tuple or dict content. + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode + - ["urllib", "Member[parse].Member[urlencode]", "Argument[0,query:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urljoin + - ["urllib", "Member[parse].Member[urljoin]", "Argument[0,base:]", "ReturnValue", "taint"] + - ["urllib", "Member[parse].Member[urljoin]", "Argument[1,url:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/re.html#re.compile + - ["re", "Member[compile]", "Argument[0,pattern:]", "ReturnValue", "taint"] - addsTo: pack: codeql/python-all extensible: neutralModel From c004ffaca8e721834f4f10ef0deb7bf6f18ff421 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 14 Mar 2024 09:22:08 +0100 Subject: [PATCH 003/347] python: move model to `Stdlib.yml` There is already a model there so we add to that one. We did observe that this existing model was blocked by the external MaD model. This is concerning and needs to be cleared up. --- python/ql/lib/ext/StdLib.model.yml | 2 -- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 9 +++++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/python/ql/lib/ext/StdLib.model.yml b/python/ql/lib/ext/StdLib.model.yml index 16f62bd77481..df4feaf04249 100644 --- a/python/ql/lib/ext/StdLib.model.yml +++ b/python/ql/lib/ext/StdLib.model.yml @@ -30,8 +30,6 @@ extensions: # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urljoin - ["urllib", "Member[parse].Member[urljoin]", "Argument[0,base:]", "ReturnValue", "taint"] - ["urllib", "Member[parse].Member[urljoin]", "Argument[1,url:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/re.html#re.compile - - ["re", "Member[compile]", "Argument[0,pattern:]", "ReturnValue", "taint"] - addsTo: pack: codeql/python-all extensible: neutralModel diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 3c23b3929911..7a373a523e47 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -3251,8 +3251,13 @@ module StdlibPrivate { override predicate propagatesFlow(string input, string output, boolean preservesValue) { input in ["Argument[0]", "Argument[pattern:]"] and - output = "ReturnValue.Attribute[pattern]" and - preservesValue = true + ( + output = "ReturnValue.Attribute[pattern]" and + preservesValue = true + or + output = "ReturnValue" and + preservesValue = false + ) } } From d410136852410110010987d5d6476ff8f7562324 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 9 Apr 2024 13:14:42 +0200 Subject: [PATCH 004/347] python: compress models --- python/ql/lib/ext/StdLib.model.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/python/ql/lib/ext/StdLib.model.yml b/python/ql/lib/ext/StdLib.model.yml index df4feaf04249..e3cc9cd61c87 100644 --- a/python/ql/lib/ext/StdLib.model.yml +++ b/python/ql/lib/ext/StdLib.model.yml @@ -18,8 +18,7 @@ extensions: # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote_plus - ["urllib", "Member[parse].Member[quote_plus]", "Argument[0,string:]", "ReturnValue", "taint"] # See https://epydoc.sourceforge.net/stdlib/urllib-module.html - - ["urllib", "Member[parse].Member[splitquery]", "Argument[0,url:]", "ReturnValue.TupleElement[0]", "taint"] - - ["urllib", "Member[parse].Member[splitquery]", "Argument[0,url:]", "ReturnValue.TupleElement[1]", "taint"] + - ["urllib", "Member[parse].Member[splitquery]", "Argument[0,url:]", "ReturnValue.TupleElement[0,1]", "taint"] # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.unquote - ["urllib", "Member[parse].Member[unquote]", "Argument[0,string:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.unquote_plus @@ -28,8 +27,7 @@ extensions: # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode - ["urllib", "Member[parse].Member[urlencode]", "Argument[0,query:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urljoin - - ["urllib", "Member[parse].Member[urljoin]", "Argument[0,base:]", "ReturnValue", "taint"] - - ["urllib", "Member[parse].Member[urljoin]", "Argument[1,url:]", "ReturnValue", "taint"] + - ["urllib", "Member[parse].Member[urljoin]", "Argument[0,base:,1,url:]", "ReturnValue", "taint"] - addsTo: pack: codeql/python-all extensible: neutralModel From 1e97600c4aa9abf1ea7562b6367b06d9efb9334b Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 9 Apr 2024 13:31:26 +0200 Subject: [PATCH 005/347] Python: move models --- .../lib/{ext => semmle/python/frameworks/Stdlib}/StdLib.model.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/lib/{ext => semmle/python/frameworks/Stdlib}/StdLib.model.yml (100%) diff --git a/python/ql/lib/ext/StdLib.model.yml b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml similarity index 100% rename from python/ql/lib/ext/StdLib.model.yml rename to python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml From b80a711b27033581261bd2af8c3bc8e56a889ff2 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 9 Apr 2024 13:33:05 +0200 Subject: [PATCH 006/347] python: undo changes to qlpack --- python/ql/lib/qlpack.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 765cdb11c2e1..36d43473f2a6 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -15,6 +15,4 @@ dependencies: codeql/yaml: ${workspace} dataExtensions: - semmle/python/frameworks/**/*.model.yml - - ext/*.model.yml - - ext/generated/*.model.yml warnOnImplicitThis: true From 2118f233b9d020a32126535282277644ac13d6e3 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 25 Jun 2024 14:40:23 +0200 Subject: [PATCH 007/347] Python: model optparse.OptionParser.parse_arg --- python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml index e3cc9cd61c87..1b359ce05ea4 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml +++ b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml @@ -13,6 +13,8 @@ extensions: pack: codeql/python-all extensible: summaryModel data: + # See https://docs.python.org/3/library/optparse.html#optparse.OptionParser.parse_args + - ["optparse.OptionParser", "Member[parse_args]", "Argument[0,args:,1,values:]", "ReturnValue.TupleElement[0,1]", "taint"] # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote - ["urllib", "Member[parse].Member[quote]", "Argument[0,string:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote_plus From 501cda4e8c1f5d4568740b31fe437ea21eea38e8 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 25 Jun 2024 14:44:39 +0200 Subject: [PATCH 008/347] Python: model `fnmatch.filter` --- python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml index 1b359ce05ea4..c2d8546b9dfb 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml +++ b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml @@ -13,6 +13,9 @@ extensions: pack: codeql/python-all extensible: summaryModel data: + # See See https://docs.python.org/3/library/fnmatch.html#fnmatch.filter + - ["fnmatch", "Member[filter]", "Argument[0,names:].ListElement", "ReturnValue.ListElement", "value"] + - ["fnmatch", "Member[filter]", "Argument[0,names:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/optparse.html#optparse.OptionParser.parse_args - ["optparse.OptionParser", "Member[parse_args]", "Argument[0,args:,1,values:]", "ReturnValue.TupleElement[0,1]", "taint"] # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote From bc551174f95b687acb78970ac855b56f5c5a6b7f Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 25 Jun 2024 14:53:06 +0200 Subject: [PATCH 009/347] Python: model `copy.deepcopy` as a value step --- .../dataflow/new/internal/TaintTrackingPrivate.qll | 14 -------------- .../python/frameworks/Stdlib/StdLib.model.yml | 2 ++ 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index 572e67c28a9c..b268d6290603 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -46,8 +46,6 @@ private module Cached { or containerStep(nodeFrom, nodeTo) or - copyStep(nodeFrom, nodeTo) - or DataFlowPrivate::forReadStep(nodeFrom, _, nodeTo) or DataFlowPrivate::iterableUnpackingReadStep(nodeFrom, _, nodeTo) @@ -191,18 +189,6 @@ predicate containerStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { DataFlowPrivate::comprehensionStoreStep(nodeFrom, _, nodeTo) } -/** - * Holds if taint can flow from `nodeFrom` to `nodeTo` with a step related to copying. - */ -predicate copyStep(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeTo) { - exists(DataFlow::CallCfgNode call | call = nodeTo | - call = API::moduleImport("copy").getMember(["copy", "deepcopy"]).getACall() and - call.getArg(0) = nodeFrom - ) - or - nodeTo.(DataFlow::MethodCallNode).calls(nodeFrom, "copy") -} - /** * Holds if taint can flow from `nodeFrom` to `nodeTo` with an `await`-step, * such that the whole expression `await x` is tainted if `x` is tainted. diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml index c2d8546b9dfb..3a320407d9c4 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml +++ b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml @@ -13,6 +13,8 @@ extensions: pack: codeql/python-all extensible: summaryModel data: + # See https://docs.python.org/3/library/copy.html#copy.deepcopy + - ["copy", "Member[copy,deepcopy]", "Argument[0,x:]", "ReturnValue", "value"] # See See https://docs.python.org/3/library/fnmatch.html#fnmatch.filter - ["fnmatch", "Member[filter]", "Argument[0,names:].ListElement", "ReturnValue.ListElement", "value"] - ["fnmatch", "Member[filter]", "Argument[0,names:]", "ReturnValue", "taint"] From bdc48088e6dcc0ded83f81c0fdc9d6b04a3a7da8 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 25 Jun 2024 15:21:29 +0200 Subject: [PATCH 010/347] Python: MaD summary models Two of the generated summaries have been excluded: - ["re", "Member[split]", "Argument[0,pattern:]", "ReturnValue", "taint"] From the documentation, it is not clear why pattern should figure in the return value, as that is the part denoting split point and thus all those instances are filtered out. From the implementation Spit function: https://github.com/python/cpython/blob/3.12/Lib/re/__init__.py#L199 _compile function being called by split: https://github.com/python/cpython/blob/3.12/Lib/re/__init__.py#L280 We see that in case the pattern is already a compiled `Pattern`, it is returned directly from _compile and could thus be part of the return value from split. This is probably not possible to arrange for an attacker, and so an FP in practice. - ["urllib2", "Member[unquote]", "Argument[0,string:]", "ReturnValue", "taint"] urllib2 seems to be only in Python2 (e.g. https://docs.python.org/2.7/library/urllib2.html) and I cannot locate the function unquote. --- .../python/frameworks/Stdlib/StdLib.model.yml | 105 +++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml index 3a320407d9c4..1d7e0c070fe4 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml +++ b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml @@ -7,19 +7,107 @@ extensions: - addsTo: pack: codeql/python-all extensible: sinkModel - data: [] + data: + - ["subprocess.Popen!","Subclass.Call.Argument[0,args:]", "log-injection"] + - ["zipfile.ZipFile","Member[extractall].Argument[0,path:]", "path-injection"] - addsTo: pack: codeql/python-all extensible: summaryModel data: + # See + # - https://docs.python.org/3/glossary.html#term-mapping + # - https://docs.python.org/3/library/stdtypes.html#dict.get + - ["_collections_abc.Mapping", "Member[get]", "Argument[1,default:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser + - ["argparse.ArgumentParser", "Member[_parse_known_args,_read_args_from_files]", "Argument[0,arg_strings:]", "ReturnValue", "taint"] + - ["argparse.ArgumentParser", "Member[parse_args,parse_known_args]", "Argument[0,args:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/cgi.html#higher-level-interface + - ["cgi.FieldStorage", "Member[getfirst,getlist,getvalue]", "Argument[self]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/contextlib.html#contextlib.ExitStack + - ["contextlib.ExitStack", "Member[enter_context]", "Argument[0,cm:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/copy.html#copy.deepcopy - ["copy", "Member[copy,deepcopy]", "Argument[0,x:]", "ReturnValue", "value"] + # See + # - https://docs.python.org/3/library/ctypes.html#ctypes.create_string_buffer + # - https://docs.python.org/3/library/ctypes.html#ctypes.create_unicode_buffer + - ["ctypes", "Member[create_string_buffer,create_unicode_buffer]", "Argument[0,init:,init_or_size:]", "ReturnValue", "taint"] + # See https://docs.python.org/3.11/distutils/apiref.html#distutils.util.change_root + - ["distutils", "Member[util].Member[change_root]", "Argument[0,new_root:,1,pathname:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/email.header.html#email.header.Header + - ["email.header.Header!", "Subclass.Call", "Argument[0,s:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/email.utils.html#email.utils.parseaddr + - ["email", "Member[utils].Member[parseaddr]", "Argument[0,addr:]", "ReturnValue", "taint"] + - ["email", "Member[utils].Member[parseaddr]", "Argument[0,addr:]", "ReturnValue.TupleElement[0,1]", "taint"] # See See https://docs.python.org/3/library/fnmatch.html#fnmatch.filter - ["fnmatch", "Member[filter]", "Argument[0,names:].ListElement", "ReturnValue.ListElement", "value"] - ["fnmatch", "Member[filter]", "Argument[0,names:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/getopt.html#getopt.getopt + - ["getopt", "Member[getopt]", "Argument[0,args:]", "ReturnValue.TupleElement[1]", "taint"] + - ["getopt", "Member[getopt]", "Argument[1,shortopts:,2,longopts:]", "ReturnValue.TupleElement[0].ListElement.TupleElement[0]", "taint"] + # See https://docs.python.org/3/library/gettext.html#gettext.gettext + - ["gettext", "Member[gettext]", "Argument[0,message:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/gzip.html#gzip.GzipFile + - ["gzip.GzipFile!", "Subclass.Call", "Argument[0,filename:]", "ReturnValue", "taint"] + # See + # - https://docs.python.org/3/library/html.html#html.escape + # - https://docs.python.org/3/library/html.html#html.unescape + - ["html", "Member[escape,unescape]", "Argument[0,s:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/html.parser.html#html.parser.HTMLParser.feed + - ["html.parser.HTMLParser", "Member[feed]", "Argument[0,data:]", "Argument[self]", "taint"] + # See https://docs.python.org/3.11/library/imp.html#imp.find_module + - ["imp", "Member[find_module]", "Argument[0,name:,1,path:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/logging.html#logging.getLevelName + # specifically the no matching case + - ["logging", "Member[getLevelName]", "Argument[0,level:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/logging.html#logging.LogRecord.getMessage + - ["logging.LogRecord", "Member[getMessage]", "Argument[self]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/mimetypes.html#mimetypes.guess_type + - ["mimetypes", "Member[guess_type]", "Argument[0,url:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/multiprocessing.html#multiprocessing.connection.Listener + - ["multiprocessing.connection.Listener!", "Subclass.Call", "Argument[3,authkey:]", "ReturnValue", "taint"] + # See https://github.com/python/cpython/blob/main/Lib/nturl2path.py + # No user-facing documentation, unfortunately. + - ["nturl2path", "Member[pathname2url]", "Argument[0,p:]", "ReturnValue", "taint"] + - ["nturl2path", "Member[url2pathname]", "Argument[0,url:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/optparse.html#optparse.OptionParser.parse_args - ["optparse.OptionParser", "Member[parse_args]", "Argument[0,args:,1,values:]", "ReturnValue.TupleElement[0,1]", "taint"] + # See https://github.com/python/cpython/blob/3.10/Lib/pathlib.py#L972-L973 + - ["pathlib.Path", ".Member[__enter__]", "Argument[self]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/os.html#os.PathLike.__fspath__ + - ["pathlib.PurePath", "Member[__fspath__]", "Argument[self]", "ReturnValue", "taint"] + # See + # - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.put + # - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.put_nowait + - ["queue.Queue", "Member[put,put_nowait]", "Argument[0,item:]", "Argument[self]", "taint"] + # See + # - https://docs.python.org/3/library/random.html#random.choice + # - https://docs.python.org/3/library/random.html#module-random + - ["random", "Member[choice]", "Argument[0,seq:]", "ReturnValue", "taint"] + - ["random.Random", "Member[choice]", "Argument[0,seq:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/shlex.html#shlex.quote + - ["shlex", "Member[quote]", "Argument[0,s:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/shutil.html#shutil.rmtree + - ["shutil", "Member[rmtree]", "Argument[0,path:]", "Argument[2,onerror:,onexc:].Argument[1]", "taint"] + # See https://docs.python.org/3/library/shutil.html#shutil.which + - ["shutil", "Member[which]", "Argument[0,cmd:,2,path:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/subprocess.html#subprocess.Popen + - ["subprocess.Popen!", "Subclass.Call", "Argument[0,args:]", "ReturnValue", "taint"] + # See + # - https://docs.python.org/3/library/tarfile.html#tarfile.open + # - https://docs.python.org/3/library/tarfile.html#tarfile.TarFile.open + - ["tarfile", "Member[open]", "Argument[0,name:,2,fileobj:]", "ReturnValue", "taint"] + - ["tarfile.TarFile", "Member[open]", "Argument[0,name:,2,fileobj:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/tempfile.html#tempfile.mkdtemp + - ["tempfile", "Member[mkdtemp]", "Argument[0,suffix:,1,prefix:,2,dir:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/tempfile.html#tempfile.mkstemp + - ["tempfile", "Member[mkstemp]", "Argument[0,suffix:,1,prefix:,2,dir:]", "ReturnValue.TupleElement[0,1]", "taint"] + # See https://docs.python.org/3/library/textwrap.html#textwrap.dedent + - ["textwrap", "Member[dedent]", "Argument[0,text:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/traceback.html#traceback.StackSummary.from_list + - ["traceback.StackSummary", "Member[from_list]", "Argument[0,a_list:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/typing.html#typing.cast + - ["typing", "Member[cast]", "Argument[1,val:]", "ReturnValue", "value"] # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote - ["urllib", "Member[parse].Member[quote]", "Argument[0,string:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote_plus @@ -35,6 +123,21 @@ extensions: - ["urllib", "Member[parse].Member[urlencode]", "Argument[0,query:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urljoin - ["urllib", "Member[parse].Member[urljoin]", "Argument[0,base:,1,url:]", "ReturnValue", "taint"] + # See the internal documentation + # https://github.com/python/cpython/blob/3.12/Lib/zipfile/_path/__init__.py#L103-L105 + - ["zipfile.CompleteDirs", "Member[namelist]", "Argument[self]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile + # it may be necessary to read the code to understand the taint propagation + # Constructor: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1266 + - ["zipfile.ZipFile!", "Subclass.Call", "Argument[0,file:]", "ReturnValue", "taint"] + - ["zipfile.ZipFile!", "Subclass.Call", "Argument[0,file:]", "ReturnValue.Attribute[filelist].ListElement.Attribute[filename]", "value"] + # _extract_member: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1761 + - ["zipfile.ZipFile", "Member[_extract_member]", "Argument[1,targetpath:]", "ReturnValue", "taint"] + # infolist: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1498-L1501 + - ["zipfile.ZipFile", "Member[infolist]", "Argument[self]", "ReturnValue", "taint"] + - ["zipfile.ZipFile", "Member[infolist]", "Argument[self].Attribute[filelist]", "ReturnValue", "value"] + # namelist: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1494-L1496 + - ["zipfile.ZipFile", "Member[namelist]", "Argument[self]", "ReturnValue", "taint"] - addsTo: pack: codeql/python-all extensible: neutralModel From eb32cbe8a5fa65d85894c62c01dd42a5a8cbec98 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Wed, 26 Jun 2024 00:57:59 +0200 Subject: [PATCH 011/347] Python: codecs.open --- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 7a373a523e47..74e33429ed05 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -1492,6 +1492,9 @@ module StdlibPrivate { or // io.open is a special case, since it is an alias for the builtin `open` result = API::moduleImport("io").getMember("open") + or + // similarly, coecs.open calls the builtin `open`: https://github.com/python/cpython/blob/3.12/Lib/codecs.py#L918 + result = API::moduleImport("codecs").getMember("open") } /** From 571be8be3e052737e13c50d1fcc4201891aafe4f Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Wed, 26 Jun 2024 01:00:38 +0200 Subject: [PATCH 012/347] Python: model more loggers --- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 74e33429ed05..57bceeda79aa 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -254,10 +254,14 @@ module Stdlib { * See https://docs.python.org/3.9/library/logging.html#logging.Logger. */ module Logger { + private import semmle.python.dataflow.new.internal.DataFlowDispatch as DD + /** Gets a reference to the `logging.Logger` class or any subclass. */ API::Node subclassRef() { result = API::moduleImport("logging").getMember("Logger").getASubclass*() or + result = API::moduleImport("logging").getMember("getLoggerClass").getReturn().getASubclass*() + or result = ModelOutput::getATypeNode("logging.Logger~Subclass").getASubclass*() } @@ -277,6 +281,13 @@ module Stdlib { ClassInstantiation() { this = subclassRef().getACall() or + this = + DD::selfTracker(subclassRef() + .getAValueReachableFromSource() + .asExpr() + .(ClassExpr) + .getInnerScope()) + or this = API::moduleImport("logging").getMember("root").asSource() or this = API::moduleImport("logging").getMember("getLogger").getACall() From b261145f4346ee7ee666ba4445d199af076374f0 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Wed, 26 Jun 2024 10:46:38 +0200 Subject: [PATCH 013/347] Python: fix compilation --- .../functions/ModificationOfParameterWithDefault.qll | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll b/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll index 77dc4ccafcc0..68194309e1dd 100644 --- a/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll +++ b/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll @@ -8,7 +8,7 @@ private import python import semmle.python.dataflow.new.DataFlow -private import semmle.python.dataflow.new.internal.TaintTrackingPrivate as TTP +private import semmle.python.ApiGraphs /** * Provides a data-flow configuration for detecting modifications of a parameters default value. @@ -73,7 +73,13 @@ module ModificationOfParameterWithDefault { or // the target of a copy step is (presumably) a different object, and hence modifications of // this object no longer matter for the purposes of this query. - TTP::copyStep(_, node) and state in [true, false] + copyTarget(node) and state in [true, false] + } + + private predicate copyTarget(DataFlow::Node node) { + node = API::moduleImport("copy").getMember(["copy", "deepcopy"]).getACall() + or + node.(DataFlow::MethodCallNode).calls(_, "copy") } } From a3076f4f724884a71e41535f592ae8e717127c1c Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Wed, 26 Jun 2024 13:27:32 +0200 Subject: [PATCH 014/347] Python: fix test expectations, add missing sanitizer --- .../UnsafeShellCommandConstructionQuery.qll | 1 + .../CWE-022-UnsafeUnpacking/UnsafeUnpack.expected | 1 + .../Security/CWE-409/DecompressionBombs.expected | 15 +++++++++++++++ .../CommandInjection.expected | 2 +- 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll index 73205fdeb28c..6d292a88b6c7 100644 --- a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll @@ -45,6 +45,7 @@ module UnsafeShellCommandConstructionConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof Sink } predicate isBarrier(DataFlow::Node node) { + node instanceof Sanitizer or node instanceof CommandInjection::Sanitizer // using all sanitizers from `py/command-injection` } diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected index ca4d7ebafff0..e1710375df25 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected @@ -75,6 +75,7 @@ edges | UnsafeUnpack.py:161:19:161:21 | ControlFlowNode for tar | UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | provenance | | | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | UnsafeUnpack.py:161:19:161:21 | ControlFlowNode for tar | provenance | | | UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | provenance | Config | +| UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | provenance | MaD:49 | | UnsafeUnpack.py:163:23:163:28 | ControlFlowNode for member | UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | provenance | | | UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | UnsafeUnpack.py:163:23:163:28 | ControlFlowNode for member | provenance | | | UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result | UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | provenance | | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected index 5689deb01a03..92af7f59efe7 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected @@ -1,13 +1,23 @@ edges | test.py:10:16:10:24 | ControlFlowNode for file_path | test.py:11:21:11:29 | ControlFlowNode for file_path | provenance | | +| test.py:11:5:11:35 | ControlFlowNode for Attribute() | test.py:11:5:11:52 | ControlFlowNode for Attribute() | provenance | Config | +| test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:35 | ControlFlowNode for Attribute() | provenance | MaD:64 | | test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:52 | ControlFlowNode for Attribute() | provenance | Config | | test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:12:21:12:29 | ControlFlowNode for file_path | provenance | | +| test.py:12:5:12:35 | ControlFlowNode for Attribute() | test.py:12:5:12:48 | ControlFlowNode for Attribute() | provenance | Config | +| test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:35 | ControlFlowNode for Attribute() | provenance | MaD:64 | | test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:48 | ControlFlowNode for Attribute() | provenance | Config | | test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:14:26:14:34 | ControlFlowNode for file_path | provenance | | +| test.py:14:10:14:35 | ControlFlowNode for Attribute() | test.py:15:14:15:29 | ControlFlowNode for Attribute() | provenance | Config | +| test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:14:10:14:35 | ControlFlowNode for Attribute() | provenance | MaD:64 | | test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:15:14:15:29 | ControlFlowNode for Attribute() | provenance | Config | | test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:18:26:18:34 | ControlFlowNode for file_path | provenance | | +| test.py:18:10:18:35 | ControlFlowNode for Attribute() | test.py:19:14:19:39 | ControlFlowNode for Attribute() | provenance | Config | +| test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:18:10:18:35 | ControlFlowNode for Attribute() | provenance | MaD:64 | | test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:19:14:19:39 | ControlFlowNode for Attribute() | provenance | Config | | test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:22:21:22:29 | ControlFlowNode for file_path | provenance | | +| test.py:22:5:22:30 | ControlFlowNode for Attribute() | test.py:22:5:22:60 | ControlFlowNode for Attribute() | provenance | Config | +| test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:30 | ControlFlowNode for Attribute() | provenance | MaD:64 | | test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:60 | ControlFlowNode for Attribute() | provenance | Config | | test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:24:18:24:26 | ControlFlowNode for file_path | provenance | | | test.py:24:18:24:26 | ControlFlowNode for file_path | test.py:24:5:24:52 | ControlFlowNode for Attribute() | provenance | Config | @@ -37,14 +47,19 @@ edges | test.py:28:26:28:34 | ControlFlowNode for file_path | test.py:64:36:64:44 | ControlFlowNode for file_path | provenance | | nodes | test.py:10:16:10:24 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path | +| test.py:11:5:11:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:11:5:11:52 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:11:21:11:29 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path | +| test.py:12:5:12:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:12:5:12:48 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:12:21:12:29 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path | +| test.py:14:10:14:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:14:26:14:34 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path | | test.py:15:14:15:29 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:18:10:18:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:18:26:18:34 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path | | test.py:19:14:19:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:22:5:22:30 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:22:5:22:60 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:22:21:22:29 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path | | test.py:24:5:24:52 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected index 1e75c67db66b..4a1856ba98ad 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected @@ -12,7 +12,7 @@ edges | command_injection.py:11:13:11:19 | ControlFlowNode for request | command_injection.py:11:13:11:24 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | | command_injection.py:11:13:11:24 | ControlFlowNode for Attribute | command_injection.py:11:13:11:41 | ControlFlowNode for Attribute() | provenance | dict.get | | command_injection.py:11:13:11:41 | ControlFlowNode for Attribute() | command_injection.py:11:5:11:9 | ControlFlowNode for files | provenance | | -| command_injection.py:18:5:18:9 | ControlFlowNode for files | command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | provenance | | +| command_injection.py:18:5:18:9 | ControlFlowNode for files | command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:11 | | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | provenance | dict.get | | command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | command_injection.py:18:5:18:9 | ControlFlowNode for files | provenance | | From bbc3ff2dfedf7cbf087209f7863d1049db7b4bca Mon Sep 17 00:00:00 2001 From: yoff Date: Fri, 28 Jun 2024 14:39:03 +0200 Subject: [PATCH 015/347] Apply suggestions from code review Co-authored-by: Rasmus Wriedt Larsen --- .../ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml index 1d7e0c070fe4..16bd96ffe252 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml +++ b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml @@ -18,7 +18,7 @@ extensions: # See # - https://docs.python.org/3/glossary.html#term-mapping # - https://docs.python.org/3/library/stdtypes.html#dict.get - - ["_collections_abc.Mapping", "Member[get]", "Argument[1,default:]", "ReturnValue", "taint"] + - ["collections.abc.Mapping", "Member[get]", "Argument[1,default:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser - ["argparse.ArgumentParser", "Member[_parse_known_args,_read_args_from_files]", "Argument[0,arg_strings:]", "ReturnValue", "taint"] - ["argparse.ArgumentParser", "Member[parse_args,parse_known_args]", "Argument[0,args:]", "ReturnValue", "taint"] @@ -88,7 +88,7 @@ extensions: # See https://docs.python.org/3/library/shlex.html#shlex.quote - ["shlex", "Member[quote]", "Argument[0,s:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/shutil.html#shutil.rmtree - - ["shutil", "Member[rmtree]", "Argument[0,path:]", "Argument[2,onerror:,onexc:].Argument[1]", "taint"] + - ["shutil", "Member[rmtree]", "Argument[0,path:]", "Argument[2,onerror:,onexc:].Parameter[1]", "taint"] # See https://docs.python.org/3/library/shutil.html#shutil.which - ["shutil", "Member[which]", "Argument[0,cmd:,2,path:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/subprocess.html#subprocess.Popen From 59f953269a22300e011546a9ced4cc3a2c4c9234 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Fri, 28 Jun 2024 14:42:24 +0200 Subject: [PATCH 016/347] Python: remove strange sink It is not clear from the code how this could happen and I do not remember the path I saw, perhaps it was unreasonable. --- python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml index 16bd96ffe252..aee88e1d9419 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml +++ b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml @@ -8,7 +8,6 @@ extensions: pack: codeql/python-all extensible: sinkModel data: - - ["subprocess.Popen!","Subclass.Call.Argument[0,args:]", "log-injection"] - ["zipfile.ZipFile","Member[extractall].Argument[0,path:]", "path-injection"] - addsTo: From 5ddfe75a0da516249e7a7ff3c0a06bbbc2200b87 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Fri, 28 Jun 2024 15:10:08 +0200 Subject: [PATCH 017/347] Python: Add value steps for sequence elements It would be nice to simplify to a single sequence content type.. --- .../semmle/python/frameworks/Stdlib/StdLib.model.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml index aee88e1d9419..569ad9e48e7f 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml +++ b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml @@ -76,13 +76,23 @@ extensions: # See https://docs.python.org/3/library/os.html#os.PathLike.__fspath__ - ["pathlib.PurePath", "Member[__fspath__]", "Argument[self]", "ReturnValue", "taint"] # See + # - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.get + # - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.get_nowait + - ["queue.Queue", "Member[get,get_nowait]", "Argument[self].ListElement", "ReturnValue", "value"] + - ["queue.Queue", "Member[get,get_nowait]", "Argument[self]", "ReturnValue", "taint"] + # See # - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.put # - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.put_nowait + - ["queue.Queue", "Member[put,put_nowait]", "Argument[0,item:]", "Argument[self].ListElement", "value"] - ["queue.Queue", "Member[put,put_nowait]", "Argument[0,item:]", "Argument[self]", "taint"] # See # - https://docs.python.org/3/library/random.html#random.choice # - https://docs.python.org/3/library/random.html#module-random + - ["random", "Member[choice]", "Argument[0,seq:].ListElement", "ReturnValue", "value"] + - ["random", "Member[choice]", "Argument[0,seq:].SetElement", "ReturnValue", "value"] - ["random", "Member[choice]", "Argument[0,seq:]", "ReturnValue", "taint"] + - ["random.Random", "Member[choice]", "Argument[0,seq:].ListElement", "ReturnValue", "value"] + - ["random.Random", "Member[choice]", "Argument[0,seq:].SetElement", "ReturnValue", "value"] - ["random.Random", "Member[choice]", "Argument[0,seq:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/shlex.html#shlex.quote - ["shlex", "Member[quote]", "Argument[0,s:]", "ReturnValue", "taint"] From 77a00873a974c4ecec229f19a59f2cef7ede0c02 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Fri, 28 Jun 2024 15:25:17 +0200 Subject: [PATCH 018/347] Python: add tests for loggers --- .../ql/test/library-tests/frameworks/stdlib/Logging.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/python/ql/test/library-tests/frameworks/stdlib/Logging.py b/python/ql/test/library-tests/frameworks/stdlib/Logging.py index cb2e3fddc902..72a5175fef85 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/Logging.py +++ b/python/ql/test/library-tests/frameworks/stdlib/Logging.py @@ -43,3 +43,12 @@ class MyLogger(logging.Logger): pass MyLogger("bar").info("hello") # $ loggingInput="hello" + +class CustomLogger(logging.getLoggerClass()): + pass + +CustomLogger("baz").info("hello") # $ loggingInput="hello" + +class LoggerSubClassUsingSelf(logging.Logger): + def foo(self): + self.info("hello") # $ loggingInput="hello" \ No newline at end of file From e40ae2e52d3a3d378aa00a0b9f5bd6c5f9a88bc3 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Fri, 28 Jun 2024 21:56:11 +0200 Subject: [PATCH 019/347] Python: adjust test expectations MaD row numbers in provenance column --- .../CWE-022-UnsafeUnpacking/UnsafeUnpack.expected | 2 +- .../Security/CWE-409/DecompressionBombs.expected | 10 +++++----- .../CWE-078-CommandInjection/CommandInjection.expected | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected index e1710375df25..ea08c95d7b64 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected @@ -75,7 +75,7 @@ edges | UnsafeUnpack.py:161:19:161:21 | ControlFlowNode for tar | UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | provenance | | | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | UnsafeUnpack.py:161:19:161:21 | ControlFlowNode for tar | provenance | | | UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | provenance | Config | -| UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | provenance | MaD:49 | +| UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | provenance | MaD:55 | | UnsafeUnpack.py:163:23:163:28 | ControlFlowNode for member | UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | provenance | | | UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | UnsafeUnpack.py:163:23:163:28 | ControlFlowNode for member | provenance | | | UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result | UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | provenance | | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected index 92af7f59efe7..19d715d8a868 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected @@ -1,23 +1,23 @@ edges | test.py:10:16:10:24 | ControlFlowNode for file_path | test.py:11:21:11:29 | ControlFlowNode for file_path | provenance | | | test.py:11:5:11:35 | ControlFlowNode for Attribute() | test.py:11:5:11:52 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:35 | ControlFlowNode for Attribute() | provenance | MaD:64 | +| test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:35 | ControlFlowNode for Attribute() | provenance | MaD:70 | | test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:52 | ControlFlowNode for Attribute() | provenance | Config | | test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:12:21:12:29 | ControlFlowNode for file_path | provenance | | | test.py:12:5:12:35 | ControlFlowNode for Attribute() | test.py:12:5:12:48 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:35 | ControlFlowNode for Attribute() | provenance | MaD:64 | +| test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:35 | ControlFlowNode for Attribute() | provenance | MaD:70 | | test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:48 | ControlFlowNode for Attribute() | provenance | Config | | test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:14:26:14:34 | ControlFlowNode for file_path | provenance | | | test.py:14:10:14:35 | ControlFlowNode for Attribute() | test.py:15:14:15:29 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:14:10:14:35 | ControlFlowNode for Attribute() | provenance | MaD:64 | +| test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:14:10:14:35 | ControlFlowNode for Attribute() | provenance | MaD:70 | | test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:15:14:15:29 | ControlFlowNode for Attribute() | provenance | Config | | test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:18:26:18:34 | ControlFlowNode for file_path | provenance | | | test.py:18:10:18:35 | ControlFlowNode for Attribute() | test.py:19:14:19:39 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:18:10:18:35 | ControlFlowNode for Attribute() | provenance | MaD:64 | +| test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:18:10:18:35 | ControlFlowNode for Attribute() | provenance | MaD:70 | | test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:19:14:19:39 | ControlFlowNode for Attribute() | provenance | Config | | test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:22:21:22:29 | ControlFlowNode for file_path | provenance | | | test.py:22:5:22:30 | ControlFlowNode for Attribute() | test.py:22:5:22:60 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:30 | ControlFlowNode for Attribute() | provenance | MaD:64 | +| test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:30 | ControlFlowNode for Attribute() | provenance | MaD:70 | | test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:60 | ControlFlowNode for Attribute() | provenance | Config | | test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:24:18:24:26 | ControlFlowNode for file_path | provenance | | | test.py:24:18:24:26 | ControlFlowNode for file_path | test.py:24:5:24:52 | ControlFlowNode for Attribute() | provenance | Config | diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected index 4a1856ba98ad..1e75c67db66b 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected @@ -12,7 +12,7 @@ edges | command_injection.py:11:13:11:19 | ControlFlowNode for request | command_injection.py:11:13:11:24 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | | command_injection.py:11:13:11:24 | ControlFlowNode for Attribute | command_injection.py:11:13:11:41 | ControlFlowNode for Attribute() | provenance | dict.get | | command_injection.py:11:13:11:41 | ControlFlowNode for Attribute() | command_injection.py:11:5:11:9 | ControlFlowNode for files | provenance | | -| command_injection.py:18:5:18:9 | ControlFlowNode for files | command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:11 | +| command_injection.py:18:5:18:9 | ControlFlowNode for files | command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | provenance | | | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | provenance | dict.get | | command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | command_injection.py:18:5:18:9 | ControlFlowNode for files | provenance | | From e30f725e71e6637f037bd232ee1a5573ce1c2aa7 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 22 Jul 2024 15:43:06 +0200 Subject: [PATCH 020/347] Python: Remove questionable model for `multiprocessing.connection.Listener` --- python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml index 569ad9e48e7f..19a97b16537e 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml +++ b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml @@ -63,8 +63,6 @@ extensions: - ["logging.LogRecord", "Member[getMessage]", "Argument[self]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/mimetypes.html#mimetypes.guess_type - ["mimetypes", "Member[guess_type]", "Argument[0,url:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/multiprocessing.html#multiprocessing.connection.Listener - - ["multiprocessing.connection.Listener!", "Subclass.Call", "Argument[3,authkey:]", "ReturnValue", "taint"] # See https://github.com/python/cpython/blob/main/Lib/nturl2path.py # No user-facing documentation, unfortunately. - ["nturl2path", "Member[pathname2url]", "Argument[0,p:]", "ReturnValue", "taint"] From 3434c38da78189324578285f405f0bd0bb180786 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 22 Jul 2024 17:03:29 +0200 Subject: [PATCH 021/347] Python: update test expectations This is MaD... --- .../CWE-022-UnsafeUnpacking/UnsafeUnpack.expected | 2 +- .../Security/CWE-409/DecompressionBombs.expected | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected index ea08c95d7b64..0c6c30857220 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected @@ -75,7 +75,7 @@ edges | UnsafeUnpack.py:161:19:161:21 | ControlFlowNode for tar | UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | provenance | | | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | UnsafeUnpack.py:161:19:161:21 | ControlFlowNode for tar | provenance | | | UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | provenance | Config | -| UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | provenance | MaD:55 | +| UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | provenance | MaD:54 | | UnsafeUnpack.py:163:23:163:28 | ControlFlowNode for member | UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | provenance | | | UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | UnsafeUnpack.py:163:23:163:28 | ControlFlowNode for member | provenance | | | UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result | UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | provenance | | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected index 19d715d8a868..073533bcc092 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected @@ -1,23 +1,23 @@ edges | test.py:10:16:10:24 | ControlFlowNode for file_path | test.py:11:21:11:29 | ControlFlowNode for file_path | provenance | | | test.py:11:5:11:35 | ControlFlowNode for Attribute() | test.py:11:5:11:52 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:35 | ControlFlowNode for Attribute() | provenance | MaD:70 | +| test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:35 | ControlFlowNode for Attribute() | provenance | MaD:69 | | test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:52 | ControlFlowNode for Attribute() | provenance | Config | | test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:12:21:12:29 | ControlFlowNode for file_path | provenance | | | test.py:12:5:12:35 | ControlFlowNode for Attribute() | test.py:12:5:12:48 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:35 | ControlFlowNode for Attribute() | provenance | MaD:70 | +| test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:35 | ControlFlowNode for Attribute() | provenance | MaD:69 | | test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:48 | ControlFlowNode for Attribute() | provenance | Config | | test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:14:26:14:34 | ControlFlowNode for file_path | provenance | | | test.py:14:10:14:35 | ControlFlowNode for Attribute() | test.py:15:14:15:29 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:14:10:14:35 | ControlFlowNode for Attribute() | provenance | MaD:70 | +| test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:14:10:14:35 | ControlFlowNode for Attribute() | provenance | MaD:69 | | test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:15:14:15:29 | ControlFlowNode for Attribute() | provenance | Config | | test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:18:26:18:34 | ControlFlowNode for file_path | provenance | | | test.py:18:10:18:35 | ControlFlowNode for Attribute() | test.py:19:14:19:39 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:18:10:18:35 | ControlFlowNode for Attribute() | provenance | MaD:70 | +| test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:18:10:18:35 | ControlFlowNode for Attribute() | provenance | MaD:69 | | test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:19:14:19:39 | ControlFlowNode for Attribute() | provenance | Config | | test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:22:21:22:29 | ControlFlowNode for file_path | provenance | | | test.py:22:5:22:30 | ControlFlowNode for Attribute() | test.py:22:5:22:60 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:30 | ControlFlowNode for Attribute() | provenance | MaD:70 | +| test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:30 | ControlFlowNode for Attribute() | provenance | MaD:69 | | test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:60 | ControlFlowNode for Attribute() | provenance | Config | | test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:24:18:24:26 | ControlFlowNode for file_path | provenance | | | test.py:24:18:24:26 | ControlFlowNode for file_path | test.py:24:5:24:52 | ControlFlowNode for Attribute() | provenance | Config | From 35378aa7146386caac4aea2d9fa4e9341a6a3ed9 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:57:32 +0100 Subject: [PATCH 022/347] Rust: Add placeholder query + test for unreachable code query. --- .../queries/unusedentities/UnreachableCode.ql | 15 ++ .../unusedentities/UnreachableCode.expected | 0 .../unusedentities/UnreachableCode.qlref | 1 + .../query-tests/unusedentities/unreachable.rs | 140 ++++++++++++++++++ 4 files changed, 156 insertions(+) create mode 100644 rust/ql/src/queries/unusedentities/UnreachableCode.ql create mode 100644 rust/ql/test/query-tests/unusedentities/UnreachableCode.expected create mode 100644 rust/ql/test/query-tests/unusedentities/UnreachableCode.qlref create mode 100644 rust/ql/test/query-tests/unusedentities/unreachable.rs diff --git a/rust/ql/src/queries/unusedentities/UnreachableCode.ql b/rust/ql/src/queries/unusedentities/UnreachableCode.ql new file mode 100644 index 000000000000..af19469e83c4 --- /dev/null +++ b/rust/ql/src/queries/unusedentities/UnreachableCode.ql @@ -0,0 +1,15 @@ +/** + * @name Unreachable code + * @description Code that cannot be reached should be deleted. + * @kind problem + * @problem.severity recommendation + * @precision medium + * @id rust/dead-code + * @tags maintainability + */ + +import rust + +from Locatable e +where none() // TODO: implement query +select e, "This code is never reached." diff --git a/rust/ql/test/query-tests/unusedentities/UnreachableCode.expected b/rust/ql/test/query-tests/unusedentities/UnreachableCode.expected new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/rust/ql/test/query-tests/unusedentities/UnreachableCode.qlref b/rust/ql/test/query-tests/unusedentities/UnreachableCode.qlref new file mode 100644 index 000000000000..f65928931a13 --- /dev/null +++ b/rust/ql/test/query-tests/unusedentities/UnreachableCode.qlref @@ -0,0 +1 @@ +queries/unusedentities/UnreachableCode.ql \ No newline at end of file diff --git a/rust/ql/test/query-tests/unusedentities/unreachable.rs b/rust/ql/test/query-tests/unusedentities/unreachable.rs new file mode 100644 index 000000000000..3f32eb36693a --- /dev/null +++ b/rust/ql/test/query-tests/unusedentities/unreachable.rs @@ -0,0 +1,140 @@ + +//fn cond() -> bool; +//fn get_a_number() -> i32; + +// --- unreachable code -- + +fn do_something() { +} + +fn unreachable_if() { + if false { + do_something(); // BAD: unreachable code [NOT DETECTED] + } else { + do_something(); + } + + if true { + do_something(); + } else { + do_something(); // BAD: unreachable code [NOT DETECTED] + } + + let v = get_a_number(); + if v == 1 { + if v != 1 { + do_something(); // BAD: unreachable code [NOT DETECTED] + } + } + + if cond() { + return; + do_something(); // BAD: unreachable code [NOT DETECTED] + } + + if cond() { + do_something(); + } else { + return; + do_something(); // BAD: unreachable code [NOT DETECTED] + } + do_something(); + + if cond() { + return; + } else { + return; + } + do_something(); // BAD: unreachable code [NOT DETECTED] +} + +fn unreachable_panic() { + if cond() { + do_something(); + panic!("Oh no!!!"); + do_something(); // BAD: unreachable code [NOT DETECTED] + } + + if cond() { + do_something(); + unimplemented!(); + do_something(); // BAD: unreachable code [NOT DETECTED] + } + + if cond() { + do_something(); + todo!(); + do_something(); // BAD: unreachable code [NOT DETECTED] + } + + if cond() { + let mut maybe; + + maybe = Some("Thing"); + _ = maybe.unwrap(); // (safe) + do_something(); + + maybe = if cond() { Some("Other") } else { None }; + _ = maybe.unwrap(); // (might panic) + do_something(); + + maybe = None; + _ = maybe.unwrap(); // (always panics) + do_something(); // BAD: unreachable code [NOT DETECTED] + } +} + +fn unreachable_match() { + match get_a_number() { + 1=>{ + return; + } + _=>{ + do_something(); + } + } + do_something(); + + match get_a_number() { + 1=>{ + return; + } + _=>{ + return; + } + } + do_something(); // BAD: unreachable code [NOT DETECTED] +} + +fn unreachable_loop() { + loop { + do_something(); + break; + do_something(); // BAD: unreachable code [NOT DETECTED] + } + + if cond() { + while cond() { + do_something(); + } + + while false { + do_something(); // BAD: unreachable code [NOT DETECTED] + } + + while true { + do_something(); + } + do_something(); // BAD: unreachable code [NOT DETECTED] + } + + loop { + if cond() { + return; + do_something(); // BAD: unreachable code [NOT DETECTED] + } + } + do_something(); // BAD: unreachable code [NOT DETECTED] + do_something(); + do_something(); +} From e7e0c6bf12eae2e3d8de9dbb5b2573a48c409f6f Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:57:03 +0100 Subject: [PATCH 023/347] Rust: Add qhelp + examples for unreachable code query. --- .../unusedentities/UnreachableCode.qhelp | 24 +++++++++++++++++++ .../unusedentities/UnreachableCodeBad.rs | 11 +++++++++ .../unusedentities/UnreachableCodeGood.rs | 9 +++++++ 3 files changed, 44 insertions(+) create mode 100644 rust/ql/src/queries/unusedentities/UnreachableCode.qhelp create mode 100644 rust/ql/src/queries/unusedentities/UnreachableCodeBad.rs create mode 100644 rust/ql/src/queries/unusedentities/UnreachableCodeGood.rs diff --git a/rust/ql/src/queries/unusedentities/UnreachableCode.qhelp b/rust/ql/src/queries/unusedentities/UnreachableCode.qhelp new file mode 100644 index 000000000000..fef1aa71f6ba --- /dev/null +++ b/rust/ql/src/queries/unusedentities/UnreachableCode.qhelp @@ -0,0 +1,24 @@ + + + + +

This rule finds code that is never reached. Unused code should be removed to increase readability and avoid confusion.

+
+ + +

Remove any unreachable code.

+
+ + +

In the following example, the final return statement can never be reached:

+ +

The problem can be fixed simply by removing the unreachable code:

+ +
+ + +
  • Wikipedia: Unreachable code
  • +
    +
    diff --git a/rust/ql/src/queries/unusedentities/UnreachableCodeBad.rs b/rust/ql/src/queries/unusedentities/UnreachableCodeBad.rs new file mode 100644 index 000000000000..a27bc0cab164 --- /dev/null +++ b/rust/ql/src/queries/unusedentities/UnreachableCodeBad.rs @@ -0,0 +1,11 @@ +fn fib(input: u32) -> u32 { + if (input == 0) { + return 0; + } else if (input == 1) { + return 1; + } else { + return fib(input - 1) + fib(input - 2); + } + + return input; // BAD: this code is never reached +} diff --git a/rust/ql/src/queries/unusedentities/UnreachableCodeGood.rs b/rust/ql/src/queries/unusedentities/UnreachableCodeGood.rs new file mode 100644 index 000000000000..0b2bde66fe95 --- /dev/null +++ b/rust/ql/src/queries/unusedentities/UnreachableCodeGood.rs @@ -0,0 +1,9 @@ +fn fib(input: u32) -> u32 { + if (input == 0) { + return 0; + } else if (input == 1) { + return 1; + } else { + return fib(input - 1) + fib(input - 2); + } +} From 1eaa998648c099238a9e4267c25f19994926a4e8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 18 Sep 2024 17:57:42 +0100 Subject: [PATCH 024/347] Rust: Implement unreachable code query. --- .../queries/unusedentities/UnreachableCode.ql | 50 +++++++++++++++++-- .../unusedentities/UnreachableCode.expected | 15 ++++++ .../query-tests/unusedentities/unreachable.rs | 30 +++++------ 3 files changed, 77 insertions(+), 18 deletions(-) diff --git a/rust/ql/src/queries/unusedentities/UnreachableCode.ql b/rust/ql/src/queries/unusedentities/UnreachableCode.ql index af19469e83c4..3458bb338c55 100644 --- a/rust/ql/src/queries/unusedentities/UnreachableCode.ql +++ b/rust/ql/src/queries/unusedentities/UnreachableCode.ql @@ -9,7 +9,51 @@ */ import rust +import codeql.rust.controlflow.ControlFlowGraph +import codeql.rust.controlflow.internal.ControlFlowGraphImpl as ControlFlowGraphImpl -from Locatable e -where none() // TODO: implement query -select e, "This code is never reached." +/** + * Holds if `n` is an AST node that's unreachable, and is not the successor + * of an unreachable node (which would be a duplicate result). + */ +predicate firstUnreachable(AstNode n) { + // entry nodes are reachable + not exists(CfgScope s | s.scopeFirst(n)) and + // we never want a `ControlFlowTree` successor node: + // - if the predecessor is reachable, so are we. + // - if the predecessor is unreachable, we're not the *first* unreachable node. + not ControlFlowGraphImpl::succ(_, n, _) + // (note that an unreachable cycle of nodes could be missed by this logic, in + // general it wouldn't be possible to pick one node to represent it) +} + +/** + * Gets a node we'd prefer not to report as unreachable. + */ +predicate skipNode(AstNode n) { + n instanceof ControlFlowGraphImpl::PostOrderTree or // location is counter-intuitive + not n instanceof ControlFlowGraphImpl::ControlFlowTree // not expected to be reachable +} + +/** + * Gets the `ControlFlowTree` successor of a node we'd prefer not to report. + */ +AstNode skipSuccessor(AstNode n) { + skipNode(n) and + ControlFlowGraphImpl::succ(n, result, _) +} + +/** + * Gets the node `n`, skipping past any nodes we'd prefer not to report. + */ +AstNode skipSuccessors(AstNode n) { + result = skipSuccessor*(n) and + not skipNode(result) +} + +from AstNode first, AstNode report +where + firstUnreachable(first) and + report = skipSuccessors(first) and + exists(report.getFile().getRelativePath()) // in source +select report, "This code is never reached." diff --git a/rust/ql/test/query-tests/unusedentities/UnreachableCode.expected b/rust/ql/test/query-tests/unusedentities/UnreachableCode.expected index e69de29bb2d1..fc28f042e943 100644 --- a/rust/ql/test/query-tests/unusedentities/UnreachableCode.expected +++ b/rust/ql/test/query-tests/unusedentities/UnreachableCode.expected @@ -0,0 +1,15 @@ +| unreachable.rs:32:3:32:17 | ExprStmt | This code is never reached. | +| unreachable.rs:39:3:39:17 | ExprStmt | This code is never reached. | +| unreachable.rs:48:2:48:16 | ExprStmt | This code is never reached. | +| unreachable.rs:89:3:91:3 | MatchArm | This code is never reached. | +| unreachable.rs:92:3:94:3 | MatchArm | This code is never reached. | +| unreachable.rs:96:2:96:16 | ExprStmt | This code is never reached. | +| unreachable.rs:99:3:101:3 | MatchArm | This code is never reached. | +| unreachable.rs:102:3:104:3 | MatchArm | This code is never reached. | +| unreachable.rs:106:2:106:16 | ExprStmt | This code is never reached. | +| unreachable.rs:113:3:113:17 | ExprStmt | This code is never reached. | +| unreachable.rs:118:4:118:18 | ExprStmt | This code is never reached. | +| unreachable.rs:122:4:122:18 | ExprStmt | This code is never reached. | +| unreachable.rs:126:4:126:18 | ExprStmt | This code is never reached. | +| unreachable.rs:134:4:134:18 | ExprStmt | This code is never reached. | +| unreachable.rs:137:2:137:16 | ExprStmt | This code is never reached. | diff --git a/rust/ql/test/query-tests/unusedentities/unreachable.rs b/rust/ql/test/query-tests/unusedentities/unreachable.rs index 3f32eb36693a..3dbda4981e9c 100644 --- a/rust/ql/test/query-tests/unusedentities/unreachable.rs +++ b/rust/ql/test/query-tests/unusedentities/unreachable.rs @@ -29,14 +29,14 @@ fn unreachable_if() { if cond() { return; - do_something(); // BAD: unreachable code [NOT DETECTED] + do_something(); // BAD: unreachable code } if cond() { do_something(); } else { return; - do_something(); // BAD: unreachable code [NOT DETECTED] + do_something(); // BAD: unreachable code } do_something(); @@ -45,7 +45,7 @@ fn unreachable_if() { } else { return; } - do_something(); // BAD: unreachable code [NOT DETECTED] + do_something(); // BAD: unreachable code } fn unreachable_panic() { @@ -86,44 +86,44 @@ fn unreachable_panic() { fn unreachable_match() { match get_a_number() { - 1=>{ + 1=>{ // [unreachable FALSE POSITIVE] return; } - _=>{ + _=>{ // [unreachable FALSE POSITIVE] do_something(); } } - do_something(); + do_something(); // [unreachable FALSE POSITIVE] match get_a_number() { - 1=>{ + 1=>{ // [unreachable FALSE POSITIVE] return; } - _=>{ + _=>{ // [unreachable FALSE POSITIVE] return; } } - do_something(); // BAD: unreachable code [NOT DETECTED] + do_something(); // BAD: unreachable code } fn unreachable_loop() { loop { do_something(); break; - do_something(); // BAD: unreachable code [NOT DETECTED] + do_something(); // BAD: unreachable code } if cond() { while cond() { - do_something(); + do_something();{ // [unreachable FALSE POSITIVE] } while false { - do_something(); // BAD: unreachable code [NOT DETECTED] + do_something(); // BAD: unreachable code } while true { - do_something(); + do_something(); // [unreachable FALSE POSITIVE] } do_something(); // BAD: unreachable code [NOT DETECTED] } @@ -131,10 +131,10 @@ fn unreachable_loop() { loop { if cond() { return; - do_something(); // BAD: unreachable code [NOT DETECTED] + do_something(); // BAD: unreachable code } } - do_something(); // BAD: unreachable code [NOT DETECTED] + do_something(); // BAD: unreachable code do_something(); do_something(); } From 3e0d30f13a1d3b390c20195fbdcbb6e6e9733bd6 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 19 Sep 2024 16:34:31 +0100 Subject: [PATCH 025/347] Rust: Merge of unusedvar and unreachable work. --- .../query-tests/unusedentities/UnreachableCode.expected | 1 + rust/ql/test/query-tests/unusedentities/main.rs | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/rust/ql/test/query-tests/unusedentities/UnreachableCode.expected b/rust/ql/test/query-tests/unusedentities/UnreachableCode.expected index fc28f042e943..83aba7040460 100644 --- a/rust/ql/test/query-tests/unusedentities/UnreachableCode.expected +++ b/rust/ql/test/query-tests/unusedentities/UnreachableCode.expected @@ -1,3 +1,4 @@ +| main.rs:114:3:114:29 | ExprStmt | This code is never reached. | | unreachable.rs:32:3:32:17 | ExprStmt | This code is never reached. | | unreachable.rs:39:3:39:17 | ExprStmt | This code is never reached. | | unreachable.rs:48:2:48:16 | ExprStmt | This code is never reached. | diff --git a/rust/ql/test/query-tests/unusedentities/main.rs b/rust/ql/test/query-tests/unusedentities/main.rs index 8066f7c783e0..3f163b2a0641 100644 --- a/rust/ql/test/query-tests/unusedentities/main.rs +++ b/rust/ql/test/query-tests/unusedentities/main.rs @@ -111,7 +111,7 @@ fn arrays() { println!("lets use {:?}", js); for k in ks { - println!("lets use {}", k); + println!("lets use {}", k); // [unreachable FALSE POSITIVE] } } @@ -142,6 +142,8 @@ fn parameters( return x; } +// --- main --- + fn main() { locals_1(); locals_2(); @@ -149,4 +151,8 @@ fn main() { arrays(); statics(); println!("lets use result {}", parameters(1, 2, 3)); + unreachable_if(); + unreachable_panic(); + unreachable_match(); + unreachable_loop(); } From f95926e1a810b677ec2b8ce45711ea1ea0e24518 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 24 Sep 2024 20:23:39 +0200 Subject: [PATCH 026/347] Python: add change note --- python/ql/lib/change-notes/2024-09-24-std-lib-models.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python/ql/lib/change-notes/2024-09-24-std-lib-models.md diff --git a/python/ql/lib/change-notes/2024-09-24-std-lib-models.md b/python/ql/lib/change-notes/2024-09-24-std-lib-models.md new file mode 100644 index 000000000000..20b522576a30 --- /dev/null +++ b/python/ql/lib/change-notes/2024-09-24-std-lib-models.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added several models of standard library functions and classes. This should make the analysis much more complete in cases where the standard library is not extracted. \ No newline at end of file From 112e7c95fa32f9c0d2931c9948b6db57465d6d82 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 24 Sep 2024 20:58:59 +0200 Subject: [PATCH 027/347] Python: all dict constructor args are relevant --- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 3c23b3929911..ca8b10d8578a 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4219,7 +4219,7 @@ module StdlibPrivate { override predicate propagatesFlow(string input, string output, boolean preservesValue) { exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() | - input = "Argument[0].DictionaryElement[" + key + "]" and + input = "Argument[0..].DictionaryElement[" + key + "]" and output = "ReturnValue.DictionaryElement[" + key + "]" and preservesValue = true ) @@ -4230,7 +4230,7 @@ module StdlibPrivate { preservesValue = true ) or - input = "Argument[0]" and + input = "Argument[0..]" and output = "ReturnValue" and preservesValue = false } From fc2dc28f87c7e5669e240f46fa37dba22123a88f Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Wed, 25 Sep 2024 10:02:31 +0200 Subject: [PATCH 028/347] python: capture flow through comprehensions - add comprehension functions as `DataFlowCallable`s - add comprehension call as `DataFlowCall` - create capture argument node for comprehension calls --- .../new/internal/DataFlowDispatch.qll | 46 +++++++++++++++++++ .../library-tests/dataflow/coverage/test.py | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index 28c1c652df46..d71c32ffc882 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -320,6 +320,9 @@ newtype TDataFlowCallable = // same to keep things easy to reason about (and therefore exclude things that do // not have a definition) exists(func.getDefinition()) + or + // ...scratch that, variable capture requires a callable + exists(Comp c | c.getFunction() = func) } or /** see QLDoc for `DataFlowModuleScope` for why we need this. */ TModule(Module m) or @@ -1382,6 +1385,7 @@ private predicate sameEnclosingCallable(Node node1, Node node2) { // ============================================================================= newtype TDataFlowCall = TNormalCall(CallNode call, Function target, CallType type) { resolveCall(call, target, type) } or + TComprehensionCall(Comp c) or TPotentialLibraryCall(CallNode call) or /** A synthesized call inside a summarized callable */ TSummaryCall( @@ -1468,6 +1472,30 @@ class NormalCall extends ExtractedDataFlowCall, TNormalCall { CallType getCallType() { result = type } } +class ComprehensionCall extends ExtractedDataFlowCall, TComprehensionCall { + Comp c; + Function target; + + ComprehensionCall() { + this = TComprehensionCall(c) and + target = c.getFunction() + } + + Comp getComprehension() { result = c } + + override string toString() { result = "comprehension call" } + + override ControlFlowNode getNode() { result.getNode() = c } + + override Scope getScope() { result = c.getScope() } + + override DataFlowCallable getCallable() { result.(DataFlowFunction).getScope() = target } + + override ArgumentNode getArgument(ArgumentPosition apos) { none() } + + override Location getLocation() { result = c.getLocation() } +} + /** * A potential call to a summarized callable, a `LibraryCallable`. * @@ -1698,6 +1726,24 @@ class CapturedVariablesArgumentNode extends CfgNode, ArgumentNode { } } +class ComprehensionCapturedVariablesArgumentNode extends CfgNode, ArgumentNode { + Comp comp; + + ComprehensionCapturedVariablesArgumentNode() { + node.getNode() = comp and + exists(Function target | target = comp.getFunction() | + target = any(VariableCapture::CapturedVariable v).getACapturingScope() + ) + } + + override string toString() { result = "Capturing closure argument (comp)" } + + override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { + call.(ComprehensionCall).getComprehension() = comp and + pos.isLambdaSelf() + } +} + /** Gets a viable run-time target for the call `call`. */ DataFlowCallable viableCallable(DataFlowCall call) { call instanceof ExtractedDataFlowCall and diff --git a/python/ql/test/library-tests/dataflow/coverage/test.py b/python/ql/test/library-tests/dataflow/coverage/test.py index a2ea9cccd676..511390df6816 100644 --- a/python/ql/test/library-tests/dataflow/coverage/test.py +++ b/python/ql/test/library-tests/dataflow/coverage/test.py @@ -137,7 +137,7 @@ def test_list_comprehension_with_tuple_result(): s = SOURCE ns = NONSOURCE l3 = [(s, ns) for _ in [1]] - SINK(l3[0][0]) # $ MISSING: flow="SOURCE, l:-3 -> l3[0][0]" + SINK(l3[0][0]) # $ flow="SOURCE, l:-3 -> l3[0][0]" SINK_F(l3[0][1]) From 7da2845cad4dfbbdd90cc84d3c394b7734feb1c4 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 25 Sep 2024 16:30:45 +0100 Subject: [PATCH 029/347] Rust: Uncomment two lines from the test that should now behave deterministically. --- rust/ql/test/query-tests/diagnostics/LinesOfCode.expected | 2 +- .../test/query-tests/diagnostics/LinesOfUserCode.expected | 2 +- .../query-tests/diagnostics/LinesOfUserCodeInFiles.expected | 2 +- rust/ql/test/query-tests/diagnostics/SummaryStats.expected | 6 +++--- rust/ql/test/query-tests/diagnostics/main.rs | 2 +- rust/ql/test/query-tests/diagnostics/my_macro.rs | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected b/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected index 035a74975be8..d6a21ebb49cf 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected @@ -1 +1 @@ -| 48 | +| 49 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected index 035a74975be8..d6a21ebb49cf 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected @@ -1 +1 @@ -| 48 | +| 49 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected index 2be3f73088ca..dde3c7fe35a7 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected @@ -1,6 +1,6 @@ | my_struct.rs:0:0:0:0 | my_struct.rs | 21 | +| main.rs:0:0:0:0 | main.rs | 8 | | my_macro.rs:0:0:0:0 | my_macro.rs | 8 | -| main.rs:0:0:0:0 | main.rs | 7 | | lib.rs:0:0:0:0 | lib.rs | 6 | | 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 145a18cae05d..f92218d10d21 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -1,5 +1,5 @@ -| Elements extracted | 204 | +| Elements extracted | 211 | | Elements unextracted | 0 | | Files extracted | 6 | -| Lines of code extracted | 48 | -| Lines of user code extracted | 48 | +| Lines of code extracted | 49 | +| Lines of user code extracted | 49 | diff --git a/rust/ql/test/query-tests/diagnostics/main.rs b/rust/ql/test/query-tests/diagnostics/main.rs index 790547c0ff9d..6e0ddf695a3a 100644 --- a/rust/ql/test/query-tests/diagnostics/main.rs +++ b/rust/ql/test/query-tests/diagnostics/main.rs @@ -11,7 +11,7 @@ mod my_macro; // another comment fn main() { // another comment - //println!("Hello, world!"); // currently causes consistency issues + println!("Hello, world!"); my_struct::my_func(); my_macro::my_func(); diff --git a/rust/ql/test/query-tests/diagnostics/my_macro.rs b/rust/ql/test/query-tests/diagnostics/my_macro.rs index 0f85877c3c60..d8a0cc2812bd 100644 --- a/rust/ql/test/query-tests/diagnostics/my_macro.rs +++ b/rust/ql/test/query-tests/diagnostics/my_macro.rs @@ -7,7 +7,7 @@ macro_rules! myMacro { () => { - //println!("Hello, world!"); // currently causes consistency issues + println!("Hello, world!"); }; } From f8ce11b3a7d55ffeb656767239b81d0a19efb8f8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 25 Sep 2024 16:42:08 +0100 Subject: [PATCH 030/347] Rust: Improve File.getNumberOfLinesOfCode(). --- rust/ql/lib/codeql/files/FileSystem.qll | 5 ++++- rust/ql/test/query-tests/diagnostics/LinesOfCode.expected | 2 +- .../ql/test/query-tests/diagnostics/LinesOfUserCode.expected | 2 +- .../query-tests/diagnostics/LinesOfUserCodeInFiles.expected | 2 +- rust/ql/test/query-tests/diagnostics/SummaryStats.expected | 4 ++-- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/rust/ql/lib/codeql/files/FileSystem.qll b/rust/ql/lib/codeql/files/FileSystem.qll index f6926609d685..e4ff5aa0f7ed 100644 --- a/rust/ql/lib/codeql/files/FileSystem.qll +++ b/rust/ql/lib/codeql/files/FileSystem.qll @@ -2,6 +2,7 @@ private import codeql.Locations private import codeql.util.FileSystem +private import codeql.rust.elements.Module private import codeql.rust.elements.SourceFile private import codeql.rust.elements.AstNode @@ -44,7 +45,9 @@ class File extends Container, Impl::File { result = count(int line | exists(AstNode node, Location loc | - not node instanceof SourceFile and loc = node.getLocation() + not node instanceof Module and + not node instanceof SourceFile and + loc = node.getLocation() | node.getFile() = this and line = [loc.getStartLine(), loc.getEndLine()] and diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected b/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected index d6a21ebb49cf..035a74975be8 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected @@ -1 +1 @@ -| 49 | +| 48 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected index d6a21ebb49cf..035a74975be8 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected @@ -1 +1 @@ -| 49 | +| 48 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected index dde3c7fe35a7..2be3f73088ca 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected @@ -1,6 +1,6 @@ | my_struct.rs:0:0:0:0 | my_struct.rs | 21 | -| main.rs:0:0:0:0 | main.rs | 8 | | my_macro.rs:0:0:0:0 | my_macro.rs | 8 | +| main.rs:0:0:0:0 | main.rs | 7 | | lib.rs:0:0:0:0 | lib.rs | 6 | | 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 f92218d10d21..766ca8332fac 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -1,5 +1,5 @@ | Elements extracted | 211 | | Elements unextracted | 0 | | Files extracted | 6 | -| Lines of code extracted | 49 | -| Lines of user code extracted | 49 | +| Lines of code extracted | 48 | +| Lines of user code extracted | 48 | From caca4950e64097a18085e4928da940ad454e2ab1 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 26 Sep 2024 11:10:03 +0100 Subject: [PATCH 031/347] Rust: Revert the change to FileSystem.qll. --- rust/ql/lib/codeql/files/FileSystem.qll | 2 -- rust/ql/test/query-tests/diagnostics/LinesOfCode.expected | 2 +- rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected | 2 +- .../query-tests/diagnostics/LinesOfUserCodeInFiles.expected | 2 +- rust/ql/test/query-tests/diagnostics/SummaryStats.expected | 4 ++-- 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/rust/ql/lib/codeql/files/FileSystem.qll b/rust/ql/lib/codeql/files/FileSystem.qll index e4ff5aa0f7ed..0b9351800ab6 100644 --- a/rust/ql/lib/codeql/files/FileSystem.qll +++ b/rust/ql/lib/codeql/files/FileSystem.qll @@ -2,7 +2,6 @@ private import codeql.Locations private import codeql.util.FileSystem -private import codeql.rust.elements.Module private import codeql.rust.elements.SourceFile private import codeql.rust.elements.AstNode @@ -45,7 +44,6 @@ class File extends Container, Impl::File { result = count(int line | exists(AstNode node, Location loc | - not node instanceof Module and not node instanceof SourceFile and loc = node.getLocation() | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected b/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected index 035a74975be8..d6a21ebb49cf 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected @@ -1 +1 @@ -| 48 | +| 49 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected index 035a74975be8..d6a21ebb49cf 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected @@ -1 +1 @@ -| 48 | +| 49 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected index 2be3f73088ca..dde3c7fe35a7 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected @@ -1,6 +1,6 @@ | my_struct.rs:0:0:0:0 | my_struct.rs | 21 | +| main.rs:0:0:0:0 | main.rs | 8 | | my_macro.rs:0:0:0:0 | my_macro.rs | 8 | -| main.rs:0:0:0:0 | main.rs | 7 | | lib.rs:0:0:0:0 | lib.rs | 6 | | 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 766ca8332fac..f92218d10d21 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -1,5 +1,5 @@ | Elements extracted | 211 | | Elements unextracted | 0 | | Files extracted | 6 | -| Lines of code extracted | 48 | -| Lines of user code extracted | 48 | +| Lines of code extracted | 49 | +| Lines of user code extracted | 49 | From 294092b671a1e909939956c0633eef1ec9065f62 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Fri, 27 Sep 2024 09:44:39 +0200 Subject: [PATCH 032/347] Python: use comprehension function argument For a comprehension `[x for x in l] - `l` is now a legal argument (in DataFlowPublic) - `l` is the argument of the comprehension function (in DataFlowDispatch) - the parameter of the comprehension function is being read rather than `l` (in IterableUnpacking) Thus the read that used to cross callable boundaries is now split into a arg-param edge and a read from that param. --- .../semmle/python/dataflow/new/internal/DataFlowDispatch.qll | 5 ++++- .../semmle/python/dataflow/new/internal/DataFlowPublic.qll | 3 +++ .../python/dataflow/new/internal/IterableUnpacking.qll | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index d71c32ffc882..58fc674f48df 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -1491,7 +1491,10 @@ class ComprehensionCall extends ExtractedDataFlowCall, TComprehensionCall { override DataFlowCallable getCallable() { result.(DataFlowFunction).getScope() = target } - override ArgumentNode getArgument(ArgumentPosition apos) { none() } + override ArgumentNode getArgument(ArgumentPosition apos) { + result.asExpr() = c.getIterable() and + apos.isPositional(0) + } override Location getLocation() { result = c.getLocation() } } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index cb05f3887a3f..fa9e844eda39 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -350,6 +350,9 @@ class ExtractedArgumentNode extends ArgumentNode { or // and self arguments this.asCfgNode() = any(CallNode c).getFunction().(AttrNode).getObject() + or + // for comprehensions, we allow the synthetic `iterable` argument + this.asExpr() = any(Comp c).getIterable() } final override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/IterableUnpacking.qll b/python/ql/lib/semmle/python/dataflow/new/internal/IterableUnpacking.qll index 05b084672529..e83e789c2fbc 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/IterableUnpacking.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/IterableUnpacking.qll @@ -187,7 +187,7 @@ class ForTarget extends ControlFlowNode { ) or exists(Comp comp | - source = comp.getIterable() and + source = comp.getFunction().getArg(0) and this.getNode() = comp.getNthInnerLoop(0).getTarget() ) } From 72530a83129cb9eb985846efe266f970eb349986 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Fri, 27 Sep 2024 12:15:03 +0200 Subject: [PATCH 033/347] Python: use synthetic node for comprehension capture argument We used to use the CfgNode for the comprehension itself. In cases where that is also an argument, say ```python ",".join([x for x in l]) ``` that would be an argument to two different calls causing a dataflow consistency violation. --- .../dataflow/new/internal/DataFlowDispatch.qll | 18 ++++++++++++++---- .../dataflow/new/internal/DataFlowPublic.qll | 4 +++- .../dataflow/new/internal/VariableCapture.qll | 5 +++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index 58fc674f48df..c15f1751edb4 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -1729,24 +1729,34 @@ class CapturedVariablesArgumentNode extends CfgNode, ArgumentNode { } } -class ComprehensionCapturedVariablesArgumentNode extends CfgNode, ArgumentNode { +class ComprehensionCapturedVariablesArgumentNode extends Node, ArgumentNode { Comp comp; ComprehensionCapturedVariablesArgumentNode() { - node.getNode() = comp and + this = TSynthCompCapturedVariablesArgumentNode(comp) and exists(Function target | target = comp.getFunction() | target = any(VariableCapture::CapturedVariable v).getACapturingScope() ) } - override string toString() { result = "Capturing closure argument (comp)" } - override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { call.(ComprehensionCall).getComprehension() = comp and pos.isLambdaSelf() } } +class SynthCompCapturedVariablesArgumentNode extends Node, TSynthCompCapturedVariablesArgumentNode { + Comp comp; + + SynthCompCapturedVariablesArgumentNode() { this = TSynthCompCapturedVariablesArgumentNode(comp) } + + override string toString() { result = "Capturing closure argument (comp)" } + + override Scope getScope() { result = comp.getFunction() } + + override Location getLocation() { result = comp.getLocation() } +} + /** Gets a viable run-time target for the call `call`. */ DataFlowCallable viableCallable(DataFlowCall call) { call instanceof ExtractedDataFlowCall and diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index fa9e844eda39..eca9da797914 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -124,9 +124,11 @@ newtype TNode = /** A synthetic node representing the heap of a function. Used for variable capture. */ TSynthCapturedVariablesParameterNode(Function f) { f = any(VariableCapture::CapturedVariable v).getACapturingScope() and - // TODO: Remove this restriction when adding proper support for captured variables in the body of the function we generate for comprehensions exists(TFunction(f)) } or + TSynthCompCapturedVariablesArgumentNode(Comp comp) { + comp.getFunction() = any(VariableCapture::CapturedVariable v).getACapturingScope() + } or /** An empty, unused node type that exists to prevent unwanted dependencies on data flow nodes. */ TForbiddenRecursionGuard() { none() and diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/VariableCapture.qll b/python/ql/lib/semmle/python/dataflow/new/internal/VariableCapture.qll index 86dcee2bfe36..6cb80881e2a8 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/VariableCapture.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/VariableCapture.qll @@ -127,6 +127,11 @@ module Flow = Shared::Flow; private Flow::ClosureNode asClosureNode(Node n) { result = n.(SynthCaptureNode).getSynthesizedCaptureNode() or + exists(Comp comp | n = TSynthCompCapturedVariablesArgumentNode(comp) | + result.(Flow::ExprNode).getExpr().getNode() = comp + ) + or + // TODO: Should the `Comp`s above be excluded here? result.(Flow::ExprNode).getExpr() = n.(CfgNode).getNode() or result.(Flow::VariableWriteSourceNode).getVariableWrite() = n.(CfgNode).getNode() From 26e58532ee07e5f58ecc05b3f16a13fbcc570d79 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Fri, 27 Sep 2024 12:37:09 -0400 Subject: [PATCH 034/347] Adding tests and updated expected file with false positives to correct. --- .../CWE/CWE-704/WcharCharConversion.cpp | 57 ++++++++++++++++++- .../CWE/CWE-704/WcharCharConversion.expected | 14 +++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-704/WcharCharConversion.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-704/WcharCharConversion.cpp index 909927c6549c..dc2b9f4a9c18 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-704/WcharCharConversion.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-704/WcharCharConversion.cpp @@ -53,4 +53,59 @@ void NonStringFalsePositiveTest2(unsigned char* buffer) { wchar_t *lpWchar = NULL; lpWchar = (LPWSTR)buffer; // Possible False Positive -} \ No newline at end of file +} + +typedef unsigned char BYTE; +using FOO = BYTE*; + +void NonStringFalsePositiveTest3(FOO buffer) +{ + wchar_t *lpWchar = NULL; + lpWchar = (LPWSTR)buffer; // GOOD +} + +#define UNICODE 0x8 + +// assume EMPTY_MACRO is tied to if UNICODE is enabled +#ifdef EMPTY_MACRO +typedef WCHAR* LPTSTR; +#else +typedef char* LPTSTR; +#endif + +void CheckedConversionFalsePositiveTest3(unsigned short flags, LPTSTR buffer) +{ + wchar_t *lpWchar = NULL; + if(flags & UNICODE) + lpWchar = (LPWSTR)buffer; // GOOD + else + lpWchar = (LPWSTR)buffer; // BUG + + if((flags & UNICODE) == 0x8) + lpWchar = (LPWSTR)buffer; // GOOD + else + lpWchar = (LPWSTR)buffer; // BUG + + if((flags & UNICODE) != 0x8) + lpWchar = (LPWSTR)buffer; // BUG + else + lpWchar = (LPWSTR)buffer; // GOOD + + // Bad operator precedence + if(flags & UNICODE == 0x8) + lpWchar = (LPWSTR)buffer; // BUG + else + lpWchar = (LPWSTR)buffer; // BUG + + if((flags & UNICODE) != 0) + lpWchar = (LPWSTR)buffer; // GOOD + else + lpWchar = (LPWSTR)buffer; // BUG + + if((flags & UNICODE) == 0) + lpWchar = (LPWSTR)buffer; // BUG + else + lpWchar = (LPWSTR)buffer; // GOOD + + lpWchar = (LPWSTR)buffer; // BUG +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-704/WcharCharConversion.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-704/WcharCharConversion.expected index 73787d4f6eb9..5aca312c0839 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-704/WcharCharConversion.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-704/WcharCharConversion.expected @@ -3,3 +3,17 @@ | WcharCharConversion.cpp:24:22:24:27 | lpChar | Conversion from char * to wchar_t *. Use of invalid string can lead to undefined behavior. | | WcharCharConversion.cpp:26:23:26:28 | lpChar | Conversion from char * to LPCWSTR. Use of invalid string can lead to undefined behavior. | | WcharCharConversion.cpp:27:17:27:22 | lpChar | Conversion from char * to LPWSTR. Use of invalid string can lead to undefined behavior. | +| WcharCharConversion.cpp:64:20:64:25 | buffer | Conversion from FOO to LPWSTR. Use of invalid string can lead to undefined behavior. | +| WcharCharConversion.cpp:80:21:80:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | +| WcharCharConversion.cpp:82:21:82:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | +| WcharCharConversion.cpp:85:21:85:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | +| WcharCharConversion.cpp:87:21:87:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | +| WcharCharConversion.cpp:90:21:90:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | +| WcharCharConversion.cpp:92:21:92:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | +| WcharCharConversion.cpp:96:21:96:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | +| WcharCharConversion.cpp:98:21:98:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | +| WcharCharConversion.cpp:101:21:101:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | +| WcharCharConversion.cpp:103:21:103:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | +| WcharCharConversion.cpp:106:21:106:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | +| WcharCharConversion.cpp:108:21:108:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | +| WcharCharConversion.cpp:110:20:110:25 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | From cc24f1ed9fb348c563bd53df7521ca6251d42fc2 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Fri, 27 Sep 2024 12:38:22 -0400 Subject: [PATCH 035/347] Modifications to the query to address false positives. --- .../CWE/CWE-704/WcharCharConversion.ql | 78 +++++++++++++++++-- 1 file changed, 73 insertions(+), 5 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql index bfd3324f2a9b..33fcad2cbf6f 100644 --- a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql +++ b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql @@ -13,23 +13,87 @@ */ import cpp +import semmle.code.cpp.controlflow.Guards class WideCharPointerType extends PointerType { WideCharPointerType() { this.getBaseType() instanceof WideCharType } } +/** + * Recurse through types to find any intermediate type or final type + * that suggests the type is unlikely to be a string. + * Specifically looking for any unsigned character, or datatype with name containing "byte" + * or datatype uint8_t. + */ +predicate hasIntermediateType(Type cur, Type targ) { + cur = targ + or + hasIntermediateType(cur.(DerivedType).getBaseType(), targ) + or + hasIntermediateType(cur.(TypedefType).getBaseType(), targ) +} + /** * A type that may also be `CharPointerType`, but that are likely used as arbitrary buffers. */ class UnlikelyToBeAStringType extends Type { UnlikelyToBeAStringType() { - this.(PointerType).getBaseType().(CharType).isUnsigned() or - this.(PointerType).getBaseType().getName().toLowerCase().matches("%byte") or - this.getName().toLowerCase().matches("%byte") or - this.(PointerType).getBaseType().hasName("uint8_t") + exists(Type targ | + targ.(CharType).isUnsigned() or + targ.getName().toLowerCase().matches(["uint8_t", "%byte%"]) + | + hasIntermediateType(this, targ) + ) } } +// Types that can be wide depending on the UNICODE macro +// see https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types +class UnicodeMacroDependentWidthType extends Type { + UnicodeMacroDependentWidthType() { + exists(Type targ | + targ.getName() in [ + "LPCTSTR", + "LPTSTR", + "PCTSTR", + "PTSTR", + "TBYTE", + "TCHAR" + ] + | + hasIntermediateType(this, targ) + ) + } +} + +class UnicodeMacro extends Macro { + UnicodeMacro() { this.getName().toLowerCase().matches("%unicode%") } +} + +class UnicodeMacroInvocation extends MacroInvocation { + UnicodeMacroInvocation() { this.getMacro() instanceof UnicodeMacro } +} + +/** + * Holds when a expression whose type is UnicodeMacroDependentWidthType and + * is observed to be guarded by a check involving a bitwise-and operation + * with a UnicodeMacroInvocation. + * Such expressions are assumed to be checked dynamically, i.e., + * the flag would indicate if UNICODE typing is set correctly to allow + * or disallow a widening cast. + */ +predicate isLikelyDynamicChecked(Expr e, GuardCondition gc) { + e.getType() instanceof UnicodeMacroDependentWidthType and + exists(BitwiseAndExpr bai, UnicodeMacroInvocation umi | bai.getAnOperand() = umi.getExpr() | + // bai == 0 is false when reaching `e.getBasicBlock()`. + // That is, bai != 0 when reaching `e.getBasicBlock()`. + gc.ensuresEq(bai, 0, e.getBasicBlock(), false) + or + // bai == k and k != 0 is true when reaching `e.getBasicBlock()`. + gc.ensuresEq(bai, any(int k | k != 0), e.getBasicBlock(), true) + ) +} + from Expr e1, Cast e2 where e2 = e1.getConversion() and @@ -42,7 +106,11 @@ where not e1.getType() instanceof UnlikelyToBeAStringType and // Avoid castings from 'new' expressions as typically these will be safe // Example: `__Type* ret = reinterpret_cast<__Type*>(New(m_pmo) char[num * sizeof(__Type)]);` - not exists(NewOrNewArrayExpr newExpr | newExpr.getAChild*() = e1) + not exists(NewOrNewArrayExpr newExpr | newExpr.getAChild*() = e1) and + // Avoid cases where the cast is guarded by a check to determine if + // unicode encoding is enabled in such a way to disallow the dangerous cast + // at runtime. + not isLikelyDynamicChecked(e1, _) select e1, "Conversion from " + e1.getType().toString() + " to " + e2.getType().toString() + ". Use of invalid string can lead to undefined behavior." From 92c8d39ba3d5c17220b77425636366266b968f5b Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Fri, 27 Sep 2024 12:39:50 -0400 Subject: [PATCH 036/347] Updating expected file, false positives now resolved. --- .../Security/CWE/CWE-704/WcharCharConversion.expected | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-704/WcharCharConversion.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-704/WcharCharConversion.expected index 5aca312c0839..9b34966aa87f 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-704/WcharCharConversion.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-704/WcharCharConversion.expected @@ -3,17 +3,11 @@ | WcharCharConversion.cpp:24:22:24:27 | lpChar | Conversion from char * to wchar_t *. Use of invalid string can lead to undefined behavior. | | WcharCharConversion.cpp:26:23:26:28 | lpChar | Conversion from char * to LPCWSTR. Use of invalid string can lead to undefined behavior. | | WcharCharConversion.cpp:27:17:27:22 | lpChar | Conversion from char * to LPWSTR. Use of invalid string can lead to undefined behavior. | -| WcharCharConversion.cpp:64:20:64:25 | buffer | Conversion from FOO to LPWSTR. Use of invalid string can lead to undefined behavior. | -| WcharCharConversion.cpp:80:21:80:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | | WcharCharConversion.cpp:82:21:82:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | -| WcharCharConversion.cpp:85:21:85:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | | WcharCharConversion.cpp:87:21:87:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | | WcharCharConversion.cpp:90:21:90:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | -| WcharCharConversion.cpp:92:21:92:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | | WcharCharConversion.cpp:96:21:96:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | | WcharCharConversion.cpp:98:21:98:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | -| WcharCharConversion.cpp:101:21:101:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | | WcharCharConversion.cpp:103:21:103:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | | WcharCharConversion.cpp:106:21:106:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | -| WcharCharConversion.cpp:108:21:108:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | | WcharCharConversion.cpp:110:20:110:25 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. | From b73fe0ba0aaf86c10090e681a9080a7eab1ed483 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Fri, 27 Sep 2024 12:41:45 -0400 Subject: [PATCH 037/347] Adding change log --- .../2024-09-26-wcharcharconversion-false-positives.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 cpp/ql/src/change-notes/2024-09-26-wcharcharconversion-false-positives.md diff --git a/cpp/ql/src/change-notes/2024-09-26-wcharcharconversion-false-positives.md b/cpp/ql/src/change-notes/2024-09-26-wcharcharconversion-false-positives.md new file mode 100644 index 000000000000..7398013e9ef0 --- /dev/null +++ b/cpp/ql/src/change-notes/2024-09-26-wcharcharconversion-false-positives.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Removed false positives caused by failure to detect byte arrays +* Removed false positives caused by failure to recognize dynamic checks prior to possible dangerous widening \ No newline at end of file From e73d1c7b76c0466ceb717b1fcd9037beed9ab856 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 26 Sep 2024 14:14:46 +0200 Subject: [PATCH 038/347] C++: Add more macro expansion tests --- .../inmacroexpansion.expected | 169 ++++++++++++++++-- .../macros/inmacroexpansion/test.cpp | 81 ++++++++- 2 files changed, 235 insertions(+), 15 deletions(-) diff --git a/cpp/ql/test/library-tests/macros/inmacroexpansion/inmacroexpansion.expected b/cpp/ql/test/library-tests/macros/inmacroexpansion/inmacroexpansion.expected index 7ffe4cb03e9f..f8eff955d47c 100644 --- a/cpp/ql/test/library-tests/macros/inmacroexpansion/inmacroexpansion.expected +++ b/cpp/ql/test/library-tests/macros/inmacroexpansion/inmacroexpansion.expected @@ -2,25 +2,168 @@ | file://:0:0:0:0 | (unnamed parameter 0) | false | | file://:0:0:0:0 | __super | false | | file://:0:0:0:0 | __va_list_tag | false | +| file://:0:0:0:0 | decltype([...](...){...}) | false | | file://:0:0:0:0 | operator= | false | | file://:0:0:0:0 | operator= | false | | test.cpp:0:0:0:0 | test.cpp | false | -| test.cpp:2:1:2:61 | #define FOO class S{int i; void f(void) { int j; return; } }; | false | +| test.cpp:2:1:2:68 | #define CLASS_DECL class S{int i; void f(void) { int j; return; } }; | false | | test.cpp:4:1:4:1 | S | false | | test.cpp:4:1:4:1 | declaration of S | false | | test.cpp:4:1:4:1 | declaration of operator= | false | | test.cpp:4:1:4:1 | declaration of operator= | false | | test.cpp:4:1:4:1 | operator= | false | | test.cpp:4:1:4:1 | operator= | false | -| test.cpp:4:1:4:3 | FOO | false | -| test.cpp:4:1:4:3 | S | false | -| test.cpp:4:1:4:3 | declaration | true | -| test.cpp:4:1:4:3 | definition of S | true | -| test.cpp:4:1:4:3 | definition of f | true | -| test.cpp:4:1:4:3 | definition of i | true | -| test.cpp:4:1:4:3 | definition of j | true | -| test.cpp:4:1:4:3 | f | false | -| test.cpp:4:1:4:3 | i | false | -| test.cpp:4:1:4:3 | j | true | -| test.cpp:4:1:4:3 | return ... | true | -| test.cpp:4:1:4:3 | { ... } | true | +| test.cpp:4:1:4:10 | CLASS_DECL | false | +| test.cpp:4:1:4:10 | S | false | +| test.cpp:4:1:4:10 | declaration | true | +| test.cpp:4:1:4:10 | definition of S | true | +| test.cpp:4:1:4:10 | definition of f | true | +| test.cpp:4:1:4:10 | definition of i | true | +| test.cpp:4:1:4:10 | definition of j | true | +| test.cpp:4:1:4:10 | f | false | +| test.cpp:4:1:4:10 | i | false | +| test.cpp:4:1:4:10 | j | true | +| test.cpp:4:1:4:10 | return ... | true | +| test.cpp:4:1:4:10 | { ... } | true | +| test.cpp:6:1:6:42 | #define FUNCTION_DECL void f1() { int k; } | false | +| test.cpp:8:1:8:13 | FUNCTION_DECL | false | +| test.cpp:8:1:8:13 | declaration | true | +| test.cpp:8:1:8:13 | definition of f1 | true | +| test.cpp:8:1:8:13 | definition of k | true | +| test.cpp:8:1:8:13 | f1 | false | +| test.cpp:8:1:8:13 | k | true | +| test.cpp:8:1:8:13 | return ... | true | +| test.cpp:8:1:8:13 | { ... } | true | +| test.cpp:10:1:10:33 | #define VARIABLE_DECL int v1 = 1; | false | +| test.cpp:12:1:12:13 | 1 | true | +| test.cpp:12:1:12:13 | VARIABLE_DECL | false | +| test.cpp:12:1:12:13 | definition of v1 | true | +| test.cpp:12:1:12:13 | initializer for v1 | true | +| test.cpp:12:1:12:13 | v1 | true | +| test.cpp:14:1:14:35 | #define TYPE_DECL_1 typedef int t1; | false | +| test.cpp:16:1:16:11 | TYPE_DECL_1 | false | +| test.cpp:16:1:16:11 | declaration of t1 | true | +| test.cpp:16:1:16:11 | t1 | false | +| test.cpp:18:1:18:35 | #define TYPE_DECL_2 using t2 = int; | false | +| test.cpp:20:1:20:11 | TYPE_DECL_2 | false | +| test.cpp:20:1:20:11 | declaration of t2 | true | +| test.cpp:20:1:20:11 | t2 | false | +| test.cpp:22:1:22:47 | #define NAMESPACE_DECL namespace ns { int v2; } | false | +| test.cpp:24:1:24:14 | NAMESPACE_DECL | false | +| test.cpp:24:1:24:14 | definition of v2 | true | +| test.cpp:24:1:24:14 | ns | false | +| test.cpp:24:1:24:14 | ns | false | +| test.cpp:24:1:24:14 | v2 | true | +| test.cpp:26:1:26:43 | #define USING_NAMESPACE using namespace ns; | false | +| test.cpp:28:1:28:34 | #define ENUM_CONSTANT enum_element | false | +| test.cpp:30:12:30:21 | definition of enum_class | false | +| test.cpp:30:12:30:21 | enum_class | false | +| test.cpp:30:25:30:37 | ENUM_CONSTANT | false | +| test.cpp:30:25:30:37 | enum_element | false | +| test.cpp:32:1:32:41 | #define USING_ENUM using enum enum_class; | false | +| test.cpp:34:1:34:10 | USING_ENUM | false | +| test.cpp:34:1:34:10 | using enum enum_class | false | +| test.cpp:36:1:36:48 | #define STATIC_ASSERT static_assert(1 == 1, ""); | false | +| test.cpp:38:1:38:13 | 1 | true | +| test.cpp:38:1:38:13 | 1 | true | +| test.cpp:38:1:38:13 | ... == ... | true | +| test.cpp:38:1:38:13 | STATIC_ASSERT | false | +| test.cpp:38:1:38:13 | static_assert(..., "") | false | +| test.cpp:40:1:40:42 | #define ATTRIBUTE [[nodiscard("reason1")]] | false | +| test.cpp:42:1:42:9 | ATTRIBUTE | false | +| test.cpp:42:1:42:9 | nodiscard | false | +| test.cpp:42:1:42:9 | reason1 | false | +| test.cpp:42:1:42:9 | reason1 | true | +| test.cpp:43:5:43:6 | declaration of f2 | false | +| test.cpp:43:5:43:6 | f2 | false | +| test.cpp:45:1:45:31 | #define ATTRIBUTE_ARG "reason2" | false | +| test.cpp:47:3:47:11 | nodiscard | false | +| test.cpp:47:13:47:25 | ATTRIBUTE_ARG | false | +| test.cpp:47:13:47:25 | reason2 | false | +| test.cpp:47:13:47:25 | reason2 | true | +| test.cpp:48:5:48:6 | declaration of f3 | false | +| test.cpp:48:5:48:6 | f3 | false | +| test.cpp:50:1:50:16 | #define TYPE int | false | +| test.cpp:52:1:52:4 | TYPE | false | +| test.cpp:52:6:52:7 | definition of v3 | true | +| test.cpp:52:6:52:7 | v3 | true | +| test.cpp:52:11:52:11 | 1 | false | +| test.cpp:52:11:52:11 | initializer for v3 | false | +| test.cpp:54:1:54:29 | #define DERIVATION : public S | false | +| test.cpp:56:7:56:7 | T | false | +| test.cpp:56:7:56:7 | T | false | +| test.cpp:56:7:56:7 | declaration of T | false | +| test.cpp:56:7:56:7 | declaration of operator= | false | +| test.cpp:56:7:56:7 | declaration of operator= | false | +| test.cpp:56:7:56:7 | definition of T | false | +| test.cpp:56:7:56:7 | operator= | false | +| test.cpp:56:7:56:7 | operator= | false | +| test.cpp:56:9:56:18 | DERIVATION | false | +| test.cpp:56:9:56:18 | derivation | false | +| test.cpp:58:1:58:31 | #define FRIEND friend int f3(); | false | +| test.cpp:60:7:60:7 | U | false | +| test.cpp:60:7:60:7 | declaration of operator= | false | +| test.cpp:60:7:60:7 | declaration of operator= | false | +| test.cpp:60:7:60:7 | definition of U | false | +| test.cpp:60:7:60:7 | operator= | false | +| test.cpp:60:7:60:7 | operator= | false | +| test.cpp:61:3:61:8 | FRIEND | false | +| test.cpp:61:3:61:8 | U's friend | false | +| test.cpp:64:1:64:24 | #define NAME_QUAL_1 ns:: | false | +| test.cpp:66:1:66:22 | #define NAME_QUAL_2 ns | false | +| test.cpp:68:1:68:19 | #define LOCAL_VAR m | false | +| test.cpp:70:6:70:7 | definition of f4 | false | +| test.cpp:70:6:70:7 | f4 | false | +| test.cpp:70:11:76:1 | { ... } | false | +| test.cpp:71:5:71:8 | ns:: | false | +| test.cpp:71:5:71:15 | NAME_QUAL_1 | false | +| test.cpp:71:5:71:18 | v2 | false | +| test.cpp:71:5:71:19 | ExprStmt | false | +| test.cpp:72:5:72:8 | ns:: | false | +| test.cpp:72:5:72:15 | NAME_QUAL_2 | false | +| test.cpp:72:5:72:21 | v2 | false | +| test.cpp:72:5:72:22 | ExprStmt | false | +| test.cpp:73:5:73:23 | declaration | false | +| test.cpp:73:9:73:17 | LOCAL_VAR | false | +| test.cpp:73:9:73:17 | definition of m | true | +| test.cpp:73:9:73:17 | m | true | +| test.cpp:73:20:73:22 | 42 | false | +| test.cpp:73:20:73:22 | initializer for m | false | +| test.cpp:74:5:74:41 | declaration | false | +| test.cpp:74:10:74:10 | definition of l | false | +| test.cpp:74:10:74:10 | l | false | +| test.cpp:74:13:74:40 | [...](...){...} | false | +| test.cpp:74:13:74:40 | initializer for l | false | +| test.cpp:74:13:74:40 | {...} | false | +| test.cpp:74:14:74:14 | (unnamed constructor) | false | +| test.cpp:74:14:74:14 | (unnamed constructor) | false | +| test.cpp:74:14:74:14 | (unnamed constructor) | false | +| test.cpp:74:14:74:14 | declaration of (unnamed constructor) | false | +| test.cpp:74:14:74:14 | declaration of (unnamed constructor) | false | +| test.cpp:74:14:74:14 | definition of (unnamed constructor) | false | +| test.cpp:74:14:74:14 | definition of operator= | false | +| test.cpp:74:14:74:14 | operator= | false | +| test.cpp:74:15:74:15 | definition of m | false | +| test.cpp:74:15:74:15 | m | false | +| test.cpp:74:15:74:15 | m | false | +| test.cpp:74:15:74:23 | LOCAL_VAR | false | +| test.cpp:74:15:74:23 | m | true | +| test.cpp:74:25:74:25 | definition of operator() | false | +| test.cpp:74:25:74:25 | operator() | false | +| test.cpp:74:28:74:40 | { ... } | false | +| test.cpp:74:30:74:38 | return ... | false | +| test.cpp:74:37:74:37 | (int)... | false | +| test.cpp:75:5:75:5 | (const lambda [] type at line 74, col. 14)... | false | +| test.cpp:75:5:75:5 | l | false | +| test.cpp:75:5:75:8 | ExprStmt | false | +| test.cpp:75:6:75:6 | call to operator() | false | +| test.cpp:76:1:76:1 | return ... | false | +| test.cpp:78:1:78:15 | #define ID(x) x | false | +| test.cpp:79:1:79:23 | #define NESTED(x) ID(x) | false | +| test.cpp:80:5:80:6 | definition of v4 | false | +| test.cpp:80:5:80:6 | v4 | false | +| test.cpp:80:10:80:18 | ID(x) | false | +| test.cpp:80:10:80:18 | NESTED(x) | false | +| test.cpp:80:17:80:17 | 1 | true | +| test.cpp:80:17:80:17 | initializer for v4 | true | +| test.cpp:82:1:82:39 | // semmle-extractor-options: -std=c++20 | false | diff --git a/cpp/ql/test/library-tests/macros/inmacroexpansion/test.cpp b/cpp/ql/test/library-tests/macros/inmacroexpansion/test.cpp index 7cc1d581a0a9..22e55b17f5a3 100644 --- a/cpp/ql/test/library-tests/macros/inmacroexpansion/test.cpp +++ b/cpp/ql/test/library-tests/macros/inmacroexpansion/test.cpp @@ -1,5 +1,82 @@ -#define FOO class S{int i; void f(void) { int j; return; } }; +#define CLASS_DECL class S{int i; void f(void) { int j; return; } }; -FOO +CLASS_DECL +#define FUNCTION_DECL void f1() { int k; } + +FUNCTION_DECL + +#define VARIABLE_DECL int v1 = 1; + +VARIABLE_DECL + +#define TYPE_DECL_1 typedef int t1; + +TYPE_DECL_1 + +#define TYPE_DECL_2 using t2 = int; + +TYPE_DECL_2 + +#define NAMESPACE_DECL namespace ns { int v2; } + +NAMESPACE_DECL + +#define USING_NAMESPACE using namespace ns; + +#define ENUM_CONSTANT enum_element + +enum class enum_class { ENUM_CONSTANT }; + +#define USING_ENUM using enum enum_class; + +USING_ENUM + +#define STATIC_ASSERT static_assert(1 == 1, ""); + +STATIC_ASSERT + +#define ATTRIBUTE [[nodiscard("reason1")]] + +ATTRIBUTE +int f2(); + +#define ATTRIBUTE_ARG "reason2" + +[[nodiscard(ATTRIBUTE_ARG)]] +int f3(); + +#define TYPE int + +TYPE v3 = 1; + +#define DERIVATION : public S + +class T DERIVATION {}; + +#define FRIEND friend int f3(); + +class U { + FRIEND +}; + +#define NAME_QUAL_1 ns:: + +#define NAME_QUAL_2 ns + +#define LOCAL_VAR m + +void f4() { + NAME_QUAL_1 v2; + NAME_QUAL_2 :: v2; + int LOCAL_VAR = 42; + auto l = [LOCAL_VAR]() { return m; }; + l(); +} + +#define ID(x) x +#define NESTED(x) ID(x) +int v4 = NESTED(1); + +// semmle-extractor-options: -std=c++20 From d4ea62edec413cd9120cc11ef8f8ae593b17e0b0 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 30 Sep 2024 09:01:29 +0200 Subject: [PATCH 039/347] Python: flow through yield - add yield as a dataflow return - replace comprehension store step with a store step to the yield --- .../new/internal/DataFlowDispatch.qll | 7 +++- .../dataflow/new/internal/DataFlowPrivate.qll | 35 +++++++++++++++++-- .../library-tests/dataflow/coverage/test.py | 4 +-- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index c15f1751edb4..fbad70536c7a 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -1755,6 +1755,8 @@ class SynthCompCapturedVariablesArgumentNode extends Node, TSynthCompCapturedVar override Scope getScope() { result = comp.getFunction() } override Location getLocation() { result = comp.getLocation() } + + Comp getComprehension() { result = comp } } /** Gets a viable run-time target for the call `call`. */ @@ -1796,7 +1798,10 @@ abstract class ReturnNode extends Node { /** A data flow node that represents a value returned by a callable. */ class ExtractedReturnNode extends ReturnNode, CfgNode { // See `TaintTrackingImplementation::returnFlowStep` - ExtractedReturnNode() { node = any(Return ret).getValue().getAFlowNode() } + ExtractedReturnNode() { + node = any(Return ret).getValue().getAFlowNode() or + node = any(Yield yield).getAFlowNode() + } override ReturnKind getKind() { any() } } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 218dbdae3025..efe039dc7b81 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -168,6 +168,37 @@ private predicate synthDictSplatArgumentNodeStoreStep( ) } +private predicate yieldStoreStep(Node nodeFrom, Content c, Node nodeTo) { + exists(Yield yield, Function func | + nodeTo.asCfgNode() = yield.getAFlowNode() and + nodeFrom.asCfgNode() = yield.getValue().getAFlowNode() and + func.containsInScope(yield) + | + exists(Comp comp | func = comp.getFunction() | + ( + comp instanceof ListComp or + comp instanceof GeneratorExp + ) and + c instanceof ListElementContent + or + comp instanceof SetComp and + c instanceof SetElementContent + or + comp instanceof DictComp and + c instanceof DictionaryElementContent + ) + or + not exists(Comp comp | func = comp.getFunction()) and + ( + c instanceof ListElementContent + or + c instanceof SetElementContent + or + c instanceof DictionaryElementContent + ) + ) +} + /** * Ensures that the a `**kwargs` parameter will not contain elements with names of * keyword parameters. @@ -668,8 +699,6 @@ predicate storeStep(Node nodeFrom, ContentSet c, Node nodeTo) { or setStoreStep(nodeFrom, c, nodeTo) or - comprehensionStoreStep(nodeFrom, c, nodeTo) - or attributeStoreStep(nodeFrom, c, nodeTo) or matchStoreStep(nodeFrom, c, nodeTo) @@ -683,6 +712,8 @@ predicate storeStep(Node nodeFrom, ContentSet c, Node nodeTo) { or synthDictSplatArgumentNodeStoreStep(nodeFrom, c, nodeTo) or + yieldStoreStep(nodeFrom, c, nodeTo) + or VariableCapture::storeStep(nodeFrom, c, nodeTo) } diff --git a/python/ql/test/library-tests/dataflow/coverage/test.py b/python/ql/test/library-tests/dataflow/coverage/test.py index 511390df6816..64c500b5b693 100644 --- a/python/ql/test/library-tests/dataflow/coverage/test.py +++ b/python/ql/test/library-tests/dataflow/coverage/test.py @@ -245,7 +245,7 @@ def gen(x): def test_yield(): g = gen(SOURCE) - SINK(next(g)) #$ MISSING:flow="SOURCE, l:-1 -> next()" + SINK(next(g)) #$ flow="SOURCE, l:-1 -> next(..)" def gen_from(x): @@ -260,7 +260,7 @@ def test_yield_from(): # a statement rather than an expression, but related to generators def test_for(): for x in gen(SOURCE): - SINK(x) #$ MISSING:flow="SOURCE, l:-1 -> x" + SINK(x) #$ flow="SOURCE, l:-1 -> x" # 6.2.9.1. Generator-iterator methods From 310819d39282d181272d7fe8a3bc350d0cdc056d Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 30 Sep 2024 10:31:36 +0200 Subject: [PATCH 040/347] Python: fix dataflow inconsistencies - adjust scope of argument, the argument is outside the called function - add missing post-update nodes for the new arguments --- .../dataflow/new/internal/DataFlowDispatch.qll | 14 +++++++++++++- .../dataflow/new/internal/DataFlowPrivate.qll | 11 +++++++++++ .../dataflow/new/internal/DataFlowPublic.qll | 6 ++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index fbad70536c7a..29c5f4e26272 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -1752,13 +1752,25 @@ class SynthCompCapturedVariablesArgumentNode extends Node, TSynthCompCapturedVar override string toString() { result = "Capturing closure argument (comp)" } - override Scope getScope() { result = comp.getFunction() } + override Scope getScope() { result = comp.getScope() } override Location getLocation() { result = comp.getLocation() } Comp getComprehension() { result = comp } } +class SynthCompCapturedVariablesArgumentPostUpdateNode extends PostUpdateNodeImpl, + TSynthCompCapturedVariablesArgumentPostUpdateNode +{ + Comp comp; + + SynthCompCapturedVariablesArgumentPostUpdateNode() { + this = TSynthCompCapturedVariablesArgumentPostUpdateNode(comp) + } + + override Node getPreUpdateNode() { result = TSynthCompCapturedVariablesArgumentNode(comp) } +} + /** Gets a viable run-time target for the call `call`. */ DataFlowCallable viableCallable(DataFlowCall call) { call instanceof ExtractedDataFlowCall and diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index efe039dc7b81..eb2568300ecb 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -287,6 +287,12 @@ abstract class PostUpdateNodeImpl extends Node { abstract Node getPreUpdateNode(); } +/** + * A post-update node synthesised for an existing control flow node. + * Add to `TSyntheticPostUpdateNode` to get the synthetic post-update node synthesised. + * + * Synthetic post-update nodes for synthetic nodes need to be listed one by one. + */ class SyntheticPostUpdateNode extends PostUpdateNodeImpl, TSyntheticPostUpdateNode { ControlFlowNode node; @@ -301,6 +307,11 @@ class SyntheticPostUpdateNode extends PostUpdateNodeImpl, TSyntheticPostUpdateNo override Location getLocation() { result = node.getLocation() } } +/** + * An existsing control flow node being the post-update node of a synthetic pre-update node. + * + * Synthetic post-update nodes for synthetic nodes need to be listed one by one. + */ class NonSyntheticPostUpdateNode extends PostUpdateNodeImpl, CfgNode { SyntheticPreUpdateNode pre; diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index eca9da797914..b8ce9634cf33 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -71,6 +71,9 @@ newtype TNode = def.getDefiningNode() = node and def.getParameter() = func.getArg(0) ) + or + // the iterable argument to the implicit comprehension function + node.getNode() = any(Comp c).getIterable() } or /** A node representing a global (module-level) variable in a specific module. */ TModuleVariableNode(Module m, GlobalVariable v) { @@ -129,6 +132,9 @@ newtype TNode = TSynthCompCapturedVariablesArgumentNode(Comp comp) { comp.getFunction() = any(VariableCapture::CapturedVariable v).getACapturingScope() } or + TSynthCompCapturedVariablesArgumentPostUpdateNode(Comp comp) { + comp.getFunction() = any(VariableCapture::CapturedVariable v).getACapturingScope() + } or /** An empty, unused node type that exists to prevent unwanted dependencies on data flow nodes. */ TForbiddenRecursionGuard() { none() and From 3ef05a628fe5d3dbf1089f29719c654050db3f51 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 30 Sep 2024 11:56:36 +0200 Subject: [PATCH 041/347] Python: add location to node --- .../python/dataflow/new/internal/DataFlowDispatch.qll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index 29c5f4e26272..31773624aad1 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -1768,6 +1768,12 @@ class SynthCompCapturedVariablesArgumentPostUpdateNode extends PostUpdateNodeImp this = TSynthCompCapturedVariablesArgumentPostUpdateNode(comp) } + override string toString() { result = "[post] Capturing closure argument (comp)" } + + override Scope getScope() { result = comp.getScope() } + + override Location getLocation() { result = comp.getLocation() } + override Node getPreUpdateNode() { result = TSynthCompCapturedVariablesArgumentNode(comp) } } From f9f46f0f983e3988618f1995285f2e6e556e5dfe Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 30 Sep 2024 12:00:38 +0200 Subject: [PATCH 042/347] Python: update test expectations We now have a new callable, yielding new enclosing callables --- .../enclosing-callable/EnclosingCallable.expected | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/ql/test/library-tests/dataflow/enclosing-callable/EnclosingCallable.expected b/python/ql/test/library-tests/dataflow/enclosing-callable/EnclosingCallable.expected index 0a26a2f2cb39..c168ea8c3916 100644 --- a/python/ql/test/library-tests/dataflow/enclosing-callable/EnclosingCallable.expected +++ b/python/ql/test/library-tests/dataflow/enclosing-callable/EnclosingCallable.expected @@ -15,10 +15,10 @@ | generator.py:0:0:0:0 | Module generator | generator.py:1:1:1:23 | ControlFlowNode for FunctionExpr | | generator.py:0:0:0:0 | Module generator | generator.py:1:5:1:18 | ControlFlowNode for generator_func | | generator.py:1:1:1:23 | Function generator_func | generator.py:1:20:1:21 | ControlFlowNode for xs | -| generator.py:1:1:1:23 | Function generator_func | generator.py:2:12:2:26 | ControlFlowNode for .0 | -| generator.py:1:1:1:23 | Function generator_func | generator.py:2:12:2:26 | ControlFlowNode for .0 | | generator.py:1:1:1:23 | Function generator_func | generator.py:2:12:2:26 | ControlFlowNode for ListComp | -| generator.py:1:1:1:23 | Function generator_func | generator.py:2:13:2:13 | ControlFlowNode for Yield | -| generator.py:1:1:1:23 | Function generator_func | generator.py:2:13:2:13 | ControlFlowNode for x | -| generator.py:1:1:1:23 | Function generator_func | generator.py:2:19:2:19 | ControlFlowNode for x | | generator.py:1:1:1:23 | Function generator_func | generator.py:2:24:2:25 | ControlFlowNode for xs | +| generator.py:2:12:2:26 | Function listcomp | generator.py:2:12:2:26 | ControlFlowNode for .0 | +| generator.py:2:12:2:26 | Function listcomp | generator.py:2:12:2:26 | ControlFlowNode for .0 | +| generator.py:2:12:2:26 | Function listcomp | generator.py:2:13:2:13 | ControlFlowNode for Yield | +| generator.py:2:12:2:26 | Function listcomp | generator.py:2:13:2:13 | ControlFlowNode for x | +| generator.py:2:12:2:26 | Function listcomp | generator.py:2:19:2:19 | ControlFlowNode for x | From ded39749a74d7cd2f8f67f2d01e50504867b03b2 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 30 Sep 2024 13:02:20 +0200 Subject: [PATCH 043/347] Python: allow comp arg as argumentnode --- .../semmle/python/dataflow/new/internal/DataFlowDispatch.qll | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index 31773624aad1..aaea0d277233 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -163,6 +163,10 @@ newtype TArgumentPosition = // position, we need to ensure we make these available (these are specified as // parameters in the flow-summary spec) FlowSummaryImpl::ParsePositions::isParsedPositionalParameterPosition(_, index) + or + // the generated function inside a comprehension has a positional argument at index 0 + exists(Comp c) and + index = 0 } or TKeywordArgumentPosition(string name) { exists(any(CallNode c).getArgByName(name)) From ec0bd4494ce5ca2e37511a80ef517b9093a6708c Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 27 Sep 2024 15:00:19 +0200 Subject: [PATCH 044/347] Java: Add overrides to the interpretation of neutral MaD models. --- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 2 +- .../lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll | 2 +- java/ql/src/utils/modeleditor/ModelEditor.qll | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 28be9a61d75a..123e042b6215 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -416,7 +416,7 @@ private predicate elementSpec( or summaryModel(package, type, subtypes, name, signature, ext, _, _, _, _, _) or - neutralModel(package, type, name, signature, _, _) and ext = "" and subtypes = false + neutralModel(package, type, name, signature, _, _) and ext = "" and subtypes = true } private string getNestedName(Type t) { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index feab4b3cec78..b4a2bad48f35 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -34,7 +34,7 @@ module Input implements InputSig { ) { exists(string namespace, string type, string name, string signature | neutralModel(namespace, type, name, signature, kind, provenance) and - c.asCallable() = interpretElement(namespace, type, false, name, signature, "", isExact) + c.asCallable() = interpretElement(namespace, type, true, name, signature, "", isExact) ) } diff --git a/java/ql/src/utils/modeleditor/ModelEditor.qll b/java/ql/src/utils/modeleditor/ModelEditor.qll index d5286e9024a8..016b4664b3b9 100644 --- a/java/ql/src/utils/modeleditor/ModelEditor.qll +++ b/java/ql/src/utils/modeleditor/ModelEditor.qll @@ -77,7 +77,7 @@ class Endpoint extends Callable { predicate isNeutral() { exists(string namespace, string type, string name, string signature | neutralModel(namespace, type, name, signature, _, _) and - this = interpretElement(namespace, type, false, name, signature, "", _) + this = interpretElement(namespace, type, true, name, signature, "", _) ) } From fb07a56de60d183921d25a7fe17f612d6ca20943 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 30 Sep 2024 13:26:59 +0200 Subject: [PATCH 045/347] Python: adjust test expectations --- .../test/library-tests/dataflow/coverage/localFlow.expected | 5 ----- .../test/library-tests/dataflow/regression/dataflow.expected | 1 + python/ql/test/library-tests/dataflow/regression/test.py | 2 +- .../defaultAdditionalTaintStep/test_collections.py | 4 ++-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/python/ql/test/library-tests/dataflow/coverage/localFlow.expected b/python/ql/test/library-tests/dataflow/coverage/localFlow.expected index 1cb2cab49fae..665fb1aa12b8 100644 --- a/python/ql/test/library-tests/dataflow/coverage/localFlow.expected +++ b/python/ql/test/library-tests/dataflow/coverage/localFlow.expected @@ -8,9 +8,4 @@ | test.py:208:1:208:53 | Entry definition for SsaSourceVariable SINK | test.py:210:5:210:8 | ControlFlowNode for SINK | | test.py:208:1:208:53 | Entry definition for SsaSourceVariable SOURCE | test.py:209:25:209:30 | ControlFlowNode for SOURCE | | test.py:209:5:209:5 | ControlFlowNode for x | test.py:210:10:210:10 | ControlFlowNode for x | -| test.py:209:9:209:68 | ControlFlowNode for .0 | test.py:209:9:209:68 | ControlFlowNode for .0 | | test.py:209:9:209:68 | ControlFlowNode for ListComp | test.py:209:5:209:5 | ControlFlowNode for x | -| test.py:209:16:209:16 | ControlFlowNode for v | test.py:209:45:209:45 | ControlFlowNode for v | -| test.py:209:40:209:40 | ControlFlowNode for u | test.py:209:56:209:56 | ControlFlowNode for u | -| test.py:209:51:209:51 | ControlFlowNode for z | test.py:209:67:209:67 | ControlFlowNode for z | -| test.py:209:62:209:62 | ControlFlowNode for y | test.py:209:10:209:10 | ControlFlowNode for y | diff --git a/python/ql/test/library-tests/dataflow/regression/dataflow.expected b/python/ql/test/library-tests/dataflow/regression/dataflow.expected index dfce2c727378..c8ffed514463 100644 --- a/python/ql/test/library-tests/dataflow/regression/dataflow.expected +++ b/python/ql/test/library-tests/dataflow/regression/dataflow.expected @@ -23,3 +23,4 @@ | test.py:195:9:195:14 | ControlFlowNode for SOURCE | test.py:199:14:199:14 | ControlFlowNode for t | | test.py:202:10:202:15 | ControlFlowNode for SOURCE | test.py:204:14:204:14 | ControlFlowNode for i | | test.py:202:10:202:15 | ControlFlowNode for SOURCE | test.py:205:10:205:10 | ControlFlowNode for i | +| test.py:208:12:208:17 | ControlFlowNode for SOURCE | test.py:214:14:214:14 | ControlFlowNode for x | diff --git a/python/ql/test/library-tests/dataflow/regression/test.py b/python/ql/test/library-tests/dataflow/regression/test.py index 80c9c7e5e343..869993a5b643 100644 --- a/python/ql/test/library-tests/dataflow/regression/test.py +++ b/python/ql/test/library-tests/dataflow/regression/test.py @@ -211,4 +211,4 @@ def flow_in_generator(): def flow_from_generator(): for x in flow_in_generator(): - SINK(x) # Flow not found + SINK(x) diff --git a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py index 0e2aae935546..e7ae9b41eda6 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py +++ b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py @@ -61,7 +61,7 @@ def test_access(x, y, z): iter(tainted_list), # $ tainted next(iter(tainted_list)), # $ MISSING: tainted [i for i in tainted_list], # $ tainted - [tainted_list for _i in [1,2,3]], # $ MISSING: tainted + [tainted_list for _i in [1,2,3]], # $ tainted ) a, b, c = tainted_list[0:3] @@ -85,7 +85,7 @@ def test_access_explicit(x, y, z): iter(tainted_list), # $ tainted next(iter(tainted_list)), # $ tainted [i for i in tainted_list], # $ tainted - [tainted_list for i in [1,2,3]], # $ MISSING: tainted + [tainted_list for i in [1,2,3]], # $ tainted [TAINTED_STRING for i in [1,2,3]], # $ tainted [tainted_list], # $ tainted ) From 7392d186bcc9849ca0291d70a17497d1abc9804d Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 30 Sep 2024 13:49:01 +0200 Subject: [PATCH 046/347] Python: use yield step also for taint Using the comprehension store step meant that all comprehensions would receive taint. This because comprehension flow now goes via a callable, meaning they share the return node. --- .../dataflow/new/internal/DataFlowPrivate.qll | 27 +------------------ .../new/internal/TaintTrackingPrivate.qll | 2 +- 2 files changed, 2 insertions(+), 27 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index eb2568300ecb..e70a1fb8b2db 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -168,7 +168,7 @@ private predicate synthDictSplatArgumentNodeStoreStep( ) } -private predicate yieldStoreStep(Node nodeFrom, Content c, Node nodeTo) { +predicate yieldStoreStep(Node nodeFrom, Content c, Node nodeTo) { exists(Yield yield, Function func | nodeTo.asCfgNode() = yield.getAFlowNode() and nodeFrom.asCfgNode() = yield.getValue().getAFlowNode() and @@ -885,31 +885,6 @@ predicate dictClearStep(Node node, DictionaryElementContent c) { ) } -/** Data flows from an element expression in a comprehension to the comprehension. */ -predicate comprehensionStoreStep(CfgNode nodeFrom, Content c, CfgNode nodeTo) { - // Comprehension - // `[x+1 for x in l]` - // nodeFrom is `x+1`, cfg node - // nodeTo is `[x+1 for x in l]`, cfg node - // c denotes list or set or dictionary without index - // - // List - nodeTo.getNode().getNode().(ListComp).getElt() = nodeFrom.getNode().getNode() and - c instanceof ListElementContent - or - // Set - nodeTo.getNode().getNode().(SetComp).getElt() = nodeFrom.getNode().getNode() and - c instanceof SetElementContent - or - // Dictionary - nodeTo.getNode().getNode().(DictComp).getElt() = nodeFrom.getNode().getNode() and - c instanceof DictionaryElementAnyContent - or - // Generator - nodeTo.getNode().getNode().(GeneratorExp).getElt() = nodeFrom.getNode().getNode() and - c instanceof ListElementContent -} - /** * Holds if `nodeFrom` flows into the attribute `c` of `nodeTo` via an attribute assignment. * diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index 572e67c28a9c..e59301bd1ec9 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -188,7 +188,7 @@ predicate containerStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { // TODO: once we have proper flow-summary modeling, we might not need this step any // longer -- but there needs to be a matching read-step for the store-step, and we // don't provide that right now. - DataFlowPrivate::comprehensionStoreStep(nodeFrom, _, nodeTo) + DataFlowPrivate::yieldStoreStep(nodeFrom, _, nodeTo) } /** From a22ea6c1c8809b09e60108570ba3f18568748600 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 30 Sep 2024 14:22:17 +0200 Subject: [PATCH 047/347] Python: use known sanitiser - also adjust test expectations in experimental --- .../query-tests/Security/CWE-022-TarSlip/TarSlip.expected | 3 +++ python/ql/test/query-tests/Security/CWE-022-TarSlip/tarslip.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected index 664807d623d5..97527c300db5 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected @@ -34,7 +34,9 @@ edges | TarSlipImprov.py:142:9:142:13 | ControlFlowNode for entry | TarSlipImprov.py:143:36:143:40 | ControlFlowNode for entry | provenance | | | TarSlipImprov.py:151:14:151:50 | ControlFlowNode for closing() | TarSlipImprov.py:151:55:151:56 | ControlFlowNode for tf | provenance | | | TarSlipImprov.py:151:22:151:49 | ControlFlowNode for Attribute() | TarSlipImprov.py:151:14:151:50 | ControlFlowNode for closing() | provenance | Config | +| TarSlipImprov.py:151:55:151:56 | ControlFlowNode for tf | TarSlipImprov.py:152:13:152:20 | ControlFlowNode for Yield | provenance | | | TarSlipImprov.py:151:55:151:56 | ControlFlowNode for tf | TarSlipImprov.py:152:19:152:20 | ControlFlowNode for tf | provenance | | +| TarSlipImprov.py:152:13:152:20 | ControlFlowNode for Yield | TarSlipImprov.py:157:18:157:40 | ControlFlowNode for py2_tarxz() | provenance | | | TarSlipImprov.py:152:19:152:20 | ControlFlowNode for tf | TarSlipImprov.py:157:18:157:40 | ControlFlowNode for py2_tarxz() | provenance | | | TarSlipImprov.py:157:9:157:14 | ControlFlowNode for tar_cm | TarSlipImprov.py:162:20:162:23 | ControlFlowNode for tarc | provenance | | | TarSlipImprov.py:157:18:157:40 | ControlFlowNode for py2_tarxz() | TarSlipImprov.py:157:9:157:14 | ControlFlowNode for tar_cm | provenance | | @@ -131,6 +133,7 @@ nodes | TarSlipImprov.py:151:14:151:50 | ControlFlowNode for closing() | semmle.label | ControlFlowNode for closing() | | TarSlipImprov.py:151:22:151:49 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:151:55:151:56 | ControlFlowNode for tf | semmle.label | ControlFlowNode for tf | +| TarSlipImprov.py:152:13:152:20 | ControlFlowNode for Yield | semmle.label | ControlFlowNode for Yield | | TarSlipImprov.py:152:19:152:20 | ControlFlowNode for tf | semmle.label | ControlFlowNode for tf | | TarSlipImprov.py:157:9:157:14 | ControlFlowNode for tar_cm | semmle.label | ControlFlowNode for tar_cm | | TarSlipImprov.py:157:18:157:40 | ControlFlowNode for py2_tarxz() | semmle.label | ControlFlowNode for py2_tarxz() | diff --git a/python/ql/test/query-tests/Security/CWE-022-TarSlip/tarslip.py b/python/ql/test/query-tests/Security/CWE-022-TarSlip/tarslip.py index b9ca0e8e9440..2c06d01adfd5 100644 --- a/python/ql/test/query-tests/Security/CWE-022-TarSlip/tarslip.py +++ b/python/ql/test/query-tests/Security/CWE-022-TarSlip/tarslip.py @@ -46,7 +46,7 @@ #Sanitize members def safemembers(members): for info in members: - if badpath(info): + if os.path.isabs(info.name) or ".." in info.name: raise yield info From 0459d136d3d9c24b2b7a04f866d27b9f696e02fe Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 30 Sep 2024 13:21:14 +0200 Subject: [PATCH 048/347] Java: Remove neutral model for Object.toString. --- java/ql/lib/ext/java.lang.model.yml | 1 - java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index c0c0905a7a43..6fc2b8487980 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -207,7 +207,6 @@ extensions: - ["java.lang", "Object", "equals", "(Object)", "summary", "manual"] - ["java.lang", "Object", "getClass", "()", "summary", "manual"] - ["java.lang", "Object", "hashCode", "()", "summary", "manual"] - - ["java.lang", "Object", "toString", "()", "summary", "manual"] - ["java.lang", "Runtime", "getRuntime", "()", "summary", "manual"] - ["java.lang", "String", "compareTo", "(String)", "summary", "manual"] - ["java.lang", "String", "contains", "(CharSequence)", "summary", "manual"] diff --git a/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected b/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected index f289ad7feb7b..b5e3960f1b4d 100644 --- a/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected +++ b/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected @@ -1,3 +1,4 @@ +| java.lang.Object#toString() | no manual model | | java.lang.Runnable#run() | no manual model | | java.util.Comparator#comparing(Function) | no manual model | | java.util.function.BiConsumer#accept(Object,Object) | no manual model | From a8f55d93cbdd2382fcdc3ef1c314f3d71570dad9 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 30 Sep 2024 15:23:27 +0200 Subject: [PATCH 049/347] C#: Add overrides to the interpretation of neutral MaD models. --- .../lib/semmle/code/csharp/dataflow/internal/ExternalFlow.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ExternalFlow.qll index 4ac73cae9e9f..ccc0a333b9e7 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ExternalFlow.qll @@ -318,7 +318,7 @@ private predicate elementSpec( or summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) or - neutralModel(namespace, type, name, signature, _, _) and ext = "" and subtypes = false + neutralModel(namespace, type, name, signature, _, _) and ext = "" and subtypes = true } private predicate elementSpec( @@ -602,7 +602,7 @@ private predicate interpretSummary( predicate interpretNeutral(UnboundCallable c, string kind, string provenance) { exists(string namespace, string type, string name, string signature | neutralModel(namespace, type, name, signature, kind, provenance) and - c = interpretElement(namespace, type, false, name, signature, "") + c = interpretElement(namespace, type, true, name, signature, "") ) } From 438e6641167180e69b12833019c2adf3812a812e Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 30 Sep 2024 15:43:19 +0200 Subject: [PATCH 050/347] Python: add missing qldoc More doc is needed, but this should turn the tests green --- .../lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index b8ce9634cf33..085eed843eff 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -129,9 +129,11 @@ newtype TNode = f = any(VariableCapture::CapturedVariable v).getACapturingScope() and exists(TFunction(f)) } or + /** A synthetic node representing the values of variables captured by a comprehension. */ TSynthCompCapturedVariablesArgumentNode(Comp comp) { comp.getFunction() = any(VariableCapture::CapturedVariable v).getACapturingScope() } or + /** A synthetic node representing the values of variables captured by a comprehension after the output has been computed. */ TSynthCompCapturedVariablesArgumentPostUpdateNode(Comp comp) { comp.getFunction() = any(VariableCapture::CapturedVariable v).getACapturingScope() } or From dacc0ab8fe64b190ae3f11e664aeabb648ec4020 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 30 Sep 2024 16:06:30 +0200 Subject: [PATCH 051/347] Python: docs and a simplification --- .../new/internal/DataFlowDispatch.qll | 37 +++++++------------ .../dataflow/new/internal/DataFlowPrivate.qll | 10 +++++ 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index aaea0d277233..b1db806d343e 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -318,14 +318,10 @@ newtype TDataFlowCallable = * class instantiations, and (in the future) special methods. */ TFunction(Function func) { - // For generators/list-comprehensions we create a synthetic function. In the - // points-to call-graph these were not considered callable, and instead we added - // data-flow steps (read/write) for these. As an easy solution for now, we do the - // same to keep things easy to reason about (and therefore exclude things that do - // not have a definition) + // Functions with an explicit definition exists(func.getDefinition()) or - // ...scratch that, variable capture requires a callable + // For generators/list-comprehensions we create a synthetic function. exists(Comp c | c.getFunction() = func) } or /** see QLDoc for `DataFlowModuleScope` for why we need this. */ @@ -1389,6 +1385,7 @@ private predicate sameEnclosingCallable(Node node1, Node node2) { // ============================================================================= newtype TDataFlowCall = TNormalCall(CallNode call, Function target, CallType type) { resolveCall(call, target, type) } or + /** A call to the generated function inside a comprhension */ TComprehensionCall(Comp c) or TPotentialLibraryCall(CallNode call) or /** A synthesized call inside a summarized callable */ @@ -1476,6 +1473,7 @@ class NormalCall extends ExtractedDataFlowCall, TNormalCall { CallType getCallType() { result = type } } +/** A call to the generated function inside a comprhension */ class ComprehensionCall extends ExtractedDataFlowCall, TComprehensionCall { Comp c; Function target; @@ -1733,23 +1731,10 @@ class CapturedVariablesArgumentNode extends CfgNode, ArgumentNode { } } -class ComprehensionCapturedVariablesArgumentNode extends Node, ArgumentNode { - Comp comp; - - ComprehensionCapturedVariablesArgumentNode() { - this = TSynthCompCapturedVariablesArgumentNode(comp) and - exists(Function target | target = comp.getFunction() | - target = any(VariableCapture::CapturedVariable v).getACapturingScope() - ) - } - - override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { - call.(ComprehensionCall).getComprehension() = comp and - pos.isLambdaSelf() - } -} - -class SynthCompCapturedVariablesArgumentNode extends Node, TSynthCompCapturedVariablesArgumentNode { +/** A synthetic node representing the values of variables captured by a comprehension. */ +class SynthCompCapturedVariablesArgumentNode extends Node, TSynthCompCapturedVariablesArgumentNode, + ArgumentNode +{ Comp comp; SynthCompCapturedVariablesArgumentNode() { this = TSynthCompCapturedVariablesArgumentNode(comp) } @@ -1761,8 +1746,14 @@ class SynthCompCapturedVariablesArgumentNode extends Node, TSynthCompCapturedVar override Location getLocation() { result = comp.getLocation() } Comp getComprehension() { result = comp } + + override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { + call.(ComprehensionCall).getComprehension() = comp and + pos.isLambdaSelf() + } } +/** A synthetic node representing the values of variables captured by a comprehension after the output has been computed. */ class SynthCompCapturedVariablesArgumentPostUpdateNode extends PostUpdateNodeImpl, TSynthCompCapturedVariablesArgumentPostUpdateNode { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index e70a1fb8b2db..5b2457cd762e 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -168,6 +168,16 @@ private predicate synthDictSplatArgumentNodeStoreStep( ) } +/** + * Holds if `nodeFrom` is the value yielded by the `yield` found at `nodeTo`. + * + * For example, in + * ```python + * for x in l: + * yield x.name + * ``` + * data from `x.name` is stored into the `yield` (and can subsequently be read out of the iterable). + */ predicate yieldStoreStep(Node nodeFrom, Content c, Node nodeTo) { exists(Yield yield, Function func | nodeTo.asCfgNode() = yield.getAFlowNode() and From 5c4b4d644a569f0d6c580d6a8ee22fbd7cec10c5 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 30 Sep 2024 16:27:50 +0200 Subject: [PATCH 052/347] C#: Accept test changes. --- .../dataflow/library/FlowSummaries.expected | 1198 +++++++++++++++++ 1 file changed, 1198 insertions(+) diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index 1e30cae7031f..ccb38ae35f96 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -21187,6 +21187,233 @@ summary | System;WeakReference;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);Argument[this];Argument[0];taint;df-generated | | System;WeakReference;TryGetTarget;(T);Argument[this];ReturnValue;taint;df-generated | neutral +| Dapper;SqlMapper+GridReader;Dispose;();summary;df-generated | +| Dapper;SqlMapper+Identity;Equals;(Dapper.SqlMapper+Identity);summary;df-generated | +| Funq;Container;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Authentication.Cookies;PostConfigureCookieAuthenticationOptions;PostConfigure;(System.String,Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions);summary;df-generated | +| Microsoft.AspNetCore.Authentication.OAuth;OAuthTokenResponse;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Builder;ConfigureHostBuilder;Build;();summary;df-generated | +| Microsoft.AspNetCore.Builder;ConfigureHostBuilder;get_Properties;();summary;df-generated | +| Microsoft.AspNetCore.Builder;WebApplication;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Builder;WebApplication;StartAsync;(System.Threading.CancellationToken);summary;df-generated | +| Microsoft.AspNetCore.Builder;WebApplication;StopAsync;(System.Threading.CancellationToken);summary;df-generated | +| Microsoft.AspNetCore.Builder;WebApplication;get_Services;();summary;df-generated | +| Microsoft.AspNetCore.Components.Authorization;CascadingAuthenticationState;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components.Forms;DataAnnotationsValidator;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components.Forms;FieldIdentifier;Equals;(Microsoft.AspNetCore.Components.Forms.FieldIdentifier);summary;df-generated | +| Microsoft.AspNetCore.Components.Forms;InputBase;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components.Forms;InputFile;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components.Forms;ValidationMessage;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components.Forms;ValidationSummary;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components.RenderTree;Renderer;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components.Rendering;RenderTreeBuilder;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components.Routing;NavLink;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components.Routing;Router;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components.Sections;SectionContent;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components.Sections;SectionOutlet;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components.Server;RevalidatingServerAuthenticationStateProvider;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components.Web;HtmlRenderer;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components;OwningComponentBase;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Components;PersistingComponentStateSubscription;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Connections;ConnectionItems;Contains;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Microsoft.AspNetCore.Connections;ConnectionItems;ContainsKey;(System.Object);summary;df-generated | +| Microsoft.AspNetCore.Connections;ConnectionItems;Remove;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Microsoft.AspNetCore.Connections;ConnectionItems;Remove;(System.Object);summary;df-generated | +| Microsoft.AspNetCore.Connections;ConnectionItems;TryGetValue;(System.Object,System.Object);summary;df-generated | +| Microsoft.AspNetCore.Connections;ConnectionItems;get_Count;();summary;df-generated | +| Microsoft.AspNetCore.Connections;ConnectionItems;get_IsReadOnly;();summary;df-generated | +| Microsoft.AspNetCore.DataProtection;Secret;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Http.Connections;ConnectionOptionsSetup;Configure;(Microsoft.AspNetCore.Http.Connections.ConnectionOptions);summary;df-generated | +| Microsoft.AspNetCore.Http.Features;RequestServicesFeature;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Http;EndpointMetadataCollection+Enumerator;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Http;EndpointMetadataCollection+Enumerator;MoveNext;();summary;df-generated | +| Microsoft.AspNetCore.Http;EndpointMetadataCollection+Enumerator;Reset;();summary;df-generated | +| Microsoft.AspNetCore.Http;EndpointMetadataCollection+Enumerator;get_Current;();summary;df-generated | +| Microsoft.AspNetCore.Http;EndpointMetadataCollection;get_Count;();summary;df-generated | +| Microsoft.AspNetCore.Http;EndpointMetadataCollection;get_Item;(System.Int32);summary;df-generated | +| Microsoft.AspNetCore.Http;FormCollection+Enumerator;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Http;FormCollection+Enumerator;MoveNext;();summary;df-generated | +| Microsoft.AspNetCore.Http;FormCollection+Enumerator;Reset;();summary;df-generated | +| Microsoft.AspNetCore.Http;FormCollection+Enumerator;get_Current;();summary;df-generated | +| Microsoft.AspNetCore.Http;FragmentString;Equals;(Microsoft.AspNetCore.Http.FragmentString);summary;df-generated | +| Microsoft.AspNetCore.Http;HeaderDictionary+Enumerator;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Http;HeaderDictionary+Enumerator;MoveNext;();summary;df-generated | +| Microsoft.AspNetCore.Http;HeaderDictionary+Enumerator;Reset;();summary;df-generated | +| Microsoft.AspNetCore.Http;HeaderDictionary+Enumerator;get_Current;();summary;df-generated | +| Microsoft.AspNetCore.Http;HeaderDictionary;Contains;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Microsoft.AspNetCore.Http;HeaderDictionary;ContainsKey;(System.String);summary;df-generated | +| Microsoft.AspNetCore.Http;HeaderDictionary;Remove;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Microsoft.AspNetCore.Http;HeaderDictionary;Remove;(System.String);summary;df-generated | +| Microsoft.AspNetCore.Http;HeaderDictionary;TryGetValue;(System.String,Microsoft.Extensions.Primitives.StringValues);summary;df-generated | +| Microsoft.AspNetCore.Http;HeaderDictionary;get_Count;();summary;df-generated | +| Microsoft.AspNetCore.Http;HeaderDictionary;get_IsReadOnly;();summary;df-generated | +| Microsoft.AspNetCore.Http;HostString;Equals;(Microsoft.AspNetCore.Http.HostString);summary;df-generated | +| Microsoft.AspNetCore.Http;PathString;Equals;(Microsoft.AspNetCore.Http.PathString);summary;df-generated | +| Microsoft.AspNetCore.Http;QueryCollection+Enumerator;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Http;QueryCollection+Enumerator;MoveNext;();summary;df-generated | +| Microsoft.AspNetCore.Http;QueryCollection+Enumerator;Reset;();summary;df-generated | +| Microsoft.AspNetCore.Http;QueryCollection+Enumerator;get_Current;();summary;df-generated | +| Microsoft.AspNetCore.Http;QueryString;Equals;(Microsoft.AspNetCore.Http.QueryString);summary;df-generated | +| Microsoft.AspNetCore.Identity;RoleManager;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Identity;RoleStoreBase;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Identity;UserManager;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Identity;UserStoreBase;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.Diagnostics;EventData+Enumerator;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.Diagnostics;EventData+Enumerator;MoveNext;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.Diagnostics;EventData+Enumerator;Reset;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.Diagnostics;EventData+Enumerator;get_Current;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.Diagnostics;EventData;get_Count;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.Diagnostics;EventData;get_Item;(System.Int32);summary;df-generated | +| Microsoft.AspNetCore.Mvc.Formatters.Xml;DelegatingEnumerator;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.Formatters.Xml;DelegatingEnumerator;MoveNext;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.Formatters.Xml;DelegatingEnumerator;Reset;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.Formatters.Xml;DelegatingEnumerator;get_Current;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.Formatters.Xml;ProblemDetailsWrapper;GetSchema;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.Formatters.Xml;SerializableErrorWrapper;GetSchema;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.Infrastructure;ConfigureCompatibilityOptions;PostConfigure;(System.String,TOptions);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;ModelMetadataIdentity;Equals;(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding.Validation;ValidationStateDictionary;Contains;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding.Validation;ValidationStateDictionary;ContainsKey;(System.Object);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding.Validation;ValidationStateDictionary;Remove;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding.Validation;ValidationStateDictionary;Remove;(System.Object);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding.Validation;ValidationStateDictionary;TryGetValue;(System.Object,Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationStateEntry);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding.Validation;ValidationStateDictionary;get_Count;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding.Validation;ValidationStateDictionary;get_IsReadOnly;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding.Validation;ValidationStateDictionary;get_Item;(System.Object);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding.Validation;ValidationStateDictionary;get_Keys;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding.Validation;ValidationStateDictionary;get_Values;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding.Validation;ValidationVisitor+StateManager;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;BindingSource;Equals;(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelBindingContext+NestedScope;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelBindingResult;Equals;(Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelMetadata;Equals;(Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary+Enumerator;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary+Enumerator;MoveNext;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary+Enumerator;Reset;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary+Enumerator;get_Current;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary+KeyEnumerator;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary+KeyEnumerator;MoveNext;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary+KeyEnumerator;Reset;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary+KeyEnumerator;get_Current;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary+ValueEnumerator;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary+ValueEnumerator;MoveNext;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary+ValueEnumerator;Reset;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary+ValueEnumerator;get_Current;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary;ContainsKey;(System.String);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary;TryGetValue;(System.String,Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateEntry);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary;get_Count;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary;get_Item;(System.String);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary;get_Keys;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ModelStateDictionary;get_Values;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ModelBinding;ValueProviderResult;Equals;(Microsoft.AspNetCore.Mvc.ModelBinding.ValueProviderResult);summary;df-generated | +| Microsoft.AspNetCore.Mvc.Rendering;MvcForm;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.TagHelpers.Cache;CacheTagKey;Equals;(Microsoft.AspNetCore.Mvc.TagHelpers.Cache.CacheTagKey);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;AttributeDictionary+Enumerator;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;AttributeDictionary+Enumerator;MoveNext;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;AttributeDictionary+Enumerator;Reset;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;AttributeDictionary+Enumerator;get_Current;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;AttributeDictionary;Contains;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;AttributeDictionary;ContainsKey;(System.String);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;AttributeDictionary;Remove;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;AttributeDictionary;Remove;(System.String);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;AttributeDictionary;TryGetValue;(System.String,System.String);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;AttributeDictionary;get_Count;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;AttributeDictionary;get_IsReadOnly;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;AttributeDictionary;get_Item;(System.String);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;AttributeDictionary;get_Keys;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;AttributeDictionary;get_Values;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;TempDataDictionary;Contains;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;TempDataDictionary;ContainsKey;(System.String);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;TempDataDictionary;Remove;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;TempDataDictionary;Remove;(System.String);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;TempDataDictionary;TryGetValue;(System.String,System.Object);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;TempDataDictionary;get_Count;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;TempDataDictionary;get_IsReadOnly;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;ViewDataDictionary;Contains;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;ViewDataDictionary;ContainsKey;(System.String);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;ViewDataDictionary;Remove;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;ViewDataDictionary;Remove;(System.String);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;ViewDataDictionary;TryGetValue;(System.String,System.Object);summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;ViewDataDictionary;get_Count;();summary;df-generated | +| Microsoft.AspNetCore.Mvc.ViewFeatures;ViewDataDictionary;get_IsReadOnly;();summary;df-generated | +| Microsoft.AspNetCore.Mvc;Controller;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Mvc;RemoteAttributeBase;IsValid;(System.Object);summary;df-generated | +| Microsoft.AspNetCore.Razor.TagHelpers;NullHtmlEncoder;FindFirstCharacterToEncode;(System.Char*,System.Int32);summary;df-generated | +| Microsoft.AspNetCore.Razor.TagHelpers;NullHtmlEncoder;TryEncodeUnicodeScalar;(System.Int32,System.Char*,System.Int32,System.Int32);summary;df-generated | +| Microsoft.AspNetCore.Razor.TagHelpers;NullHtmlEncoder;WillEncode;(System.Int32);summary;df-generated | +| Microsoft.AspNetCore.Razor.TagHelpers;NullHtmlEncoder;get_MaxOutputCharactersPerInputCharacter;();summary;df-generated | +| Microsoft.AspNetCore.Razor.TagHelpers;TagHelperAttributeList;Remove;(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute);summary;df-generated | +| Microsoft.AspNetCore.Razor.TagHelpers;TagHelperAttributeList;RemoveAt;(System.Int32);summary;df-generated | +| Microsoft.AspNetCore.Razor.TagHelpers;TagHelperAttributeList;get_IsReadOnly;();summary;df-generated | +| Microsoft.AspNetCore.ResponseCompression;BrotliCompressionProviderOptions;get_Value;();summary;df-generated | +| Microsoft.AspNetCore.ResponseCompression;GzipCompressionProviderOptions;get_Value;();summary;df-generated | +| Microsoft.AspNetCore.Routing.Matching;EndpointMetadataComparer;Compare;(Microsoft.AspNetCore.Http.Endpoint,Microsoft.AspNetCore.Http.Endpoint);summary;df-generated | +| Microsoft.AspNetCore.Routing.Matching;EndpointMetadataComparer;Compare;(Microsoft.AspNetCore.Http.Endpoint,Microsoft.AspNetCore.Http.Endpoint);summary;df-generated | +| Microsoft.AspNetCore.Routing;CompositeEndpointDataSource;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueDictionary+Enumerator;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueDictionary+Enumerator;MoveNext;();summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueDictionary+Enumerator;Reset;();summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueDictionary+Enumerator;get_Current;();summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueDictionary;Contains;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueDictionary;ContainsKey;(System.String);summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueDictionary;Remove;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueDictionary;Remove;(System.String);summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueDictionary;TryGetValue;(System.String,System.Object);summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueDictionary;get_Count;();summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueDictionary;get_IsReadOnly;();summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueDictionary;get_Item;(System.String);summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueDictionary;get_Keys;();summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueDictionary;get_Values;();summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueEqualityComparer;Equals;(System.Object,System.Object);summary;df-generated | +| Microsoft.AspNetCore.Routing;RouteValueEqualityComparer;GetHashCode;(System.Object);summary;df-generated | +| Microsoft.AspNetCore.Server.HttpSys;DelegationRule;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Server.HttpSys;HttpSysException;get_ErrorCode;();summary;df-generated | +| Microsoft.AspNetCore.Server.HttpSys;UrlPrefixCollection;Contains;(Microsoft.AspNetCore.Server.HttpSys.UrlPrefix);summary;df-generated | +| Microsoft.AspNetCore.Server.HttpSys;UrlPrefixCollection;Remove;(Microsoft.AspNetCore.Server.HttpSys.UrlPrefix);summary;df-generated | +| Microsoft.AspNetCore.Server.HttpSys;UrlPrefixCollection;get_Count;();summary;df-generated | +| Microsoft.AspNetCore.Server.HttpSys;UrlPrefixCollection;get_IsReadOnly;();summary;df-generated | +| Microsoft.AspNetCore.Server.Kestrel.Core;KestrelServer;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets;SocketConnectionContextFactory;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.SignalR;Hub;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.SignalR;HubConnectionStore+Enumerator;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.SignalR;HubConnectionStore+Enumerator;MoveNext;();summary;df-generated | +| Microsoft.AspNetCore.SignalR;HubConnectionStore+Enumerator;Reset;();summary;df-generated | +| Microsoft.AspNetCore.SignalR;HubConnectionStore+Enumerator;get_Current;();summary;df-generated | +| Microsoft.AspNetCore.SignalR;HubOptionsSetup;Configure;(Microsoft.AspNetCore.SignalR.HubOptions);summary;df-generated | +| Microsoft.AspNetCore.SignalR;HubOptionsSetup;Configure;(Microsoft.AspNetCore.SignalR.HubOptions);summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;BufferedReadStream;Dispose;(System.Boolean);summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;BufferedReadStream;Flush;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;BufferedReadStream;Seek;(System.Int64,System.IO.SeekOrigin);summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;BufferedReadStream;SetLength;(System.Int64);summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;BufferedReadStream;get_CanRead;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;BufferedReadStream;get_CanSeek;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;BufferedReadStream;get_CanTimeout;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;BufferedReadStream;get_CanWrite;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;BufferedReadStream;get_Length;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingReadStream;Dispose;(System.Boolean);summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingReadStream;Flush;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingReadStream;Seek;(System.Int64,System.IO.SeekOrigin);summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingReadStream;SetLength;(System.Int64);summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingReadStream;get_CanRead;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingReadStream;get_CanSeek;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingReadStream;get_CanWrite;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingReadStream;get_Length;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingWriteStream;Dispose;(System.Boolean);summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingWriteStream;Flush;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingWriteStream;Seek;(System.Int64,System.IO.SeekOrigin);summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingWriteStream;SetLength;(System.Int64);summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingWriteStream;get_CanRead;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingWriteStream;get_CanSeek;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingWriteStream;get_CanWrite;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FileBufferingWriteStream;get_Length;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;FormReader;Dispose;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;HttpRequestStreamReader;Dispose;(System.Boolean);summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;HttpRequestStreamReader;Peek;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;HttpResponseStreamWriter;Dispose;(System.Boolean);summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;HttpResponseStreamWriter;Flush;();summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;HttpResponseStreamWriter;Write;(System.Char);summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;HttpResponseStreamWriter;Write;(System.ReadOnlySpan);summary;df-generated | +| Microsoft.AspNetCore.WebUtilities;HttpResponseStreamWriter;WriteLine;(System.ReadOnlySpan);summary;df-generated | | Microsoft.CSharp.RuntimeBinder;Binder;Convert;(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Type);summary;df-generated | | Microsoft.CSharp.RuntimeBinder;RuntimeBinderException;RuntimeBinderException;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);summary;df-generated | | Microsoft.CSharp.RuntimeBinder;RuntimeBinderException;RuntimeBinderException;(System.String);summary;df-generated | @@ -21196,6 +21423,7 @@ neutral | Microsoft.CSharp.RuntimeBinder;RuntimeBinderInternalCompilerException;RuntimeBinderInternalCompilerException;(System.String,System.Exception);summary;df-generated | | Microsoft.CSharp;CSharpCodeProvider;GetConverter;(System.Type);summary;df-generated | | Microsoft.CSharp;CSharpCodeProvider;get_FileExtension;();summary;df-generated | +| Microsoft.EntityFrameworkCore;DbContext;Dispose;();summary;df-generated | | Microsoft.Extensions.Caching.Distributed;DistributedCacheExtensions;GetString;(Microsoft.Extensions.Caching.Distributed.IDistributedCache,System.String);summary;df-generated | | Microsoft.Extensions.Caching.Distributed;DistributedCacheExtensions;GetStringAsync;(Microsoft.Extensions.Caching.Distributed.IDistributedCache,System.String,System.Threading.CancellationToken);summary;df-generated | | Microsoft.Extensions.Caching.Distributed;DistributedCacheExtensions;Set;(Microsoft.Extensions.Caching.Distributed.IDistributedCache,System.String,System.Byte[]);summary;df-generated | @@ -21239,6 +21467,7 @@ neutral | Microsoft.Extensions.Caching.Memory;MemoryCache;get_Count;();summary;df-generated | | Microsoft.Extensions.Caching.Memory;MemoryCacheEntryOptions;get_ExpirationTokens;();summary;df-generated | | Microsoft.Extensions.Caching.Memory;MemoryCacheEntryOptions;get_PostEvictionCallbacks;();summary;df-generated | +| Microsoft.Extensions.Caching.Memory;MemoryCacheOptions;get_Value;();summary;df-generated | | Microsoft.Extensions.Configuration.CommandLine;CommandLineConfigurationProvider;CommandLineConfigurationProvider;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IDictionary);summary;df-generated | | Microsoft.Extensions.Configuration.CommandLine;CommandLineConfigurationProvider;Load;();summary;df-generated | | Microsoft.Extensions.Configuration.EnvironmentVariables;EnvironmentVariablesConfigurationProvider;Load;();summary;df-generated | @@ -21251,6 +21480,8 @@ neutral | Microsoft.Extensions.Configuration.Json;JsonConfigurationProvider;Load;(System.IO.Stream);summary;df-generated | | Microsoft.Extensions.Configuration.Json;JsonStreamConfigurationProvider;JsonStreamConfigurationProvider;(Microsoft.Extensions.Configuration.Json.JsonStreamConfigurationSource);summary;df-generated | | Microsoft.Extensions.Configuration.Json;JsonStreamConfigurationProvider;Load;(System.IO.Stream);summary;df-generated | +| Microsoft.Extensions.Configuration.KeyPerFile;KeyPerFileConfigurationProvider;Dispose;();summary;df-generated | +| Microsoft.Extensions.Configuration.KeyPerFile;KeyPerFileConfigurationProvider;Load;();summary;df-generated | | Microsoft.Extensions.Configuration.Memory;MemoryConfigurationProvider;Add;(System.String,System.String);summary;df-generated | | Microsoft.Extensions.Configuration.UserSecrets;UserSecretsIdAttribute;UserSecretsIdAttribute;(System.String);summary;df-generated | | Microsoft.Extensions.Configuration.UserSecrets;UserSecretsIdAttribute;get_UserSecretsId;();summary;df-generated | @@ -21283,6 +21514,7 @@ neutral | Microsoft.Extensions.Configuration;ConfigurationProvider;OnReload;();summary;df-generated | | Microsoft.Extensions.Configuration;ConfigurationProvider;Set;(System.String,System.String);summary;df-generated | | Microsoft.Extensions.Configuration;ConfigurationReloadToken;OnReload;();summary;df-generated | +| Microsoft.Extensions.Configuration;ConfigurationReloadToken;get_ActiveChangeCallbacks;();summary;df-generated | | Microsoft.Extensions.Configuration;ConfigurationReloadToken;get_HasChanged;();summary;df-generated | | Microsoft.Extensions.Configuration;ConfigurationRoot;Dispose;();summary;df-generated | | Microsoft.Extensions.Configuration;ConfigurationRoot;GetChildren;();summary;df-generated | @@ -21339,6 +21571,7 @@ neutral | Microsoft.Extensions.DependencyInjection;ActivatorUtilities;CreateInstance;(System.IServiceProvider,System.Type,System.Object[]);summary;df-generated | | Microsoft.Extensions.DependencyInjection;ActivatorUtilities;CreateInstance;(System.IServiceProvider,System.Object[]);summary;df-generated | | Microsoft.Extensions.DependencyInjection;AsyncServiceScope;Dispose;();summary;df-generated | +| Microsoft.Extensions.DependencyInjection;DefaultServiceProviderFactory;CreateBuilder;(Microsoft.Extensions.DependencyInjection.IServiceCollection);summary;df-generated | | Microsoft.Extensions.DependencyInjection;DefaultServiceProviderFactory;CreateServiceProvider;(Microsoft.Extensions.DependencyInjection.IServiceCollection);summary;df-generated | | Microsoft.Extensions.DependencyInjection;FromKeyedServicesAttribute;FromKeyedServicesAttribute;(System.Object);summary;df-generated | | Microsoft.Extensions.DependencyInjection;FromKeyedServicesAttribute;get_Key;();summary;df-generated | @@ -21354,6 +21587,7 @@ neutral | Microsoft.Extensions.DependencyInjection;ISocketsHttpHandlerBuilder;get_Services;();summary;df-generated | | Microsoft.Extensions.DependencyInjection;ISupportRequiredService;GetRequiredService;(System.Type);summary;df-generated | | Microsoft.Extensions.DependencyInjection;KeyedService;get_AnyKey;();summary;df-generated | +| Microsoft.Extensions.DependencyInjection;OAuthPostConfigureOptions;PostConfigure;(System.String,TOptions);summary;df-generated | | Microsoft.Extensions.DependencyInjection;OptionsServiceCollectionExtensions;AddOptions;(Microsoft.Extensions.DependencyInjection.IServiceCollection);summary;df-generated | | Microsoft.Extensions.DependencyInjection;OptionsServiceCollectionExtensions;AddOptions;(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.String);summary;df-generated | | Microsoft.Extensions.DependencyInjection;OptionsServiceCollectionExtensions;AddOptionsWithValidateOnStart;(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.String);summary;df-generated | @@ -21420,6 +21654,10 @@ neutral | Microsoft.Extensions.Diagnostics.Metrics;InstrumentRule;get_Scopes;();summary;df-generated | | Microsoft.Extensions.Diagnostics.Metrics;MetricsOptions;get_Rules;();summary;df-generated | | Microsoft.Extensions.FileProviders.Composite;CompositeDirectoryContents;get_Exists;();summary;df-generated | +| Microsoft.Extensions.FileProviders.Embedded;EmbeddedResourceFileInfo;get_Exists;();summary;df-generated | +| Microsoft.Extensions.FileProviders.Embedded;EmbeddedResourceFileInfo;get_IsDirectory;();summary;df-generated | +| Microsoft.Extensions.FileProviders.Embedded;EmbeddedResourceFileInfo;get_LastModified;();summary;df-generated | +| Microsoft.Extensions.FileProviders.Embedded;EmbeddedResourceFileInfo;get_Length;();summary;df-generated | | Microsoft.Extensions.FileProviders.Internal;PhysicalDirectoryContents;PhysicalDirectoryContents;(System.String);summary;df-generated | | Microsoft.Extensions.FileProviders.Internal;PhysicalDirectoryContents;PhysicalDirectoryContents;(System.String,Microsoft.Extensions.FileProviders.Physical.ExclusionFilters);summary;df-generated | | Microsoft.Extensions.FileProviders.Internal;PhysicalDirectoryContents;get_Exists;();summary;df-generated | @@ -21435,12 +21673,16 @@ neutral | Microsoft.Extensions.FileProviders.Physical;PhysicalFilesWatcher;Dispose;();summary;df-generated | | Microsoft.Extensions.FileProviders.Physical;PhysicalFilesWatcher;Dispose;(System.Boolean);summary;df-generated | | Microsoft.Extensions.FileProviders.Physical;PhysicalFilesWatcher;PhysicalFilesWatcher;(System.String,System.IO.FileSystemWatcher,System.Boolean);summary;df-generated | +| Microsoft.Extensions.FileProviders.Physical;PollingFileChangeToken;get_ActiveChangeCallbacks;();summary;df-generated | | Microsoft.Extensions.FileProviders.Physical;PollingFileChangeToken;get_HasChanged;();summary;df-generated | | Microsoft.Extensions.FileProviders.Physical;PollingWildCardChangeToken;GetLastWriteUtc;(System.String);summary;df-generated | | Microsoft.Extensions.FileProviders.Physical;PollingWildCardChangeToken;PollingWildCardChangeToken;(System.String,System.String);summary;df-generated | +| Microsoft.Extensions.FileProviders.Physical;PollingWildCardChangeToken;get_ActiveChangeCallbacks;();summary;df-generated | | Microsoft.Extensions.FileProviders.Physical;PollingWildCardChangeToken;get_HasChanged;();summary;df-generated | | Microsoft.Extensions.FileProviders;CompositeFileProvider;GetFileInfo;(System.String);summary;df-generated | | Microsoft.Extensions.FileProviders;CompositeFileProvider;Watch;(System.String);summary;df-generated | +| Microsoft.Extensions.FileProviders;EmbeddedFileProvider;GetFileInfo;(System.String);summary;df-generated | +| Microsoft.Extensions.FileProviders;EmbeddedFileProvider;Watch;(System.String);summary;df-generated | | Microsoft.Extensions.FileProviders;IDirectoryContents;get_Exists;();summary;df-generated | | Microsoft.Extensions.FileProviders;IFileInfo;get_Exists;();summary;df-generated | | Microsoft.Extensions.FileProviders;IFileInfo;get_IsDirectory;();summary;df-generated | @@ -21448,6 +21690,8 @@ neutral | Microsoft.Extensions.FileProviders;IFileInfo;get_Length;();summary;df-generated | | Microsoft.Extensions.FileProviders;IFileProvider;GetFileInfo;(System.String);summary;df-generated | | Microsoft.Extensions.FileProviders;IFileProvider;Watch;(System.String);summary;df-generated | +| Microsoft.Extensions.FileProviders;ManifestEmbeddedFileProvider;GetFileInfo;(System.String);summary;df-generated | +| Microsoft.Extensions.FileProviders;ManifestEmbeddedFileProvider;Watch;(System.String);summary;df-generated | | Microsoft.Extensions.FileProviders;NotFoundDirectoryContents;get_Exists;();summary;df-generated | | Microsoft.Extensions.FileProviders;NotFoundDirectoryContents;get_Singleton;();summary;df-generated | | Microsoft.Extensions.FileProviders;NotFoundFileInfo;NotFoundFileInfo;(System.String);summary;df-generated | @@ -21638,12 +21882,15 @@ neutral | Microsoft.Extensions.Logging.Configuration;LoggerProviderOptionsChangeTokenSource;LoggerProviderOptionsChangeTokenSource;(Microsoft.Extensions.Logging.Configuration.ILoggerProviderConfiguration);summary;df-generated | | Microsoft.Extensions.Logging.Configuration;LoggingBuilderConfigurationExtensions;AddConfiguration;(Microsoft.Extensions.Logging.ILoggingBuilder);summary;df-generated | | Microsoft.Extensions.Logging.Console;ConfigurationConsoleLoggerSettings;TryGetSwitch;(System.String,Microsoft.Extensions.Logging.LogLevel);summary;df-generated | +| Microsoft.Extensions.Logging.Console;ConfigurationConsoleLoggerSettings;get_ChangeToken;();summary;df-generated | | Microsoft.Extensions.Logging.Console;ConfigurationConsoleLoggerSettings;get_IncludeScopes;();summary;df-generated | | Microsoft.Extensions.Logging.Console;ConsoleFormatter;ConsoleFormatter;(System.String);summary;df-generated | | Microsoft.Extensions.Logging.Console;ConsoleFormatter;get_Name;();summary;df-generated | | Microsoft.Extensions.Logging.Console;ConsoleLoggerProvider;ConsoleLoggerProvider;(Microsoft.Extensions.Options.IOptionsMonitor);summary;df-generated | | Microsoft.Extensions.Logging.Console;ConsoleLoggerProvider;Dispose;();summary;df-generated | | Microsoft.Extensions.Logging.Console;ConsoleLoggerSettings;TryGetSwitch;(System.String,Microsoft.Extensions.Logging.LogLevel);summary;df-generated | +| Microsoft.Extensions.Logging.Console;ConsoleLoggerSettings;get_ChangeToken;();summary;df-generated | +| Microsoft.Extensions.Logging.Console;ConsoleLoggerSettings;get_IncludeScopes;();summary;df-generated | | Microsoft.Extensions.Logging.Console;IConsoleLoggerSettings;TryGetSwitch;(System.String,Microsoft.Extensions.Logging.LogLevel);summary;df-generated | | Microsoft.Extensions.Logging.Console;IConsoleLoggerSettings;get_ChangeToken;();summary;df-generated | | Microsoft.Extensions.Logging.Console;IConsoleLoggerSettings;get_IncludeScopes;();summary;df-generated | @@ -21734,6 +21981,7 @@ neutral | Microsoft.Extensions.Logging;ProviderAliasAttribute;ProviderAliasAttribute;(System.String);summary;df-generated | | Microsoft.Extensions.Logging;ProviderAliasAttribute;get_Alias;();summary;df-generated | | Microsoft.Extensions.Options;ConfigurationChangeTokenSource;ConfigurationChangeTokenSource;(Microsoft.Extensions.Configuration.IConfiguration);summary;df-generated | +| Microsoft.Extensions.Options;ConfigurationChangeTokenSource;GetChangeToken;();summary;df-generated | | Microsoft.Extensions.Options;ConfigurationChangeTokenSource;get_Name;();summary;df-generated | | Microsoft.Extensions.Options;ConfigureFromConfigurationOptions;ConfigureFromConfigurationOptions;(Microsoft.Extensions.Configuration.IConfiguration);summary;df-generated | | Microsoft.Extensions.Options;ConfigureNamedOptions;Configure;(System.String,TOptions);summary;df-generated | @@ -21902,6 +22150,7 @@ neutral | Microsoft.Extensions.Options;ValidateOptionsResult;Fail;(System.String);summary;df-generated | | Microsoft.Extensions.Options;ValidateOptionsResultBuilder;Build;();summary;df-generated | | Microsoft.Extensions.Options;ValidateOptionsResultBuilder;Clear;();summary;df-generated | +| Microsoft.Extensions.Primitives;CancellationChangeToken;get_ActiveChangeCallbacks;();summary;df-generated | | Microsoft.Extensions.Primitives;CancellationChangeToken;get_HasChanged;();summary;df-generated | | Microsoft.Extensions.Primitives;CompositeChangeToken;CompositeChangeToken;(System.Collections.Generic.IReadOnlyList);summary;df-generated | | Microsoft.Extensions.Primitives;CompositeChangeToken;get_ActiveChangeCallbacks;();summary;df-generated | @@ -21957,10 +22206,22 @@ neutral | Microsoft.Extensions.Primitives;StringTokenizer+Enumerator;Dispose;();summary;df-generated | | Microsoft.Extensions.Primitives;StringTokenizer+Enumerator;MoveNext;();summary;df-generated | | Microsoft.Extensions.Primitives;StringTokenizer+Enumerator;Reset;();summary;df-generated | +| Microsoft.Extensions.Primitives;StringTokenizer+Enumerator;get_Current;();summary;df-generated | | Microsoft.Extensions.Primitives;StringValues+Enumerator;Dispose;();summary;df-generated | | Microsoft.Extensions.Primitives;StringValues+Enumerator;Enumerator;(Microsoft.Extensions.Primitives.StringValues);summary;df-generated | | Microsoft.Extensions.Primitives;StringValues+Enumerator;MoveNext;();summary;df-generated | | Microsoft.Extensions.Primitives;StringValues+Enumerator;Reset;();summary;df-generated | +| Microsoft.Extensions.Primitives;StringValues+Enumerator;get_Current;();summary;df-generated | +| Microsoft.Extensions.Primitives;StringValues;Contains;(System.String);summary;df-generated | +| Microsoft.Extensions.Primitives;StringValues;Equals;(Microsoft.Extensions.Primitives.StringValues);summary;df-generated | +| Microsoft.Extensions.Primitives;StringValues;Equals;(System.String);summary;df-generated | +| Microsoft.Extensions.Primitives;StringValues;Equals;(System.String[]);summary;df-generated | +| Microsoft.Extensions.Primitives;StringValues;IndexOf;(System.String);summary;df-generated | +| Microsoft.Extensions.Primitives;StringValues;Remove;(System.String);summary;df-generated | +| Microsoft.Extensions.Primitives;StringValues;RemoveAt;(System.Int32);summary;df-generated | +| Microsoft.Extensions.Primitives;StringValues;get_Count;();summary;df-generated | +| Microsoft.Extensions.Primitives;StringValues;get_IsReadOnly;();summary;df-generated | +| Microsoft.Extensions.Primitives;StringValues;get_Item;(System.Int32);summary;df-generated | | Microsoft.Extensions.Primitives;StringValues;op_Equality;(Microsoft.Extensions.Primitives.StringValues,Microsoft.Extensions.Primitives.StringValues);summary;df-generated | | Microsoft.Extensions.Primitives;StringValues;op_Equality;(Microsoft.Extensions.Primitives.StringValues,System.Object);summary;df-generated | | Microsoft.Extensions.Primitives;StringValues;op_Equality;(Microsoft.Extensions.Primitives.StringValues,System.String);summary;df-generated | @@ -21975,6 +22236,44 @@ neutral | Microsoft.Extensions.Primitives;StringValues;op_Inequality;(System.Object,Microsoft.Extensions.Primitives.StringValues);summary;df-generated | | Microsoft.Extensions.Primitives;StringValues;op_Inequality;(System.String,Microsoft.Extensions.Primitives.StringValues);summary;df-generated | | Microsoft.Extensions.Primitives;StringValues;op_Inequality;(System.String[],Microsoft.Extensions.Primitives.StringValues);summary;df-generated | +| Microsoft.Extensions.WebEncoders.Testing;HtmlTestEncoder;FindFirstCharacterToEncode;(System.Char*,System.Int32);summary;df-generated | +| Microsoft.Extensions.WebEncoders.Testing;HtmlTestEncoder;TryEncodeUnicodeScalar;(System.Int32,System.Char*,System.Int32,System.Int32);summary;df-generated | +| Microsoft.Extensions.WebEncoders.Testing;HtmlTestEncoder;WillEncode;(System.Int32);summary;df-generated | +| Microsoft.Extensions.WebEncoders.Testing;HtmlTestEncoder;get_MaxOutputCharactersPerInputCharacter;();summary;df-generated | +| Microsoft.Extensions.WebEncoders.Testing;JavaScriptTestEncoder;FindFirstCharacterToEncode;(System.Char*,System.Int32);summary;df-generated | +| Microsoft.Extensions.WebEncoders.Testing;JavaScriptTestEncoder;TryEncodeUnicodeScalar;(System.Int32,System.Char*,System.Int32,System.Int32);summary;df-generated | +| Microsoft.Extensions.WebEncoders.Testing;JavaScriptTestEncoder;WillEncode;(System.Int32);summary;df-generated | +| Microsoft.Extensions.WebEncoders.Testing;JavaScriptTestEncoder;get_MaxOutputCharactersPerInputCharacter;();summary;df-generated | +| Microsoft.Extensions.WebEncoders.Testing;UrlTestEncoder;FindFirstCharacterToEncode;(System.Char*,System.Int32);summary;df-generated | +| Microsoft.Extensions.WebEncoders.Testing;UrlTestEncoder;TryEncodeUnicodeScalar;(System.Int32,System.Char*,System.Int32,System.Int32);summary;df-generated | +| Microsoft.Extensions.WebEncoders.Testing;UrlTestEncoder;WillEncode;(System.Int32);summary;df-generated | +| Microsoft.Extensions.WebEncoders.Testing;UrlTestEncoder;get_MaxOutputCharactersPerInputCharacter;();summary;df-generated | +| Microsoft.JSInterop.Implementation;JSInProcessObjectReference;Dispose;();summary;df-generated | +| Microsoft.JSInterop;DotNetObjectReference;Dispose;();summary;df-generated | +| Microsoft.JSInterop;DotNetStreamReference;Dispose;();summary;df-generated | +| Microsoft.JSInterop;JSRuntime;Dispose;();summary;df-generated | +| Microsoft.Net.Http.Headers;MediaTypeHeaderValueComparer;Compare;(Microsoft.Net.Http.Headers.MediaTypeHeaderValue,Microsoft.Net.Http.Headers.MediaTypeHeaderValue);summary;df-generated | +| Microsoft.Net.Http.Headers;StringWithQualityHeaderValueComparer;Compare;(Microsoft.Net.Http.Headers.StringWithQualityHeaderValue,Microsoft.Net.Http.Headers.StringWithQualityHeaderValue);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetBoolean;(System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetByte;(System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetBytes;(System.Int32,System.Int64,System.Byte[],System.Int32,System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetChar;(System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetChars;(System.Int32,System.Int64,System.Char[],System.Int32,System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetData;(System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetDataTypeName;(System.Int32);summary;manual | +| Microsoft.SqlServer.Server;SqlDataRecord;GetDateTime;(System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetDecimal;(System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetDouble;(System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetFieldType;(System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetFloat;(System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetGuid;(System.Int32);summary;manual | +| Microsoft.SqlServer.Server;SqlDataRecord;GetInt16;(System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetInt32;(System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetInt64;(System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;GetName;(System.Int32);summary;manual | +| Microsoft.SqlServer.Server;SqlDataRecord;GetOrdinal;(System.String);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;IsDBNull;(System.Int32);summary;df-generated | +| Microsoft.SqlServer.Server;SqlDataRecord;get_FieldCount;();summary;df-generated | | Microsoft.VisualBasic.CompilerServices;BooleanType;FromObject;(System.Object);summary;df-generated | | Microsoft.VisualBasic.CompilerServices;BooleanType;FromString;(System.String);summary;df-generated | | Microsoft.VisualBasic.CompilerServices;ByteType;FromObject;(System.Object);summary;df-generated | @@ -22648,6 +22947,238 @@ neutral | Microsoft.Win32;UserPreferenceChangedEventArgs;get_Category;();summary;df-generated | | Microsoft.Win32;UserPreferenceChangingEventArgs;UserPreferenceChangingEventArgs;(Microsoft.Win32.UserPreferenceCategory);summary;df-generated | | Microsoft.Win32;UserPreferenceChangingEventArgs;get_Category;();summary;df-generated | +| Newtonsoft.Json.Linq;JArray;Contains;(Newtonsoft.Json.Linq.JToken);summary;df-generated | +| Newtonsoft.Json.Linq;JArray;IndexOf;(Newtonsoft.Json.Linq.JToken);summary;df-generated | +| Newtonsoft.Json.Linq;JArray;Remove;(Newtonsoft.Json.Linq.JToken);summary;df-generated | +| Newtonsoft.Json.Linq;JArray;RemoveAt;(System.Int32);summary;df-generated | +| Newtonsoft.Json.Linq;JArray;get_IsReadOnly;();summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;AddIndex;(System.ComponentModel.PropertyDescriptor);summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;Contains;(Newtonsoft.Json.Linq.JToken);summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;Contains;(System.Object);summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;IndexOf;(Newtonsoft.Json.Linq.JToken);summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;IndexOf;(System.Object);summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;Remove;(Newtonsoft.Json.Linq.JToken);summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;RemoveAt;(System.Int32);summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;RemoveIndex;(System.ComponentModel.PropertyDescriptor);summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;RemoveSort;();summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;get_AllowEdit;();summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;get_AllowNew;();summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;get_AllowRemove;();summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;get_Count;();summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;get_IsFixedSize;();summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;get_IsReadOnly;();summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;get_IsSorted;();summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;get_IsSynchronized;();summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;get_SortDirection;();summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;get_SupportsChangeNotification;();summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;get_SupportsSearching;();summary;df-generated | +| Newtonsoft.Json.Linq;JContainer;get_SupportsSorting;();summary;df-generated | +| Newtonsoft.Json.Linq;JEnumerable;Equals;(Newtonsoft.Json.Linq.JEnumerable);summary;df-generated | +| Newtonsoft.Json.Linq;JObject;Contains;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Newtonsoft.Json.Linq;JObject;ContainsKey;(System.String);summary;df-generated | +| Newtonsoft.Json.Linq;JObject;GetClassName;();summary;df-generated | +| Newtonsoft.Json.Linq;JObject;GetComponentName;();summary;df-generated | +| Newtonsoft.Json.Linq;JObject;GetConverter;();summary;df-generated | +| Newtonsoft.Json.Linq;JObject;GetDefaultEvent;();summary;df-generated | +| Newtonsoft.Json.Linq;JObject;GetDefaultProperty;();summary;df-generated | +| Newtonsoft.Json.Linq;JObject;GetEditor;(System.Type);summary;df-generated | +| Newtonsoft.Json.Linq;JObject;GetEvents;();summary;df-generated | +| Newtonsoft.Json.Linq;JObject;GetEvents;(System.Attribute[]);summary;df-generated | +| Newtonsoft.Json.Linq;JObject;Remove;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| Newtonsoft.Json.Linq;JObject;Remove;(System.String);summary;df-generated | +| Newtonsoft.Json.Linq;JObject;TryGetValue;(System.String,Newtonsoft.Json.Linq.JToken);summary;df-generated | +| Newtonsoft.Json.Linq;JObject;get_IsReadOnly;();summary;df-generated | +| Newtonsoft.Json.Linq;JPropertyDescriptor;CanResetValue;(System.Object);summary;df-generated | +| Newtonsoft.Json.Linq;JPropertyDescriptor;ShouldSerializeValue;(System.Object);summary;df-generated | +| Newtonsoft.Json.Linq;JPropertyDescriptor;get_ComponentType;();summary;df-generated | +| Newtonsoft.Json.Linq;JPropertyDescriptor;get_IsReadOnly;();summary;df-generated | +| Newtonsoft.Json.Linq;JPropertyDescriptor;get_NameHashCode;();summary;df-generated | +| Newtonsoft.Json.Linq;JPropertyDescriptor;get_PropertyType;();summary;df-generated | +| Newtonsoft.Json.Linq;JToken;GetMetaObject;(System.Linq.Expressions.Expression);summary;df-generated | +| Newtonsoft.Json.Linq;JTokenEqualityComparer;Equals;(Newtonsoft.Json.Linq.JToken,Newtonsoft.Json.Linq.JToken);summary;df-generated | +| Newtonsoft.Json.Linq;JTokenEqualityComparer;GetHashCode;(Newtonsoft.Json.Linq.JToken);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;CompareTo;(Newtonsoft.Json.Linq.JValue);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;CompareTo;(System.Object);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;Equals;(Newtonsoft.Json.Linq.JValue);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;GetTypeCode;();summary;df-generated | +| Newtonsoft.Json.Linq;JValue;ToBoolean;(System.IFormatProvider);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;ToByte;(System.IFormatProvider);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;ToChar;(System.IFormatProvider);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;ToDouble;(System.IFormatProvider);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;ToInt16;(System.IFormatProvider);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;ToInt32;(System.IFormatProvider);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;ToInt64;(System.IFormatProvider);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;ToSByte;(System.IFormatProvider);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;ToSingle;(System.IFormatProvider);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;ToUInt16;(System.IFormatProvider);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;ToUInt32;(System.IFormatProvider);summary;df-generated | +| Newtonsoft.Json.Linq;JValue;ToUInt64;(System.IFormatProvider);summary;df-generated | +| Newtonsoft.Json.Serialization;DefaultSerializationBinder;BindToName;(System.Type,System.String,System.String);summary;df-generated | +| Newtonsoft.Json.Serialization;DefaultSerializationBinder;BindToType;(System.String,System.String);summary;df-generated | +| Newtonsoft.Json.Serialization;JsonPropertyCollection;GetKeyForItem;(Newtonsoft.Json.Serialization.JsonProperty);summary;df-generated | +| Newtonsoft.Json;JsonReader;Dispose;();summary;df-generated | +| Newtonsoft.Json;JsonWriter;Dispose;();summary;df-generated | +| ServiceStack.AsyncEx;CancellationTokenTaskSource;Dispose;();summary;df-generated | +| ServiceStack.Caching;CacheClientWithPrefix;Dispose;();summary;df-generated | +| ServiceStack.Caching;MemoryCacheClient;Dispose;();summary;df-generated | +| ServiceStack.Caching;MultiCacheClient;Dispose;();summary;df-generated | +| ServiceStack.Messaging;BackgroundMqClient;Dispose;();summary;df-generated | +| ServiceStack.Messaging;BackgroundMqCollection;Dispose;();summary;df-generated | +| ServiceStack.Messaging;BackgroundMqMessageFactory;Dispose;();summary;df-generated | +| ServiceStack.Messaging;BackgroundMqService;Dispose;();summary;df-generated | +| ServiceStack.Messaging;BackgroundMqWorker;Dispose;();summary;df-generated | +| ServiceStack.Messaging;InMemoryMessageQueueClient;Dispose;();summary;df-generated | +| ServiceStack.Messaging;InMemoryTransientMessageFactory;Dispose;();summary;df-generated | +| ServiceStack.Messaging;MessageHandler;Dispose;();summary;df-generated | +| ServiceStack.Messaging;MessageQueueClientFactory;Dispose;();summary;df-generated | +| ServiceStack.Messaging;RedisMessageFactory;Dispose;();summary;df-generated | +| ServiceStack.Messaging;RedisMessageProducer;Dispose;();summary;df-generated | +| ServiceStack.Messaging;RedisMessageQueueClient;Dispose;();summary;df-generated | +| ServiceStack.Messaging;RedisMessageQueueClientFactory;Dispose;();summary;df-generated | +| ServiceStack.Messaging;TransientMessageServiceBase;Dispose;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledCommand;Cancel;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledCommand;CreateDbParameter;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledCommand;Dispose;(System.Boolean);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledCommand;ExecuteNonQuery;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledCommand;Prepare;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledConnection;ChangeDatabase;(System.String);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledConnection;Close;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledConnection;Dispose;(System.Boolean);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledConnection;Open;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledConnection;get_CanRaiseEvents;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledConnection;get_ConnectionTimeout;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledConnection;get_DataSource;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledConnection;get_Database;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledConnection;get_State;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;Close;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetBoolean;(System.Int32);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetByte;(System.Int32);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetBytes;(System.Int32,System.Int64,System.Byte[],System.Int32,System.Int32);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetChar;(System.Int32);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetChars;(System.Int32,System.Int64,System.Char[],System.Int32,System.Int32);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetDataTypeName;(System.Int32);summary;manual | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetDateTime;(System.Int32);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetDecimal;(System.Int32);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetDouble;(System.Int32);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetFieldType;(System.Int32);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetFloat;(System.Int32);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetGuid;(System.Int32);summary;manual | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetInt16;(System.Int32);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetInt32;(System.Int32);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetInt64;(System.Int32);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetName;(System.Int32);summary;manual | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;GetOrdinal;(System.String);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;IsDBNull;(System.Int32);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;NextResult;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;Read;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;get_Depth;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;get_FieldCount;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;get_HasRows;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;get_IsClosed;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbDataReader;get_RecordsAffected;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbTransaction;Commit;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbTransaction;Dispose;(System.Boolean);summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbTransaction;Rollback;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledDbTransaction;get_IsolationLevel;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledProviderFactory;CreateCommand;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledProviderFactory;CreateConnection;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledProviderFactory;CreateConnectionStringBuilder;();summary;df-generated | +| ServiceStack.MiniProfiler.Data;ProfiledProviderFactory;CreateParameter;();summary;df-generated | +| ServiceStack.NetCore;NetCoreContainerAdapter;Dispose;();summary;df-generated | +| ServiceStack.NetCore;NetCoreHeadersCollection;GetValues;(System.String);summary;df-generated | +| ServiceStack.NetCore;NetCoreHeadersCollection;Remove;(System.String);summary;df-generated | +| ServiceStack.NetCore;NetCoreHeadersCollection;get_Count;();summary;df-generated | +| ServiceStack.NetCore;NetCoreQueryStringCollection;GetValues;(System.String);summary;df-generated | +| ServiceStack.NetCore;NetCoreQueryStringCollection;Remove;(System.String);summary;df-generated | +| ServiceStack.NetCore;NetCoreQueryStringCollection;get_Count;();summary;df-generated | +| ServiceStack.OrmLite.Dapper;SqlMapper+GridReader;Dispose;();summary;df-generated | +| ServiceStack.OrmLite.Dapper;SqlMapper+Identity;Equals;(ServiceStack.OrmLite.Dapper.SqlMapper+Identity);summary;df-generated | +| ServiceStack.OrmLite;OrmLiteCommand;Cancel;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteCommand;CreateParameter;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteCommand;Dispose;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteCommand;ExecuteNonQuery;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteCommand;ExecuteReader;(System.Data.CommandBehavior);summary;df-generated | +| ServiceStack.OrmLite;OrmLiteCommand;Prepare;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteConnection;ChangeDatabase;(System.String);summary;df-generated | +| ServiceStack.OrmLite;OrmLiteConnection;Close;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteConnection;Dispose;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteConnection;Open;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteConnection;get_ConnectionTimeout;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteConnection;get_Database;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteConnection;get_State;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteDataParameter;get_IsNullable;();summary;df-generated | +| ServiceStack.OrmLite;OrmLitePersistenceProvider;Dispose;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteResultsFilter;Dispose;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteSPStatement;Dispose;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteTransaction;Commit;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteTransaction;Dispose;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteTransaction;Rollback;();summary;df-generated | +| ServiceStack.OrmLite;OrmLiteTransaction;get_IsolationLevel;();summary;df-generated | +| ServiceStack.Script;PageResult;Dispose;();summary;df-generated | +| ServiceStack.Script;ScriptContext;Dispose;();summary;df-generated | +| ServiceStack.Script;SharpCodePage;Dispose;();summary;df-generated | +| ServiceStack.Serialization;XmlSerializerWrapper;IsStartObject;(System.Xml.XmlDictionaryReader);summary;df-generated | +| ServiceStack.Serialization;XmlSerializerWrapper;ReadObject;(System.Xml.XmlDictionaryReader);summary;df-generated | +| ServiceStack.Serialization;XmlSerializerWrapper;ReadObject;(System.Xml.XmlDictionaryReader,System.Boolean);summary;df-generated | +| ServiceStack.Serialization;XmlSerializerWrapper;WriteEndObject;(System.Xml.XmlDictionaryWriter);summary;df-generated | +| ServiceStack.Serialization;XmlSerializerWrapper;WriteObject;(System.Xml.XmlDictionaryWriter,System.Object);summary;df-generated | +| ServiceStack.Serialization;XmlSerializerWrapper;WriteObjectContent;(System.Xml.XmlDictionaryWriter,System.Object);summary;df-generated | +| ServiceStack.Serialization;XmlSerializerWrapper;WriteStartObject;(System.Xml.XmlDictionaryWriter,System.Object);summary;df-generated | +| ServiceStack.Text.Pools;PooledObject;Dispose;();summary;df-generated | +| ServiceStack.Text;DirectStreamWriter;Flush;();summary;df-generated | +| ServiceStack.Text;DirectStreamWriter;Write;(System.Char);summary;df-generated | +| ServiceStack.Text;JsConfigScope;Dispose;();summary;df-generated | +| ServiceStack.Text;RecyclableMemoryStream;Close;();summary;df-generated | +| ServiceStack.Text;RecyclableMemoryStream;Dispose;(System.Boolean);summary;df-generated | +| ServiceStack.Text;RecyclableMemoryStream;ReadByte;();summary;df-generated | +| ServiceStack.Text;RecyclableMemoryStream;Seek;(System.Int64,System.IO.SeekOrigin);summary;df-generated | +| ServiceStack.Text;RecyclableMemoryStream;SetLength;(System.Int64);summary;df-generated | +| ServiceStack.Text;RecyclableMemoryStream;Write;(System.ReadOnlySpan);summary;df-generated | +| ServiceStack.Text;RecyclableMemoryStream;WriteByte;(System.Byte);summary;df-generated | +| ServiceStack.Text;RecyclableMemoryStream;get_CanRead;();summary;df-generated | +| ServiceStack.Text;RecyclableMemoryStream;get_CanSeek;();summary;df-generated | +| ServiceStack.Text;RecyclableMemoryStream;get_CanTimeout;();summary;df-generated | +| ServiceStack.Text;RecyclableMemoryStream;get_CanWrite;();summary;df-generated | +| ServiceStack.Text;RecyclableMemoryStream;get_Length;();summary;df-generated | +| ServiceStack.Validation;ExecOnceOnly;Dispose;();summary;df-generated | +| ServiceStack;AsyncTimer;Dispose;();summary;df-generated | +| ServiceStack;AuthenticateAttribute;Equals;(System.Object);summary;df-generated | +| ServiceStack;AuthenticateAttribute;GetHashCode;();summary;df-generated | +| ServiceStack;ByteArrayComparer;Equals;(System.Byte[],System.Byte[]);summary;df-generated | +| ServiceStack;ByteArrayComparer;GetHashCode;(System.Byte[]);summary;df-generated | +| ServiceStack;CachedServiceClient;Dispose;();summary;df-generated | +| ServiceStack;Defer;Dispose;();summary;df-generated | +| ServiceStack;DisposableTracker;Dispose;();summary;df-generated | +| ServiceStack;DynamicJson;TryGetMember;(System.Dynamic.GetMemberBinder,System.Object);summary;df-generated | +| ServiceStack;DynamicJson;TrySetMember;(System.Dynamic.SetMemberBinder,System.Object);summary;df-generated | +| ServiceStack;EventSubscription;Dispose;();summary;df-generated | +| ServiceStack;HttpResult;Dispose;();summary;df-generated | +| ServiceStack;JsonApiClient;Dispose;();summary;df-generated | +| ServiceStack;LispReplTcpServer;Dispose;();summary;df-generated | +| ServiceStack;LogicBase;Dispose;();summary;df-generated | +| ServiceStack;LongRange;Equals;(ServiceStack.LongRange);summary;df-generated | +| ServiceStack;MemoryServerEvents;Dispose;();summary;df-generated | +| ServiceStack;NameValue;Equals;(ServiceStack.NameValue);summary;df-generated | +| ServiceStack;ProfilerDiagnosticObserver;OnCompleted;();summary;df-generated | +| ServiceStack;ProfilerDiagnosticObserver;OnError;(System.Exception);summary;df-generated | +| ServiceStack;ProfilerDiagnosticObserver;OnNext;(System.Collections.Generic.KeyValuePair);summary;df-generated | +| ServiceStack;ProfilerDiagnosticObserver;OnNext;(System.Diagnostics.DiagnosticListener);summary;df-generated | +| ServiceStack;QueryDataSource;Dispose;();summary;df-generated | +| ServiceStack;RepositoryBase;Dispose;();summary;df-generated | +| ServiceStack;RequiredClaimAttribute;Equals;(System.Object);summary;df-generated | +| ServiceStack;RequiredClaimAttribute;GetHashCode;();summary;df-generated | +| ServiceStack;RequiredPermissionAttribute;Equals;(System.Object);summary;df-generated | +| ServiceStack;RequiredPermissionAttribute;GetHashCode;();summary;df-generated | +| ServiceStack;RequiredRoleAttribute;Equals;(System.Object);summary;df-generated | +| ServiceStack;RequiredRoleAttribute;GetHashCode;();summary;df-generated | +| ServiceStack;RouteAttribute;Equals;(System.Object);summary;df-generated | +| ServiceStack;RouteAttribute;GetHashCode;();summary;df-generated | +| ServiceStack;ServerEventsClient;Dispose;();summary;df-generated | +| ServiceStack;Service;Dispose;();summary;df-generated | +| ServiceStack;ServiceClientBase;Dispose;();summary;df-generated | +| ServiceStack;ServiceStackCodePage;Dispose;();summary;df-generated | +| ServiceStack;ServiceStackHost;Dispose;();summary;df-generated | +| ServiceStack;ServiceStackProvider;Dispose;();summary;df-generated | | System.Buffers.Binary;BinaryPrimitives;ReadDoubleBigEndian;(System.ReadOnlySpan);summary;df-generated | | System.Buffers.Binary;BinaryPrimitives;ReadDoubleLittleEndian;(System.ReadOnlySpan);summary;df-generated | | System.Buffers.Binary;BinaryPrimitives;ReadHalfBigEndian;(System.ReadOnlySpan);summary;df-generated | @@ -22819,6 +23350,7 @@ neutral | System.Buffers;ArrayBufferWriter;Advance;(System.Int32);summary;df-generated | | System.Buffers;ArrayBufferWriter;ArrayBufferWriter;(System.Int32);summary;df-generated | | System.Buffers;ArrayBufferWriter;Clear;();summary;df-generated | +| System.Buffers;ArrayBufferWriter;GetMemory;(System.Int32);summary;df-generated | | System.Buffers;ArrayBufferWriter;GetSpan;(System.Int32);summary;df-generated | | System.Buffers;ArrayBufferWriter;ResetWrittenCount;();summary;df-generated | | System.Buffers;ArrayBufferWriter;get_Capacity;();summary;df-generated | @@ -22844,6 +23376,7 @@ neutral | System.Buffers;MemoryManager;Pin;(System.Int32);summary;df-generated | | System.Buffers;MemoryManager;TryGetArray;(System.ArraySegment);summary;df-generated | | System.Buffers;MemoryManager;Unpin;();summary;df-generated | +| System.Buffers;MemoryManager;get_Memory;();summary;df-generated | | System.Buffers;MemoryPool;Dispose;();summary;df-generated | | System.Buffers;MemoryPool;Dispose;(System.Boolean);summary;df-generated | | System.Buffers;MemoryPool;Rent;(System.Int32);summary;df-generated | @@ -23136,6 +23669,9 @@ neutral | System.Collections.Concurrent;BlockingCollection;get_IsCompleted;();summary;df-generated | | System.Collections.Concurrent;BlockingCollection;get_IsSynchronized;();summary;df-generated | | System.Collections.Concurrent;ConcurrentBag;ConcurrentBag;(System.Collections.Generic.IEnumerable);summary;df-generated | +| System.Collections.Concurrent;ConcurrentBag;ToArray;();summary;df-generated | +| System.Collections.Concurrent;ConcurrentBag;TryAdd;(T);summary;df-generated | +| System.Collections.Concurrent;ConcurrentBag;TryTake;(T);summary;df-generated | | System.Collections.Concurrent;ConcurrentBag;get_Count;();summary;df-generated | | System.Collections.Concurrent;ConcurrentBag;get_IsEmpty;();summary;df-generated | | System.Collections.Concurrent;ConcurrentBag;get_IsSynchronized;();summary;df-generated | @@ -23159,6 +23695,9 @@ neutral | System.Collections.Concurrent;ConcurrentDictionary;get_IsFixedSize;();summary;df-generated | | System.Collections.Concurrent;ConcurrentDictionary;get_IsReadOnly;();summary;df-generated | | System.Collections.Concurrent;ConcurrentDictionary;get_IsSynchronized;();summary;df-generated | +| System.Collections.Concurrent;ConcurrentDictionary;get_Item;(TKey);summary;df-generated | +| System.Collections.Concurrent;ConcurrentDictionary;get_Keys;();summary;df-generated | +| System.Collections.Concurrent;ConcurrentDictionary;get_Values;();summary;df-generated | | System.Collections.Concurrent;ConcurrentQueue;ConcurrentQueue;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Concurrent;ConcurrentQueue;Enqueue;(T);summary;df-generated | | System.Collections.Concurrent;ConcurrentQueue;ToArray;();summary;df-generated | @@ -23174,6 +23713,7 @@ neutral | System.Collections.Concurrent;ConcurrentStack;PushRange;(T[],System.Int32,System.Int32);summary;df-generated | | System.Collections.Concurrent;ConcurrentStack;ToArray;();summary;df-generated | | System.Collections.Concurrent;ConcurrentStack;TryAdd;(T);summary;df-generated | +| System.Collections.Concurrent;ConcurrentStack;TryTake;(T);summary;df-generated | | System.Collections.Concurrent;ConcurrentStack;get_Count;();summary;df-generated | | System.Collections.Concurrent;ConcurrentStack;get_IsEmpty;();summary;df-generated | | System.Collections.Concurrent;ConcurrentStack;get_IsSynchronized;();summary;df-generated | @@ -23195,6 +23735,7 @@ neutral | System.Collections.Frozen;FrozenDictionary+Enumerator;Dispose;();summary;df-generated | | System.Collections.Frozen;FrozenDictionary+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Frozen;FrozenDictionary+Enumerator;Reset;();summary;df-generated | +| System.Collections.Frozen;FrozenDictionary+Enumerator;get_Current;();summary;df-generated | | System.Collections.Frozen;FrozenDictionary;Contains;(System.Collections.Generic.KeyValuePair);summary;df-generated | | System.Collections.Frozen;FrozenDictionary;Contains;(System.Object);summary;df-generated | | System.Collections.Frozen;FrozenDictionary;ContainsKey;(TKey);summary;df-generated | @@ -23212,9 +23753,12 @@ neutral | System.Collections.Frozen;FrozenDictionary;get_IsReadOnly;();summary;df-generated | | System.Collections.Frozen;FrozenDictionary;get_IsSynchronized;();summary;df-generated | | System.Collections.Frozen;FrozenDictionary;get_Item;(TKey);summary;df-generated | +| System.Collections.Frozen;FrozenDictionary;get_Keys;();summary;df-generated | +| System.Collections.Frozen;FrozenDictionary;get_Values;();summary;df-generated | | System.Collections.Frozen;FrozenSet+Enumerator;Dispose;();summary;df-generated | | System.Collections.Frozen;FrozenSet+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Frozen;FrozenSet+Enumerator;Reset;();summary;df-generated | +| System.Collections.Frozen;FrozenSet+Enumerator;get_Current;();summary;df-generated | | System.Collections.Frozen;FrozenSet;Contains;(T);summary;df-generated | | System.Collections.Frozen;FrozenSet;ExceptWith;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Frozen;FrozenSet;GetEnumerator;();summary;df-generated | @@ -23241,9 +23785,11 @@ neutral | System.Collections.Generic;Dictionary+Enumerator;Dispose;();summary;df-generated | | System.Collections.Generic;Dictionary+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Generic;Dictionary+Enumerator;Reset;();summary;df-generated | +| System.Collections.Generic;Dictionary+Enumerator;get_Current;();summary;df-generated | | System.Collections.Generic;Dictionary+KeyCollection+Enumerator;Dispose;();summary;df-generated | | System.Collections.Generic;Dictionary+KeyCollection+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Generic;Dictionary+KeyCollection+Enumerator;Reset;();summary;df-generated | +| System.Collections.Generic;Dictionary+KeyCollection+Enumerator;get_Current;();summary;df-generated | | System.Collections.Generic;Dictionary+KeyCollection;Contains;(TKey);summary;df-generated | | System.Collections.Generic;Dictionary+KeyCollection;Remove;(TKey);summary;df-generated | | System.Collections.Generic;Dictionary+KeyCollection;get_Count;();summary;df-generated | @@ -23252,6 +23798,7 @@ neutral | System.Collections.Generic;Dictionary+ValueCollection+Enumerator;Dispose;();summary;df-generated | | System.Collections.Generic;Dictionary+ValueCollection+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Generic;Dictionary+ValueCollection+Enumerator;Reset;();summary;df-generated | +| System.Collections.Generic;Dictionary+ValueCollection+Enumerator;get_Current;();summary;df-generated | | System.Collections.Generic;Dictionary+ValueCollection;Contains;(TValue);summary;df-generated | | System.Collections.Generic;Dictionary+ValueCollection;Remove;(TValue);summary;df-generated | | System.Collections.Generic;Dictionary+ValueCollection;get_Count;();summary;df-generated | @@ -23278,6 +23825,9 @@ neutral | System.Collections.Generic;Dictionary;get_IsFixedSize;();summary;df-generated | | System.Collections.Generic;Dictionary;get_IsReadOnly;();summary;df-generated | | System.Collections.Generic;Dictionary;get_IsSynchronized;();summary;df-generated | +| System.Collections.Generic;Dictionary;get_Item;(TKey);summary;df-generated | +| System.Collections.Generic;Dictionary;get_Keys;();summary;df-generated | +| System.Collections.Generic;Dictionary;get_Values;();summary;df-generated | | System.Collections.Generic;EqualityComparer;Equals;(System.Object,System.Object);summary;df-generated | | System.Collections.Generic;EqualityComparer;Equals;(T,T);summary;df-generated | | System.Collections.Generic;EqualityComparer;GetHashCode;(System.Object);summary;df-generated | @@ -23286,6 +23836,7 @@ neutral | System.Collections.Generic;HashSet+Enumerator;Dispose;();summary;df-generated | | System.Collections.Generic;HashSet+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Generic;HashSet+Enumerator;Reset;();summary;df-generated | +| System.Collections.Generic;HashSet+Enumerator;get_Current;();summary;df-generated | | System.Collections.Generic;HashSet;Contains;(T);summary;df-generated | | System.Collections.Generic;HashSet;CopyTo;(T[]);summary;df-generated | | System.Collections.Generic;HashSet;CopyTo;(T[],System.Int32,System.Int32);summary;df-generated | @@ -23358,6 +23909,7 @@ neutral | System.Collections.Generic;LinkedList+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Generic;LinkedList+Enumerator;OnDeserialization;(System.Object);summary;df-generated | | System.Collections.Generic;LinkedList+Enumerator;Reset;();summary;df-generated | +| System.Collections.Generic;LinkedList+Enumerator;get_Current;();summary;df-generated | | System.Collections.Generic;LinkedList;Contains;(T);summary;df-generated | | System.Collections.Generic;LinkedList;OnDeserialization;(System.Object);summary;df-generated | | System.Collections.Generic;LinkedList;Remove;(T);summary;df-generated | @@ -23370,6 +23922,7 @@ neutral | System.Collections.Generic;List+Enumerator;Dispose;();summary;df-generated | | System.Collections.Generic;List+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Generic;List+Enumerator;Reset;();summary;df-generated | +| System.Collections.Generic;List+Enumerator;get_Current;();summary;df-generated | | System.Collections.Generic;List;BinarySearch;(System.Int32,System.Int32,T,System.Collections.Generic.IComparer);summary;df-generated | | System.Collections.Generic;List;BinarySearch;(T);summary;df-generated | | System.Collections.Generic;List;BinarySearch;(T,System.Collections.Generic.IComparer);summary;df-generated | @@ -23399,6 +23952,7 @@ neutral | System.Collections.Generic;List;get_IsFixedSize;();summary;df-generated | | System.Collections.Generic;List;get_IsReadOnly;();summary;df-generated | | System.Collections.Generic;List;get_IsSynchronized;();summary;df-generated | +| System.Collections.Generic;List;get_Item;(System.Int32);summary;df-generated | | System.Collections.Generic;PriorityQueue+UnorderedItemsCollection+Enumerator;Dispose;();summary;df-generated | | System.Collections.Generic;PriorityQueue+UnorderedItemsCollection+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Generic;PriorityQueue+UnorderedItemsCollection+Enumerator;Reset;();summary;df-generated | @@ -23417,6 +23971,7 @@ neutral | System.Collections.Generic;Queue+Enumerator;Dispose;();summary;df-generated | | System.Collections.Generic;Queue+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Generic;Queue+Enumerator;Reset;();summary;df-generated | +| System.Collections.Generic;Queue+Enumerator;get_Current;();summary;df-generated | | System.Collections.Generic;Queue;Contains;(T);summary;df-generated | | System.Collections.Generic;Queue;EnsureCapacity;(System.Int32);summary;df-generated | | System.Collections.Generic;Queue;Queue;(System.Int32);summary;df-generated | @@ -23430,6 +23985,7 @@ neutral | System.Collections.Generic;SortedDictionary+Enumerator;Dispose;();summary;df-generated | | System.Collections.Generic;SortedDictionary+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Generic;SortedDictionary+Enumerator;Reset;();summary;df-generated | +| System.Collections.Generic;SortedDictionary+Enumerator;get_Current;();summary;df-generated | | System.Collections.Generic;SortedDictionary+KeyCollection+Enumerator;Dispose;();summary;df-generated | | System.Collections.Generic;SortedDictionary+KeyCollection+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Generic;SortedDictionary+KeyCollection+Enumerator;Reset;();summary;df-generated | @@ -23462,6 +24018,9 @@ neutral | System.Collections.Generic;SortedDictionary;get_IsFixedSize;();summary;df-generated | | System.Collections.Generic;SortedDictionary;get_IsReadOnly;();summary;df-generated | | System.Collections.Generic;SortedDictionary;get_IsSynchronized;();summary;df-generated | +| System.Collections.Generic;SortedDictionary;get_Item;(TKey);summary;df-generated | +| System.Collections.Generic;SortedDictionary;get_Keys;();summary;df-generated | +| System.Collections.Generic;SortedDictionary;get_Values;();summary;df-generated | | System.Collections.Generic;SortedList;Contains;(System.Collections.Generic.KeyValuePair);summary;df-generated | | System.Collections.Generic;SortedList;Contains;(System.Object);summary;df-generated | | System.Collections.Generic;SortedList;ContainsKey;(TKey);summary;df-generated | @@ -23475,18 +24034,24 @@ neutral | System.Collections.Generic;SortedList;SortedList;(System.Int32);summary;df-generated | | System.Collections.Generic;SortedList;SortedList;(System.Int32,System.Collections.Generic.IComparer);summary;df-generated | | System.Collections.Generic;SortedList;TrimExcess;();summary;df-generated | +| System.Collections.Generic;SortedList;TryGetValue;(TKey,TValue);summary;df-generated | | System.Collections.Generic;SortedList;get_Count;();summary;df-generated | | System.Collections.Generic;SortedList;get_IsFixedSize;();summary;df-generated | | System.Collections.Generic;SortedList;get_IsReadOnly;();summary;df-generated | | System.Collections.Generic;SortedList;get_IsSynchronized;();summary;df-generated | +| System.Collections.Generic;SortedList;get_Item;(TKey);summary;df-generated | +| System.Collections.Generic;SortedList;get_Keys;();summary;df-generated | +| System.Collections.Generic;SortedList;get_Values;();summary;df-generated | | System.Collections.Generic;SortedSet+Enumerator;Dispose;();summary;df-generated | | System.Collections.Generic;SortedSet+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Generic;SortedSet+Enumerator;OnDeserialization;(System.Object);summary;df-generated | | System.Collections.Generic;SortedSet+Enumerator;Reset;();summary;df-generated | +| System.Collections.Generic;SortedSet+Enumerator;get_Current;();summary;df-generated | | System.Collections.Generic;SortedSet;Contains;(T);summary;df-generated | | System.Collections.Generic;SortedSet;CreateSetComparer;();summary;df-generated | | System.Collections.Generic;SortedSet;CreateSetComparer;(System.Collections.Generic.IEqualityComparer);summary;df-generated | | System.Collections.Generic;SortedSet;ExceptWith;(System.Collections.Generic.IEnumerable);summary;df-generated | +| System.Collections.Generic;SortedSet;IntersectWith;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Generic;SortedSet;IsProperSubsetOf;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Generic;SortedSet;IsProperSupersetOf;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Generic;SortedSet;IsSubsetOf;(System.Collections.Generic.IEnumerable);summary;df-generated | @@ -23496,12 +24061,15 @@ neutral | System.Collections.Generic;SortedSet;Remove;(T);summary;df-generated | | System.Collections.Generic;SortedSet;SetEquals;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Generic;SortedSet;SortedSet;(System.Collections.Generic.IEnumerable);summary;df-generated | +| System.Collections.Generic;SortedSet;SymmetricExceptWith;(System.Collections.Generic.IEnumerable);summary;df-generated | +| System.Collections.Generic;SortedSet;UnionWith;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Generic;SortedSet;get_Count;();summary;df-generated | | System.Collections.Generic;SortedSet;get_IsReadOnly;();summary;df-generated | | System.Collections.Generic;SortedSet;get_IsSynchronized;();summary;df-generated | | System.Collections.Generic;Stack+Enumerator;Dispose;();summary;df-generated | | System.Collections.Generic;Stack+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Generic;Stack+Enumerator;Reset;();summary;df-generated | +| System.Collections.Generic;Stack+Enumerator;get_Current;();summary;df-generated | | System.Collections.Generic;Stack;Contains;(T);summary;df-generated | | System.Collections.Generic;Stack;EnsureCapacity;(System.Int32);summary;df-generated | | System.Collections.Generic;Stack;Stack;(System.Int32);summary;df-generated | @@ -23585,7 +24153,9 @@ neutral | System.Collections.Immutable;ImmutableArray+Builder;Sort;(System.Int32,System.Int32,System.Collections.Generic.IComparer);summary;df-generated | | System.Collections.Immutable;ImmutableArray+Builder;ToArray;();summary;df-generated | | System.Collections.Immutable;ImmutableArray+Builder;ToImmutable;();summary;df-generated | +| System.Collections.Immutable;ImmutableArray+Builder;get_Count;();summary;df-generated | | System.Collections.Immutable;ImmutableArray+Builder;get_IsReadOnly;();summary;df-generated | +| System.Collections.Immutable;ImmutableArray+Builder;get_Item;(System.Int32);summary;df-generated | | System.Collections.Immutable;ImmutableArray+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Immutable;ImmutableArray;Clear;();summary;df-generated | | System.Collections.Immutable;ImmutableArray;CompareTo;(System.Object,System.Collections.IComparer);summary;df-generated | @@ -23605,13 +24175,20 @@ neutral | System.Collections.Immutable;ImmutableArray;IndexOf;(T,System.Int32,System.Collections.Generic.IEqualityComparer);summary;df-generated | | System.Collections.Immutable;ImmutableArray;IndexOf;(T,System.Int32,System.Int32);summary;df-generated | | System.Collections.Immutable;ImmutableArray;IndexOf;(T,System.Int32,System.Int32,System.Collections.Generic.IEqualityComparer);summary;df-generated | +| System.Collections.Immutable;ImmutableArray;Insert;(System.Int32,T);summary;df-generated | +| System.Collections.Immutable;ImmutableArray;InsertRange;(System.Int32,System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableArray;ItemRef;(System.Int32);summary;df-generated | | System.Collections.Immutable;ImmutableArray;LastIndexOf;(T);summary;df-generated | | System.Collections.Immutable;ImmutableArray;LastIndexOf;(T,System.Int32);summary;df-generated | | System.Collections.Immutable;ImmutableArray;LastIndexOf;(T,System.Int32,System.Int32);summary;df-generated | | System.Collections.Immutable;ImmutableArray;LastIndexOf;(T,System.Int32,System.Int32,System.Collections.Generic.IEqualityComparer);summary;df-generated | | System.Collections.Immutable;ImmutableArray;Remove;(T);summary;df-generated | +| System.Collections.Immutable;ImmutableArray;Remove;(T,System.Collections.Generic.IEqualityComparer);summary;df-generated | | System.Collections.Immutable;ImmutableArray;RemoveAt;(System.Int32);summary;df-generated | +| System.Collections.Immutable;ImmutableArray;RemoveRange;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);summary;df-generated | +| System.Collections.Immutable;ImmutableArray;RemoveRange;(System.Int32,System.Int32);summary;df-generated | +| System.Collections.Immutable;ImmutableArray;Replace;(T,T,System.Collections.Generic.IEqualityComparer);summary;df-generated | +| System.Collections.Immutable;ImmutableArray;SetItem;(System.Int32,T);summary;df-generated | | System.Collections.Immutable;ImmutableArray;get_Count;();summary;df-generated | | System.Collections.Immutable;ImmutableArray;get_IsDefault;();summary;df-generated | | System.Collections.Immutable;ImmutableArray;get_IsDefaultOrEmpty;();summary;df-generated | @@ -23619,6 +24196,7 @@ neutral | System.Collections.Immutable;ImmutableArray;get_IsFixedSize;();summary;df-generated | | System.Collections.Immutable;ImmutableArray;get_IsReadOnly;();summary;df-generated | | System.Collections.Immutable;ImmutableArray;get_IsSynchronized;();summary;df-generated | +| System.Collections.Immutable;ImmutableArray;get_Item;(System.Int32);summary;df-generated | | System.Collections.Immutable;ImmutableArray;get_Length;();summary;df-generated | | System.Collections.Immutable;ImmutableArray;op_Equality;(System.Collections.Immutable.ImmutableArray,System.Collections.Immutable.ImmutableArray);summary;df-generated | | System.Collections.Immutable;ImmutableArray;op_Equality;(System.Nullable>,System.Nullable>);summary;df-generated | @@ -23644,9 +24222,14 @@ neutral | System.Collections.Immutable;ImmutableDictionary+Builder;get_IsFixedSize;();summary;df-generated | | System.Collections.Immutable;ImmutableDictionary+Builder;get_IsReadOnly;();summary;df-generated | | System.Collections.Immutable;ImmutableDictionary+Builder;get_IsSynchronized;();summary;df-generated | +| System.Collections.Immutable;ImmutableDictionary+Builder;get_Item;(TKey);summary;df-generated | +| System.Collections.Immutable;ImmutableDictionary+Builder;get_Keys;();summary;df-generated | +| System.Collections.Immutable;ImmutableDictionary+Builder;get_Values;();summary;df-generated | | System.Collections.Immutable;ImmutableDictionary+Enumerator;Dispose;();summary;df-generated | | System.Collections.Immutable;ImmutableDictionary+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Immutable;ImmutableDictionary+Enumerator;Reset;();summary;df-generated | +| System.Collections.Immutable;ImmutableDictionary+Enumerator;get_Current;();summary;df-generated | +| System.Collections.Immutable;ImmutableDictionary;Add;(TKey,TValue);summary;df-generated | | System.Collections.Immutable;ImmutableDictionary;Contains;(System.Collections.Generic.KeyValuePair);summary;df-generated | | System.Collections.Immutable;ImmutableDictionary;Contains;(System.Object);summary;df-generated | | System.Collections.Immutable;ImmutableDictionary;ContainsKey;(TKey);summary;df-generated | @@ -23654,12 +24237,19 @@ neutral | System.Collections.Immutable;ImmutableDictionary;Remove;(System.Collections.Generic.KeyValuePair);summary;df-generated | | System.Collections.Immutable;ImmutableDictionary;Remove;(System.Object);summary;df-generated | | System.Collections.Immutable;ImmutableDictionary;Remove;(TKey);summary;df-generated | +| System.Collections.Immutable;ImmutableDictionary;RemoveRange;(System.Collections.Generic.IEnumerable);summary;df-generated | +| System.Collections.Immutable;ImmutableDictionary;SetItem;(TKey,TValue);summary;df-generated | +| System.Collections.Immutable;ImmutableDictionary;SetItems;(System.Collections.Generic.IEnumerable>);summary;df-generated | +| System.Collections.Immutable;ImmutableDictionary;TryGetKey;(TKey,TKey);summary;df-generated | | System.Collections.Immutable;ImmutableDictionary;TryGetValue;(TKey,TValue);summary;df-generated | | System.Collections.Immutable;ImmutableDictionary;get_Count;();summary;df-generated | | System.Collections.Immutable;ImmutableDictionary;get_IsEmpty;();summary;df-generated | | System.Collections.Immutable;ImmutableDictionary;get_IsFixedSize;();summary;df-generated | | System.Collections.Immutable;ImmutableDictionary;get_IsReadOnly;();summary;df-generated | | System.Collections.Immutable;ImmutableDictionary;get_IsSynchronized;();summary;df-generated | +| System.Collections.Immutable;ImmutableDictionary;get_Item;(TKey);summary;df-generated | +| System.Collections.Immutable;ImmutableDictionary;get_Keys;();summary;df-generated | +| System.Collections.Immutable;ImmutableDictionary;get_Values;();summary;df-generated | | System.Collections.Immutable;ImmutableHashSet;Create;();summary;df-generated | | System.Collections.Immutable;ImmutableHashSet;Create;(System.Collections.Generic.IEqualityComparer);summary;df-generated | | System.Collections.Immutable;ImmutableHashSet;CreateBuilder;();summary;df-generated | @@ -23675,6 +24265,7 @@ neutral | System.Collections.Immutable;ImmutableHashSet+Builder;Overlaps;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableHashSet+Builder;Remove;(T);summary;df-generated | | System.Collections.Immutable;ImmutableHashSet+Builder;SetEquals;(System.Collections.Generic.IEnumerable);summary;df-generated | +| System.Collections.Immutable;ImmutableHashSet+Builder;SymmetricExceptWith;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableHashSet+Builder;ToImmutable;();summary;df-generated | | System.Collections.Immutable;ImmutableHashSet+Builder;UnionWith;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableHashSet+Builder;get_Count;();summary;df-generated | @@ -23682,8 +24273,11 @@ neutral | System.Collections.Immutable;ImmutableHashSet+Enumerator;Dispose;();summary;df-generated | | System.Collections.Immutable;ImmutableHashSet+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Immutable;ImmutableHashSet+Enumerator;Reset;();summary;df-generated | +| System.Collections.Immutable;ImmutableHashSet+Enumerator;get_Current;();summary;df-generated | | System.Collections.Immutable;ImmutableHashSet;Contains;(T);summary;df-generated | +| System.Collections.Immutable;ImmutableHashSet;Except;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableHashSet;ExceptWith;(System.Collections.Generic.IEnumerable);summary;df-generated | +| System.Collections.Immutable;ImmutableHashSet;Intersect;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableHashSet;IntersectWith;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableHashSet;IsProperSubsetOf;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableHashSet;IsProperSupersetOf;(System.Collections.Generic.IEnumerable);summary;df-generated | @@ -23692,7 +24286,10 @@ neutral | System.Collections.Immutable;ImmutableHashSet;Overlaps;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableHashSet;Remove;(T);summary;df-generated | | System.Collections.Immutable;ImmutableHashSet;SetEquals;(System.Collections.Generic.IEnumerable);summary;df-generated | +| System.Collections.Immutable;ImmutableHashSet;SymmetricExcept;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableHashSet;SymmetricExceptWith;(System.Collections.Generic.IEnumerable);summary;df-generated | +| System.Collections.Immutable;ImmutableHashSet;TryGetValue;(T,T);summary;df-generated | +| System.Collections.Immutable;ImmutableHashSet;Union;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableHashSet;UnionWith;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableHashSet;get_Count;();summary;df-generated | | System.Collections.Immutable;ImmutableHashSet;get_IsEmpty;();summary;df-generated | @@ -23754,6 +24351,7 @@ neutral | System.Collections.Immutable;ImmutableList+Enumerator;Dispose;();summary;df-generated | | System.Collections.Immutable;ImmutableList+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Immutable;ImmutableList+Enumerator;Reset;();summary;df-generated | +| System.Collections.Immutable;ImmutableList+Enumerator;get_Current;();summary;df-generated | | System.Collections.Immutable;ImmutableList;BinarySearch;(T);summary;df-generated | | System.Collections.Immutable;ImmutableList;Clear;();summary;df-generated | | System.Collections.Immutable;ImmutableList;Contains;(System.Object);summary;df-generated | @@ -23762,18 +24360,29 @@ neutral | System.Collections.Immutable;ImmutableList;IndexOf;(System.Object);summary;df-generated | | System.Collections.Immutable;ImmutableList;IndexOf;(T);summary;df-generated | | System.Collections.Immutable;ImmutableList;IndexOf;(T,System.Int32,System.Int32,System.Collections.Generic.IEqualityComparer);summary;df-generated | +| System.Collections.Immutable;ImmutableList;Insert;(System.Int32,T);summary;df-generated | +| System.Collections.Immutable;ImmutableList;InsertRange;(System.Int32,System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableList;ItemRef;(System.Int32);summary;df-generated | | System.Collections.Immutable;ImmutableList;LastIndexOf;(T,System.Int32,System.Int32,System.Collections.Generic.IEqualityComparer);summary;df-generated | | System.Collections.Immutable;ImmutableList;Remove;(T);summary;df-generated | +| System.Collections.Immutable;ImmutableList;Remove;(T,System.Collections.Generic.IEqualityComparer);summary;df-generated | | System.Collections.Immutable;ImmutableList;RemoveAt;(System.Int32);summary;df-generated | +| System.Collections.Immutable;ImmutableList;RemoveRange;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);summary;df-generated | +| System.Collections.Immutable;ImmutableList;RemoveRange;(System.Int32,System.Int32);summary;df-generated | +| System.Collections.Immutable;ImmutableList;Replace;(T,T,System.Collections.Generic.IEqualityComparer);summary;df-generated | +| System.Collections.Immutable;ImmutableList;SetItem;(System.Int32,T);summary;df-generated | | System.Collections.Immutable;ImmutableList;get_Count;();summary;df-generated | | System.Collections.Immutable;ImmutableList;get_IsEmpty;();summary;df-generated | | System.Collections.Immutable;ImmutableList;get_IsFixedSize;();summary;df-generated | | System.Collections.Immutable;ImmutableList;get_IsReadOnly;();summary;df-generated | | System.Collections.Immutable;ImmutableList;get_IsSynchronized;();summary;df-generated | +| System.Collections.Immutable;ImmutableList;get_Item;(System.Int32);summary;df-generated | | System.Collections.Immutable;ImmutableQueue;Create;();summary;df-generated | | System.Collections.Immutable;ImmutableQueue+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Immutable;ImmutableQueue;Clear;();summary;df-generated | +| System.Collections.Immutable;ImmutableQueue;Dequeue;();summary;df-generated | +| System.Collections.Immutable;ImmutableQueue;Enqueue;(T);summary;df-generated | +| System.Collections.Immutable;ImmutableQueue;Peek;();summary;df-generated | | System.Collections.Immutable;ImmutableQueue;PeekRef;();summary;df-generated | | System.Collections.Immutable;ImmutableQueue;get_Empty;();summary;df-generated | | System.Collections.Immutable;ImmutableQueue;get_IsEmpty;();summary;df-generated | @@ -23796,9 +24405,14 @@ neutral | System.Collections.Immutable;ImmutableSortedDictionary+Builder;get_IsFixedSize;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary+Builder;get_IsReadOnly;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary+Builder;get_IsSynchronized;();summary;df-generated | +| System.Collections.Immutable;ImmutableSortedDictionary+Builder;get_Item;(TKey);summary;df-generated | +| System.Collections.Immutable;ImmutableSortedDictionary+Builder;get_Keys;();summary;df-generated | +| System.Collections.Immutable;ImmutableSortedDictionary+Builder;get_Values;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary+Enumerator;Dispose;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary+Enumerator;Reset;();summary;df-generated | +| System.Collections.Immutable;ImmutableSortedDictionary+Enumerator;get_Current;();summary;df-generated | +| System.Collections.Immutable;ImmutableSortedDictionary;Add;(TKey,TValue);summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary;Contains;(System.Collections.Generic.KeyValuePair);summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary;Contains;(System.Object);summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary;ContainsKey;(TKey);summary;df-generated | @@ -23806,6 +24420,10 @@ neutral | System.Collections.Immutable;ImmutableSortedDictionary;Remove;(System.Collections.Generic.KeyValuePair);summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary;Remove;(System.Object);summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary;Remove;(TKey);summary;df-generated | +| System.Collections.Immutable;ImmutableSortedDictionary;RemoveRange;(System.Collections.Generic.IEnumerable);summary;df-generated | +| System.Collections.Immutable;ImmutableSortedDictionary;SetItem;(TKey,TValue);summary;df-generated | +| System.Collections.Immutable;ImmutableSortedDictionary;SetItems;(System.Collections.Generic.IEnumerable>);summary;df-generated | +| System.Collections.Immutable;ImmutableSortedDictionary;TryGetKey;(TKey,TKey);summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary;TryGetValue;(TKey,TValue);summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary;ValueRef;(TKey);summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary;get_Count;();summary;df-generated | @@ -23813,12 +24431,16 @@ neutral | System.Collections.Immutable;ImmutableSortedDictionary;get_IsFixedSize;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary;get_IsReadOnly;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedDictionary;get_IsSynchronized;();summary;df-generated | +| System.Collections.Immutable;ImmutableSortedDictionary;get_Item;(TKey);summary;df-generated | +| System.Collections.Immutable;ImmutableSortedDictionary;get_Keys;();summary;df-generated | +| System.Collections.Immutable;ImmutableSortedDictionary;get_Values;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;Create;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;CreateBuilder;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;ToImmutableSortedSet;(System.Collections.Immutable.ImmutableSortedSet+Builder);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet+Builder;Contains;(T);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet+Builder;ExceptWith;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet+Builder;IndexOf;(T);summary;df-generated | +| System.Collections.Immutable;ImmutableSortedSet+Builder;IntersectWith;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet+Builder;IsProperSubsetOf;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet+Builder;IsProperSupersetOf;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet+Builder;IsSubsetOf;(System.Collections.Generic.IEnumerable);summary;df-generated | @@ -23827,7 +24449,9 @@ neutral | System.Collections.Immutable;ImmutableSortedSet+Builder;Overlaps;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet+Builder;Remove;(T);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet+Builder;SetEquals;(System.Collections.Generic.IEnumerable);summary;df-generated | +| System.Collections.Immutable;ImmutableSortedSet+Builder;SymmetricExceptWith;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet+Builder;ToImmutable;();summary;df-generated | +| System.Collections.Immutable;ImmutableSortedSet+Builder;UnionWith;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet+Builder;get_Count;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet+Builder;get_IsReadOnly;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet+Builder;get_IsSynchronized;();summary;df-generated | @@ -23835,11 +24459,14 @@ neutral | System.Collections.Immutable;ImmutableSortedSet+Enumerator;Dispose;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet+Enumerator;Reset;();summary;df-generated | +| System.Collections.Immutable;ImmutableSortedSet+Enumerator;get_Current;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;Contains;(System.Object);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;Contains;(T);summary;df-generated | +| System.Collections.Immutable;ImmutableSortedSet;Except;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;ExceptWith;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;IndexOf;(System.Object);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;IndexOf;(T);summary;df-generated | +| System.Collections.Immutable;ImmutableSortedSet;Intersect;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;IntersectWith;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;IsProperSubsetOf;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;IsProperSupersetOf;(System.Collections.Generic.IEnumerable);summary;df-generated | @@ -23850,17 +24477,24 @@ neutral | System.Collections.Immutable;ImmutableSortedSet;Remove;(T);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;RemoveAt;(System.Int32);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;SetEquals;(System.Collections.Generic.IEnumerable);summary;df-generated | +| System.Collections.Immutable;ImmutableSortedSet;SymmetricExcept;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;SymmetricExceptWith;(System.Collections.Generic.IEnumerable);summary;df-generated | +| System.Collections.Immutable;ImmutableSortedSet;TryGetValue;(T,T);summary;df-generated | +| System.Collections.Immutable;ImmutableSortedSet;Union;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;UnionWith;(System.Collections.Generic.IEnumerable);summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;get_Count;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;get_IsEmpty;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;get_IsFixedSize;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;get_IsReadOnly;();summary;df-generated | | System.Collections.Immutable;ImmutableSortedSet;get_IsSynchronized;();summary;df-generated | +| System.Collections.Immutable;ImmutableSortedSet;get_Item;(System.Int32);summary;df-generated | | System.Collections.Immutable;ImmutableStack;Create;();summary;df-generated | | System.Collections.Immutable;ImmutableStack+Enumerator;MoveNext;();summary;df-generated | | System.Collections.Immutable;ImmutableStack;Clear;();summary;df-generated | +| System.Collections.Immutable;ImmutableStack;Peek;();summary;df-generated | | System.Collections.Immutable;ImmutableStack;PeekRef;();summary;df-generated | +| System.Collections.Immutable;ImmutableStack;Pop;();summary;df-generated | +| System.Collections.Immutable;ImmutableStack;Push;(T);summary;df-generated | | System.Collections.Immutable;ImmutableStack;get_Empty;();summary;df-generated | | System.Collections.Immutable;ImmutableStack;get_IsEmpty;();summary;df-generated | | System.Collections.ObjectModel;Collection;ClearItems;();summary;df-generated | @@ -23875,6 +24509,7 @@ neutral | System.Collections.ObjectModel;Collection;get_IsFixedSize;();summary;df-generated | | System.Collections.ObjectModel;Collection;get_IsReadOnly;();summary;df-generated | | System.Collections.ObjectModel;Collection;get_IsSynchronized;();summary;df-generated | +| System.Collections.ObjectModel;Collection;get_Item;(System.Int32);summary;df-generated | | System.Collections.ObjectModel;KeyedCollection;ChangeItemKey;(TItem,TKey);summary;df-generated | | System.Collections.ObjectModel;KeyedCollection;ClearItems;();summary;df-generated | | System.Collections.ObjectModel;KeyedCollection;Contains;(TKey);summary;df-generated | @@ -23903,6 +24538,7 @@ neutral | System.Collections.ObjectModel;ReadOnlyCollection;get_IsFixedSize;();summary;df-generated | | System.Collections.ObjectModel;ReadOnlyCollection;get_IsReadOnly;();summary;df-generated | | System.Collections.ObjectModel;ReadOnlyCollection;get_IsSynchronized;();summary;df-generated | +| System.Collections.ObjectModel;ReadOnlyCollection;get_Item;(System.Int32);summary;df-generated | | System.Collections.ObjectModel;ReadOnlyDictionary+KeyCollection;Contains;(TKey);summary;df-generated | | System.Collections.ObjectModel;ReadOnlyDictionary+KeyCollection;Remove;(TKey);summary;df-generated | | System.Collections.ObjectModel;ReadOnlyDictionary+KeyCollection;get_Count;();summary;df-generated | @@ -23925,6 +24561,9 @@ neutral | System.Collections.ObjectModel;ReadOnlyDictionary;get_IsFixedSize;();summary;df-generated | | System.Collections.ObjectModel;ReadOnlyDictionary;get_IsReadOnly;();summary;df-generated | | System.Collections.ObjectModel;ReadOnlyDictionary;get_IsSynchronized;();summary;df-generated | +| System.Collections.ObjectModel;ReadOnlyDictionary;get_Item;(TKey);summary;df-generated | +| System.Collections.ObjectModel;ReadOnlyDictionary;get_Keys;();summary;df-generated | +| System.Collections.ObjectModel;ReadOnlyDictionary;get_Values;();summary;df-generated | | System.Collections.ObjectModel;ReadOnlyObservableCollection;OnCollectionChanged;(System.Collections.Specialized.NotifyCollectionChangedEventArgs);summary;df-generated | | System.Collections.ObjectModel;ReadOnlyObservableCollection;OnPropertyChanged;(System.ComponentModel.PropertyChangedEventArgs);summary;df-generated | | System.Collections.ObjectModel;ReadOnlyObservableCollection;ReadOnlyObservableCollection;(System.Collections.ObjectModel.ObservableCollection);summary;df-generated | @@ -24010,6 +24649,7 @@ neutral | System.Collections.Specialized;NotifyCollectionChangedEventArgs;get_NewStartingIndex;();summary;df-generated | | System.Collections.Specialized;NotifyCollectionChangedEventArgs;get_OldStartingIndex;();summary;df-generated | | System.Collections.Specialized;OrderedDictionary;Contains;(System.Object);summary;df-generated | +| System.Collections.Specialized;OrderedDictionary;GetEnumerator;();summary;df-generated | | System.Collections.Specialized;OrderedDictionary;Insert;(System.Int32,System.Object,System.Object);summary;df-generated | | System.Collections.Specialized;OrderedDictionary;OnDeserialization;(System.Object);summary;df-generated | | System.Collections.Specialized;OrderedDictionary;OrderedDictionary;(System.Collections.IEqualityComparer);summary;df-generated | @@ -24193,6 +24833,8 @@ neutral | System.ComponentModel.DataAnnotations.Schema;DatabaseGeneratedAttribute;get_DatabaseGeneratedOption;();summary;df-generated | | System.ComponentModel.DataAnnotations.Schema;ForeignKeyAttribute;ForeignKeyAttribute;(System.String);summary;df-generated | | System.ComponentModel.DataAnnotations.Schema;ForeignKeyAttribute;get_Name;();summary;df-generated | +| System.ComponentModel.DataAnnotations.Schema;IndexAttribute;Equals;(System.Object);summary;df-generated | +| System.ComponentModel.DataAnnotations.Schema;IndexAttribute;GetHashCode;();summary;df-generated | | System.ComponentModel.DataAnnotations.Schema;InversePropertyAttribute;InversePropertyAttribute;(System.String);summary;df-generated | | System.ComponentModel.DataAnnotations.Schema;InversePropertyAttribute;get_Property;();summary;df-generated | | System.ComponentModel.DataAnnotations.Schema;TableAttribute;TableAttribute;(System.String);summary;df-generated | @@ -25167,6 +25809,7 @@ neutral | System.ComponentModel;PropertyDescriptorCollection;InternalSort;(System.Collections.IComparer);summary;df-generated | | System.ComponentModel;PropertyDescriptorCollection;InternalSort;(System.String[]);summary;df-generated | | System.ComponentModel;PropertyDescriptorCollection;Remove;(System.ComponentModel.PropertyDescriptor);summary;df-generated | +| System.ComponentModel;PropertyDescriptorCollection;Remove;(System.Object);summary;df-generated | | System.ComponentModel;PropertyDescriptorCollection;RemoveAt;(System.Int32);summary;df-generated | | System.ComponentModel;PropertyDescriptorCollection;get_Count;();summary;df-generated | | System.ComponentModel;PropertyDescriptorCollection;get_IsFixedSize;();summary;df-generated | @@ -25968,15 +26611,18 @@ neutral | System.Data.Common;DbDataReader;GetChars;(System.Int32,System.Int64,System.Char[],System.Int32,System.Int32);summary;df-generated | | System.Data.Common;DbDataReader;GetColumnSchemaAsync;(System.Threading.CancellationToken);summary;df-generated | | System.Data.Common;DbDataReader;GetData;(System.Int32);summary;df-generated | +| System.Data.Common;DbDataReader;GetDataTypeName;(System.Int32);summary;manual | | System.Data.Common;DbDataReader;GetDateTime;(System.Int32);summary;df-generated | | System.Data.Common;DbDataReader;GetDbDataReader;(System.Int32);summary;df-generated | | System.Data.Common;DbDataReader;GetDecimal;(System.Int32);summary;df-generated | | System.Data.Common;DbDataReader;GetDouble;(System.Int32);summary;df-generated | | System.Data.Common;DbDataReader;GetFieldType;(System.Int32);summary;df-generated | | System.Data.Common;DbDataReader;GetFloat;(System.Int32);summary;df-generated | +| System.Data.Common;DbDataReader;GetGuid;(System.Int32);summary;manual | | System.Data.Common;DbDataReader;GetInt16;(System.Int32);summary;df-generated | | System.Data.Common;DbDataReader;GetInt32;(System.Int32);summary;df-generated | | System.Data.Common;DbDataReader;GetInt64;(System.Int32);summary;df-generated | +| System.Data.Common;DbDataReader;GetName;(System.Int32);summary;manual | | System.Data.Common;DbDataReader;GetOrdinal;(System.String);summary;df-generated | | System.Data.Common;DbDataReader;GetProviderSpecificFieldType;(System.Int32);summary;df-generated | | System.Data.Common;DbDataReader;GetStream;(System.Int32);summary;df-generated | @@ -26006,6 +26652,7 @@ neutral | System.Data.Common;DbDataRecord;GetComponentName;();summary;df-generated | | System.Data.Common;DbDataRecord;GetConverter;();summary;df-generated | | System.Data.Common;DbDataRecord;GetData;(System.Int32);summary;df-generated | +| System.Data.Common;DbDataRecord;GetDataTypeName;(System.Int32);summary;manual | | System.Data.Common;DbDataRecord;GetDateTime;(System.Int32);summary;df-generated | | System.Data.Common;DbDataRecord;GetDbDataReader;(System.Int32);summary;df-generated | | System.Data.Common;DbDataRecord;GetDecimal;(System.Int32);summary;df-generated | @@ -26017,9 +26664,11 @@ neutral | System.Data.Common;DbDataRecord;GetEvents;(System.Attribute[]);summary;df-generated | | System.Data.Common;DbDataRecord;GetFieldType;(System.Int32);summary;df-generated | | System.Data.Common;DbDataRecord;GetFloat;(System.Int32);summary;df-generated | +| System.Data.Common;DbDataRecord;GetGuid;(System.Int32);summary;manual | | System.Data.Common;DbDataRecord;GetInt16;(System.Int32);summary;df-generated | | System.Data.Common;DbDataRecord;GetInt32;(System.Int32);summary;df-generated | | System.Data.Common;DbDataRecord;GetInt64;(System.Int32);summary;df-generated | +| System.Data.Common;DbDataRecord;GetName;(System.Int32);summary;manual | | System.Data.Common;DbDataRecord;GetOrdinal;(System.String);summary;df-generated | | System.Data.Common;DbDataRecord;IsDBNull;(System.Int32);summary;df-generated | | System.Data.Common;DbDataRecord;get_FieldCount;();summary;df-generated | @@ -26047,6 +26696,7 @@ neutral | System.Data.Common;DbException;get_IsTransient;();summary;df-generated | | System.Data.Common;DbException;get_SqlState;();summary;df-generated | | System.Data.Common;DbParameter;ResetDbType;();summary;df-generated | +| System.Data.Common;DbParameter;get_IsNullable;();summary;df-generated | | System.Data.Common;DbParameterCollection;Contains;(System.Object);summary;df-generated | | System.Data.Common;DbParameterCollection;Contains;(System.String);summary;df-generated | | System.Data.Common;DbParameterCollection;IndexOf;(System.Object);summary;df-generated | @@ -26096,6 +26746,150 @@ neutral | System.Data.Common;RowUpdatedEventArgs;get_RowCount;();summary;df-generated | | System.Data.Common;RowUpdatedEventArgs;get_StatementType;();summary;df-generated | | System.Data.Common;RowUpdatingEventArgs;get_StatementType;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityCommand;Cancel;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityCommand;CreateDbParameter;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityCommand;ExecuteNonQuery;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityCommand;ExecuteNonQueryAsync;(System.Threading.CancellationToken);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityCommand;Prepare;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityConnection;ChangeDatabase;(System.String);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityConnection;Close;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityConnection;Dispose;(System.Boolean);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityConnection;EnlistTransaction;(System.Transactions.Transaction);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityConnection;Open;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityConnection;get_ConnectionTimeout;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityConnection;get_DataSource;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityConnection;get_Database;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityConnection;get_DbProviderFactory;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityConnection;get_State;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityConnectionStringBuilder;ContainsKey;(System.String);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityConnectionStringBuilder;Remove;(System.String);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityConnectionStringBuilder;get_IsFixedSize;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;Close;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;Dispose;(System.Boolean);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetBoolean;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetByte;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetBytes;(System.Int32,System.Int64,System.Byte[],System.Int32,System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetChar;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetChars;(System.Int32,System.Int64,System.Char[],System.Int32,System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetDataTypeName;(System.Int32);summary;manual | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetDateTime;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetDbDataReader;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetDecimal;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetDouble;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetFieldType;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetFloat;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetGuid;(System.Int32);summary;manual | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetInt16;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetInt32;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetInt64;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetName;(System.Int32);summary;manual | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetOrdinal;(System.String);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;GetProviderSpecificFieldType;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;IsDBNull;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;NextResult;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;NextResultAsync;(System.Threading.CancellationToken);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;Read;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;ReadAsync;(System.Threading.CancellationToken);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;get_Depth;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;get_FieldCount;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;get_HasRows;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;get_IsClosed;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;get_RecordsAffected;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityDataReader;get_VisibleFieldCount;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityParameter;ResetDbType;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityParameter;get_IsNullable;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityParameterCollection;Contains;(System.Object);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityParameterCollection;Contains;(System.String);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityParameterCollection;IndexOf;(System.Object);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityParameterCollection;IndexOf;(System.String);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityParameterCollection;Remove;(System.Object);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityParameterCollection;RemoveAt;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityParameterCollection;RemoveAt;(System.String);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityParameterCollection;get_Count;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityParameterCollection;get_IsFixedSize;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityParameterCollection;get_IsReadOnly;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityParameterCollection;get_IsSynchronized;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityProviderFactory;CreateCommand;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityProviderFactory;CreateCommandBuilder;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityProviderFactory;CreateConnection;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityProviderFactory;CreateConnectionStringBuilder;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityProviderFactory;CreateDataAdapter;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityProviderFactory;CreateParameter;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityTransaction;Commit;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityTransaction;Dispose;(System.Boolean);summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityTransaction;Rollback;();summary;df-generated | +| System.Data.Entity.Core.EntityClient;EntityTransaction;get_IsolationLevel;();summary;df-generated | +| System.Data.Entity.Core.Metadata.Edm;ReadOnlyMetadataCollection+Enumerator;Dispose;();summary;df-generated | +| System.Data.Entity.Core.Metadata.Edm;ReadOnlyMetadataCollection+Enumerator;MoveNext;();summary;df-generated | +| System.Data.Entity.Core.Metadata.Edm;ReadOnlyMetadataCollection+Enumerator;Reset;();summary;df-generated | +| System.Data.Entity.Core.Metadata.Edm;ReadOnlyMetadataCollection+Enumerator;get_Current;();summary;df-generated | +| System.Data.Entity.Core.Objects.DataClasses;EntityCollection;Contains;(TEntity);summary;df-generated | +| System.Data.Entity.Core.Objects.DataClasses;EntityCollection;Remove;(TEntity);summary;df-generated | +| System.Data.Entity.Core.Objects.DataClasses;EntityCollection;get_ContainsListCollection;();summary;df-generated | +| System.Data.Entity.Core.Objects.DataClasses;EntityCollection;get_Count;();summary;df-generated | +| System.Data.Entity.Core.Objects.DataClasses;EntityCollection;get_IsReadOnly;();summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetBoolean;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetByte;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetBytes;(System.Int32,System.Int64,System.Byte[],System.Int32,System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetChar;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetChars;(System.Int32,System.Int64,System.Char[],System.Int32,System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetData;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetDataTypeName;(System.Int32);summary;manual | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetDateTime;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetDbDataReader;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetDecimal;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetDouble;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetFieldType;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetFloat;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetGuid;(System.Int32);summary;manual | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetInt16;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetInt32;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetInt64;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetName;(System.Int32);summary;manual | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;GetOrdinal;(System.String);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;IsDBNull;(System.Int32);summary;df-generated | +| System.Data.Entity.Core.Objects;DbUpdatableDataRecord;get_FieldCount;();summary;df-generated | +| System.Data.Entity.Core.Objects;ObjectContext;Dispose;();summary;df-generated | +| System.Data.Entity.Core.Objects;ObjectParameterCollection;Contains;(System.Data.Entity.Core.Objects.ObjectParameter);summary;df-generated | +| System.Data.Entity.Core.Objects;ObjectParameterCollection;Remove;(System.Data.Entity.Core.Objects.ObjectParameter);summary;df-generated | +| System.Data.Entity.Core.Objects;ObjectParameterCollection;get_Count;();summary;df-generated | +| System.Data.Entity.Core.Objects;ObjectParameterCollection;get_IsReadOnly;();summary;df-generated | +| System.Data.Entity.Core.Objects;ObjectQuery;get_ContainsListCollection;();summary;df-generated | +| System.Data.Entity.Core.Objects;ObjectQuery;get_ElementType;();summary;df-generated | +| System.Data.Entity.Core.Objects;ObjectResult;Dispose;();summary;df-generated | +| System.Data.Entity.Core.Objects;ObjectResult;get_ContainsListCollection;();summary;df-generated | +| System.Data.Entity.Core.Objects;ProxyDataContractResolver;ResolveName;(System.String,System.String,System.Type,System.Runtime.Serialization.DataContractResolver);summary;df-generated | +| System.Data.Entity.Core.Objects;ProxyDataContractResolver;TryResolveType;(System.Type,System.Type,System.Runtime.Serialization.DataContractResolver,System.Xml.XmlDictionaryString,System.Xml.XmlDictionaryString);summary;df-generated | +| System.Data.Entity.Core;EntityKey;Equals;(System.Data.Entity.Core.EntityKey);summary;df-generated | +| System.Data.Entity.Hierarchy;HierarchyId;CompareTo;(System.Object);summary;df-generated | +| System.Data.Entity.Infrastructure.Interception;DatabaseLogger;Dispose;();summary;df-generated | +| System.Data.Entity.Infrastructure;DbQuery;get_ContainsListCollection;();summary;df-generated | +| System.Data.Entity.Infrastructure;DbQuery;get_ElementType;();summary;df-generated | +| System.Data.Entity.Infrastructure;DbQuery;get_ContainsListCollection;();summary;df-generated | +| System.Data.Entity.Infrastructure;DbQuery;get_ElementType;();summary;df-generated | +| System.Data.Entity.Infrastructure;DbRawSqlQuery;get_ContainsListCollection;();summary;df-generated | +| System.Data.Entity.Infrastructure;DbRawSqlQuery;get_ContainsListCollection;();summary;df-generated | +| System.Data.Entity.Infrastructure;ObjectReferenceEqualityComparer;Equals;(System.Object,System.Object);summary;df-generated | +| System.Data.Entity.Infrastructure;ObjectReferenceEqualityComparer;GetHashCode;(System.Object);summary;df-generated | +| System.Data.Entity.Infrastructure;TransactionHandler;Dispose;();summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;Close;();summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;Flush;();summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;Write;(System.Boolean);summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;Write;(System.Char);summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;Write;(System.Double);summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;Write;(System.Int32);summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;Write;(System.Int64);summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;Write;(System.Single);summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;WriteLine;();summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;WriteLine;(System.Boolean);summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;WriteLine;(System.Char);summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;WriteLine;(System.Double);summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;WriteLine;(System.Int32);summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;WriteLine;(System.Int64);summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;WriteLine;(System.Single);summary;df-generated | +| System.Data.Entity.Migrations.Utilities;IndentedTextWriter;WriteLine;(System.UInt32);summary;df-generated | +| System.Data.Entity;DbContext;Dispose;();summary;df-generated | +| System.Data.Entity;DbContextTransaction;Dispose;();summary;df-generated | | System.Data.Odbc;OdbcPermission;Add;(System.String,System.String,System.Data.KeyRestrictionBehavior);summary;df-generated | | System.Data.Odbc;OdbcPermission;OdbcPermission;(System.Security.Permissions.PermissionState);summary;df-generated | | System.Data.Odbc;OdbcPermission;OdbcPermission;(System.Security.Permissions.PermissionState,System.Boolean);summary;df-generated | @@ -26115,11 +26909,95 @@ neutral | System.Data.OracleClient;OraclePermissionAttribute;OraclePermissionAttribute;(System.Security.Permissions.SecurityAction);summary;df-generated | | System.Data.OracleClient;OraclePermissionAttribute;ShouldSerializeConnectionString;();summary;df-generated | | System.Data.OracleClient;OraclePermissionAttribute;ShouldSerializeKeyRestrictions;();summary;df-generated | +| System.Data.SqlClient;SqlBulkCopy;Dispose;();summary;df-generated | +| System.Data.SqlClient;SqlClientFactory;CreateCommand;();summary;df-generated | +| System.Data.SqlClient;SqlClientFactory;CreateCommandBuilder;();summary;df-generated | +| System.Data.SqlClient;SqlClientFactory;CreateConnection;();summary;df-generated | +| System.Data.SqlClient;SqlClientFactory;CreateConnectionStringBuilder;();summary;df-generated | +| System.Data.SqlClient;SqlClientFactory;CreateDataAdapter;();summary;df-generated | +| System.Data.SqlClient;SqlClientFactory;CreateParameter;();summary;df-generated | | System.Data.SqlClient;SqlClientPermission;Add;(System.String,System.String,System.Data.KeyRestrictionBehavior);summary;df-generated | | System.Data.SqlClient;SqlClientPermission;SqlClientPermission;(System.Security.Permissions.PermissionState);summary;df-generated | | System.Data.SqlClient;SqlClientPermission;SqlClientPermission;(System.Security.Permissions.PermissionState,System.Boolean);summary;df-generated | | System.Data.SqlClient;SqlClientPermissionAttribute;CreatePermission;();summary;df-generated | | System.Data.SqlClient;SqlClientPermissionAttribute;SqlClientPermissionAttribute;(System.Security.Permissions.SecurityAction);summary;df-generated | +| System.Data.SqlClient;SqlCommand;Cancel;();summary;df-generated | +| System.Data.SqlClient;SqlCommand;CreateDbParameter;();summary;df-generated | +| System.Data.SqlClient;SqlCommand;Dispose;(System.Boolean);summary;df-generated | +| System.Data.SqlClient;SqlCommand;ExecuteNonQuery;();summary;df-generated | +| System.Data.SqlClient;SqlCommand;ExecuteNonQueryAsync;(System.Threading.CancellationToken);summary;df-generated | +| System.Data.SqlClient;SqlCommand;Prepare;();summary;df-generated | +| System.Data.SqlClient;SqlCommandBuilder;ApplyParameterInfo;(System.Data.Common.DbParameter,System.Data.DataRow,System.Data.StatementType,System.Boolean);summary;df-generated | +| System.Data.SqlClient;SqlCommandBuilder;GetParameterName;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlCommandBuilder;GetParameterPlaceholder;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlCommandBuilder;GetSchemaTable;(System.Data.Common.DbCommand);summary;df-generated | +| System.Data.SqlClient;SqlCommandBuilder;SetRowUpdatingHandler;(System.Data.Common.DbDataAdapter);summary;df-generated | +| System.Data.SqlClient;SqlConnection;ChangeDatabase;(System.String);summary;df-generated | +| System.Data.SqlClient;SqlConnection;Close;();summary;df-generated | +| System.Data.SqlClient;SqlConnection;Dispose;(System.Boolean);summary;df-generated | +| System.Data.SqlClient;SqlConnection;GetSchema;();summary;df-generated | +| System.Data.SqlClient;SqlConnection;GetSchema;(System.String);summary;df-generated | +| System.Data.SqlClient;SqlConnection;GetSchema;(System.String,System.String[]);summary;df-generated | +| System.Data.SqlClient;SqlConnection;Open;();summary;df-generated | +| System.Data.SqlClient;SqlConnection;get_ConnectionTimeout;();summary;df-generated | +| System.Data.SqlClient;SqlConnection;get_DataSource;();summary;df-generated | +| System.Data.SqlClient;SqlConnection;get_Database;();summary;df-generated | +| System.Data.SqlClient;SqlConnection;get_State;();summary;df-generated | +| System.Data.SqlClient;SqlConnectionStringBuilder;ContainsKey;(System.String);summary;df-generated | +| System.Data.SqlClient;SqlConnectionStringBuilder;Remove;(System.String);summary;df-generated | +| System.Data.SqlClient;SqlConnectionStringBuilder;ShouldSerialize;(System.String);summary;df-generated | +| System.Data.SqlClient;SqlDataAdapter;OnRowUpdated;(System.Data.Common.RowUpdatedEventArgs);summary;df-generated | +| System.Data.SqlClient;SqlDataAdapter;OnRowUpdating;(System.Data.Common.RowUpdatingEventArgs);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetBoolean;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetByte;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetBytes;(System.Int32,System.Int64,System.Byte[],System.Int32,System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetChar;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetChars;(System.Int32,System.Int64,System.Char[],System.Int32,System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetColumnSchema;();summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetDataTypeName;(System.Int32);summary;manual | +| System.Data.SqlClient;SqlDataReader;GetDateTime;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetDecimal;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetDouble;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetFieldType;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetFloat;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetGuid;(System.Int32);summary;manual | +| System.Data.SqlClient;SqlDataReader;GetInt16;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetInt32;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetInt64;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetName;(System.Int32);summary;manual | +| System.Data.SqlClient;SqlDataReader;GetOrdinal;(System.String);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetProviderSpecificFieldType;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;GetStream;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;IsDBNull;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;IsDBNullAsync;(System.Int32,System.Threading.CancellationToken);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;NextResult;();summary;df-generated | +| System.Data.SqlClient;SqlDataReader;NextResultAsync;(System.Threading.CancellationToken);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;Read;();summary;df-generated | +| System.Data.SqlClient;SqlDataReader;ReadAsync;(System.Threading.CancellationToken);summary;df-generated | +| System.Data.SqlClient;SqlDataReader;get_Depth;();summary;df-generated | +| System.Data.SqlClient;SqlDataReader;get_FieldCount;();summary;df-generated | +| System.Data.SqlClient;SqlDataReader;get_HasRows;();summary;df-generated | +| System.Data.SqlClient;SqlDataReader;get_IsClosed;();summary;df-generated | +| System.Data.SqlClient;SqlDataReader;get_RecordsAffected;();summary;df-generated | +| System.Data.SqlClient;SqlDataReader;get_VisibleFieldCount;();summary;df-generated | +| System.Data.SqlClient;SqlErrorCollection;get_Count;();summary;df-generated | +| System.Data.SqlClient;SqlErrorCollection;get_IsSynchronized;();summary;df-generated | +| System.Data.SqlClient;SqlParameter;ResetDbType;();summary;df-generated | +| System.Data.SqlClient;SqlParameter;get_IsNullable;();summary;df-generated | +| System.Data.SqlClient;SqlParameterCollection;Contains;(System.Object);summary;df-generated | +| System.Data.SqlClient;SqlParameterCollection;Contains;(System.String);summary;df-generated | +| System.Data.SqlClient;SqlParameterCollection;IndexOf;(System.Object);summary;df-generated | +| System.Data.SqlClient;SqlParameterCollection;IndexOf;(System.String);summary;df-generated | +| System.Data.SqlClient;SqlParameterCollection;Remove;(System.Object);summary;df-generated | +| System.Data.SqlClient;SqlParameterCollection;RemoveAt;(System.Int32);summary;df-generated | +| System.Data.SqlClient;SqlParameterCollection;RemoveAt;(System.String);summary;df-generated | +| System.Data.SqlClient;SqlParameterCollection;get_Count;();summary;df-generated | +| System.Data.SqlClient;SqlParameterCollection;get_IsFixedSize;();summary;df-generated | +| System.Data.SqlClient;SqlParameterCollection;get_IsReadOnly;();summary;df-generated | +| System.Data.SqlClient;SqlTransaction;Commit;();summary;df-generated | +| System.Data.SqlClient;SqlTransaction;Dispose;(System.Boolean);summary;df-generated | +| System.Data.SqlClient;SqlTransaction;Rollback;();summary;df-generated | +| System.Data.SqlClient;SqlTransaction;get_IsolationLevel;();summary;df-generated | | System.Data.SqlTypes;INullable;get_IsNull;();summary;df-generated | | System.Data.SqlTypes;SqlAlreadyFilledException;SqlAlreadyFilledException;(System.String);summary;df-generated | | System.Data.SqlTypes;SqlAlreadyFilledException;SqlAlreadyFilledException;(System.String,System.Exception);summary;df-generated | @@ -26408,6 +27286,13 @@ neutral | System.Data.SqlTypes;SqlDouble;op_Multiply;(System.Data.SqlTypes.SqlDouble,System.Data.SqlTypes.SqlDouble);summary;df-generated | | System.Data.SqlTypes;SqlDouble;op_Subtraction;(System.Data.SqlTypes.SqlDouble,System.Data.SqlTypes.SqlDouble);summary;df-generated | | System.Data.SqlTypes;SqlDouble;op_UnaryNegation;(System.Data.SqlTypes.SqlDouble);summary;df-generated | +| System.Data.SqlTypes;SqlFileStream;Flush;();summary;df-generated | +| System.Data.SqlTypes;SqlFileStream;Seek;(System.Int64,System.IO.SeekOrigin);summary;df-generated | +| System.Data.SqlTypes;SqlFileStream;SetLength;(System.Int64);summary;df-generated | +| System.Data.SqlTypes;SqlFileStream;get_CanRead;();summary;df-generated | +| System.Data.SqlTypes;SqlFileStream;get_CanSeek;();summary;df-generated | +| System.Data.SqlTypes;SqlFileStream;get_CanWrite;();summary;df-generated | +| System.Data.SqlTypes;SqlFileStream;get_Length;();summary;df-generated | | System.Data.SqlTypes;SqlGuid;CompareTo;(System.Data.SqlTypes.SqlGuid);summary;df-generated | | System.Data.SqlTypes;SqlGuid;CompareTo;(System.Object);summary;df-generated | | System.Data.SqlTypes;SqlGuid;Equals;(System.Data.SqlTypes.SqlGuid);summary;df-generated | @@ -27046,14 +27931,17 @@ neutral | System.Data;DataTableReader;GetBytes;(System.Int32,System.Int64,System.Byte[],System.Int32,System.Int32);summary;df-generated | | System.Data;DataTableReader;GetChar;(System.Int32);summary;df-generated | | System.Data;DataTableReader;GetChars;(System.Int32,System.Int64,System.Char[],System.Int32,System.Int32);summary;df-generated | +| System.Data;DataTableReader;GetDataTypeName;(System.Int32);summary;manual | | System.Data;DataTableReader;GetDateTime;(System.Int32);summary;df-generated | | System.Data;DataTableReader;GetDecimal;(System.Int32);summary;df-generated | | System.Data;DataTableReader;GetDouble;(System.Int32);summary;df-generated | | System.Data;DataTableReader;GetFieldType;(System.Int32);summary;df-generated | | System.Data;DataTableReader;GetFloat;(System.Int32);summary;df-generated | +| System.Data;DataTableReader;GetGuid;(System.Int32);summary;manual | | System.Data;DataTableReader;GetInt16;(System.Int32);summary;df-generated | | System.Data;DataTableReader;GetInt32;(System.Int32);summary;df-generated | | System.Data;DataTableReader;GetInt64;(System.Int32);summary;df-generated | +| System.Data;DataTableReader;GetName;(System.Int32);summary;manual | | System.Data;DataTableReader;GetOrdinal;(System.String);summary;df-generated | | System.Data;DataTableReader;GetProviderSpecificFieldType;(System.Int32);summary;df-generated | | System.Data;DataTableReader;IsDBNull;(System.Int32);summary;df-generated | @@ -27790,10 +28678,12 @@ neutral | System.Diagnostics;ActivityTagsCollection+Enumerator;Dispose;();summary;df-generated | | System.Diagnostics;ActivityTagsCollection+Enumerator;MoveNext;();summary;df-generated | | System.Diagnostics;ActivityTagsCollection+Enumerator;Reset;();summary;df-generated | +| System.Diagnostics;ActivityTagsCollection+Enumerator;get_Current;();summary;df-generated | | System.Diagnostics;ActivityTagsCollection;Contains;(System.Collections.Generic.KeyValuePair);summary;df-generated | | System.Diagnostics;ActivityTagsCollection;ContainsKey;(System.String);summary;df-generated | | System.Diagnostics;ActivityTagsCollection;Remove;(System.Collections.Generic.KeyValuePair);summary;df-generated | | System.Diagnostics;ActivityTagsCollection;Remove;(System.String);summary;df-generated | +| System.Diagnostics;ActivityTagsCollection;TryGetValue;(System.String,System.Object);summary;df-generated | | System.Diagnostics;ActivityTagsCollection;get_Count;();summary;df-generated | | System.Diagnostics;ActivityTagsCollection;get_IsReadOnly;();summary;df-generated | | System.Diagnostics;ActivityTraceId;CopyTo;(System.Span);summary;df-generated | @@ -27913,6 +28803,7 @@ neutral | System.Diagnostics;DiagnosticListener;IsEnabled;(System.String,System.Object,System.Object);summary;df-generated | | System.Diagnostics;DiagnosticListener;OnActivityExport;(System.Diagnostics.Activity,System.Object);summary;df-generated | | System.Diagnostics;DiagnosticListener;OnActivityImport;(System.Diagnostics.Activity,System.Object);summary;df-generated | +| System.Diagnostics;DiagnosticListener;Subscribe;(System.IObserver>);summary;df-generated | | System.Diagnostics;DiagnosticListener;Write;(System.String,System.Object);summary;df-generated | | System.Diagnostics;DiagnosticListener;get_AllListeners;();summary;df-generated | | System.Diagnostics;DiagnosticSource;IsEnabled;(System.String);summary;df-generated | @@ -28196,6 +29087,7 @@ neutral | System.Diagnostics;TagList+Enumerator;Dispose;();summary;df-generated | | System.Diagnostics;TagList+Enumerator;MoveNext;();summary;df-generated | | System.Diagnostics;TagList+Enumerator;Reset;();summary;df-generated | +| System.Diagnostics;TagList+Enumerator;get_Current;();summary;df-generated | | System.Diagnostics;TagList;Add;(System.String,System.Object);summary;df-generated | | System.Diagnostics;TagList;Contains;(System.Collections.Generic.KeyValuePair);summary;df-generated | | System.Diagnostics;TagList;IndexOf;(System.Collections.Generic.KeyValuePair);summary;df-generated | @@ -28203,6 +29095,7 @@ neutral | System.Diagnostics;TagList;RemoveAt;(System.Int32);summary;df-generated | | System.Diagnostics;TagList;get_Count;();summary;df-generated | | System.Diagnostics;TagList;get_IsReadOnly;();summary;df-generated | +| System.Diagnostics;TagList;get_Item;(System.Int32);summary;df-generated | | System.Diagnostics;TextWriterTraceListener;Close;();summary;df-generated | | System.Diagnostics;TextWriterTraceListener;Dispose;(System.Boolean);summary;df-generated | | System.Diagnostics;TextWriterTraceListener;Flush;();summary;df-generated | @@ -28300,6 +29193,25 @@ neutral | System.Diagnostics;XmlWriterTraceListener;XmlWriterTraceListener;(System.IO.TextWriter,System.String);summary;df-generated | | System.Diagnostics;XmlWriterTraceListener;XmlWriterTraceListener;(System.String);summary;df-generated | | System.Diagnostics;XmlWriterTraceListener;XmlWriterTraceListener;(System.String,System.String);summary;df-generated | +| System.Drawing.Drawing2D;CustomLineCap;Dispose;();summary;df-generated | +| System.Drawing.Drawing2D;GraphicsPath;Dispose;();summary;df-generated | +| System.Drawing.Drawing2D;GraphicsPathIterator;Dispose;();summary;df-generated | +| System.Drawing.Drawing2D;Matrix;Dispose;();summary;df-generated | +| System.Drawing.Imaging;EncoderParameter;Dispose;();summary;df-generated | +| System.Drawing.Imaging;EncoderParameters;Dispose;();summary;df-generated | +| System.Drawing.Imaging;ImageAttributes;Dispose;();summary;df-generated | +| System.Drawing.Printing;MarginsConverter;CanConvertFrom;(System.ComponentModel.ITypeDescriptorContext,System.Type);summary;df-generated | +| System.Drawing.Printing;MarginsConverter;CanConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Type);summary;df-generated | +| System.Drawing.Printing;MarginsConverter;CreateInstance;(System.ComponentModel.ITypeDescriptorContext,System.Collections.IDictionary);summary;df-generated | +| System.Drawing.Printing;MarginsConverter;GetCreateInstanceSupported;(System.ComponentModel.ITypeDescriptorContext);summary;df-generated | +| System.Drawing.Printing;PrinterSettings+PaperSizeCollection;get_Count;();summary;df-generated | +| System.Drawing.Printing;PrinterSettings+PaperSizeCollection;get_IsSynchronized;();summary;df-generated | +| System.Drawing.Printing;PrinterSettings+PaperSourceCollection;get_Count;();summary;df-generated | +| System.Drawing.Printing;PrinterSettings+PaperSourceCollection;get_IsSynchronized;();summary;df-generated | +| System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;get_Count;();summary;df-generated | +| System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;get_IsSynchronized;();summary;df-generated | +| System.Drawing.Printing;PrinterSettings+StringCollection;get_Count;();summary;df-generated | +| System.Drawing.Printing;PrinterSettings+StringCollection;get_IsSynchronized;();summary;df-generated | | System.Drawing.Printing;PrintingPermission;FromXml;(System.Security.SecurityElement);summary;df-generated | | System.Drawing.Printing;PrintingPermission;IsSubsetOf;(System.Security.IPermission);summary;df-generated | | System.Drawing.Printing;PrintingPermission;IsUnrestricted;();summary;df-generated | @@ -28308,6 +29220,10 @@ neutral | System.Drawing.Printing;PrintingPermission;ToXml;();summary;df-generated | | System.Drawing.Printing;PrintingPermissionAttribute;CreatePermission;();summary;df-generated | | System.Drawing.Printing;PrintingPermissionAttribute;PrintingPermissionAttribute;(System.Security.Permissions.SecurityAction);summary;df-generated | +| System.Drawing.Text;FontCollection;Dispose;();summary;df-generated | +| System.Drawing;Brush;Dispose;();summary;df-generated | +| System.Drawing;BufferedGraphics;Dispose;();summary;df-generated | +| System.Drawing;BufferedGraphicsContext;Dispose;();summary;df-generated | | System.Drawing;Color;Equals;(System.Drawing.Color);summary;df-generated | | System.Drawing;Color;Equals;(System.Object);summary;df-generated | | System.Drawing;Color;FromArgb;(System.Int32);summary;df-generated | @@ -28480,6 +29396,29 @@ neutral | System.Drawing;ColorTranslator;FromWin32;(System.Int32);summary;df-generated | | System.Drawing;ColorTranslator;ToOle;(System.Drawing.Color);summary;df-generated | | System.Drawing;ColorTranslator;ToWin32;(System.Drawing.Color);summary;df-generated | +| System.Drawing;Font;Dispose;();summary;df-generated | +| System.Drawing;FontConverter+FontNameConverter;CanConvertFrom;(System.ComponentModel.ITypeDescriptorContext,System.Type);summary;df-generated | +| System.Drawing;FontConverter+FontNameConverter;Dispose;();summary;df-generated | +| System.Drawing;FontConverter+FontNameConverter;GetStandardValuesExclusive;(System.ComponentModel.ITypeDescriptorContext);summary;df-generated | +| System.Drawing;FontConverter+FontNameConverter;GetStandardValuesSupported;(System.ComponentModel.ITypeDescriptorContext);summary;df-generated | +| System.Drawing;FontConverter;CanConvertFrom;(System.ComponentModel.ITypeDescriptorContext,System.Type);summary;df-generated | +| System.Drawing;FontConverter;CanConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Type);summary;df-generated | +| System.Drawing;FontConverter;CreateInstance;(System.ComponentModel.ITypeDescriptorContext,System.Collections.IDictionary);summary;df-generated | +| System.Drawing;FontConverter;GetCreateInstanceSupported;(System.ComponentModel.ITypeDescriptorContext);summary;df-generated | +| System.Drawing;FontConverter;GetPropertiesSupported;(System.ComponentModel.ITypeDescriptorContext);summary;df-generated | +| System.Drawing;FontFamily;Dispose;();summary;df-generated | +| System.Drawing;Graphics;Dispose;();summary;df-generated | +| System.Drawing;Icon;Dispose;();summary;df-generated | +| System.Drawing;IconConverter;CanConvertFrom;(System.ComponentModel.ITypeDescriptorContext,System.Type);summary;df-generated | +| System.Drawing;IconConverter;CanConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Type);summary;df-generated | +| System.Drawing;Image;Dispose;();summary;df-generated | +| System.Drawing;ImageConverter;CanConvertFrom;(System.ComponentModel.ITypeDescriptorContext,System.Type);summary;df-generated | +| System.Drawing;ImageConverter;CanConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Type);summary;df-generated | +| System.Drawing;ImageConverter;GetPropertiesSupported;(System.ComponentModel.ITypeDescriptorContext);summary;df-generated | +| System.Drawing;ImageFormatConverter;CanConvertFrom;(System.ComponentModel.ITypeDescriptorContext,System.Type);summary;df-generated | +| System.Drawing;ImageFormatConverter;CanConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Type);summary;df-generated | +| System.Drawing;ImageFormatConverter;GetStandardValuesSupported;(System.ComponentModel.ITypeDescriptorContext);summary;df-generated | +| System.Drawing;Pen;Dispose;();summary;df-generated | | System.Drawing;Point;Add;(System.Drawing.Point,System.Drawing.Size);summary;df-generated | | System.Drawing;Point;Ceiling;(System.Drawing.PointF);summary;df-generated | | System.Drawing;Point;Equals;(System.Drawing.Point);summary;df-generated | @@ -28582,6 +29521,7 @@ neutral | System.Drawing;RectangleF;get_Top;();summary;df-generated | | System.Drawing;RectangleF;op_Equality;(System.Drawing.RectangleF,System.Drawing.RectangleF);summary;df-generated | | System.Drawing;RectangleF;op_Inequality;(System.Drawing.RectangleF,System.Drawing.RectangleF);summary;df-generated | +| System.Drawing;Region;Dispose;();summary;df-generated | | System.Drawing;Size;Add;(System.Drawing.Size,System.Drawing.Size);summary;df-generated | | System.Drawing;Size;Ceiling;(System.Drawing.SizeF);summary;df-generated | | System.Drawing;Size;Equals;(System.Drawing.Size);summary;df-generated | @@ -28635,6 +29575,7 @@ neutral | System.Drawing;SizeFConverter;CreateInstance;(System.ComponentModel.ITypeDescriptorContext,System.Collections.IDictionary);summary;df-generated | | System.Drawing;SizeFConverter;GetCreateInstanceSupported;(System.ComponentModel.ITypeDescriptorContext);summary;df-generated | | System.Drawing;SizeFConverter;GetPropertiesSupported;(System.ComponentModel.ITypeDescriptorContext);summary;df-generated | +| System.Drawing;StringFormat;Dispose;();summary;df-generated | | System.Drawing;SystemColors;get_ActiveBorder;();summary;df-generated | | System.Drawing;SystemColors;get_ActiveCaption;();summary;df-generated | | System.Drawing;SystemColors;get_ActiveCaptionText;();summary;df-generated | @@ -28668,6 +29609,8 @@ neutral | System.Drawing;SystemColors;get_Window;();summary;df-generated | | System.Drawing;SystemColors;get_WindowFrame;();summary;df-generated | | System.Drawing;SystemColors;get_WindowText;();summary;df-generated | +| System.Drawing;ToolboxBitmapAttribute;Equals;(System.Object);summary;df-generated | +| System.Drawing;ToolboxBitmapAttribute;GetHashCode;();summary;df-generated | | System.Dynamic;BinaryOperationBinder;BinaryOperationBinder;(System.Linq.Expressions.ExpressionType);summary;df-generated | | System.Dynamic;BinaryOperationBinder;Bind;(System.Dynamic.DynamicMetaObject,System.Dynamic.DynamicMetaObject[]);summary;df-generated | | System.Dynamic;BinaryOperationBinder;FallbackBinaryOperation;(System.Dynamic.DynamicMetaObject,System.Dynamic.DynamicMetaObject);summary;df-generated | @@ -28748,6 +29691,7 @@ neutral | System.Dynamic;ExpandoObject;GetMetaObject;(System.Linq.Expressions.Expression);summary;df-generated | | System.Dynamic;ExpandoObject;Remove;(System.Collections.Generic.KeyValuePair);summary;df-generated | | System.Dynamic;ExpandoObject;Remove;(System.String);summary;df-generated | +| System.Dynamic;ExpandoObject;TryGetValue;(System.String,System.Object);summary;df-generated | | System.Dynamic;ExpandoObject;get_Count;();summary;df-generated | | System.Dynamic;ExpandoObject;get_IsReadOnly;();summary;df-generated | | System.Dynamic;GetIndexBinder;Bind;(System.Dynamic.DynamicMetaObject,System.Dynamic.DynamicMetaObject[]);summary;df-generated | @@ -29485,6 +30429,7 @@ neutral | System.IO.Enumeration;FileSystemEnumerator;ShouldIncludeEntry;(System.IO.Enumeration.FileSystemEntry);summary;df-generated | | System.IO.Enumeration;FileSystemEnumerator;ShouldRecurseIntoEntry;(System.IO.Enumeration.FileSystemEntry);summary;df-generated | | System.IO.Enumeration;FileSystemEnumerator;TransformEntry;(System.IO.Enumeration.FileSystemEntry);summary;df-generated | +| System.IO.Enumeration;FileSystemEnumerator;get_Current;();summary;df-generated | | System.IO.Enumeration;FileSystemName;MatchesSimpleExpression;(System.ReadOnlySpan,System.ReadOnlySpan,System.Boolean);summary;df-generated | | System.IO.Enumeration;FileSystemName;MatchesWin32Expression;(System.ReadOnlySpan,System.ReadOnlySpan,System.Boolean);summary;df-generated | | System.IO.IsolatedStorage;INormalizeForIsolatedStorage;Normalize;();summary;df-generated | @@ -29616,6 +30561,8 @@ neutral | System.IO.Pipelines;PipeWriter;Complete;(System.Exception);summary;df-generated | | System.IO.Pipelines;PipeWriter;CompleteAsync;(System.Exception);summary;df-generated | | System.IO.Pipelines;PipeWriter;CopyFromAsync;(System.IO.Stream,System.Threading.CancellationToken);summary;df-generated | +| System.IO.Pipelines;PipeWriter;GetMemory;(System.Int32);summary;df-generated | +| System.IO.Pipelines;PipeWriter;GetSpan;(System.Int32);summary;df-generated | | System.IO.Pipelines;PipeWriter;get_CanGetUnflushedBytes;();summary;df-generated | | System.IO.Pipelines;PipeWriter;get_UnflushedBytes;();summary;df-generated | | System.IO.Pipelines;ReadResult;get_IsCanceled;();summary;df-generated | @@ -30605,6 +31552,7 @@ neutral | System.Linq;ImmutableArrayExtensions;SingleOrDefault;(System.Collections.Immutable.ImmutableArray);summary;df-generated | | System.Linq;Lookup;Contains;(TKey);summary;df-generated | | System.Linq;Lookup;get_Count;();summary;df-generated | +| System.Linq;Lookup;get_Item;(TKey);summary;df-generated | | System.Linq;ParallelEnumerable;Any;(System.Linq.ParallelQuery);summary;df-generated | | System.Linq;ParallelEnumerable;Average;(System.Linq.ParallelQuery);summary;df-generated | | System.Linq;ParallelEnumerable;Average;(System.Linq.ParallelQuery);summary;df-generated | @@ -30774,6 +31722,7 @@ neutral | System.Net.Http.Headers;HeaderStringValues+Enumerator;Dispose;();summary;df-generated | | System.Net.Http.Headers;HeaderStringValues+Enumerator;MoveNext;();summary;df-generated | | System.Net.Http.Headers;HeaderStringValues+Enumerator;Reset;();summary;df-generated | +| System.Net.Http.Headers;HeaderStringValues+Enumerator;get_Current;();summary;df-generated | | System.Net.Http.Headers;HeaderStringValues;get_Count;();summary;df-generated | | System.Net.Http.Headers;HttpContentHeaders;get_Allow;();summary;df-generated | | System.Net.Http.Headers;HttpContentHeaders;get_ContentEncoding;();summary;df-generated | @@ -30797,9 +31746,14 @@ neutral | System.Net.Http.Headers;HttpHeadersNonValidated+Enumerator;Dispose;();summary;df-generated | | System.Net.Http.Headers;HttpHeadersNonValidated+Enumerator;MoveNext;();summary;df-generated | | System.Net.Http.Headers;HttpHeadersNonValidated+Enumerator;Reset;();summary;df-generated | +| System.Net.Http.Headers;HttpHeadersNonValidated+Enumerator;get_Current;();summary;df-generated | | System.Net.Http.Headers;HttpHeadersNonValidated;Contains;(System.String);summary;df-generated | | System.Net.Http.Headers;HttpHeadersNonValidated;ContainsKey;(System.String);summary;df-generated | +| System.Net.Http.Headers;HttpHeadersNonValidated;TryGetValue;(System.String,System.Net.Http.Headers.HeaderStringValues);summary;df-generated | | System.Net.Http.Headers;HttpHeadersNonValidated;get_Count;();summary;df-generated | +| System.Net.Http.Headers;HttpHeadersNonValidated;get_Item;(System.String);summary;df-generated | +| System.Net.Http.Headers;HttpHeadersNonValidated;get_Keys;();summary;df-generated | +| System.Net.Http.Headers;HttpHeadersNonValidated;get_Values;();summary;df-generated | | System.Net.Http.Headers;HttpRequestHeaders;get_Accept;();summary;df-generated | | System.Net.Http.Headers;HttpRequestHeaders;get_AcceptCharset;();summary;df-generated | | System.Net.Http.Headers;HttpRequestHeaders;get_AcceptEncoding;();summary;df-generated | @@ -31056,6 +32010,9 @@ neutral | System.Net.Http;HttpRequestOptions;TryGetValue;(System.Net.Http.HttpRequestOptionsKey,TValue);summary;df-generated | | System.Net.Http;HttpRequestOptions;get_Count;();summary;df-generated | | System.Net.Http;HttpRequestOptions;get_IsReadOnly;();summary;df-generated | +| System.Net.Http;HttpRequestOptions;get_Item;(System.String);summary;df-generated | +| System.Net.Http;HttpRequestOptions;get_Keys;();summary;df-generated | +| System.Net.Http;HttpRequestOptions;get_Values;();summary;df-generated | | System.Net.Http;HttpRequestOptionsKey;HttpRequestOptionsKey;(System.String);summary;df-generated | | System.Net.Http;HttpRequestOptionsKey;get_Key;();summary;df-generated | | System.Net.Http;HttpResponseMessage;Dispose;();summary;df-generated | @@ -32234,6 +33191,7 @@ neutral | System.Net;WebUtility;UrlDecodeToBytes;(System.Byte[],System.Int32,System.Int32);summary;df-generated | | System.Net;WebUtility;UrlEncodeToBytes;(System.Byte[],System.Int32,System.Int32);summary;df-generated | | System.Net;WriteStreamClosedEventArgs;get_Error;();summary;df-generated | +| System.Numerics;BigInteger;Abs;(System.Numerics.BigInteger);summary;df-generated | | System.Numerics;BigInteger;Add;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | | System.Numerics;BigInteger;BigInteger;(System.Byte[]);summary;df-generated | | System.Numerics;BigInteger;BigInteger;(System.Decimal);summary;df-generated | @@ -32249,6 +33207,7 @@ neutral | System.Numerics;BigInteger;CompareTo;(System.Numerics.BigInteger);summary;df-generated | | System.Numerics;BigInteger;CompareTo;(System.Object);summary;df-generated | | System.Numerics;BigInteger;CompareTo;(System.UInt64);summary;df-generated | +| System.Numerics;BigInteger;DivRem;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | | System.Numerics;BigInteger;Divide;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | | System.Numerics;BigInteger;Equals;(System.Int64);summary;df-generated | | System.Numerics;BigInteger;Equals;(System.Numerics.BigInteger);summary;df-generated | @@ -32283,6 +33242,10 @@ neutral | System.Numerics;BigInteger;Log10;(System.Numerics.BigInteger);summary;df-generated | | System.Numerics;BigInteger;Log;(System.Numerics.BigInteger);summary;df-generated | | System.Numerics;BigInteger;Log;(System.Numerics.BigInteger,System.Double);summary;df-generated | +| System.Numerics;BigInteger;MaxMagnitude;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;MaxMagnitudeNumber;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;MinMagnitude;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;MinMagnitudeNumber;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | | System.Numerics;BigInteger;ModPow;(System.Numerics.BigInteger,System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | | System.Numerics;BigInteger;Multiply;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | | System.Numerics;BigInteger;Negate;(System.Numerics.BigInteger);summary;df-generated | @@ -32293,8 +33256,32 @@ neutral | System.Numerics;BigInteger;Parse;(System.String,System.Globalization.NumberStyles,System.IFormatProvider);summary;df-generated | | System.Numerics;BigInteger;Parse;(System.String,System.IFormatProvider);summary;df-generated | | System.Numerics;BigInteger;PopCount;(System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;RotateLeft;(System.Numerics.BigInteger,System.Int32);summary;df-generated | +| System.Numerics;BigInteger;RotateRight;(System.Numerics.BigInteger,System.Int32);summary;df-generated | | System.Numerics;BigInteger;Sign;(System.Numerics.BigInteger);summary;df-generated | | System.Numerics;BigInteger;Subtract;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IAdditionOperators.op_Addition;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IBitwiseOperators.op_BitwiseAnd;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IBitwiseOperators.op_BitwiseOr;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IBitwiseOperators.op_ExclusiveOr;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IBitwiseOperators.op_OnesComplement;(System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IComparisonOperators.op_GreaterThan;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IComparisonOperators.op_GreaterThanOrEqual;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IComparisonOperators.op_LessThan;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IComparisonOperators.op_LessThanOrEqual;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IDecrementOperators.op_Decrement;(System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IDivisionOperators.op_Division;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IEqualityOperators.op_Equality;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IEqualityOperators.op_Inequality;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IIncrementOperators.op_Increment;(System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IModulusOperators.op_Modulus;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IMultiplyOperators.op_Multiply;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IShiftOperators.op_LeftShift;(System.Numerics.BigInteger,System.Int32);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IShiftOperators.op_RightShift;(System.Numerics.BigInteger,System.Int32);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IShiftOperators.op_UnsignedRightShift;(System.Numerics.BigInteger,System.Int32);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.ISubtractionOperators.op_Subtraction;(System.Numerics.BigInteger,System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IUnaryNegationOperators.op_UnaryNegation;(System.Numerics.BigInteger);summary;df-generated | +| System.Numerics;BigInteger;System.Numerics.IUnaryPlusOperators.op_UnaryPlus;(System.Numerics.BigInteger);summary;df-generated | | System.Numerics;BigInteger;ToByteArray;();summary;df-generated | | System.Numerics;BigInteger;ToByteArray;(System.Boolean,System.Boolean);summary;df-generated | | System.Numerics;BigInteger;ToString;();summary;df-generated | @@ -32429,6 +33416,10 @@ neutral | System.Numerics;Complex;Log10;(System.Numerics.Complex);summary;df-generated | | System.Numerics;Complex;Log;(System.Numerics.Complex);summary;df-generated | | System.Numerics;Complex;Log;(System.Numerics.Complex,System.Double);summary;df-generated | +| System.Numerics;Complex;MaxMagnitude;(System.Numerics.Complex,System.Numerics.Complex);summary;df-generated | +| System.Numerics;Complex;MaxMagnitudeNumber;(System.Numerics.Complex,System.Numerics.Complex);summary;df-generated | +| System.Numerics;Complex;MinMagnitude;(System.Numerics.Complex,System.Numerics.Complex);summary;df-generated | +| System.Numerics;Complex;MinMagnitudeNumber;(System.Numerics.Complex,System.Numerics.Complex);summary;df-generated | | System.Numerics;Complex;Multiply;(System.Double,System.Numerics.Complex);summary;df-generated | | System.Numerics;Complex;Multiply;(System.Numerics.Complex,System.Double);summary;df-generated | | System.Numerics;Complex;Multiply;(System.Numerics.Complex,System.Numerics.Complex);summary;df-generated | @@ -32446,6 +33437,16 @@ neutral | System.Numerics;Complex;Subtract;(System.Double,System.Numerics.Complex);summary;df-generated | | System.Numerics;Complex;Subtract;(System.Numerics.Complex,System.Double);summary;df-generated | | System.Numerics;Complex;Subtract;(System.Numerics.Complex,System.Numerics.Complex);summary;df-generated | +| System.Numerics;Complex;System.Numerics.IAdditionOperators.op_Addition;(System.Numerics.Complex,System.Numerics.Complex);summary;df-generated | +| System.Numerics;Complex;System.Numerics.IDecrementOperators.op_Decrement;(System.Numerics.Complex);summary;df-generated | +| System.Numerics;Complex;System.Numerics.IDivisionOperators.op_Division;(System.Numerics.Complex,System.Numerics.Complex);summary;df-generated | +| System.Numerics;Complex;System.Numerics.IEqualityOperators.op_Equality;(System.Numerics.Complex,System.Numerics.Complex);summary;df-generated | +| System.Numerics;Complex;System.Numerics.IEqualityOperators.op_Inequality;(System.Numerics.Complex,System.Numerics.Complex);summary;df-generated | +| System.Numerics;Complex;System.Numerics.IIncrementOperators.op_Increment;(System.Numerics.Complex);summary;df-generated | +| System.Numerics;Complex;System.Numerics.IMultiplyOperators.op_Multiply;(System.Numerics.Complex,System.Numerics.Complex);summary;df-generated | +| System.Numerics;Complex;System.Numerics.ISubtractionOperators.op_Subtraction;(System.Numerics.Complex,System.Numerics.Complex);summary;df-generated | +| System.Numerics;Complex;System.Numerics.IUnaryNegationOperators.op_UnaryNegation;(System.Numerics.Complex);summary;df-generated | +| System.Numerics;Complex;System.Numerics.IUnaryPlusOperators.op_UnaryPlus;(System.Numerics.Complex);summary;df-generated | | System.Numerics;Complex;Tan;(System.Numerics.Complex);summary;df-generated | | System.Numerics;Complex;Tanh;(System.Numerics.Complex);summary;df-generated | | System.Numerics;Complex;ToString;();summary;df-generated | @@ -34377,6 +35378,7 @@ neutral | System.Reflection.Metadata;ImportDefinitionCollection+Enumerator;Dispose;();summary;df-generated | | System.Reflection.Metadata;ImportDefinitionCollection+Enumerator;MoveNext;();summary;df-generated | | System.Reflection.Metadata;ImportDefinitionCollection+Enumerator;Reset;();summary;df-generated | +| System.Reflection.Metadata;ImportDefinitionCollection+Enumerator;get_Current;();summary;df-generated | | System.Reflection.Metadata;ImportScope;GetImports;();summary;df-generated | | System.Reflection.Metadata;ImportScope;get_ImportsBlob;();summary;df-generated | | System.Reflection.Metadata;ImportScope;get_Parent;();summary;df-generated | @@ -34672,6 +35674,7 @@ neutral | System.Reflection.Metadata;SequencePointCollection+Enumerator;Dispose;();summary;df-generated | | System.Reflection.Metadata;SequencePointCollection+Enumerator;MoveNext;();summary;df-generated | | System.Reflection.Metadata;SequencePointCollection+Enumerator;Reset;();summary;df-generated | +| System.Reflection.Metadata;SequencePointCollection+Enumerator;get_Current;();summary;df-generated | | System.Reflection.Metadata;SignatureHeader;Equals;(System.Object);summary;df-generated | | System.Reflection.Metadata;SignatureHeader;Equals;(System.Reflection.Metadata.SignatureHeader);summary;df-generated | | System.Reflection.Metadata;SignatureHeader;GetHashCode;();summary;df-generated | @@ -36601,17 +37604,32 @@ neutral | System.Runtime.InteropServices;NFloat;SinPi;(System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;Sinh;(System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;Sqrt;(System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.IAdditionOperators.op_Addition;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;System.Numerics.IAdditionOperators.op_CheckedAddition;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;System.Numerics.IBitwiseOperators.op_BitwiseAnd;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;System.Numerics.IBitwiseOperators.op_BitwiseOr;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;System.Numerics.IBitwiseOperators.op_ExclusiveOr;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;System.Numerics.IBitwiseOperators.op_OnesComplement;(System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.IComparisonOperators.op_GreaterThan;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.IComparisonOperators.op_GreaterThanOrEqual;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.IComparisonOperators.op_LessThan;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.IComparisonOperators.op_LessThanOrEqual;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;System.Numerics.IDecrementOperators.op_CheckedDecrement;(System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.IDecrementOperators.op_Decrement;(System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;System.Numerics.IDivisionOperators.op_CheckedDivision;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.IDivisionOperators.op_Division;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.IEqualityOperators.op_Equality;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.IEqualityOperators.op_Inequality;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;System.Numerics.IIncrementOperators.op_CheckedIncrement;(System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.IIncrementOperators.op_Increment;(System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.IModulusOperators.op_Modulus;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;System.Numerics.IMultiplyOperators.op_CheckedMultiply;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.IMultiplyOperators.op_Multiply;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;System.Numerics.ISubtractionOperators.op_CheckedSubtraction;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.ISubtractionOperators.op_Subtraction;(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;System.Numerics.IUnaryNegationOperators.op_CheckedUnaryNegation;(System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.IUnaryNegationOperators.op_UnaryNegation;(System.Runtime.InteropServices.NFloat);summary;df-generated | +| System.Runtime.InteropServices;NFloat;System.Numerics.IUnaryPlusOperators.op_UnaryPlus;(System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;Tan;(System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;TanPi;(System.Runtime.InteropServices.NFloat);summary;df-generated | | System.Runtime.InteropServices;NFloat;Tanh;(System.Runtime.InteropServices.NFloat);summary;df-generated | @@ -43755,6 +44773,7 @@ neutral | System.Security.Cryptography.X509Certificates;X509Certificate2Enumerator;Dispose;();summary;df-generated | | System.Security.Cryptography.X509Certificates;X509Certificate2Enumerator;MoveNext;();summary;df-generated | | System.Security.Cryptography.X509Certificates;X509Certificate2Enumerator;Reset;();summary;df-generated | +| System.Security.Cryptography.X509Certificates;X509Certificate2Enumerator;get_Current;();summary;df-generated | | System.Security.Cryptography.X509Certificates;X509Certificate2UI;DisplayCertificate;(System.Security.Cryptography.X509Certificates.X509Certificate2);summary;df-generated | | System.Security.Cryptography.X509Certificates;X509Certificate2UI;DisplayCertificate;(System.Security.Cryptography.X509Certificates.X509Certificate2,System.IntPtr);summary;df-generated | | System.Security.Cryptography.X509Certificates;X509Certificate2UI;SelectFromCollection;(System.Security.Cryptography.X509Certificates.X509Certificate2Collection,System.String,System.String,System.Security.Cryptography.X509Certificates.X509SelectionFlag);summary;df-generated | @@ -43828,6 +44847,7 @@ neutral | System.Security.Cryptography.X509Certificates;X509ChainElementEnumerator;Dispose;();summary;df-generated | | System.Security.Cryptography.X509Certificates;X509ChainElementEnumerator;MoveNext;();summary;df-generated | | System.Security.Cryptography.X509Certificates;X509ChainElementEnumerator;Reset;();summary;df-generated | +| System.Security.Cryptography.X509Certificates;X509ChainElementEnumerator;get_Current;();summary;df-generated | | System.Security.Cryptography.X509Certificates;X509ChainPolicy;Reset;();summary;df-generated | | System.Security.Cryptography.X509Certificates;X509ChainPolicy;get_ApplicationPolicy;();summary;df-generated | | System.Security.Cryptography.X509Certificates;X509ChainPolicy;get_CertificatePolicy;();summary;df-generated | @@ -43845,6 +44865,7 @@ neutral | System.Security.Cryptography.X509Certificates;X509ExtensionEnumerator;Dispose;();summary;df-generated | | System.Security.Cryptography.X509Certificates;X509ExtensionEnumerator;MoveNext;();summary;df-generated | | System.Security.Cryptography.X509Certificates;X509ExtensionEnumerator;Reset;();summary;df-generated | +| System.Security.Cryptography.X509Certificates;X509ExtensionEnumerator;get_Current;();summary;df-generated | | System.Security.Cryptography.X509Certificates;X509KeyUsageExtension;X509KeyUsageExtension;(System.Security.Cryptography.AsnEncodedData,System.Boolean);summary;df-generated | | System.Security.Cryptography.X509Certificates;X509KeyUsageExtension;X509KeyUsageExtension;(System.Security.Cryptography.X509Certificates.X509KeyUsageFlags,System.Boolean);summary;df-generated | | System.Security.Cryptography.X509Certificates;X509KeyUsageExtension;get_KeyUsages;();summary;df-generated | @@ -46049,6 +47070,7 @@ neutral | System.Text.Json.Nodes;JsonObject;JsonObject;(System.Nullable);summary;df-generated | | System.Text.Json.Nodes;JsonObject;Remove;(System.Collections.Generic.KeyValuePair);summary;df-generated | | System.Text.Json.Nodes;JsonObject;Remove;(System.String);summary;df-generated | +| System.Text.Json.Nodes;JsonObject;TryGetValue;(System.String,System.Text.Json.Nodes.JsonNode);summary;df-generated | | System.Text.Json.Nodes;JsonObject;WriteTo;(System.Text.Json.Utf8JsonWriter,System.Text.Json.JsonSerializerOptions);summary;df-generated | | System.Text.Json.Nodes;JsonObject;get_Count;();summary;df-generated | | System.Text.Json.Nodes;JsonObject;get_IsReadOnly;();summary;df-generated | @@ -46188,6 +47210,7 @@ neutral | System.Text.Json;JsonElement+ArrayEnumerator;Dispose;();summary;df-generated | | System.Text.Json;JsonElement+ArrayEnumerator;MoveNext;();summary;df-generated | | System.Text.Json;JsonElement+ArrayEnumerator;Reset;();summary;df-generated | +| System.Text.Json;JsonElement+ArrayEnumerator;get_Current;();summary;df-generated | | System.Text.Json;JsonElement+ObjectEnumerator;Dispose;();summary;df-generated | | System.Text.Json;JsonElement+ObjectEnumerator;MoveNext;();summary;df-generated | | System.Text.Json;JsonElement+ObjectEnumerator;Reset;();summary;df-generated | @@ -46507,6 +47530,7 @@ neutral | System.Text.RegularExpressions;CaptureCollection;get_IsFixedSize;();summary;df-generated | | System.Text.RegularExpressions;CaptureCollection;get_IsReadOnly;();summary;df-generated | | System.Text.RegularExpressions;CaptureCollection;get_IsSynchronized;();summary;df-generated | +| System.Text.RegularExpressions;CaptureCollection;get_Item;(System.Int32);summary;df-generated | | System.Text.RegularExpressions;GeneratedRegexAttribute;GeneratedRegexAttribute;(System.String);summary;df-generated | | System.Text.RegularExpressions;GeneratedRegexAttribute;GeneratedRegexAttribute;(System.String,System.Text.RegularExpressions.RegexOptions);summary;df-generated | | System.Text.RegularExpressions;GeneratedRegexAttribute;GeneratedRegexAttribute;(System.String,System.Text.RegularExpressions.RegexOptions,System.Int32);summary;df-generated | @@ -46525,10 +47549,15 @@ neutral | System.Text.RegularExpressions;GroupCollection;IndexOf;(System.Text.RegularExpressions.Group);summary;df-generated | | System.Text.RegularExpressions;GroupCollection;Remove;(System.Text.RegularExpressions.Group);summary;df-generated | | System.Text.RegularExpressions;GroupCollection;RemoveAt;(System.Int32);summary;df-generated | +| System.Text.RegularExpressions;GroupCollection;TryGetValue;(System.String,System.Text.RegularExpressions.Group);summary;df-generated | | System.Text.RegularExpressions;GroupCollection;get_Count;();summary;df-generated | | System.Text.RegularExpressions;GroupCollection;get_IsFixedSize;();summary;df-generated | | System.Text.RegularExpressions;GroupCollection;get_IsReadOnly;();summary;df-generated | | System.Text.RegularExpressions;GroupCollection;get_IsSynchronized;();summary;df-generated | +| System.Text.RegularExpressions;GroupCollection;get_Item;(System.Int32);summary;df-generated | +| System.Text.RegularExpressions;GroupCollection;get_Item;(System.String);summary;df-generated | +| System.Text.RegularExpressions;GroupCollection;get_Keys;();summary;df-generated | +| System.Text.RegularExpressions;GroupCollection;get_Values;();summary;df-generated | | System.Text.RegularExpressions;Match;Result;(System.String);summary;df-generated | | System.Text.RegularExpressions;Match;get_Empty;();summary;df-generated | | System.Text.RegularExpressions;Match;get_Groups;();summary;df-generated | @@ -46542,6 +47571,7 @@ neutral | System.Text.RegularExpressions;MatchCollection;get_IsFixedSize;();summary;df-generated | | System.Text.RegularExpressions;MatchCollection;get_IsReadOnly;();summary;df-generated | | System.Text.RegularExpressions;MatchCollection;get_IsSynchronized;();summary;df-generated | +| System.Text.RegularExpressions;MatchCollection;get_Item;(System.Int32);summary;df-generated | | System.Text.RegularExpressions;Regex+ValueMatchEnumerator;MoveNext;();summary;df-generated | | System.Text.RegularExpressions;Regex;CompileToAssembly;(System.Text.RegularExpressions.RegexCompilationInfo[],System.Reflection.AssemblyName);summary;df-generated | | System.Text.RegularExpressions;Regex;CompileToAssembly;(System.Text.RegularExpressions.RegexCompilationInfo[],System.Reflection.AssemblyName,System.Reflection.Emit.CustomAttributeBuilder[]);summary;df-generated | @@ -47062,6 +48092,7 @@ neutral | System.Text;StringRuneEnumerator;Dispose;();summary;df-generated | | System.Text;StringRuneEnumerator;MoveNext;();summary;df-generated | | System.Text;StringRuneEnumerator;Reset;();summary;df-generated | +| System.Text;StringRuneEnumerator;get_Current;();summary;df-generated | | System.Text;UTF7Encoding;Equals;(System.Object);summary;df-generated | | System.Text;UTF7Encoding;GetByteCount;(System.Char*,System.Int32);summary;df-generated | | System.Text;UTF7Encoding;GetByteCount;(System.Char[],System.Int32,System.Int32);summary;df-generated | @@ -47202,8 +48233,10 @@ neutral | System.Threading.Tasks.Dataflow;BatchBlock;Complete;();summary;df-generated | | System.Threading.Tasks.Dataflow;BatchBlock;ConsumeMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;BatchBlock;Fault;(System.Exception);summary;df-generated | +| System.Threading.Tasks.Dataflow;BatchBlock;LinkTo;(System.Threading.Tasks.Dataflow.ITargetBlock,System.Threading.Tasks.Dataflow.DataflowLinkOptions);summary;df-generated | | System.Threading.Tasks.Dataflow;BatchBlock;OfferMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,T,System.Threading.Tasks.Dataflow.ISourceBlock,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;BatchBlock;ReleaseReservation;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock);summary;df-generated | +| System.Threading.Tasks.Dataflow;BatchBlock;ReserveMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock);summary;df-generated | | System.Threading.Tasks.Dataflow;BatchBlock;ToString;();summary;df-generated | | System.Threading.Tasks.Dataflow;BatchBlock;TriggerBatch;();summary;df-generated | | System.Threading.Tasks.Dataflow;BatchBlock;TryReceiveAll;(System.Collections.Generic.IList);summary;df-generated | @@ -47213,7 +48246,9 @@ neutral | System.Threading.Tasks.Dataflow;BatchedJoinBlock;Complete;();summary;df-generated | | System.Threading.Tasks.Dataflow;BatchedJoinBlock;ConsumeMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock,System.Collections.Generic.IList,System.Collections.Generic.IList>>,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;BatchedJoinBlock;Fault;(System.Exception);summary;df-generated | +| System.Threading.Tasks.Dataflow;BatchedJoinBlock;LinkTo;(System.Threading.Tasks.Dataflow.ITargetBlock,System.Collections.Generic.IList,System.Collections.Generic.IList>>,System.Threading.Tasks.Dataflow.DataflowLinkOptions);summary;df-generated | | System.Threading.Tasks.Dataflow;BatchedJoinBlock;ReleaseReservation;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock,System.Collections.Generic.IList,System.Collections.Generic.IList>>);summary;df-generated | +| System.Threading.Tasks.Dataflow;BatchedJoinBlock;ReserveMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock,System.Collections.Generic.IList,System.Collections.Generic.IList>>);summary;df-generated | | System.Threading.Tasks.Dataflow;BatchedJoinBlock;ToString;();summary;df-generated | | System.Threading.Tasks.Dataflow;BatchedJoinBlock;TryReceiveAll;(System.Collections.Generic.IList,System.Collections.Generic.IList,System.Collections.Generic.IList>>);summary;df-generated | | System.Threading.Tasks.Dataflow;BatchedJoinBlock;get_BatchSize;();summary;df-generated | @@ -47222,21 +48257,29 @@ neutral | System.Threading.Tasks.Dataflow;BatchedJoinBlock;Complete;();summary;df-generated | | System.Threading.Tasks.Dataflow;BatchedJoinBlock;ConsumeMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock,System.Collections.Generic.IList>>,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;BatchedJoinBlock;Fault;(System.Exception);summary;df-generated | +| System.Threading.Tasks.Dataflow;BatchedJoinBlock;LinkTo;(System.Threading.Tasks.Dataflow.ITargetBlock,System.Collections.Generic.IList>>,System.Threading.Tasks.Dataflow.DataflowLinkOptions);summary;df-generated | | System.Threading.Tasks.Dataflow;BatchedJoinBlock;ReleaseReservation;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock,System.Collections.Generic.IList>>);summary;df-generated | +| System.Threading.Tasks.Dataflow;BatchedJoinBlock;ReserveMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock,System.Collections.Generic.IList>>);summary;df-generated | | System.Threading.Tasks.Dataflow;BatchedJoinBlock;ToString;();summary;df-generated | | System.Threading.Tasks.Dataflow;BatchedJoinBlock;TryReceiveAll;(System.Collections.Generic.IList,System.Collections.Generic.IList>>);summary;df-generated | | System.Threading.Tasks.Dataflow;BatchedJoinBlock;get_BatchSize;();summary;df-generated | | System.Threading.Tasks.Dataflow;BatchedJoinBlock;get_OutputCount;();summary;df-generated | | System.Threading.Tasks.Dataflow;BroadcastBlock;Complete;();summary;df-generated | +| System.Threading.Tasks.Dataflow;BroadcastBlock;ConsumeMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;BroadcastBlock;Fault;(System.Exception);summary;df-generated | +| System.Threading.Tasks.Dataflow;BroadcastBlock;LinkTo;(System.Threading.Tasks.Dataflow.ITargetBlock,System.Threading.Tasks.Dataflow.DataflowLinkOptions);summary;df-generated | | System.Threading.Tasks.Dataflow;BroadcastBlock;OfferMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,T,System.Threading.Tasks.Dataflow.ISourceBlock,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;BroadcastBlock;ReleaseReservation;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock);summary;df-generated | +| System.Threading.Tasks.Dataflow;BroadcastBlock;ReserveMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock);summary;df-generated | | System.Threading.Tasks.Dataflow;BroadcastBlock;ToString;();summary;df-generated | +| System.Threading.Tasks.Dataflow;BroadcastBlock;TryReceiveAll;(System.Collections.Generic.IList);summary;df-generated | | System.Threading.Tasks.Dataflow;BufferBlock;Complete;();summary;df-generated | | System.Threading.Tasks.Dataflow;BufferBlock;ConsumeMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;BufferBlock;Fault;(System.Exception);summary;df-generated | +| System.Threading.Tasks.Dataflow;BufferBlock;LinkTo;(System.Threading.Tasks.Dataflow.ITargetBlock,System.Threading.Tasks.Dataflow.DataflowLinkOptions);summary;df-generated | | System.Threading.Tasks.Dataflow;BufferBlock;OfferMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,T,System.Threading.Tasks.Dataflow.ISourceBlock,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;BufferBlock;ReleaseReservation;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock);summary;df-generated | +| System.Threading.Tasks.Dataflow;BufferBlock;ReserveMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock);summary;df-generated | | System.Threading.Tasks.Dataflow;BufferBlock;ToString;();summary;df-generated | | System.Threading.Tasks.Dataflow;BufferBlock;TryReceiveAll;(System.Collections.Generic.IList);summary;df-generated | | System.Threading.Tasks.Dataflow;BufferBlock;get_Count;();summary;df-generated | @@ -47262,22 +48305,28 @@ neutral | System.Threading.Tasks.Dataflow;JoinBlock;Complete;();summary;df-generated | | System.Threading.Tasks.Dataflow;JoinBlock;ConsumeMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock>,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;JoinBlock;Fault;(System.Exception);summary;df-generated | +| System.Threading.Tasks.Dataflow;JoinBlock;LinkTo;(System.Threading.Tasks.Dataflow.ITargetBlock>,System.Threading.Tasks.Dataflow.DataflowLinkOptions);summary;df-generated | | System.Threading.Tasks.Dataflow;JoinBlock;ReleaseReservation;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock>);summary;df-generated | +| System.Threading.Tasks.Dataflow;JoinBlock;ReserveMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock>);summary;df-generated | | System.Threading.Tasks.Dataflow;JoinBlock;ToString;();summary;df-generated | | System.Threading.Tasks.Dataflow;JoinBlock;TryReceiveAll;(System.Collections.Generic.IList>);summary;df-generated | | System.Threading.Tasks.Dataflow;JoinBlock;get_OutputCount;();summary;df-generated | | System.Threading.Tasks.Dataflow;JoinBlock;Complete;();summary;df-generated | | System.Threading.Tasks.Dataflow;JoinBlock;ConsumeMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock>,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;JoinBlock;Fault;(System.Exception);summary;df-generated | +| System.Threading.Tasks.Dataflow;JoinBlock;LinkTo;(System.Threading.Tasks.Dataflow.ITargetBlock>,System.Threading.Tasks.Dataflow.DataflowLinkOptions);summary;df-generated | | System.Threading.Tasks.Dataflow;JoinBlock;ReleaseReservation;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock>);summary;df-generated | +| System.Threading.Tasks.Dataflow;JoinBlock;ReserveMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock>);summary;df-generated | | System.Threading.Tasks.Dataflow;JoinBlock;ToString;();summary;df-generated | | System.Threading.Tasks.Dataflow;JoinBlock;TryReceiveAll;(System.Collections.Generic.IList>);summary;df-generated | | System.Threading.Tasks.Dataflow;JoinBlock;get_OutputCount;();summary;df-generated | | System.Threading.Tasks.Dataflow;TransformBlock;Complete;();summary;df-generated | | System.Threading.Tasks.Dataflow;TransformBlock;ConsumeMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;TransformBlock;Fault;(System.Exception);summary;df-generated | +| System.Threading.Tasks.Dataflow;TransformBlock;LinkTo;(System.Threading.Tasks.Dataflow.ITargetBlock,System.Threading.Tasks.Dataflow.DataflowLinkOptions);summary;df-generated | | System.Threading.Tasks.Dataflow;TransformBlock;OfferMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,TInput,System.Threading.Tasks.Dataflow.ISourceBlock,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;TransformBlock;ReleaseReservation;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock);summary;df-generated | +| System.Threading.Tasks.Dataflow;TransformBlock;ReserveMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock);summary;df-generated | | System.Threading.Tasks.Dataflow;TransformBlock;ToString;();summary;df-generated | | System.Threading.Tasks.Dataflow;TransformBlock;TryReceiveAll;(System.Collections.Generic.IList);summary;df-generated | | System.Threading.Tasks.Dataflow;TransformBlock;get_InputCount;();summary;df-generated | @@ -47285,15 +48334,22 @@ neutral | System.Threading.Tasks.Dataflow;TransformManyBlock;Complete;();summary;df-generated | | System.Threading.Tasks.Dataflow;TransformManyBlock;ConsumeMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;TransformManyBlock;Fault;(System.Exception);summary;df-generated | +| System.Threading.Tasks.Dataflow;TransformManyBlock;LinkTo;(System.Threading.Tasks.Dataflow.ITargetBlock,System.Threading.Tasks.Dataflow.DataflowLinkOptions);summary;df-generated | | System.Threading.Tasks.Dataflow;TransformManyBlock;OfferMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,TInput,System.Threading.Tasks.Dataflow.ISourceBlock,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;TransformManyBlock;ReleaseReservation;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock);summary;df-generated | +| System.Threading.Tasks.Dataflow;TransformManyBlock;ReserveMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock);summary;df-generated | | System.Threading.Tasks.Dataflow;TransformManyBlock;ToString;();summary;df-generated | | System.Threading.Tasks.Dataflow;TransformManyBlock;TryReceiveAll;(System.Collections.Generic.IList);summary;df-generated | | System.Threading.Tasks.Dataflow;TransformManyBlock;get_InputCount;();summary;df-generated | | System.Threading.Tasks.Dataflow;TransformManyBlock;get_OutputCount;();summary;df-generated | | System.Threading.Tasks.Dataflow;WriteOnceBlock;Complete;();summary;df-generated | +| System.Threading.Tasks.Dataflow;WriteOnceBlock;ConsumeMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock,System.Boolean);summary;df-generated | | System.Threading.Tasks.Dataflow;WriteOnceBlock;Fault;(System.Exception);summary;df-generated | +| System.Threading.Tasks.Dataflow;WriteOnceBlock;LinkTo;(System.Threading.Tasks.Dataflow.ITargetBlock,System.Threading.Tasks.Dataflow.DataflowLinkOptions);summary;df-generated | +| System.Threading.Tasks.Dataflow;WriteOnceBlock;OfferMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,T,System.Threading.Tasks.Dataflow.ISourceBlock,System.Boolean);summary;df-generated | +| System.Threading.Tasks.Dataflow;WriteOnceBlock;ReleaseReservation;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock);summary;df-generated | | System.Threading.Tasks.Dataflow;WriteOnceBlock;ReserveMessage;(System.Threading.Tasks.Dataflow.DataflowMessageHeader,System.Threading.Tasks.Dataflow.ITargetBlock);summary;df-generated | +| System.Threading.Tasks.Dataflow;WriteOnceBlock;TryReceiveAll;(System.Collections.Generic.IList);summary;df-generated | | System.Threading.Tasks.Sources;IValueTaskSource;GetResult;(System.Int16);summary;df-generated | | System.Threading.Tasks.Sources;IValueTaskSource;GetStatus;(System.Int16);summary;df-generated | | System.Threading.Tasks.Sources;IValueTaskSource;GetResult;(System.Int16);summary;df-generated | @@ -47986,6 +49042,7 @@ neutral | System.Web;AspNetHostingPermission;ToXml;();summary;df-generated | | System.Web;AspNetHostingPermissionAttribute;AspNetHostingPermissionAttribute;(System.Security.Permissions.SecurityAction);summary;df-generated | | System.Web;AspNetHostingPermissionAttribute;CreatePermission;();summary;df-generated | +| System.Web;HtmlString;ToHtmlString;();summary;df-generated | | System.Web;HttpUtility;ParseQueryString;(System.String);summary;df-generated | | System.Web;HttpUtility;ParseQueryString;(System.String,System.Text.Encoding);summary;df-generated | | System.Web;HttpUtility;UrlDecode;(System.Byte[],System.Int32,System.Int32,System.Text.Encoding);summary;df-generated | @@ -48186,6 +49243,9 @@ neutral | System.Xml.Schema;XmlSchemaInferenceException;XmlSchemaInferenceException;(System.String);summary;df-generated | | System.Xml.Schema;XmlSchemaInferenceException;XmlSchemaInferenceException;(System.String,System.Exception);summary;df-generated | | System.Xml.Schema;XmlSchemaInferenceException;XmlSchemaInferenceException;(System.String,System.Exception,System.Int32,System.Int32);summary;df-generated | +| System.Xml.Schema;XmlSchemaInfo;get_IsDefault;();summary;df-generated | +| System.Xml.Schema;XmlSchemaInfo;get_IsNil;();summary;df-generated | +| System.Xml.Schema;XmlSchemaInfo;get_Validity;();summary;df-generated | | System.Xml.Schema;XmlSchemaObjectCollection;Contains;(System.Xml.Schema.XmlSchemaObject);summary;df-generated | | System.Xml.Schema;XmlSchemaObjectCollection;IndexOf;(System.Xml.Schema.XmlSchemaObject);summary;df-generated | | System.Xml.Schema;XmlSchemaObjectCollection;OnClear;();summary;df-generated | @@ -48283,6 +49343,7 @@ neutral | System.Xml.Serialization;XmlSchemaEnumerator;Dispose;();summary;df-generated | | System.Xml.Serialization;XmlSchemaEnumerator;MoveNext;();summary;df-generated | | System.Xml.Serialization;XmlSchemaEnumerator;Reset;();summary;df-generated | +| System.Xml.Serialization;XmlSchemaEnumerator;get_Current;();summary;df-generated | | System.Xml.Serialization;XmlSchemaExporter;ExportAnyType;(System.String);summary;df-generated | | System.Xml.Serialization;XmlSchemaExporter;ExportAnyType;(System.Xml.Serialization.XmlMembersMapping);summary;df-generated | | System.Xml.Serialization;XmlSchemaImporter;ImportAnyType;(System.Xml.XmlQualifiedName,System.String);summary;df-generated | @@ -49314,6 +50375,7 @@ neutral | System;ArraySegment+Enumerator;Dispose;();summary;df-generated | | System;ArraySegment+Enumerator;MoveNext;();summary;df-generated | | System;ArraySegment+Enumerator;Reset;();summary;df-generated | +| System;ArraySegment+Enumerator;get_Current;();summary;df-generated | | System;ArraySegment;Contains;(T);summary;df-generated | | System;ArraySegment;CopyTo;(System.ArraySegment);summary;df-generated | | System;ArraySegment;CopyTo;(T[]);summary;df-generated | @@ -49328,6 +50390,7 @@ neutral | System;ArraySegment;get_Count;();summary;df-generated | | System;ArraySegment;get_Empty;();summary;df-generated | | System;ArraySegment;get_IsReadOnly;();summary;df-generated | +| System;ArraySegment;get_Item;(System.Int32);summary;df-generated | | System;ArraySegment;get_Offset;();summary;df-generated | | System;ArraySegment;op_Equality;(System.ArraySegment,System.ArraySegment);summary;df-generated | | System;ArraySegment;op_Inequality;(System.ArraySegment,System.ArraySegment);summary;df-generated | @@ -50221,6 +51284,21 @@ neutral | System;Decimal;Round;(System.Decimal,System.MidpointRounding);summary;df-generated | | System;Decimal;Sign;(System.Decimal);summary;df-generated | | System;Decimal;Subtract;(System.Decimal,System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.IAdditionOperators.op_Addition;(System.Decimal,System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.IComparisonOperators.op_GreaterThan;(System.Decimal,System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.IComparisonOperators.op_GreaterThanOrEqual;(System.Decimal,System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.IComparisonOperators.op_LessThan;(System.Decimal,System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.IComparisonOperators.op_LessThanOrEqual;(System.Decimal,System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.IDecrementOperators.op_Decrement;(System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.IDivisionOperators.op_Division;(System.Decimal,System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.IEqualityOperators.op_Equality;(System.Decimal,System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.IEqualityOperators.op_Inequality;(System.Decimal,System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.IIncrementOperators.op_Increment;(System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.IModulusOperators.op_Modulus;(System.Decimal,System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.IMultiplyOperators.op_Multiply;(System.Decimal,System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.ISubtractionOperators.op_Subtraction;(System.Decimal,System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.IUnaryNegationOperators.op_UnaryNegation;(System.Decimal);summary;df-generated | +| System;Decimal;System.Numerics.IUnaryPlusOperators.op_UnaryPlus;(System.Decimal);summary;df-generated | | System;Decimal;ToBoolean;(System.IFormatProvider);summary;df-generated | | System;Decimal;ToByte;(System.Decimal);summary;df-generated | | System;Decimal;ToByte;(System.IFormatProvider);summary;df-generated | @@ -50410,8 +51488,14 @@ neutral | System;Double;System.Numerics.IBitwiseOperators.op_BitwiseOr;(System.Double,System.Double);summary;df-generated | | System;Double;System.Numerics.IBitwiseOperators.op_ExclusiveOr;(System.Double,System.Double);summary;df-generated | | System;Double;System.Numerics.IBitwiseOperators.op_OnesComplement;(System.Double);summary;df-generated | +| System;Double;System.Numerics.IComparisonOperators.op_GreaterThan;(System.Double,System.Double);summary;df-generated | +| System;Double;System.Numerics.IComparisonOperators.op_GreaterThanOrEqual;(System.Double,System.Double);summary;df-generated | +| System;Double;System.Numerics.IComparisonOperators.op_LessThan;(System.Double,System.Double);summary;df-generated | +| System;Double;System.Numerics.IComparisonOperators.op_LessThanOrEqual;(System.Double,System.Double);summary;df-generated | | System;Double;System.Numerics.IDecrementOperators.op_Decrement;(System.Double);summary;df-generated | | System;Double;System.Numerics.IDivisionOperators.op_Division;(System.Double,System.Double);summary;df-generated | +| System;Double;System.Numerics.IEqualityOperators.op_Equality;(System.Double,System.Double);summary;df-generated | +| System;Double;System.Numerics.IEqualityOperators.op_Inequality;(System.Double,System.Double);summary;df-generated | | System;Double;System.Numerics.IIncrementOperators.op_Increment;(System.Double);summary;df-generated | | System;Double;System.Numerics.IModulusOperators.op_Modulus;(System.Double,System.Double);summary;df-generated | | System;Double;System.Numerics.IMultiplyOperators.op_Multiply;(System.Double,System.Double);summary;df-generated | @@ -50695,6 +51779,8 @@ neutral | System;Half;Atan;(System.Half);summary;df-generated | | System;Half;AtanPi;(System.Half);summary;df-generated | | System;Half;Atanh;(System.Half);summary;df-generated | +| System;Half;BitDecrement;(System.Half);summary;df-generated | +| System;Half;BitIncrement;(System.Half);summary;df-generated | | System;Half;Cbrt;(System.Half);summary;df-generated | | System;Half;Ceiling;(System.Half);summary;df-generated | | System;Half;Clamp;(System.Half,System.Half,System.Half);summary;df-generated | @@ -50751,8 +51837,10 @@ neutral | System;Half;LogP1;(System.Half);summary;df-generated | | System;Half;Max;(System.Half,System.Half);summary;df-generated | | System;Half;MaxMagnitude;(System.Half,System.Half);summary;df-generated | +| System;Half;MaxMagnitudeNumber;(System.Half,System.Half);summary;df-generated | | System;Half;Min;(System.Half,System.Half);summary;df-generated | | System;Half;MinMagnitude;(System.Half,System.Half);summary;df-generated | +| System;Half;MinMagnitudeNumber;(System.Half,System.Half);summary;df-generated | | System;Half;Parse;(System.ReadOnlySpan,System.Globalization.NumberStyles,System.IFormatProvider);summary;df-generated | | System;Half;Parse;(System.ReadOnlySpan,System.IFormatProvider);summary;df-generated | | System;Half;Parse;(System.ReadOnlySpan,System.Globalization.NumberStyles,System.IFormatProvider);summary;df-generated | @@ -50778,10 +51866,25 @@ neutral | System;Half;SinPi;(System.Half);summary;df-generated | | System;Half;Sinh;(System.Half);summary;df-generated | | System;Half;Sqrt;(System.Half);summary;df-generated | +| System;Half;System.Numerics.IAdditionOperators.op_Addition;(System.Half,System.Half);summary;df-generated | | System;Half;System.Numerics.IBitwiseOperators.op_BitwiseAnd;(System.Half,System.Half);summary;df-generated | | System;Half;System.Numerics.IBitwiseOperators.op_BitwiseOr;(System.Half,System.Half);summary;df-generated | | System;Half;System.Numerics.IBitwiseOperators.op_ExclusiveOr;(System.Half,System.Half);summary;df-generated | | System;Half;System.Numerics.IBitwiseOperators.op_OnesComplement;(System.Half);summary;df-generated | +| System;Half;System.Numerics.IComparisonOperators.op_GreaterThan;(System.Half,System.Half);summary;df-generated | +| System;Half;System.Numerics.IComparisonOperators.op_GreaterThanOrEqual;(System.Half,System.Half);summary;df-generated | +| System;Half;System.Numerics.IComparisonOperators.op_LessThan;(System.Half,System.Half);summary;df-generated | +| System;Half;System.Numerics.IComparisonOperators.op_LessThanOrEqual;(System.Half,System.Half);summary;df-generated | +| System;Half;System.Numerics.IDecrementOperators.op_Decrement;(System.Half);summary;df-generated | +| System;Half;System.Numerics.IDivisionOperators.op_Division;(System.Half,System.Half);summary;df-generated | +| System;Half;System.Numerics.IEqualityOperators.op_Equality;(System.Half,System.Half);summary;df-generated | +| System;Half;System.Numerics.IEqualityOperators.op_Inequality;(System.Half,System.Half);summary;df-generated | +| System;Half;System.Numerics.IIncrementOperators.op_Increment;(System.Half);summary;df-generated | +| System;Half;System.Numerics.IModulusOperators.op_Modulus;(System.Half,System.Half);summary;df-generated | +| System;Half;System.Numerics.IMultiplyOperators.op_Multiply;(System.Half,System.Half);summary;df-generated | +| System;Half;System.Numerics.ISubtractionOperators.op_Subtraction;(System.Half,System.Half);summary;df-generated | +| System;Half;System.Numerics.IUnaryNegationOperators.op_UnaryNegation;(System.Half);summary;df-generated | +| System;Half;System.Numerics.IUnaryPlusOperators.op_UnaryPlus;(System.Half);summary;df-generated | | System;Half;Tan;(System.Half);summary;df-generated | | System;Half;TanPi;(System.Half);summary;df-generated | | System;Half;Tanh;(System.Half);summary;df-generated | @@ -51064,7 +52167,10 @@ neutral | System;Int32;MinNumber;(System.Int32,System.Int32);summary;df-generated | | System;Int32;Parse;(System.ReadOnlySpan,System.Globalization.NumberStyles,System.IFormatProvider);summary;df-generated | | System;Int32;Parse;(System.ReadOnlySpan,System.IFormatProvider);summary;df-generated | +| System;Int32;Parse;(System.ReadOnlySpan,System.Globalization.NumberStyles,System.IFormatProvider);summary;df-generated | | System;Int32;Parse;(System.ReadOnlySpan,System.IFormatProvider);summary;df-generated | +| System;Int32;Parse;(System.String,System.Globalization.NumberStyles,System.IFormatProvider);summary;df-generated | +| System;Int32;Parse;(System.String,System.IFormatProvider);summary;df-generated | | System;Int32;PopCount;(System.Int32);summary;df-generated | | System;Int32;RotateLeft;(System.Int32,System.Int32);summary;df-generated | | System;Int32;RotateRight;(System.Int32,System.Int32);summary;df-generated | @@ -51123,7 +52229,9 @@ neutral | System;Int32;TryParse;(System.ReadOnlySpan,System.Globalization.NumberStyles,System.IFormatProvider,System.Int32);summary;df-generated | | System;Int32;TryParse;(System.ReadOnlySpan,System.IFormatProvider,System.Int32);summary;df-generated | | System;Int32;TryParse;(System.ReadOnlySpan,System.Int32);summary;df-generated | +| System;Int32;TryParse;(System.ReadOnlySpan,System.Globalization.NumberStyles,System.IFormatProvider,System.Int32);summary;df-generated | | System;Int32;TryParse;(System.ReadOnlySpan,System.IFormatProvider,System.Int32);summary;df-generated | +| System;Int32;TryParse;(System.String,System.Globalization.NumberStyles,System.IFormatProvider,System.Int32);summary;df-generated | | System;Int32;TryParse;(System.String,System.IFormatProvider,System.Int32);summary;df-generated | | System;Int32;TryReadBigEndian;(System.ReadOnlySpan,System.Boolean,System.Int32);summary;df-generated | | System;Int32;TryReadLittleEndian;(System.ReadOnlySpan,System.Boolean,System.Int32);summary;df-generated | @@ -51266,6 +52374,7 @@ neutral | System;Int64;get_One;();summary;df-generated | | System;Int64;get_Radix;();summary;df-generated | | System;Int64;get_Zero;();summary;df-generated | +| System;Int128;Abs;(System.Int128);summary;df-generated | | System;Int128;CompareTo;(System.Int128);summary;df-generated | | System;Int128;CompareTo;(System.Object);summary;df-generated | | System;Int128;DivRem;(System.Int128,System.Int128);summary;df-generated | @@ -51295,6 +52404,10 @@ neutral | System;Int128;IsZero;(System.Int128);summary;df-generated | | System;Int128;LeadingZeroCount;(System.Int128);summary;df-generated | | System;Int128;Log2;(System.Int128);summary;df-generated | +| System;Int128;MaxMagnitude;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;MaxMagnitudeNumber;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;MinMagnitude;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;MinMagnitudeNumber;(System.Int128,System.Int128);summary;df-generated | | System;Int128;Parse;(System.ReadOnlySpan,System.Globalization.NumberStyles,System.IFormatProvider);summary;df-generated | | System;Int128;Parse;(System.ReadOnlySpan,System.IFormatProvider);summary;df-generated | | System;Int128;Parse;(System.ReadOnlySpan,System.Globalization.NumberStyles,System.IFormatProvider);summary;df-generated | @@ -51307,6 +52420,34 @@ neutral | System;Int128;RotateLeft;(System.Int128,System.Int32);summary;df-generated | | System;Int128;RotateRight;(System.Int128,System.Int32);summary;df-generated | | System;Int128;Sign;(System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IAdditionOperators.op_Addition;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IBitwiseOperators.op_BitwiseAnd;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IBitwiseOperators.op_BitwiseOr;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IBitwiseOperators.op_ExclusiveOr;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IBitwiseOperators.op_OnesComplement;(System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IComparisonOperators.op_GreaterThan;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IComparisonOperators.op_GreaterThanOrEqual;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IComparisonOperators.op_LessThan;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IComparisonOperators.op_LessThanOrEqual;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IDecrementOperators.op_CheckedDecrement;(System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IDecrementOperators.op_Decrement;(System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IDivisionOperators.op_CheckedDivision;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IDivisionOperators.op_Division;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IEqualityOperators.op_Equality;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IEqualityOperators.op_Inequality;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IIncrementOperators.op_CheckedIncrement;(System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IIncrementOperators.op_Increment;(System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IModulusOperators.op_Modulus;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IMultiplyOperators.op_CheckedMultiply;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IMultiplyOperators.op_Multiply;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IShiftOperators.op_LeftShift;(System.Int128,System.Int32);summary;df-generated | +| System;Int128;System.Numerics.IShiftOperators.op_RightShift;(System.Int128,System.Int32);summary;df-generated | +| System;Int128;System.Numerics.IShiftOperators.op_UnsignedRightShift;(System.Int128,System.Int32);summary;df-generated | +| System;Int128;System.Numerics.ISubtractionOperators.op_CheckedSubtraction;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.ISubtractionOperators.op_Subtraction;(System.Int128,System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IUnaryNegationOperators.op_CheckedUnaryNegation;(System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IUnaryNegationOperators.op_UnaryNegation;(System.Int128);summary;df-generated | +| System;Int128;System.Numerics.IUnaryPlusOperators.op_UnaryPlus;(System.Int128);summary;df-generated | | System;Int128;ToString;();summary;df-generated | | System;Int128;ToString;(System.IFormatProvider);summary;df-generated | | System;Int128;ToString;(System.String);summary;df-generated | @@ -51341,6 +52482,7 @@ neutral | System;Int128;get_One;();summary;df-generated | | System;Int128;get_Radix;();summary;df-generated | | System;Int128;get_Zero;();summary;df-generated | +| System;IntPtr;Abs;(System.IntPtr);summary;df-generated | | System;IntPtr;CompareTo;(System.IntPtr);summary;df-generated | | System;IntPtr;CompareTo;(System.Object);summary;df-generated | | System;IntPtr;DivRem;(System.IntPtr,System.IntPtr);summary;df-generated | @@ -51372,6 +52514,10 @@ neutral | System;IntPtr;IsZero;(System.IntPtr);summary;df-generated | | System;IntPtr;LeadingZeroCount;(System.IntPtr);summary;df-generated | | System;IntPtr;Log2;(System.IntPtr);summary;df-generated | +| System;IntPtr;MaxMagnitude;(System.IntPtr,System.IntPtr);summary;df-generated | +| System;IntPtr;MaxMagnitudeNumber;(System.IntPtr,System.IntPtr);summary;df-generated | +| System;IntPtr;MinMagnitude;(System.IntPtr,System.IntPtr);summary;df-generated | +| System;IntPtr;MinMagnitudeNumber;(System.IntPtr,System.IntPtr);summary;df-generated | | System;IntPtr;Parse;(System.ReadOnlySpan,System.Globalization.NumberStyles,System.IFormatProvider);summary;df-generated | | System;IntPtr;Parse;(System.ReadOnlySpan,System.IFormatProvider);summary;df-generated | | System;IntPtr;Parse;(System.ReadOnlySpan,System.Globalization.NumberStyles,System.IFormatProvider);summary;df-generated | @@ -51385,6 +52531,7 @@ neutral | System;IntPtr;RotateRight;(System.IntPtr,System.Int32);summary;df-generated | | System;IntPtr;Sign;(System.IntPtr);summary;df-generated | | System;IntPtr;Subtract;(System.IntPtr,System.Int32);summary;df-generated | +| System;IntPtr;System.Numerics.IAdditionOperators.op_Addition;(System.IntPtr,System.IntPtr);summary;df-generated | | System;IntPtr;System.Numerics.IBitwiseOperators.op_BitwiseAnd;(System.IntPtr,System.IntPtr);summary;df-generated | | System;IntPtr;System.Numerics.IBitwiseOperators.op_BitwiseOr;(System.IntPtr,System.IntPtr);summary;df-generated | | System;IntPtr;System.Numerics.IBitwiseOperators.op_ExclusiveOr;(System.IntPtr,System.IntPtr);summary;df-generated | @@ -51396,6 +52543,8 @@ neutral | System;IntPtr;System.Numerics.IDecrementOperators.op_CheckedDecrement;(System.IntPtr);summary;df-generated | | System;IntPtr;System.Numerics.IDecrementOperators.op_Decrement;(System.IntPtr);summary;df-generated | | System;IntPtr;System.Numerics.IDivisionOperators.op_Division;(System.IntPtr,System.IntPtr);summary;df-generated | +| System;IntPtr;System.Numerics.IEqualityOperators.op_Equality;(System.IntPtr,System.IntPtr);summary;df-generated | +| System;IntPtr;System.Numerics.IEqualityOperators.op_Inequality;(System.IntPtr,System.IntPtr);summary;df-generated | | System;IntPtr;System.Numerics.IIncrementOperators.op_CheckedIncrement;(System.IntPtr);summary;df-generated | | System;IntPtr;System.Numerics.IIncrementOperators.op_Increment;(System.IntPtr);summary;df-generated | | System;IntPtr;System.Numerics.IModulusOperators.op_Modulus;(System.IntPtr,System.IntPtr);summary;df-generated | @@ -52203,8 +53352,14 @@ neutral | System;Single;System.Numerics.IBitwiseOperators.op_BitwiseOr;(System.Single,System.Single);summary;df-generated | | System;Single;System.Numerics.IBitwiseOperators.op_ExclusiveOr;(System.Single,System.Single);summary;df-generated | | System;Single;System.Numerics.IBitwiseOperators.op_OnesComplement;(System.Single);summary;df-generated | +| System;Single;System.Numerics.IComparisonOperators.op_GreaterThan;(System.Single,System.Single);summary;df-generated | +| System;Single;System.Numerics.IComparisonOperators.op_GreaterThanOrEqual;(System.Single,System.Single);summary;df-generated | +| System;Single;System.Numerics.IComparisonOperators.op_LessThan;(System.Single,System.Single);summary;df-generated | +| System;Single;System.Numerics.IComparisonOperators.op_LessThanOrEqual;(System.Single,System.Single);summary;df-generated | | System;Single;System.Numerics.IDecrementOperators.op_Decrement;(System.Single);summary;df-generated | | System;Single;System.Numerics.IDivisionOperators.op_Division;(System.Single,System.Single);summary;df-generated | +| System;Single;System.Numerics.IEqualityOperators.op_Equality;(System.Single,System.Single);summary;df-generated | +| System;Single;System.Numerics.IEqualityOperators.op_Inequality;(System.Single,System.Single);summary;df-generated | | System;Single;System.Numerics.IIncrementOperators.op_Increment;(System.Single);summary;df-generated | | System;Single;System.Numerics.IModulusOperators.op_Modulus;(System.Single,System.Single);summary;df-generated | | System;Single;System.Numerics.IMultiplyOperators.op_Multiply;(System.Single,System.Single);summary;df-generated | @@ -52349,6 +53504,7 @@ neutral | System;String;LastIndexOfAny;(System.Char[],System.Int32);summary;df-generated | | System;String;LastIndexOfAny;(System.Char[],System.Int32,System.Int32);summary;df-generated | | System;String;Parse;(System.ReadOnlySpan,System.IFormatProvider);summary;df-generated | +| System;String;Parse;(System.String,System.IFormatProvider);summary;df-generated | | System;String;StartsWith;(System.Char);summary;df-generated | | System;String;StartsWith;(System.String);summary;df-generated | | System;String;StartsWith;(System.String,System.Boolean,System.Globalization.CultureInfo);summary;df-generated | @@ -52376,6 +53532,7 @@ neutral | System;String;ToUInt64;(System.IFormatProvider);summary;df-generated | | System;String;TryCopyTo;(System.Span);summary;df-generated | | System;String;TryParse;(System.ReadOnlySpan,System.IFormatProvider,System.String);summary;df-generated | +| System;String;TryParse;(System.String,System.IFormatProvider,System.String);summary;df-generated | | System;String;get_Chars;(System.Int32);summary;df-generated | | System;String;get_Length;();summary;df-generated | | System;String;op_Equality;(System.String,System.String);summary;df-generated | @@ -53235,6 +54392,7 @@ neutral | System;UInt64;get_One;();summary;df-generated | | System;UInt64;get_Radix;();summary;df-generated | | System;UInt64;get_Zero;();summary;df-generated | +| System;UInt128;Abs;(System.UInt128);summary;df-generated | | System;UInt128;CompareTo;(System.Object);summary;df-generated | | System;UInt128;CompareTo;(System.UInt128);summary;df-generated | | System;UInt128;DivRem;(System.UInt128,System.UInt128);summary;df-generated | @@ -53263,6 +54421,10 @@ neutral | System;UInt128;IsZero;(System.UInt128);summary;df-generated | | System;UInt128;LeadingZeroCount;(System.UInt128);summary;df-generated | | System;UInt128;Log2;(System.UInt128);summary;df-generated | +| System;UInt128;MaxMagnitude;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;MaxMagnitudeNumber;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;MinMagnitude;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;MinMagnitudeNumber;(System.UInt128,System.UInt128);summary;df-generated | | System;UInt128;Parse;(System.ReadOnlySpan,System.Globalization.NumberStyles,System.IFormatProvider);summary;df-generated | | System;UInt128;Parse;(System.ReadOnlySpan,System.IFormatProvider);summary;df-generated | | System;UInt128;Parse;(System.ReadOnlySpan,System.Globalization.NumberStyles,System.IFormatProvider);summary;df-generated | @@ -53275,6 +54437,34 @@ neutral | System;UInt128;RotateLeft;(System.UInt128,System.Int32);summary;df-generated | | System;UInt128;RotateRight;(System.UInt128,System.Int32);summary;df-generated | | System;UInt128;Sign;(System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IAdditionOperators.op_Addition;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IBitwiseOperators.op_BitwiseAnd;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IBitwiseOperators.op_BitwiseOr;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IBitwiseOperators.op_ExclusiveOr;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IBitwiseOperators.op_OnesComplement;(System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IComparisonOperators.op_GreaterThan;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IComparisonOperators.op_GreaterThanOrEqual;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IComparisonOperators.op_LessThan;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IComparisonOperators.op_LessThanOrEqual;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IDecrementOperators.op_CheckedDecrement;(System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IDecrementOperators.op_Decrement;(System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IDivisionOperators.op_CheckedDivision;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IDivisionOperators.op_Division;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IEqualityOperators.op_Equality;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IEqualityOperators.op_Inequality;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IIncrementOperators.op_CheckedIncrement;(System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IIncrementOperators.op_Increment;(System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IModulusOperators.op_Modulus;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IMultiplyOperators.op_CheckedMultiply;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IMultiplyOperators.op_Multiply;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IShiftOperators.op_LeftShift;(System.UInt128,System.Int32);summary;df-generated | +| System;UInt128;System.Numerics.IShiftOperators.op_RightShift;(System.UInt128,System.Int32);summary;df-generated | +| System;UInt128;System.Numerics.IShiftOperators.op_UnsignedRightShift;(System.UInt128,System.Int32);summary;df-generated | +| System;UInt128;System.Numerics.ISubtractionOperators.op_CheckedSubtraction;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.ISubtractionOperators.op_Subtraction;(System.UInt128,System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IUnaryNegationOperators.op_CheckedUnaryNegation;(System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IUnaryNegationOperators.op_UnaryNegation;(System.UInt128);summary;df-generated | +| System;UInt128;System.Numerics.IUnaryPlusOperators.op_UnaryPlus;(System.UInt128);summary;df-generated | | System;UInt128;ToString;();summary;df-generated | | System;UInt128;ToString;(System.IFormatProvider);summary;df-generated | | System;UInt128;ToString;(System.String);summary;df-generated | @@ -53309,6 +54499,7 @@ neutral | System;UInt128;get_One;();summary;df-generated | | System;UInt128;get_Radix;();summary;df-generated | | System;UInt128;get_Zero;();summary;df-generated | +| System;UIntPtr;Abs;(System.UIntPtr);summary;df-generated | | System;UIntPtr;CompareTo;(System.Object);summary;df-generated | | System;UIntPtr;CompareTo;(System.UIntPtr);summary;df-generated | | System;UIntPtr;DivRem;(System.UIntPtr,System.UIntPtr);summary;df-generated | @@ -53337,6 +54528,10 @@ neutral | System;UIntPtr;IsZero;(System.UIntPtr);summary;df-generated | | System;UIntPtr;LeadingZeroCount;(System.UIntPtr);summary;df-generated | | System;UIntPtr;Log2;(System.UIntPtr);summary;df-generated | +| System;UIntPtr;MaxMagnitude;(System.UIntPtr,System.UIntPtr);summary;df-generated | +| System;UIntPtr;MaxMagnitudeNumber;(System.UIntPtr,System.UIntPtr);summary;df-generated | +| System;UIntPtr;MinMagnitude;(System.UIntPtr,System.UIntPtr);summary;df-generated | +| System;UIntPtr;MinMagnitudeNumber;(System.UIntPtr,System.UIntPtr);summary;df-generated | | System;UIntPtr;Parse;(System.ReadOnlySpan,System.Globalization.NumberStyles,System.IFormatProvider);summary;df-generated | | System;UIntPtr;Parse;(System.ReadOnlySpan,System.IFormatProvider);summary;df-generated | | System;UIntPtr;Parse;(System.ReadOnlySpan,System.Globalization.NumberStyles,System.IFormatProvider);summary;df-generated | @@ -53350,6 +54545,7 @@ neutral | System;UIntPtr;RotateRight;(System.UIntPtr,System.Int32);summary;df-generated | | System;UIntPtr;Sign;(System.UIntPtr);summary;df-generated | | System;UIntPtr;Subtract;(System.UIntPtr,System.Int32);summary;df-generated | +| System;UIntPtr;System.Numerics.IAdditionOperators.op_Addition;(System.UIntPtr,System.UIntPtr);summary;df-generated | | System;UIntPtr;System.Numerics.IBitwiseOperators.op_BitwiseAnd;(System.UIntPtr,System.UIntPtr);summary;df-generated | | System;UIntPtr;System.Numerics.IBitwiseOperators.op_BitwiseOr;(System.UIntPtr,System.UIntPtr);summary;df-generated | | System;UIntPtr;System.Numerics.IBitwiseOperators.op_ExclusiveOr;(System.UIntPtr,System.UIntPtr);summary;df-generated | @@ -53361,6 +54557,8 @@ neutral | System;UIntPtr;System.Numerics.IDecrementOperators.op_CheckedDecrement;(System.UIntPtr);summary;df-generated | | System;UIntPtr;System.Numerics.IDecrementOperators.op_Decrement;(System.UIntPtr);summary;df-generated | | System;UIntPtr;System.Numerics.IDivisionOperators.op_Division;(System.UIntPtr,System.UIntPtr);summary;df-generated | +| System;UIntPtr;System.Numerics.IEqualityOperators.op_Equality;(System.UIntPtr,System.UIntPtr);summary;df-generated | +| System;UIntPtr;System.Numerics.IEqualityOperators.op_Inequality;(System.UIntPtr,System.UIntPtr);summary;df-generated | | System;UIntPtr;System.Numerics.IIncrementOperators.op_CheckedIncrement;(System.UIntPtr);summary;df-generated | | System;UIntPtr;System.Numerics.IIncrementOperators.op_Increment;(System.UIntPtr);summary;df-generated | | System;UIntPtr;System.Numerics.IModulusOperators.op_Modulus;(System.UIntPtr,System.UIntPtr);summary;df-generated | From 338ab96593586950dabee168a1428a7bf6e59af1 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Mon, 30 Sep 2024 10:46:39 -0400 Subject: [PATCH 053/347] Correct comment. --- cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql index 33fcad2cbf6f..7c9ae8b99319 100644 --- a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql +++ b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql @@ -20,10 +20,8 @@ class WideCharPointerType extends PointerType { } /** - * Recurse through types to find any intermediate type or final type - * that suggests the type is unlikely to be a string. - * Specifically looking for any unsigned character, or datatype with name containing "byte" - * or datatype uint8_t. + * Given type `cur`, recurses through all intermediate types to find + * any intermediate type equal to type `targ` */ predicate hasIntermediateType(Type cur, Type targ) { cur = targ From c4737c7fbb564935062937296ec9c4d3cbdaf00b Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Mon, 30 Sep 2024 10:58:45 -0400 Subject: [PATCH 054/347] Changing from hasIntermediateType to getABaseType. --- .../Security/CWE/CWE-704/WcharCharConversion.ql | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql index 7c9ae8b99319..5e6e8a66b00b 100644 --- a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql +++ b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql @@ -20,15 +20,15 @@ class WideCharPointerType extends PointerType { } /** - * Given type `cur`, recurses through all intermediate types to find - * any intermediate type equal to type `targ` + * Given type `t`, recurses through and returns all + * intermediate base types, including `t`. */ -predicate hasIntermediateType(Type cur, Type targ) { - cur = targ +Type getABaseType(Type t) { + result = t or - hasIntermediateType(cur.(DerivedType).getBaseType(), targ) + result = getABaseType(t.(DerivedType).getBaseType()) or - hasIntermediateType(cur.(TypedefType).getBaseType(), targ) + result = getABaseType(t.(TypedefType).getBaseType()) } /** @@ -40,7 +40,7 @@ class UnlikelyToBeAStringType extends Type { targ.(CharType).isUnsigned() or targ.getName().toLowerCase().matches(["uint8_t", "%byte%"]) | - hasIntermediateType(this, targ) + getABaseType(this) = targ ) } } @@ -59,7 +59,7 @@ class UnicodeMacroDependentWidthType extends Type { "TCHAR" ] | - hasIntermediateType(this, targ) + getABaseType(this) = targ ) } } From 51e787b31657ea2ed27c09aa02a29936d0455153 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Mon, 30 Sep 2024 11:02:43 -0400 Subject: [PATCH 055/347] Switching to looking for explicit declaration of unsigned char, to avoid cases where unsigned char is the default char width for `char`. --- cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql index 5e6e8a66b00b..f8a57aa0c54d 100644 --- a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql +++ b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql @@ -37,7 +37,9 @@ Type getABaseType(Type t) { class UnlikelyToBeAStringType extends Type { UnlikelyToBeAStringType() { exists(Type targ | - targ.(CharType).isUnsigned() or + // NOTE: not using CharType isUnsigned, but rather look for any explicitly declared unsigned + // char types. Assuming these are used for buffers, not strings. + targ.(CharType).getName().toLowerCase().matches(["unsigned%"]) or targ.getName().toLowerCase().matches(["uint8_t", "%byte%"]) | getABaseType(this) = targ From 31324fc7785e07524e6bc80b0032b347cb92e30d Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Mon, 30 Sep 2024 11:05:38 -0400 Subject: [PATCH 056/347] Altering ordering for exists statement to be clearer. --- cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql index f8a57aa0c54d..c31b4c8a6188 100644 --- a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql +++ b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql @@ -36,13 +36,11 @@ Type getABaseType(Type t) { */ class UnlikelyToBeAStringType extends Type { UnlikelyToBeAStringType() { - exists(Type targ | - // NOTE: not using CharType isUnsigned, but rather look for any explicitly declared unsigned + exists(Type targ | getABaseType(this) = targ | + // NOTE: not using CharType isUnsigned, but rather look for any explicitly declared unsigned // char types. Assuming these are used for buffers, not strings. targ.(CharType).getName().toLowerCase().matches(["unsigned%"]) or targ.getName().toLowerCase().matches(["uint8_t", "%byte%"]) - | - getABaseType(this) = targ ) } } From c91f7f4918709e78f03234538c75bdac08ef3d13 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Mon, 30 Sep 2024 11:07:09 -0400 Subject: [PATCH 057/347] Altering exists predicate ordering to be clearer. --- cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql index c31b4c8a6188..05a8a705575e 100644 --- a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql +++ b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql @@ -49,7 +49,7 @@ class UnlikelyToBeAStringType extends Type { // see https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types class UnicodeMacroDependentWidthType extends Type { UnicodeMacroDependentWidthType() { - exists(Type targ | + exists(Type targ | getABaseType(this) = targ | targ.getName() in [ "LPCTSTR", "LPTSTR", @@ -58,8 +58,6 @@ class UnicodeMacroDependentWidthType extends Type { "TBYTE", "TCHAR" ] - | - getABaseType(this) = targ ) } } From 318e75c0946281888f21fcc8da2c250f44db75a2 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Mon, 30 Sep 2024 11:10:28 -0400 Subject: [PATCH 058/347] Changing name of predicate to be clearer, and removing an unused parameter. --- cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql index 05a8a705575e..5ef519268704 100644 --- a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql +++ b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql @@ -78,9 +78,9 @@ class UnicodeMacroInvocation extends MacroInvocation { * the flag would indicate if UNICODE typing is set correctly to allow * or disallow a widening cast. */ -predicate isLikelyDynamicChecked(Expr e, GuardCondition gc) { +predicate isLikelyDynamicallyChecked(Expr e) { e.getType() instanceof UnicodeMacroDependentWidthType and - exists(BitwiseAndExpr bai, UnicodeMacroInvocation umi | bai.getAnOperand() = umi.getExpr() | + exists(GuardCondition gc, BitwiseAndExpr bai, UnicodeMacroInvocation umi | bai.getAnOperand() = umi.getExpr() | // bai == 0 is false when reaching `e.getBasicBlock()`. // That is, bai != 0 when reaching `e.getBasicBlock()`. gc.ensuresEq(bai, 0, e.getBasicBlock(), false) @@ -106,7 +106,7 @@ where // Avoid cases where the cast is guarded by a check to determine if // unicode encoding is enabled in such a way to disallow the dangerous cast // at runtime. - not isLikelyDynamicChecked(e1, _) + not isLikelyDynamicallyChecked(e1) select e1, "Conversion from " + e1.getType().toString() + " to " + e2.getType().toString() + ". Use of invalid string can lead to undefined behavior." From 9e9469f3ca9d8331792dc908a467ea72765b08b0 Mon Sep 17 00:00:00 2001 From: Ben Rodes Date: Mon, 30 Sep 2024 11:17:48 -0400 Subject: [PATCH 059/347] Update cpp/ql/src/change-notes/2024-09-26-wcharcharconversion-false-positives.md Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- .../2024-09-26-wcharcharconversion-false-positives.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/change-notes/2024-09-26-wcharcharconversion-false-positives.md b/cpp/ql/src/change-notes/2024-09-26-wcharcharconversion-false-positives.md index 7398013e9ef0..b0fa7a953c59 100644 --- a/cpp/ql/src/change-notes/2024-09-26-wcharcharconversion-false-positives.md +++ b/cpp/ql/src/change-notes/2024-09-26-wcharcharconversion-false-positives.md @@ -1,5 +1,5 @@ --- category: minorAnalysis --- -* Removed false positives caused by failure to detect byte arrays -* Removed false positives caused by failure to recognize dynamic checks prior to possible dangerous widening \ No newline at end of file +* The `cpp/incorrect-string-type-conversion` query now produces fewer false positives caused by failure to detect byte arrays. +* The `cpp/incorrect-string-type-conversion` query now produces fewer false positives caused by failure to recognize dynamic checks prior to possible dangerous widening. \ No newline at end of file From 162519185d78f2888c84ea884c302f249045df2e Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Mon, 30 Sep 2024 11:19:31 -0400 Subject: [PATCH 060/347] Removing unnecessary bracket/singleton set literal. --- cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql index 5ef519268704..da09e8a61a66 100644 --- a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql +++ b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql @@ -39,7 +39,7 @@ class UnlikelyToBeAStringType extends Type { exists(Type targ | getABaseType(this) = targ | // NOTE: not using CharType isUnsigned, but rather look for any explicitly declared unsigned // char types. Assuming these are used for buffers, not strings. - targ.(CharType).getName().toLowerCase().matches(["unsigned%"]) or + targ.(CharType).getName().toLowerCase().matches("unsigned%") or targ.getName().toLowerCase().matches(["uint8_t", "%byte%"]) ) } From c496503053ac6a11c989cafde0ce34835752f24e Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Mon, 30 Sep 2024 11:23:08 -0400 Subject: [PATCH 061/347] Formatting. --- cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql index da09e8a61a66..e3f15bd12b5d 100644 --- a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql +++ b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql @@ -80,7 +80,9 @@ class UnicodeMacroInvocation extends MacroInvocation { */ predicate isLikelyDynamicallyChecked(Expr e) { e.getType() instanceof UnicodeMacroDependentWidthType and - exists(GuardCondition gc, BitwiseAndExpr bai, UnicodeMacroInvocation umi | bai.getAnOperand() = umi.getExpr() | + exists(GuardCondition gc, BitwiseAndExpr bai, UnicodeMacroInvocation umi | + bai.getAnOperand() = umi.getExpr() + | // bai == 0 is false when reaching `e.getBasicBlock()`. // That is, bai != 0 when reaching `e.getBasicBlock()`. gc.ensuresEq(bai, 0, e.getBasicBlock(), false) From 684aedf6aa6b3cdf9e9a31c612f9d1f051d40f40 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 30 Sep 2024 18:24:49 +0100 Subject: [PATCH 062/347] Golang vendor dir extraction: add extractor option --- go/codeql-extractor.yml | 7 +++++++ go/extractor/extractor.go | 2 +- go/extractor/util/extractvendordirs.go | 3 ++- go/ql/integration-tests/extract-vendor/test.py | 3 +++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/go/codeql-extractor.yml b/go/codeql-extractor.yml index f21c0ed7466d..49c8c75232f3 100644 --- a/go/codeql-extractor.yml +++ b/go/codeql-extractor.yml @@ -27,3 +27,10 @@ options: The default is 'false'. type: string pattern: "^(false|true)$" + extract_vendor_dirs: + title: Whether to include Go vendor directories in the CodeQL database. + description: > + A value indicating whether Go vendor directories should be included in the CodeQL database. + The default is 'false'. + type: string + pattern: "^(false|true)$" diff --git a/go/extractor/extractor.go b/go/extractor/extractor.go index f372cc161805..eeb1513e7247 100644 --- a/go/extractor/extractor.go +++ b/go/extractor/extractor.go @@ -233,7 +233,7 @@ func ExtractWithFlags(buildFlags []string, patterns []string, extractTests bool) // Construct a list of directory segments to exclude from extraction, starting with ".." excludedDirs := []string{`\.\.`} - // If CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS is "true", we extract `vendor` directories; + // If CODEQL_EXTRACTOR_GO_[OPTION_]EXTRACT_VENDOR_DIRS is "true", we extract `vendor` directories; // otherwise (the default) is to exclude them from extraction includeVendor := util.IsVendorDirExtractionEnabled() if !includeVendor { diff --git a/go/extractor/util/extractvendordirs.go b/go/extractor/util/extractvendordirs.go index 778d5120cf20..eadf5d24740e 100644 --- a/go/extractor/util/extractvendordirs.go +++ b/go/extractor/util/extractvendordirs.go @@ -5,5 +5,6 @@ import ( ) func IsVendorDirExtractionEnabled() bool { - return os.Getenv("CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS") == "true" + return os.Getenv("CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS") == "true" || + os.Getenv("CODEQL_EXTRACTOR_GO_OPTION_EXTRACT_VENDOR_DIRS") == "true" } diff --git a/go/ql/integration-tests/extract-vendor/test.py b/go/ql/integration-tests/extract-vendor/test.py index 04dfd61c38f3..ff28cc6fe9a3 100644 --- a/go/ql/integration-tests/extract-vendor/test.py +++ b/go/ql/integration-tests/extract-vendor/test.py @@ -4,3 +4,6 @@ def test(codeql, go): os.environ["CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS"] = "true" codeql.database.create(source_root="src") + +def test_extractor_option(codeql, go): + codeql.database.create(source_root="src", extractor_option = "extract_vendor_dirs=true") From c9d6c8091368ccfd6d88b59c12f63c52ad0dbf90 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 30 Sep 2024 18:44:20 +0100 Subject: [PATCH 063/347] Log when vendor dir extraction is active --- go/extractor/extractor.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/go/extractor/extractor.go b/go/extractor/extractor.go index eeb1513e7247..69aeeddc2a47 100644 --- a/go/extractor/extractor.go +++ b/go/extractor/extractor.go @@ -81,11 +81,23 @@ func ExtractWithFlags(buildFlags []string, patterns []string, extractTests bool) } } - testMessage := "" + // If CODEQL_EXTRACTOR_GO_[OPTION_]EXTRACT_VENDOR_DIRS is "true", we extract `vendor` directories; + // otherwise (the default) is to exclude them from extraction + includeVendor := util.IsVendorDirExtractionEnabled() + + modeNotifications := make([]string, 0, 2) if extractTests { - testMessage = " (test extraction enabled)" + modeNotifications = append(modeNotifications, "test extraction enabled") + } + if includeVendor { + modeNotifications = append(modeNotifications, "extracting vendor directories") } - log.Printf("Running packages.Load%s.", testMessage) + + modeMessage := strings.Join(modeNotifications, ", ") + if modeMessage != "" { + modeMessage = " (" + modeMessage + ")" + } + log.Printf("Running packages.Load%s.", modeMessage) // This includes test packages if either we're tracing a `go test` command, // or if CODEQL_EXTRACTOR_GO_OPTION_EXTRACT_TESTS is set to "true". @@ -233,9 +245,6 @@ func ExtractWithFlags(buildFlags []string, patterns []string, extractTests bool) // Construct a list of directory segments to exclude from extraction, starting with ".." excludedDirs := []string{`\.\.`} - // If CODEQL_EXTRACTOR_GO_[OPTION_]EXTRACT_VENDOR_DIRS is "true", we extract `vendor` directories; - // otherwise (the default) is to exclude them from extraction - includeVendor := util.IsVendorDirExtractionEnabled() if !includeVendor { excludedDirs = append(excludedDirs, "vendor") } From be389b4c19d1ad3bf5f347238eca0b535f50cebd Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 30 Sep 2024 19:54:14 +0100 Subject: [PATCH 064/347] Go: deduplicate integration tests --- .../test-extraction-autobuild/test.py | 4 -- .../test-extraction-traced/src/Makefile | 2 - .../test-extraction-traced/src/go.mod | 3 -- .../test-extraction-traced/src/go.sum | 45 ------------------- .../test-extraction-traced/src/testme.go | 5 --- .../src/testme_blackbox_test.go | 15 ------- .../test-extraction-traced/src/testme_test.go | 19 -------- .../test-extraction-traced/test.expected | 9 ---- .../test-extraction-traced/test.py | 4 -- .../test-extraction-traced/test.ql | 9 ---- .../src/Makefile | 0 .../src/go.mod | 0 .../src/go.sum | 0 .../src/testme.go | 0 .../src/testme_blackbox_test.go | 0 .../src/testme_test.go | 0 .../test.expected | 0 .../integration-tests/test-extraction/test.py | 7 +++ .../test.ql | 0 19 files changed, 7 insertions(+), 115 deletions(-) delete mode 100644 go/ql/integration-tests/test-extraction-autobuild/test.py delete mode 100644 go/ql/integration-tests/test-extraction-traced/src/Makefile delete mode 100644 go/ql/integration-tests/test-extraction-traced/src/go.mod delete mode 100644 go/ql/integration-tests/test-extraction-traced/src/go.sum delete mode 100644 go/ql/integration-tests/test-extraction-traced/src/testme.go delete mode 100644 go/ql/integration-tests/test-extraction-traced/src/testme_blackbox_test.go delete mode 100644 go/ql/integration-tests/test-extraction-traced/src/testme_test.go delete mode 100644 go/ql/integration-tests/test-extraction-traced/test.expected delete mode 100644 go/ql/integration-tests/test-extraction-traced/test.py delete mode 100644 go/ql/integration-tests/test-extraction-traced/test.ql rename go/ql/integration-tests/{test-extraction-autobuild => test-extraction}/src/Makefile (100%) rename go/ql/integration-tests/{test-extraction-autobuild => test-extraction}/src/go.mod (100%) rename go/ql/integration-tests/{test-extraction-autobuild => test-extraction}/src/go.sum (100%) rename go/ql/integration-tests/{test-extraction-autobuild => test-extraction}/src/testme.go (100%) rename go/ql/integration-tests/{test-extraction-autobuild => test-extraction}/src/testme_blackbox_test.go (100%) rename go/ql/integration-tests/{test-extraction-autobuild => test-extraction}/src/testme_test.go (100%) rename go/ql/integration-tests/{test-extraction-autobuild => test-extraction}/test.expected (100%) create mode 100644 go/ql/integration-tests/test-extraction/test.py rename go/ql/integration-tests/{test-extraction-autobuild => test-extraction}/test.ql (100%) diff --git a/go/ql/integration-tests/test-extraction-autobuild/test.py b/go/ql/integration-tests/test-extraction-autobuild/test.py deleted file mode 100644 index 0dc91b5212c5..000000000000 --- a/go/ql/integration-tests/test-extraction-autobuild/test.py +++ /dev/null @@ -1,4 +0,0 @@ -import os - -def test(codeql, go): - codeql.database.create(source_root="src", extractor_option = ["extract_tests=true"]) diff --git a/go/ql/integration-tests/test-extraction-traced/src/Makefile b/go/ql/integration-tests/test-extraction-traced/src/Makefile deleted file mode 100644 index 266e02877884..000000000000 --- a/go/ql/integration-tests/test-extraction-traced/src/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - go get diff --git a/go/ql/integration-tests/test-extraction-traced/src/go.mod b/go/ql/integration-tests/test-extraction-traced/src/go.mod deleted file mode 100644 index c4a9f55df6c1..000000000000 --- a/go/ql/integration-tests/test-extraction-traced/src/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -go 1.14 - -module testsample diff --git a/go/ql/integration-tests/test-extraction-traced/src/go.sum b/go/ql/integration-tests/test-extraction-traced/src/go.sum deleted file mode 100644 index a8e1b59ae4b1..000000000000 --- a/go/ql/integration-tests/test-extraction-traced/src/go.sum +++ /dev/null @@ -1,45 +0,0 @@ -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go/ql/integration-tests/test-extraction-traced/src/testme.go b/go/ql/integration-tests/test-extraction-traced/src/testme.go deleted file mode 100644 index e24138553ce9..000000000000 --- a/go/ql/integration-tests/test-extraction-traced/src/testme.go +++ /dev/null @@ -1,5 +0,0 @@ -package testsample - -func PublicFunction() int { return 1 } - -func privateFunction() int { return 2 } diff --git a/go/ql/integration-tests/test-extraction-traced/src/testme_blackbox_test.go b/go/ql/integration-tests/test-extraction-traced/src/testme_blackbox_test.go deleted file mode 100644 index 18a507b5aa38..000000000000 --- a/go/ql/integration-tests/test-extraction-traced/src/testme_blackbox_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package testsample_test - -import ( - "testing" - "testsample" -) - -func TestTestMe(t *testing.T) { - - publicResult := testsample.PublicFunction() - if publicResult != 1 { - t.Errorf("Expected 1, got %d", publicResult) - } - -} diff --git a/go/ql/integration-tests/test-extraction-traced/src/testme_test.go b/go/ql/integration-tests/test-extraction-traced/src/testme_test.go deleted file mode 100644 index 183d7cd3dffe..000000000000 --- a/go/ql/integration-tests/test-extraction-traced/src/testme_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package testsample - -import ( - "testing" -) - -func TestTestMe(t *testing.T) { - - publicResult := PublicFunction() - if publicResult != 1 { - t.Errorf("Expected 1, got %d", publicResult) - } - - privateResult := privateFunction() - if privateResult != 2 { - t.Errorf("Expected 2, got %d", privateResult) - } - -} diff --git a/go/ql/integration-tests/test-extraction-traced/test.expected b/go/ql/integration-tests/test-extraction-traced/test.expected deleted file mode 100644 index 9e1585fc5ef8..000000000000 --- a/go/ql/integration-tests/test-extraction-traced/test.expected +++ /dev/null @@ -1,9 +0,0 @@ -#select -| src/testme.go:0:0:0:0 | src/testme.go | -| src/testme_blackbox_test.go:0:0:0:0 | src/testme_blackbox_test.go | -| src/testme_test.go:0:0:0:0 | src/testme_test.go | -calls -| src/testme_blackbox_test.go:10:18:10:44 | call to PublicFunction | src/testme.go:3:1:3:38 | function declaration | -| src/testme_test.go:9:18:9:33 | call to PublicFunction | src/testme.go:3:1:3:38 | function declaration | -| src/testme_test.go:14:19:14:35 | call to privateFunction | src/testme.go:5:1:5:39 | function declaration | -extractionErrors diff --git a/go/ql/integration-tests/test-extraction-traced/test.py b/go/ql/integration-tests/test-extraction-traced/test.py deleted file mode 100644 index 2887d3fa0d09..000000000000 --- a/go/ql/integration-tests/test-extraction-traced/test.py +++ /dev/null @@ -1,4 +0,0 @@ -import os - -def test(codeql, go): - codeql.database.create(source_root="src", command="go test -c") diff --git a/go/ql/integration-tests/test-extraction-traced/test.ql b/go/ql/integration-tests/test-extraction-traced/test.ql deleted file mode 100644 index 15eae8959862..000000000000 --- a/go/ql/integration-tests/test-extraction-traced/test.ql +++ /dev/null @@ -1,9 +0,0 @@ -import go -import semmle.go.DiagnosticsReporting - -from GoFile f -select f - -query predicate calls(CallExpr ce, FuncDecl f) { f = ce.getTarget().getFuncDecl() } - -query predicate extractionErrors(string msg, int sev) { reportableDiagnostics(_, msg, sev) } diff --git a/go/ql/integration-tests/test-extraction-autobuild/src/Makefile b/go/ql/integration-tests/test-extraction/src/Makefile similarity index 100% rename from go/ql/integration-tests/test-extraction-autobuild/src/Makefile rename to go/ql/integration-tests/test-extraction/src/Makefile diff --git a/go/ql/integration-tests/test-extraction-autobuild/src/go.mod b/go/ql/integration-tests/test-extraction/src/go.mod similarity index 100% rename from go/ql/integration-tests/test-extraction-autobuild/src/go.mod rename to go/ql/integration-tests/test-extraction/src/go.mod diff --git a/go/ql/integration-tests/test-extraction-autobuild/src/go.sum b/go/ql/integration-tests/test-extraction/src/go.sum similarity index 100% rename from go/ql/integration-tests/test-extraction-autobuild/src/go.sum rename to go/ql/integration-tests/test-extraction/src/go.sum diff --git a/go/ql/integration-tests/test-extraction-autobuild/src/testme.go b/go/ql/integration-tests/test-extraction/src/testme.go similarity index 100% rename from go/ql/integration-tests/test-extraction-autobuild/src/testme.go rename to go/ql/integration-tests/test-extraction/src/testme.go diff --git a/go/ql/integration-tests/test-extraction-autobuild/src/testme_blackbox_test.go b/go/ql/integration-tests/test-extraction/src/testme_blackbox_test.go similarity index 100% rename from go/ql/integration-tests/test-extraction-autobuild/src/testme_blackbox_test.go rename to go/ql/integration-tests/test-extraction/src/testme_blackbox_test.go diff --git a/go/ql/integration-tests/test-extraction-autobuild/src/testme_test.go b/go/ql/integration-tests/test-extraction/src/testme_test.go similarity index 100% rename from go/ql/integration-tests/test-extraction-autobuild/src/testme_test.go rename to go/ql/integration-tests/test-extraction/src/testme_test.go diff --git a/go/ql/integration-tests/test-extraction-autobuild/test.expected b/go/ql/integration-tests/test-extraction/test.expected similarity index 100% rename from go/ql/integration-tests/test-extraction-autobuild/test.expected rename to go/ql/integration-tests/test-extraction/test.expected diff --git a/go/ql/integration-tests/test-extraction/test.py b/go/ql/integration-tests/test-extraction/test.py new file mode 100644 index 000000000000..6419ae83f38c --- /dev/null +++ b/go/ql/integration-tests/test-extraction/test.py @@ -0,0 +1,7 @@ +import os + +def test_traced(codeql, go): + codeql.database.create(source_root="src", command="go test -c") + +def test_autobuild(codeql, go): + codeql.database.create(source_root="src", extractor_option = ["extract_tests=true"]) diff --git a/go/ql/integration-tests/test-extraction-autobuild/test.ql b/go/ql/integration-tests/test-extraction/test.ql similarity index 100% rename from go/ql/integration-tests/test-extraction-autobuild/test.ql rename to go/ql/integration-tests/test-extraction/test.ql From e97878ed63c546fbca7b5db5c995fd091ce7ce66 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 30 Sep 2024 19:49:00 +0000 Subject: [PATCH 065/347] Post-release preparation for codeql-cli-2.19.1 --- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/consistency-queries/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/automodel/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/controlflow/qlpack.yml | 2 +- shared/dataflow/qlpack.yml | 2 +- shared/mad/qlpack.yml | 2 +- shared/rangeanalysis/qlpack.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/threat-models/qlpack.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typeflow/qlpack.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/xml/qlpack.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 35 files changed, 35 insertions(+), 35 deletions(-) diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index f1a2ac3942f2..ba5db8c6e6f9 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 2.0.1 +version: 2.0.2-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index e541f95cd85f..d01ac2f048c2 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 1.2.4 +version: 1.2.5-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 871d2ed3619a..3cab08a0f3ec 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.7.26 +version: 1.7.27-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 00c3209afe98..c46baf0b2518 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.7.26 +version: 1.7.27-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index a8e9c68cfb44..55a99929ac87 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 3.0.0 +version: 3.0.1-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 82e9607d7ab7..6209cc5f88d5 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 1.0.9 +version: 1.0.10-dev groups: - csharp - queries diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index 9800f5090fac..5a7ca8082a53 100644 --- a/go/ql/consistency-queries/qlpack.yml +++ b/go/ql/consistency-queries/qlpack.yml @@ -1,5 +1,5 @@ name: codeql-go-consistency-queries -version: 1.0.9 +version: 1.0.10-dev groups: - go - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index b6987a250d1a..9cb5e3620117 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 2.1.0 +version: 2.1.1-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index e783026f6cfd..0b3f5076bb6d 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 1.1.0 +version: 1.1.1-dev groups: - go - queries diff --git a/java/ql/automodel/src/qlpack.yml b/java/ql/automodel/src/qlpack.yml index 1e1fdbb9f38d..fe961cb4392c 100644 --- a/java/ql/automodel/src/qlpack.yml +++ b/java/ql/automodel/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-automodel-queries -version: 1.0.9 +version: 1.0.10-dev groups: - java - automodel diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 9c69e18a30b8..0d4f67146c1b 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 4.1.0 +version: 4.1.1-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 635ef97836fe..c8e95f52ca4a 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 1.1.6 +version: 1.1.7-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index a93cb421a869..bea3bbacd5fa 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 2.0.1 +version: 2.0.2-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 49489696e79a..407aa03f7802 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 1.2.1 +version: 1.2.2-dev groups: - javascript - queries diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index a4d970e31297..76c86b26be6b 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 1.0.9 +version: 1.0.10-dev groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 316f7a1cc1e6..445940cdd889 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 2.1.0 +version: 2.1.1-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 02c861d40e1d..3f5ee4e78041 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 1.3.0 +version: 1.3.1-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index da808214ea50..dc0b471a171d 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 2.0.1 +version: 2.0.2-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 47651d248c01..b7eee713fbaa 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 1.1.4 +version: 1.1.5-dev groups: - ruby - queries diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index fc8bdde934d4..532b2fa69a09 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 2ad3f8bc73c0..df5c8c4c38af 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 1.1.3 +version: 1.1.4-dev groups: shared library: true dependencies: diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index ed0c1f7113c5..ef3755c80bc4 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index aaf1b1903576..b4deed51c9d8 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index d8b03f4ad2f5..5593197f674b 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 1bd2bea757b3..7bc3773a575f 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index 434466938b1c..dd4331d7e749 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 1.0.9 +version: 1.0.10-dev library: true groups: shared dataExtensions: diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index 9a89b262a321..2390ce7ad116 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,7 +1,7 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index 21b1ddbc9654..04f843aacb5f 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 6f7282c54e9e..e48446dc3e0b 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 3e644f92d6d1..5eccd54b2afa 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index ab191310e567..508143471db4 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: null diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index f43260879fb6..a81184e65886 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 4a63da564e55..1df4193b862f 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index dd1896b3c291..1904a1b1ca48 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 2.0.1 +version: 2.0.2-dev groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 8f33acf16a69..6fbae9403605 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 1.0.9 +version: 1.0.10-dev groups: - swift - queries From 9357762e06ffec5e188319f3d2ea86dba5048295 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 1 Oct 2024 00:03:04 +0200 Subject: [PATCH 066/347] Python: remove superflous code This is handled by parameter-argument matching --- .../semmle/python/dataflow/new/internal/DataFlowDispatch.qll | 4 ---- 1 file changed, 4 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index 28c1c652df46..88a6ed903146 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -372,10 +372,6 @@ abstract class DataFlowFunction extends DataFlowCallable, TFunction { result.getParameter() = func.getArg(index + this.positionalOffset()) ) or - exists(int index1, int index2 | ppos.isPositionalLowerBound(index1) and index2 >= index1 | - result.getParameter() = func.getArg(index2 + this.positionalOffset()) - ) - or exists(string name | ppos.isKeyword(name) | result.getParameter() = func.getArgByName(name)) or // `*args` From 1d6626c82151357893106ff277c4aeb4f35ea6c8 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 27 Sep 2024 15:02:37 +0200 Subject: [PATCH 067/347] Rust: Implement `IdentPat.toString()` --- rust/ql/.generated.list | 1 - rust/ql/.gitattributes | 1 - .../rust/elements/internal/IdentPatImpl.qll | 6 ++- .../generated/IdentPat/IdentPat.expected | 4 +- .../IdentPat/IdentPat_getName.expected | 4 +- .../IdentPat/IdentPat_getPat.expected | 2 +- .../generated/LetStmt/LetStmt_getPat.expected | 8 ++-- .../SlicePat/SlicePat_getPat.expected | 6 +-- .../TuplePat/TuplePat_getField.expected | 10 ++-- .../ql/test/extractor-tests/utf8/ast.expected | 2 +- .../CONSISTENCY/CfgConsistency.expected | 2 +- .../library-tests/controlflow/Cfg.expected | 46 +++++++++---------- 12 files changed, 46 insertions(+), 46 deletions(-) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index eb997e2eeffc..2c4bb309f4c0 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -239,7 +239,6 @@ lib/codeql/rust/elements/internal/GenericParamImpl.qll f435f80d7f275803c1311d362 lib/codeql/rust/elements/internal/GenericParamListConstructor.qll 7221146d1724e0add3a8e70e0e46670142589eb7143425e1871ac4358a8c8bdb 2fbb7576444d6b2da6164245e2660d592d276ae2c1ca9f2bda5656b1c5c0a73a lib/codeql/rust/elements/internal/GenericParamListImpl.qll 524aa0949df6d4d2cb9bee6226650f63a6f181d7644933fa265673b281074885 27b0210e5eaa2040bc8a093e35e1394befb6994b25369544738d0447ef269a9c lib/codeql/rust/elements/internal/IdentPatConstructor.qll 09792f5a070996b65f095dc6b1b9e0fb096a56648eed26c0643c59f82377cab0 0bb1a9fcdc62b5197aef3dd6e0ea4d679dde10d5be54b57b5209727ba66e078b -lib/codeql/rust/elements/internal/IdentPatImpl.qll 10b2758419b48d34013d0e1ea55006a72ea351e5298c9cde4d988f510d4094eb 63bdb210d7bcab42888b4f44688966a33951061573b0a9a734b5b262cbfa2cd8 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 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index b3526b1ec22f..932ff725a476 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -241,7 +241,6 @@ /lib/codeql/rust/elements/internal/GenericParamListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/GenericParamListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/IdentPatConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/IdentPatImpl.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 diff --git a/rust/ql/lib/codeql/rust/elements/internal/IdentPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/IdentPatImpl.qll index 6f90f3d6d032..0c6092074774 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/IdentPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/IdentPatImpl.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 `IdentPat`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.IdentPat * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A binding pattern. For example: * ```rust @@ -27,5 +27,7 @@ module Impl { * }; * ``` */ - class IdentPat extends Generated::IdentPat { } + class IdentPat extends Generated::IdentPat { + override string toString() { result = this.getName().getText() } + } } diff --git a/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat.expected b/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat.expected index 53a4c59d3986..5f7d899ccab9 100644 --- a/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat.expected +++ b/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat.expected @@ -1,2 +1,2 @@ -| gen_ident_pat.rs:6:22:6:22 | IdentPat | getNumberOfAttrs: | 0 | hasName: | yes | hasPat: | no | -| gen_ident_pat.rs:10:9:10:25 | IdentPat | getNumberOfAttrs: | 0 | hasName: | yes | hasPat: | yes | +| gen_ident_pat.rs:6:22:6:22 | y | getNumberOfAttrs: | 0 | hasName: | yes | hasPat: | no | +| gen_ident_pat.rs:10:9:10:25 | y | getNumberOfAttrs: | 0 | hasName: | yes | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getName.expected b/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getName.expected index 2a49521ead99..45273e9c8a41 100644 --- a/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getName.expected +++ b/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getName.expected @@ -1,2 +1,2 @@ -| gen_ident_pat.rs:6:22:6:22 | IdentPat | gen_ident_pat.rs:6:22:6:22 | Name | -| gen_ident_pat.rs:10:9:10:25 | IdentPat | gen_ident_pat.rs:10:9:10:9 | Name | +| gen_ident_pat.rs:6:22:6:22 | y | gen_ident_pat.rs:6:22:6:22 | Name | +| gen_ident_pat.rs:10:9:10:25 | y | gen_ident_pat.rs:10:9:10:9 | Name | diff --git a/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getPat.expected b/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getPat.expected index 705456753b9c..2e2f0d9228e0 100644 --- a/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getPat.expected @@ -1 +1 @@ -| gen_ident_pat.rs:10:9:10:25 | IdentPat | gen_ident_pat.rs:10:11:10:25 | TupleStructPat | +| gen_ident_pat.rs:10:9:10:25 | y | gen_ident_pat.rs:10:11:10:25 | TupleStructPat | 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 37462e8cfb64..93810df10e36 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 | IdentPat | -| gen_let_stmt.rs:6:5:6:20 | LetStmt | gen_let_stmt.rs:6:9:6:9 | IdentPat | -| gen_let_stmt.rs:7:5:7:15 | LetStmt | gen_let_stmt.rs:7:9:7:9 | IdentPat | -| gen_let_stmt.rs:8:5:8:10 | LetStmt | gen_let_stmt.rs:8:9:8:9 | IdentPat | +| 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 | 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 7c5355875f33..e874d3a22ee4 100644 --- a/rust/ql/test/extractor-tests/generated/SlicePat/SlicePat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/SlicePat/SlicePat_getPat.expected @@ -6,8 +6,8 @@ | 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:8:9:8:24 | SlicePat | 0 | gen_slice_pat.rs:8:10:8:10 | IdentPat | -| gen_slice_pat.rs:8:9:8:24 | SlicePat | 1 | gen_slice_pat.rs:8:13:8:13 | IdentPat | +| 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 | 3 | gen_slice_pat.rs:8:20:8:20 | IdentPat | +| 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 | 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 8f42a4e1393e..59d028b43ca9 100644 --- a/rust/ql/test/extractor-tests/generated/TuplePat/TuplePat_getField.expected +++ b/rust/ql/test/extractor-tests/generated/TuplePat/TuplePat_getField.expected @@ -1,6 +1,6 @@ -| gen_tuple_pat.rs:5:9:5:14 | TuplePat | 0 | gen_tuple_pat.rs:5:10:5:10 | IdentPat | -| gen_tuple_pat.rs:5:9:5:14 | TuplePat | 1 | gen_tuple_pat.rs:5:13:5:13 | IdentPat | -| gen_tuple_pat.rs:6:9:6:22 | TuplePat | 0 | gen_tuple_pat.rs:6:10:6:10 | IdentPat | -| gen_tuple_pat.rs:6:9:6:22 | TuplePat | 1 | gen_tuple_pat.rs:6:13:6:13 | IdentPat | +| gen_tuple_pat.rs:5:9:5:14 | TuplePat | 0 | gen_tuple_pat.rs:5:10:5:10 | x | +| 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 | 3 | gen_tuple_pat.rs:6:21:6:21 | IdentPat | +| 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/utf8/ast.expected b/rust/ql/test/extractor-tests/utf8/ast.expected index 2ebf1fb7f03d..5f353287fbb1 100644 --- a/rust/ql/test/extractor-tests/utf8/ast.expected +++ b/rust/ql/test/extractor-tests/utf8/ast.expected @@ -34,6 +34,6 @@ | 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:11:9:11:9 | IdentPat | | utf8-identifiers.rs:11:9:11:9 | Name | +| 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/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected index a997162e6cdc..ec8ec04bf3ea 100644 --- a/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected +++ b/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected @@ -1,5 +1,5 @@ deadEnd -| test.rs:55:13:55:17 | IdentPat | +| test.rs:55:13:55:17 | b | | test.rs:224:28:224:33 | ... < ... | | test.rs:239:30:239:48 | BlockExpr | scopeNoFirst diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 43cc44ea2cbe..52715de2a267 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -14,8 +14,8 @@ | test.rs:8:5:24:5 | enter test_break_and_continue | test.rs:9:9:9:22 | LetStmt | | | test.rs:8:5:24:5 | exit test_break_and_continue (normal) | test.rs:8:5:24:5 | exit test_break_and_continue | | | test.rs:9:9:9:22 | LetStmt | test.rs:9:21:9:21 | PathExpr | | -| test.rs:9:13:9:17 | IdentPat | test.rs:10:9:22:9 | ExprStmt | match, no-match | -| test.rs:9:21:9:21 | PathExpr | test.rs:9:13:9:17 | IdentPat | | +| test.rs:9:13:9:17 | i | test.rs:10:9:22:9 | ExprStmt | match, no-match | +| test.rs:9:21:9:21 | PathExpr | test.rs:9:13:9:17 | i | | | test.rs:10:9:22:9 | ExprStmt | test.rs:11:13:11:24 | ExprStmt | | | test.rs:10:9:22:9 | LoopExpr | test.rs:23:9:23:20 | ExprStmt | | | test.rs:10:14:22:9 | BlockExpr | test.rs:11:13:11:24 | ExprStmt | | @@ -99,13 +99,13 @@ | test.rs:49:17:49:32 | ExprStmt | test.rs:49:17:49:31 | ContinueExpr | | | test.rs:54:5:60:5 | enter test_while | test.rs:55:9:55:25 | LetStmt | | | test.rs:55:9:55:25 | LetStmt | test.rs:55:21:55:24 | true | | -| test.rs:55:21:55:24 | true | test.rs:55:13:55:17 | IdentPat | | +| test.rs:55:21:55:24 | true | test.rs:55:13:55:17 | b | | | test.rs:69:1:72:1 | enter test_nested_function | test.rs:70:5:70:28 | LetStmt | | | test.rs:69:1:72:1 | exit test_nested_function (normal) | test.rs:69:1:72:1 | exit test_nested_function | | | test.rs:69:40:72:1 | BlockExpr | test.rs:69:1:72:1 | exit test_nested_function (normal) | | | test.rs:70:5:70:28 | LetStmt | test.rs:70:19:70:27 | ClosureExpr | | -| test.rs:70:9:70:15 | IdentPat | test.rs:71:5:71:11 | PathExpr | match, no-match | -| test.rs:70:19:70:27 | ClosureExpr | test.rs:70:9:70:15 | IdentPat | | +| test.rs:70:9:70:15 | add_one | test.rs:71:5:71:11 | PathExpr | match, no-match | +| test.rs:70:19:70:27 | ClosureExpr | test.rs:70:9:70:15 | add_one | | | test.rs:70:19:70:27 | enter ClosureExpr | test.rs:70:23:70:23 | PathExpr | | | test.rs:70:19:70:27 | exit ClosureExpr (normal) | test.rs:70:19:70:27 | exit ClosureExpr | | | test.rs:70:23:70:23 | PathExpr | test.rs:70:27:70:27 | 1 | | @@ -212,8 +212,8 @@ | test.rs:129:5:136:5 | exit test_if_assignment (normal) | test.rs:129:5:136:5 | exit test_if_assignment | | | test.rs:129:42:136:5 | BlockExpr | test.rs:129:5:136:5 | exit test_if_assignment (normal) | | | test.rs:130:9:130:26 | LetStmt | test.rs:130:21:130:25 | false | | -| test.rs:130:13:130:17 | IdentPat | test.rs:131:12:131:12 | PathExpr | match, no-match | -| test.rs:130:21:130:25 | false | test.rs:130:13:130:17 | IdentPat | | +| test.rs:130:13:130:17 | x | test.rs:131:12:131:12 | PathExpr | match, no-match | +| test.rs:130:21:130:25 | false | test.rs:130:13:130:17 | x | | | test.rs:131:9:135:9 | IfExpr | test.rs:129:42:136:5 | BlockExpr | | | test.rs:131:12:131:12 | PathExpr | test.rs:131:16:131:19 | true | | | test.rs:131:12:131:19 | ... = ... | test.rs:132:13:132:13 | 1 | true | @@ -288,50 +288,50 @@ | test.rs:177:5:180:5 | exit test_and_operator (normal) | test.rs:177:5:180:5 | exit test_and_operator | | | test.rs:177:61:180:5 | BlockExpr | test.rs:177:5:180:5 | exit test_and_operator (normal) | | | test.rs:178:9:178:28 | LetStmt | test.rs:178:17:178:27 | ... && ... | | -| test.rs:178:13:178:13 | IdentPat | test.rs:179:9:179:9 | PathExpr | match, no-match | -| test.rs:178:17:178:17 | PathExpr | test.rs:178:13:178:13 | IdentPat | false | +| test.rs:178:13:178:13 | d | test.rs:179:9:179:9 | PathExpr | match, no-match | +| test.rs:178:17:178:17 | PathExpr | test.rs:178:13:178:13 | d | false | | test.rs:178:17:178:17 | PathExpr | test.rs:178:22:178:22 | PathExpr | true | | test.rs:178:17:178:22 | ... && ... | test.rs:178:17:178:17 | PathExpr | | | test.rs:178:17:178:27 | ... && ... | test.rs:178:17:178:22 | ... && ... | | -| test.rs:178:22:178:22 | PathExpr | test.rs:178:13:178:13 | IdentPat | false | +| test.rs:178:22:178:22 | PathExpr | test.rs:178:13:178:13 | d | false | | test.rs:178:22:178:22 | PathExpr | test.rs:178:27:178:27 | PathExpr | true | -| test.rs:178:27:178:27 | PathExpr | test.rs:178:13:178:13 | IdentPat | | +| test.rs:178:27:178:27 | PathExpr | test.rs:178:13:178:13 | d | | | test.rs:179:9:179:9 | PathExpr | test.rs:177:61:180:5 | BlockExpr | | | test.rs:182:5:185:5 | enter test_or_operator | test.rs:183:9:183:28 | LetStmt | | | test.rs:182:5:185:5 | exit test_or_operator (normal) | test.rs:182:5:185:5 | exit test_or_operator | | | test.rs:182:60:185:5 | BlockExpr | test.rs:182:5:185:5 | exit test_or_operator (normal) | | | test.rs:183:9:183:28 | LetStmt | test.rs:183:17:183:27 | ... \|\| ... | | -| test.rs:183:13:183:13 | IdentPat | test.rs:184:9:184:9 | PathExpr | match, no-match | -| test.rs:183:17:183:17 | PathExpr | test.rs:183:13:183:13 | IdentPat | true | +| test.rs:183:13:183:13 | d | test.rs:184:9:184:9 | PathExpr | match, no-match | +| test.rs:183:17:183:17 | PathExpr | test.rs:183:13:183:13 | d | true | | test.rs:183:17:183:17 | PathExpr | test.rs:183:22:183:22 | PathExpr | false | | test.rs:183:17:183:22 | ... \|\| ... | test.rs:183:17:183:17 | PathExpr | | | test.rs:183:17:183:27 | ... \|\| ... | test.rs:183:17:183:22 | ... \|\| ... | | -| test.rs:183:22:183:22 | PathExpr | test.rs:183:13:183:13 | IdentPat | true | +| test.rs:183:22:183:22 | PathExpr | test.rs:183:13:183:13 | d | true | | test.rs:183:22:183:22 | PathExpr | test.rs:183:27:183:27 | PathExpr | false | -| test.rs:183:27:183:27 | PathExpr | test.rs:183:13:183:13 | IdentPat | | +| test.rs:183:27:183:27 | PathExpr | test.rs:183:13:183:13 | d | | | test.rs:184:9:184:9 | PathExpr | test.rs:182:60:185:5 | BlockExpr | | | test.rs:187:5:190:5 | enter test_or_operator_2 | test.rs:188:9:188:36 | LetStmt | | | test.rs:187:5:190:5 | exit test_or_operator_2 (normal) | test.rs:187:5:190:5 | exit test_or_operator_2 | | | test.rs:187:61:190:5 | BlockExpr | test.rs:187:5:190:5 | exit test_or_operator_2 (normal) | | | test.rs:188:9:188:36 | LetStmt | test.rs:188:17:188:35 | ... \|\| ... | | -| test.rs:188:13:188:13 | IdentPat | test.rs:189:9:189:9 | PathExpr | match, no-match | -| test.rs:188:17:188:17 | PathExpr | test.rs:188:13:188:13 | IdentPat | true | +| test.rs:188:13:188:13 | d | test.rs:189:9:189:9 | PathExpr | match, no-match | +| test.rs:188:17:188:17 | PathExpr | test.rs:188:13:188:13 | d | true | | test.rs:188:17:188:17 | PathExpr | test.rs:188:23:188:23 | PathExpr | false | | test.rs:188:17:188:30 | ... \|\| ... | test.rs:188:17:188:17 | PathExpr | | | test.rs:188:17:188:35 | ... \|\| ... | test.rs:188:17:188:30 | ... \|\| ... | | -| test.rs:188:22:188:30 | ParenExpr | test.rs:188:13:188:13 | IdentPat | true | +| test.rs:188:22:188:30 | ParenExpr | test.rs:188:13:188:13 | d | true | | test.rs:188:22:188:30 | ParenExpr | test.rs:188:35:188:35 | PathExpr | false | | test.rs:188:23:188:23 | PathExpr | test.rs:188:28:188:29 | 28 | | | test.rs:188:23:188:29 | ... == ... | test.rs:188:22:188:30 | ParenExpr | | | test.rs:188:28:188:29 | 28 | test.rs:188:23:188:29 | ... == ... | | -| test.rs:188:35:188:35 | PathExpr | test.rs:188:13:188:13 | IdentPat | | +| test.rs:188:35:188:35 | PathExpr | test.rs:188:13:188:13 | d | | | test.rs:189:9:189:9 | PathExpr | test.rs:187:61:190:5 | BlockExpr | | | test.rs:192:5:195:5 | enter test_not_operator | test.rs:193:9:193:19 | LetStmt | | | test.rs:192:5:195:5 | exit test_not_operator (normal) | test.rs:192:5:195:5 | exit test_not_operator | | | test.rs:192:43:195:5 | BlockExpr | test.rs:192:5:195:5 | exit test_not_operator (normal) | | | test.rs:193:9:193:19 | LetStmt | test.rs:193:18:193:18 | PathExpr | | -| test.rs:193:13:193:13 | IdentPat | test.rs:194:9:194:9 | PathExpr | match, no-match | -| test.rs:193:17:193:18 | ! ... | test.rs:193:13:193:13 | IdentPat | | +| test.rs:193:13:193:13 | d | test.rs:194:9:194:9 | PathExpr | match, no-match | +| test.rs:193:17:193:18 | ! ... | test.rs:193:13:193:13 | d | | | test.rs:193:18:193:18 | PathExpr | test.rs:193:17:193:18 | ! ... | | | test.rs:194:9:194:9 | PathExpr | test.rs:192:43:195:5 | BlockExpr | | | test.rs:197:5:203:5 | enter test_if_and_operator | test.rs:198:12:198:22 | ... && ... | | @@ -416,8 +416,8 @@ | test.rs:251:1:264:1 | exit labelled_block (normal) | test.rs:251:1:264:1 | exit labelled_block | | | test.rs:251:28:264:1 | BlockExpr | test.rs:251:1:264:1 | exit labelled_block (normal) | | | test.rs:252:5:263:6 | LetStmt | test.rs:253:9:253:19 | ExprStmt | | -| test.rs:252:9:252:14 | IdentPat | test.rs:251:28:264:1 | BlockExpr | match, no-match | -| test.rs:252:18:263:5 | BlockExpr | test.rs:252:9:252:14 | IdentPat | | +| test.rs:252:9:252:14 | result | test.rs:251:28:264:1 | BlockExpr | match, no-match | +| test.rs:252:18:263:5 | BlockExpr | test.rs:252:9:252:14 | result | | | test.rs:253:9:253:16 | PathExpr | test.rs:253:9:253:18 | CallExpr | | | test.rs:253:9:253:18 | CallExpr | test.rs:254:9:256:9 | ExprStmt | | | test.rs:253:9:253:19 | ExprStmt | test.rs:253:9:253:16 | PathExpr | | From a282efc43e7a004c48c280ebdd9fced583e63f30 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Oct 2024 09:09:14 +0200 Subject: [PATCH 068/347] Rust: Add inline test expectations library --- rust/ql/.generated.list | 1 - rust/ql/.gitattributes | 1 - .../codeql/rust/elements/internal/CommentImpl.qll | 11 +++++++++-- rust/ql/test/utils/InlineExpectationsTest.qll | 8 ++++++++ .../utils/internal/InlineExpectationsTestImpl.qll | 15 +++++++++++++++ 5 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 rust/ql/test/utils/InlineExpectationsTest.qll create mode 100644 rust/ql/test/utils/internal/InlineExpectationsTestImpl.qll diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 2c4bb309f4c0..18337b8a6d78 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -193,7 +193,6 @@ lib/codeql/rust/elements/internal/ClosureBinderImpl.qll 58c6b17d34d678802ce3484f 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/CommentImpl.qll c1b7f2fca9cfb7e611b25486ca5f06c4996f4436b72ed3a76e27a6409af4ec01 36f7d7c6d2dadda4d3423afc4f23bdaf275978b6f3d9ca71bf145afc92858f9c lib/codeql/rust/elements/internal/ConstArgConstructor.qll f63021dc1ca2276786da3a981d06c18d7a360b5e75c08bca5d1afece4f7c4a83 487a870cbf5ed6554d671a8e159edd9261d853eba2d28ce2bd459759f47f11f2 lib/codeql/rust/elements/internal/ConstArgImpl.qll 234fe6533c208a1731cdb423aa3a28909bd7e042dbc28bbedfd4f62e42b6f21e c576a49006f7a10483041fc07f2f0d089710ac61840be61a2e71140db709f9c6 lib/codeql/rust/elements/internal/ConstBlockPatConstructor.qll ddb4a0045635d477e87360ecafec0ba90ddcffc6e62996eb6e7edd5a5d65b860 442061d0497a615b3f008b990f5e3c4f045110f76500eff81a7f44ffd1319acf diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 932ff725a476..8e15852654c4 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -195,7 +195,6 @@ /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/CommentImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ConstArgConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ConstArgImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ConstBlockPatConstructor.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.qll index 0e5b68b0f358..32a4f415ab7c 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.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 `Comment`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.Comment * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A comment. For example: * ```rust @@ -19,5 +19,12 @@ module Impl { * /// This is a doc comment * ``` */ - class Comment extends Generated::Comment { } + class Comment extends Generated::Comment { + /** + * Gets the text of this comment, excluding the comment marker. + */ + string getCommentText() { + exists(string s | s = this.getText() | result = s.regexpCapture("///?\\s*(.*)", 1)) + } + } } diff --git a/rust/ql/test/utils/InlineExpectationsTest.qll b/rust/ql/test/utils/InlineExpectationsTest.qll new file mode 100644 index 000000000000..840e04ccbe01 --- /dev/null +++ b/rust/ql/test/utils/InlineExpectationsTest.qll @@ -0,0 +1,8 @@ +/** + * Inline expectation tests for Rust. + * See `shared/util/codeql/util/test/InlineExpectationsTest.qll` + */ + +private import codeql.util.test.InlineExpectationsTest +private import internal.InlineExpectationsTestImpl +import Make diff --git a/rust/ql/test/utils/internal/InlineExpectationsTestImpl.qll b/rust/ql/test/utils/internal/InlineExpectationsTestImpl.qll new file mode 100644 index 000000000000..74b8a39431de --- /dev/null +++ b/rust/ql/test/utils/internal/InlineExpectationsTestImpl.qll @@ -0,0 +1,15 @@ +private import rust as R +private import R +private import codeql.util.test.InlineExpectationsTest + +module Impl implements InlineExpectationsTestSig { + /** + * A class representing line comments in C# used by the InlineExpectations core code + */ + class ExpectationComment extends R::Comment { + /** Gets the contents of the given comment, _without_ the preceding comment marker (`//`). */ + string getContents() { result = this.getCommentText() } + } + + class Location = R::Location; +} From bd68986fa4669251b440e6a6e7f22b0f0485fbd8 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 1 Oct 2024 10:01:22 +0200 Subject: [PATCH 069/347] Python: add test showing `dict` can take multiple arguments --- .../test/library-tests/dataflow/coverage/test_builtins.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/python/ql/test/library-tests/dataflow/coverage/test_builtins.py b/python/ql/test/library-tests/dataflow/coverage/test_builtins.py index 245923370765..2de6adeb20bf 100644 --- a/python/ql/test/library-tests/dataflow/coverage/test_builtins.py +++ b/python/ql/test/library-tests/dataflow/coverage/test_builtins.py @@ -142,6 +142,13 @@ def test_dict_from_dict(): SINK(d2["k"]) #$ flow="SOURCE, l:-2 -> d2['k']" SINK_F(d2["k1"]) +def test_dict_from_multiple_args(): + d = dict([("k", SOURCE), ("k1", NONSOURCE)], k2 = SOURCE, k3 = NONSOURCE) + SINK(d["k"]) #$ MISSING: flow="SOURCE, l:-1 -> d['k']" + SINK_F(d["k1"]) + SINK(d["k2"]) #$ flow="SOURCE, l:-3 -> d['k2']" + SINK_F(d["k3"]) + ## Container methods ### List From b0efffd8f05e7418eb24ff9f935383eb072449f3 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 27 Sep 2024 15:03:35 +0200 Subject: [PATCH 070/347] Rust: AST support for variables --- rust/ql/lib/codeql/rust/elements/Variable.qll | 9 + .../rust/elements/internal/VariableImpl.qll | 340 ++++++++++++++++++ rust/ql/lib/rust.qll | 1 + .../LetExpr/LetExpr_getExpr.expected | 2 +- .../MatchArm/MatchArm_getExpr.expected | 2 +- .../MatchExpr/MatchExpr_getExpr.expected | 4 +- .../library-tests/controlflow/Cfg.expected | 208 +++++------ .../CONSISTENCY/CfgConsistency.expected | 5 + .../variables/variables.expected | 144 ++++++++ .../test/library-tests/variables/variables.ql | 41 +++ .../test/library-tests/variables/variables.rs | 325 +++++++++++++++++ 11 files changed, 973 insertions(+), 108 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/elements/Variable.qll create mode 100644 rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll create mode 100644 rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected create mode 100644 rust/ql/test/library-tests/variables/variables.expected create mode 100644 rust/ql/test/library-tests/variables/variables.ql create mode 100644 rust/ql/test/library-tests/variables/variables.rs diff --git a/rust/ql/lib/codeql/rust/elements/Variable.qll b/rust/ql/lib/codeql/rust/elements/Variable.qll new file mode 100644 index 000000000000..76c2d9f19f72 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/Variable.qll @@ -0,0 +1,9 @@ +/** + * This module provides classes related to variables. + */ + +private import internal.VariableImpl + +final class Variable = Impl::Variable; + +final class VariableAccess = Impl::VariableAccess; diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll new file mode 100644 index 000000000000..9ddf1d9755a1 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -0,0 +1,340 @@ +private import rust +private import codeql.rust.elements.internal.generated.ParentChild +private import codeql.rust.elements.internal.PathExprImpl::Impl as PathExprImpl + +module Impl { + /** + * A variable scope. Either a block `{ ... }`, the guard/rhs + * of a match arm, or the body of a closure. + */ + abstract class VariableScope extends AstNode { } + + class BlockExprScope extends VariableScope, BlockExpr { } + + abstract class MatchArmScope extends VariableScope { + MatchArm arm; + + bindingset[arm] + MatchArmScope() { exists(arm) } + + Pat getPat() { result = arm.getPat() } + } + + class MatchArmExprScope extends MatchArmScope { + MatchArmExprScope() { this = arm.getExpr() } + } + + class MatchArmGuardScope extends MatchArmScope { + MatchArmGuardScope() { this = arm.getGuard() } + } + + class ClosureBodyScope extends VariableScope { + ClosureBodyScope() { this = any(ClosureExpr ce).getBody() } + } + + private Pat getImmediatePatParent(AstNode n) { + result = getImmediateParent(n) + or + result.(RecordPat).getRecordPatFieldList().getAField().getPat() = n + } + + private Pat getAPatAncestor(Pat p) { + (p instanceof IdentPat or p instanceof OrPat) and + exists(Pat p0 | result = getImmediatePatParent(p0) | + p0 = p + or + p0 = getAPatAncestor(p) and + not p0 instanceof OrPat + ) + } + + /** Gets the immediately enclosing `|` pattern of `p`, if any */ + private OrPat getEnclosingOrPat(Pat p) { result = getAPatAncestor(p) } + + /** Gets the outermost enclosing `|` pattern parent of `p`, if any. */ + private OrPat getOutermostEnclosingOrPat(IdentPat p) { + result = getEnclosingOrPat+(p) and + not exists(getEnclosingOrPat(result)) + } + + /** + * Holds if `p` declares a variable named `name` at `definingNode`. Normally, + * `definingNode = p`, except in cases like + * + * ```rust + * match either { + * Either::Left(x) | Either::Right(x) => println!(x), + * } + * ``` + * + * 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() + } + + /** A variable. */ + class Variable extends MkVariable { + private AstNode definingNode; + private string name; + + Variable() { this = MkVariable(definingNode, name) } + + /** Gets the name of this variable. */ + string getName() { result = name } + + /** Gets the location of this variable. */ + Location getLocation() { result = definingNode.getLocation() } + + /** Gets a textual representation of this variable. */ + string toString() { result = this.getName() } + + /** Gets an access to this variable. */ + VariableAccess getAnAccess() { result.getVariable() = this } + } + + /** A path expression that may access a local variable. */ + private class VariableAccessCand extends PathExpr { + string name_; + + VariableAccessCand() { + exists(Path p, PathSegment ps | + p = this.getPath() and + not p.hasQualifier() and + ps = p.getPart() and + not ps.hasGenericArgList() and + not ps.hasParamList() and + not ps.hasPathType() and + not ps.hasReturnTypeSyntax() and + name_ = ps.getNameRef().getText() + ) + } + + string getName() { result = name_ } + } + + private AstNode getAnAncestorInVariableScope(AstNode n) { + ( + n instanceof Pat or + n instanceof VariableAccessCand or + n instanceof LetStmt or + n instanceof VariableScope + ) and + exists(AstNode n0 | result = getImmediateParent(n0) | + n0 = n + or + n0 = getAnAncestorInVariableScope(n) and + not n0 instanceof VariableScope + ) + } + + /** Gets the immediately enclosing variable scope of `n`. */ + 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) + ) + or + exists(Pat mid | + mid = getAVariablePatAncestor(v) and + result = getImmediatePatParent(mid) + ) + } + + /** + * Holds if `v` is named `name` and is declared inside variable scope + * `scope`, and `v` is bound starting from `(line, column)`. + */ + private predicate variableDeclInScope( + Variable v, VariableScope scope, string name, int line, int column + ) { + name = v.getName() and + exists(Pat pat | pat = getAVariablePatAncestor(v) | + scope = + any(MatchArmScope arm | + arm.getPat() = pat and + arm.getLocation().hasLocationInfo(_, line, column, _, _) + ) + or + exists(Function f | + f.getParamList().getAParam().getPat() = pat and + scope = f.getBody() and + scope.getLocation().hasLocationInfo(_, line, column, _, _) + ) + or + exists(LetStmt let | + let.getPat() = pat and + scope = getEnclosingScope(let) and + // for `let` statements, variables are bound _after_ the statement, i.e. + // not in the RHS + let.getLocation().hasLocationInfo(_, _, _, line, column) + ) + or + exists(IfExpr ie, LetExpr let | + let.getPat() = pat and + ie.getCondition() = let and + scope = ie.getThen() and + scope.getLocation().hasLocationInfo(_, line, column, _, _) + ) + or + exists(ForExpr fe | + fe.getPat() = pat and + scope = fe.getLoopBody() and + scope.getLocation().hasLocationInfo(_, line, column, _, _) + ) + or + exists(ClosureExpr ce | + ce.getParamList().getAParam().getPat() = pat and + scope = ce.getBody() and + scope.getLocation().hasLocationInfo(_, line, column, _, _) + ) + ) + } + + /** + * Holds if `cand` may access a variable named `name` at + * `(startline, startcolumn, endline, endcolumn)` in the variable scope + * `scope`. + * + * `nestLevel` is the number of nested scopes that need to be traversed + * to reach `scope` from `cand`. + */ + private predicate variableAccessCandInScope( + VariableAccessCand cand, VariableScope scope, string name, int nestLevel, int startline, + int startcolumn, int endline, int endcolumn + ) { + name = cand.getName() and + scope = [cand.(VariableScope), getEnclosingScope(cand)] and + cand.getLocation().hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and + nestLevel = 0 + or + exists(VariableScope inner | + variableAccessCandInScope(cand, inner, name, nestLevel - 1, _, _, _, _) and + scope = getEnclosingScope(inner) and + // Use the location of the inner scope as the location of the access, instead of the + // actual access location. This allows us to collapse multiple accesses in inner + // scopes to a single entity + scope.getLocation().hasLocationInfo(_, startline, startcolumn, endline, endcolumn) + ) + } + + private newtype TVariableOrAccessCand = + TVariableOrAccessCandVariable(Variable v) or + TVariableOrAccessCandVariableAccessCand(VariableAccessCand va) + + private class VariableOrAccessCand extends TVariableOrAccessCand { + Variable asVariable() { this = TVariableOrAccessCandVariable(result) } + + VariableAccessCand asVariableAccessCand() { + this = TVariableOrAccessCandVariableAccessCand(result) + } + + string toString() { + result = this.asVariable().toString() or result = this.asVariableAccessCand().toString() + } + + Location getLocation() { + result = this.asVariable().getLocation() or result = this.asVariableAccessCand().getLocation() + } + + pragma[nomagic] + predicate rankBy( + string name, VariableScope scope, int startline, int startcolumn, int endline, int endcolumn + ) { + variableDeclInScope(this.asVariable(), scope, name, startline, startcolumn) and + endline = -1 and + endcolumn = -1 + or + variableAccessCandInScope(this.asVariableAccessCand(), scope, name, _, startline, startcolumn, + endline, endcolumn) + } + } + + /** + * Gets the rank of `v` amongst all other declarations or access candidates + * to a variable named `name` in the variable scope `scope`. + */ + private int rankVariableOrAccess(VariableScope scope, string name, VariableOrAccessCand v) { + v = + rank[result + 1](VariableOrAccessCand v0, int startline, int startcolumn, int endline, + int endcolumn | + v0.rankBy(name, scope, startline, startcolumn, endline, endcolumn) + | + v0 order by startline, startcolumn, endline, endcolumn + ) + } + + /** + * Holds if `v` can reach rank `rnk` in the variable scope `scope`. This is needed to + * take shadowing into account, for example in + * + * ```rust + * let x = 0; // rank 0 + * use(x); // rank 1 + * let x = ""; // rank 2 + * use(x); // rank 3 + * ``` + * + * the declaration at rank 0 can only reach the access at rank 1, while the declaration + * at rank 2 can only reach the access at rank 3. + */ + private predicate variableReachesRank(VariableScope scope, string name, Variable v, int rnk) { + rnk = rankVariableOrAccess(scope, name, TVariableOrAccessCandVariable(v)) + or + variableReachesRank(scope, name, v, rnk - 1) and + rnk = rankVariableOrAccess(scope, name, TVariableOrAccessCandVariableAccessCand(_)) + } + + private predicate variableReachesCand( + VariableScope scope, string name, Variable v, VariableAccessCand cand, int nestLevel + ) { + exists(int rnk | + variableReachesRank(scope, name, v, rnk) and + rnk = rankVariableOrAccess(scope, name, TVariableOrAccessCandVariableAccessCand(cand)) and + variableAccessCandInScope(cand, scope, name, nestLevel, _, _, _, _) + ) + } + + /** A variable access. */ + class VariableAccess extends PathExprImpl::PathExpr instanceof VariableAccessCand { + private string name; + private Variable v; + + VariableAccess() { variableAccess(_, name, v, this) } + + /** Gets the variable being accessed. */ + Variable getVariable() { result = v } + + override string toString() { result = name } + + override string getAPrimaryQlClass() { result = "VariableAccess" } + } + + cached + private module Cached { + cached + newtype TVariable = + MkVariable(AstNode definingNode, string name) { variableDecl(definingNode, _, name) } + + cached + predicate variableAccess(VariableScope scope, string name, Variable v, VariableAccessCand cand) { + v = + min(Variable v0, int nestLevel | + variableReachesCand(scope, name, v0, cand, nestLevel) + | + v0 order by nestLevel + ) + } + } + + private import Cached +} diff --git a/rust/ql/lib/rust.qll b/rust/ql/lib/rust.qll index 72d2bd5498d2..7723400c41b6 100644 --- a/rust/ql/lib/rust.qll +++ b/rust/ql/lib/rust.qll @@ -4,3 +4,4 @@ import codeql.rust.elements import codeql.Locations import codeql.files.FileSystem import codeql.rust.elements.LogicalOperation +import codeql.rust.elements.Variable 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 66fab8ec8099..f90fa5862299 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 | PathExpr | +| gen_let_expr.rs:5:8:5:31 | LetExpr | gen_let_expr.rs:5:22:5:31 | maybe_some | 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 ea9eaff95307..493ea8d9bb03 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 | PathExpr | +| 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 | 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 631592c910d6..924eb3f807fa 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 | PathExpr | -| gen_match_expr.rs:9:5:12:5 | MatchExpr | gen_match_expr.rs:9:11:9:11 | PathExpr | +| 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 | diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 52715de2a267..d0ab3bd10d63 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -13,9 +13,9 @@ | test.rs:3:21:3:22 | 42 | test.rs:3:5:3:23 | CallExpr | | | test.rs:8:5:24:5 | enter test_break_and_continue | test.rs:9:9:9:22 | LetStmt | | | test.rs:8:5:24:5 | exit test_break_and_continue (normal) | test.rs:8:5:24:5 | exit test_break_and_continue | | -| test.rs:9:9:9:22 | LetStmt | test.rs:9:21:9:21 | PathExpr | | +| test.rs:9:9:9:22 | LetStmt | test.rs:9:21:9:21 | n | | | test.rs:9:13:9:17 | i | test.rs:10:9:22:9 | ExprStmt | match, no-match | -| test.rs:9:21:9:21 | PathExpr | test.rs:9:13:9:17 | i | | +| test.rs:9:21:9:21 | n | test.rs:9:13:9:17 | i | | | test.rs:10:9:22:9 | ExprStmt | test.rs:11:13:11:24 | ExprStmt | | | test.rs:10:9:22:9 | LoopExpr | test.rs:23:9:23:20 | ExprStmt | | | test.rs:10:14:22:9 | BlockExpr | test.rs:11:13:11:24 | ExprStmt | | @@ -67,15 +67,15 @@ | test.rs:27:9:36:9 | LoopExpr | test.rs:37:9:37:12 | true | | | test.rs:27:22:36:9 | BlockExpr | test.rs:29:17:33:17 | ExprStmt | | | test.rs:28:13:35:13 | LoopExpr | test.rs:27:22:36:9 | BlockExpr | | -| test.rs:29:17:33:17 | ExprStmt | test.rs:29:20:29:20 | PathExpr | | +| test.rs:29:17:33:17 | ExprStmt | test.rs:29:20:29:20 | b | | | test.rs:29:17:33:17 | IfExpr | test.rs:34:17:34:29 | ExprStmt | | -| test.rs:29:20:29:20 | PathExpr | test.rs:30:21:30:26 | ExprStmt | true | -| test.rs:29:20:29:20 | PathExpr | test.rs:31:27:31:27 | PathExpr | false | +| test.rs:29:20:29:20 | b | test.rs:30:21:30:26 | ExprStmt | true | +| test.rs:29:20:29:20 | b | test.rs:31:27:31:27 | b | false | | test.rs:30:21:30:25 | BreakExpr | test.rs:28:13:35:13 | LoopExpr | break | | test.rs:30:21:30:26 | ExprStmt | test.rs:30:21:30:25 | BreakExpr | | | test.rs:31:24:33:17 | IfExpr | test.rs:29:17:33:17 | IfExpr | | -| test.rs:31:27:31:27 | PathExpr | test.rs:31:24:33:17 | IfExpr | false | -| test.rs:31:27:31:27 | PathExpr | test.rs:32:21:32:33 | ExprStmt | true | +| test.rs:31:27:31:27 | b | test.rs:31:24:33:17 | IfExpr | false | +| test.rs:31:27:31:27 | b | test.rs:32:21:32:33 | ExprStmt | true | | test.rs:32:21:32:32 | BreakExpr | test.rs:27:9:36:9 | LoopExpr | break('outer) | | test.rs:32:21:32:33 | ExprStmt | test.rs:32:21:32:32 | BreakExpr | | | test.rs:34:17:34:28 | BreakExpr | test.rs:28:13:35:13 | LoopExpr | break('inner) | @@ -84,15 +84,15 @@ | test.rs:40:5:52:5 | enter test_continue_with_labels | test.rs:42:13:42:14 | ExprStmt | | | test.rs:42:13:42:13 | 1 | test.rs:44:17:48:17 | ExprStmt | | | test.rs:42:13:42:14 | ExprStmt | test.rs:42:13:42:13 | 1 | | -| test.rs:44:17:48:17 | ExprStmt | test.rs:44:20:44:20 | PathExpr | | +| test.rs:44:17:48:17 | ExprStmt | test.rs:44:20:44:20 | b | | | test.rs:44:17:48:17 | IfExpr | test.rs:49:17:49:32 | ExprStmt | | -| test.rs:44:20:44:20 | PathExpr | test.rs:45:21:45:29 | ExprStmt | true | -| test.rs:44:20:44:20 | PathExpr | test.rs:46:27:46:27 | PathExpr | false | +| test.rs:44:20:44:20 | b | test.rs:45:21:45:29 | ExprStmt | true | +| test.rs:44:20:44:20 | b | test.rs:46:27:46:27 | b | false | | test.rs:45:21:45:28 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | continue | | test.rs:45:21:45:29 | ExprStmt | test.rs:45:21:45:28 | ContinueExpr | | | test.rs:46:24:48:17 | IfExpr | test.rs:44:17:48:17 | IfExpr | | -| test.rs:46:27:46:27 | PathExpr | test.rs:46:24:48:17 | IfExpr | false | -| test.rs:46:27:46:27 | PathExpr | test.rs:47:21:47:36 | ExprStmt | true | +| test.rs:46:27:46:27 | b | test.rs:46:24:48:17 | IfExpr | false | +| test.rs:46:27:46:27 | b | test.rs:47:21:47:36 | ExprStmt | true | | test.rs:47:21:47:35 | ContinueExpr | test.rs:42:13:42:14 | ExprStmt | continue('outer) | | test.rs:47:21:47:36 | ExprStmt | test.rs:47:21:47:35 | ContinueExpr | | | test.rs:49:17:49:31 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | continue('inner) | @@ -104,30 +104,30 @@ | test.rs:69:1:72:1 | exit test_nested_function (normal) | test.rs:69:1:72:1 | exit test_nested_function | | | test.rs:69:40:72:1 | BlockExpr | test.rs:69:1:72:1 | exit test_nested_function (normal) | | | test.rs:70:5:70:28 | LetStmt | test.rs:70:19:70:27 | ClosureExpr | | -| test.rs:70:9:70:15 | add_one | test.rs:71:5:71:11 | PathExpr | match, no-match | +| test.rs:70:9:70:15 | add_one | test.rs:71:5:71:11 | add_one | match, no-match | | test.rs:70:19:70:27 | ClosureExpr | test.rs:70:9:70:15 | add_one | | -| test.rs:70:19:70:27 | enter ClosureExpr | test.rs:70:23:70:23 | PathExpr | | +| test.rs:70:19:70:27 | enter ClosureExpr | test.rs:70:23:70:23 | i | | | test.rs:70:19:70:27 | exit ClosureExpr (normal) | test.rs:70:19:70:27 | exit ClosureExpr | | -| test.rs:70:23:70:23 | PathExpr | test.rs:70:27:70:27 | 1 | | +| test.rs:70:23:70:23 | i | test.rs:70:27:70:27 | 1 | | | test.rs:70:23:70:27 | ... + ... | test.rs:70:19:70:27 | exit ClosureExpr (normal) | | | test.rs:70:27:70:27 | 1 | test.rs:70:23:70:27 | ... + ... | | -| test.rs:71:5:71:11 | PathExpr | test.rs:71:13:71:19 | PathExpr | | +| test.rs:71:5:71:11 | add_one | test.rs:71:13:71:19 | add_one | | | test.rs:71:5:71:23 | CallExpr | test.rs:69:40:72:1 | BlockExpr | | -| test.rs:71:13:71:19 | PathExpr | test.rs:71:21:71:21 | PathExpr | | +| test.rs:71:13:71:19 | add_one | test.rs:71:21:71:21 | n | | | test.rs:71:13:71:22 | CallExpr | test.rs:71:5:71:23 | CallExpr | | -| test.rs:71:21:71:21 | PathExpr | test.rs:71:13:71:22 | CallExpr | | -| test.rs:76:5:82:5 | enter test_if_else | test.rs:77:12:77:12 | PathExpr | | +| test.rs:71:21:71:21 | n | test.rs:71:13:71:22 | CallExpr | | +| test.rs:76:5:82:5 | enter test_if_else | test.rs:77:12:77:12 | n | | | test.rs:76:5:82:5 | exit test_if_else (normal) | test.rs:76:5:82:5 | exit test_if_else | | | test.rs:76:36:82:5 | BlockExpr | test.rs:76:5:82:5 | exit test_if_else (normal) | | | test.rs:77:9:81:9 | IfExpr | test.rs:76:36:82:5 | BlockExpr | | -| test.rs:77:12:77:12 | PathExpr | test.rs:77:17:77:17 | 0 | | +| test.rs:77:12:77:12 | n | test.rs:77:17:77:17 | 0 | | | test.rs:77:12:77:17 | ... <= ... | test.rs:78:13:78:13 | 0 | true | -| test.rs:77:12:77:17 | ... <= ... | test.rs:80:13:80:13 | PathExpr | false | +| test.rs:77:12:77:17 | ... <= ... | test.rs:80:13:80:13 | n | false | | test.rs:77:17:77:17 | 0 | test.rs:77:12:77:17 | ... <= ... | | | test.rs:77:19:79:9 | BlockExpr | test.rs:77:9:81:9 | IfExpr | | | test.rs:78:13:78:13 | 0 | test.rs:77:19:79:9 | BlockExpr | | | test.rs:79:16:81:9 | BlockExpr | test.rs:77:9:81:9 | IfExpr | | -| test.rs:80:13:80:13 | PathExpr | test.rs:80:17:80:17 | 1 | | +| test.rs:80:13:80:13 | n | test.rs:80:17:80:17 | 1 | | | test.rs:80:13:80:17 | ... - ... | test.rs:79:16:81:9 | BlockExpr | | | test.rs:80:17:80:17 | 1 | test.rs:80:13:80:17 | ... - ... | | | test.rs:84:5:90:5 | enter test_if_let_else | test.rs:85:12:85:26 | LetExpr | | @@ -135,10 +135,10 @@ | test.rs:84:48:90:5 | BlockExpr | test.rs:84:5:90:5 | exit test_if_let_else (normal) | | | test.rs:85:9:89:9 | IfExpr | test.rs:84:48:90:5 | BlockExpr | | | test.rs:85:12:85:26 | LetExpr | test.rs:85:16:85:22 | TupleStructPat | | -| test.rs:85:16:85:22 | TupleStructPat | test.rs:86:13:86:13 | PathExpr | match | +| test.rs:85:16:85:22 | TupleStructPat | test.rs:86:13:86:13 | n | match | | test.rs:85:16:85:22 | TupleStructPat | test.rs:88:13:88:13 | 0 | no-match | | test.rs:85:28:87:9 | BlockExpr | test.rs:85:9:89:9 | IfExpr | | -| test.rs:86:13:86:13 | PathExpr | test.rs:85:28:87:9 | BlockExpr | | +| test.rs:86:13:86:13 | n | test.rs:85:28:87:9 | BlockExpr | | | test.rs:87:16:89:9 | BlockExpr | test.rs:85:9:89:9 | IfExpr | | | test.rs:88:13:88:13 | 0 | test.rs:87:16:89:9 | BlockExpr | | | test.rs:92:5:97:5 | enter test_if_let | test.rs:93:9:95:9 | ExprStmt | | @@ -148,9 +148,9 @@ | test.rs:93:9:95:9 | IfExpr | test.rs:96:9:96:9 | 0 | | | test.rs:93:12:93:26 | LetExpr | test.rs:93:16:93:22 | TupleStructPat | | | test.rs:93:16:93:22 | TupleStructPat | test.rs:93:9:95:9 | IfExpr | no-match | -| test.rs:93:16:93:22 | TupleStructPat | test.rs:94:13:94:13 | PathExpr | match | +| test.rs:93:16:93:22 | TupleStructPat | test.rs:94:13:94:13 | n | match | | test.rs:93:28:95:9 | BlockExpr | test.rs:93:9:95:9 | IfExpr | | -| test.rs:94:13:94:13 | PathExpr | test.rs:93:28:95:9 | BlockExpr | | +| test.rs:94:13:94:13 | n | test.rs:93:28:95:9 | BlockExpr | | | test.rs:96:9:96:9 | 0 | test.rs:92:43:97:5 | BlockExpr | | | test.rs:99:5:105:5 | enter test_nested_if | test.rs:100:16:100:16 | PathExpr | | | test.rs:99:5:105:5 | exit test_nested_if (normal) | test.rs:99:5:105:5 | exit test_nested_if | | @@ -160,30 +160,30 @@ | test.rs:100:12:100:49 | ParenExpr | test.rs:103:13:103:13 | 0 | false | | test.rs:100:13:100:48 | IfExpr | test.rs:100:12:100:49 | ParenExpr | | | test.rs:100:16:100:16 | PathExpr | test.rs:100:20:100:20 | 0 | | -| test.rs:100:16:100:20 | ... < ... | test.rs:100:24:100:24 | PathExpr | true | -| test.rs:100:16:100:20 | ... < ... | test.rs:100:41:100:41 | PathExpr | false | +| test.rs:100:16:100:20 | ... < ... | test.rs:100:24:100:24 | a | true | +| test.rs:100:16:100:20 | ... < ... | test.rs:100:41:100:41 | a | false | | test.rs:100:20:100:20 | 0 | test.rs:100:16:100:20 | ... < ... | | | test.rs:100:22:100:32 | BlockExpr | test.rs:100:13:100:48 | IfExpr | | -| test.rs:100:24:100:24 | PathExpr | test.rs:100:29:100:30 | 10 | | +| test.rs:100:24:100:24 | a | test.rs:100:29:100:30 | 10 | | | test.rs:100:24:100:30 | ... < ... | test.rs:100:22:100:32 | BlockExpr | | | test.rs:100:28:100:30 | - ... | test.rs:100:24:100:30 | ... < ... | | | test.rs:100:29:100:30 | 10 | test.rs:100:28:100:30 | - ... | | | test.rs:100:39:100:48 | BlockExpr | test.rs:100:13:100:48 | IfExpr | | -| test.rs:100:41:100:41 | PathExpr | test.rs:100:45:100:46 | 10 | | +| test.rs:100:41:100:41 | a | test.rs:100:45:100:46 | 10 | | | test.rs:100:41:100:46 | ... > ... | test.rs:100:39:100:48 | BlockExpr | | | test.rs:100:45:100:46 | 10 | test.rs:100:41:100:46 | ... > ... | | | test.rs:100:51:102:9 | BlockExpr | test.rs:100:9:104:9 | IfExpr | | | test.rs:101:13:101:13 | 1 | test.rs:100:51:102:9 | BlockExpr | | | test.rs:102:16:104:9 | BlockExpr | test.rs:100:9:104:9 | IfExpr | | | test.rs:103:13:103:13 | 0 | test.rs:102:16:104:9 | BlockExpr | | -| test.rs:107:5:116:5 | enter test_nested_if_match | test.rs:108:19:108:19 | PathExpr | | +| test.rs:107:5:116:5 | enter test_nested_if_match | test.rs:108:19:108:19 | a | | | test.rs:107:5:116:5 | exit test_nested_if_match (normal) | test.rs:107:5:116:5 | exit test_nested_if_match | | | test.rs:107:44:116:5 | BlockExpr | test.rs:107:5:116:5 | exit test_nested_if_match (normal) | | | test.rs:108:9:115:9 | IfExpr | test.rs:107:44:116:5 | BlockExpr | | | test.rs:108:12:111:10 | ParenExpr | test.rs:112:13:112:13 | 1 | true | | test.rs:108:12:111:10 | ParenExpr | test.rs:114:13:114:13 | 0 | false | | test.rs:108:13:111:9 | MatchExpr | test.rs:108:12:111:10 | ParenExpr | | -| test.rs:108:19:108:19 | PathExpr | test.rs:109:13:109:13 | LiteralPat | | +| test.rs:108:19:108:19 | a | test.rs:109:13:109:13 | LiteralPat | | | test.rs:109:13:109:13 | LiteralPat | test.rs:109:18:109:21 | true | match | | test.rs:109:13:109:13 | LiteralPat | test.rs:110:13:110:13 | WildcardPat | no-match | | test.rs:109:18:109:21 | true | test.rs:108:13:111:9 | MatchExpr | | @@ -199,9 +199,9 @@ | test.rs:119:9:126:9 | IfExpr | test.rs:118:44:127:5 | BlockExpr | | | test.rs:119:12:122:9 | BlockExpr | test.rs:123:13:123:13 | 1 | true | | test.rs:119:12:122:9 | BlockExpr | test.rs:125:13:125:13 | 0 | false | -| test.rs:120:13:120:14 | TupleExpr | test.rs:121:13:121:13 | PathExpr | | +| test.rs:120:13:120:14 | TupleExpr | test.rs:121:13:121:13 | a | | | test.rs:120:13:120:15 | ExprStmt | test.rs:120:13:120:14 | TupleExpr | | -| test.rs:121:13:121:13 | PathExpr | test.rs:121:17:121:17 | 0 | | +| test.rs:121:13:121:13 | a | test.rs:121:17:121:17 | 0 | | | test.rs:121:13:121:17 | ... > ... | test.rs:119:12:122:9 | BlockExpr | false, true | | test.rs:121:17:121:17 | 0 | test.rs:121:13:121:17 | ... > ... | | | test.rs:122:11:124:9 | BlockExpr | test.rs:119:9:126:9 | IfExpr | | @@ -212,10 +212,10 @@ | test.rs:129:5:136:5 | exit test_if_assignment (normal) | test.rs:129:5:136:5 | exit test_if_assignment | | | test.rs:129:42:136:5 | BlockExpr | test.rs:129:5:136:5 | exit test_if_assignment (normal) | | | test.rs:130:9:130:26 | LetStmt | test.rs:130:21:130:25 | false | | -| test.rs:130:13:130:17 | x | test.rs:131:12:131:12 | PathExpr | match, no-match | +| test.rs:130:13:130:17 | x | test.rs:131:12:131:12 | x | match, no-match | | test.rs:130:21:130:25 | false | test.rs:130:13:130:17 | x | | | test.rs:131:9:135:9 | IfExpr | test.rs:129:42:136:5 | BlockExpr | | -| test.rs:131:12:131:12 | PathExpr | test.rs:131:16:131:19 | true | | +| test.rs:131:12:131:12 | x | test.rs:131:16:131:19 | true | | | test.rs:131:12:131:19 | ... = ... | test.rs:132:13:132:13 | 1 | true | | test.rs:131:12:131:19 | ... = ... | test.rs:134:13:134:13 | 0 | false | | test.rs:131:16:131:19 | true | test.rs:131:12:131:19 | ... = ... | | @@ -232,19 +232,19 @@ | test.rs:139:13:144:9 | LoopExpr | test.rs:139:12:144:10 | ParenExpr | | | test.rs:139:18:144:9 | BlockExpr | test.rs:140:13:142:14 | ExprStmt | | | test.rs:140:13:142:13 | IfExpr | test.rs:143:13:143:19 | ExprStmt | | -| test.rs:140:13:142:14 | ExprStmt | test.rs:140:16:140:16 | PathExpr | | -| test.rs:140:16:140:16 | PathExpr | test.rs:140:20:140:20 | 0 | | +| test.rs:140:13:142:14 | ExprStmt | test.rs:140:16:140:16 | a | | +| test.rs:140:16:140:16 | a | test.rs:140:20:140:20 | 0 | | | test.rs:140:16:140:20 | ... > ... | test.rs:140:13:142:13 | IfExpr | false | | test.rs:140:16:140:20 | ... > ... | test.rs:141:17:141:29 | ExprStmt | true | | test.rs:140:20:140:20 | 0 | test.rs:140:16:140:20 | ... > ... | | | test.rs:141:17:141:28 | BreakExpr | test.rs:139:13:144:9 | LoopExpr | break | -| test.rs:141:17:141:29 | ExprStmt | test.rs:141:23:141:23 | PathExpr | | -| test.rs:141:23:141:23 | PathExpr | test.rs:141:27:141:28 | 10 | | +| test.rs:141:17:141:29 | ExprStmt | test.rs:141:23:141:23 | a | | +| test.rs:141:23:141:23 | a | test.rs:141:27:141:28 | 10 | | | test.rs:141:23:141:28 | ... > ... | test.rs:141:17:141:28 | BreakExpr | | | test.rs:141:27:141:28 | 10 | test.rs:141:23:141:28 | ... > ... | | -| test.rs:143:13:143:13 | PathExpr | test.rs:143:17:143:18 | 10 | | +| test.rs:143:13:143:13 | a | test.rs:143:17:143:18 | 10 | | | test.rs:143:13:143:18 | ... < ... | test.rs:139:18:144:9 | BlockExpr | | -| test.rs:143:13:143:19 | ExprStmt | test.rs:143:13:143:13 | PathExpr | | +| test.rs:143:13:143:19 | ExprStmt | test.rs:143:13:143:13 | a | | | test.rs:143:17:143:18 | 10 | test.rs:143:13:143:18 | ... < ... | | | test.rs:144:12:146:9 | BlockExpr | test.rs:139:9:148:9 | IfExpr | | | test.rs:145:13:145:13 | 1 | test.rs:144:12:146:9 | BlockExpr | | @@ -259,19 +259,19 @@ | test.rs:152:13:157:9 | LoopExpr | test.rs:152:12:157:10 | ParenExpr | | | test.rs:152:26:157:9 | BlockExpr | test.rs:153:13:155:14 | ExprStmt | | | test.rs:153:13:155:13 | IfExpr | test.rs:156:13:156:19 | ExprStmt | | -| test.rs:153:13:155:14 | ExprStmt | test.rs:153:16:153:16 | PathExpr | | -| test.rs:153:16:153:16 | PathExpr | test.rs:153:20:153:20 | 0 | | +| test.rs:153:13:155:14 | ExprStmt | test.rs:153:16:153:16 | a | | +| test.rs:153:16:153:16 | a | test.rs:153:20:153:20 | 0 | | | test.rs:153:16:153:20 | ... > ... | test.rs:153:13:155:13 | IfExpr | false | | test.rs:153:16:153:20 | ... > ... | test.rs:154:17:154:36 | ExprStmt | true | | test.rs:153:20:153:20 | 0 | test.rs:153:16:153:20 | ... > ... | | | test.rs:154:17:154:35 | BreakExpr | test.rs:152:13:157:9 | LoopExpr | break('label) | -| test.rs:154:17:154:36 | ExprStmt | test.rs:154:30:154:30 | PathExpr | | -| test.rs:154:30:154:30 | PathExpr | test.rs:154:34:154:35 | 10 | | +| test.rs:154:17:154:36 | ExprStmt | test.rs:154:30:154:30 | a | | +| test.rs:154:30:154:30 | a | test.rs:154:34:154:35 | 10 | | | test.rs:154:30:154:35 | ... > ... | test.rs:154:17:154:35 | BreakExpr | | | test.rs:154:34:154:35 | 10 | test.rs:154:30:154:35 | ... > ... | | -| test.rs:156:13:156:13 | PathExpr | test.rs:156:17:156:18 | 10 | | +| test.rs:156:13:156:13 | a | test.rs:156:17:156:18 | 10 | | | test.rs:156:13:156:18 | ... < ... | test.rs:152:26:157:9 | BlockExpr | | -| test.rs:156:13:156:19 | ExprStmt | test.rs:156:13:156:13 | PathExpr | | +| test.rs:156:13:156:19 | ExprStmt | test.rs:156:13:156:13 | a | | | test.rs:156:17:156:18 | 10 | test.rs:156:13:156:18 | ... < ... | | | test.rs:157:12:159:9 | BlockExpr | test.rs:152:9:161:9 | IfExpr | | | test.rs:158:13:158:13 | 1 | test.rs:157:12:159:9 | BlockExpr | | @@ -280,72 +280,72 @@ | test.rs:164:5:172:5 | enter test_labelled_block | test.rs:166:13:166:31 | ExprStmt | | | test.rs:164:5:172:5 | exit test_labelled_block (normal) | test.rs:164:5:172:5 | exit test_labelled_block | | | test.rs:166:13:166:30 | BreakExpr | test.rs:164:5:172:5 | exit test_labelled_block (normal) | break('block) | -| test.rs:166:13:166:31 | ExprStmt | test.rs:166:26:166:26 | PathExpr | | -| test.rs:166:26:166:26 | PathExpr | test.rs:166:30:166:30 | 0 | | +| test.rs:166:13:166:31 | ExprStmt | test.rs:166:26:166:26 | a | | +| test.rs:166:26:166:26 | a | test.rs:166:30:166:30 | 0 | | | test.rs:166:26:166:30 | ... > ... | test.rs:166:13:166:30 | BreakExpr | | | test.rs:166:30:166:30 | 0 | test.rs:166:26:166:30 | ... > ... | | | test.rs:177:5:180:5 | enter test_and_operator | test.rs:178:9:178:28 | LetStmt | | | test.rs:177:5:180:5 | exit test_and_operator (normal) | test.rs:177:5:180:5 | exit test_and_operator | | | test.rs:177:61:180:5 | BlockExpr | test.rs:177:5:180:5 | exit test_and_operator (normal) | | | test.rs:178:9:178:28 | LetStmt | test.rs:178:17:178:27 | ... && ... | | -| test.rs:178:13:178:13 | d | test.rs:179:9:179:9 | PathExpr | match, no-match | -| test.rs:178:17:178:17 | PathExpr | test.rs:178:13:178:13 | d | false | -| test.rs:178:17:178:17 | PathExpr | test.rs:178:22:178:22 | PathExpr | true | -| test.rs:178:17:178:22 | ... && ... | test.rs:178:17:178:17 | PathExpr | | +| test.rs:178:13:178:13 | d | test.rs:179:9:179:9 | d | match, no-match | +| test.rs:178:17:178:17 | a | test.rs:178:13:178:13 | d | false | +| test.rs:178:17:178:17 | a | test.rs:178:22:178:22 | b | true | +| test.rs:178:17:178:22 | ... && ... | test.rs:178:17:178:17 | a | | | test.rs:178:17:178:27 | ... && ... | test.rs:178:17:178:22 | ... && ... | | -| test.rs:178:22:178:22 | PathExpr | test.rs:178:13:178:13 | d | false | -| test.rs:178:22:178:22 | PathExpr | test.rs:178:27:178:27 | PathExpr | true | -| test.rs:178:27:178:27 | PathExpr | test.rs:178:13:178:13 | d | | -| test.rs:179:9:179:9 | PathExpr | test.rs:177:61:180:5 | BlockExpr | | +| test.rs:178:22:178:22 | b | test.rs:178:13:178:13 | d | false | +| test.rs:178:22:178:22 | b | test.rs:178:27:178:27 | c | true | +| test.rs:178:27:178:27 | c | test.rs:178:13:178:13 | d | | +| test.rs:179:9:179:9 | d | test.rs:177:61:180:5 | BlockExpr | | | test.rs:182:5:185:5 | enter test_or_operator | test.rs:183:9:183:28 | LetStmt | | | test.rs:182:5:185:5 | exit test_or_operator (normal) | test.rs:182:5:185:5 | exit test_or_operator | | | test.rs:182:60:185:5 | BlockExpr | test.rs:182:5:185:5 | exit test_or_operator (normal) | | | test.rs:183:9:183:28 | LetStmt | test.rs:183:17:183:27 | ... \|\| ... | | -| test.rs:183:13:183:13 | d | test.rs:184:9:184:9 | PathExpr | match, no-match | -| test.rs:183:17:183:17 | PathExpr | test.rs:183:13:183:13 | d | true | -| test.rs:183:17:183:17 | PathExpr | test.rs:183:22:183:22 | PathExpr | false | -| test.rs:183:17:183:22 | ... \|\| ... | test.rs:183:17:183:17 | PathExpr | | +| test.rs:183:13:183:13 | d | test.rs:184:9:184:9 | d | match, no-match | +| test.rs:183:17:183:17 | a | test.rs:183:13:183:13 | d | true | +| test.rs:183:17:183:17 | a | test.rs:183:22:183:22 | b | false | +| test.rs:183:17:183:22 | ... \|\| ... | test.rs:183:17:183:17 | a | | | test.rs:183:17:183:27 | ... \|\| ... | test.rs:183:17:183:22 | ... \|\| ... | | -| test.rs:183:22:183:22 | PathExpr | test.rs:183:13:183:13 | d | true | -| test.rs:183:22:183:22 | PathExpr | test.rs:183:27:183:27 | PathExpr | false | -| test.rs:183:27:183:27 | PathExpr | test.rs:183:13:183:13 | d | | -| test.rs:184:9:184:9 | PathExpr | test.rs:182:60:185:5 | BlockExpr | | +| test.rs:183:22:183:22 | b | test.rs:183:13:183:13 | d | true | +| test.rs:183:22:183:22 | b | test.rs:183:27:183:27 | c | false | +| test.rs:183:27:183:27 | c | test.rs:183:13:183:13 | d | | +| test.rs:184:9:184:9 | d | test.rs:182:60:185:5 | BlockExpr | | | test.rs:187:5:190:5 | enter test_or_operator_2 | test.rs:188:9:188:36 | LetStmt | | | test.rs:187:5:190:5 | exit test_or_operator_2 (normal) | test.rs:187:5:190:5 | exit test_or_operator_2 | | | test.rs:187:61:190:5 | BlockExpr | test.rs:187:5:190:5 | exit test_or_operator_2 (normal) | | | test.rs:188:9:188:36 | LetStmt | test.rs:188:17:188:35 | ... \|\| ... | | -| test.rs:188:13:188:13 | d | test.rs:189:9:189:9 | PathExpr | match, no-match | -| test.rs:188:17:188:17 | PathExpr | test.rs:188:13:188:13 | d | true | -| test.rs:188:17:188:17 | PathExpr | test.rs:188:23:188:23 | PathExpr | false | -| test.rs:188:17:188:30 | ... \|\| ... | test.rs:188:17:188:17 | PathExpr | | +| test.rs:188:13:188:13 | d | test.rs:189:9:189:9 | d | match, no-match | +| test.rs:188:17:188:17 | a | test.rs:188:13:188:13 | d | true | +| test.rs:188:17:188:17 | a | test.rs:188:23:188:23 | b | false | +| test.rs:188:17:188:30 | ... \|\| ... | test.rs:188:17:188:17 | a | | | test.rs:188:17:188:35 | ... \|\| ... | test.rs:188:17:188:30 | ... \|\| ... | | | test.rs:188:22:188:30 | ParenExpr | test.rs:188:13:188:13 | d | true | -| test.rs:188:22:188:30 | ParenExpr | test.rs:188:35:188:35 | PathExpr | false | -| test.rs:188:23:188:23 | PathExpr | test.rs:188:28:188:29 | 28 | | +| test.rs:188:22:188:30 | ParenExpr | test.rs:188:35:188:35 | c | false | +| test.rs:188:23:188:23 | b | test.rs:188:28:188:29 | 28 | | | test.rs:188:23:188:29 | ... == ... | test.rs:188:22:188:30 | ParenExpr | | | test.rs:188:28:188:29 | 28 | test.rs:188:23:188:29 | ... == ... | | -| test.rs:188:35:188:35 | PathExpr | test.rs:188:13:188:13 | d | | -| test.rs:189:9:189:9 | PathExpr | test.rs:187:61:190:5 | BlockExpr | | +| test.rs:188:35:188:35 | c | test.rs:188:13:188:13 | d | | +| test.rs:189:9:189:9 | d | test.rs:187:61:190:5 | BlockExpr | | | test.rs:192:5:195:5 | enter test_not_operator | test.rs:193:9:193:19 | LetStmt | | | test.rs:192:5:195:5 | exit test_not_operator (normal) | test.rs:192:5:195:5 | exit test_not_operator | | | test.rs:192:43:195:5 | BlockExpr | test.rs:192:5:195:5 | exit test_not_operator (normal) | | -| test.rs:193:9:193:19 | LetStmt | test.rs:193:18:193:18 | PathExpr | | -| test.rs:193:13:193:13 | d | test.rs:194:9:194:9 | PathExpr | match, no-match | +| test.rs:193:9:193:19 | LetStmt | test.rs:193:18:193:18 | a | | +| test.rs:193:13:193:13 | d | test.rs:194:9:194:9 | d | match, no-match | | test.rs:193:17:193:18 | ! ... | test.rs:193:13:193:13 | d | | -| test.rs:193:18:193:18 | PathExpr | test.rs:193:17:193:18 | ! ... | | -| test.rs:194:9:194:9 | PathExpr | test.rs:192:43:195:5 | BlockExpr | | +| test.rs:193:18:193:18 | a | test.rs:193:17:193:18 | ! ... | | +| test.rs:194:9:194:9 | d | test.rs:192:43:195:5 | BlockExpr | | | test.rs:197:5:203:5 | enter test_if_and_operator | test.rs:198:12:198:22 | ... && ... | | | test.rs:197:5:203:5 | exit test_if_and_operator (normal) | test.rs:197:5:203:5 | exit test_if_and_operator | | | test.rs:197:63:203:5 | BlockExpr | test.rs:197:5:203:5 | exit test_if_and_operator (normal) | | | test.rs:198:9:202:9 | IfExpr | test.rs:197:63:203:5 | BlockExpr | | -| test.rs:198:12:198:12 | PathExpr | test.rs:198:17:198:17 | PathExpr | true | -| test.rs:198:12:198:12 | PathExpr | test.rs:201:13:201:17 | false | false | -| test.rs:198:12:198:17 | ... && ... | test.rs:198:12:198:12 | PathExpr | | +| test.rs:198:12:198:12 | a | test.rs:198:17:198:17 | b | true | +| test.rs:198:12:198:12 | a | test.rs:201:13:201:17 | false | false | +| test.rs:198:12:198:17 | ... && ... | test.rs:198:12:198:12 | a | | | test.rs:198:12:198:22 | ... && ... | test.rs:198:12:198:17 | ... && ... | | -| test.rs:198:17:198:17 | PathExpr | test.rs:198:22:198:22 | PathExpr | true | -| test.rs:198:17:198:17 | PathExpr | test.rs:201:13:201:17 | false | false | -| test.rs:198:22:198:22 | PathExpr | test.rs:199:13:199:16 | true | true | -| test.rs:198:22:198:22 | PathExpr | test.rs:201:13:201:17 | false | false | +| test.rs:198:17:198:17 | b | test.rs:198:22:198:22 | c | true | +| test.rs:198:17:198:17 | b | test.rs:201:13:201:17 | false | false | +| test.rs:198:22:198:22 | c | test.rs:199:13:199:16 | true | true | +| test.rs:198:22:198:22 | c | test.rs:201:13:201:17 | false | false | | test.rs:198:24:200:9 | BlockExpr | test.rs:198:9:202:9 | IfExpr | | | test.rs:199:13:199:16 | true | test.rs:198:24:200:9 | BlockExpr | | | test.rs:200:16:202:9 | BlockExpr | test.rs:198:9:202:9 | IfExpr | | @@ -354,41 +354,41 @@ | test.rs:205:5:211:5 | exit test_if_or_operator (normal) | test.rs:205:5:211:5 | exit test_if_or_operator | | | test.rs:205:62:211:5 | BlockExpr | test.rs:205:5:211:5 | exit test_if_or_operator (normal) | | | test.rs:206:9:210:9 | IfExpr | test.rs:205:62:211:5 | BlockExpr | | -| test.rs:206:12:206:12 | PathExpr | test.rs:206:17:206:17 | PathExpr | false | -| test.rs:206:12:206:12 | PathExpr | test.rs:207:13:207:16 | true | true | -| test.rs:206:12:206:17 | ... \|\| ... | test.rs:206:12:206:12 | PathExpr | | +| test.rs:206:12:206:12 | a | test.rs:206:17:206:17 | b | false | +| test.rs:206:12:206:12 | a | test.rs:207:13:207:16 | true | true | +| test.rs:206:12:206:17 | ... \|\| ... | test.rs:206:12:206:12 | a | | | test.rs:206:12:206:22 | ... \|\| ... | test.rs:206:12:206:17 | ... \|\| ... | | -| test.rs:206:17:206:17 | PathExpr | test.rs:206:22:206:22 | PathExpr | false | -| test.rs:206:17:206:17 | PathExpr | test.rs:207:13:207:16 | true | true | -| test.rs:206:22:206:22 | PathExpr | test.rs:207:13:207:16 | true | true | -| test.rs:206:22:206:22 | PathExpr | test.rs:209:13:209:17 | false | false | +| test.rs:206:17:206:17 | b | test.rs:206:22:206:22 | c | false | +| test.rs:206:17:206:17 | b | test.rs:207:13:207:16 | true | true | +| test.rs:206:22:206:22 | c | test.rs:207:13:207:16 | true | true | +| test.rs:206:22:206:22 | c | test.rs:209:13:209:17 | false | false | | test.rs:206:24:208:9 | BlockExpr | test.rs:206:9:210:9 | IfExpr | | | test.rs:207:13:207:16 | true | test.rs:206:24:208:9 | BlockExpr | | | test.rs:208:16:210:9 | BlockExpr | test.rs:206:9:210:9 | IfExpr | | | test.rs:209:13:209:17 | false | test.rs:208:16:210:9 | BlockExpr | | -| test.rs:213:5:219:5 | enter test_if_not_operator | test.rs:214:13:214:13 | PathExpr | | +| test.rs:213:5:219:5 | enter test_if_not_operator | test.rs:214:13:214:13 | a | | | test.rs:213:5:219:5 | exit test_if_not_operator (normal) | test.rs:213:5:219:5 | exit test_if_not_operator | | | test.rs:213:46:219:5 | BlockExpr | test.rs:213:5:219:5 | exit test_if_not_operator (normal) | | | test.rs:214:9:218:9 | IfExpr | test.rs:213:46:219:5 | BlockExpr | | | test.rs:214:12:214:13 | ! ... | test.rs:215:13:215:16 | true | true | | test.rs:214:12:214:13 | ! ... | test.rs:217:13:217:17 | false | false | -| test.rs:214:13:214:13 | PathExpr | test.rs:214:12:214:13 | ! ... | false, true | +| test.rs:214:13:214:13 | a | test.rs:214:12:214:13 | ! ... | false, true | | test.rs:214:15:216:9 | BlockExpr | test.rs:214:9:218:9 | IfExpr | | | test.rs:215:13:215:16 | true | test.rs:214:15:216:9 | BlockExpr | | | test.rs:216:16:218:9 | BlockExpr | test.rs:214:9:218:9 | IfExpr | | | test.rs:217:13:217:17 | false | test.rs:216:16:218:9 | BlockExpr | | -| test.rs:222:1:228:1 | enter test_match | test.rs:223:11:223:21 | PathExpr | | +| test.rs:222:1:228:1 | enter test_match | test.rs:223:11:223:21 | maybe_digit | | | test.rs:222:1:228:1 | exit test_match (normal) | test.rs:222:1:228:1 | exit test_match | | | test.rs:222:48:228:1 | BlockExpr | test.rs:222:1:228:1 | exit test_match (normal) | | | test.rs:223:5:227:5 | MatchExpr | test.rs:222:48:228:1 | BlockExpr | | -| test.rs:223:11:223:21 | PathExpr | test.rs:224:9:224:23 | TupleStructPat | | -| test.rs:224:9:224:23 | TupleStructPat | test.rs:224:28:224:28 | PathExpr | match | +| test.rs:223:11:223:21 | maybe_digit | test.rs:224:9:224:23 | TupleStructPat | | +| test.rs:224:9:224:23 | TupleStructPat | test.rs:224:28:224:28 | x | match | | test.rs:224:9:224:23 | TupleStructPat | test.rs:225:9:225:23 | TupleStructPat | no-match | -| test.rs:224:28:224:28 | PathExpr | test.rs:224:32:224:33 | 10 | | +| test.rs:224:28:224:28 | x | test.rs:224:32:224:33 | 10 | | | test.rs:224:32:224:33 | 10 | test.rs:224:28:224:33 | ... < ... | | -| test.rs:225:9:225:23 | TupleStructPat | test.rs:225:28:225:28 | PathExpr | match | +| test.rs:225:9:225:23 | TupleStructPat | test.rs:225:28:225:28 | x | match | | test.rs:225:9:225:23 | TupleStructPat | test.rs:226:9:226:20 | PathPat | no-match | -| test.rs:225:28:225:28 | PathExpr | test.rs:223:5:227:5 | MatchExpr | | +| test.rs:225:28:225:28 | x | test.rs:223:5:227:5 | MatchExpr | | | test.rs:226:9:226:20 | PathPat | test.rs:226:25:226:25 | 5 | match | | test.rs:226:25:226:25 | 5 | test.rs:223:5:227:5 | MatchExpr | | | test.rs:231:5:236:5 | enter test_infinite_loop | test.rs:232:9:234:9 | ExprStmt | | @@ -398,12 +398,12 @@ | test.rs:238:5:241:5 | enter test_let_match | test.rs:239:9:239:49 | LetStmt | | | test.rs:238:5:241:5 | exit test_let_match (normal) | test.rs:238:5:241:5 | exit test_let_match | | | test.rs:238:39:241:5 | BlockExpr | test.rs:238:5:241:5 | exit test_let_match (normal) | | -| test.rs:239:9:239:49 | LetStmt | test.rs:239:23:239:23 | PathExpr | | +| test.rs:239:9:239:49 | LetStmt | test.rs:239:23:239:23 | a | | | test.rs:239:13:239:19 | TupleStructPat | test.rs:239:32:239:46 | "Expected some" | no-match | -| test.rs:239:13:239:19 | TupleStructPat | test.rs:240:9:240:9 | PathExpr | match | -| test.rs:239:23:239:23 | PathExpr | test.rs:239:13:239:19 | TupleStructPat | | +| test.rs:239:13:239:19 | TupleStructPat | test.rs:240:9:240:9 | n | match | +| test.rs:239:23:239:23 | a | test.rs:239:13:239:19 | TupleStructPat | | | test.rs:239:32:239:46 | "Expected some" | test.rs:239:30:239:48 | BlockExpr | | -| test.rs:240:9:240:9 | PathExpr | test.rs:238:39:241:5 | BlockExpr | | +| test.rs:240:9:240:9 | n | test.rs:238:39:241:5 | BlockExpr | | | test.rs:244:1:249:1 | enter dead_code | test.rs:245:5:247:5 | ExprStmt | | | test.rs:244:1:249:1 | exit dead_code (normal) | test.rs:244:1:249:1 | exit dead_code | | | test.rs:245:5:247:5 | ExprStmt | test.rs:245:9:245:12 | true | | diff --git a/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected new file mode 100644 index 000000000000..56ae06526e76 --- /dev/null +++ b/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected @@ -0,0 +1,5 @@ +deadEnd +| variables.rs:2:5:2:22 | ExprStmt | +| variables.rs:6:5:6:22 | ExprStmt | +| variables.rs:200:16:200:21 | ... > ... | +| variables.rs:295:5:295:42 | LetStmt | diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected new file mode 100644 index 000000000000..18ee16a3da9c --- /dev/null +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -0,0 +1,144 @@ +testFailures +failures +variable +| variables.rs:1:14:1:14 | s | +| variables.rs:5:14:5:14 | i | +| variables.rs:10:9:10:10 | x1 | +| variables.rs:15:13:15:14 | x2 | +| variables.rs:22:9:22:10 | x3 | +| variables.rs:24:9:24:10 | x3 | +| variables.rs:30:9:30:10 | x4 | +| variables.rs:33:13:33:14 | x4 | +| variables.rs:47:13:47:14 | a1 | +| variables.rs:48:13:48:14 | b1 | +| variables.rs:51:13:51:13 | x | +| variables.rs:52:13:52:13 | y | +| variables.rs:62:9:62:10 | p1 | +| variables.rs:64:12:64:13 | a2 | +| variables.rs:65:12:65:13 | b2 | +| variables.rs:72:9:72:10 | s1 | +| variables.rs:74:21:74:22 | s2 | +| variables.rs:81:14:81:15 | x5 | +| variables.rs:89:9:89:10 | x6 | +| variables.rs:90:9:90:10 | y1 | +| variables.rs:94:14:94:15 | y1 | +| variables.rs:99:9:99:12 | None | +| variables.rs:106:9:106:15 | numbers | +| variables.rs:110:13:110:17 | first | +| variables.rs:111:13:111:17 | third | +| variables.rs:112:13:112:17 | fifth | +| variables.rs:122:13:122:17 | first | +| variables.rs:124:13:124:16 | last | +| variables.rs:133:9:133:10 | p2 | +| variables.rs:137:16:137:17 | x7 | +| variables.rs:147:9:147:11 | msg | +| variables.rs:151:17:151:27 | id_variable | +| variables.rs:156:26:156:27 | id | +| variables.rs:167:9:167:14 | either | +| variables.rs:169:9:169:44 | a3 | +| variables.rs:181:9:181:10 | tv | +| variables.rs:183:9:183:81 | a4 | +| variables.rs:187:9:187:83 | a5 | +| variables.rs:191:9:191:83 | a6 | +| variables.rs:197:9:197:14 | either | +| variables.rs:199:9:199:44 | a7 | +| variables.rs:207:9:207:14 | either | +| variables.rs:210:13:210:13 | e | +| variables.rs:211:14:211:51 | a11 | +| variables.rs:214:33:214:35 | a12 | +| variables.rs:224:5:224:6 | a8 | +| variables.rs:226:9:226:10 | b3 | +| variables.rs:227:9:227:10 | c1 | +| variables.rs:235:6:235:41 | a9 | +| variables.rs:242:13:242:15 | a10 | +| variables.rs:243:13:243:14 | b4 | +| variables.rs:244:13:244:14 | c2 | +| variables.rs:265:13:265:15 | a10 | +| variables.rs:266:13:266:14 | b4 | +| variables.rs:278:9:278:23 | example_closure | +| variables.rs:279:10:279:10 | x | +| variables.rs:281:9:281:10 | n1 | +| variables.rs:286:9:286:26 | immutable_variable | +| variables.rs:287:10:287:10 | x | +| variables.rs:289:9:289:10 | n2 | +| variables.rs:295:9:295:9 | v | +| variables.rs:297:9:297:12 | text | +variableAccess +| variables.rs:11:15:11:16 | x1 | variables.rs:10:9:10:10 | x1 | +| variables.rs:16:15:16:16 | x2 | variables.rs:15:13:15:14 | x2 | +| variables.rs:17:5:17:6 | x2 | variables.rs:15:13:15:14 | x2 | +| variables.rs:18:15:18:16 | x2 | variables.rs:15:13:15:14 | x2 | +| variables.rs:23:15:23:16 | x3 | variables.rs:22:9:22:10 | x3 | +| variables.rs:25:9:25:10 | x3 | variables.rs:22:9:22:10 | x3 | +| variables.rs:26:15:26:16 | x3 | variables.rs:24:9:24:10 | x3 | +| variables.rs:31:15:31:16 | x4 | variables.rs:30:9:30:10 | x4 | +| variables.rs:34:19:34:20 | x4 | variables.rs:33:13:33:14 | x4 | +| variables.rs:36:15:36:16 | x4 | variables.rs:30:9:30:10 | x4 | +| variables.rs:55:15:55:16 | a1 | variables.rs:47:13:47:14 | a1 | +| variables.rs:56:15:56:16 | b1 | variables.rs:48:13:48:14 | b1 | +| variables.rs:57:15:57:15 | x | variables.rs:51:13:51:13 | x | +| variables.rs:58:15:58:15 | y | variables.rs:52:13:52:13 | y | +| variables.rs:66:9:66:10 | p1 | variables.rs:62:9:62:10 | p1 | +| variables.rs:67:15:67:16 | a2 | variables.rs:64:12:64:13 | a2 | +| variables.rs:68:15:68:16 | b2 | variables.rs:65:12:65:13 | b2 | +| variables.rs:75:11:75:12 | s1 | variables.rs:72:9:72:10 | s1 | +| variables.rs:76:19:76:20 | s2 | variables.rs:74:21:74:22 | s2 | +| variables.rs:85:15:85:16 | x5 | variables.rs:81:14:81:15 | x5 | +| variables.rs:92:11:92:12 | x6 | variables.rs:89:9:89:10 | x6 | +| variables.rs:97:23:97:24 | y1 | variables.rs:94:14:94:15 | y1 | +| variables.rs:102:15:102:16 | y1 | variables.rs:90:9:90:10 | y1 | +| variables.rs:108:11:108:17 | numbers | variables.rs:106:9:106:15 | numbers | +| variables.rs:114:23:114:27 | first | variables.rs:110:13:110:17 | first | +| variables.rs:115:23:115:27 | third | variables.rs:111:13:111:17 | third | +| variables.rs:116:23:116:27 | fifth | variables.rs:112:13:112:17 | fifth | +| variables.rs:120:11:120:17 | numbers | variables.rs:106:9:106:15 | numbers | +| variables.rs:126:23:126:27 | first | variables.rs:122:13:122:17 | first | +| variables.rs:127:23:127:26 | last | variables.rs:124:13:124:16 | last | +| variables.rs:135:11:135:12 | p2 | variables.rs:133:9:133:10 | p2 | +| variables.rs:138:24:138:25 | x7 | variables.rs:137:16:137:17 | x7 | +| variables.rs:149:11:149:13 | msg | variables.rs:147:9:147:11 | msg | +| variables.rs:152:24:152:34 | id_variable | variables.rs:151:17:151:27 | id_variable | +| variables.rs:157:23:157:24 | id | variables.rs:156:26:156:27 | id | +| variables.rs:168:11:168:16 | either | variables.rs:167:9:167:14 | either | +| variables.rs:170:26:170:27 | a3 | variables.rs:169:9:169:44 | a3 | +| variables.rs:182:11:182:12 | tv | variables.rs:181:9:181:10 | tv | +| variables.rs:184:26:184:27 | a4 | variables.rs:183:9:183:81 | a4 | +| variables.rs:186:11:186:12 | tv | variables.rs:181:9:181:10 | tv | +| variables.rs:188:26:188:27 | a5 | variables.rs:187:9:187:83 | a5 | +| variables.rs:190:11:190:12 | tv | variables.rs:181:9:181:10 | tv | +| variables.rs:192:26:192:27 | a6 | variables.rs:191:9:191:83 | a6 | +| variables.rs:198:11:198:16 | either | variables.rs:197:9:197:14 | either | +| variables.rs:200:16:200:17 | a7 | variables.rs:199:9:199:44 | a7 | +| variables.rs:201:26:201:27 | a7 | variables.rs:199:9:199:44 | a7 | +| variables.rs:209:11:209:16 | either | variables.rs:207:9:207:14 | either | +| variables.rs:213:23:213:25 | a11 | variables.rs:211:14:211:51 | a11 | +| variables.rs:215:15:215:15 | e | variables.rs:210:13:210:13 | e | +| variables.rs:216:28:216:30 | a12 | variables.rs:214:33:214:35 | a12 | +| variables.rs:229:15:229:16 | a8 | variables.rs:224:5:224:6 | a8 | +| variables.rs:230:15:230:16 | b3 | variables.rs:226:9:226:10 | b3 | +| variables.rs:231:15:231:16 | c1 | variables.rs:227:9:227:10 | c1 | +| variables.rs:237:15:237:16 | a9 | variables.rs:235:6:235:41 | a9 | +| variables.rs:246:15:246:17 | a10 | variables.rs:242:13:242:15 | a10 | +| variables.rs:247:15:247:16 | b4 | variables.rs:243:13:243:14 | b4 | +| variables.rs:248:15:248:16 | c2 | variables.rs:244:13:244:14 | c2 | +| variables.rs:251:9:251:10 | c2 | variables.rs:244:13:244:14 | c2 | +| variables.rs:252:9:252:10 | b4 | variables.rs:243:13:243:14 | b4 | +| variables.rs:253:9:253:11 | a10 | variables.rs:242:13:242:15 | a10 | +| variables.rs:255:9:255:11 | a10 | variables.rs:242:13:242:15 | a10 | +| variables.rs:256:9:256:10 | b4 | variables.rs:243:13:243:14 | b4 | +| variables.rs:257:9:257:10 | c2 | variables.rs:244:13:244:14 | c2 | +| variables.rs:259:15:259:17 | a10 | variables.rs:242:13:242:15 | a10 | +| variables.rs:260:15:260:16 | b4 | variables.rs:243:13:243:14 | b4 | +| variables.rs:261:15:261:16 | c2 | variables.rs:244:13:244:14 | c2 | +| variables.rs:268:23:268:25 | a10 | variables.rs:265:13:265:15 | a10 | +| variables.rs:269:23:269:24 | b4 | variables.rs:266:13:266:14 | b4 | +| variables.rs:273:15:273:17 | a10 | variables.rs:242:13:242:15 | a10 | +| variables.rs:274:15:274:16 | b4 | variables.rs:243:13:243:14 | b4 | +| variables.rs:280:9:280:9 | x | variables.rs:279:10:279:10 | x | +| variables.rs:282:9:282:23 | example_closure | variables.rs:278:9:278:23 | example_closure | +| variables.rs:283:15:283:16 | n1 | variables.rs:281:9:281:10 | n1 | +| variables.rs:288:9:288:9 | x | variables.rs:287:10:287:10 | x | +| variables.rs:290:9:290:26 | immutable_variable | variables.rs:286:9:286:26 | immutable_variable | +| variables.rs:291:15:291:16 | n2 | variables.rs:289:9:289:10 | n2 | +| variables.rs:298:12:298:12 | v | variables.rs:295:9:295:9 | v | +| variables.rs:299:19:299:22 | text | variables.rs:297:9:297:12 | text | diff --git a/rust/ql/test/library-tests/variables/variables.ql b/rust/ql/test/library-tests/variables/variables.ql new file mode 100644 index 000000000000..b96f6ceabcae --- /dev/null +++ b/rust/ql/test/library-tests/variables/variables.ql @@ -0,0 +1,41 @@ +import rust +import utils.InlineExpectationsTest + +query predicate variable(Variable v) { any() } + +query predicate variableAccess(VariableAccess va, Variable v) { v = va.getVariable() } + +module VariableAccessTest implements TestSig { + string getARelevantTag() { result = "access" } + + private predicate declAt(Variable v, string filepath, int line) { + v.getLocation().hasLocationInfo(filepath, _, _, line, _) + } + + private predicate commmentAt(string text, string filepath, int line) { + exists(Comment c | + c.getLocation().hasLocationInfo(filepath, line, _, _, _) and + c.getCommentText() = text + ) + } + + private predicate decl(Variable v, string value) { + exists(string filepath, int line | declAt(v, filepath, line) | + commmentAt(value, filepath, line) + or + not commmentAt(_, filepath, line) and + value = v.getName() + ) + } + + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(VariableAccess va | + location = va.getLocation() and + element = va.toString() and + tag = "access" and + decl(va.getVariable(), value) + ) + } +} + +import MakeTest diff --git a/rust/ql/test/library-tests/variables/variables.rs b/rust/ql/test/library-tests/variables/variables.rs new file mode 100644 index 000000000000..f9d3e89938c3 --- /dev/null +++ b/rust/ql/test/library-tests/variables/variables.rs @@ -0,0 +1,325 @@ +fn print_str(s: &str) { + println!("{}", s); +} + +fn print_i64(i: i64) { + println!("{}", i); +} + +fn immutable_variable() { + let x1 = "a"; // x1 + print_str(x1); // $ access=x1 +} + +fn mutable_variable() { + let mut x2 = 4; // x2 + print_i64(x2); // $ access=x2 + x2 = 5; // $ access=x2 + print_i64(x2); // $ access=x2 +} + +fn variable_shadow1() { + let x3 = 1; // x3_1 + print_i64(x3); // $ access=x3_1 + let x3 = // x3_2 + x3 + 1; // $ access=x3_1 + print_i64(x3); // $ access=x3_2 +} + +fn variable_shadow2() { + let x4 = "a"; // x4_1 + print_str(x4); // $ access=x4_1 + { + let x4 = "b"; // x4_2 + print_str(x4); // $ access=x4_2 + } + print_str(x4); // $ access=x4_1 +} + +struct Point<'a> { + x: &'a str, + y: &'a str, +} + +fn let_pattern1() { + let ( + ( + a1, // a1 + b1, // b1 + ), + Point { + x, // x + y, // y + }, + ) = (("a", "b"), Point { x: "x", y: "y" }); + print_str(a1); // $ access=a1 + print_str(b1); // $ access=b1 + print_str(x); // $ access=x + print_str(y); // $ access=y +} + +fn let_pattern2() { + let p1 = Point { x: "a", y: "b" }; // p1 + let Point { + x: a2, // a2 + y: b2, // b2 + } = p1; // $ access=p1 + print_str(a2); // $ access=a2 + print_str(b2); // $ access=b2 +} + +fn let_pattern3() { + let s1 = Some(String::from("Hello!")); // s1 + + if let Some(ref s2) // s2 + = s1 { // $ access=s1 + print_str(s2); // $ access=s2 + } +} + +fn let_pattern4() { + let Some(x5): Option<&str> = Some("x5") else { + // x5 + todo!() + }; + print_str(x5); // $ access=x5 +} + +fn match_pattern1() { + let x6 = Some(5); // x6 + let y1 = 10; // y1_1 + + match x6 { // $ access=x6 + Some(50) => print_str("Got 50"), + Some(y1) // y1_2 + => + { + print_i64(y1)// $ access=y1_2 + } + None => print_str("NONE"), + } + + print_i64(y1); // $ access=y1_1 +} + +fn match_pattern2() { + let numbers = (2, 4, 8, 16, 32); // numbers + + match numbers { // $ access=numbers + ( + first, _, // first + third, _, // third + fifth // fifth + ) => { + print_i64(first); // $ access=first + print_i64(third); // $ access=third + print_i64(fifth); // $ access=fifth + } + } + + match numbers { // $ access=numbers + ( + first, // first + .., + last // last + ) => { + print_i64(first); // $ access=first + print_i64(last); // $ access=last + } + } +} + +fn match_pattern3() { + let p2 = Point { x: "x", y: "y" }; // p2 + + match p2 { // $ access=p2 + Point { + x: x7, .. // x7 + } => print_str(x7), // $ access=x7 + } +} + +enum Message { + Hello { id: i64 }, +} + +fn match_pattern4() { + let msg = Message::Hello { id: 0 }; // msg + + match msg { // $ access=msg + Message::Hello { + id: id_variable @ 3..=7, // id_variable + } => print_i64(id_variable), // $ access=id_variable + Message::Hello { id: 10..=12 } => { + println!("Found an id in another range") + } + Message::Hello { id } => // id + print_i64(id), // $ access=id + } +} + +enum Either { + Left(i64), + Right(i64), +} + +fn match_pattern5() { + let either = Either::Left(32); // either + match either { // $ access=either + Either::Left(a3) | Either::Right(a3) // a3 + => print_i64(a3), // $ access=a3 + } +} + +enum ThreeValued { + First(i64), + Second(i64), + Third(i64), +} + +fn match_pattern6() { + let tv = ThreeValued::Second(62); // tv + match tv { // $ access=tv + ThreeValued::First(a4) | ThreeValued::Second(a4) | ThreeValued::Third(a4) // a4 + => print_i64(a4), // $ access=a4 + } + match tv { // $ access=tv + (ThreeValued::First(a5) | ThreeValued::Second(a5)) | ThreeValued::Third(a5) // a5 + => print_i64(a5), // $ access=a5 + } + match tv { // $ access=tv + ThreeValued::First(a6) | (ThreeValued::Second(a6) | ThreeValued::Third(a6)) // a6 + => print_i64(a6), // $ access=a6 + } +} + +fn match_pattern7() { + let either = Either::Left(32); // either + match either { // $ access=either + Either::Left(a7) | Either::Right(a7) // a7 + if a7 > 0 // $ access=a7 + => print_i64(a7), // $ access=a7 + _ => (), + } +} + +fn match_pattern8() { + let either = Either::Left(32); // either + + match either { // $ access=either + ref e @ // e + (Either::Left(a11) | Either::Right(a11)) // a11 + => { + print_i64(a11); // $ access=a11 + if let Either::Left(a12) // a12 + = e { // $ access=e + print_i64(*a12); // $ access=a12 + } + } + _ => (), + } +} + +fn param_pattern1( + a8: &str, // a8 + ( + b3, // b3 + c1, // c1 + ): (&str, &str)) -> () { + print_str(a8); // $ access=a8 + print_str(b3); // $ access=b3 + print_str(c1); // $ access=c1 +} + +fn param_pattern2( + (Either::Left(a9) | Either::Right(a9)): Either // a9 +) -> () { + print_i64(a9); // $ access=a9 +} + +fn destruct_assignment() { + let ( + mut a10, // a10 + mut b4, // b4 + mut c2 // c2 + ) = (1, 2, 3); + print_i64(a10); // $ access=a10 + print_i64(b4); // $ access=b4 + print_i64(c2); // $ access=c2 + + ( + c2, // $ access=c2 + b4, // $ access=b4 + a10 // $ access=a10 + ) = ( + a10, // $ access=a10 + b4, // $ access=b4 + c2 // $ access=c2 + ); + print_i64(a10); // $ access=a10 + print_i64(b4); // $ access=b4 + print_i64(c2); // $ access=c2 + + match (4, 5) { + ( + a10, // a10_2 + b4 // b4 + ) => { + print_i64(a10); // $ access=a10_2 + print_i64(b4); // $ access=b4 + } + } + + print_i64(a10); // $ access=a10 + print_i64(b4); // $ access=b4 +} + +fn closure_variable() { + let example_closure = // example_closure + |x: i64| // x_1 + x; // $ access=x_1 + let n1 = // n1 + example_closure(5); // $ access=example_closure + print_i64(n1); // $ access=n1 + + immutable_variable(); + let immutable_variable = + |x: i64| // x_2 + x; // $ access=x_2 + let n2 = // n2 + immutable_variable(6); // $ access=immutable_variable + print_i64(n2); // $ access=n2 +} + +fn for_variable() { + let v = &["apples", "cake", "coffee"]; // v + + for text // text + in v { // $ access=v + print_str(text); // $ access=text + } +} + +fn main() { + immutable_variable(); + mutable_variable(); + variable_shadow1(); + variable_shadow2(); + let_pattern1(); + let_pattern2(); + let_pattern3(); + let_pattern4(); + match_pattern1(); + match_pattern2(); + match_pattern3(); + match_pattern4(); + match_pattern5(); + match_pattern6(); + match_pattern7(); + match_pattern8(); + param_pattern1("a", ("b", "c")); + param_pattern2(Either::Left(45)); + destruct_assignment(); + closure_variable(); + for_variable(); +} From e0a3c8a1c4e3abd0eebf2dabc08c4e78a1117734 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 1 Oct 2024 10:12:39 +0200 Subject: [PATCH 071/347] Python: add change note --- .../ql/lib/change-notes/2024-10-01-comprehension-flow.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 python/ql/lib/change-notes/2024-10-01-comprehension-flow.md diff --git a/python/ql/lib/change-notes/2024-10-01-comprehension-flow.md b/python/ql/lib/change-notes/2024-10-01-comprehension-flow.md new file mode 100644 index 000000000000..5981251970c4 --- /dev/null +++ b/python/ql/lib/change-notes/2024-10-01-comprehension-flow.md @@ -0,0 +1,7 @@ +```yaml +--- +category: minorAnalysis +--- +* More precise modelling of the dataflow through comprehensions. In particular, captured variables are now handled correctly. +* Dataflow out of yield is added, allowing proper tracing through generators. +``` \ No newline at end of file From 60abea17e62bef99989fede63c15804217e3a9f3 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Mon, 16 Sep 2024 15:10:17 +0100 Subject: [PATCH 072/347] C++: Test for cpp/uninitialized-local --- .../semmle/tests/UninitializedLocal.expected | 4 ++++ .../Security/CWE/CWE-457/semmle/tests/errors.cpp | 15 +++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/errors.cpp diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected index a8b3c7782e7c..385105e6e19b 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected @@ -1,5 +1,7 @@ edges nodes +| errors.cpp:4:7:4:7 | definition of x | semmle.label | definition of x | +| errors.cpp:13:7:13:7 | definition of x | semmle.label | definition of x | | test.cpp:11:6:11:8 | definition of foo | semmle.label | definition of foo | | test.cpp:111:6:111:8 | definition of foo | semmle.label | definition of foo | | test.cpp:226:7:226:7 | definition of x | semmle.label | definition of x | @@ -14,6 +16,8 @@ nodes | test.cpp:472:6:472:6 | definition of x | semmle.label | definition of x | | test.cpp:479:6:479:6 | definition of x | semmle.label | definition of x | #select +| errors.cpp:6:10:6:10 | x | errors.cpp:4:7:4:7 | definition of x | errors.cpp:4:7:4:7 | definition of x | The variable $@ may not be initialized at this access. | errors.cpp:4:7:4:7 | x | x | +| errors.cpp:14:18:14:18 | x | errors.cpp:13:7:13:7 | definition of x | errors.cpp:13:7:13:7 | definition of x | The variable $@ may not be initialized at this access. | errors.cpp:13:7:13:7 | x | x | | test.cpp:12:6:12:8 | foo | test.cpp:11:6:11:8 | definition of foo | test.cpp:11:6:11:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:11:6:11:8 | foo | foo | | test.cpp:113:6:113:8 | foo | test.cpp:111:6:111:8 | definition of foo | test.cpp:111:6:111:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:111:6:111:8 | foo | foo | | test.cpp:227:3:227:3 | x | test.cpp:226:7:226:7 | definition of x | test.cpp:226:7:226:7 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:226:7:226:7 | x | x | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/errors.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/errors.cpp new file mode 100644 index 000000000000..07bb61f943ed --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/errors.cpp @@ -0,0 +1,15 @@ +// semmle-extractor-options: --expect_errors + +int f1() { + int x; + initialize(&x); // error expression - initialize() is not defined + return x; // GOOD - assume x is initialized +} + +void * operator new(unsigned long, bool); +void operator delete(void*, bool); + +int f2() { + int x; + new(true) int (x); // BAD, ignore implicit error expression +} From 62509a10c293d1fb9cbdf21837e6fe4e1e46b11c Mon Sep 17 00:00:00 2001 From: yoff Date: Tue, 1 Oct 2024 11:39:12 +0200 Subject: [PATCH 073/347] Update python/ql/test/library-tests/dataflow/coverage/test_builtins.py Co-authored-by: Rasmus Wriedt Larsen --- python/ql/test/library-tests/dataflow/coverage/test_builtins.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/ql/test/library-tests/dataflow/coverage/test_builtins.py b/python/ql/test/library-tests/dataflow/coverage/test_builtins.py index 2de6adeb20bf..29afa9bfdb25 100644 --- a/python/ql/test/library-tests/dataflow/coverage/test_builtins.py +++ b/python/ql/test/library-tests/dataflow/coverage/test_builtins.py @@ -142,6 +142,7 @@ def test_dict_from_dict(): SINK(d2["k"]) #$ flow="SOURCE, l:-2 -> d2['k']" SINK_F(d2["k1"]) +@expects(4) def test_dict_from_multiple_args(): d = dict([("k", SOURCE), ("k1", NONSOURCE)], k2 = SOURCE, k3 = NONSOURCE) SINK(d["k"]) #$ MISSING: flow="SOURCE, l:-1 -> d['k']" From d689db23d85433e6bd4814f210bd25151add8fbc Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 1 Oct 2024 10:43:28 +0100 Subject: [PATCH 074/347] Warn on use of old option --- go/extractor/configurebaseline/configurebaseline.go | 3 ++- go/extractor/extractor.go | 6 +++++- go/extractor/util/extractvendordirs.go | 7 ++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/go/extractor/configurebaseline/configurebaseline.go b/go/extractor/configurebaseline/configurebaseline.go index f8e2c998f8c1..04037d61425e 100644 --- a/go/extractor/configurebaseline/configurebaseline.go +++ b/go/extractor/configurebaseline/configurebaseline.go @@ -28,7 +28,8 @@ type BaselineConfig struct { func GetConfigBaselineAsJSON(rootDir string) ([]byte, error) { vendorDirs := make([]string, 0) - if util.IsVendorDirExtractionEnabled() { + extractVendorDirs, _ := util.IsVendorDirExtractionEnabled() + if extractVendorDirs { // The user wants vendor directories scanned; emit an empty report. } else { filepath.WalkDir(rootDir, func(dirPath string, d fs.DirEntry, err error) error { diff --git a/go/extractor/extractor.go b/go/extractor/extractor.go index 69aeeddc2a47..b1d476d10948 100644 --- a/go/extractor/extractor.go +++ b/go/extractor/extractor.go @@ -83,7 +83,11 @@ func ExtractWithFlags(buildFlags []string, patterns []string, extractTests bool) // If CODEQL_EXTRACTOR_GO_[OPTION_]EXTRACT_VENDOR_DIRS is "true", we extract `vendor` directories; // otherwise (the default) is to exclude them from extraction - includeVendor := util.IsVendorDirExtractionEnabled() + includeVendor, oldOptionUsed := util.IsVendorDirExtractionEnabled() + + if oldOptionUsed { + log.Println("Warning: obsolete option \"CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS\" was set. Use \"CODEQL_EXTRACTOR_GO_OPTION_EXTRACT_VENDOR_DIRS\" or pass `--extractor-option extract_vendor_dirs=true` instead.") + } modeNotifications := make([]string, 0, 2) if extractTests { diff --git a/go/extractor/util/extractvendordirs.go b/go/extractor/util/extractvendordirs.go index eadf5d24740e..adeb2461f892 100644 --- a/go/extractor/util/extractvendordirs.go +++ b/go/extractor/util/extractvendordirs.go @@ -4,7 +4,8 @@ import ( "os" ) -func IsVendorDirExtractionEnabled() bool { - return os.Getenv("CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS") == "true" || - os.Getenv("CODEQL_EXTRACTOR_GO_OPTION_EXTRACT_VENDOR_DIRS") == "true" +func IsVendorDirExtractionEnabled() (bool, bool) { + oldOptionVal := os.Getenv("CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS") + return (oldOptionVal == "true" || + os.Getenv("CODEQL_EXTRACTOR_GO_OPTION_EXTRACT_VENDOR_DIRS") == "true"), oldOptionVal != "" } From 2eac11edd604be61b40d392dd9a4a441be865e3b Mon Sep 17 00:00:00 2001 From: yoff Date: Tue, 1 Oct 2024 11:47:42 +0200 Subject: [PATCH 075/347] Update python/ql/lib/change-notes/2024-09-24-std-lib-models.md Co-authored-by: Rasmus Wriedt Larsen --- python/ql/lib/change-notes/2024-09-24-std-lib-models.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/change-notes/2024-09-24-std-lib-models.md b/python/ql/lib/change-notes/2024-09-24-std-lib-models.md index 20b522576a30..3166e0c8ff0f 100644 --- a/python/ql/lib/change-notes/2024-09-24-std-lib-models.md +++ b/python/ql/lib/change-notes/2024-09-24-std-lib-models.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* Added several models of standard library functions and classes. This should make the analysis much more complete in cases where the standard library is not extracted. \ No newline at end of file +* Added several models of standard library functions and classes, in anticipation of no longer extracting the standard library in a future release. \ No newline at end of file From 4b5aa1497ba86cdfb652d7b6a0c1eb40a9ed322d Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Tue, 1 Oct 2024 11:00:44 +0100 Subject: [PATCH 076/347] C++: Implement Function::hasErrors() --- cpp/ql/lib/semmle/code/cpp/Function.qll | 8 ++++++++ cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll | 7 +++++++ .../Likely Bugs/Memory Management/UninitializedLocal.ql | 3 ++- .../CWE/CWE-457/semmle/tests/UninitializedLocal.expected | 1 - 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/Function.qll b/cpp/ql/lib/semmle/code/cpp/Function.qll index 0648c6260ce5..1234791576b1 100644 --- a/cpp/ql/lib/semmle/code/cpp/Function.qll +++ b/cpp/ql/lib/semmle/code/cpp/Function.qll @@ -500,6 +500,14 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function { * Gets the nearest enclosing AccessHolder. */ override AccessHolder getEnclosingAccessHolder() { result = this.getDeclaringType() } + + /** + * Holds if this function has extraction errors that create an `ErrorExpr`. + */ + predicate hasErrors() { + // Exclude allocator call arguments because they are are always extracted as `ErrorExpr`. + exists(ErrorExpr e | e.getEnclosingFunction() = this and not e.isFirstAllocatorCallArgument()) + } } pragma[noinline] diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll index 91b57049a54e..7faef545c0e4 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll @@ -744,6 +744,13 @@ class ErrorExpr extends Expr, @errorexpr { override string toString() { result = "" } override string getAPrimaryQlClass() { result = "ErrorExpr" } + + /** + * Holds if this error expression is the first argument to a `new` allocation call. + */ + predicate isFirstAllocatorCallArgument() { + this = any(NewOrNewArrayExpr new).getAllocatorCall().getArgument(0) + } } /** diff --git a/cpp/ql/src/Likely Bugs/Memory Management/UninitializedLocal.ql b/cpp/ql/src/Likely Bugs/Memory Management/UninitializedLocal.ql index 35bee25c9f5f..226cbfd322b9 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/UninitializedLocal.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/UninitializedLocal.ql @@ -89,5 +89,6 @@ from where conf.hasFlowPath(source, sink) and isSinkImpl(sink.getInstruction(), va) and - v = va.getTarget() + v = va.getTarget() and + not v.getFunction().hasErrors() select va, source, sink, "The variable $@ may not be initialized at this access.", v, v.getName() diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected index 385105e6e19b..30896607a18d 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected @@ -16,7 +16,6 @@ nodes | test.cpp:472:6:472:6 | definition of x | semmle.label | definition of x | | test.cpp:479:6:479:6 | definition of x | semmle.label | definition of x | #select -| errors.cpp:6:10:6:10 | x | errors.cpp:4:7:4:7 | definition of x | errors.cpp:4:7:4:7 | definition of x | The variable $@ may not be initialized at this access. | errors.cpp:4:7:4:7 | x | x | | errors.cpp:14:18:14:18 | x | errors.cpp:13:7:13:7 | definition of x | errors.cpp:13:7:13:7 | definition of x | The variable $@ may not be initialized at this access. | errors.cpp:13:7:13:7 | x | x | | test.cpp:12:6:12:8 | foo | test.cpp:11:6:11:8 | definition of foo | test.cpp:11:6:11:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:11:6:11:8 | foo | foo | | test.cpp:113:6:113:8 | foo | test.cpp:111:6:111:8 | definition of foo | test.cpp:111:6:111:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:111:6:111:8 | foo | foo | From 59a77d70c0d90eb9e78f068bea92e594b41501d7 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Tue, 1 Oct 2024 11:01:23 +0100 Subject: [PATCH 077/347] C++: Use Function::hasErrors in queries --- cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.ql | 2 +- .../Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql | 2 +- .../Likely Bugs/Memory Management/UsingExpiredStackAddress.ql | 2 +- cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.ql b/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.ql index 1d02474bfbb7..f824ecf53e76 100644 --- a/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.ql +++ b/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.ql @@ -57,5 +57,5 @@ where not declarationHasSideEffects(v) and not exists(AsmStmt s | f = s.getEnclosingFunction()) and not v.getAnAttribute().getName() = "unused" and - not any(ErrorExpr e).getEnclosingFunction() = f // unextracted expr may use `v` + not f.hasErrors() select v, "Variable " + v.getName() + " is not used." diff --git a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql index 16679d67fd2e..02678beaf124 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql @@ -29,7 +29,7 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration { override predicate isSource(Instruction source) { exists(Function func | // Rule out FPs caused by extraction errors. - not any(ErrorExpr e).getEnclosingFunction() = func and + not func.hasErrors() and not intentionallyReturnsStackPointer(func) and func = source.getEnclosingFunction() | diff --git a/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql b/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql index 678cb95a7214..0df59b5f01db 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql @@ -24,7 +24,7 @@ predicate instructionHasVariable(VariableAddressInstruction vai, StackVariable v // Pointer-to-member types aren't properly handled in the dbscheme. not vai.getResultType() instanceof PointerToMemberType and // Rule out FPs caused by extraction errors. - not any(ErrorExpr e).getEnclosingFunction() = f + not f.hasErrors() } /** diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql index ac5db25ea6b5..9027c064ac67 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql @@ -49,7 +49,7 @@ predicate functionsMissingReturnStmt(Function f, ControlFlowNode blame) { predicate functionImperfectlyExtracted(Function f) { exists(CompilerError e | f.getBlock().getLocation().subsumes(e.getLocation())) or - exists(ErrorExpr ee | ee.getEnclosingFunction() = f) + f.hasErrors() or count(f.getType()) > 1 or From 4712ae1cfc5073be85a102753a540e573da54803 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Tue, 1 Oct 2024 11:01:51 +0100 Subject: [PATCH 078/347] C++: Use refactored isFirstAllocatorCallArgument() --- .../cpp/ir/implementation/raw/internal/TranslatedElement.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 0f9bc370f7a5..1047dc2b8a7b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -151,7 +151,7 @@ private predicate ignoreExprOnly(Expr expr) { // The extractor deliberately emits an `ErrorExpr` as the first argument to // the allocator call, if any, of a `NewOrNewArrayExpr`. That `ErrorExpr` // should not be translated. - exists(NewOrNewArrayExpr new | expr = new.getAllocatorCall().getArgument(0)) + expr.(ErrorExpr).isFirstAllocatorCallArgument() or not translateFunction(getEnclosingFunction(expr)) and not Raw::varHasIRFunc(getEnclosingVariable(expr)) From fe00c8819d373a5ab46ac6c7e6cc735f8665304d Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Tue, 1 Oct 2024 11:26:47 +0100 Subject: [PATCH 079/347] C++: Fix formatting --- cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll index 7faef545c0e4..4eaf83e2c03f 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll @@ -748,7 +748,7 @@ class ErrorExpr extends Expr, @errorexpr { /** * Holds if this error expression is the first argument to a `new` allocation call. */ - predicate isFirstAllocatorCallArgument() { + predicate isFirstAllocatorCallArgument() { this = any(NewOrNewArrayExpr new).getAllocatorCall().getArgument(0) } } From 2b6aab108d1721691e2bb265f2452182d2c4f8dc Mon Sep 17 00:00:00 2001 From: yoff Date: Tue, 1 Oct 2024 12:36:20 +0200 Subject: [PATCH 080/347] Update python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll Co-authored-by: Taus --- .../semmle/python/dataflow/new/internal/DataFlowDispatch.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index b1db806d343e..061687ad879c 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -1385,7 +1385,7 @@ private predicate sameEnclosingCallable(Node node1, Node node2) { // ============================================================================= newtype TDataFlowCall = TNormalCall(CallNode call, Function target, CallType type) { resolveCall(call, target, type) } or - /** A call to the generated function inside a comprhension */ + /** A call to the generated function inside a comprehension */ TComprehensionCall(Comp c) or TPotentialLibraryCall(CallNode call) or /** A synthesized call inside a summarized callable */ From 64890a1a6b426ef1b0f1caa8e5dd2d75b5154511 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 1 Oct 2024 12:37:45 +0200 Subject: [PATCH 081/347] Python: valid change note --- python/ql/lib/change-notes/2024-10-01-comprehension-flow.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/python/ql/lib/change-notes/2024-10-01-comprehension-flow.md b/python/ql/lib/change-notes/2024-10-01-comprehension-flow.md index 5981251970c4..bc3165f05f33 100644 --- a/python/ql/lib/change-notes/2024-10-01-comprehension-flow.md +++ b/python/ql/lib/change-notes/2024-10-01-comprehension-flow.md @@ -1,7 +1,5 @@ -```yaml --- category: minorAnalysis --- * More precise modelling of the dataflow through comprehensions. In particular, captured variables are now handled correctly. -* Dataflow out of yield is added, allowing proper tracing through generators. -``` \ No newline at end of file +* Dataflow out of yield is added, allowing proper tracing through generators. \ No newline at end of file From cef8744a3776fdff4e3f6566080a4d0e590b9b59 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 1 Oct 2024 12:56:21 +0200 Subject: [PATCH 082/347] Python: consolidate models in one file --- .../semmle/python/frameworks/Stdlib.model.yml | 154 ++++++++++++++++- .../python/frameworks/Stdlib/StdLib.model.yml | 161 ------------------ 2 files changed, 153 insertions(+), 162 deletions(-) delete mode 100644 python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml b/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml index 53d918d07ac3..946c4d5ed4f6 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml @@ -21,9 +21,161 @@ extensions: - ['argparse.ArgumentParser', 'Member[parse_args,parse_known_args].WithArity[0].ReturnValue', 'commandargs'] - ['os', 'Member[read].ReturnValue', 'file'] + + - addsTo: + pack: codeql/python-all + extensible: sinkModel + data: + - ["zipfile.ZipFile","Member[extractall].Argument[0,path:]", "path-injection"] + - addsTo: pack: codeql/python-all extensible: summaryModel data: - - ['argparse.ArgumentParser', 'Member[parse_args,parse_known_args]', 'Argument[0,args:]', 'ReturnValue', 'taint'] + # See https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser + - ["argparse.ArgumentParser", "Member[_parse_known_args,_read_args_from_files]", "Argument[0,arg_strings:]", "ReturnValue", "taint"] # note: taint of attribute lookups is handled in QL + - ["argparse.ArgumentParser", "Member[parse_args,parse_known_args]", "Argument[0,args:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/cgi.html#higher-level-interface + - ["cgi.FieldStorage", "Member[getfirst,getlist,getvalue]", "Argument[self]", "ReturnValue", "taint"] + # See + # - https://docs.python.org/3/glossary.html#term-mapping + # - https://docs.python.org/3/library/stdtypes.html#dict.get + - ["collections.abc.Mapping", "Member[get]", "Argument[1,default:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/contextlib.html#contextlib.ExitStack + - ["contextlib.ExitStack", "Member[enter_context]", "Argument[0,cm:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/copy.html#copy.deepcopy + - ["copy", "Member[copy,deepcopy]", "Argument[0,x:]", "ReturnValue", "value"] + # See + # - https://docs.python.org/3/library/ctypes.html#ctypes.create_string_buffer + # - https://docs.python.org/3/library/ctypes.html#ctypes.create_unicode_buffer + - ["ctypes", "Member[create_string_buffer,create_unicode_buffer]", "Argument[0,init:,init_or_size:]", "ReturnValue", "taint"] + # See https://docs.python.org/3.11/distutils/apiref.html#distutils.util.change_root + - ["distutils", "Member[util].Member[change_root]", "Argument[0,new_root:,1,pathname:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/email.header.html#email.header.Header + - ["email.header.Header!", "Subclass.Call", "Argument[0,s:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/email.utils.html#email.utils.parseaddr + - ["email", "Member[utils].Member[parseaddr]", "Argument[0,addr:]", "ReturnValue", "taint"] + - ["email", "Member[utils].Member[parseaddr]", "Argument[0,addr:]", "ReturnValue.TupleElement[0,1]", "taint"] + # See See https://docs.python.org/3/library/fnmatch.html#fnmatch.filter + - ["fnmatch", "Member[filter]", "Argument[0,names:].ListElement", "ReturnValue.ListElement", "value"] + - ["fnmatch", "Member[filter]", "Argument[0,names:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/getopt.html#getopt.getopt + - ["getopt", "Member[getopt]", "Argument[0,args:]", "ReturnValue.TupleElement[1]", "taint"] + - ["getopt", "Member[getopt]", "Argument[1,shortopts:,2,longopts:]", "ReturnValue.TupleElement[0].ListElement.TupleElement[0]", "taint"] + # See https://docs.python.org/3/library/gettext.html#gettext.gettext + - ["gettext", "Member[gettext]", "Argument[0,message:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/gzip.html#gzip.GzipFile + - ["gzip.GzipFile!", "Subclass.Call", "Argument[0,filename:]", "ReturnValue", "taint"] + # See + # - https://docs.python.org/3/library/html.html#html.escape + # - https://docs.python.org/3/library/html.html#html.unescape + - ["html", "Member[escape,unescape]", "Argument[0,s:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/html.parser.html#html.parser.HTMLParser.feed + - ["html.parser.HTMLParser", "Member[feed]", "Argument[0,data:]", "Argument[self]", "taint"] + # See https://docs.python.org/3.11/library/imp.html#imp.find_module + - ["imp", "Member[find_module]", "Argument[0,name:,1,path:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/logging.html#logging.getLevelName + # specifically the no matching case + - ["logging", "Member[getLevelName]", "Argument[0,level:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/logging.html#logging.LogRecord.getMessage + - ["logging.LogRecord", "Member[getMessage]", "Argument[self]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/mimetypes.html#mimetypes.guess_type + - ["mimetypes", "Member[guess_type]", "Argument[0,url:]", "ReturnValue", "taint"] + # See https://github.com/python/cpython/blob/main/Lib/nturl2path.py + # No user-facing documentation, unfortunately. + - ["nturl2path", "Member[pathname2url]", "Argument[0,p:]", "ReturnValue", "taint"] + - ["nturl2path", "Member[url2pathname]", "Argument[0,url:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/optparse.html#optparse.OptionParser.parse_args + - ["optparse.OptionParser", "Member[parse_args]", "Argument[0,args:,1,values:]", "ReturnValue.TupleElement[0,1]", "taint"] + # See https://github.com/python/cpython/blob/3.10/Lib/pathlib.py#L972-L973 + - ["pathlib.Path", ".Member[__enter__]", "Argument[self]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/os.html#os.PathLike.__fspath__ + - ["pathlib.PurePath", "Member[__fspath__]", "Argument[self]", "ReturnValue", "taint"] + # See + # - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.get + # - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.get_nowait + - ["queue.Queue", "Member[get,get_nowait]", "Argument[self].ListElement", "ReturnValue", "value"] + - ["queue.Queue", "Member[get,get_nowait]", "Argument[self]", "ReturnValue", "taint"] + # See + # - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.put + # - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.put_nowait + - ["queue.Queue", "Member[put,put_nowait]", "Argument[0,item:]", "Argument[self].ListElement", "value"] + - ["queue.Queue", "Member[put,put_nowait]", "Argument[0,item:]", "Argument[self]", "taint"] + # See + # - https://docs.python.org/3/library/random.html#random.choice + # - https://docs.python.org/3/library/random.html#module-random + - ["random", "Member[choice]", "Argument[0,seq:].ListElement", "ReturnValue", "value"] + - ["random", "Member[choice]", "Argument[0,seq:].SetElement", "ReturnValue", "value"] + - ["random", "Member[choice]", "Argument[0,seq:]", "ReturnValue", "taint"] + - ["random.Random", "Member[choice]", "Argument[0,seq:].ListElement", "ReturnValue", "value"] + - ["random.Random", "Member[choice]", "Argument[0,seq:].SetElement", "ReturnValue", "value"] + - ["random.Random", "Member[choice]", "Argument[0,seq:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/shlex.html#shlex.quote + - ["shlex", "Member[quote]", "Argument[0,s:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/shutil.html#shutil.rmtree + - ["shutil", "Member[rmtree]", "Argument[0,path:]", "Argument[2,onerror:,onexc:].Parameter[1]", "taint"] + # See https://docs.python.org/3/library/shutil.html#shutil.which + - ["shutil", "Member[which]", "Argument[0,cmd:,2,path:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/subprocess.html#subprocess.Popen + - ["subprocess.Popen!", "Subclass.Call", "Argument[0,args:]", "ReturnValue", "taint"] + # See + # - https://docs.python.org/3/library/tarfile.html#tarfile.open + # - https://docs.python.org/3/library/tarfile.html#tarfile.TarFile.open + - ["tarfile", "Member[open]", "Argument[0,name:,2,fileobj:]", "ReturnValue", "taint"] + - ["tarfile.TarFile", "Member[open]", "Argument[0,name:,2,fileobj:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/tempfile.html#tempfile.mkdtemp + - ["tempfile", "Member[mkdtemp]", "Argument[0,suffix:,1,prefix:,2,dir:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/tempfile.html#tempfile.mkstemp + - ["tempfile", "Member[mkstemp]", "Argument[0,suffix:,1,prefix:,2,dir:]", "ReturnValue.TupleElement[0,1]", "taint"] + # See https://docs.python.org/3/library/textwrap.html#textwrap.dedent + - ["textwrap", "Member[dedent]", "Argument[0,text:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/traceback.html#traceback.StackSummary.from_list + - ["traceback.StackSummary", "Member[from_list]", "Argument[0,a_list:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/typing.html#typing.cast + - ["typing", "Member[cast]", "Argument[1,val:]", "ReturnValue", "value"] + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote + - ["urllib", "Member[parse].Member[quote]", "Argument[0,string:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote_plus + - ["urllib", "Member[parse].Member[quote_plus]", "Argument[0,string:]", "ReturnValue", "taint"] + # See https://epydoc.sourceforge.net/stdlib/urllib-module.html + - ["urllib", "Member[parse].Member[splitquery]", "Argument[0,url:]", "ReturnValue.TupleElement[0,1]", "taint"] + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.unquote + - ["urllib", "Member[parse].Member[unquote]", "Argument[0,string:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.unquote_plus + - ["urllib", "Member[parse].Member[unquote_plus]", "Argument[0,string:]", "ReturnValue", "taint"] + # We could consider a more precise source than the first argument, namely tuple or dict content. + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode + - ["urllib", "Member[parse].Member[urlencode]", "Argument[0,query:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urljoin + - ["urllib", "Member[parse].Member[urljoin]", "Argument[0,base:,1,url:]", "ReturnValue", "taint"] + # See the internal documentation + # https://github.com/python/cpython/blob/3.12/Lib/zipfile/_path/__init__.py#L103-L105 + - ["zipfile.CompleteDirs", "Member[namelist]", "Argument[self]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile + # it may be necessary to read the code to understand the taint propagation + # Constructor: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1266 + - ["zipfile.ZipFile!", "Subclass.Call", "Argument[0,file:]", "ReturnValue", "taint"] + - ["zipfile.ZipFile!", "Subclass.Call", "Argument[0,file:]", "ReturnValue.Attribute[filelist].ListElement.Attribute[filename]", "value"] + # _extract_member: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1761 + - ["zipfile.ZipFile", "Member[_extract_member]", "Argument[1,targetpath:]", "ReturnValue", "taint"] + # infolist: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1498-L1501 + - ["zipfile.ZipFile", "Member[infolist]", "Argument[self]", "ReturnValue", "taint"] + - ["zipfile.ZipFile", "Member[infolist]", "Argument[self].Attribute[filelist]", "ReturnValue", "value"] + # namelist: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1494-L1496 + - ["zipfile.ZipFile", "Member[namelist]", "Argument[self]", "ReturnValue", "taint"] + + - addsTo: + pack: codeql/python-all + extensible: neutralModel + data: [] + + - addsTo: + pack: codeql/python-all + extensible: typeModel + data: [] + + - addsTo: + pack: codeql/python-all + extensible: typeVariableModel + data: [] \ No newline at end of file diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml b/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml deleted file mode 100644 index 19a97b16537e..000000000000 --- a/python/ql/lib/semmle/python/frameworks/Stdlib/StdLib.model.yml +++ /dev/null @@ -1,161 +0,0 @@ -extensions: - - addsTo: - pack: codeql/python-all - extensible: sourceModel - data: [] - - - addsTo: - pack: codeql/python-all - extensible: sinkModel - data: - - ["zipfile.ZipFile","Member[extractall].Argument[0,path:]", "path-injection"] - - - addsTo: - pack: codeql/python-all - extensible: summaryModel - data: - # See - # - https://docs.python.org/3/glossary.html#term-mapping - # - https://docs.python.org/3/library/stdtypes.html#dict.get - - ["collections.abc.Mapping", "Member[get]", "Argument[1,default:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser - - ["argparse.ArgumentParser", "Member[_parse_known_args,_read_args_from_files]", "Argument[0,arg_strings:]", "ReturnValue", "taint"] - - ["argparse.ArgumentParser", "Member[parse_args,parse_known_args]", "Argument[0,args:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/cgi.html#higher-level-interface - - ["cgi.FieldStorage", "Member[getfirst,getlist,getvalue]", "Argument[self]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/contextlib.html#contextlib.ExitStack - - ["contextlib.ExitStack", "Member[enter_context]", "Argument[0,cm:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/copy.html#copy.deepcopy - - ["copy", "Member[copy,deepcopy]", "Argument[0,x:]", "ReturnValue", "value"] - # See - # - https://docs.python.org/3/library/ctypes.html#ctypes.create_string_buffer - # - https://docs.python.org/3/library/ctypes.html#ctypes.create_unicode_buffer - - ["ctypes", "Member[create_string_buffer,create_unicode_buffer]", "Argument[0,init:,init_or_size:]", "ReturnValue", "taint"] - # See https://docs.python.org/3.11/distutils/apiref.html#distutils.util.change_root - - ["distutils", "Member[util].Member[change_root]", "Argument[0,new_root:,1,pathname:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/email.header.html#email.header.Header - - ["email.header.Header!", "Subclass.Call", "Argument[0,s:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/email.utils.html#email.utils.parseaddr - - ["email", "Member[utils].Member[parseaddr]", "Argument[0,addr:]", "ReturnValue", "taint"] - - ["email", "Member[utils].Member[parseaddr]", "Argument[0,addr:]", "ReturnValue.TupleElement[0,1]", "taint"] - # See See https://docs.python.org/3/library/fnmatch.html#fnmatch.filter - - ["fnmatch", "Member[filter]", "Argument[0,names:].ListElement", "ReturnValue.ListElement", "value"] - - ["fnmatch", "Member[filter]", "Argument[0,names:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/getopt.html#getopt.getopt - - ["getopt", "Member[getopt]", "Argument[0,args:]", "ReturnValue.TupleElement[1]", "taint"] - - ["getopt", "Member[getopt]", "Argument[1,shortopts:,2,longopts:]", "ReturnValue.TupleElement[0].ListElement.TupleElement[0]", "taint"] - # See https://docs.python.org/3/library/gettext.html#gettext.gettext - - ["gettext", "Member[gettext]", "Argument[0,message:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/gzip.html#gzip.GzipFile - - ["gzip.GzipFile!", "Subclass.Call", "Argument[0,filename:]", "ReturnValue", "taint"] - # See - # - https://docs.python.org/3/library/html.html#html.escape - # - https://docs.python.org/3/library/html.html#html.unescape - - ["html", "Member[escape,unescape]", "Argument[0,s:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/html.parser.html#html.parser.HTMLParser.feed - - ["html.parser.HTMLParser", "Member[feed]", "Argument[0,data:]", "Argument[self]", "taint"] - # See https://docs.python.org/3.11/library/imp.html#imp.find_module - - ["imp", "Member[find_module]", "Argument[0,name:,1,path:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/logging.html#logging.getLevelName - # specifically the no matching case - - ["logging", "Member[getLevelName]", "Argument[0,level:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/logging.html#logging.LogRecord.getMessage - - ["logging.LogRecord", "Member[getMessage]", "Argument[self]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/mimetypes.html#mimetypes.guess_type - - ["mimetypes", "Member[guess_type]", "Argument[0,url:]", "ReturnValue", "taint"] - # See https://github.com/python/cpython/blob/main/Lib/nturl2path.py - # No user-facing documentation, unfortunately. - - ["nturl2path", "Member[pathname2url]", "Argument[0,p:]", "ReturnValue", "taint"] - - ["nturl2path", "Member[url2pathname]", "Argument[0,url:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/optparse.html#optparse.OptionParser.parse_args - - ["optparse.OptionParser", "Member[parse_args]", "Argument[0,args:,1,values:]", "ReturnValue.TupleElement[0,1]", "taint"] - # See https://github.com/python/cpython/blob/3.10/Lib/pathlib.py#L972-L973 - - ["pathlib.Path", ".Member[__enter__]", "Argument[self]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/os.html#os.PathLike.__fspath__ - - ["pathlib.PurePath", "Member[__fspath__]", "Argument[self]", "ReturnValue", "taint"] - # See - # - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.get - # - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.get_nowait - - ["queue.Queue", "Member[get,get_nowait]", "Argument[self].ListElement", "ReturnValue", "value"] - - ["queue.Queue", "Member[get,get_nowait]", "Argument[self]", "ReturnValue", "taint"] - # See - # - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.put - # - https://docs.python.org/3/library/asyncio-queue.html#asyncio.Queue.put_nowait - - ["queue.Queue", "Member[put,put_nowait]", "Argument[0,item:]", "Argument[self].ListElement", "value"] - - ["queue.Queue", "Member[put,put_nowait]", "Argument[0,item:]", "Argument[self]", "taint"] - # See - # - https://docs.python.org/3/library/random.html#random.choice - # - https://docs.python.org/3/library/random.html#module-random - - ["random", "Member[choice]", "Argument[0,seq:].ListElement", "ReturnValue", "value"] - - ["random", "Member[choice]", "Argument[0,seq:].SetElement", "ReturnValue", "value"] - - ["random", "Member[choice]", "Argument[0,seq:]", "ReturnValue", "taint"] - - ["random.Random", "Member[choice]", "Argument[0,seq:].ListElement", "ReturnValue", "value"] - - ["random.Random", "Member[choice]", "Argument[0,seq:].SetElement", "ReturnValue", "value"] - - ["random.Random", "Member[choice]", "Argument[0,seq:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/shlex.html#shlex.quote - - ["shlex", "Member[quote]", "Argument[0,s:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/shutil.html#shutil.rmtree - - ["shutil", "Member[rmtree]", "Argument[0,path:]", "Argument[2,onerror:,onexc:].Parameter[1]", "taint"] - # See https://docs.python.org/3/library/shutil.html#shutil.which - - ["shutil", "Member[which]", "Argument[0,cmd:,2,path:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/subprocess.html#subprocess.Popen - - ["subprocess.Popen!", "Subclass.Call", "Argument[0,args:]", "ReturnValue", "taint"] - # See - # - https://docs.python.org/3/library/tarfile.html#tarfile.open - # - https://docs.python.org/3/library/tarfile.html#tarfile.TarFile.open - - ["tarfile", "Member[open]", "Argument[0,name:,2,fileobj:]", "ReturnValue", "taint"] - - ["tarfile.TarFile", "Member[open]", "Argument[0,name:,2,fileobj:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/tempfile.html#tempfile.mkdtemp - - ["tempfile", "Member[mkdtemp]", "Argument[0,suffix:,1,prefix:,2,dir:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/tempfile.html#tempfile.mkstemp - - ["tempfile", "Member[mkstemp]", "Argument[0,suffix:,1,prefix:,2,dir:]", "ReturnValue.TupleElement[0,1]", "taint"] - # See https://docs.python.org/3/library/textwrap.html#textwrap.dedent - - ["textwrap", "Member[dedent]", "Argument[0,text:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/traceback.html#traceback.StackSummary.from_list - - ["traceback.StackSummary", "Member[from_list]", "Argument[0,a_list:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/typing.html#typing.cast - - ["typing", "Member[cast]", "Argument[1,val:]", "ReturnValue", "value"] - # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote - - ["urllib", "Member[parse].Member[quote]", "Argument[0,string:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote_plus - - ["urllib", "Member[parse].Member[quote_plus]", "Argument[0,string:]", "ReturnValue", "taint"] - # See https://epydoc.sourceforge.net/stdlib/urllib-module.html - - ["urllib", "Member[parse].Member[splitquery]", "Argument[0,url:]", "ReturnValue.TupleElement[0,1]", "taint"] - # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.unquote - - ["urllib", "Member[parse].Member[unquote]", "Argument[0,string:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.unquote_plus - - ["urllib", "Member[parse].Member[unquote_plus]", "Argument[0,string:]", "ReturnValue", "taint"] - # We could consider a more precise source than the first argument, namely tuple or dict content. - # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode - - ["urllib", "Member[parse].Member[urlencode]", "Argument[0,query:]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urljoin - - ["urllib", "Member[parse].Member[urljoin]", "Argument[0,base:,1,url:]", "ReturnValue", "taint"] - # See the internal documentation - # https://github.com/python/cpython/blob/3.12/Lib/zipfile/_path/__init__.py#L103-L105 - - ["zipfile.CompleteDirs", "Member[namelist]", "Argument[self]", "ReturnValue", "taint"] - # See https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile - # it may be necessary to read the code to understand the taint propagation - # Constructor: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1266 - - ["zipfile.ZipFile!", "Subclass.Call", "Argument[0,file:]", "ReturnValue", "taint"] - - ["zipfile.ZipFile!", "Subclass.Call", "Argument[0,file:]", "ReturnValue.Attribute[filelist].ListElement.Attribute[filename]", "value"] - # _extract_member: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1761 - - ["zipfile.ZipFile", "Member[_extract_member]", "Argument[1,targetpath:]", "ReturnValue", "taint"] - # infolist: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1498-L1501 - - ["zipfile.ZipFile", "Member[infolist]", "Argument[self]", "ReturnValue", "taint"] - - ["zipfile.ZipFile", "Member[infolist]", "Argument[self].Attribute[filelist]", "ReturnValue", "value"] - # namelist: https://github.com/python/cpython/blob/3.12/Lib/zipfile/__init__.py#L1494-L1496 - - ["zipfile.ZipFile", "Member[namelist]", "Argument[self]", "ReturnValue", "taint"] - - addsTo: - pack: codeql/python-all - extensible: neutralModel - data: [] - - - addsTo: - pack: codeql/python-all - extensible: typeModel - data: [] - - - addsTo: - pack: codeql/python-all - extensible: typeVariableModel - data: [] From 05910de8d1321cb523cfb29be365756a6961f129 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 1 Oct 2024 13:21:22 +0200 Subject: [PATCH 083/347] Python: MaD expectations --- .../CWE-022-UnsafeUnpacking/UnsafeUnpack.expected | 2 +- .../Security/CWE-409/DecompressionBombs.expected | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected index 0c6c30857220..38d8719bfd0a 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected @@ -75,7 +75,7 @@ edges | UnsafeUnpack.py:161:19:161:21 | ControlFlowNode for tar | UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | provenance | | | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | UnsafeUnpack.py:161:19:161:21 | ControlFlowNode for tar | provenance | | | UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | provenance | Config | -| UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | provenance | MaD:54 | +| UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | provenance | MaD:67 | | UnsafeUnpack.py:163:23:163:28 | ControlFlowNode for member | UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | provenance | | | UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | UnsafeUnpack.py:163:23:163:28 | ControlFlowNode for member | provenance | | | UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result | UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | provenance | | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected index 073533bcc092..2b16f9ef178f 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected @@ -1,23 +1,23 @@ edges | test.py:10:16:10:24 | ControlFlowNode for file_path | test.py:11:21:11:29 | ControlFlowNode for file_path | provenance | | | test.py:11:5:11:35 | ControlFlowNode for Attribute() | test.py:11:5:11:52 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:35 | ControlFlowNode for Attribute() | provenance | MaD:69 | +| test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:35 | ControlFlowNode for Attribute() | provenance | MaD:82 | | test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:52 | ControlFlowNode for Attribute() | provenance | Config | | test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:12:21:12:29 | ControlFlowNode for file_path | provenance | | | test.py:12:5:12:35 | ControlFlowNode for Attribute() | test.py:12:5:12:48 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:35 | ControlFlowNode for Attribute() | provenance | MaD:69 | +| test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:35 | ControlFlowNode for Attribute() | provenance | MaD:82 | | test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:48 | ControlFlowNode for Attribute() | provenance | Config | | test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:14:26:14:34 | ControlFlowNode for file_path | provenance | | | test.py:14:10:14:35 | ControlFlowNode for Attribute() | test.py:15:14:15:29 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:14:10:14:35 | ControlFlowNode for Attribute() | provenance | MaD:69 | +| test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:14:10:14:35 | ControlFlowNode for Attribute() | provenance | MaD:82 | | test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:15:14:15:29 | ControlFlowNode for Attribute() | provenance | Config | | test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:18:26:18:34 | ControlFlowNode for file_path | provenance | | | test.py:18:10:18:35 | ControlFlowNode for Attribute() | test.py:19:14:19:39 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:18:10:18:35 | ControlFlowNode for Attribute() | provenance | MaD:69 | +| test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:18:10:18:35 | ControlFlowNode for Attribute() | provenance | MaD:82 | | test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:19:14:19:39 | ControlFlowNode for Attribute() | provenance | Config | | test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:22:21:22:29 | ControlFlowNode for file_path | provenance | | | test.py:22:5:22:30 | ControlFlowNode for Attribute() | test.py:22:5:22:60 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:30 | ControlFlowNode for Attribute() | provenance | MaD:69 | +| test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:30 | ControlFlowNode for Attribute() | provenance | MaD:82 | | test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:60 | ControlFlowNode for Attribute() | provenance | Config | | test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:24:18:24:26 | ControlFlowNode for file_path | provenance | | | test.py:24:18:24:26 | ControlFlowNode for file_path | test.py:24:5:24:52 | ControlFlowNode for Attribute() | provenance | Config | From a172063e6a88c7841c4df65eed23e69494b04e53 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Oct 2024 13:37:56 +0200 Subject: [PATCH 084/347] Rust: Document `VariableOrAccessCand` --- .../rust/elements/internal/VariableImpl.qll | 47 +++++++++++++++++++ .../internal/InlineExpectationsTestImpl.qll | 3 -- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index 9ddf1d9755a1..58c9a4fb6ebf 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -231,6 +231,53 @@ module Impl { TVariableOrAccessCandVariable(Variable v) or TVariableOrAccessCandVariableAccessCand(VariableAccessCand va) + /** + * A variable declaration or variable access candidate. + * + * In order to determine whether a candidate is an actual variable access, + * we rank declarations and candidates by their position in source code. + * + * The ranking must take variable names into account, but also variable scopes; + * below a comment `rank(scope, name, i)` means that the declaration/access on + * the given line has rank `i` amongst all declarations/accesses inside variable + * scope `scope`, for variable name `name`: + * + * ```rust + * fn f() { // scope0 + * let x = 0; // rank(scope0, "x", 0) + * use(x); // rank(scope0, "x", 1) + * let x = // rank(scope0, "x", 3) + * x + 1; // rank(scope0, "x", 2) + * let y = // rank(scope0, "y", 0) + * x; // rank(scope0, "x", 4) + * + * { // scope1 + * use(x); // rank(scope1, "x", 0), rank(scope0, "x", 4) + * use(y); // rank(scope1, "y", 0), rank(scope0, "y", 1) + * let x = 2; // rank(scope1, "x", 1) + * use(x); // rank(scope1, "x", 2), rank(scope0, "x", 4) + * } + * } + * ``` + * + * Variable declarations are only ranked in the scope that they bind into, while + * accesses candidates propagate outwards through scopes, as they may access + * declarations from outer scopes. + * + * For an access candidate with ranks `{ rank(scope_i, name, rnk_i) | i in I }` and + * declarations `d in D` with ranks `rnk(scope_d, name, rnk_d)`, the target is + * calculated as + * ``` + * max_{i in I} ( + * max_{d in D | scope_d = scope_i and rnk_d < rnk_i} ( + * d + * ) + * ) + * ``` + * + * i.e., its the nearest declaration before the access in the same (or outer) scope + * as the access. + */ private class VariableOrAccessCand extends TVariableOrAccessCand { Variable asVariable() { this = TVariableOrAccessCandVariable(result) } diff --git a/rust/ql/test/utils/internal/InlineExpectationsTestImpl.qll b/rust/ql/test/utils/internal/InlineExpectationsTestImpl.qll index 74b8a39431de..2e851f529512 100644 --- a/rust/ql/test/utils/internal/InlineExpectationsTestImpl.qll +++ b/rust/ql/test/utils/internal/InlineExpectationsTestImpl.qll @@ -3,9 +3,6 @@ private import R private import codeql.util.test.InlineExpectationsTest module Impl implements InlineExpectationsTestSig { - /** - * A class representing line comments in C# used by the InlineExpectations core code - */ class ExpectationComment extends R::Comment { /** Gets the contents of the given comment, _without_ the preceding comment marker (`//`). */ string getContents() { result = this.getCommentText() } From 91e26d0f4473626cdea80840f55717252cc4aaab Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Oct 2024 13:45:58 +0200 Subject: [PATCH 085/347] Rust: Add another variable test --- .../CONSISTENCY/CfgConsistency.expected | 2 +- .../variables/variables.expected | 94 ++++++++++--------- .../test/library-tests/variables/variables.rs | 16 ++++ 3 files changed, 66 insertions(+), 46 deletions(-) diff --git a/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected index 56ae06526e76..5457cb7c9d96 100644 --- a/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected +++ b/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected @@ -2,4 +2,4 @@ deadEnd | variables.rs:2:5:2:22 | ExprStmt | | variables.rs:6:5:6:22 | ExprStmt | | variables.rs:200:16:200:21 | ... > ... | -| variables.rs:295:5:295:42 | LetStmt | +| variables.rs:310:5:310:42 | LetStmt | diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index 18ee16a3da9c..ba563aeab6ef 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -46,23 +46,25 @@ variable | variables.rs:210:13:210:13 | e | | variables.rs:211:14:211:51 | a11 | | variables.rs:214:33:214:35 | a12 | -| variables.rs:224:5:224:6 | a8 | -| variables.rs:226:9:226:10 | b3 | -| variables.rs:227:9:227:10 | c1 | -| variables.rs:235:6:235:41 | a9 | -| variables.rs:242:13:242:15 | a10 | -| variables.rs:243:13:243:14 | b4 | -| variables.rs:244:13:244:14 | c2 | -| variables.rs:265:13:265:15 | a10 | -| variables.rs:266:13:266:14 | b4 | -| variables.rs:278:9:278:23 | example_closure | -| variables.rs:279:10:279:10 | x | -| variables.rs:281:9:281:10 | n1 | -| variables.rs:286:9:286:26 | immutable_variable | -| variables.rs:287:10:287:10 | x | -| variables.rs:289:9:289:10 | n2 | -| variables.rs:295:9:295:9 | v | -| variables.rs:297:9:297:12 | text | +| variables.rs:231:9:231:10 | fv | +| variables.rs:233:9:233:109 | a13 | +| variables.rs:239:5:239:6 | a8 | +| variables.rs:241:9:241:10 | b3 | +| variables.rs:242:9:242:10 | c1 | +| variables.rs:250:6:250:41 | a9 | +| variables.rs:257:13:257:15 | a10 | +| variables.rs:258:13:258:14 | b4 | +| variables.rs:259:13:259:14 | c2 | +| variables.rs:280:13:280:15 | a10 | +| variables.rs:281:13:281:14 | b4 | +| variables.rs:293:9:293:23 | example_closure | +| variables.rs:294:10:294:10 | x | +| variables.rs:296:9:296:10 | n1 | +| variables.rs:301:9:301:26 | immutable_variable | +| variables.rs:302:10:302:10 | x | +| variables.rs:304:9:304:10 | n2 | +| variables.rs:310:9:310:9 | v | +| variables.rs:312:9:312:12 | text | variableAccess | variables.rs:11:15:11:16 | x1 | variables.rs:10:9:10:10 | x1 | | variables.rs:16:15:16:16 | x2 | variables.rs:15:13:15:14 | x2 | @@ -114,31 +116,33 @@ variableAccess | variables.rs:213:23:213:25 | a11 | variables.rs:211:14:211:51 | a11 | | variables.rs:215:15:215:15 | e | variables.rs:210:13:210:13 | e | | variables.rs:216:28:216:30 | a12 | variables.rs:214:33:214:35 | a12 | -| variables.rs:229:15:229:16 | a8 | variables.rs:224:5:224:6 | a8 | -| variables.rs:230:15:230:16 | b3 | variables.rs:226:9:226:10 | b3 | -| variables.rs:231:15:231:16 | c1 | variables.rs:227:9:227:10 | c1 | -| variables.rs:237:15:237:16 | a9 | variables.rs:235:6:235:41 | a9 | -| variables.rs:246:15:246:17 | a10 | variables.rs:242:13:242:15 | a10 | -| variables.rs:247:15:247:16 | b4 | variables.rs:243:13:243:14 | b4 | -| variables.rs:248:15:248:16 | c2 | variables.rs:244:13:244:14 | c2 | -| variables.rs:251:9:251:10 | c2 | variables.rs:244:13:244:14 | c2 | -| variables.rs:252:9:252:10 | b4 | variables.rs:243:13:243:14 | b4 | -| variables.rs:253:9:253:11 | a10 | variables.rs:242:13:242:15 | a10 | -| variables.rs:255:9:255:11 | a10 | variables.rs:242:13:242:15 | a10 | -| variables.rs:256:9:256:10 | b4 | variables.rs:243:13:243:14 | b4 | -| variables.rs:257:9:257:10 | c2 | variables.rs:244:13:244:14 | c2 | -| variables.rs:259:15:259:17 | a10 | variables.rs:242:13:242:15 | a10 | -| variables.rs:260:15:260:16 | b4 | variables.rs:243:13:243:14 | b4 | -| variables.rs:261:15:261:16 | c2 | variables.rs:244:13:244:14 | c2 | -| variables.rs:268:23:268:25 | a10 | variables.rs:265:13:265:15 | a10 | -| variables.rs:269:23:269:24 | b4 | variables.rs:266:13:266:14 | b4 | -| variables.rs:273:15:273:17 | a10 | variables.rs:242:13:242:15 | a10 | -| variables.rs:274:15:274:16 | b4 | variables.rs:243:13:243:14 | b4 | -| variables.rs:280:9:280:9 | x | variables.rs:279:10:279:10 | x | -| variables.rs:282:9:282:23 | example_closure | variables.rs:278:9:278:23 | example_closure | -| variables.rs:283:15:283:16 | n1 | variables.rs:281:9:281:10 | n1 | -| variables.rs:288:9:288:9 | x | variables.rs:287:10:287:10 | x | -| variables.rs:290:9:290:26 | immutable_variable | variables.rs:286:9:286:26 | immutable_variable | -| variables.rs:291:15:291:16 | n2 | variables.rs:289:9:289:10 | n2 | -| variables.rs:298:12:298:12 | v | variables.rs:295:9:295:9 | v | -| variables.rs:299:19:299:22 | text | variables.rs:297:9:297:12 | text | +| variables.rs:232:11:232:12 | fv | variables.rs:231:9:231:10 | fv | +| variables.rs:234:26:234:28 | a13 | variables.rs:233:9:233:109 | a13 | +| variables.rs:244:15:244:16 | a8 | variables.rs:239:5:239:6 | a8 | +| variables.rs:245:15:245:16 | b3 | variables.rs:241:9:241:10 | b3 | +| variables.rs:246:15:246:16 | c1 | variables.rs:242:9:242:10 | c1 | +| variables.rs:252:15:252:16 | a9 | variables.rs:250:6:250:41 | a9 | +| variables.rs:261:15:261:17 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:262:15:262:16 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:263:15:263:16 | c2 | variables.rs:259:13:259:14 | c2 | +| variables.rs:266:9:266:10 | c2 | variables.rs:259:13:259:14 | c2 | +| variables.rs:267:9:267:10 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:268:9:268:11 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:270:9:270:11 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:271:9:271:10 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:272:9:272:10 | c2 | variables.rs:259:13:259:14 | c2 | +| variables.rs:274:15:274:17 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:275:15:275:16 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:276:15:276:16 | c2 | variables.rs:259:13:259:14 | c2 | +| variables.rs:283:23:283:25 | a10 | variables.rs:280:13:280:15 | a10 | +| variables.rs:284:23:284:24 | b4 | variables.rs:281:13:281:14 | b4 | +| variables.rs:288:15:288:17 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:289:15:289:16 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:295:9:295:9 | x | variables.rs:294:10:294:10 | x | +| variables.rs:297:9:297:23 | example_closure | variables.rs:293:9:293:23 | example_closure | +| variables.rs:298:15:298:16 | n1 | variables.rs:296:9:296:10 | n1 | +| variables.rs:303:9:303:9 | x | variables.rs:302:10:302:10 | x | +| variables.rs:305:9:305:26 | immutable_variable | variables.rs:301:9:301:26 | immutable_variable | +| variables.rs:306:15:306:16 | n2 | variables.rs:304:9:304:10 | n2 | +| variables.rs:313:12:313:12 | v | variables.rs:310:9:310:9 | v | +| variables.rs:314:19:314:22 | text | variables.rs:312:9:312:12 | text | diff --git a/rust/ql/test/library-tests/variables/variables.rs b/rust/ql/test/library-tests/variables/variables.rs index f9d3e89938c3..8a0e83c9eff7 100644 --- a/rust/ql/test/library-tests/variables/variables.rs +++ b/rust/ql/test/library-tests/variables/variables.rs @@ -220,6 +220,21 @@ fn match_pattern8() { } } +enum FourValued { + First(i64), + Second(i64), + Third(i64), + Fourth(i64), +} + +fn match_pattern9() { + let fv = FourValued::Second(62); // tv + match fv { // $ access=tv + FourValued::First(a13) | (FourValued::Second(a13) | FourValued::Third(a13)) | FourValued::Fourth(a13) // a13 + => print_i64(a13), // $ access=a13 + } +} + fn param_pattern1( a8: &str, // a8 ( @@ -317,6 +332,7 @@ fn main() { match_pattern6(); match_pattern7(); match_pattern8(); + match_pattern9(); param_pattern1("a", ("b", "c")); param_pattern2(Either::Left(45)); destruct_assignment(); From f39dc41903dfbd7e4f863688e72a2342945a1eae Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 1 Oct 2024 13:53:25 +0200 Subject: [PATCH 086/347] Python: use imprecise content in cp We had accidentally used precise content leadingto blowup --- .../semmle/python/dataflow/new/internal/DataFlowPrivate.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 5b2457cd762e..4d97f04d28d8 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -195,7 +195,7 @@ predicate yieldStoreStep(Node nodeFrom, Content c, Node nodeTo) { c instanceof SetElementContent or comp instanceof DictComp and - c instanceof DictionaryElementContent + c instanceof DictionaryElementAnyContent ) or not exists(Comp comp | func = comp.getFunction()) and @@ -204,7 +204,7 @@ predicate yieldStoreStep(Node nodeFrom, Content c, Node nodeTo) { or c instanceof SetElementContent or - c instanceof DictionaryElementContent + c instanceof DictionaryElementAnyContent ) ) } From 901f756c692860c48131fdeba3e2230a2ea6dabd Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Tue, 1 Oct 2024 12:36:38 +0100 Subject: [PATCH 087/347] Java: Add a test for parameter names --- .../library-tests/MemberRefExpr/parameters.expected | 10 ++++++++++ java/ql/test/library-tests/MemberRefExpr/parameters.ql | 5 +++++ 2 files changed, 15 insertions(+) create mode 100644 java/ql/test/library-tests/MemberRefExpr/parameters.expected create mode 100644 java/ql/test/library-tests/MemberRefExpr/parameters.ql diff --git a/java/ql/test/library-tests/MemberRefExpr/parameters.expected b/java/ql/test/library-tests/MemberRefExpr/parameters.expected new file mode 100644 index 000000000000..12f149b5d243 --- /dev/null +++ b/java/ql/test/library-tests/MemberRefExpr/parameters.expected @@ -0,0 +1,10 @@ +| Test.java:3:22:3:24 | o | +| Test.java:7:22:7:26 | i | +| Test.java:45:22:45:26 | s | +| Test.java:49:29:49:42 | p0 | +| Test.java:50:29:50:42 | p0 | +| Test.java:51:29:51:39 | p0 | +| Test.java:52:40:52:64 | p0 | +| Test.java:70:13:70:22 | p0 | +| Test.java:71:13:71:26 | p0 | +| Test.java:75:31:75:47 | p0 | diff --git a/java/ql/test/library-tests/MemberRefExpr/parameters.ql b/java/ql/test/library-tests/MemberRefExpr/parameters.ql new file mode 100644 index 000000000000..d4b8690b4850 --- /dev/null +++ b/java/ql/test/library-tests/MemberRefExpr/parameters.ql @@ -0,0 +1,5 @@ +import java + +from Parameter p +where p.fromSource() +select p From 323b7cb96f84c86176a82ea1b30c52062be86248 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Tue, 1 Oct 2024 12:37:34 +0100 Subject: [PATCH 088/347] Java: Follow change of implicit parameter names --- .../MemberRefExpr/parameters.expected | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/java/ql/test/library-tests/MemberRefExpr/parameters.expected b/java/ql/test/library-tests/MemberRefExpr/parameters.expected index 12f149b5d243..2981f022fef6 100644 --- a/java/ql/test/library-tests/MemberRefExpr/parameters.expected +++ b/java/ql/test/library-tests/MemberRefExpr/parameters.expected @@ -1,10 +1,10 @@ | Test.java:3:22:3:24 | o | | Test.java:7:22:7:26 | i | | Test.java:45:22:45:26 | s | -| Test.java:49:29:49:42 | p0 | -| Test.java:50:29:50:42 | p0 | -| Test.java:51:29:51:39 | p0 | -| Test.java:52:40:52:64 | p0 | -| Test.java:70:13:70:22 | p0 | -| Test.java:71:13:71:26 | p0 | -| Test.java:75:31:75:47 | p0 | +| Test.java:49:29:49:42 | this | +| Test.java:50:29:50:42 | this | +| Test.java:51:29:51:39 | this | +| Test.java:52:40:52:64 | this | +| Test.java:70:13:70:22 | length | +| Test.java:71:13:71:26 | length | +| Test.java:75:31:75:47 | this | From 38b1eb7c71a0dd77b59e493d3222a56f13c5ca31 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 1 Oct 2024 16:24:15 +0200 Subject: [PATCH 089/347] Python: just use `ListElementContent` for iterables --- .../dataflow/new/internal/DataFlowPrivate.qll | 27 ++----------------- .../lib/semmle/python/frameworks/Stdlib.qll | 4 +++ .../dataflow/coverage/test_builtins.py | 4 +-- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 4d97f04d28d8..3d2329f0ad98 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -179,33 +179,10 @@ private predicate synthDictSplatArgumentNodeStoreStep( * data from `x.name` is stored into the `yield` (and can subsequently be read out of the iterable). */ predicate yieldStoreStep(Node nodeFrom, Content c, Node nodeTo) { - exists(Yield yield, Function func | + exists(Yield yield | nodeTo.asCfgNode() = yield.getAFlowNode() and nodeFrom.asCfgNode() = yield.getValue().getAFlowNode() and - func.containsInScope(yield) - | - exists(Comp comp | func = comp.getFunction() | - ( - comp instanceof ListComp or - comp instanceof GeneratorExp - ) and - c instanceof ListElementContent - or - comp instanceof SetComp and - c instanceof SetElementContent - or - comp instanceof DictComp and - c instanceof DictionaryElementAnyContent - ) - or - not exists(Comp comp | func = comp.getFunction()) and - ( - c instanceof ListElementContent - or - c instanceof SetElementContent - or - c instanceof DictionaryElementAnyContent - ) + c instanceof ListElementContent ) } diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 3c23b3929911..6d73258d65b8 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4224,6 +4224,10 @@ module StdlibPrivate { preservesValue = true ) or + input = "Argument[0].ListElement.TupleElement[1]" and + output = "ReturnValue.DictionaryElementAny" and + preservesValue = true + or exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() | input = "Argument[" + key + ":]" and output = "ReturnValue.DictionaryElement[" + key + "]" and diff --git a/python/ql/test/library-tests/dataflow/coverage/test_builtins.py b/python/ql/test/library-tests/dataflow/coverage/test_builtins.py index 245923370765..d0791ffae47b 100644 --- a/python/ql/test/library-tests/dataflow/coverage/test_builtins.py +++ b/python/ql/test/library-tests/dataflow/coverage/test_builtins.py @@ -132,8 +132,8 @@ def test_dict_from_keyword(): @expects(2) def test_dict_from_list(): d = dict([("k", SOURCE), ("k1", NONSOURCE)]) - SINK(d["k"]) #$ MISSING: flow="SOURCE, l:-1 -> d[k]" - SINK_F(d["k1"]) + SINK(d["k"]) #$ flow="SOURCE, l:-1 -> d['k']" + SINK_F(d["k1"]) #$ SPURIOUS: flow="SOURCE, l:-2 -> d['k1']" // due to imprecise list content @expects(2) def test_dict_from_dict(): From a9b3c0d91b4988bf27e9c0e5b7d8494043932500 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Tue, 1 Oct 2024 15:47:12 +0100 Subject: [PATCH 090/347] C++: Address review comments --- cpp/ql/lib/semmle/code/cpp/Function.qll | 7 +++++-- cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll | 7 ------- .../ir/implementation/raw/internal/TranslatedElement.qll | 2 +- .../Likely Bugs/Memory Management/UninitializedLocal.ql | 4 ++-- .../CWE/CWE-457/semmle/tests/UninitializedLocal.expected | 1 - 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/Function.qll b/cpp/ql/lib/semmle/code/cpp/Function.qll index 1234791576b1..7cfa779338f7 100644 --- a/cpp/ql/lib/semmle/code/cpp/Function.qll +++ b/cpp/ql/lib/semmle/code/cpp/Function.qll @@ -505,8 +505,11 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function { * Holds if this function has extraction errors that create an `ErrorExpr`. */ predicate hasErrors() { - // Exclude allocator call arguments because they are are always extracted as `ErrorExpr`. - exists(ErrorExpr e | e.getEnclosingFunction() = this and not e.isFirstAllocatorCallArgument()) + exists(ErrorExpr e | + e.getEnclosingFunction() = this and + // Exclude the first allocator call argument because it is always extracted as `ErrorExpr`. + not exists(NewOrNewArrayExpr new | e = new.getAllocatorCall().getArgument(0)) + ) } } diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll index 4eaf83e2c03f..91b57049a54e 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll @@ -744,13 +744,6 @@ class ErrorExpr extends Expr, @errorexpr { override string toString() { result = "" } override string getAPrimaryQlClass() { result = "ErrorExpr" } - - /** - * Holds if this error expression is the first argument to a `new` allocation call. - */ - predicate isFirstAllocatorCallArgument() { - this = any(NewOrNewArrayExpr new).getAllocatorCall().getArgument(0) - } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 1047dc2b8a7b..0f9bc370f7a5 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -151,7 +151,7 @@ private predicate ignoreExprOnly(Expr expr) { // The extractor deliberately emits an `ErrorExpr` as the first argument to // the allocator call, if any, of a `NewOrNewArrayExpr`. That `ErrorExpr` // should not be translated. - expr.(ErrorExpr).isFirstAllocatorCallArgument() + exists(NewOrNewArrayExpr new | expr = new.getAllocatorCall().getArgument(0)) or not translateFunction(getEnclosingFunction(expr)) and not Raw::varHasIRFunc(getEnclosingVariable(expr)) diff --git a/cpp/ql/src/Likely Bugs/Memory Management/UninitializedLocal.ql b/cpp/ql/src/Likely Bugs/Memory Management/UninitializedLocal.ql index 226cbfd322b9..763a142f1b90 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/UninitializedLocal.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/UninitializedLocal.ql @@ -65,6 +65,7 @@ predicate isSinkImpl(Instruction sink, VariableAccess va) { exists(LoadInstruction load | va = load.getUnconvertedResultExpression() and not va = commonException() and + not va.getTarget().(LocalVariable).getFunction().hasErrors() and sink = load.getSourceValue() ) } @@ -89,6 +90,5 @@ from where conf.hasFlowPath(source, sink) and isSinkImpl(sink.getInstruction(), va) and - v = va.getTarget() and - not v.getFunction().hasErrors() + v = va.getTarget() select va, source, sink, "The variable $@ may not be initialized at this access.", v, v.getName() diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected index 30896607a18d..6773f5aef942 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected @@ -1,6 +1,5 @@ edges nodes -| errors.cpp:4:7:4:7 | definition of x | semmle.label | definition of x | | errors.cpp:13:7:13:7 | definition of x | semmle.label | definition of x | | test.cpp:11:6:11:8 | definition of foo | semmle.label | definition of foo | | test.cpp:111:6:111:8 | definition of foo | semmle.label | definition of foo | From 315890680cc38d86c49c37e18d104fee2cb95775 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 1 Oct 2024 16:48:43 +0200 Subject: [PATCH 091/347] Python: dict only has one positional argument --- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index ca8b10d8578a..37cb23a472db 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4219,7 +4219,7 @@ module StdlibPrivate { override predicate propagatesFlow(string input, string output, boolean preservesValue) { exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() | - input = "Argument[0..].DictionaryElement[" + key + "]" and + input = "Argument[0].DictionaryElement[" + key + "]" and output = "ReturnValue.DictionaryElement[" + key + "]" and preservesValue = true ) From 9a82ea48f2708439ce6c2b56b79f907a4171cb9f Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 1 Oct 2024 15:41:17 +0100 Subject: [PATCH 092/347] Add test for cross-package references with test extraction --- go/ql/integration-tests/test-extraction/src/go.mod | 2 +- .../test-extraction/src/pkg1/def.go | 7 +++++++ .../test-extraction/src/pkg1/def_test.go | 5 +++++ .../test-extraction/src/pkg2/use.go | 12 ++++++++++++ .../integration-tests/test-extraction/test.expected | 4 ++++ 5 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 go/ql/integration-tests/test-extraction/src/pkg1/def.go create mode 100644 go/ql/integration-tests/test-extraction/src/pkg1/def_test.go create mode 100644 go/ql/integration-tests/test-extraction/src/pkg2/use.go diff --git a/go/ql/integration-tests/test-extraction/src/go.mod b/go/ql/integration-tests/test-extraction/src/go.mod index c4a9f55df6c1..dae010718cf0 100644 --- a/go/ql/integration-tests/test-extraction/src/go.mod +++ b/go/ql/integration-tests/test-extraction/src/go.mod @@ -1,3 +1,3 @@ -go 1.14 +go 1.18 module testsample diff --git a/go/ql/integration-tests/test-extraction/src/pkg1/def.go b/go/ql/integration-tests/test-extraction/src/pkg1/def.go new file mode 100644 index 000000000000..2492919f76df --- /dev/null +++ b/go/ql/integration-tests/test-extraction/src/pkg1/def.go @@ -0,0 +1,7 @@ +package pkg1 + +type Generic[T any] struct { + element T +} + +func TestMe() { } diff --git a/go/ql/integration-tests/test-extraction/src/pkg1/def_test.go b/go/ql/integration-tests/test-extraction/src/pkg1/def_test.go new file mode 100644 index 000000000000..f321ab577c90 --- /dev/null +++ b/go/ql/integration-tests/test-extraction/src/pkg1/def_test.go @@ -0,0 +1,5 @@ +package pkg1 + +func UsePkg1() { + TestMe() +} diff --git a/go/ql/integration-tests/test-extraction/src/pkg2/use.go b/go/ql/integration-tests/test-extraction/src/pkg2/use.go new file mode 100644 index 000000000000..8caabc3847e7 --- /dev/null +++ b/go/ql/integration-tests/test-extraction/src/pkg2/use.go @@ -0,0 +1,12 @@ +package pkg2 + +import ( + "testsample/pkg1" +) + +// This tests the case of cross-package generic type references +// in the presence of test extraction. We need to make sure we +// extract packages, including test variants, in the right order +// such that we've seen pkg1.Generic before we try to use it here. + +type Specialised = pkg1.Generic[string] diff --git a/go/ql/integration-tests/test-extraction/test.expected b/go/ql/integration-tests/test-extraction/test.expected index 9e1585fc5ef8..c4135434743d 100644 --- a/go/ql/integration-tests/test-extraction/test.expected +++ b/go/ql/integration-tests/test-extraction/test.expected @@ -1,8 +1,12 @@ #select +| src/pkg1/def.go:0:0:0:0 | src/pkg1/def.go | +| src/pkg1/def_test.go:0:0:0:0 | src/pkg1/def_test.go | +| src/pkg2/use.go:0:0:0:0 | src/pkg2/use.go | | src/testme.go:0:0:0:0 | src/testme.go | | src/testme_blackbox_test.go:0:0:0:0 | src/testme_blackbox_test.go | | src/testme_test.go:0:0:0:0 | src/testme_test.go | calls +| src/pkg1/def_test.go:4:2:4:9 | call to TestMe | src/pkg1/def.go:7:1:7:17 | function declaration | | src/testme_blackbox_test.go:10:18:10:44 | call to PublicFunction | src/testme.go:3:1:3:38 | function declaration | | src/testme_test.go:9:18:9:33 | call to PublicFunction | src/testme.go:3:1:3:38 | function declaration | | src/testme_test.go:14:19:14:35 | call to privateFunction | src/testme.go:5:1:5:39 | function declaration | From 6ef2aed3aa0d1f57602261f4e8a2de680a43d3aa Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 1 Oct 2024 15:52:30 +0100 Subject: [PATCH 093/347] Add blackbox, out-of-package test --- .../test-extraction/src/pkg1/def_blackbox_test.go | 9 +++++++++ go/ql/integration-tests/test-extraction/test.expected | 2 ++ go/ql/integration-tests/test-extraction/test.py | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 go/ql/integration-tests/test-extraction/src/pkg1/def_blackbox_test.go diff --git a/go/ql/integration-tests/test-extraction/src/pkg1/def_blackbox_test.go b/go/ql/integration-tests/test-extraction/src/pkg1/def_blackbox_test.go new file mode 100644 index 000000000000..09c9474567a6 --- /dev/null +++ b/go/ql/integration-tests/test-extraction/src/pkg1/def_blackbox_test.go @@ -0,0 +1,9 @@ +package pkg1_test + +import ( + "testsample/pkg1" +) + +func UsePkg1() { + pkg1.TestMe() +} diff --git a/go/ql/integration-tests/test-extraction/test.expected b/go/ql/integration-tests/test-extraction/test.expected index c4135434743d..eda27075ad43 100644 --- a/go/ql/integration-tests/test-extraction/test.expected +++ b/go/ql/integration-tests/test-extraction/test.expected @@ -1,11 +1,13 @@ #select | src/pkg1/def.go:0:0:0:0 | src/pkg1/def.go | +| src/pkg1/def_blackbox_test.go:0:0:0:0 | src/pkg1/def_blackbox_test.go | | src/pkg1/def_test.go:0:0:0:0 | src/pkg1/def_test.go | | src/pkg2/use.go:0:0:0:0 | src/pkg2/use.go | | src/testme.go:0:0:0:0 | src/testme.go | | src/testme_blackbox_test.go:0:0:0:0 | src/testme_blackbox_test.go | | src/testme_test.go:0:0:0:0 | src/testme_test.go | calls +| src/pkg1/def_blackbox_test.go:8:2:8:14 | call to TestMe | src/pkg1/def.go:7:1:7:17 | function declaration | | src/pkg1/def_test.go:4:2:4:9 | call to TestMe | src/pkg1/def.go:7:1:7:17 | function declaration | | src/testme_blackbox_test.go:10:18:10:44 | call to PublicFunction | src/testme.go:3:1:3:38 | function declaration | | src/testme_test.go:9:18:9:33 | call to PublicFunction | src/testme.go:3:1:3:38 | function declaration | diff --git a/go/ql/integration-tests/test-extraction/test.py b/go/ql/integration-tests/test-extraction/test.py index 6419ae83f38c..e25b46801146 100644 --- a/go/ql/integration-tests/test-extraction/test.py +++ b/go/ql/integration-tests/test-extraction/test.py @@ -1,7 +1,7 @@ import os def test_traced(codeql, go): - codeql.database.create(source_root="src", command="go test -c") + codeql.database.create(source_root="src", command="go test -c ./...") def test_autobuild(codeql, go): codeql.database.create(source_root="src", extractor_option = ["extract_tests=true"]) From cd1f10cdea4b0dc52cf8ef66923e2b6ea9fb98e3 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Tue, 1 Oct 2024 16:15:24 +0100 Subject: [PATCH 094/347] C++: Reinstate accidentally-deleted comment --- cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.ql b/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.ql index f824ecf53e76..5ae8468d0fc4 100644 --- a/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.ql +++ b/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.ql @@ -57,5 +57,5 @@ where not declarationHasSideEffects(v) and not exists(AsmStmt s | f = s.getEnclosingFunction()) and not v.getAnAttribute().getName() = "unused" and - not f.hasErrors() + not f.hasErrors() // Unextracted expressions may use `v` select v, "Variable " + v.getName() + " is not used." From 3a54c10f369826f3d0491267f582dd4cf33c8bd5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 1 Oct 2024 17:35:30 +0100 Subject: [PATCH 095/347] Rust: For now exclude top-level AST elements from LOC counts. This is not ideal. --- rust/ql/lib/codeql/files/FileSystem.qll | 2 ++ rust/ql/test/query-tests/diagnostics/LinesOfCode.expected | 2 +- .../test/query-tests/diagnostics/LinesOfUserCode.expected | 2 +- .../query-tests/diagnostics/LinesOfUserCodeInFiles.expected | 6 +++--- rust/ql/test/query-tests/diagnostics/SummaryStats.expected | 4 ++-- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/rust/ql/lib/codeql/files/FileSystem.qll b/rust/ql/lib/codeql/files/FileSystem.qll index ee7a2235476e..a5410ece9712 100644 --- a/rust/ql/lib/codeql/files/FileSystem.qll +++ b/rust/ql/lib/codeql/files/FileSystem.qll @@ -5,6 +5,7 @@ private import codeql.util.FileSystem private import codeql.rust.elements.SourceFile private import codeql.rust.elements.AstNode private import codeql.rust.elements.Comment +private import codeql.rust.elements.internal.generated.ParentChild private module Input implements InputSig { abstract class ContainerBase extends @container { @@ -47,6 +48,7 @@ class File extends Container, Impl::File { exists(AstNode node, Location loc | not node instanceof Comment and not node instanceof SourceFile and + not getImmediateParent(node) instanceof SourceFile and // ignore top-level elements for now as we're getting their locations wrong when a comment is attached loc = node.getLocation() | node.getFile() = this and diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected b/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected index d6a21ebb49cf..3885b955c3f3 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected @@ -1 +1 @@ -| 49 | +| 46 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected index d6a21ebb49cf..3885b955c3f3 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected @@ -1 +1 @@ -| 49 | +| 46 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected index dde3c7fe35a7..52ee2055e8fe 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected @@ -1,6 +1,6 @@ -| my_struct.rs:0:0:0:0 | my_struct.rs | 21 | -| main.rs:0:0:0:0 | main.rs | 8 | -| my_macro.rs:0:0:0:0 | my_macro.rs | 8 | +| my_struct.rs:0:0:0:0 | my_struct.rs | 20 | +| main.rs:0:0:0:0 | main.rs | 7 | +| my_macro.rs:0:0:0:0 | my_macro.rs | 7 | | lib.rs:0:0:0:0 | lib.rs | 6 | | 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 6c5eafcc38e3..da1e6cd7b60c 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -1,5 +1,5 @@ | Elements extracted | 216 | | Elements unextracted | 0 | | Files extracted | 6 | -| Lines of code extracted | 49 | -| Lines of user code extracted | 49 | +| Lines of code extracted | 46 | +| Lines of user code extracted | 46 | From 5444a5bf8adce0b37cd34c05319b2a9813fa3301 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 30 Sep 2024 16:57:31 +0200 Subject: [PATCH 096/347] Rust: Extend `while` and `for` CFG tests --- .../CONSISTENCY/CfgConsistency.expected | 6 +- .../library-tests/controlflow/Cfg.expected | 690 +++++++++--------- .../ql/test/library-tests/controlflow/test.rs | 10 +- 3 files changed, 356 insertions(+), 350 deletions(-) diff --git a/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected index ec8ec04bf3ea..49f433fff2c8 100644 --- a/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected +++ b/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected @@ -1,6 +1,6 @@ deadEnd | test.rs:55:13:55:17 | b | -| test.rs:224:28:224:33 | ... < ... | -| test.rs:239:30:239:48 | BlockExpr | +| test.rs:230:28:230:33 | ... < ... | +| test.rs:245:30:245:48 | BlockExpr | scopeNoFirst -| test.rs:62:5:66:5 | test_for | +| test.rs:65:5:72:5 | test_for | diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index d0ab3bd10d63..f7d5365cf182 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -97,350 +97,350 @@ | test.rs:47:21:47:36 | ExprStmt | test.rs:47:21:47:35 | ContinueExpr | | | test.rs:49:17:49:31 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | continue('inner) | | test.rs:49:17:49:32 | ExprStmt | test.rs:49:17:49:31 | ContinueExpr | | -| test.rs:54:5:60:5 | enter test_while | test.rs:55:9:55:25 | LetStmt | | +| test.rs:54:5:63:5 | enter test_while | test.rs:55:9:55:25 | LetStmt | | | test.rs:55:9:55:25 | LetStmt | test.rs:55:21:55:24 | true | | | test.rs:55:21:55:24 | true | test.rs:55:13:55:17 | b | | -| test.rs:69:1:72:1 | enter test_nested_function | test.rs:70:5:70:28 | LetStmt | | -| test.rs:69:1:72:1 | exit test_nested_function (normal) | test.rs:69:1:72:1 | exit test_nested_function | | -| test.rs:69:40:72:1 | BlockExpr | test.rs:69:1:72:1 | exit test_nested_function (normal) | | -| test.rs:70:5:70:28 | LetStmt | test.rs:70:19:70:27 | ClosureExpr | | -| test.rs:70:9:70:15 | add_one | test.rs:71:5:71:11 | add_one | match, no-match | -| test.rs:70:19:70:27 | ClosureExpr | test.rs:70:9:70:15 | add_one | | -| test.rs:70:19:70:27 | enter ClosureExpr | test.rs:70:23:70:23 | i | | -| test.rs:70:19:70:27 | exit ClosureExpr (normal) | test.rs:70:19:70:27 | exit ClosureExpr | | -| test.rs:70:23:70:23 | i | test.rs:70:27:70:27 | 1 | | -| test.rs:70:23:70:27 | ... + ... | test.rs:70:19:70:27 | exit ClosureExpr (normal) | | -| test.rs:70:27:70:27 | 1 | test.rs:70:23:70:27 | ... + ... | | -| test.rs:71:5:71:11 | add_one | test.rs:71:13:71:19 | add_one | | -| test.rs:71:5:71:23 | CallExpr | test.rs:69:40:72:1 | BlockExpr | | -| test.rs:71:13:71:19 | add_one | test.rs:71:21:71:21 | n | | -| test.rs:71:13:71:22 | CallExpr | test.rs:71:5:71:23 | CallExpr | | -| test.rs:71:21:71:21 | n | test.rs:71:13:71:22 | CallExpr | | -| test.rs:76:5:82:5 | enter test_if_else | test.rs:77:12:77:12 | n | | -| test.rs:76:5:82:5 | exit test_if_else (normal) | test.rs:76:5:82:5 | exit test_if_else | | -| test.rs:76:36:82:5 | BlockExpr | test.rs:76:5:82:5 | exit test_if_else (normal) | | -| test.rs:77:9:81:9 | IfExpr | test.rs:76:36:82:5 | BlockExpr | | -| test.rs:77:12:77:12 | n | test.rs:77:17:77:17 | 0 | | -| test.rs:77:12:77:17 | ... <= ... | test.rs:78:13:78:13 | 0 | true | -| test.rs:77:12:77:17 | ... <= ... | test.rs:80:13:80:13 | n | false | -| test.rs:77:17:77:17 | 0 | test.rs:77:12:77:17 | ... <= ... | | -| test.rs:77:19:79:9 | BlockExpr | test.rs:77:9:81:9 | IfExpr | | -| test.rs:78:13:78:13 | 0 | test.rs:77:19:79:9 | BlockExpr | | -| test.rs:79:16:81:9 | BlockExpr | test.rs:77:9:81:9 | IfExpr | | -| test.rs:80:13:80:13 | n | test.rs:80:17:80:17 | 1 | | -| test.rs:80:13:80:17 | ... - ... | test.rs:79:16:81:9 | BlockExpr | | -| test.rs:80:17:80:17 | 1 | test.rs:80:13:80:17 | ... - ... | | -| test.rs:84:5:90:5 | enter test_if_let_else | test.rs:85:12:85:26 | LetExpr | | -| test.rs:84:5:90:5 | exit test_if_let_else (normal) | test.rs:84:5:90:5 | exit test_if_let_else | | -| test.rs:84:48:90:5 | BlockExpr | test.rs:84:5:90:5 | exit test_if_let_else (normal) | | -| test.rs:85:9:89:9 | IfExpr | test.rs:84:48:90:5 | BlockExpr | | -| test.rs:85:12:85:26 | LetExpr | test.rs:85:16:85:22 | TupleStructPat | | -| test.rs:85:16:85:22 | TupleStructPat | test.rs:86:13:86:13 | n | match | -| test.rs:85:16:85:22 | TupleStructPat | test.rs:88:13:88:13 | 0 | no-match | -| test.rs:85:28:87:9 | BlockExpr | test.rs:85:9:89:9 | IfExpr | | -| test.rs:86:13:86:13 | n | test.rs:85:28:87:9 | BlockExpr | | -| test.rs:87:16:89:9 | BlockExpr | test.rs:85:9:89:9 | IfExpr | | -| test.rs:88:13:88:13 | 0 | test.rs:87:16:89:9 | BlockExpr | | -| test.rs:92:5:97:5 | enter test_if_let | test.rs:93:9:95:9 | ExprStmt | | -| test.rs:92:5:97:5 | exit test_if_let (normal) | test.rs:92:5:97:5 | exit test_if_let | | -| test.rs:92:43:97:5 | BlockExpr | test.rs:92:5:97:5 | exit test_if_let (normal) | | -| test.rs:93:9:95:9 | ExprStmt | test.rs:93:12:93:26 | LetExpr | | -| test.rs:93:9:95:9 | IfExpr | test.rs:96:9:96:9 | 0 | | -| test.rs:93:12:93:26 | LetExpr | test.rs:93:16:93:22 | TupleStructPat | | -| test.rs:93:16:93:22 | TupleStructPat | test.rs:93:9:95:9 | IfExpr | no-match | -| test.rs:93:16:93:22 | TupleStructPat | test.rs:94:13:94:13 | n | match | -| test.rs:93:28:95:9 | BlockExpr | test.rs:93:9:95:9 | IfExpr | | -| test.rs:94:13:94:13 | n | test.rs:93:28:95:9 | BlockExpr | | -| test.rs:96:9:96:9 | 0 | test.rs:92:43:97:5 | BlockExpr | | -| test.rs:99:5:105:5 | enter test_nested_if | test.rs:100:16:100:16 | PathExpr | | -| test.rs:99:5:105:5 | exit test_nested_if (normal) | test.rs:99:5:105:5 | exit test_nested_if | | -| test.rs:99:38:105:5 | BlockExpr | test.rs:99:5:105:5 | exit test_nested_if (normal) | | -| test.rs:100:9:104:9 | IfExpr | test.rs:99:38:105:5 | BlockExpr | | -| test.rs:100:12:100:49 | ParenExpr | test.rs:101:13:101:13 | 1 | true | -| test.rs:100:12:100:49 | ParenExpr | test.rs:103:13:103:13 | 0 | false | -| test.rs:100:13:100:48 | IfExpr | test.rs:100:12:100:49 | ParenExpr | | -| test.rs:100:16:100:16 | PathExpr | test.rs:100:20:100:20 | 0 | | -| test.rs:100:16:100:20 | ... < ... | test.rs:100:24:100:24 | a | true | -| test.rs:100:16:100:20 | ... < ... | test.rs:100:41:100:41 | a | false | -| test.rs:100:20:100:20 | 0 | test.rs:100:16:100:20 | ... < ... | | -| test.rs:100:22:100:32 | BlockExpr | test.rs:100:13:100:48 | IfExpr | | -| test.rs:100:24:100:24 | a | test.rs:100:29:100:30 | 10 | | -| test.rs:100:24:100:30 | ... < ... | test.rs:100:22:100:32 | BlockExpr | | -| test.rs:100:28:100:30 | - ... | test.rs:100:24:100:30 | ... < ... | | -| test.rs:100:29:100:30 | 10 | test.rs:100:28:100:30 | - ... | | -| test.rs:100:39:100:48 | BlockExpr | test.rs:100:13:100:48 | IfExpr | | -| test.rs:100:41:100:41 | a | test.rs:100:45:100:46 | 10 | | -| test.rs:100:41:100:46 | ... > ... | test.rs:100:39:100:48 | BlockExpr | | -| test.rs:100:45:100:46 | 10 | test.rs:100:41:100:46 | ... > ... | | -| test.rs:100:51:102:9 | BlockExpr | test.rs:100:9:104:9 | IfExpr | | -| test.rs:101:13:101:13 | 1 | test.rs:100:51:102:9 | BlockExpr | | -| test.rs:102:16:104:9 | BlockExpr | test.rs:100:9:104:9 | IfExpr | | -| test.rs:103:13:103:13 | 0 | test.rs:102:16:104:9 | BlockExpr | | -| test.rs:107:5:116:5 | enter test_nested_if_match | test.rs:108:19:108:19 | a | | -| test.rs:107:5:116:5 | exit test_nested_if_match (normal) | test.rs:107:5:116:5 | exit test_nested_if_match | | -| test.rs:107:44:116:5 | BlockExpr | test.rs:107:5:116:5 | exit test_nested_if_match (normal) | | -| test.rs:108:9:115:9 | IfExpr | test.rs:107:44:116:5 | BlockExpr | | -| test.rs:108:12:111:10 | ParenExpr | test.rs:112:13:112:13 | 1 | true | -| test.rs:108:12:111:10 | ParenExpr | test.rs:114:13:114:13 | 0 | false | -| test.rs:108:13:111:9 | MatchExpr | test.rs:108:12:111:10 | ParenExpr | | -| test.rs:108:19:108:19 | a | test.rs:109:13:109:13 | LiteralPat | | -| test.rs:109:13:109:13 | LiteralPat | test.rs:109:18:109:21 | true | match | -| test.rs:109:13:109:13 | LiteralPat | test.rs:110:13:110:13 | WildcardPat | no-match | -| test.rs:109:18:109:21 | true | test.rs:108:13:111:9 | MatchExpr | | -| test.rs:110:13:110:13 | WildcardPat | test.rs:110:18:110:22 | false | match | -| test.rs:110:18:110:22 | false | test.rs:108:13:111:9 | MatchExpr | | -| test.rs:111:12:113:9 | BlockExpr | test.rs:108:9:115:9 | IfExpr | | -| test.rs:112:13:112:13 | 1 | test.rs:111:12:113:9 | BlockExpr | | -| test.rs:113:16:115:9 | BlockExpr | test.rs:108:9:115:9 | IfExpr | | -| test.rs:114:13:114:13 | 0 | test.rs:113:16:115:9 | BlockExpr | | -| test.rs:118:5:127:5 | enter test_nested_if_block | test.rs:120:13:120:15 | ExprStmt | | -| test.rs:118:5:127:5 | exit test_nested_if_block (normal) | test.rs:118:5:127:5 | exit test_nested_if_block | | -| test.rs:118:44:127:5 | BlockExpr | test.rs:118:5:127:5 | exit test_nested_if_block (normal) | | -| test.rs:119:9:126:9 | IfExpr | test.rs:118:44:127:5 | BlockExpr | | -| test.rs:119:12:122:9 | BlockExpr | test.rs:123:13:123:13 | 1 | true | -| test.rs:119:12:122:9 | BlockExpr | test.rs:125:13:125:13 | 0 | false | -| test.rs:120:13:120:14 | TupleExpr | test.rs:121:13:121:13 | a | | -| test.rs:120:13:120:15 | ExprStmt | test.rs:120:13:120:14 | TupleExpr | | -| test.rs:121:13:121:13 | a | test.rs:121:17:121:17 | 0 | | -| test.rs:121:13:121:17 | ... > ... | test.rs:119:12:122:9 | BlockExpr | false, true | -| test.rs:121:17:121:17 | 0 | test.rs:121:13:121:17 | ... > ... | | -| test.rs:122:11:124:9 | BlockExpr | test.rs:119:9:126:9 | IfExpr | | -| test.rs:123:13:123:13 | 1 | test.rs:122:11:124:9 | BlockExpr | | -| test.rs:124:16:126:9 | BlockExpr | test.rs:119:9:126:9 | IfExpr | | -| test.rs:125:13:125:13 | 0 | test.rs:124:16:126:9 | BlockExpr | | -| test.rs:129:5:136:5 | enter test_if_assignment | test.rs:130:9:130:26 | LetStmt | | -| test.rs:129:5:136:5 | exit test_if_assignment (normal) | test.rs:129:5:136:5 | exit test_if_assignment | | -| test.rs:129:42:136:5 | BlockExpr | test.rs:129:5:136:5 | exit test_if_assignment (normal) | | -| test.rs:130:9:130:26 | LetStmt | test.rs:130:21:130:25 | false | | -| test.rs:130:13:130:17 | x | test.rs:131:12:131:12 | x | match, no-match | -| test.rs:130:21:130:25 | false | test.rs:130:13:130:17 | x | | -| test.rs:131:9:135:9 | IfExpr | test.rs:129:42:136:5 | BlockExpr | | -| test.rs:131:12:131:12 | x | test.rs:131:16:131:19 | true | | -| test.rs:131:12:131:19 | ... = ... | test.rs:132:13:132:13 | 1 | true | -| test.rs:131:12:131:19 | ... = ... | test.rs:134:13:134:13 | 0 | false | -| test.rs:131:16:131:19 | true | test.rs:131:12:131:19 | ... = ... | | -| test.rs:131:21:133:9 | BlockExpr | test.rs:131:9:135:9 | IfExpr | | -| test.rs:132:13:132:13 | 1 | test.rs:131:21:133:9 | BlockExpr | | -| test.rs:133:16:135:9 | BlockExpr | test.rs:131:9:135:9 | IfExpr | | -| test.rs:134:13:134:13 | 0 | test.rs:133:16:135:9 | BlockExpr | | -| test.rs:138:5:149:5 | enter test_if_loop1 | test.rs:140:13:142:14 | ExprStmt | | -| test.rs:138:5:149:5 | exit test_if_loop1 (normal) | test.rs:138:5:149:5 | exit test_if_loop1 | | -| test.rs:138:37:149:5 | BlockExpr | test.rs:138:5:149:5 | exit test_if_loop1 (normal) | | -| test.rs:139:9:148:9 | IfExpr | test.rs:138:37:149:5 | BlockExpr | | -| test.rs:139:12:144:10 | ParenExpr | test.rs:145:13:145:13 | 1 | true | -| test.rs:139:12:144:10 | ParenExpr | test.rs:147:13:147:13 | 0 | false | -| test.rs:139:13:144:9 | LoopExpr | test.rs:139:12:144:10 | ParenExpr | | -| test.rs:139:18:144:9 | BlockExpr | test.rs:140:13:142:14 | ExprStmt | | -| test.rs:140:13:142:13 | IfExpr | test.rs:143:13:143:19 | ExprStmt | | -| test.rs:140:13:142:14 | ExprStmt | test.rs:140:16:140:16 | a | | -| test.rs:140:16:140:16 | a | test.rs:140:20:140:20 | 0 | | -| test.rs:140:16:140:20 | ... > ... | test.rs:140:13:142:13 | IfExpr | false | -| test.rs:140:16:140:20 | ... > ... | test.rs:141:17:141:29 | ExprStmt | true | -| test.rs:140:20:140:20 | 0 | test.rs:140:16:140:20 | ... > ... | | -| test.rs:141:17:141:28 | BreakExpr | test.rs:139:13:144:9 | LoopExpr | break | -| test.rs:141:17:141:29 | ExprStmt | test.rs:141:23:141:23 | a | | -| test.rs:141:23:141:23 | a | test.rs:141:27:141:28 | 10 | | -| test.rs:141:23:141:28 | ... > ... | test.rs:141:17:141:28 | BreakExpr | | -| test.rs:141:27:141:28 | 10 | test.rs:141:23:141:28 | ... > ... | | -| test.rs:143:13:143:13 | a | test.rs:143:17:143:18 | 10 | | -| test.rs:143:13:143:18 | ... < ... | test.rs:139:18:144:9 | BlockExpr | | -| test.rs:143:13:143:19 | ExprStmt | test.rs:143:13:143:13 | a | | -| test.rs:143:17:143:18 | 10 | test.rs:143:13:143:18 | ... < ... | | -| test.rs:144:12:146:9 | BlockExpr | test.rs:139:9:148:9 | IfExpr | | -| test.rs:145:13:145:13 | 1 | test.rs:144:12:146:9 | BlockExpr | | -| test.rs:146:16:148:9 | BlockExpr | test.rs:139:9:148:9 | IfExpr | | -| test.rs:147:13:147:13 | 0 | test.rs:146:16:148:9 | BlockExpr | | -| test.rs:151:5:162:5 | enter test_if_loop2 | test.rs:153:13:155:14 | ExprStmt | | -| test.rs:151:5:162:5 | exit test_if_loop2 (normal) | test.rs:151:5:162:5 | exit test_if_loop2 | | -| test.rs:151:37:162:5 | BlockExpr | test.rs:151:5:162:5 | exit test_if_loop2 (normal) | | -| test.rs:152:9:161:9 | IfExpr | test.rs:151:37:162:5 | BlockExpr | | -| test.rs:152:12:157:10 | ParenExpr | test.rs:158:13:158:13 | 1 | true | -| test.rs:152:12:157:10 | ParenExpr | test.rs:160:13:160:13 | 0 | false | -| test.rs:152:13:157:9 | LoopExpr | test.rs:152:12:157:10 | ParenExpr | | -| test.rs:152:26:157:9 | BlockExpr | test.rs:153:13:155:14 | ExprStmt | | -| test.rs:153:13:155:13 | IfExpr | test.rs:156:13:156:19 | ExprStmt | | -| test.rs:153:13:155:14 | ExprStmt | test.rs:153:16:153:16 | a | | -| test.rs:153:16:153:16 | a | test.rs:153:20:153:20 | 0 | | -| test.rs:153:16:153:20 | ... > ... | test.rs:153:13:155:13 | IfExpr | false | -| test.rs:153:16:153:20 | ... > ... | test.rs:154:17:154:36 | ExprStmt | true | -| test.rs:153:20:153:20 | 0 | test.rs:153:16:153:20 | ... > ... | | -| test.rs:154:17:154:35 | BreakExpr | test.rs:152:13:157:9 | LoopExpr | break('label) | -| test.rs:154:17:154:36 | ExprStmt | test.rs:154:30:154:30 | a | | -| test.rs:154:30:154:30 | a | test.rs:154:34:154:35 | 10 | | -| test.rs:154:30:154:35 | ... > ... | test.rs:154:17:154:35 | BreakExpr | | -| test.rs:154:34:154:35 | 10 | test.rs:154:30:154:35 | ... > ... | | -| test.rs:156:13:156:13 | a | test.rs:156:17:156:18 | 10 | | -| test.rs:156:13:156:18 | ... < ... | test.rs:152:26:157:9 | BlockExpr | | -| test.rs:156:13:156:19 | ExprStmt | test.rs:156:13:156:13 | a | | -| test.rs:156:17:156:18 | 10 | test.rs:156:13:156:18 | ... < ... | | -| test.rs:157:12:159:9 | BlockExpr | test.rs:152:9:161:9 | IfExpr | | -| test.rs:158:13:158:13 | 1 | test.rs:157:12:159:9 | BlockExpr | | -| test.rs:159:16:161:9 | BlockExpr | test.rs:152:9:161:9 | IfExpr | | -| test.rs:160:13:160:13 | 0 | test.rs:159:16:161:9 | BlockExpr | | -| test.rs:164:5:172:5 | enter test_labelled_block | test.rs:166:13:166:31 | ExprStmt | | -| test.rs:164:5:172:5 | exit test_labelled_block (normal) | test.rs:164:5:172:5 | exit test_labelled_block | | -| test.rs:166:13:166:30 | BreakExpr | test.rs:164:5:172:5 | exit test_labelled_block (normal) | break('block) | -| test.rs:166:13:166:31 | ExprStmt | test.rs:166:26:166:26 | a | | -| test.rs:166:26:166:26 | a | test.rs:166:30:166:30 | 0 | | -| test.rs:166:26:166:30 | ... > ... | test.rs:166:13:166:30 | BreakExpr | | -| test.rs:166:30:166:30 | 0 | test.rs:166:26:166:30 | ... > ... | | -| test.rs:177:5:180:5 | enter test_and_operator | test.rs:178:9:178:28 | LetStmt | | -| test.rs:177:5:180:5 | exit test_and_operator (normal) | test.rs:177:5:180:5 | exit test_and_operator | | -| test.rs:177:61:180:5 | BlockExpr | test.rs:177:5:180:5 | exit test_and_operator (normal) | | -| test.rs:178:9:178:28 | LetStmt | test.rs:178:17:178:27 | ... && ... | | -| test.rs:178:13:178:13 | d | test.rs:179:9:179:9 | d | match, no-match | -| test.rs:178:17:178:17 | a | test.rs:178:13:178:13 | d | false | -| test.rs:178:17:178:17 | a | test.rs:178:22:178:22 | b | true | -| test.rs:178:17:178:22 | ... && ... | test.rs:178:17:178:17 | a | | -| test.rs:178:17:178:27 | ... && ... | test.rs:178:17:178:22 | ... && ... | | -| test.rs:178:22:178:22 | b | test.rs:178:13:178:13 | d | false | -| test.rs:178:22:178:22 | b | test.rs:178:27:178:27 | c | true | -| test.rs:178:27:178:27 | c | test.rs:178:13:178:13 | d | | -| test.rs:179:9:179:9 | d | test.rs:177:61:180:5 | BlockExpr | | -| test.rs:182:5:185:5 | enter test_or_operator | test.rs:183:9:183:28 | LetStmt | | -| test.rs:182:5:185:5 | exit test_or_operator (normal) | test.rs:182:5:185:5 | exit test_or_operator | | -| test.rs:182:60:185:5 | BlockExpr | test.rs:182:5:185:5 | exit test_or_operator (normal) | | -| test.rs:183:9:183:28 | LetStmt | test.rs:183:17:183:27 | ... \|\| ... | | -| test.rs:183:13:183:13 | d | test.rs:184:9:184:9 | d | match, no-match | -| test.rs:183:17:183:17 | a | test.rs:183:13:183:13 | d | true | -| test.rs:183:17:183:17 | a | test.rs:183:22:183:22 | b | false | -| test.rs:183:17:183:22 | ... \|\| ... | test.rs:183:17:183:17 | a | | -| test.rs:183:17:183:27 | ... \|\| ... | test.rs:183:17:183:22 | ... \|\| ... | | -| test.rs:183:22:183:22 | b | test.rs:183:13:183:13 | d | true | -| test.rs:183:22:183:22 | b | test.rs:183:27:183:27 | c | false | -| test.rs:183:27:183:27 | c | test.rs:183:13:183:13 | d | | -| test.rs:184:9:184:9 | d | test.rs:182:60:185:5 | BlockExpr | | -| test.rs:187:5:190:5 | enter test_or_operator_2 | test.rs:188:9:188:36 | LetStmt | | -| test.rs:187:5:190:5 | exit test_or_operator_2 (normal) | test.rs:187:5:190:5 | exit test_or_operator_2 | | -| test.rs:187:61:190:5 | BlockExpr | test.rs:187:5:190:5 | exit test_or_operator_2 (normal) | | -| test.rs:188:9:188:36 | LetStmt | test.rs:188:17:188:35 | ... \|\| ... | | -| test.rs:188:13:188:13 | d | test.rs:189:9:189:9 | d | match, no-match | -| test.rs:188:17:188:17 | a | test.rs:188:13:188:13 | d | true | -| test.rs:188:17:188:17 | a | test.rs:188:23:188:23 | b | false | -| test.rs:188:17:188:30 | ... \|\| ... | test.rs:188:17:188:17 | a | | -| test.rs:188:17:188:35 | ... \|\| ... | test.rs:188:17:188:30 | ... \|\| ... | | -| test.rs:188:22:188:30 | ParenExpr | test.rs:188:13:188:13 | d | true | -| test.rs:188:22:188:30 | ParenExpr | test.rs:188:35:188:35 | c | false | -| test.rs:188:23:188:23 | b | test.rs:188:28:188:29 | 28 | | -| test.rs:188:23:188:29 | ... == ... | test.rs:188:22:188:30 | ParenExpr | | -| test.rs:188:28:188:29 | 28 | test.rs:188:23:188:29 | ... == ... | | -| test.rs:188:35:188:35 | c | test.rs:188:13:188:13 | d | | -| test.rs:189:9:189:9 | d | test.rs:187:61:190:5 | BlockExpr | | -| test.rs:192:5:195:5 | enter test_not_operator | test.rs:193:9:193:19 | LetStmt | | -| test.rs:192:5:195:5 | exit test_not_operator (normal) | test.rs:192:5:195:5 | exit test_not_operator | | -| test.rs:192:43:195:5 | BlockExpr | test.rs:192:5:195:5 | exit test_not_operator (normal) | | -| test.rs:193:9:193:19 | LetStmt | test.rs:193:18:193:18 | a | | -| test.rs:193:13:193:13 | d | test.rs:194:9:194:9 | d | match, no-match | -| test.rs:193:17:193:18 | ! ... | test.rs:193:13:193:13 | d | | -| test.rs:193:18:193:18 | a | test.rs:193:17:193:18 | ! ... | | -| test.rs:194:9:194:9 | d | test.rs:192:43:195:5 | BlockExpr | | -| test.rs:197:5:203:5 | enter test_if_and_operator | test.rs:198:12:198:22 | ... && ... | | -| test.rs:197:5:203:5 | exit test_if_and_operator (normal) | test.rs:197:5:203:5 | exit test_if_and_operator | | -| test.rs:197:63:203:5 | BlockExpr | test.rs:197:5:203:5 | exit test_if_and_operator (normal) | | -| test.rs:198:9:202:9 | IfExpr | test.rs:197:63:203:5 | BlockExpr | | -| test.rs:198:12:198:12 | a | test.rs:198:17:198:17 | b | true | -| test.rs:198:12:198:12 | a | test.rs:201:13:201:17 | false | false | -| test.rs:198:12:198:17 | ... && ... | test.rs:198:12:198:12 | a | | -| test.rs:198:12:198:22 | ... && ... | test.rs:198:12:198:17 | ... && ... | | -| test.rs:198:17:198:17 | b | test.rs:198:22:198:22 | c | true | -| test.rs:198:17:198:17 | b | test.rs:201:13:201:17 | false | false | -| test.rs:198:22:198:22 | c | test.rs:199:13:199:16 | true | true | -| test.rs:198:22:198:22 | c | test.rs:201:13:201:17 | false | false | -| test.rs:198:24:200:9 | BlockExpr | test.rs:198:9:202:9 | IfExpr | | -| test.rs:199:13:199:16 | true | test.rs:198:24:200:9 | BlockExpr | | -| test.rs:200:16:202:9 | BlockExpr | test.rs:198:9:202:9 | IfExpr | | -| test.rs:201:13:201:17 | false | test.rs:200:16:202:9 | BlockExpr | | -| test.rs:205:5:211:5 | enter test_if_or_operator | test.rs:206:12:206:22 | ... \|\| ... | | -| test.rs:205:5:211:5 | exit test_if_or_operator (normal) | test.rs:205:5:211:5 | exit test_if_or_operator | | -| test.rs:205:62:211:5 | BlockExpr | test.rs:205:5:211:5 | exit test_if_or_operator (normal) | | -| test.rs:206:9:210:9 | IfExpr | test.rs:205:62:211:5 | BlockExpr | | -| test.rs:206:12:206:12 | a | test.rs:206:17:206:17 | b | false | -| test.rs:206:12:206:12 | a | test.rs:207:13:207:16 | true | true | -| test.rs:206:12:206:17 | ... \|\| ... | test.rs:206:12:206:12 | a | | -| test.rs:206:12:206:22 | ... \|\| ... | test.rs:206:12:206:17 | ... \|\| ... | | -| test.rs:206:17:206:17 | b | test.rs:206:22:206:22 | c | false | -| test.rs:206:17:206:17 | b | test.rs:207:13:207:16 | true | true | -| test.rs:206:22:206:22 | c | test.rs:207:13:207:16 | true | true | -| test.rs:206:22:206:22 | c | test.rs:209:13:209:17 | false | false | -| test.rs:206:24:208:9 | BlockExpr | test.rs:206:9:210:9 | IfExpr | | -| test.rs:207:13:207:16 | true | test.rs:206:24:208:9 | BlockExpr | | -| test.rs:208:16:210:9 | BlockExpr | test.rs:206:9:210:9 | IfExpr | | -| test.rs:209:13:209:17 | false | test.rs:208:16:210:9 | BlockExpr | | -| test.rs:213:5:219:5 | enter test_if_not_operator | test.rs:214:13:214:13 | a | | -| test.rs:213:5:219:5 | exit test_if_not_operator (normal) | test.rs:213:5:219:5 | exit test_if_not_operator | | -| test.rs:213:46:219:5 | BlockExpr | test.rs:213:5:219:5 | exit test_if_not_operator (normal) | | -| test.rs:214:9:218:9 | IfExpr | test.rs:213:46:219:5 | BlockExpr | | -| test.rs:214:12:214:13 | ! ... | test.rs:215:13:215:16 | true | true | -| test.rs:214:12:214:13 | ! ... | test.rs:217:13:217:17 | false | false | -| test.rs:214:13:214:13 | a | test.rs:214:12:214:13 | ! ... | false, true | -| test.rs:214:15:216:9 | BlockExpr | test.rs:214:9:218:9 | IfExpr | | -| test.rs:215:13:215:16 | true | test.rs:214:15:216:9 | BlockExpr | | -| test.rs:216:16:218:9 | BlockExpr | test.rs:214:9:218:9 | IfExpr | | -| test.rs:217:13:217:17 | false | test.rs:216:16:218:9 | BlockExpr | | -| test.rs:222:1:228:1 | enter test_match | test.rs:223:11:223:21 | maybe_digit | | -| test.rs:222:1:228:1 | exit test_match (normal) | test.rs:222:1:228:1 | exit test_match | | -| test.rs:222:48:228:1 | BlockExpr | test.rs:222:1:228:1 | exit test_match (normal) | | -| test.rs:223:5:227:5 | MatchExpr | test.rs:222:48:228:1 | BlockExpr | | -| test.rs:223:11:223:21 | maybe_digit | test.rs:224:9:224:23 | TupleStructPat | | -| test.rs:224:9:224:23 | TupleStructPat | test.rs:224:28:224:28 | x | match | -| test.rs:224:9:224:23 | TupleStructPat | test.rs:225:9:225:23 | TupleStructPat | no-match | -| test.rs:224:28:224:28 | x | test.rs:224:32:224:33 | 10 | | -| test.rs:224:32:224:33 | 10 | test.rs:224:28:224:33 | ... < ... | | -| test.rs:225:9:225:23 | TupleStructPat | test.rs:225:28:225:28 | x | match | -| test.rs:225:9:225:23 | TupleStructPat | test.rs:226:9:226:20 | PathPat | no-match | -| test.rs:225:28:225:28 | x | test.rs:223:5:227:5 | MatchExpr | | -| test.rs:226:9:226:20 | PathPat | test.rs:226:25:226:25 | 5 | match | -| test.rs:226:25:226:25 | 5 | test.rs:223:5:227:5 | MatchExpr | | -| test.rs:231:5:236:5 | enter test_infinite_loop | test.rs:232:9:234:9 | ExprStmt | | -| test.rs:232:9:234:9 | ExprStmt | test.rs:233:13:233:13 | 1 | | -| test.rs:232:14:234:9 | BlockExpr | test.rs:233:13:233:13 | 1 | | -| test.rs:233:13:233:13 | 1 | test.rs:232:14:234:9 | BlockExpr | | -| test.rs:238:5:241:5 | enter test_let_match | test.rs:239:9:239:49 | LetStmt | | -| test.rs:238:5:241:5 | exit test_let_match (normal) | test.rs:238:5:241:5 | exit test_let_match | | -| test.rs:238:39:241:5 | BlockExpr | test.rs:238:5:241:5 | exit test_let_match (normal) | | -| test.rs:239:9:239:49 | LetStmt | test.rs:239:23:239:23 | a | | -| test.rs:239:13:239:19 | TupleStructPat | test.rs:239:32:239:46 | "Expected some" | no-match | -| test.rs:239:13:239:19 | TupleStructPat | test.rs:240:9:240:9 | n | match | -| test.rs:239:23:239:23 | a | test.rs:239:13:239:19 | TupleStructPat | | -| test.rs:239:32:239:46 | "Expected some" | test.rs:239:30:239:48 | BlockExpr | | -| test.rs:240:9:240:9 | n | test.rs:238:39:241:5 | BlockExpr | | -| test.rs:244:1:249:1 | enter dead_code | test.rs:245:5:247:5 | ExprStmt | | -| test.rs:244:1:249:1 | exit dead_code (normal) | test.rs:244:1:249:1 | exit dead_code | | -| test.rs:245:5:247:5 | ExprStmt | test.rs:245:9:245:12 | true | | -| test.rs:245:8:245:13 | ParenExpr | test.rs:246:9:246:17 | ExprStmt | true | -| test.rs:245:9:245:12 | true | test.rs:245:8:245:13 | ParenExpr | | -| test.rs:246:9:246:16 | ReturnExpr | test.rs:244:1:249:1 | exit dead_code (normal) | return | -| test.rs:246:9:246:17 | ExprStmt | test.rs:246:16:246:16 | 0 | | -| test.rs:246:16:246:16 | 0 | test.rs:246:9:246:16 | ReturnExpr | | -| test.rs:251:1:264:1 | enter labelled_block | test.rs:252:5:263:6 | LetStmt | | -| test.rs:251:1:264:1 | exit labelled_block (normal) | test.rs:251:1:264:1 | exit labelled_block | | -| test.rs:251:28:264:1 | BlockExpr | test.rs:251:1:264:1 | exit labelled_block (normal) | | -| test.rs:252:5:263:6 | LetStmt | test.rs:253:9:253:19 | ExprStmt | | -| test.rs:252:9:252:14 | result | test.rs:251:28:264:1 | BlockExpr | match, no-match | -| test.rs:252:18:263:5 | BlockExpr | test.rs:252:9:252:14 | result | | -| test.rs:253:9:253:16 | PathExpr | test.rs:253:9:253:18 | CallExpr | | -| test.rs:253:9:253:18 | CallExpr | test.rs:254:9:256:9 | ExprStmt | | -| test.rs:253:9:253:19 | ExprStmt | test.rs:253:9:253:16 | PathExpr | | -| test.rs:254:9:256:9 | ExprStmt | test.rs:254:12:254:28 | PathExpr | | -| test.rs:254:9:256:9 | IfExpr | test.rs:257:9:257:24 | ExprStmt | | -| test.rs:254:12:254:28 | PathExpr | test.rs:254:12:254:30 | CallExpr | | -| test.rs:254:12:254:30 | CallExpr | test.rs:254:9:256:9 | IfExpr | false | -| test.rs:254:12:254:30 | CallExpr | test.rs:255:13:255:27 | ExprStmt | true | -| test.rs:255:13:255:26 | BreakExpr | test.rs:251:1:264:1 | exit labelled_block (normal) | break('block) | -| test.rs:255:13:255:27 | ExprStmt | test.rs:255:26:255:26 | 1 | | -| test.rs:255:26:255:26 | 1 | test.rs:255:13:255:26 | BreakExpr | | -| test.rs:257:9:257:21 | PathExpr | test.rs:257:9:257:23 | CallExpr | | -| test.rs:257:9:257:23 | CallExpr | test.rs:258:9:260:9 | ExprStmt | | -| test.rs:257:9:257:24 | ExprStmt | test.rs:257:9:257:21 | PathExpr | | -| test.rs:258:9:260:9 | ExprStmt | test.rs:258:12:258:28 | PathExpr | | -| test.rs:258:9:260:9 | IfExpr | test.rs:261:9:261:24 | ExprStmt | | -| test.rs:258:12:258:28 | PathExpr | test.rs:258:12:258:30 | CallExpr | | -| test.rs:258:12:258:30 | CallExpr | test.rs:258:9:260:9 | IfExpr | false | -| test.rs:258:12:258:30 | CallExpr | test.rs:259:13:259:27 | ExprStmt | true | -| test.rs:259:13:259:26 | BreakExpr | test.rs:251:1:264:1 | exit labelled_block (normal) | break('block) | -| test.rs:259:13:259:27 | ExprStmt | test.rs:259:26:259:26 | 2 | | -| test.rs:259:26:259:26 | 2 | test.rs:259:13:259:26 | BreakExpr | | -| test.rs:261:9:261:21 | PathExpr | test.rs:261:9:261:23 | CallExpr | | -| test.rs:261:9:261:23 | CallExpr | test.rs:262:9:262:9 | 3 | | -| test.rs:261:9:261:24 | ExprStmt | test.rs:261:9:261:21 | PathExpr | | -| test.rs:262:9:262:9 | 3 | test.rs:252:18:263:5 | BlockExpr | | +| test.rs:75:1:78:1 | enter test_nested_function | test.rs:76:5:76:28 | LetStmt | | +| test.rs:75:1:78:1 | exit test_nested_function (normal) | test.rs:75:1:78:1 | exit test_nested_function | | +| test.rs:75:40:78:1 | BlockExpr | test.rs:75:1:78:1 | exit test_nested_function (normal) | | +| test.rs:76:5:76:28 | LetStmt | test.rs:76:19:76:27 | ClosureExpr | | +| test.rs:76:9:76:15 | add_one | test.rs:77:5:77:11 | add_one | match, no-match | +| test.rs:76:19:76:27 | ClosureExpr | test.rs:76:9:76:15 | add_one | | +| test.rs:76:19:76:27 | enter ClosureExpr | test.rs:76:23:76:23 | i | | +| test.rs:76:19:76:27 | exit ClosureExpr (normal) | test.rs:76:19:76:27 | exit ClosureExpr | | +| test.rs:76:23:76:23 | i | test.rs:76:27:76:27 | 1 | | +| test.rs:76:23:76:27 | ... + ... | test.rs:76:19:76:27 | exit ClosureExpr (normal) | | +| test.rs:76:27:76:27 | 1 | test.rs:76:23:76:27 | ... + ... | | +| test.rs:77:5:77:11 | add_one | test.rs:77:13:77:19 | add_one | | +| test.rs:77:5:77:23 | CallExpr | test.rs:75:40:78:1 | BlockExpr | | +| test.rs:77:13:77:19 | add_one | test.rs:77:21:77:21 | n | | +| test.rs:77:13:77:22 | CallExpr | test.rs:77:5:77:23 | CallExpr | | +| test.rs:77:21:77:21 | n | test.rs:77:13:77:22 | CallExpr | | +| test.rs:82:5:88:5 | enter test_if_else | test.rs:83:12:83:12 | n | | +| test.rs:82:5:88:5 | exit test_if_else (normal) | test.rs:82:5:88:5 | exit test_if_else | | +| test.rs:82:36:88:5 | BlockExpr | test.rs:82:5:88:5 | exit test_if_else (normal) | | +| test.rs:83:9:87:9 | IfExpr | test.rs:82:36:88:5 | BlockExpr | | +| test.rs:83:12:83:12 | n | test.rs:83:17:83:17 | 0 | | +| test.rs:83:12:83:17 | ... <= ... | test.rs:84:13:84:13 | 0 | true | +| test.rs:83:12:83:17 | ... <= ... | test.rs:86:13:86:13 | n | false | +| test.rs:83:17:83:17 | 0 | test.rs:83:12:83:17 | ... <= ... | | +| test.rs:83:19:85:9 | BlockExpr | test.rs:83:9:87:9 | IfExpr | | +| test.rs:84:13:84:13 | 0 | test.rs:83:19:85:9 | BlockExpr | | +| test.rs:85:16:87:9 | BlockExpr | test.rs:83:9:87:9 | IfExpr | | +| test.rs:86:13:86:13 | n | test.rs:86:17:86:17 | 1 | | +| test.rs:86:13:86:17 | ... - ... | test.rs:85:16:87:9 | BlockExpr | | +| test.rs:86:17:86:17 | 1 | test.rs:86:13:86:17 | ... - ... | | +| test.rs:90:5:96:5 | enter test_if_let_else | test.rs:91:12:91:26 | LetExpr | | +| test.rs:90:5:96:5 | exit test_if_let_else (normal) | test.rs:90:5:96:5 | exit test_if_let_else | | +| test.rs:90:48:96:5 | BlockExpr | test.rs:90:5:96:5 | exit test_if_let_else (normal) | | +| test.rs:91:9:95:9 | IfExpr | test.rs:90:48:96:5 | BlockExpr | | +| test.rs:91:12:91:26 | LetExpr | test.rs:91:16:91:22 | TupleStructPat | | +| test.rs:91:16:91:22 | TupleStructPat | test.rs:92:13:92:13 | n | match | +| test.rs:91:16:91:22 | TupleStructPat | test.rs:94:13:94:13 | 0 | no-match | +| test.rs:91:28:93:9 | BlockExpr | test.rs:91:9:95:9 | IfExpr | | +| test.rs:92:13:92:13 | n | test.rs:91:28:93:9 | BlockExpr | | +| test.rs:93:16:95:9 | BlockExpr | test.rs:91:9:95:9 | IfExpr | | +| test.rs:94:13:94:13 | 0 | test.rs:93:16:95:9 | BlockExpr | | +| test.rs:98:5:103:5 | enter test_if_let | test.rs:99:9:101:9 | ExprStmt | | +| test.rs:98:5:103:5 | exit test_if_let (normal) | test.rs:98:5:103:5 | exit test_if_let | | +| test.rs:98:43:103:5 | BlockExpr | test.rs:98:5:103:5 | exit test_if_let (normal) | | +| test.rs:99:9:101:9 | ExprStmt | test.rs:99:12:99:26 | LetExpr | | +| test.rs:99:9:101:9 | IfExpr | test.rs:102:9:102:9 | 0 | | +| test.rs:99:12:99:26 | LetExpr | test.rs:99:16:99:22 | TupleStructPat | | +| test.rs:99:16:99:22 | TupleStructPat | test.rs:99:9:101:9 | IfExpr | no-match | +| test.rs:99:16:99:22 | TupleStructPat | test.rs:100:13:100:13 | n | match | +| test.rs:99:28:101:9 | BlockExpr | test.rs:99:9:101:9 | IfExpr | | +| test.rs:100:13:100:13 | n | test.rs:99:28:101:9 | BlockExpr | | +| test.rs:102:9:102:9 | 0 | test.rs:98:43:103:5 | BlockExpr | | +| test.rs:105:5:111:5 | enter test_nested_if | test.rs:106:16:106:16 | PathExpr | | +| test.rs:105:5:111:5 | exit test_nested_if (normal) | test.rs:105:5:111:5 | exit test_nested_if | | +| test.rs:105:38:111:5 | BlockExpr | test.rs:105:5:111:5 | exit test_nested_if (normal) | | +| test.rs:106:9:110:9 | IfExpr | test.rs:105:38:111:5 | BlockExpr | | +| test.rs:106:12:106:49 | ParenExpr | test.rs:107:13:107:13 | 1 | true | +| test.rs:106:12:106:49 | ParenExpr | test.rs:109:13:109:13 | 0 | false | +| test.rs:106:13:106:48 | IfExpr | test.rs:106:12:106:49 | ParenExpr | | +| test.rs:106:16:106:16 | PathExpr | test.rs:106:20:106:20 | 0 | | +| test.rs:106:16:106:20 | ... < ... | test.rs:106:24:106:24 | a | true | +| test.rs:106:16:106:20 | ... < ... | test.rs:106:41:106:41 | a | false | +| test.rs:106:20:106:20 | 0 | test.rs:106:16:106:20 | ... < ... | | +| test.rs:106:22:106:32 | BlockExpr | test.rs:106:13:106:48 | IfExpr | | +| test.rs:106:24:106:24 | a | test.rs:106:29:106:30 | 10 | | +| test.rs:106:24:106:30 | ... < ... | test.rs:106:22:106:32 | BlockExpr | | +| test.rs:106:28:106:30 | - ... | test.rs:106:24:106:30 | ... < ... | | +| test.rs:106:29:106:30 | 10 | test.rs:106:28:106:30 | - ... | | +| test.rs:106:39:106:48 | BlockExpr | test.rs:106:13:106:48 | IfExpr | | +| test.rs:106:41:106:41 | a | test.rs:106:45:106:46 | 10 | | +| test.rs:106:41:106:46 | ... > ... | test.rs:106:39:106:48 | BlockExpr | | +| test.rs:106:45:106:46 | 10 | test.rs:106:41:106:46 | ... > ... | | +| test.rs:106:51:108:9 | BlockExpr | test.rs:106:9:110:9 | IfExpr | | +| test.rs:107:13:107:13 | 1 | test.rs:106:51:108:9 | BlockExpr | | +| test.rs:108:16:110:9 | BlockExpr | test.rs:106:9:110:9 | IfExpr | | +| test.rs:109:13:109:13 | 0 | test.rs:108:16:110:9 | BlockExpr | | +| test.rs:113:5:122:5 | enter test_nested_if_match | test.rs:114:19:114:19 | a | | +| test.rs:113:5:122:5 | exit test_nested_if_match (normal) | test.rs:113:5:122:5 | exit test_nested_if_match | | +| test.rs:113:44:122:5 | BlockExpr | test.rs:113:5:122:5 | exit test_nested_if_match (normal) | | +| test.rs:114:9:121:9 | IfExpr | test.rs:113:44:122:5 | BlockExpr | | +| test.rs:114:12:117:10 | ParenExpr | test.rs:118:13:118:13 | 1 | true | +| test.rs:114:12:117:10 | ParenExpr | test.rs:120:13:120:13 | 0 | false | +| test.rs:114:13:117:9 | MatchExpr | test.rs:114:12:117:10 | ParenExpr | | +| test.rs:114:19:114:19 | a | test.rs:115:13:115:13 | LiteralPat | | +| test.rs:115:13:115:13 | LiteralPat | test.rs:115:18:115:21 | true | match | +| test.rs:115:13:115:13 | LiteralPat | test.rs:116:13:116:13 | WildcardPat | no-match | +| test.rs:115:18:115:21 | true | test.rs:114:13:117:9 | MatchExpr | | +| test.rs:116:13:116:13 | WildcardPat | test.rs:116:18:116:22 | false | match | +| test.rs:116:18:116:22 | false | test.rs:114:13:117:9 | MatchExpr | | +| test.rs:117:12:119:9 | BlockExpr | test.rs:114:9:121:9 | IfExpr | | +| test.rs:118:13:118:13 | 1 | test.rs:117:12:119:9 | BlockExpr | | +| test.rs:119:16:121:9 | BlockExpr | test.rs:114:9:121:9 | IfExpr | | +| test.rs:120:13:120:13 | 0 | test.rs:119:16:121:9 | BlockExpr | | +| test.rs:124:5:133:5 | enter test_nested_if_block | test.rs:126:13:126:15 | ExprStmt | | +| test.rs:124:5:133:5 | exit test_nested_if_block (normal) | test.rs:124:5:133:5 | exit test_nested_if_block | | +| test.rs:124:44:133:5 | BlockExpr | test.rs:124:5:133:5 | exit test_nested_if_block (normal) | | +| test.rs:125:9:132:9 | IfExpr | test.rs:124:44:133:5 | BlockExpr | | +| test.rs:125:12:128:9 | BlockExpr | test.rs:129:13:129:13 | 1 | true | +| test.rs:125:12:128:9 | BlockExpr | test.rs:131:13:131:13 | 0 | false | +| test.rs:126:13:126:14 | TupleExpr | test.rs:127:13:127:13 | a | | +| test.rs:126:13:126:15 | ExprStmt | test.rs:126:13:126:14 | TupleExpr | | +| test.rs:127:13:127:13 | a | test.rs:127:17:127:17 | 0 | | +| test.rs:127:13:127:17 | ... > ... | test.rs:125:12:128:9 | BlockExpr | false, true | +| test.rs:127:17:127:17 | 0 | test.rs:127:13:127:17 | ... > ... | | +| test.rs:128:11:130:9 | BlockExpr | test.rs:125:9:132:9 | IfExpr | | +| test.rs:129:13:129:13 | 1 | test.rs:128:11:130:9 | BlockExpr | | +| test.rs:130:16:132:9 | BlockExpr | test.rs:125:9:132:9 | IfExpr | | +| test.rs:131:13:131:13 | 0 | test.rs:130:16:132:9 | BlockExpr | | +| test.rs:135:5:142:5 | enter test_if_assignment | test.rs:136:9:136:26 | LetStmt | | +| test.rs:135:5:142:5 | exit test_if_assignment (normal) | test.rs:135:5:142:5 | exit test_if_assignment | | +| test.rs:135:42:142:5 | BlockExpr | test.rs:135:5:142:5 | exit test_if_assignment (normal) | | +| test.rs:136:9:136:26 | LetStmt | test.rs:136:21:136:25 | false | | +| test.rs:136:13:136:17 | x | test.rs:137:12:137:12 | x | match, no-match | +| test.rs:136:21:136:25 | false | test.rs:136:13:136:17 | x | | +| test.rs:137:9:141:9 | IfExpr | test.rs:135:42:142:5 | BlockExpr | | +| test.rs:137:12:137:12 | x | test.rs:137:16:137:19 | true | | +| test.rs:137:12:137:19 | ... = ... | test.rs:138:13:138:13 | 1 | true | +| test.rs:137:12:137:19 | ... = ... | test.rs:140:13:140:13 | 0 | false | +| test.rs:137:16:137:19 | true | test.rs:137:12:137:19 | ... = ... | | +| test.rs:137:21:139:9 | BlockExpr | test.rs:137:9:141:9 | IfExpr | | +| test.rs:138:13:138:13 | 1 | test.rs:137:21:139:9 | BlockExpr | | +| test.rs:139:16:141:9 | BlockExpr | test.rs:137:9:141:9 | IfExpr | | +| test.rs:140:13:140:13 | 0 | test.rs:139:16:141:9 | BlockExpr | | +| test.rs:144:5:155:5 | enter test_if_loop1 | test.rs:146:13:148:14 | ExprStmt | | +| test.rs:144:5:155:5 | exit test_if_loop1 (normal) | test.rs:144:5:155:5 | exit test_if_loop1 | | +| test.rs:144:37:155:5 | BlockExpr | test.rs:144:5:155:5 | exit test_if_loop1 (normal) | | +| test.rs:145:9:154:9 | IfExpr | test.rs:144:37:155:5 | BlockExpr | | +| test.rs:145:12:150:10 | ParenExpr | test.rs:151:13:151:13 | 1 | true | +| test.rs:145:12:150:10 | ParenExpr | test.rs:153:13:153:13 | 0 | false | +| test.rs:145:13:150:9 | LoopExpr | test.rs:145:12:150:10 | ParenExpr | | +| test.rs:145:18:150:9 | BlockExpr | test.rs:146:13:148:14 | ExprStmt | | +| test.rs:146:13:148:13 | IfExpr | test.rs:149:13:149:19 | ExprStmt | | +| test.rs:146:13:148:14 | ExprStmt | test.rs:146:16:146:16 | a | | +| test.rs:146:16:146:16 | a | test.rs:146:20:146:20 | 0 | | +| test.rs:146:16:146:20 | ... > ... | test.rs:146:13:148:13 | IfExpr | false | +| test.rs:146:16:146:20 | ... > ... | test.rs:147:17:147:29 | ExprStmt | true | +| test.rs:146:20:146:20 | 0 | test.rs:146:16:146:20 | ... > ... | | +| test.rs:147:17:147:28 | BreakExpr | test.rs:145:13:150:9 | LoopExpr | break | +| test.rs:147:17:147:29 | ExprStmt | test.rs:147:23:147:23 | a | | +| test.rs:147:23:147:23 | a | test.rs:147:27:147:28 | 10 | | +| test.rs:147:23:147:28 | ... > ... | test.rs:147:17:147:28 | BreakExpr | | +| test.rs:147:27:147:28 | 10 | test.rs:147:23:147:28 | ... > ... | | +| test.rs:149:13:149:13 | a | test.rs:149:17:149:18 | 10 | | +| test.rs:149:13:149:18 | ... < ... | test.rs:145:18:150:9 | BlockExpr | | +| test.rs:149:13:149:19 | ExprStmt | test.rs:149:13:149:13 | a | | +| test.rs:149:17:149:18 | 10 | test.rs:149:13:149:18 | ... < ... | | +| test.rs:150:12:152:9 | BlockExpr | test.rs:145:9:154:9 | IfExpr | | +| test.rs:151:13:151:13 | 1 | test.rs:150:12:152:9 | BlockExpr | | +| test.rs:152:16:154:9 | BlockExpr | test.rs:145:9:154:9 | IfExpr | | +| test.rs:153:13:153:13 | 0 | test.rs:152:16:154:9 | BlockExpr | | +| test.rs:157:5:168:5 | enter test_if_loop2 | test.rs:159:13:161:14 | ExprStmt | | +| test.rs:157:5:168:5 | exit test_if_loop2 (normal) | test.rs:157:5:168:5 | exit test_if_loop2 | | +| test.rs:157:37:168:5 | BlockExpr | test.rs:157:5:168:5 | exit test_if_loop2 (normal) | | +| test.rs:158:9:167:9 | IfExpr | test.rs:157:37:168:5 | BlockExpr | | +| test.rs:158:12:163:10 | ParenExpr | test.rs:164:13:164:13 | 1 | true | +| test.rs:158:12:163:10 | ParenExpr | test.rs:166:13:166:13 | 0 | false | +| test.rs:158:13:163:9 | LoopExpr | test.rs:158:12:163:10 | ParenExpr | | +| test.rs:158:26:163:9 | BlockExpr | test.rs:159:13:161:14 | ExprStmt | | +| test.rs:159:13:161:13 | IfExpr | test.rs:162:13:162:19 | ExprStmt | | +| test.rs:159:13:161:14 | ExprStmt | test.rs:159:16:159:16 | a | | +| test.rs:159:16:159:16 | a | test.rs:159:20:159:20 | 0 | | +| test.rs:159:16:159:20 | ... > ... | test.rs:159:13:161:13 | IfExpr | false | +| test.rs:159:16:159:20 | ... > ... | test.rs:160:17:160:36 | ExprStmt | true | +| test.rs:159:20:159:20 | 0 | test.rs:159:16:159:20 | ... > ... | | +| test.rs:160:17:160:35 | BreakExpr | test.rs:158:13:163:9 | LoopExpr | break('label) | +| test.rs:160:17:160:36 | ExprStmt | test.rs:160:30:160:30 | a | | +| test.rs:160:30:160:30 | a | test.rs:160:34:160:35 | 10 | | +| test.rs:160:30:160:35 | ... > ... | test.rs:160:17:160:35 | BreakExpr | | +| test.rs:160:34:160:35 | 10 | test.rs:160:30:160:35 | ... > ... | | +| test.rs:162:13:162:13 | a | test.rs:162:17:162:18 | 10 | | +| test.rs:162:13:162:18 | ... < ... | test.rs:158:26:163:9 | BlockExpr | | +| test.rs:162:13:162:19 | ExprStmt | test.rs:162:13:162:13 | a | | +| test.rs:162:17:162:18 | 10 | test.rs:162:13:162:18 | ... < ... | | +| test.rs:163:12:165:9 | BlockExpr | test.rs:158:9:167:9 | IfExpr | | +| test.rs:164:13:164:13 | 1 | test.rs:163:12:165:9 | BlockExpr | | +| test.rs:165:16:167:9 | BlockExpr | test.rs:158:9:167:9 | IfExpr | | +| test.rs:166:13:166:13 | 0 | test.rs:165:16:167:9 | BlockExpr | | +| test.rs:170:5:178:5 | enter test_labelled_block | test.rs:172:13:172:31 | ExprStmt | | +| test.rs:170:5:178:5 | exit test_labelled_block (normal) | test.rs:170:5:178:5 | exit test_labelled_block | | +| test.rs:172:13:172:30 | BreakExpr | test.rs:170:5:178:5 | exit test_labelled_block (normal) | break('block) | +| test.rs:172:13:172:31 | ExprStmt | test.rs:172:26:172:26 | a | | +| test.rs:172:26:172:26 | a | test.rs:172:30:172:30 | 0 | | +| test.rs:172:26:172:30 | ... > ... | test.rs:172:13:172:30 | BreakExpr | | +| test.rs:172:30:172:30 | 0 | test.rs:172:26:172:30 | ... > ... | | +| test.rs:183:5:186:5 | enter test_and_operator | test.rs:184:9:184:28 | LetStmt | | +| test.rs:183:5:186:5 | exit test_and_operator (normal) | test.rs:183:5:186:5 | exit test_and_operator | | +| test.rs:183:61:186:5 | BlockExpr | test.rs:183:5:186:5 | exit test_and_operator (normal) | | +| test.rs:184:9:184:28 | LetStmt | test.rs:184:17:184:27 | ... && ... | | +| test.rs:184:13:184:13 | d | test.rs:185:9:185:9 | d | match, no-match | +| test.rs:184:17:184:17 | a | test.rs:184:13:184:13 | d | false | +| test.rs:184:17:184:17 | a | test.rs:184:22:184:22 | b | true | +| test.rs:184:17:184:22 | ... && ... | test.rs:184:17:184:17 | a | | +| test.rs:184:17:184:27 | ... && ... | test.rs:184:17:184:22 | ... && ... | | +| test.rs:184:22:184:22 | b | test.rs:184:13:184:13 | d | false | +| test.rs:184:22:184:22 | b | test.rs:184:27:184:27 | c | true | +| test.rs:184:27:184:27 | c | test.rs:184:13:184:13 | d | | +| test.rs:185:9:185:9 | d | test.rs:183:61:186:5 | BlockExpr | | +| test.rs:188:5:191:5 | enter test_or_operator | test.rs:189:9:189:28 | LetStmt | | +| test.rs:188:5:191:5 | exit test_or_operator (normal) | test.rs:188:5:191:5 | exit test_or_operator | | +| test.rs:188:60:191:5 | BlockExpr | test.rs:188:5:191:5 | exit test_or_operator (normal) | | +| test.rs:189:9:189:28 | LetStmt | test.rs:189:17:189:27 | ... \|\| ... | | +| test.rs:189:13:189:13 | d | test.rs:190:9:190:9 | d | match, no-match | +| test.rs:189:17:189:17 | a | test.rs:189:13:189:13 | d | true | +| test.rs:189:17:189:17 | a | test.rs:189:22:189:22 | b | false | +| test.rs:189:17:189:22 | ... \|\| ... | test.rs:189:17:189:17 | a | | +| test.rs:189:17:189:27 | ... \|\| ... | test.rs:189:17:189:22 | ... \|\| ... | | +| test.rs:189:22:189:22 | b | test.rs:189:13:189:13 | d | true | +| test.rs:189:22:189:22 | b | test.rs:189:27:189:27 | c | false | +| test.rs:189:27:189:27 | c | test.rs:189:13:189:13 | d | | +| test.rs:190:9:190:9 | d | test.rs:188:60:191:5 | BlockExpr | | +| test.rs:193:5:196:5 | enter test_or_operator_2 | test.rs:194:9:194:36 | LetStmt | | +| test.rs:193:5:196:5 | exit test_or_operator_2 (normal) | test.rs:193:5:196:5 | exit test_or_operator_2 | | +| test.rs:193:61:196:5 | BlockExpr | test.rs:193:5:196:5 | exit test_or_operator_2 (normal) | | +| test.rs:194:9:194:36 | LetStmt | test.rs:194:17:194:35 | ... \|\| ... | | +| test.rs:194:13:194:13 | d | test.rs:195:9:195:9 | d | match, no-match | +| test.rs:194:17:194:17 | a | test.rs:194:13:194:13 | d | true | +| test.rs:194:17:194:17 | a | test.rs:194:23:194:23 | b | false | +| test.rs:194:17:194:30 | ... \|\| ... | test.rs:194:17:194:17 | a | | +| test.rs:194:17:194:35 | ... \|\| ... | test.rs:194:17:194:30 | ... \|\| ... | | +| test.rs:194:22:194:30 | ParenExpr | test.rs:194:13:194:13 | d | true | +| test.rs:194:22:194:30 | ParenExpr | test.rs:194:35:194:35 | c | false | +| test.rs:194:23:194:23 | b | test.rs:194:28:194:29 | 28 | | +| test.rs:194:23:194:29 | ... == ... | test.rs:194:22:194:30 | ParenExpr | | +| test.rs:194:28:194:29 | 28 | test.rs:194:23:194:29 | ... == ... | | +| test.rs:194:35:194:35 | c | test.rs:194:13:194:13 | d | | +| test.rs:195:9:195:9 | d | test.rs:193:61:196:5 | BlockExpr | | +| test.rs:198:5:201:5 | enter test_not_operator | test.rs:199:9:199:19 | LetStmt | | +| test.rs:198:5:201:5 | exit test_not_operator (normal) | test.rs:198:5:201:5 | exit test_not_operator | | +| test.rs:198:43:201:5 | BlockExpr | test.rs:198:5:201:5 | exit test_not_operator (normal) | | +| test.rs:199:9:199:19 | LetStmt | test.rs:199:18:199:18 | a | | +| test.rs:199:13:199:13 | d | test.rs:200:9:200:9 | d | match, no-match | +| test.rs:199:17:199:18 | ! ... | test.rs:199:13:199:13 | d | | +| test.rs:199:18:199:18 | a | test.rs:199:17:199:18 | ! ... | | +| test.rs:200:9:200:9 | d | test.rs:198:43:201:5 | BlockExpr | | +| test.rs:203:5:209:5 | enter test_if_and_operator | test.rs:204:12:204:22 | ... && ... | | +| test.rs:203:5:209:5 | exit test_if_and_operator (normal) | test.rs:203:5:209:5 | exit test_if_and_operator | | +| test.rs:203:63:209:5 | BlockExpr | test.rs:203:5:209:5 | exit test_if_and_operator (normal) | | +| test.rs:204:9:208:9 | IfExpr | test.rs:203:63:209:5 | BlockExpr | | +| test.rs:204:12:204:12 | a | test.rs:204:17:204:17 | b | true | +| test.rs:204:12:204:12 | a | test.rs:207:13:207:17 | false | false | +| test.rs:204:12:204:17 | ... && ... | test.rs:204:12:204:12 | a | | +| test.rs:204:12:204:22 | ... && ... | test.rs:204:12:204:17 | ... && ... | | +| test.rs:204:17:204:17 | b | test.rs:204:22:204:22 | c | true | +| test.rs:204:17:204:17 | b | test.rs:207:13:207:17 | false | false | +| test.rs:204:22:204:22 | c | test.rs:205:13:205:16 | true | true | +| test.rs:204:22:204:22 | c | test.rs:207:13:207:17 | false | false | +| test.rs:204:24:206:9 | BlockExpr | test.rs:204:9:208:9 | IfExpr | | +| test.rs:205:13:205:16 | true | test.rs:204:24:206:9 | BlockExpr | | +| test.rs:206:16:208:9 | BlockExpr | test.rs:204:9:208:9 | IfExpr | | +| test.rs:207:13:207:17 | false | test.rs:206:16:208:9 | BlockExpr | | +| test.rs:211:5:217:5 | enter test_if_or_operator | test.rs:212:12:212:22 | ... \|\| ... | | +| test.rs:211:5:217:5 | exit test_if_or_operator (normal) | test.rs:211:5:217:5 | exit test_if_or_operator | | +| test.rs:211:62:217:5 | BlockExpr | test.rs:211:5:217:5 | exit test_if_or_operator (normal) | | +| test.rs:212:9:216:9 | IfExpr | test.rs:211:62:217:5 | BlockExpr | | +| test.rs:212:12:212:12 | a | test.rs:212:17:212:17 | b | false | +| test.rs:212:12:212:12 | a | test.rs:213:13:213:16 | true | true | +| test.rs:212:12:212:17 | ... \|\| ... | test.rs:212:12:212:12 | a | | +| test.rs:212:12:212:22 | ... \|\| ... | test.rs:212:12:212:17 | ... \|\| ... | | +| test.rs:212:17:212:17 | b | test.rs:212:22:212:22 | c | false | +| test.rs:212:17:212:17 | b | test.rs:213:13:213:16 | true | true | +| test.rs:212:22:212:22 | c | test.rs:213:13:213:16 | true | true | +| test.rs:212:22:212:22 | c | test.rs:215:13:215:17 | false | false | +| test.rs:212:24:214:9 | BlockExpr | test.rs:212:9:216:9 | IfExpr | | +| test.rs:213:13:213:16 | true | test.rs:212:24:214:9 | BlockExpr | | +| test.rs:214:16:216:9 | BlockExpr | test.rs:212:9:216:9 | IfExpr | | +| test.rs:215:13:215:17 | false | test.rs:214:16:216:9 | BlockExpr | | +| test.rs:219:5:225:5 | enter test_if_not_operator | test.rs:220:13:220:13 | a | | +| test.rs:219:5:225:5 | exit test_if_not_operator (normal) | test.rs:219:5:225:5 | exit test_if_not_operator | | +| test.rs:219:46:225:5 | BlockExpr | test.rs:219:5:225:5 | exit test_if_not_operator (normal) | | +| test.rs:220:9:224:9 | IfExpr | test.rs:219:46:225:5 | BlockExpr | | +| test.rs:220:12:220:13 | ! ... | test.rs:221:13:221:16 | true | true | +| test.rs:220:12:220:13 | ! ... | test.rs:223:13:223:17 | false | false | +| test.rs:220:13:220:13 | a | test.rs:220:12:220:13 | ! ... | false, true | +| test.rs:220:15:222:9 | BlockExpr | test.rs:220:9:224:9 | IfExpr | | +| test.rs:221:13:221:16 | true | test.rs:220:15:222:9 | BlockExpr | | +| test.rs:222:16:224:9 | BlockExpr | test.rs:220:9:224:9 | IfExpr | | +| test.rs:223:13:223:17 | false | test.rs:222:16:224:9 | BlockExpr | | +| test.rs:228:1:234:1 | enter test_match | test.rs:229:11:229:21 | maybe_digit | | +| test.rs:228:1:234:1 | exit test_match (normal) | test.rs:228:1:234:1 | exit test_match | | +| test.rs:228:48:234:1 | BlockExpr | test.rs:228:1:234:1 | exit test_match (normal) | | +| test.rs:229:5:233:5 | MatchExpr | test.rs:228:48:234:1 | BlockExpr | | +| test.rs:229:11:229:21 | maybe_digit | test.rs:230:9:230:23 | TupleStructPat | | +| test.rs:230:9:230:23 | TupleStructPat | test.rs:230:28:230:28 | x | match | +| test.rs:230:9:230:23 | TupleStructPat | test.rs:231:9:231:23 | TupleStructPat | no-match | +| test.rs:230:28:230:28 | x | test.rs:230:32:230:33 | 10 | | +| test.rs:230:32:230:33 | 10 | test.rs:230:28:230:33 | ... < ... | | +| test.rs:231:9:231:23 | TupleStructPat | test.rs:231:28:231:28 | x | match | +| test.rs:231:9:231:23 | TupleStructPat | test.rs:232:9:232:20 | PathPat | no-match | +| test.rs:231:28:231:28 | x | test.rs:229:5:233:5 | MatchExpr | | +| test.rs:232:9:232:20 | PathPat | test.rs:232:25:232:25 | 5 | match | +| test.rs:232:25:232:25 | 5 | test.rs:229:5:233:5 | MatchExpr | | +| test.rs:237:5:242:5 | enter test_infinite_loop | test.rs:238:9:240:9 | ExprStmt | | +| test.rs:238:9:240:9 | ExprStmt | test.rs:239:13:239:13 | 1 | | +| test.rs:238:14:240:9 | BlockExpr | test.rs:239:13:239:13 | 1 | | +| test.rs:239:13:239:13 | 1 | test.rs:238:14:240:9 | BlockExpr | | +| test.rs:244:5:247:5 | enter test_let_match | test.rs:245:9:245:49 | LetStmt | | +| test.rs:244:5:247:5 | exit test_let_match (normal) | test.rs:244:5:247:5 | exit test_let_match | | +| test.rs:244:39:247:5 | BlockExpr | test.rs:244:5:247:5 | exit test_let_match (normal) | | +| test.rs:245:9:245:49 | LetStmt | test.rs:245:23:245:23 | a | | +| test.rs:245:13:245:19 | TupleStructPat | test.rs:245:32:245:46 | "Expected some" | no-match | +| test.rs:245:13:245:19 | TupleStructPat | test.rs:246:9:246:9 | n | match | +| test.rs:245:23:245:23 | a | test.rs:245:13:245:19 | TupleStructPat | | +| test.rs:245:32:245:46 | "Expected some" | test.rs:245:30:245:48 | BlockExpr | | +| test.rs:246:9:246:9 | n | test.rs:244:39:247:5 | BlockExpr | | +| test.rs:250:1:255:1 | enter dead_code | test.rs:251:5:253:5 | ExprStmt | | +| test.rs:250:1:255:1 | exit dead_code (normal) | test.rs:250:1:255:1 | exit dead_code | | +| test.rs:251:5:253:5 | ExprStmt | test.rs:251:9:251:12 | true | | +| test.rs:251:8:251:13 | ParenExpr | test.rs:252:9:252:17 | ExprStmt | true | +| test.rs:251:9:251:12 | true | test.rs:251:8:251:13 | ParenExpr | | +| test.rs:252:9:252:16 | ReturnExpr | test.rs:250:1:255:1 | exit dead_code (normal) | return | +| test.rs:252:9:252:17 | ExprStmt | test.rs:252:16:252:16 | 0 | | +| test.rs:252:16:252:16 | 0 | test.rs:252:9:252:16 | ReturnExpr | | +| test.rs:257:1:270:1 | enter labelled_block | test.rs:258:5:269:6 | LetStmt | | +| test.rs:257:1:270:1 | exit labelled_block (normal) | test.rs:257:1:270:1 | exit labelled_block | | +| test.rs:257:28:270:1 | BlockExpr | test.rs:257:1:270:1 | exit labelled_block (normal) | | +| test.rs:258:5:269:6 | LetStmt | test.rs:259:9:259:19 | ExprStmt | | +| test.rs:258:9:258:14 | result | test.rs:257:28:270:1 | BlockExpr | match, no-match | +| test.rs:258:18:269:5 | BlockExpr | test.rs:258:9:258:14 | result | | +| test.rs:259:9:259:16 | PathExpr | test.rs:259:9:259:18 | CallExpr | | +| test.rs:259:9:259:18 | CallExpr | test.rs:260:9:262:9 | ExprStmt | | +| test.rs:259:9:259:19 | ExprStmt | test.rs:259:9:259:16 | PathExpr | | +| test.rs:260:9:262:9 | ExprStmt | test.rs:260:12:260:28 | PathExpr | | +| test.rs:260:9:262:9 | IfExpr | test.rs:263:9:263:24 | ExprStmt | | +| test.rs:260:12:260:28 | PathExpr | test.rs:260:12:260:30 | CallExpr | | +| test.rs:260:12:260:30 | CallExpr | test.rs:260:9:262:9 | IfExpr | false | +| test.rs:260:12:260:30 | CallExpr | test.rs:261:13:261:27 | ExprStmt | true | +| test.rs:261:13:261:26 | BreakExpr | test.rs:257:1:270:1 | exit labelled_block (normal) | break('block) | +| test.rs:261:13:261:27 | ExprStmt | test.rs:261:26:261:26 | 1 | | +| test.rs:261:26:261:26 | 1 | test.rs:261:13:261:26 | BreakExpr | | +| test.rs:263:9:263:21 | PathExpr | test.rs:263:9:263:23 | CallExpr | | +| test.rs:263:9:263:23 | CallExpr | test.rs:264:9:266:9 | ExprStmt | | +| test.rs:263:9:263:24 | ExprStmt | test.rs:263:9:263:21 | PathExpr | | +| test.rs:264:9:266:9 | ExprStmt | test.rs:264:12:264:28 | PathExpr | | +| test.rs:264:9:266:9 | IfExpr | test.rs:267:9:267:24 | ExprStmt | | +| test.rs:264:12:264:28 | PathExpr | test.rs:264:12:264:30 | CallExpr | | +| test.rs:264:12:264:30 | CallExpr | test.rs:264:9:266:9 | IfExpr | false | +| test.rs:264:12:264:30 | CallExpr | test.rs:265:13:265:27 | ExprStmt | true | +| test.rs:265:13:265:26 | BreakExpr | test.rs:257:1:270:1 | exit labelled_block (normal) | break('block) | +| test.rs:265:13:265:27 | ExprStmt | test.rs:265:26:265:26 | 2 | | +| test.rs:265:26:265:26 | 2 | test.rs:265:13:265:26 | BreakExpr | | +| test.rs:267:9:267:21 | PathExpr | test.rs:267:9:267:23 | CallExpr | | +| test.rs:267:9:267:23 | CallExpr | test.rs:268:9:268:9 | 3 | | +| test.rs:267:9:267:24 | ExprStmt | test.rs:267:9:267:21 | PathExpr | | +| test.rs:268:9:268:9 | 3 | test.rs:258:18:269:5 | BlockExpr | | diff --git a/rust/ql/test/library-tests/controlflow/test.rs b/rust/ql/test/library-tests/controlflow/test.rs index 220241832186..dd1659ee997b 100644 --- a/rust/ql/test/library-tests/controlflow/test.rs +++ b/rust/ql/test/library-tests/controlflow/test.rs @@ -51,16 +51,22 @@ mod loop_expression { } } - fn test_while() { + fn test_while(i: i64) { let mut b = true; while b { 1; + if (i > 0) { + break; + } b = false; } } - fn test_for() { + fn test_for(j: i64) { for i in 0..10 { + if (i == j) { + break; + } 1; } } From f3e373442442c544193f960b86ebfa0f08dbdf5f Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 30 Sep 2024 16:58:44 +0200 Subject: [PATCH 097/347] Rust: Implement CFG for `WhileExpr`s --- .../rust/controlflow/internal/Completion.qll | 2 + .../internal/ControlFlowGraphImpl.qll | 63 +++++++++++++++---- .../CONSISTENCY/CfgConsistency.expected | 1 - .../library-tests/controlflow/Cfg.expected | 22 +++++++ 4 files changed, 74 insertions(+), 14 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll index 7e51f62a535b..e9c5d95f910c 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll @@ -84,6 +84,8 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion { private predicate isValidForSpecific0(AstNode e) { e = any(IfExpr c).getCondition() or + e = any(WhileExpr c).getCondition() + or any(MatchArm arm).getGuard() = e or exists(BinaryExpr expr | diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 1e4c2ec431d8..2cbf49b9e2b1 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -277,45 +277,82 @@ class LetStmtTree extends PreOrderTree instanceof LetStmt { class LiteralExprTree extends LeafTree instanceof LiteralExpr { } -class LoopExprTree extends PostOrderTree instanceof LoopExpr { +abstract class LoopingExprTree extends PostOrderTree { override predicate propagatesAbnormal(AstNode child) { none() } - override predicate first(AstNode node) { first(super.getLoopBody(), node) } + abstract BlockExpr getLoopBody(); - /** Whether this `LoopExpr` captures the `c` completion. */ - private predicate capturesLoopJumpCompletion(LoopJumpCompletion c) { + abstract Label getLabel(); + + /** Whether this loop captures the `c` completion. */ + predicate capturesLoopJumpCompletion(LoopJumpCompletion c) { not c.hasLabel() or - c.getLabelName() = super.getLabel().getLifetime().getText() + c.getLabelName() = this.getLabel().getLifetime().getText() } override predicate succ(AstNode pred, AstNode succ, Completion c) { + // Edge for exiting the loop with a break expressions + last(this.getLoopBody(), pred, c) and + c.(LoopJumpCompletion).isBreak() and + this.capturesLoopJumpCompletion(c) and + succ = this + or // Edge back to the start for final expression and continue expressions - last(super.getLoopBody(), pred, c) and + last(this.getLoopBody(), pred, c) and ( completionIsNormal(c) or c.(LoopJumpCompletion).isContinue() and this.capturesLoopJumpCompletion(c) ) and this.first(succ) - or - // Edge for exiting the loop with a break expressions - last(super.getLoopBody(), pred, c) and - c.(LoopJumpCompletion).isBreak() and - this.capturesLoopJumpCompletion(c) and - succ = this } override predicate last(AstNode last, Completion c) { super.last(last, c) or // Any abnormal completions that this loop does not capture should propagate - last(super.getLoopBody(), last, c) and + last(this.getLoopBody(), last, c) and not completionIsNormal(c) and not this.capturesLoopJumpCompletion(c) } } +class LoopExprTree extends LoopingExprTree instanceof LoopExpr { + override BlockExpr getLoopBody() { result = LoopExpr.super.getLoopBody() } + + override Label getLabel() { result = LoopExpr.super.getLabel() } + + override predicate first(AstNode node) { first(this.getLoopBody(), node) } +} + +class WhileExprTree extends LoopingExprTree instanceof WhileExpr { + override BlockExpr getLoopBody() { result = WhileExpr.super.getLoopBody() } + + override Label getLabel() { result = WhileExpr.super.getLabel() } + + override predicate first(AstNode node) { first(super.getCondition(), node) } + + override predicate succ(AstNode pred, AstNode succ, Completion c) { + super.succ(pred, succ, c) + or + last(super.getCondition(), pred, c) and + c.(BooleanCompletion).succeeded() and + first(this.getLoopBody(), succ) + or + last(super.getCondition(), pred, c) and + c.(BooleanCompletion).failed() and + succ = this + } + + override predicate last(AstNode last, Completion c) { + super.last(last, c) + or + last(super.getCondition(), last, c) and + not completionIsNormal(c) + } +} + class MatchArmTree extends ControlFlowTree instanceof MatchArm { override predicate propagatesAbnormal(AstNode child) { child = super.getExpr() } diff --git a/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected index 49f433fff2c8..df4c34f39f73 100644 --- a/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected +++ b/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected @@ -1,5 +1,4 @@ deadEnd -| test.rs:55:13:55:17 | b | | test.rs:230:28:230:33 | ... < ... | | test.rs:245:30:245:48 | BlockExpr | scopeNoFirst diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index f7d5365cf182..388ebed628a2 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -98,8 +98,30 @@ | test.rs:49:17:49:31 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | continue('inner) | | test.rs:49:17:49:32 | ExprStmt | test.rs:49:17:49:31 | ContinueExpr | | | test.rs:54:5:63:5 | enter test_while | test.rs:55:9:55:25 | LetStmt | | +| test.rs:54:5:63:5 | exit test_while (normal) | test.rs:54:5:63:5 | exit test_while | | +| test.rs:54:27:63:5 | BlockExpr | test.rs:54:5:63:5 | exit test_while (normal) | | | test.rs:55:9:55:25 | LetStmt | test.rs:55:21:55:24 | true | | +| test.rs:55:13:55:17 | b | test.rs:56:15:56:15 | b | match, no-match | | test.rs:55:21:55:24 | true | test.rs:55:13:55:17 | b | | +| test.rs:56:9:62:9 | WhileExpr | test.rs:54:27:63:5 | BlockExpr | | +| test.rs:56:15:56:15 | b | test.rs:56:9:62:9 | WhileExpr | false | +| test.rs:56:15:56:15 | b | test.rs:57:13:57:14 | ExprStmt | true | +| test.rs:56:17:62:9 | BlockExpr | test.rs:56:15:56:15 | b | | +| test.rs:57:13:57:13 | 1 | test.rs:58:13:60:13 | ExprStmt | | +| test.rs:57:13:57:14 | ExprStmt | test.rs:57:13:57:13 | 1 | | +| test.rs:58:13:60:13 | ExprStmt | test.rs:58:17:58:17 | i | | +| test.rs:58:13:60:13 | IfExpr | test.rs:61:13:61:22 | ExprStmt | | +| test.rs:58:16:58:22 | ParenExpr | test.rs:58:13:60:13 | IfExpr | false | +| test.rs:58:16:58:22 | ParenExpr | test.rs:59:17:59:22 | ExprStmt | true | +| test.rs:58:17:58:17 | i | test.rs:58:21:58:21 | 0 | | +| test.rs:58:17:58:21 | ... > ... | test.rs:58:16:58:22 | ParenExpr | | +| test.rs:58:21:58:21 | 0 | test.rs:58:17:58:21 | ... > ... | | +| test.rs:59:17:59:21 | BreakExpr | test.rs:56:9:62:9 | WhileExpr | break | +| test.rs:59:17:59:22 | ExprStmt | test.rs:59:17:59:21 | BreakExpr | | +| test.rs:61:13:61:13 | PathExpr | test.rs:61:17:61:21 | false | | +| test.rs:61:13:61:21 | ... = ... | test.rs:56:17:62:9 | BlockExpr | | +| test.rs:61:13:61:22 | ExprStmt | test.rs:61:13:61:13 | PathExpr | | +| test.rs:61:17:61:21 | false | test.rs:61:13:61:21 | ... = ... | | | test.rs:75:1:78:1 | enter test_nested_function | test.rs:76:5:76:28 | LetStmt | | | test.rs:75:1:78:1 | exit test_nested_function (normal) | test.rs:75:1:78:1 | exit test_nested_function | | | test.rs:75:40:78:1 | BlockExpr | test.rs:75:1:78:1 | exit test_nested_function (normal) | | From 8c1fd8fa7a22a4f5f99aa0ca9f58b3dc6d2a0d00 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Oct 2024 10:27:38 +0200 Subject: [PATCH 098/347] Rust: Implement CFG for `ForExpr`s --- .../internal/ControlFlowGraphImpl.qll | 43 ++++++++++++++++++- .../CONSISTENCY/CfgConsistency.expected | 2 - .../library-tests/controlflow/Cfg.expected | 21 +++++++++ 3 files changed, 62 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 2cbf49b9e2b1..4535e0be4c1c 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -284,7 +284,9 @@ abstract class LoopingExprTree extends PostOrderTree { abstract Label getLabel(); - /** Whether this loop captures the `c` completion. */ + abstract predicate entry(AstNode node); + + /** Holds if this loop captures the `c` completion. */ predicate capturesLoopJumpCompletion(LoopJumpCompletion c) { not c.hasLabel() or @@ -305,7 +307,7 @@ abstract class LoopingExprTree extends PostOrderTree { or c.(LoopJumpCompletion).isContinue() and this.capturesLoopJumpCompletion(c) ) and - this.first(succ) + this.entry(succ) } override predicate last(AstNode last, Completion c) { @@ -323,6 +325,8 @@ class LoopExprTree extends LoopingExprTree instanceof LoopExpr { override Label getLabel() { result = LoopExpr.super.getLabel() } + override predicate entry(AstNode node) { this.first(node) } + override predicate first(AstNode node) { first(this.getLoopBody(), node) } } @@ -331,6 +335,8 @@ class WhileExprTree extends LoopingExprTree instanceof WhileExpr { override Label getLabel() { result = WhileExpr.super.getLabel() } + override predicate entry(AstNode node) { this.first(node) } + override predicate first(AstNode node) { first(super.getCondition(), node) } override predicate succ(AstNode pred, AstNode succ, Completion c) { @@ -353,6 +359,39 @@ class WhileExprTree extends LoopingExprTree instanceof WhileExpr { } } +class ForExprTree extends LoopingExprTree instanceof ForExpr { + override BlockExpr getLoopBody() { result = ForExpr.super.getLoopBody() } + + override Label getLabel() { result = ForExpr.super.getLabel() } + + override predicate entry(AstNode n) { first(super.getPat(), n) } + + override predicate first(AstNode node) { first(super.getIterable(), node) } + + override predicate succ(AstNode pred, AstNode succ, Completion c) { + super.succ(pred, succ, c) + or + last(super.getIterable(), pred, c) and + first(super.getPat(), succ) and + completionIsNormal(c) + or + last(super.getPat(), pred, c) and + c.(MatchCompletion).succeeded() and + first(this.getLoopBody(), succ) + or + last(super.getPat(), pred, c) and + c.(MatchCompletion).failed() and + succ = this + } + + override predicate last(AstNode last, Completion c) { + super.last(last, c) + or + last(super.getIterable(), last, c) and + not completionIsNormal(c) + } +} + class MatchArmTree extends ControlFlowTree instanceof MatchArm { override predicate propagatesAbnormal(AstNode child) { child = super.getExpr() } diff --git a/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected index df4c34f39f73..64911eb1788f 100644 --- a/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected +++ b/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected @@ -1,5 +1,3 @@ deadEnd | test.rs:230:28:230:33 | ... < ... | | test.rs:245:30:245:48 | BlockExpr | -scopeNoFirst -| test.rs:65:5:72:5 | test_for | diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 388ebed628a2..67756a2bca27 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -122,6 +122,27 @@ | test.rs:61:13:61:21 | ... = ... | test.rs:56:17:62:9 | BlockExpr | | | test.rs:61:13:61:22 | ExprStmt | test.rs:61:13:61:13 | PathExpr | | | test.rs:61:17:61:21 | false | test.rs:61:13:61:21 | ... = ... | | +| test.rs:65:5:72:5 | enter test_for | test.rs:66:18:66:18 | 0 | | +| test.rs:65:5:72:5 | exit test_for (normal) | test.rs:65:5:72:5 | exit test_for | | +| test.rs:65:25:72:5 | BlockExpr | test.rs:65:5:72:5 | exit test_for (normal) | | +| test.rs:66:9:71:9 | ForExpr | test.rs:65:25:72:5 | BlockExpr | | +| test.rs:66:13:66:13 | i | test.rs:66:9:71:9 | ForExpr | no-match | +| test.rs:66:13:66:13 | i | test.rs:67:13:69:13 | ExprStmt | match | +| test.rs:66:18:66:18 | 0 | test.rs:66:21:66:22 | 10 | | +| test.rs:66:18:66:22 | RangeExpr | test.rs:66:13:66:13 | i | | +| test.rs:66:21:66:22 | 10 | test.rs:66:18:66:22 | RangeExpr | | +| test.rs:66:24:71:9 | BlockExpr | test.rs:66:13:66:13 | i | | +| test.rs:67:13:69:13 | ExprStmt | test.rs:67:17:67:17 | i | | +| test.rs:67:13:69:13 | IfExpr | test.rs:70:13:70:14 | ExprStmt | | +| test.rs:67:16:67:23 | ParenExpr | test.rs:67:13:69:13 | IfExpr | false | +| test.rs:67:16:67:23 | ParenExpr | test.rs:68:17:68:22 | ExprStmt | true | +| test.rs:67:17:67:17 | i | test.rs:67:22:67:22 | j | | +| test.rs:67:17:67:22 | ... == ... | test.rs:67:16:67:23 | ParenExpr | | +| test.rs:67:22:67:22 | j | test.rs:67:17:67:22 | ... == ... | | +| test.rs:68:17:68:21 | BreakExpr | test.rs:66:9:71:9 | ForExpr | break | +| test.rs:68:17:68:22 | ExprStmt | test.rs:68:17:68:21 | BreakExpr | | +| test.rs:70:13:70:13 | 1 | test.rs:66:24:71:9 | BlockExpr | | +| test.rs:70:13:70:14 | ExprStmt | test.rs:70:13:70:13 | 1 | | | test.rs:75:1:78:1 | enter test_nested_function | test.rs:76:5:76:28 | LetStmt | | | test.rs:75:1:78:1 | exit test_nested_function (normal) | test.rs:75:1:78:1 | exit test_nested_function | | | test.rs:75:40:78:1 | BlockExpr | test.rs:75:1:78:1 | exit test_nested_function (normal) | | From a507854288824de825761439bf1fbb233813ffd2 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Oct 2024 10:34:15 +0200 Subject: [PATCH 099/347] Rust: Fix bug in `BooleanCompletion.isValidForSpecific0` --- rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll | 2 +- .../controlflow/CONSISTENCY/CfgConsistency.expected | 1 - rust/ql/test/library-tests/controlflow/Cfg.expected | 5 +++++ .../variables/CONSISTENCY/CfgConsistency.expected | 1 - 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll index e9c5d95f910c..facb3849f71f 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll @@ -86,7 +86,7 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion { or e = any(WhileExpr c).getCondition() or - any(MatchArm arm).getGuard() = e + any(MatchGuard guard).getCondition() = e or exists(BinaryExpr expr | expr.getOperatorName() = ["&&", "||"] and diff --git a/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected index 64911eb1788f..10964769c6e7 100644 --- a/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected +++ b/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected @@ -1,3 +1,2 @@ deadEnd -| test.rs:230:28:230:33 | ... < ... | | test.rs:245:30:245:48 | BlockExpr | diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 67756a2bca27..30ffb3673c14 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -428,7 +428,12 @@ | test.rs:230:9:230:23 | TupleStructPat | test.rs:230:28:230:28 | x | match | | test.rs:230:9:230:23 | TupleStructPat | test.rs:231:9:231:23 | TupleStructPat | no-match | | test.rs:230:28:230:28 | x | test.rs:230:32:230:33 | 10 | | +| test.rs:230:28:230:33 | ... < ... | test.rs:230:38:230:38 | x | true | +| test.rs:230:28:230:33 | ... < ... | test.rs:231:9:231:23 | TupleStructPat | false | | test.rs:230:32:230:33 | 10 | test.rs:230:28:230:33 | ... < ... | | +| test.rs:230:38:230:38 | x | test.rs:230:42:230:42 | 5 | | +| test.rs:230:38:230:42 | ... + ... | test.rs:229:5:233:5 | MatchExpr | | +| test.rs:230:42:230:42 | 5 | test.rs:230:38:230:42 | ... + ... | | | test.rs:231:9:231:23 | TupleStructPat | test.rs:231:28:231:28 | x | match | | test.rs:231:9:231:23 | TupleStructPat | test.rs:232:9:232:20 | PathPat | no-match | | test.rs:231:28:231:28 | x | test.rs:229:5:233:5 | MatchExpr | | diff --git a/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected index 5457cb7c9d96..f7c02f86bb8d 100644 --- a/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected +++ b/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected @@ -1,5 +1,4 @@ deadEnd | variables.rs:2:5:2:22 | ExprStmt | | variables.rs:6:5:6:22 | ExprStmt | -| variables.rs:200:16:200:21 | ... > ... | | variables.rs:310:5:310:42 | LetStmt | From 17770af491b69035e616fe2f61c7e1d509e1b808 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Oct 2024 10:39:09 +0200 Subject: [PATCH 100/347] Rust: Account for `let` statement `else` blocks in `deadEnd` --- rust/ql/consistency-queries/CfgConsistency.ql | 6 ++++++ .../controlflow/CONSISTENCY/CfgConsistency.expected | 2 -- 2 files changed, 6 insertions(+), 2 deletions(-) delete mode 100644 rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected diff --git a/rust/ql/consistency-queries/CfgConsistency.ql b/rust/ql/consistency-queries/CfgConsistency.ql index ef7f9b6f2551..52b44170a397 100644 --- a/rust/ql/consistency-queries/CfgConsistency.ql +++ b/rust/ql/consistency-queries/CfgConsistency.ql @@ -25,3 +25,9 @@ query predicate scopeNoFirst(CfgScope scope) { not scope = any(Function f | not exists(f.getBody())) and not scope = any(ClosureExpr c | not exists(c.getBody())) } + +query predicate deadEnd(CfgImpl::Node node) { + Consistency::deadEnd(node) and + // `else` blocks in `let` statements diverge, so they are by definition dead ends + not node.getAstNode() = any(LetStmt let).getLetElse().getBlockExpr() +} diff --git a/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 10964769c6e7..000000000000 --- a/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -deadEnd -| test.rs:245:30:245:48 | BlockExpr | From bbd0aa929fa196432d0d2b02075b00ce3f688826 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Oct 2024 11:11:42 +0200 Subject: [PATCH 101/347] Rust: Add more missing CFG trees --- .../internal/ControlFlowGraphImpl.qll | 35 +++++++++++++++++++ .../Abi/CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../Attr/CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../Const/CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../Enum/CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../Impl/CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../Label/CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../Meta/CONSISTENCY/CfgConsistency.expected | 2 -- .../Name/CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../Param/CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../Trait/CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../Union/CONSISTENCY/CfgConsistency.expected | 2 -- .../Use/CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 2 -- .../CONSISTENCY/CfgConsistency.expected | 4 --- .../CONSISTENCY/CfgConsistency.expected | 4 --- .../CONSISTENCY/CfgConsistency.expected | 8 ----- 98 files changed, 35 insertions(+), 204 deletions(-) delete mode 100644 rust/ql/test/extractor-tests/generated/Abi/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ArgList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ArrayExpr/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ArrayType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/AssocItemList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/AssocTypeArg/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Attr/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ClosureBinder/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Const/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ConstArg/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ConstParam/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/DynTraitType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Enum/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ExprStmt/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ExternBlock/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ExternCrate/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ExternItemList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/FnPtrType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ForExpr/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ForType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsArg/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/GenericParamList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/IfExpr/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Impl/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ImplTraitType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/InferType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ItemList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Label/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/LetElse/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/LetExpr/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Lifetime/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/LifetimeArg/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/LifetimeParam/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/LoopExpr/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/MacroCall/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/MacroDef/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/MacroExpr/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/MacroPat/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/MacroRules/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/MacroType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/MatchArm/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/MatchArmList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/MatchExpr/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/MatchGuard/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Meta/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Name/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/NameRef/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/NeverType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Param/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ParamList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ParenExpr/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ParenPat/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ParenType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/PathSegment/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/PathType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/PtrType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/RecordExprFieldList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/RecordField/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/RecordFieldList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/RecordPatFieldList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/RefType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Rename/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/RestPat/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/RetType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/ReturnTypeSyntax/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/SelfParam/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/SliceType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/SourceFile/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Static/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/StmtList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Struct/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/TokenTree/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Trait/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/TraitAlias/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/TryExpr/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/TupleField/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/TupleFieldList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/TupleType/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/TypeAlias/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/TypeArg/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/TypeBound/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/TypeBoundList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/TypeParam/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Union/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Use/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/UseTree/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/UseTreeList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Variant/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/VariantList/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/Visibility/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/WhereClause/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/WherePred/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/generated/WhileExpr/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/query-tests/diagnostics/CONSISTENCY/CfgConsistency.expected delete mode 100644 rust/ql/test/query-tests/unusedentities/CONSISTENCY/CfgConsistency.expected diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 4535e0be4c1c..177651bf1ca8 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -61,6 +61,10 @@ import CfgImpl /** Holds if `p` is a trivial pattern that is always guaranteed to match. */ predicate trivialPat(Pat p) { p instanceof WildcardPat or p instanceof IdentPat } +class ArrayExprTree extends StandardPostOrderTree, ArrayExpr { + override AstNode getChildNode(int i) { result = this.getExpr(i) } +} + class AsmExprTree extends LeafTree instanceof AsmExpr { } class AwaitExprTree extends StandardPostOrderTree instanceof AwaitExpr { @@ -392,6 +396,9 @@ class ForExprTree extends LoopingExprTree instanceof ForExpr { } } +// TODO: replace with expanded macro once the extractor supports it +class MacroExprTree extends LeafTree, MacroExpr { } + class MatchArmTree extends ControlFlowTree instanceof MatchArm { override predicate propagatesAbnormal(AstNode child) { child = super.getExpr() } @@ -452,6 +459,10 @@ class MethodCallExprTree extends StandardPostOrderTree instanceof MethodCallExpr } } +class NameTree extends LeafTree, Name { } + +class NameRefTree extends LeafTree, NameRef { } + class OffsetOfExprTree extends LeafTree instanceof OffsetOfExpr { } class ParenExprTree extends StandardPostOrderTree, ParenExpr { @@ -461,6 +472,18 @@ class ParenExprTree extends StandardPostOrderTree, ParenExpr { // This covers all patterns as they all extend `Pat` class PatExprTree extends LeafTree instanceof Pat { } +class PathTree extends StandardPostOrderTree, Path { + override AstNode getChildNode(int i) { + i = 0 and result = this.getQualifier() + or + i = 1 and result = this.getPart() + } +} + +class PathSegmentTree extends StandardPostOrderTree, PathSegment { + override AstNode getChildNode(int i) { i = 0 and result = this.getNameRef() } +} + class PathExprTree extends LeafTree instanceof PathExpr { } class PrefixExprTree extends StandardPostOrderTree instanceof PrefixExpr { @@ -499,6 +522,14 @@ class ReturnExprTree extends PostOrderTree instanceof ReturnExpr { } } +class StaticTree extends StandardPostOrderTree, Static { + override AstNode getChildNode(int i) { + i = 0 and result = this.getName() + or + i = 1 and result = this.getBody() + } +} + class TupleExprTree extends StandardPostOrderTree instanceof TupleExpr { override AstNode getChildNode(int i) { result = super.getField(i) } } @@ -507,6 +538,10 @@ class TypeRefTree extends LeafTree instanceof TypeRef { } class UnderscoreExprTree extends LeafTree instanceof UnderscoreExpr { } +class UseTree_ extends StandardPreOrderTree, Use { + override AstNode getChildNode(int i) { i = 0 and result = this.getUseTree().getPath() } +} + // NOTE: `yield` is a reserved but unused keyword. class YieldExprTree extends StandardPostOrderTree instanceof YieldExpr { override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() } diff --git a/rust/ql/test/extractor-tests/generated/Abi/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Abi/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 8d4bdf6cd3dc..000000000000 --- a/rust/ql/test/extractor-tests/generated/Abi/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_abi.rs:3:1:6:1 | test_abi | diff --git a/rust/ql/test/extractor-tests/generated/ArgList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ArgList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 9d248b750b83..000000000000 --- a/rust/ql/test/extractor-tests/generated/ArgList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_arg_list.rs:3:1:6:1 | test_arg_list | diff --git a/rust/ql/test/extractor-tests/generated/ArrayExpr/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ArrayExpr/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 4bf8e4062121..000000000000 --- a/rust/ql/test/extractor-tests/generated/ArrayExpr/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -deadEnd -| gen_array_expr.rs:5:5:5:14 | ExprStmt | diff --git a/rust/ql/test/extractor-tests/generated/ArrayType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ArrayType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 62342a759d5b..000000000000 --- a/rust/ql/test/extractor-tests/generated/ArrayType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_array_type.rs:3:1:6:1 | test_array_type | diff --git a/rust/ql/test/extractor-tests/generated/AssocItemList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/AssocItemList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index cc7eef9075c0..000000000000 --- a/rust/ql/test/extractor-tests/generated/AssocItemList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_assoc_item_list.rs:3:1:6:1 | test_assoc_item_list | diff --git a/rust/ql/test/extractor-tests/generated/AssocTypeArg/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/AssocTypeArg/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 0b79831a0c6c..000000000000 --- a/rust/ql/test/extractor-tests/generated/AssocTypeArg/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_assoc_type_arg.rs:3:1:6:1 | test_assoc_type_arg | diff --git a/rust/ql/test/extractor-tests/generated/Attr/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Attr/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 0b123c1df9bf..000000000000 --- a/rust/ql/test/extractor-tests/generated/Attr/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_attr.rs:3:1:6:1 | test_attr | diff --git a/rust/ql/test/extractor-tests/generated/ClosureBinder/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ClosureBinder/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index f60c0a4be22e..000000000000 --- a/rust/ql/test/extractor-tests/generated/ClosureBinder/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_closure_binder.rs:3:1:6:1 | test_closure_binder | diff --git a/rust/ql/test/extractor-tests/generated/Const/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Const/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index ee1cb7311e75..000000000000 --- a/rust/ql/test/extractor-tests/generated/Const/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_const.rs:3:1:6:1 | test_const | diff --git a/rust/ql/test/extractor-tests/generated/ConstArg/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ConstArg/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index bc07de34ae2a..000000000000 --- a/rust/ql/test/extractor-tests/generated/ConstArg/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_const_arg.rs:3:1:6:1 | test_const_arg | diff --git a/rust/ql/test/extractor-tests/generated/ConstParam/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ConstParam/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 634709095ffd..000000000000 --- a/rust/ql/test/extractor-tests/generated/ConstParam/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_const_param.rs:3:1:6:1 | test_const_param | diff --git a/rust/ql/test/extractor-tests/generated/DynTraitType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/DynTraitType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 4753404b64da..000000000000 --- a/rust/ql/test/extractor-tests/generated/DynTraitType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_dyn_trait_type.rs:3:1:6:1 | test_dyn_trait_type | diff --git a/rust/ql/test/extractor-tests/generated/Enum/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Enum/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 112cd9bc2ff8..000000000000 --- a/rust/ql/test/extractor-tests/generated/Enum/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_enum.rs:3:1:6:1 | test_enum | diff --git a/rust/ql/test/extractor-tests/generated/ExprStmt/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ExprStmt/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 1013a9a4bb51..000000000000 --- a/rust/ql/test/extractor-tests/generated/ExprStmt/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -deadEnd -| gen_expr_stmt.rs:6:5:6:12 | CallExpr | diff --git a/rust/ql/test/extractor-tests/generated/ExternBlock/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ExternBlock/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index dcd514c03c23..000000000000 --- a/rust/ql/test/extractor-tests/generated/ExternBlock/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_extern_block.rs:3:1:6:1 | test_extern_block | diff --git a/rust/ql/test/extractor-tests/generated/ExternCrate/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ExternCrate/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index a3657bdec4eb..000000000000 --- a/rust/ql/test/extractor-tests/generated/ExternCrate/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_extern_crate.rs:3:1:6:1 | test_extern_crate | diff --git a/rust/ql/test/extractor-tests/generated/ExternItemList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ExternItemList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 004b9a6b6a2e..000000000000 --- a/rust/ql/test/extractor-tests/generated/ExternItemList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_extern_item_list.rs:3:1:6:1 | test_extern_item_list | diff --git a/rust/ql/test/extractor-tests/generated/FnPtrType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/FnPtrType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index ee3d592a18f5..000000000000 --- a/rust/ql/test/extractor-tests/generated/FnPtrType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_fn_ptr_type.rs:3:1:6:1 | test_fn_ptr_type | diff --git a/rust/ql/test/extractor-tests/generated/ForExpr/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ForExpr/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 536401b32bd6..000000000000 --- a/rust/ql/test/extractor-tests/generated/ForExpr/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_for_expr.rs:3:1:6:1 | test_for_expr | diff --git a/rust/ql/test/extractor-tests/generated/ForType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ForType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 9b87a1cae09b..000000000000 --- a/rust/ql/test/extractor-tests/generated/ForType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_for_type.rs:3:1:6:1 | test_for_type | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsArg/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/FormatArgsArg/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 80e93a811d5c..000000000000 --- a/rust/ql/test/extractor-tests/generated/FormatArgsArg/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_format_args_arg.rs:3:1:6:1 | test_format_args_arg | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 7fb70c61bde5..000000000000 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_format_args_expr.rs:3:1:6:1 | test_format_args_expr | diff --git a/rust/ql/test/extractor-tests/generated/GenericParamList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/GenericParamList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 1468fc6dd52d..000000000000 --- a/rust/ql/test/extractor-tests/generated/GenericParamList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_generic_param_list.rs:3:1:6:1 | test_generic_param_list | diff --git a/rust/ql/test/extractor-tests/generated/IfExpr/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/IfExpr/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 8049e813d65e..000000000000 --- a/rust/ql/test/extractor-tests/generated/IfExpr/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -deadEnd -| gen_if_expr.rs:6:9:6:38 | ExprStmt | diff --git a/rust/ql/test/extractor-tests/generated/Impl/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Impl/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 43501141e2be..000000000000 --- a/rust/ql/test/extractor-tests/generated/Impl/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_impl.rs:3:1:6:1 | test_impl | diff --git a/rust/ql/test/extractor-tests/generated/ImplTraitType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ImplTraitType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index a88979d04764..000000000000 --- a/rust/ql/test/extractor-tests/generated/ImplTraitType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_impl_trait_type.rs:3:1:6:1 | test_impl_trait_type | diff --git a/rust/ql/test/extractor-tests/generated/InferType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/InferType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 2eaf72e19646..000000000000 --- a/rust/ql/test/extractor-tests/generated/InferType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_infer_type.rs:3:1:6:1 | test_infer_type | diff --git a/rust/ql/test/extractor-tests/generated/ItemList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ItemList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 47b7abefadc3..000000000000 --- a/rust/ql/test/extractor-tests/generated/ItemList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_item_list.rs:3:1:6:1 | test_item_list | diff --git a/rust/ql/test/extractor-tests/generated/Label/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Label/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 8409c37b3651..000000000000 --- a/rust/ql/test/extractor-tests/generated/Label/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -deadEnd -| gen_label.rs:6:9:6:41 | ExprStmt | diff --git a/rust/ql/test/extractor-tests/generated/LetElse/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/LetElse/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 3e531a4f531c..000000000000 --- a/rust/ql/test/extractor-tests/generated/LetElse/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_let_else.rs:3:1:6:1 | test_let_else | diff --git a/rust/ql/test/extractor-tests/generated/LetExpr/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/LetExpr/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index b095048ef145..000000000000 --- a/rust/ql/test/extractor-tests/generated/LetExpr/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -deadEnd -| gen_let_expr.rs:6:9:6:26 | ExprStmt | diff --git a/rust/ql/test/extractor-tests/generated/Lifetime/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Lifetime/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 5ce6674c6dbc..000000000000 --- a/rust/ql/test/extractor-tests/generated/Lifetime/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_lifetime.rs:3:1:6:1 | test_lifetime | diff --git a/rust/ql/test/extractor-tests/generated/LifetimeArg/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/LifetimeArg/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index e7fb5e883146..000000000000 --- a/rust/ql/test/extractor-tests/generated/LifetimeArg/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_lifetime_arg.rs:3:1:6:1 | test_lifetime_arg | diff --git a/rust/ql/test/extractor-tests/generated/LifetimeParam/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/LifetimeParam/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index e8267e036098..000000000000 --- a/rust/ql/test/extractor-tests/generated/LifetimeParam/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_lifetime_param.rs:3:1:6:1 | test_lifetime_param | diff --git a/rust/ql/test/extractor-tests/generated/LoopExpr/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/LoopExpr/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 51c4af3241b0..000000000000 --- a/rust/ql/test/extractor-tests/generated/LoopExpr/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -deadEnd -| gen_loop_expr.rs:6:9:6:42 | ExprStmt | diff --git a/rust/ql/test/extractor-tests/generated/MacroCall/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/MacroCall/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 6d53cc3fb6cb..000000000000 --- a/rust/ql/test/extractor-tests/generated/MacroCall/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_macro_call.rs:3:1:6:1 | test_macro_call | diff --git a/rust/ql/test/extractor-tests/generated/MacroDef/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/MacroDef/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 35a5ed182593..000000000000 --- a/rust/ql/test/extractor-tests/generated/MacroDef/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_macro_def.rs:3:1:6:1 | test_macro_def | diff --git a/rust/ql/test/extractor-tests/generated/MacroExpr/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/MacroExpr/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index f1bbf3a66f5a..000000000000 --- a/rust/ql/test/extractor-tests/generated/MacroExpr/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_macro_expr.rs:3:1:6:1 | test_macro_expr | diff --git a/rust/ql/test/extractor-tests/generated/MacroPat/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/MacroPat/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index bc683af91462..000000000000 --- a/rust/ql/test/extractor-tests/generated/MacroPat/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_macro_pat.rs:3:1:6:1 | test_macro_pat | diff --git a/rust/ql/test/extractor-tests/generated/MacroRules/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/MacroRules/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 5705ce551635..000000000000 --- a/rust/ql/test/extractor-tests/generated/MacroRules/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_macro_rules.rs:3:1:6:1 | test_macro_rules | diff --git a/rust/ql/test/extractor-tests/generated/MacroType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/MacroType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 12fc80e517d5..000000000000 --- a/rust/ql/test/extractor-tests/generated/MacroType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_macro_type.rs:3:1:6:1 | test_macro_type | diff --git a/rust/ql/test/extractor-tests/generated/MatchArm/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/MatchArm/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index e558c7c1c28d..000000000000 --- a/rust/ql/test/extractor-tests/generated/MatchArm/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -deadEnd -| gen_match_arm.rs:10:20:10:25 | ... != ... | diff --git a/rust/ql/test/extractor-tests/generated/MatchArmList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/MatchArmList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 1f87a7f2ff2f..000000000000 --- a/rust/ql/test/extractor-tests/generated/MatchArmList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_match_arm_list.rs:3:1:6:1 | test_match_arm_list | diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 8d6730211c8e..000000000000 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -deadEnd -| gen_match_expr.rs:10:20:10:25 | ... != ... | diff --git a/rust/ql/test/extractor-tests/generated/MatchGuard/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/MatchGuard/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index c43c4e80a15f..000000000000 --- a/rust/ql/test/extractor-tests/generated/MatchGuard/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_match_guard.rs:3:1:6:1 | test_match_guard | diff --git a/rust/ql/test/extractor-tests/generated/Meta/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Meta/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 5b99494cfb9b..000000000000 --- a/rust/ql/test/extractor-tests/generated/Meta/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_meta.rs:3:1:6:1 | test_meta | diff --git a/rust/ql/test/extractor-tests/generated/Name/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Name/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index ab6b629565a7..000000000000 --- a/rust/ql/test/extractor-tests/generated/Name/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_name.rs:3:1:6:1 | test_name | diff --git a/rust/ql/test/extractor-tests/generated/NameRef/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/NameRef/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 00229745d5e8..000000000000 --- a/rust/ql/test/extractor-tests/generated/NameRef/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_name_ref.rs:3:1:6:1 | test_name_ref | diff --git a/rust/ql/test/extractor-tests/generated/NeverType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/NeverType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index f439296033cc..000000000000 --- a/rust/ql/test/extractor-tests/generated/NeverType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_never_type.rs:3:1:6:1 | test_never_type | diff --git a/rust/ql/test/extractor-tests/generated/Param/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Param/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 4ae2cf3ef7a7..000000000000 --- a/rust/ql/test/extractor-tests/generated/Param/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_param.rs:3:1:6:1 | test_param | diff --git a/rust/ql/test/extractor-tests/generated/ParamList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ParamList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 5ec0293119d0..000000000000 --- a/rust/ql/test/extractor-tests/generated/ParamList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_param_list.rs:3:1:6:1 | test_param_list | diff --git a/rust/ql/test/extractor-tests/generated/ParenExpr/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ParenExpr/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index d6456a3eeaf3..000000000000 --- a/rust/ql/test/extractor-tests/generated/ParenExpr/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_paren_expr.rs:3:1:6:1 | test_paren_expr | diff --git a/rust/ql/test/extractor-tests/generated/ParenPat/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ParenPat/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 8bae5ce6c3bf..000000000000 --- a/rust/ql/test/extractor-tests/generated/ParenPat/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_paren_pat.rs:3:1:6:1 | test_paren_pat | diff --git a/rust/ql/test/extractor-tests/generated/ParenType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ParenType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 2b51b5ff5c74..000000000000 --- a/rust/ql/test/extractor-tests/generated/ParenType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_paren_type.rs:3:1:6:1 | test_paren_type | diff --git a/rust/ql/test/extractor-tests/generated/PathSegment/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/PathSegment/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index ce4905c17cbb..000000000000 --- a/rust/ql/test/extractor-tests/generated/PathSegment/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_path_segment.rs:3:1:6:1 | test_path_segment | diff --git a/rust/ql/test/extractor-tests/generated/PathType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/PathType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index d274a77daf7b..000000000000 --- a/rust/ql/test/extractor-tests/generated/PathType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_path_type.rs:3:1:6:1 | test_path_type | diff --git a/rust/ql/test/extractor-tests/generated/PtrType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/PtrType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index a85b631b54dd..000000000000 --- a/rust/ql/test/extractor-tests/generated/PtrType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_ptr_type.rs:3:1:6:1 | test_ptr_type | diff --git a/rust/ql/test/extractor-tests/generated/RecordExprFieldList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/RecordExprFieldList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 979b32ad4d84..000000000000 --- a/rust/ql/test/extractor-tests/generated/RecordExprFieldList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_record_expr_field_list.rs:3:1:6:1 | test_record_expr_field_list | diff --git a/rust/ql/test/extractor-tests/generated/RecordField/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/RecordField/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 233c2442b42b..000000000000 --- a/rust/ql/test/extractor-tests/generated/RecordField/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_record_field.rs:3:1:6:1 | test_record_field | diff --git a/rust/ql/test/extractor-tests/generated/RecordFieldList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/RecordFieldList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 28fe2e3666a4..000000000000 --- a/rust/ql/test/extractor-tests/generated/RecordFieldList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_record_field_list.rs:3:1:6:1 | test_record_field_list | diff --git a/rust/ql/test/extractor-tests/generated/RecordPatFieldList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/RecordPatFieldList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 90d25f25c4dc..000000000000 --- a/rust/ql/test/extractor-tests/generated/RecordPatFieldList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_record_pat_field_list.rs:3:1:6:1 | test_record_pat_field_list | diff --git a/rust/ql/test/extractor-tests/generated/RefType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/RefType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index c8e70e9406c7..000000000000 --- a/rust/ql/test/extractor-tests/generated/RefType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_ref_type.rs:3:1:6:1 | test_ref_type | diff --git a/rust/ql/test/extractor-tests/generated/Rename/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Rename/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index da7a362c6c57..000000000000 --- a/rust/ql/test/extractor-tests/generated/Rename/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_rename.rs:3:1:6:1 | test_rename | diff --git a/rust/ql/test/extractor-tests/generated/RestPat/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/RestPat/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 4a73b0c3aca5..000000000000 --- a/rust/ql/test/extractor-tests/generated/RestPat/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_rest_pat.rs:3:1:6:1 | test_rest_pat | diff --git a/rust/ql/test/extractor-tests/generated/RetType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/RetType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index c203f29b4243..000000000000 --- a/rust/ql/test/extractor-tests/generated/RetType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_ret_type.rs:3:1:6:1 | test_ret_type | diff --git a/rust/ql/test/extractor-tests/generated/ReturnTypeSyntax/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/ReturnTypeSyntax/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 74c6038da131..000000000000 --- a/rust/ql/test/extractor-tests/generated/ReturnTypeSyntax/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_return_type_syntax.rs:3:1:6:1 | test_return_type_syntax | diff --git a/rust/ql/test/extractor-tests/generated/SelfParam/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/SelfParam/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index ffd6ee6bb3a7..000000000000 --- a/rust/ql/test/extractor-tests/generated/SelfParam/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_self_param.rs:3:1:6:1 | test_self_param | diff --git a/rust/ql/test/extractor-tests/generated/SliceType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/SliceType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 1785d38746fb..000000000000 --- a/rust/ql/test/extractor-tests/generated/SliceType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_slice_type.rs:3:1:6:1 | test_slice_type | diff --git a/rust/ql/test/extractor-tests/generated/SourceFile/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/SourceFile/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 77f954842667..000000000000 --- a/rust/ql/test/extractor-tests/generated/SourceFile/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_source_file.rs:3:1:6:1 | test_source_file | diff --git a/rust/ql/test/extractor-tests/generated/Static/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Static/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 405775d54459..000000000000 --- a/rust/ql/test/extractor-tests/generated/Static/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_static.rs:3:1:6:1 | test_static | diff --git a/rust/ql/test/extractor-tests/generated/StmtList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/StmtList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 3772daffc17e..000000000000 --- a/rust/ql/test/extractor-tests/generated/StmtList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_stmt_list.rs:3:1:6:1 | test_stmt_list | diff --git a/rust/ql/test/extractor-tests/generated/Struct/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Struct/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 6aedff0227a8..000000000000 --- a/rust/ql/test/extractor-tests/generated/Struct/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_struct.rs:3:1:6:1 | test_struct | diff --git a/rust/ql/test/extractor-tests/generated/TokenTree/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/TokenTree/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index b1414f7d8ac5..000000000000 --- a/rust/ql/test/extractor-tests/generated/TokenTree/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_token_tree.rs:3:1:6:1 | test_token_tree | diff --git a/rust/ql/test/extractor-tests/generated/Trait/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Trait/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 9988046e52da..000000000000 --- a/rust/ql/test/extractor-tests/generated/Trait/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_trait.rs:3:1:6:1 | test_trait | diff --git a/rust/ql/test/extractor-tests/generated/TraitAlias/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/TraitAlias/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 5216d265777e..000000000000 --- a/rust/ql/test/extractor-tests/generated/TraitAlias/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_trait_alias.rs:3:1:6:1 | test_trait_alias | diff --git a/rust/ql/test/extractor-tests/generated/TryExpr/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/TryExpr/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 9cd4cb86f31a..000000000000 --- a/rust/ql/test/extractor-tests/generated/TryExpr/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_try_expr.rs:3:1:6:1 | test_try_expr | diff --git a/rust/ql/test/extractor-tests/generated/TupleField/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/TupleField/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index ba75cb574e11..000000000000 --- a/rust/ql/test/extractor-tests/generated/TupleField/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_tuple_field.rs:3:1:6:1 | test_tuple_field | diff --git a/rust/ql/test/extractor-tests/generated/TupleFieldList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/TupleFieldList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 94ad834a83f7..000000000000 --- a/rust/ql/test/extractor-tests/generated/TupleFieldList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_tuple_field_list.rs:3:1:6:1 | test_tuple_field_list | diff --git a/rust/ql/test/extractor-tests/generated/TupleType/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/TupleType/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index df23cd353b8e..000000000000 --- a/rust/ql/test/extractor-tests/generated/TupleType/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_tuple_type.rs:3:1:6:1 | test_tuple_type | diff --git a/rust/ql/test/extractor-tests/generated/TypeAlias/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/TypeAlias/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 5473c4f4d29f..000000000000 --- a/rust/ql/test/extractor-tests/generated/TypeAlias/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_type_alias.rs:3:1:6:1 | test_type_alias | diff --git a/rust/ql/test/extractor-tests/generated/TypeArg/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/TypeArg/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index a4ef31c67be5..000000000000 --- a/rust/ql/test/extractor-tests/generated/TypeArg/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_type_arg.rs:3:1:6:1 | test_type_arg | diff --git a/rust/ql/test/extractor-tests/generated/TypeBound/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/TypeBound/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 65b362b2ce06..000000000000 --- a/rust/ql/test/extractor-tests/generated/TypeBound/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_type_bound.rs:3:1:6:1 | test_type_bound | diff --git a/rust/ql/test/extractor-tests/generated/TypeBoundList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/TypeBoundList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 11f983ef491e..000000000000 --- a/rust/ql/test/extractor-tests/generated/TypeBoundList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_type_bound_list.rs:3:1:6:1 | test_type_bound_list | diff --git a/rust/ql/test/extractor-tests/generated/TypeParam/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/TypeParam/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index d852e7f00743..000000000000 --- a/rust/ql/test/extractor-tests/generated/TypeParam/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_type_param.rs:3:1:6:1 | test_type_param | diff --git a/rust/ql/test/extractor-tests/generated/Union/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Union/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 2e1da077f375..000000000000 --- a/rust/ql/test/extractor-tests/generated/Union/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_union.rs:3:1:6:1 | test_union | diff --git a/rust/ql/test/extractor-tests/generated/Use/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Use/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index eb0529d66f9a..000000000000 --- a/rust/ql/test/extractor-tests/generated/Use/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_use.rs:3:1:6:1 | test_use | diff --git a/rust/ql/test/extractor-tests/generated/UseTree/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/UseTree/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 0f5a9b35a2df..000000000000 --- a/rust/ql/test/extractor-tests/generated/UseTree/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_use_tree.rs:3:1:6:1 | test_use_tree | diff --git a/rust/ql/test/extractor-tests/generated/UseTreeList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/UseTreeList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index d754f9e4cf63..000000000000 --- a/rust/ql/test/extractor-tests/generated/UseTreeList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_use_tree_list.rs:3:1:6:1 | test_use_tree_list | diff --git a/rust/ql/test/extractor-tests/generated/Variant/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Variant/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index e60f96aeee22..000000000000 --- a/rust/ql/test/extractor-tests/generated/Variant/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_variant.rs:3:1:6:1 | test_variant | diff --git a/rust/ql/test/extractor-tests/generated/VariantList/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/VariantList/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 16e583712b31..000000000000 --- a/rust/ql/test/extractor-tests/generated/VariantList/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_variant_list.rs:3:1:6:1 | test_variant_list | diff --git a/rust/ql/test/extractor-tests/generated/Visibility/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/Visibility/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 331e57ed0a41..000000000000 --- a/rust/ql/test/extractor-tests/generated/Visibility/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_visibility.rs:3:1:6:1 | test_visibility | diff --git a/rust/ql/test/extractor-tests/generated/WhereClause/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/WhereClause/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 2606d6d4113f..000000000000 --- a/rust/ql/test/extractor-tests/generated/WhereClause/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_where_clause.rs:3:1:6:1 | test_where_clause | diff --git a/rust/ql/test/extractor-tests/generated/WherePred/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/WherePred/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index e5601587a5fe..000000000000 --- a/rust/ql/test/extractor-tests/generated/WherePred/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_where_pred.rs:3:1:6:1 | test_where_pred | diff --git a/rust/ql/test/extractor-tests/generated/WhileExpr/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/extractor-tests/generated/WhileExpr/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index b9d575da0447..000000000000 --- a/rust/ql/test/extractor-tests/generated/WhileExpr/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -scopeNoFirst -| gen_while_expr.rs:3:1:6:1 | test_while_expr | diff --git a/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index f7c02f86bb8d..000000000000 --- a/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,4 +0,0 @@ -deadEnd -| variables.rs:2:5:2:22 | ExprStmt | -| variables.rs:6:5:6:22 | ExprStmt | -| variables.rs:310:5:310:42 | LetStmt | diff --git a/rust/ql/test/query-tests/diagnostics/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/query-tests/diagnostics/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 8aa73f9d3c1f..000000000000 --- a/rust/ql/test/query-tests/diagnostics/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,4 +0,0 @@ -deadEnd -| error.rs:2:5:2:32 | ExprStmt | -| my_macro.rs:16:9:16:19 | ExprStmt | -| my_struct.rs:17:9:17:34 | ExprStmt | diff --git a/rust/ql/test/query-tests/unusedentities/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/query-tests/unusedentities/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index f88f86c81777..000000000000 --- a/rust/ql/test/query-tests/unusedentities/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,8 +0,0 @@ -deadEnd -| main.rs:14:2:14:23 | ExprStmt | -| main.rs:38:2:38:23 | ExprStmt | -| main.rs:93:2:93:44 | ExprStmt | -| main.rs:107:2:107:20 | LetStmt | -| main.rs:151:2:151:53 | ExprStmt | -scopeNoFirst -| main.rs:125:1:133:1 | statics | From 26c69b8f8a2dc619360ba63e2173c1d14402db5e Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Oct 2024 14:54:44 +0200 Subject: [PATCH 102/347] Rust: Add more CFG tests --- .../library-tests/controlflow/Cfg.expected | 762 +++++++++--------- .../ql/test/library-tests/controlflow/test.rs | 21 +- 2 files changed, 413 insertions(+), 370 deletions(-) diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 30ffb3673c14..d5097158874d 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -122,373 +122,397 @@ | test.rs:61:13:61:21 | ... = ... | test.rs:56:17:62:9 | BlockExpr | | | test.rs:61:13:61:22 | ExprStmt | test.rs:61:13:61:13 | PathExpr | | | test.rs:61:17:61:21 | false | test.rs:61:13:61:21 | ... = ... | | -| test.rs:65:5:72:5 | enter test_for | test.rs:66:18:66:18 | 0 | | -| test.rs:65:5:72:5 | exit test_for (normal) | test.rs:65:5:72:5 | exit test_for | | -| test.rs:65:25:72:5 | BlockExpr | test.rs:65:5:72:5 | exit test_for (normal) | | -| test.rs:66:9:71:9 | ForExpr | test.rs:65:25:72:5 | BlockExpr | | -| test.rs:66:13:66:13 | i | test.rs:66:9:71:9 | ForExpr | no-match | -| test.rs:66:13:66:13 | i | test.rs:67:13:69:13 | ExprStmt | match | -| test.rs:66:18:66:18 | 0 | test.rs:66:21:66:22 | 10 | | -| test.rs:66:18:66:22 | RangeExpr | test.rs:66:13:66:13 | i | | -| test.rs:66:21:66:22 | 10 | test.rs:66:18:66:22 | RangeExpr | | -| test.rs:66:24:71:9 | BlockExpr | test.rs:66:13:66:13 | i | | -| test.rs:67:13:69:13 | ExprStmt | test.rs:67:17:67:17 | i | | -| test.rs:67:13:69:13 | IfExpr | test.rs:70:13:70:14 | ExprStmt | | -| test.rs:67:16:67:23 | ParenExpr | test.rs:67:13:69:13 | IfExpr | false | -| test.rs:67:16:67:23 | ParenExpr | test.rs:68:17:68:22 | ExprStmt | true | -| test.rs:67:17:67:17 | i | test.rs:67:22:67:22 | j | | -| test.rs:67:17:67:22 | ... == ... | test.rs:67:16:67:23 | ParenExpr | | -| test.rs:67:22:67:22 | j | test.rs:67:17:67:22 | ... == ... | | -| test.rs:68:17:68:21 | BreakExpr | test.rs:66:9:71:9 | ForExpr | break | -| test.rs:68:17:68:22 | ExprStmt | test.rs:68:17:68:21 | BreakExpr | | -| test.rs:70:13:70:13 | 1 | test.rs:66:24:71:9 | BlockExpr | | -| test.rs:70:13:70:14 | ExprStmt | test.rs:70:13:70:13 | 1 | | -| test.rs:75:1:78:1 | enter test_nested_function | test.rs:76:5:76:28 | LetStmt | | -| test.rs:75:1:78:1 | exit test_nested_function (normal) | test.rs:75:1:78:1 | exit test_nested_function | | -| test.rs:75:40:78:1 | BlockExpr | test.rs:75:1:78:1 | exit test_nested_function (normal) | | -| test.rs:76:5:76:28 | LetStmt | test.rs:76:19:76:27 | ClosureExpr | | -| test.rs:76:9:76:15 | add_one | test.rs:77:5:77:11 | add_one | match, no-match | -| test.rs:76:19:76:27 | ClosureExpr | test.rs:76:9:76:15 | add_one | | -| test.rs:76:19:76:27 | enter ClosureExpr | test.rs:76:23:76:23 | i | | -| test.rs:76:19:76:27 | exit ClosureExpr (normal) | test.rs:76:19:76:27 | exit ClosureExpr | | -| test.rs:76:23:76:23 | i | test.rs:76:27:76:27 | 1 | | -| test.rs:76:23:76:27 | ... + ... | test.rs:76:19:76:27 | exit ClosureExpr (normal) | | -| test.rs:76:27:76:27 | 1 | test.rs:76:23:76:27 | ... + ... | | -| test.rs:77:5:77:11 | add_one | test.rs:77:13:77:19 | add_one | | -| test.rs:77:5:77:23 | CallExpr | test.rs:75:40:78:1 | BlockExpr | | -| test.rs:77:13:77:19 | add_one | test.rs:77:21:77:21 | n | | -| test.rs:77:13:77:22 | CallExpr | test.rs:77:5:77:23 | CallExpr | | -| test.rs:77:21:77:21 | n | test.rs:77:13:77:22 | CallExpr | | -| test.rs:82:5:88:5 | enter test_if_else | test.rs:83:12:83:12 | n | | -| test.rs:82:5:88:5 | exit test_if_else (normal) | test.rs:82:5:88:5 | exit test_if_else | | -| test.rs:82:36:88:5 | BlockExpr | test.rs:82:5:88:5 | exit test_if_else (normal) | | -| test.rs:83:9:87:9 | IfExpr | test.rs:82:36:88:5 | BlockExpr | | -| test.rs:83:12:83:12 | n | test.rs:83:17:83:17 | 0 | | -| test.rs:83:12:83:17 | ... <= ... | test.rs:84:13:84:13 | 0 | true | -| test.rs:83:12:83:17 | ... <= ... | test.rs:86:13:86:13 | n | false | -| test.rs:83:17:83:17 | 0 | test.rs:83:12:83:17 | ... <= ... | | -| test.rs:83:19:85:9 | BlockExpr | test.rs:83:9:87:9 | IfExpr | | -| test.rs:84:13:84:13 | 0 | test.rs:83:19:85:9 | BlockExpr | | -| test.rs:85:16:87:9 | BlockExpr | test.rs:83:9:87:9 | IfExpr | | -| test.rs:86:13:86:13 | n | test.rs:86:17:86:17 | 1 | | -| test.rs:86:13:86:17 | ... - ... | test.rs:85:16:87:9 | BlockExpr | | -| test.rs:86:17:86:17 | 1 | test.rs:86:13:86:17 | ... - ... | | -| test.rs:90:5:96:5 | enter test_if_let_else | test.rs:91:12:91:26 | LetExpr | | -| test.rs:90:5:96:5 | exit test_if_let_else (normal) | test.rs:90:5:96:5 | exit test_if_let_else | | -| test.rs:90:48:96:5 | BlockExpr | test.rs:90:5:96:5 | exit test_if_let_else (normal) | | -| test.rs:91:9:95:9 | IfExpr | test.rs:90:48:96:5 | BlockExpr | | -| test.rs:91:12:91:26 | LetExpr | test.rs:91:16:91:22 | TupleStructPat | | -| test.rs:91:16:91:22 | TupleStructPat | test.rs:92:13:92:13 | n | match | -| test.rs:91:16:91:22 | TupleStructPat | test.rs:94:13:94:13 | 0 | no-match | -| test.rs:91:28:93:9 | BlockExpr | test.rs:91:9:95:9 | IfExpr | | -| test.rs:92:13:92:13 | n | test.rs:91:28:93:9 | BlockExpr | | -| test.rs:93:16:95:9 | BlockExpr | test.rs:91:9:95:9 | IfExpr | | -| test.rs:94:13:94:13 | 0 | test.rs:93:16:95:9 | BlockExpr | | -| test.rs:98:5:103:5 | enter test_if_let | test.rs:99:9:101:9 | ExprStmt | | -| test.rs:98:5:103:5 | exit test_if_let (normal) | test.rs:98:5:103:5 | exit test_if_let | | -| test.rs:98:43:103:5 | BlockExpr | test.rs:98:5:103:5 | exit test_if_let (normal) | | -| test.rs:99:9:101:9 | ExprStmt | test.rs:99:12:99:26 | LetExpr | | -| test.rs:99:9:101:9 | IfExpr | test.rs:102:9:102:9 | 0 | | -| test.rs:99:12:99:26 | LetExpr | test.rs:99:16:99:22 | TupleStructPat | | -| test.rs:99:16:99:22 | TupleStructPat | test.rs:99:9:101:9 | IfExpr | no-match | -| test.rs:99:16:99:22 | TupleStructPat | test.rs:100:13:100:13 | n | match | -| test.rs:99:28:101:9 | BlockExpr | test.rs:99:9:101:9 | IfExpr | | -| test.rs:100:13:100:13 | n | test.rs:99:28:101:9 | BlockExpr | | -| test.rs:102:9:102:9 | 0 | test.rs:98:43:103:5 | BlockExpr | | -| test.rs:105:5:111:5 | enter test_nested_if | test.rs:106:16:106:16 | PathExpr | | -| test.rs:105:5:111:5 | exit test_nested_if (normal) | test.rs:105:5:111:5 | exit test_nested_if | | -| test.rs:105:38:111:5 | BlockExpr | test.rs:105:5:111:5 | exit test_nested_if (normal) | | -| test.rs:106:9:110:9 | IfExpr | test.rs:105:38:111:5 | BlockExpr | | -| test.rs:106:12:106:49 | ParenExpr | test.rs:107:13:107:13 | 1 | true | -| test.rs:106:12:106:49 | ParenExpr | test.rs:109:13:109:13 | 0 | false | -| test.rs:106:13:106:48 | IfExpr | test.rs:106:12:106:49 | ParenExpr | | -| test.rs:106:16:106:16 | PathExpr | test.rs:106:20:106:20 | 0 | | -| test.rs:106:16:106:20 | ... < ... | test.rs:106:24:106:24 | a | true | -| test.rs:106:16:106:20 | ... < ... | test.rs:106:41:106:41 | a | false | -| test.rs:106:20:106:20 | 0 | test.rs:106:16:106:20 | ... < ... | | -| test.rs:106:22:106:32 | BlockExpr | test.rs:106:13:106:48 | IfExpr | | -| test.rs:106:24:106:24 | a | test.rs:106:29:106:30 | 10 | | -| test.rs:106:24:106:30 | ... < ... | test.rs:106:22:106:32 | BlockExpr | | -| test.rs:106:28:106:30 | - ... | test.rs:106:24:106:30 | ... < ... | | -| test.rs:106:29:106:30 | 10 | test.rs:106:28:106:30 | - ... | | -| test.rs:106:39:106:48 | BlockExpr | test.rs:106:13:106:48 | IfExpr | | -| test.rs:106:41:106:41 | a | test.rs:106:45:106:46 | 10 | | -| test.rs:106:41:106:46 | ... > ... | test.rs:106:39:106:48 | BlockExpr | | -| test.rs:106:45:106:46 | 10 | test.rs:106:41:106:46 | ... > ... | | -| test.rs:106:51:108:9 | BlockExpr | test.rs:106:9:110:9 | IfExpr | | -| test.rs:107:13:107:13 | 1 | test.rs:106:51:108:9 | BlockExpr | | -| test.rs:108:16:110:9 | BlockExpr | test.rs:106:9:110:9 | IfExpr | | -| test.rs:109:13:109:13 | 0 | test.rs:108:16:110:9 | BlockExpr | | -| test.rs:113:5:122:5 | enter test_nested_if_match | test.rs:114:19:114:19 | a | | -| test.rs:113:5:122:5 | exit test_nested_if_match (normal) | test.rs:113:5:122:5 | exit test_nested_if_match | | -| test.rs:113:44:122:5 | BlockExpr | test.rs:113:5:122:5 | exit test_nested_if_match (normal) | | -| test.rs:114:9:121:9 | IfExpr | test.rs:113:44:122:5 | BlockExpr | | -| test.rs:114:12:117:10 | ParenExpr | test.rs:118:13:118:13 | 1 | true | -| test.rs:114:12:117:10 | ParenExpr | test.rs:120:13:120:13 | 0 | false | -| test.rs:114:13:117:9 | MatchExpr | test.rs:114:12:117:10 | ParenExpr | | -| test.rs:114:19:114:19 | a | test.rs:115:13:115:13 | LiteralPat | | -| test.rs:115:13:115:13 | LiteralPat | test.rs:115:18:115:21 | true | match | -| test.rs:115:13:115:13 | LiteralPat | test.rs:116:13:116:13 | WildcardPat | no-match | -| test.rs:115:18:115:21 | true | test.rs:114:13:117:9 | MatchExpr | | -| test.rs:116:13:116:13 | WildcardPat | test.rs:116:18:116:22 | false | match | -| test.rs:116:18:116:22 | false | test.rs:114:13:117:9 | MatchExpr | | -| test.rs:117:12:119:9 | BlockExpr | test.rs:114:9:121:9 | IfExpr | | -| test.rs:118:13:118:13 | 1 | test.rs:117:12:119:9 | BlockExpr | | -| test.rs:119:16:121:9 | BlockExpr | test.rs:114:9:121:9 | IfExpr | | -| test.rs:120:13:120:13 | 0 | test.rs:119:16:121:9 | BlockExpr | | -| test.rs:124:5:133:5 | enter test_nested_if_block | test.rs:126:13:126:15 | ExprStmt | | -| test.rs:124:5:133:5 | exit test_nested_if_block (normal) | test.rs:124:5:133:5 | exit test_nested_if_block | | -| test.rs:124:44:133:5 | BlockExpr | test.rs:124:5:133:5 | exit test_nested_if_block (normal) | | -| test.rs:125:9:132:9 | IfExpr | test.rs:124:44:133:5 | BlockExpr | | -| test.rs:125:12:128:9 | BlockExpr | test.rs:129:13:129:13 | 1 | true | -| test.rs:125:12:128:9 | BlockExpr | test.rs:131:13:131:13 | 0 | false | -| test.rs:126:13:126:14 | TupleExpr | test.rs:127:13:127:13 | a | | -| test.rs:126:13:126:15 | ExprStmt | test.rs:126:13:126:14 | TupleExpr | | -| test.rs:127:13:127:13 | a | test.rs:127:17:127:17 | 0 | | -| test.rs:127:13:127:17 | ... > ... | test.rs:125:12:128:9 | BlockExpr | false, true | -| test.rs:127:17:127:17 | 0 | test.rs:127:13:127:17 | ... > ... | | -| test.rs:128:11:130:9 | BlockExpr | test.rs:125:9:132:9 | IfExpr | | -| test.rs:129:13:129:13 | 1 | test.rs:128:11:130:9 | BlockExpr | | -| test.rs:130:16:132:9 | BlockExpr | test.rs:125:9:132:9 | IfExpr | | -| test.rs:131:13:131:13 | 0 | test.rs:130:16:132:9 | BlockExpr | | -| test.rs:135:5:142:5 | enter test_if_assignment | test.rs:136:9:136:26 | LetStmt | | -| test.rs:135:5:142:5 | exit test_if_assignment (normal) | test.rs:135:5:142:5 | exit test_if_assignment | | -| test.rs:135:42:142:5 | BlockExpr | test.rs:135:5:142:5 | exit test_if_assignment (normal) | | -| test.rs:136:9:136:26 | LetStmt | test.rs:136:21:136:25 | false | | -| test.rs:136:13:136:17 | x | test.rs:137:12:137:12 | x | match, no-match | -| test.rs:136:21:136:25 | false | test.rs:136:13:136:17 | x | | -| test.rs:137:9:141:9 | IfExpr | test.rs:135:42:142:5 | BlockExpr | | -| test.rs:137:12:137:12 | x | test.rs:137:16:137:19 | true | | -| test.rs:137:12:137:19 | ... = ... | test.rs:138:13:138:13 | 1 | true | -| test.rs:137:12:137:19 | ... = ... | test.rs:140:13:140:13 | 0 | false | -| test.rs:137:16:137:19 | true | test.rs:137:12:137:19 | ... = ... | | -| test.rs:137:21:139:9 | BlockExpr | test.rs:137:9:141:9 | IfExpr | | -| test.rs:138:13:138:13 | 1 | test.rs:137:21:139:9 | BlockExpr | | -| test.rs:139:16:141:9 | BlockExpr | test.rs:137:9:141:9 | IfExpr | | +| test.rs:65:5:72:5 | enter test_while_let | test.rs:66:9:66:29 | LetStmt | | +| test.rs:66:9:66:29 | LetStmt | test.rs:66:24:66:24 | 1 | | +| test.rs:66:13:66:20 | iter | test.rs:67:15:67:39 | LetExpr | match, no-match | +| test.rs:66:24:66:24 | 1 | test.rs:66:27:66:28 | 10 | | +| test.rs:66:24:66:28 | RangeExpr | test.rs:66:13:66:20 | iter | | +| test.rs:66:27:66:28 | 10 | test.rs:66:24:66:28 | RangeExpr | | +| test.rs:67:15:67:39 | LetExpr | test.rs:67:19:67:25 | TupleStructPat | | +| test.rs:74:5:81:5 | enter test_for | test.rs:75:18:75:18 | 0 | | +| test.rs:74:5:81:5 | exit test_for (normal) | test.rs:74:5:81:5 | exit test_for | | +| test.rs:74:25:81:5 | BlockExpr | test.rs:74:5:81:5 | exit test_for (normal) | | +| test.rs:75:9:80:9 | ForExpr | test.rs:74:25:81:5 | BlockExpr | | +| test.rs:75:13:75:13 | i | test.rs:75:9:80:9 | ForExpr | no-match | +| test.rs:75:13:75:13 | i | test.rs:76:13:78:13 | ExprStmt | match | +| test.rs:75:18:75:18 | 0 | test.rs:75:21:75:22 | 10 | | +| test.rs:75:18:75:22 | RangeExpr | test.rs:75:13:75:13 | i | | +| test.rs:75:21:75:22 | 10 | test.rs:75:18:75:22 | RangeExpr | | +| test.rs:75:24:80:9 | BlockExpr | test.rs:75:13:75:13 | i | | +| test.rs:76:13:78:13 | ExprStmt | test.rs:76:17:76:17 | i | | +| test.rs:76:13:78:13 | IfExpr | test.rs:79:13:79:14 | ExprStmt | | +| test.rs:76:16:76:23 | ParenExpr | test.rs:76:13:78:13 | IfExpr | false | +| test.rs:76:16:76:23 | ParenExpr | test.rs:77:17:77:22 | ExprStmt | true | +| test.rs:76:17:76:17 | i | test.rs:76:22:76:22 | j | | +| test.rs:76:17:76:22 | ... == ... | test.rs:76:16:76:23 | ParenExpr | | +| test.rs:76:22:76:22 | j | test.rs:76:17:76:22 | ... == ... | | +| test.rs:77:17:77:21 | BreakExpr | test.rs:75:9:80:9 | ForExpr | break | +| test.rs:77:17:77:22 | ExprStmt | test.rs:77:17:77:21 | BreakExpr | | +| test.rs:79:13:79:13 | 1 | test.rs:75:24:80:9 | BlockExpr | | +| test.rs:79:13:79:14 | ExprStmt | test.rs:79:13:79:13 | 1 | | +| test.rs:84:1:87:1 | enter test_nested_function | test.rs:85:5:85:28 | LetStmt | | +| test.rs:84:1:87:1 | exit test_nested_function (normal) | test.rs:84:1:87:1 | exit test_nested_function | | +| test.rs:84:40:87:1 | BlockExpr | test.rs:84:1:87:1 | exit test_nested_function (normal) | | +| test.rs:85:5:85:28 | LetStmt | test.rs:85:19:85:27 | ClosureExpr | | +| test.rs:85:9:85:15 | add_one | test.rs:86:5:86:11 | add_one | match, no-match | +| test.rs:85:19:85:27 | ClosureExpr | test.rs:85:9:85:15 | add_one | | +| test.rs:85:19:85:27 | enter ClosureExpr | test.rs:85:23:85:23 | i | | +| test.rs:85:19:85:27 | exit ClosureExpr (normal) | test.rs:85:19:85:27 | exit ClosureExpr | | +| test.rs:85:23:85:23 | i | test.rs:85:27:85:27 | 1 | | +| test.rs:85:23:85:27 | ... + ... | test.rs:85:19:85:27 | exit ClosureExpr (normal) | | +| test.rs:85:27:85:27 | 1 | test.rs:85:23:85:27 | ... + ... | | +| test.rs:86:5:86:11 | add_one | test.rs:86:13:86:19 | add_one | | +| test.rs:86:5:86:23 | CallExpr | test.rs:84:40:87:1 | BlockExpr | | +| test.rs:86:13:86:19 | add_one | test.rs:86:21:86:21 | n | | +| test.rs:86:13:86:22 | CallExpr | test.rs:86:5:86:23 | CallExpr | | +| test.rs:86:21:86:21 | n | test.rs:86:13:86:22 | CallExpr | | +| test.rs:91:5:97:5 | enter test_if_else | test.rs:92:12:92:12 | n | | +| test.rs:91:5:97:5 | exit test_if_else (normal) | test.rs:91:5:97:5 | exit test_if_else | | +| test.rs:91:36:97:5 | BlockExpr | test.rs:91:5:97:5 | exit test_if_else (normal) | | +| test.rs:92:9:96:9 | IfExpr | test.rs:91:36:97:5 | BlockExpr | | +| test.rs:92:12:92:12 | n | test.rs:92:17:92:17 | 0 | | +| test.rs:92:12:92:17 | ... <= ... | test.rs:93:13:93:13 | 0 | true | +| test.rs:92:12:92:17 | ... <= ... | test.rs:95:13:95:13 | n | false | +| test.rs:92:17:92:17 | 0 | test.rs:92:12:92:17 | ... <= ... | | +| test.rs:92:19:94:9 | BlockExpr | test.rs:92:9:96:9 | IfExpr | | +| test.rs:93:13:93:13 | 0 | test.rs:92:19:94:9 | BlockExpr | | +| test.rs:94:16:96:9 | BlockExpr | test.rs:92:9:96:9 | IfExpr | | +| test.rs:95:13:95:13 | n | test.rs:95:17:95:17 | 1 | | +| test.rs:95:13:95:17 | ... - ... | test.rs:94:16:96:9 | BlockExpr | | +| test.rs:95:17:95:17 | 1 | test.rs:95:13:95:17 | ... - ... | | +| test.rs:99:5:105:5 | enter test_if_let_else | test.rs:100:12:100:26 | LetExpr | | +| test.rs:99:5:105:5 | exit test_if_let_else (normal) | test.rs:99:5:105:5 | exit test_if_let_else | | +| test.rs:99:48:105:5 | BlockExpr | test.rs:99:5:105:5 | exit test_if_let_else (normal) | | +| test.rs:100:9:104:9 | IfExpr | test.rs:99:48:105:5 | BlockExpr | | +| test.rs:100:12:100:26 | LetExpr | test.rs:100:16:100:22 | TupleStructPat | | +| test.rs:100:16:100:22 | TupleStructPat | test.rs:101:13:101:13 | n | match | +| test.rs:100:16:100:22 | TupleStructPat | test.rs:103:13:103:13 | 0 | no-match | +| test.rs:100:28:102:9 | BlockExpr | test.rs:100:9:104:9 | IfExpr | | +| test.rs:101:13:101:13 | n | test.rs:100:28:102:9 | BlockExpr | | +| test.rs:102:16:104:9 | BlockExpr | test.rs:100:9:104:9 | IfExpr | | +| test.rs:103:13:103:13 | 0 | test.rs:102:16:104:9 | BlockExpr | | +| test.rs:107:5:112:5 | enter test_if_let | test.rs:108:9:110:9 | ExprStmt | | +| test.rs:107:5:112:5 | exit test_if_let (normal) | test.rs:107:5:112:5 | exit test_if_let | | +| test.rs:107:43:112:5 | BlockExpr | test.rs:107:5:112:5 | exit test_if_let (normal) | | +| test.rs:108:9:110:9 | ExprStmt | test.rs:108:12:108:26 | LetExpr | | +| test.rs:108:9:110:9 | IfExpr | test.rs:111:9:111:9 | 0 | | +| test.rs:108:12:108:26 | LetExpr | test.rs:108:16:108:22 | TupleStructPat | | +| test.rs:108:16:108:22 | TupleStructPat | test.rs:108:9:110:9 | IfExpr | no-match | +| test.rs:108:16:108:22 | TupleStructPat | test.rs:109:13:109:13 | n | match | +| test.rs:108:28:110:9 | BlockExpr | test.rs:108:9:110:9 | IfExpr | | +| test.rs:109:13:109:13 | n | test.rs:108:28:110:9 | BlockExpr | | +| test.rs:111:9:111:9 | 0 | test.rs:107:43:112:5 | BlockExpr | | +| test.rs:114:5:120:5 | enter test_nested_if | test.rs:115:16:115:16 | PathExpr | | +| test.rs:114:5:120:5 | exit test_nested_if (normal) | test.rs:114:5:120:5 | exit test_nested_if | | +| test.rs:114:38:120:5 | BlockExpr | test.rs:114:5:120:5 | exit test_nested_if (normal) | | +| test.rs:115:9:119:9 | IfExpr | test.rs:114:38:120:5 | BlockExpr | | +| test.rs:115:12:115:49 | ParenExpr | test.rs:116:13:116:13 | 1 | true | +| test.rs:115:12:115:49 | ParenExpr | test.rs:118:13:118:13 | 0 | false | +| test.rs:115:13:115:48 | IfExpr | test.rs:115:12:115:49 | ParenExpr | | +| test.rs:115:16:115:16 | PathExpr | test.rs:115:20:115:20 | 0 | | +| test.rs:115:16:115:20 | ... < ... | test.rs:115:24:115:24 | a | true | +| test.rs:115:16:115:20 | ... < ... | test.rs:115:41:115:41 | a | false | +| test.rs:115:20:115:20 | 0 | test.rs:115:16:115:20 | ... < ... | | +| test.rs:115:22:115:32 | BlockExpr | test.rs:115:13:115:48 | IfExpr | | +| test.rs:115:24:115:24 | a | test.rs:115:29:115:30 | 10 | | +| test.rs:115:24:115:30 | ... < ... | test.rs:115:22:115:32 | BlockExpr | | +| test.rs:115:28:115:30 | - ... | test.rs:115:24:115:30 | ... < ... | | +| test.rs:115:29:115:30 | 10 | test.rs:115:28:115:30 | - ... | | +| test.rs:115:39:115:48 | BlockExpr | test.rs:115:13:115:48 | IfExpr | | +| test.rs:115:41:115:41 | a | test.rs:115:45:115:46 | 10 | | +| test.rs:115:41:115:46 | ... > ... | test.rs:115:39:115:48 | BlockExpr | | +| test.rs:115:45:115:46 | 10 | test.rs:115:41:115:46 | ... > ... | | +| test.rs:115:51:117:9 | BlockExpr | test.rs:115:9:119:9 | IfExpr | | +| test.rs:116:13:116:13 | 1 | test.rs:115:51:117:9 | BlockExpr | | +| test.rs:117:16:119:9 | BlockExpr | test.rs:115:9:119:9 | IfExpr | | +| test.rs:118:13:118:13 | 0 | test.rs:117:16:119:9 | BlockExpr | | +| test.rs:122:5:131:5 | enter test_nested_if_match | test.rs:123:19:123:19 | a | | +| test.rs:122:5:131:5 | exit test_nested_if_match (normal) | test.rs:122:5:131:5 | exit test_nested_if_match | | +| test.rs:122:44:131:5 | BlockExpr | test.rs:122:5:131:5 | exit test_nested_if_match (normal) | | +| test.rs:123:9:130:9 | IfExpr | test.rs:122:44:131:5 | BlockExpr | | +| test.rs:123:12:126:10 | ParenExpr | test.rs:127:13:127:13 | 1 | true | +| test.rs:123:12:126:10 | ParenExpr | test.rs:129:13:129:13 | 0 | false | +| test.rs:123:13:126:9 | MatchExpr | test.rs:123:12:126:10 | ParenExpr | | +| test.rs:123:19:123:19 | a | test.rs:124:13:124:13 | LiteralPat | | +| test.rs:124:13:124:13 | LiteralPat | test.rs:124:18:124:21 | true | match | +| test.rs:124:13:124:13 | LiteralPat | test.rs:125:13:125:13 | WildcardPat | no-match | +| test.rs:124:18:124:21 | true | test.rs:123:13:126:9 | MatchExpr | | +| test.rs:125:13:125:13 | WildcardPat | test.rs:125:18:125:22 | false | match | +| test.rs:125:18:125:22 | false | test.rs:123:13:126:9 | MatchExpr | | +| test.rs:126:12:128:9 | BlockExpr | test.rs:123:9:130:9 | IfExpr | | +| test.rs:127:13:127:13 | 1 | test.rs:126:12:128:9 | BlockExpr | | +| test.rs:128:16:130:9 | BlockExpr | test.rs:123:9:130:9 | IfExpr | | +| test.rs:129:13:129:13 | 0 | test.rs:128:16:130:9 | BlockExpr | | +| test.rs:133:5:142:5 | enter test_nested_if_block | test.rs:135:13:135:15 | ExprStmt | | +| test.rs:133:5:142:5 | exit test_nested_if_block (normal) | test.rs:133:5:142:5 | exit test_nested_if_block | | +| test.rs:133:44:142:5 | BlockExpr | test.rs:133:5:142:5 | exit test_nested_if_block (normal) | | +| test.rs:134:9:141:9 | IfExpr | test.rs:133:44:142:5 | BlockExpr | | +| test.rs:134:12:137:9 | BlockExpr | test.rs:138:13:138:13 | 1 | true | +| test.rs:134:12:137:9 | BlockExpr | test.rs:140:13:140:13 | 0 | false | +| test.rs:135:13:135:14 | TupleExpr | test.rs:136:13:136:13 | a | | +| test.rs:135:13:135:15 | ExprStmt | test.rs:135:13:135:14 | TupleExpr | | +| test.rs:136:13:136:13 | a | test.rs:136:17:136:17 | 0 | | +| test.rs:136:13:136:17 | ... > ... | test.rs:134:12:137:9 | BlockExpr | false, true | +| test.rs:136:17:136:17 | 0 | test.rs:136:13:136:17 | ... > ... | | +| test.rs:137:11:139:9 | BlockExpr | test.rs:134:9:141:9 | IfExpr | | +| test.rs:138:13:138:13 | 1 | test.rs:137:11:139:9 | BlockExpr | | +| test.rs:139:16:141:9 | BlockExpr | test.rs:134:9:141:9 | IfExpr | | | test.rs:140:13:140:13 | 0 | test.rs:139:16:141:9 | BlockExpr | | -| test.rs:144:5:155:5 | enter test_if_loop1 | test.rs:146:13:148:14 | ExprStmt | | -| test.rs:144:5:155:5 | exit test_if_loop1 (normal) | test.rs:144:5:155:5 | exit test_if_loop1 | | -| test.rs:144:37:155:5 | BlockExpr | test.rs:144:5:155:5 | exit test_if_loop1 (normal) | | -| test.rs:145:9:154:9 | IfExpr | test.rs:144:37:155:5 | BlockExpr | | -| test.rs:145:12:150:10 | ParenExpr | test.rs:151:13:151:13 | 1 | true | -| test.rs:145:12:150:10 | ParenExpr | test.rs:153:13:153:13 | 0 | false | -| test.rs:145:13:150:9 | LoopExpr | test.rs:145:12:150:10 | ParenExpr | | -| test.rs:145:18:150:9 | BlockExpr | test.rs:146:13:148:14 | ExprStmt | | -| test.rs:146:13:148:13 | IfExpr | test.rs:149:13:149:19 | ExprStmt | | -| test.rs:146:13:148:14 | ExprStmt | test.rs:146:16:146:16 | a | | -| test.rs:146:16:146:16 | a | test.rs:146:20:146:20 | 0 | | -| test.rs:146:16:146:20 | ... > ... | test.rs:146:13:148:13 | IfExpr | false | -| test.rs:146:16:146:20 | ... > ... | test.rs:147:17:147:29 | ExprStmt | true | -| test.rs:146:20:146:20 | 0 | test.rs:146:16:146:20 | ... > ... | | -| test.rs:147:17:147:28 | BreakExpr | test.rs:145:13:150:9 | LoopExpr | break | -| test.rs:147:17:147:29 | ExprStmt | test.rs:147:23:147:23 | a | | -| test.rs:147:23:147:23 | a | test.rs:147:27:147:28 | 10 | | -| test.rs:147:23:147:28 | ... > ... | test.rs:147:17:147:28 | BreakExpr | | -| test.rs:147:27:147:28 | 10 | test.rs:147:23:147:28 | ... > ... | | -| test.rs:149:13:149:13 | a | test.rs:149:17:149:18 | 10 | | -| test.rs:149:13:149:18 | ... < ... | test.rs:145:18:150:9 | BlockExpr | | -| test.rs:149:13:149:19 | ExprStmt | test.rs:149:13:149:13 | a | | -| test.rs:149:17:149:18 | 10 | test.rs:149:13:149:18 | ... < ... | | -| test.rs:150:12:152:9 | BlockExpr | test.rs:145:9:154:9 | IfExpr | | -| test.rs:151:13:151:13 | 1 | test.rs:150:12:152:9 | BlockExpr | | -| test.rs:152:16:154:9 | BlockExpr | test.rs:145:9:154:9 | IfExpr | | -| test.rs:153:13:153:13 | 0 | test.rs:152:16:154:9 | BlockExpr | | -| test.rs:157:5:168:5 | enter test_if_loop2 | test.rs:159:13:161:14 | ExprStmt | | -| test.rs:157:5:168:5 | exit test_if_loop2 (normal) | test.rs:157:5:168:5 | exit test_if_loop2 | | -| test.rs:157:37:168:5 | BlockExpr | test.rs:157:5:168:5 | exit test_if_loop2 (normal) | | -| test.rs:158:9:167:9 | IfExpr | test.rs:157:37:168:5 | BlockExpr | | -| test.rs:158:12:163:10 | ParenExpr | test.rs:164:13:164:13 | 1 | true | -| test.rs:158:12:163:10 | ParenExpr | test.rs:166:13:166:13 | 0 | false | -| test.rs:158:13:163:9 | LoopExpr | test.rs:158:12:163:10 | ParenExpr | | -| test.rs:158:26:163:9 | BlockExpr | test.rs:159:13:161:14 | ExprStmt | | -| test.rs:159:13:161:13 | IfExpr | test.rs:162:13:162:19 | ExprStmt | | -| test.rs:159:13:161:14 | ExprStmt | test.rs:159:16:159:16 | a | | -| test.rs:159:16:159:16 | a | test.rs:159:20:159:20 | 0 | | -| test.rs:159:16:159:20 | ... > ... | test.rs:159:13:161:13 | IfExpr | false | -| test.rs:159:16:159:20 | ... > ... | test.rs:160:17:160:36 | ExprStmt | true | -| test.rs:159:20:159:20 | 0 | test.rs:159:16:159:20 | ... > ... | | -| test.rs:160:17:160:35 | BreakExpr | test.rs:158:13:163:9 | LoopExpr | break('label) | -| test.rs:160:17:160:36 | ExprStmt | test.rs:160:30:160:30 | a | | -| test.rs:160:30:160:30 | a | test.rs:160:34:160:35 | 10 | | -| test.rs:160:30:160:35 | ... > ... | test.rs:160:17:160:35 | BreakExpr | | -| test.rs:160:34:160:35 | 10 | test.rs:160:30:160:35 | ... > ... | | -| test.rs:162:13:162:13 | a | test.rs:162:17:162:18 | 10 | | -| test.rs:162:13:162:18 | ... < ... | test.rs:158:26:163:9 | BlockExpr | | -| test.rs:162:13:162:19 | ExprStmt | test.rs:162:13:162:13 | a | | -| test.rs:162:17:162:18 | 10 | test.rs:162:13:162:18 | ... < ... | | -| test.rs:163:12:165:9 | BlockExpr | test.rs:158:9:167:9 | IfExpr | | -| test.rs:164:13:164:13 | 1 | test.rs:163:12:165:9 | BlockExpr | | -| test.rs:165:16:167:9 | BlockExpr | test.rs:158:9:167:9 | IfExpr | | -| test.rs:166:13:166:13 | 0 | test.rs:165:16:167:9 | BlockExpr | | -| test.rs:170:5:178:5 | enter test_labelled_block | test.rs:172:13:172:31 | ExprStmt | | -| test.rs:170:5:178:5 | exit test_labelled_block (normal) | test.rs:170:5:178:5 | exit test_labelled_block | | -| test.rs:172:13:172:30 | BreakExpr | test.rs:170:5:178:5 | exit test_labelled_block (normal) | break('block) | -| test.rs:172:13:172:31 | ExprStmt | test.rs:172:26:172:26 | a | | -| test.rs:172:26:172:26 | a | test.rs:172:30:172:30 | 0 | | -| test.rs:172:26:172:30 | ... > ... | test.rs:172:13:172:30 | BreakExpr | | -| test.rs:172:30:172:30 | 0 | test.rs:172:26:172:30 | ... > ... | | -| test.rs:183:5:186:5 | enter test_and_operator | test.rs:184:9:184:28 | LetStmt | | -| test.rs:183:5:186:5 | exit test_and_operator (normal) | test.rs:183:5:186:5 | exit test_and_operator | | -| test.rs:183:61:186:5 | BlockExpr | test.rs:183:5:186:5 | exit test_and_operator (normal) | | -| test.rs:184:9:184:28 | LetStmt | test.rs:184:17:184:27 | ... && ... | | -| test.rs:184:13:184:13 | d | test.rs:185:9:185:9 | d | match, no-match | -| test.rs:184:17:184:17 | a | test.rs:184:13:184:13 | d | false | -| test.rs:184:17:184:17 | a | test.rs:184:22:184:22 | b | true | -| test.rs:184:17:184:22 | ... && ... | test.rs:184:17:184:17 | a | | -| test.rs:184:17:184:27 | ... && ... | test.rs:184:17:184:22 | ... && ... | | -| test.rs:184:22:184:22 | b | test.rs:184:13:184:13 | d | false | -| test.rs:184:22:184:22 | b | test.rs:184:27:184:27 | c | true | -| test.rs:184:27:184:27 | c | test.rs:184:13:184:13 | d | | -| test.rs:185:9:185:9 | d | test.rs:183:61:186:5 | BlockExpr | | -| test.rs:188:5:191:5 | enter test_or_operator | test.rs:189:9:189:28 | LetStmt | | -| test.rs:188:5:191:5 | exit test_or_operator (normal) | test.rs:188:5:191:5 | exit test_or_operator | | -| test.rs:188:60:191:5 | BlockExpr | test.rs:188:5:191:5 | exit test_or_operator (normal) | | -| test.rs:189:9:189:28 | LetStmt | test.rs:189:17:189:27 | ... \|\| ... | | -| test.rs:189:13:189:13 | d | test.rs:190:9:190:9 | d | match, no-match | -| test.rs:189:17:189:17 | a | test.rs:189:13:189:13 | d | true | -| test.rs:189:17:189:17 | a | test.rs:189:22:189:22 | b | false | -| test.rs:189:17:189:22 | ... \|\| ... | test.rs:189:17:189:17 | a | | -| test.rs:189:17:189:27 | ... \|\| ... | test.rs:189:17:189:22 | ... \|\| ... | | -| test.rs:189:22:189:22 | b | test.rs:189:13:189:13 | d | true | -| test.rs:189:22:189:22 | b | test.rs:189:27:189:27 | c | false | -| test.rs:189:27:189:27 | c | test.rs:189:13:189:13 | d | | -| test.rs:190:9:190:9 | d | test.rs:188:60:191:5 | BlockExpr | | -| test.rs:193:5:196:5 | enter test_or_operator_2 | test.rs:194:9:194:36 | LetStmt | | -| test.rs:193:5:196:5 | exit test_or_operator_2 (normal) | test.rs:193:5:196:5 | exit test_or_operator_2 | | -| test.rs:193:61:196:5 | BlockExpr | test.rs:193:5:196:5 | exit test_or_operator_2 (normal) | | -| test.rs:194:9:194:36 | LetStmt | test.rs:194:17:194:35 | ... \|\| ... | | -| test.rs:194:13:194:13 | d | test.rs:195:9:195:9 | d | match, no-match | -| test.rs:194:17:194:17 | a | test.rs:194:13:194:13 | d | true | -| test.rs:194:17:194:17 | a | test.rs:194:23:194:23 | b | false | -| test.rs:194:17:194:30 | ... \|\| ... | test.rs:194:17:194:17 | a | | -| test.rs:194:17:194:35 | ... \|\| ... | test.rs:194:17:194:30 | ... \|\| ... | | -| test.rs:194:22:194:30 | ParenExpr | test.rs:194:13:194:13 | d | true | -| test.rs:194:22:194:30 | ParenExpr | test.rs:194:35:194:35 | c | false | -| test.rs:194:23:194:23 | b | test.rs:194:28:194:29 | 28 | | -| test.rs:194:23:194:29 | ... == ... | test.rs:194:22:194:30 | ParenExpr | | -| test.rs:194:28:194:29 | 28 | test.rs:194:23:194:29 | ... == ... | | -| test.rs:194:35:194:35 | c | test.rs:194:13:194:13 | d | | -| test.rs:195:9:195:9 | d | test.rs:193:61:196:5 | BlockExpr | | -| test.rs:198:5:201:5 | enter test_not_operator | test.rs:199:9:199:19 | LetStmt | | -| test.rs:198:5:201:5 | exit test_not_operator (normal) | test.rs:198:5:201:5 | exit test_not_operator | | -| test.rs:198:43:201:5 | BlockExpr | test.rs:198:5:201:5 | exit test_not_operator (normal) | | -| test.rs:199:9:199:19 | LetStmt | test.rs:199:18:199:18 | a | | -| test.rs:199:13:199:13 | d | test.rs:200:9:200:9 | d | match, no-match | -| test.rs:199:17:199:18 | ! ... | test.rs:199:13:199:13 | d | | -| test.rs:199:18:199:18 | a | test.rs:199:17:199:18 | ! ... | | -| test.rs:200:9:200:9 | d | test.rs:198:43:201:5 | BlockExpr | | -| test.rs:203:5:209:5 | enter test_if_and_operator | test.rs:204:12:204:22 | ... && ... | | -| test.rs:203:5:209:5 | exit test_if_and_operator (normal) | test.rs:203:5:209:5 | exit test_if_and_operator | | -| test.rs:203:63:209:5 | BlockExpr | test.rs:203:5:209:5 | exit test_if_and_operator (normal) | | -| test.rs:204:9:208:9 | IfExpr | test.rs:203:63:209:5 | BlockExpr | | -| test.rs:204:12:204:12 | a | test.rs:204:17:204:17 | b | true | -| test.rs:204:12:204:12 | a | test.rs:207:13:207:17 | false | false | -| test.rs:204:12:204:17 | ... && ... | test.rs:204:12:204:12 | a | | -| test.rs:204:12:204:22 | ... && ... | test.rs:204:12:204:17 | ... && ... | | -| test.rs:204:17:204:17 | b | test.rs:204:22:204:22 | c | true | -| test.rs:204:17:204:17 | b | test.rs:207:13:207:17 | false | false | -| test.rs:204:22:204:22 | c | test.rs:205:13:205:16 | true | true | -| test.rs:204:22:204:22 | c | test.rs:207:13:207:17 | false | false | -| test.rs:204:24:206:9 | BlockExpr | test.rs:204:9:208:9 | IfExpr | | -| test.rs:205:13:205:16 | true | test.rs:204:24:206:9 | BlockExpr | | -| test.rs:206:16:208:9 | BlockExpr | test.rs:204:9:208:9 | IfExpr | | -| test.rs:207:13:207:17 | false | test.rs:206:16:208:9 | BlockExpr | | -| test.rs:211:5:217:5 | enter test_if_or_operator | test.rs:212:12:212:22 | ... \|\| ... | | -| test.rs:211:5:217:5 | exit test_if_or_operator (normal) | test.rs:211:5:217:5 | exit test_if_or_operator | | -| test.rs:211:62:217:5 | BlockExpr | test.rs:211:5:217:5 | exit test_if_or_operator (normal) | | -| test.rs:212:9:216:9 | IfExpr | test.rs:211:62:217:5 | BlockExpr | | -| test.rs:212:12:212:12 | a | test.rs:212:17:212:17 | b | false | -| test.rs:212:12:212:12 | a | test.rs:213:13:213:16 | true | true | -| test.rs:212:12:212:17 | ... \|\| ... | test.rs:212:12:212:12 | a | | -| test.rs:212:12:212:22 | ... \|\| ... | test.rs:212:12:212:17 | ... \|\| ... | | -| test.rs:212:17:212:17 | b | test.rs:212:22:212:22 | c | false | -| test.rs:212:17:212:17 | b | test.rs:213:13:213:16 | true | true | -| test.rs:212:22:212:22 | c | test.rs:213:13:213:16 | true | true | -| test.rs:212:22:212:22 | c | test.rs:215:13:215:17 | false | false | -| test.rs:212:24:214:9 | BlockExpr | test.rs:212:9:216:9 | IfExpr | | -| test.rs:213:13:213:16 | true | test.rs:212:24:214:9 | BlockExpr | | -| test.rs:214:16:216:9 | BlockExpr | test.rs:212:9:216:9 | IfExpr | | -| test.rs:215:13:215:17 | false | test.rs:214:16:216:9 | BlockExpr | | -| test.rs:219:5:225:5 | enter test_if_not_operator | test.rs:220:13:220:13 | a | | -| test.rs:219:5:225:5 | exit test_if_not_operator (normal) | test.rs:219:5:225:5 | exit test_if_not_operator | | -| test.rs:219:46:225:5 | BlockExpr | test.rs:219:5:225:5 | exit test_if_not_operator (normal) | | -| test.rs:220:9:224:9 | IfExpr | test.rs:219:46:225:5 | BlockExpr | | -| test.rs:220:12:220:13 | ! ... | test.rs:221:13:221:16 | true | true | -| test.rs:220:12:220:13 | ! ... | test.rs:223:13:223:17 | false | false | -| test.rs:220:13:220:13 | a | test.rs:220:12:220:13 | ! ... | false, true | -| test.rs:220:15:222:9 | BlockExpr | test.rs:220:9:224:9 | IfExpr | | -| test.rs:221:13:221:16 | true | test.rs:220:15:222:9 | BlockExpr | | -| test.rs:222:16:224:9 | BlockExpr | test.rs:220:9:224:9 | IfExpr | | -| test.rs:223:13:223:17 | false | test.rs:222:16:224:9 | BlockExpr | | -| test.rs:228:1:234:1 | enter test_match | test.rs:229:11:229:21 | maybe_digit | | -| test.rs:228:1:234:1 | exit test_match (normal) | test.rs:228:1:234:1 | exit test_match | | -| test.rs:228:48:234:1 | BlockExpr | test.rs:228:1:234:1 | exit test_match (normal) | | -| test.rs:229:5:233:5 | MatchExpr | test.rs:228:48:234:1 | BlockExpr | | -| test.rs:229:11:229:21 | maybe_digit | test.rs:230:9:230:23 | TupleStructPat | | -| test.rs:230:9:230:23 | TupleStructPat | test.rs:230:28:230:28 | x | match | -| test.rs:230:9:230:23 | TupleStructPat | test.rs:231:9:231:23 | TupleStructPat | no-match | -| test.rs:230:28:230:28 | x | test.rs:230:32:230:33 | 10 | | -| test.rs:230:28:230:33 | ... < ... | test.rs:230:38:230:38 | x | true | -| test.rs:230:28:230:33 | ... < ... | test.rs:231:9:231:23 | TupleStructPat | false | -| test.rs:230:32:230:33 | 10 | test.rs:230:28:230:33 | ... < ... | | -| test.rs:230:38:230:38 | x | test.rs:230:42:230:42 | 5 | | -| test.rs:230:38:230:42 | ... + ... | test.rs:229:5:233:5 | MatchExpr | | -| test.rs:230:42:230:42 | 5 | test.rs:230:38:230:42 | ... + ... | | -| test.rs:231:9:231:23 | TupleStructPat | test.rs:231:28:231:28 | x | match | -| test.rs:231:9:231:23 | TupleStructPat | test.rs:232:9:232:20 | PathPat | no-match | -| test.rs:231:28:231:28 | x | test.rs:229:5:233:5 | MatchExpr | | -| test.rs:232:9:232:20 | PathPat | test.rs:232:25:232:25 | 5 | match | -| test.rs:232:25:232:25 | 5 | test.rs:229:5:233:5 | MatchExpr | | -| test.rs:237:5:242:5 | enter test_infinite_loop | test.rs:238:9:240:9 | ExprStmt | | -| test.rs:238:9:240:9 | ExprStmt | test.rs:239:13:239:13 | 1 | | -| test.rs:238:14:240:9 | BlockExpr | test.rs:239:13:239:13 | 1 | | -| test.rs:239:13:239:13 | 1 | test.rs:238:14:240:9 | BlockExpr | | -| test.rs:244:5:247:5 | enter test_let_match | test.rs:245:9:245:49 | LetStmt | | -| test.rs:244:5:247:5 | exit test_let_match (normal) | test.rs:244:5:247:5 | exit test_let_match | | -| test.rs:244:39:247:5 | BlockExpr | test.rs:244:5:247:5 | exit test_let_match (normal) | | -| test.rs:245:9:245:49 | LetStmt | test.rs:245:23:245:23 | a | | -| test.rs:245:13:245:19 | TupleStructPat | test.rs:245:32:245:46 | "Expected some" | no-match | -| test.rs:245:13:245:19 | TupleStructPat | test.rs:246:9:246:9 | n | match | -| test.rs:245:23:245:23 | a | test.rs:245:13:245:19 | TupleStructPat | | -| test.rs:245:32:245:46 | "Expected some" | test.rs:245:30:245:48 | BlockExpr | | -| test.rs:246:9:246:9 | n | test.rs:244:39:247:5 | BlockExpr | | -| test.rs:250:1:255:1 | enter dead_code | test.rs:251:5:253:5 | ExprStmt | | -| test.rs:250:1:255:1 | exit dead_code (normal) | test.rs:250:1:255:1 | exit dead_code | | -| test.rs:251:5:253:5 | ExprStmt | test.rs:251:9:251:12 | true | | -| test.rs:251:8:251:13 | ParenExpr | test.rs:252:9:252:17 | ExprStmt | true | -| test.rs:251:9:251:12 | true | test.rs:251:8:251:13 | ParenExpr | | -| test.rs:252:9:252:16 | ReturnExpr | test.rs:250:1:255:1 | exit dead_code (normal) | return | -| test.rs:252:9:252:17 | ExprStmt | test.rs:252:16:252:16 | 0 | | -| test.rs:252:16:252:16 | 0 | test.rs:252:9:252:16 | ReturnExpr | | -| test.rs:257:1:270:1 | enter labelled_block | test.rs:258:5:269:6 | LetStmt | | -| test.rs:257:1:270:1 | exit labelled_block (normal) | test.rs:257:1:270:1 | exit labelled_block | | -| test.rs:257:28:270:1 | BlockExpr | test.rs:257:1:270:1 | exit labelled_block (normal) | | -| test.rs:258:5:269:6 | LetStmt | test.rs:259:9:259:19 | ExprStmt | | -| test.rs:258:9:258:14 | result | test.rs:257:28:270:1 | BlockExpr | match, no-match | -| test.rs:258:18:269:5 | BlockExpr | test.rs:258:9:258:14 | result | | -| test.rs:259:9:259:16 | PathExpr | test.rs:259:9:259:18 | CallExpr | | -| test.rs:259:9:259:18 | CallExpr | test.rs:260:9:262:9 | ExprStmt | | -| test.rs:259:9:259:19 | ExprStmt | test.rs:259:9:259:16 | PathExpr | | -| test.rs:260:9:262:9 | ExprStmt | test.rs:260:12:260:28 | PathExpr | | -| test.rs:260:9:262:9 | IfExpr | test.rs:263:9:263:24 | ExprStmt | | -| test.rs:260:12:260:28 | PathExpr | test.rs:260:12:260:30 | CallExpr | | -| test.rs:260:12:260:30 | CallExpr | test.rs:260:9:262:9 | IfExpr | false | -| test.rs:260:12:260:30 | CallExpr | test.rs:261:13:261:27 | ExprStmt | true | -| test.rs:261:13:261:26 | BreakExpr | test.rs:257:1:270:1 | exit labelled_block (normal) | break('block) | -| test.rs:261:13:261:27 | ExprStmt | test.rs:261:26:261:26 | 1 | | -| test.rs:261:26:261:26 | 1 | test.rs:261:13:261:26 | BreakExpr | | -| test.rs:263:9:263:21 | PathExpr | test.rs:263:9:263:23 | CallExpr | | -| test.rs:263:9:263:23 | CallExpr | test.rs:264:9:266:9 | ExprStmt | | -| test.rs:263:9:263:24 | ExprStmt | test.rs:263:9:263:21 | PathExpr | | -| test.rs:264:9:266:9 | ExprStmt | test.rs:264:12:264:28 | PathExpr | | -| test.rs:264:9:266:9 | IfExpr | test.rs:267:9:267:24 | ExprStmt | | -| test.rs:264:12:264:28 | PathExpr | test.rs:264:12:264:30 | CallExpr | | -| test.rs:264:12:264:30 | CallExpr | test.rs:264:9:266:9 | IfExpr | false | -| test.rs:264:12:264:30 | CallExpr | test.rs:265:13:265:27 | ExprStmt | true | -| test.rs:265:13:265:26 | BreakExpr | test.rs:257:1:270:1 | exit labelled_block (normal) | break('block) | -| test.rs:265:13:265:27 | ExprStmt | test.rs:265:26:265:26 | 2 | | -| test.rs:265:26:265:26 | 2 | test.rs:265:13:265:26 | BreakExpr | | -| test.rs:267:9:267:21 | PathExpr | test.rs:267:9:267:23 | CallExpr | | -| test.rs:267:9:267:23 | CallExpr | test.rs:268:9:268:9 | 3 | | -| test.rs:267:9:267:24 | ExprStmt | test.rs:267:9:267:21 | PathExpr | | -| test.rs:268:9:268:9 | 3 | test.rs:258:18:269:5 | BlockExpr | | +| test.rs:144:5:151:5 | enter test_if_assignment | test.rs:145:9:145:26 | LetStmt | | +| test.rs:144:5:151:5 | exit test_if_assignment (normal) | test.rs:144:5:151:5 | exit test_if_assignment | | +| test.rs:144:42:151:5 | BlockExpr | test.rs:144:5:151:5 | exit test_if_assignment (normal) | | +| test.rs:145:9:145:26 | LetStmt | test.rs:145:21:145:25 | false | | +| test.rs:145:13:145:17 | x | test.rs:146:12:146:12 | x | match, no-match | +| test.rs:145:21:145:25 | false | test.rs:145:13:145:17 | x | | +| test.rs:146:9:150:9 | IfExpr | test.rs:144:42:151:5 | BlockExpr | | +| test.rs:146:12:146:12 | x | test.rs:146:16:146:19 | true | | +| test.rs:146:12:146:19 | ... = ... | test.rs:147:13:147:13 | 1 | true | +| test.rs:146:12:146:19 | ... = ... | test.rs:149:13:149:13 | 0 | false | +| test.rs:146:16:146:19 | true | test.rs:146:12:146:19 | ... = ... | | +| test.rs:146:21:148:9 | BlockExpr | test.rs:146:9:150:9 | IfExpr | | +| test.rs:147:13:147:13 | 1 | test.rs:146:21:148:9 | BlockExpr | | +| test.rs:148:16:150:9 | BlockExpr | test.rs:146:9:150:9 | IfExpr | | +| test.rs:149:13:149:13 | 0 | test.rs:148:16:150:9 | BlockExpr | | +| test.rs:153:5:164:5 | enter test_if_loop1 | test.rs:155:13:157:14 | ExprStmt | | +| test.rs:153:5:164:5 | exit test_if_loop1 (normal) | test.rs:153:5:164:5 | exit test_if_loop1 | | +| test.rs:153:37:164:5 | BlockExpr | test.rs:153:5:164:5 | exit test_if_loop1 (normal) | | +| test.rs:154:9:163:9 | IfExpr | test.rs:153:37:164:5 | BlockExpr | | +| test.rs:154:12:159:10 | ParenExpr | test.rs:160:13:160:13 | 1 | true | +| test.rs:154:12:159:10 | ParenExpr | test.rs:162:13:162:13 | 0 | false | +| test.rs:154:13:159:9 | LoopExpr | test.rs:154:12:159:10 | ParenExpr | | +| test.rs:154:18:159:9 | BlockExpr | test.rs:155:13:157:14 | ExprStmt | | +| test.rs:155:13:157:13 | IfExpr | test.rs:158:13:158:19 | ExprStmt | | +| test.rs:155:13:157:14 | ExprStmt | test.rs:155:16:155:16 | a | | +| test.rs:155:16:155:16 | a | test.rs:155:20:155:20 | 0 | | +| test.rs:155:16:155:20 | ... > ... | test.rs:155:13:157:13 | IfExpr | false | +| test.rs:155:16:155:20 | ... > ... | test.rs:156:17:156:29 | ExprStmt | true | +| test.rs:155:20:155:20 | 0 | test.rs:155:16:155:20 | ... > ... | | +| test.rs:156:17:156:28 | BreakExpr | test.rs:154:13:159:9 | LoopExpr | break | +| test.rs:156:17:156:29 | ExprStmt | test.rs:156:23:156:23 | a | | +| test.rs:156:23:156:23 | a | test.rs:156:27:156:28 | 10 | | +| test.rs:156:23:156:28 | ... > ... | test.rs:156:17:156:28 | BreakExpr | | +| test.rs:156:27:156:28 | 10 | test.rs:156:23:156:28 | ... > ... | | +| test.rs:158:13:158:13 | a | test.rs:158:17:158:18 | 10 | | +| test.rs:158:13:158:18 | ... < ... | test.rs:154:18:159:9 | BlockExpr | | +| test.rs:158:13:158:19 | ExprStmt | test.rs:158:13:158:13 | a | | +| test.rs:158:17:158:18 | 10 | test.rs:158:13:158:18 | ... < ... | | +| test.rs:159:12:161:9 | BlockExpr | test.rs:154:9:163:9 | IfExpr | | +| test.rs:160:13:160:13 | 1 | test.rs:159:12:161:9 | BlockExpr | | +| test.rs:161:16:163:9 | BlockExpr | test.rs:154:9:163:9 | IfExpr | | +| test.rs:162:13:162:13 | 0 | test.rs:161:16:163:9 | BlockExpr | | +| test.rs:166:5:177:5 | enter test_if_loop2 | test.rs:168:13:170:14 | ExprStmt | | +| test.rs:166:5:177:5 | exit test_if_loop2 (normal) | test.rs:166:5:177:5 | exit test_if_loop2 | | +| test.rs:166:37:177:5 | BlockExpr | test.rs:166:5:177:5 | exit test_if_loop2 (normal) | | +| test.rs:167:9:176:9 | IfExpr | test.rs:166:37:177:5 | BlockExpr | | +| test.rs:167:12:172:10 | ParenExpr | test.rs:173:13:173:13 | 1 | true | +| test.rs:167:12:172:10 | ParenExpr | test.rs:175:13:175:13 | 0 | false | +| test.rs:167:13:172:9 | LoopExpr | test.rs:167:12:172:10 | ParenExpr | | +| test.rs:167:26:172:9 | BlockExpr | test.rs:168:13:170:14 | ExprStmt | | +| test.rs:168:13:170:13 | IfExpr | test.rs:171:13:171:19 | ExprStmt | | +| test.rs:168:13:170:14 | ExprStmt | test.rs:168:16:168:16 | a | | +| test.rs:168:16:168:16 | a | test.rs:168:20:168:20 | 0 | | +| test.rs:168:16:168:20 | ... > ... | test.rs:168:13:170:13 | IfExpr | false | +| test.rs:168:16:168:20 | ... > ... | test.rs:169:17:169:36 | ExprStmt | true | +| test.rs:168:20:168:20 | 0 | test.rs:168:16:168:20 | ... > ... | | +| test.rs:169:17:169:35 | BreakExpr | test.rs:167:13:172:9 | LoopExpr | break('label) | +| test.rs:169:17:169:36 | ExprStmt | test.rs:169:30:169:30 | a | | +| test.rs:169:30:169:30 | a | test.rs:169:34:169:35 | 10 | | +| test.rs:169:30:169:35 | ... > ... | test.rs:169:17:169:35 | BreakExpr | | +| test.rs:169:34:169:35 | 10 | test.rs:169:30:169:35 | ... > ... | | +| test.rs:171:13:171:13 | a | test.rs:171:17:171:18 | 10 | | +| test.rs:171:13:171:18 | ... < ... | test.rs:167:26:172:9 | BlockExpr | | +| test.rs:171:13:171:19 | ExprStmt | test.rs:171:13:171:13 | a | | +| test.rs:171:17:171:18 | 10 | test.rs:171:13:171:18 | ... < ... | | +| test.rs:172:12:174:9 | BlockExpr | test.rs:167:9:176:9 | IfExpr | | +| test.rs:173:13:173:13 | 1 | test.rs:172:12:174:9 | BlockExpr | | +| test.rs:174:16:176:9 | BlockExpr | test.rs:167:9:176:9 | IfExpr | | +| test.rs:175:13:175:13 | 0 | test.rs:174:16:176:9 | BlockExpr | | +| test.rs:179:5:187:5 | enter test_labelled_block | test.rs:181:13:181:31 | ExprStmt | | +| test.rs:179:5:187:5 | exit test_labelled_block (normal) | test.rs:179:5:187:5 | exit test_labelled_block | | +| test.rs:181:13:181:30 | BreakExpr | test.rs:179:5:187:5 | exit test_labelled_block (normal) | break('block) | +| test.rs:181:13:181:31 | ExprStmt | test.rs:181:26:181:26 | a | | +| test.rs:181:26:181:26 | a | test.rs:181:30:181:30 | 0 | | +| test.rs:181:26:181:30 | ... > ... | test.rs:181:13:181:30 | BreakExpr | | +| test.rs:181:30:181:30 | 0 | test.rs:181:26:181:30 | ... > ... | | +| test.rs:192:5:195:5 | enter test_and_operator | test.rs:193:9:193:28 | LetStmt | | +| test.rs:192:5:195:5 | exit test_and_operator (normal) | test.rs:192:5:195:5 | exit test_and_operator | | +| test.rs:192:61:195:5 | BlockExpr | test.rs:192:5:195:5 | exit test_and_operator (normal) | | +| test.rs:193:9:193:28 | LetStmt | test.rs:193:17:193:27 | ... && ... | | +| test.rs:193:13:193:13 | d | test.rs:194:9:194:9 | d | match, no-match | +| test.rs:193:17:193:17 | a | test.rs:193:13:193:13 | d | false | +| test.rs:193:17:193:17 | a | test.rs:193:22:193:22 | b | true | +| test.rs:193:17:193:22 | ... && ... | test.rs:193:17:193:17 | a | | +| test.rs:193:17:193:27 | ... && ... | test.rs:193:17:193:22 | ... && ... | | +| test.rs:193:22:193:22 | b | test.rs:193:13:193:13 | d | false | +| test.rs:193:22:193:22 | b | test.rs:193:27:193:27 | c | true | +| test.rs:193:27:193:27 | c | test.rs:193:13:193:13 | d | | +| test.rs:194:9:194:9 | d | test.rs:192:61:195:5 | BlockExpr | | +| test.rs:197:5:200:5 | enter test_or_operator | test.rs:198:9:198:28 | LetStmt | | +| test.rs:197:5:200:5 | exit test_or_operator (normal) | test.rs:197:5:200:5 | exit test_or_operator | | +| test.rs:197:60:200:5 | BlockExpr | test.rs:197:5:200:5 | exit test_or_operator (normal) | | +| test.rs:198:9:198:28 | LetStmt | test.rs:198:17:198:27 | ... \|\| ... | | +| test.rs:198:13:198:13 | d | test.rs:199:9:199:9 | d | match, no-match | +| test.rs:198:17:198:17 | a | test.rs:198:13:198:13 | d | true | +| test.rs:198:17:198:17 | a | test.rs:198:22:198:22 | b | false | +| test.rs:198:17:198:22 | ... \|\| ... | test.rs:198:17:198:17 | a | | +| test.rs:198:17:198:27 | ... \|\| ... | test.rs:198:17:198:22 | ... \|\| ... | | +| test.rs:198:22:198:22 | b | test.rs:198:13:198:13 | d | true | +| test.rs:198:22:198:22 | b | test.rs:198:27:198:27 | c | false | +| test.rs:198:27:198:27 | c | test.rs:198:13:198:13 | d | | +| test.rs:199:9:199:9 | d | test.rs:197:60:200:5 | BlockExpr | | +| test.rs:202:5:205:5 | enter test_or_operator_2 | test.rs:203:9:203:36 | LetStmt | | +| test.rs:202:5:205:5 | exit test_or_operator_2 (normal) | test.rs:202:5:205:5 | exit test_or_operator_2 | | +| test.rs:202:61:205:5 | BlockExpr | test.rs:202:5:205:5 | exit test_or_operator_2 (normal) | | +| test.rs:203:9:203:36 | LetStmt | test.rs:203:17:203:35 | ... \|\| ... | | +| test.rs:203:13:203:13 | d | test.rs:204:9:204:9 | d | match, no-match | +| test.rs:203:17:203:17 | a | test.rs:203:13:203:13 | d | true | +| test.rs:203:17:203:17 | a | test.rs:203:23:203:23 | b | false | +| test.rs:203:17:203:30 | ... \|\| ... | test.rs:203:17:203:17 | a | | +| test.rs:203:17:203:35 | ... \|\| ... | test.rs:203:17:203:30 | ... \|\| ... | | +| test.rs:203:22:203:30 | ParenExpr | test.rs:203:13:203:13 | d | true | +| test.rs:203:22:203:30 | ParenExpr | test.rs:203:35:203:35 | c | false | +| test.rs:203:23:203:23 | b | test.rs:203:28:203:29 | 28 | | +| test.rs:203:23:203:29 | ... == ... | test.rs:203:22:203:30 | ParenExpr | | +| test.rs:203:28:203:29 | 28 | test.rs:203:23:203:29 | ... == ... | | +| test.rs:203:35:203:35 | c | test.rs:203:13:203:13 | d | | +| test.rs:204:9:204:9 | d | test.rs:202:61:205:5 | BlockExpr | | +| test.rs:207:5:210:5 | enter test_not_operator | test.rs:208:9:208:19 | LetStmt | | +| test.rs:207:5:210:5 | exit test_not_operator (normal) | test.rs:207:5:210:5 | exit test_not_operator | | +| test.rs:207:43:210:5 | BlockExpr | test.rs:207:5:210:5 | exit test_not_operator (normal) | | +| test.rs:208:9:208:19 | LetStmt | test.rs:208:18:208:18 | a | | +| test.rs:208:13:208:13 | d | test.rs:209:9:209:9 | d | match, no-match | +| test.rs:208:17:208:18 | ! ... | test.rs:208:13:208:13 | d | | +| test.rs:208:18:208:18 | a | test.rs:208:17:208:18 | ! ... | | +| test.rs:209:9:209:9 | d | test.rs:207:43:210:5 | BlockExpr | | +| test.rs:212:5:218:5 | enter test_if_and_operator | test.rs:213:12:213:22 | ... && ... | | +| test.rs:212:5:218:5 | exit test_if_and_operator (normal) | test.rs:212:5:218:5 | exit test_if_and_operator | | +| test.rs:212:63:218:5 | BlockExpr | test.rs:212:5:218:5 | exit test_if_and_operator (normal) | | +| test.rs:213:9:217:9 | IfExpr | test.rs:212:63:218:5 | BlockExpr | | +| test.rs:213:12:213:12 | a | test.rs:213:17:213:17 | b | true | +| test.rs:213:12:213:12 | a | test.rs:216:13:216:17 | false | false | +| test.rs:213:12:213:17 | ... && ... | test.rs:213:12:213:12 | a | | +| test.rs:213:12:213:22 | ... && ... | test.rs:213:12:213:17 | ... && ... | | +| test.rs:213:17:213:17 | b | test.rs:213:22:213:22 | c | true | +| test.rs:213:17:213:17 | b | test.rs:216:13:216:17 | false | false | +| test.rs:213:22:213:22 | c | test.rs:214:13:214:16 | true | true | +| test.rs:213:22:213:22 | c | test.rs:216:13:216:17 | false | false | +| test.rs:213:24:215:9 | BlockExpr | test.rs:213:9:217:9 | IfExpr | | +| test.rs:214:13:214:16 | true | test.rs:213:24:215:9 | BlockExpr | | +| test.rs:215:16:217:9 | BlockExpr | test.rs:213:9:217:9 | IfExpr | | +| test.rs:216:13:216:17 | false | test.rs:215:16:217:9 | BlockExpr | | +| test.rs:220:5:226:5 | enter test_if_or_operator | test.rs:221:12:221:22 | ... \|\| ... | | +| test.rs:220:5:226:5 | exit test_if_or_operator (normal) | test.rs:220:5:226:5 | exit test_if_or_operator | | +| test.rs:220:62:226:5 | BlockExpr | test.rs:220:5:226:5 | exit test_if_or_operator (normal) | | +| test.rs:221:9:225:9 | IfExpr | test.rs:220:62:226:5 | BlockExpr | | +| test.rs:221:12:221:12 | a | test.rs:221:17:221:17 | b | false | +| test.rs:221:12:221:12 | a | test.rs:222:13:222:16 | true | true | +| test.rs:221:12:221:17 | ... \|\| ... | test.rs:221:12:221:12 | a | | +| test.rs:221:12:221:22 | ... \|\| ... | test.rs:221:12:221:17 | ... \|\| ... | | +| test.rs:221:17:221:17 | b | test.rs:221:22:221:22 | c | false | +| test.rs:221:17:221:17 | b | test.rs:222:13:222:16 | true | true | +| test.rs:221:22:221:22 | c | test.rs:222:13:222:16 | true | true | +| test.rs:221:22:221:22 | c | test.rs:224:13:224:17 | false | false | +| test.rs:221:24:223:9 | BlockExpr | test.rs:221:9:225:9 | IfExpr | | +| test.rs:222:13:222:16 | true | test.rs:221:24:223:9 | BlockExpr | | +| test.rs:223:16:225:9 | BlockExpr | test.rs:221:9:225:9 | IfExpr | | +| test.rs:224:13:224:17 | false | test.rs:223:16:225:9 | BlockExpr | | +| test.rs:228:5:234:5 | enter test_if_not_operator | test.rs:229:13:229:13 | a | | +| test.rs:228:5:234:5 | exit test_if_not_operator (normal) | test.rs:228:5:234:5 | exit test_if_not_operator | | +| test.rs:228:46:234:5 | BlockExpr | test.rs:228:5:234:5 | exit test_if_not_operator (normal) | | +| test.rs:229:9:233:9 | IfExpr | test.rs:228:46:234:5 | BlockExpr | | +| test.rs:229:12:229:13 | ! ... | test.rs:230:13:230:16 | true | true | +| test.rs:229:12:229:13 | ! ... | test.rs:232:13:232:17 | false | false | +| test.rs:229:13:229:13 | a | test.rs:229:12:229:13 | ! ... | false, true | +| test.rs:229:15:231:9 | BlockExpr | test.rs:229:9:233:9 | IfExpr | | +| test.rs:230:13:230:16 | true | test.rs:229:15:231:9 | BlockExpr | | +| test.rs:231:16:233:9 | BlockExpr | test.rs:229:9:233:9 | IfExpr | | +| test.rs:232:13:232:17 | false | test.rs:231:16:233:9 | BlockExpr | | +| test.rs:237:1:243:1 | enter test_match | test.rs:238:11:238:21 | maybe_digit | | +| test.rs:237:1:243:1 | exit test_match (normal) | test.rs:237:1:243:1 | exit test_match | | +| test.rs:237:48:243:1 | BlockExpr | test.rs:237:1:243:1 | exit test_match (normal) | | +| test.rs:238:5:242:5 | MatchExpr | test.rs:237:48:243:1 | BlockExpr | | +| test.rs:238:11:238:21 | maybe_digit | test.rs:239:9:239:23 | TupleStructPat | | +| test.rs:239:9:239:23 | TupleStructPat | test.rs:239:28:239:28 | x | match | +| test.rs:239:9:239:23 | TupleStructPat | test.rs:240:9:240:23 | TupleStructPat | no-match | +| test.rs:239:28:239:28 | x | test.rs:239:32:239:33 | 10 | | +| test.rs:239:28:239:33 | ... < ... | test.rs:239:38:239:38 | x | true | +| test.rs:239:28:239:33 | ... < ... | test.rs:240:9:240:23 | TupleStructPat | false | +| test.rs:239:32:239:33 | 10 | test.rs:239:28:239:33 | ... < ... | | +| test.rs:239:38:239:38 | x | test.rs:239:42:239:42 | 5 | | +| test.rs:239:38:239:42 | ... + ... | test.rs:238:5:242:5 | MatchExpr | | +| test.rs:239:42:239:42 | 5 | test.rs:239:38:239:42 | ... + ... | | +| test.rs:240:9:240:23 | TupleStructPat | test.rs:240:28:240:28 | x | match | +| test.rs:240:9:240:23 | TupleStructPat | test.rs:241:9:241:20 | PathPat | no-match | +| test.rs:240:28:240:28 | x | test.rs:238:5:242:5 | MatchExpr | | +| test.rs:241:9:241:20 | PathPat | test.rs:241:25:241:25 | 5 | match | +| test.rs:241:25:241:25 | 5 | test.rs:238:5:242:5 | MatchExpr | | +| test.rs:246:5:251:5 | enter test_infinite_loop | test.rs:247:9:249:9 | ExprStmt | | +| test.rs:247:9:249:9 | ExprStmt | test.rs:248:13:248:13 | 1 | | +| test.rs:247:14:249:9 | BlockExpr | test.rs:248:13:248:13 | 1 | | +| test.rs:248:13:248:13 | 1 | test.rs:247:14:249:9 | BlockExpr | | +| test.rs:253:5:256:5 | enter test_let_match | test.rs:254:9:254:49 | LetStmt | | +| test.rs:253:5:256:5 | exit test_let_match (normal) | test.rs:253:5:256:5 | exit test_let_match | | +| test.rs:253:39:256:5 | BlockExpr | test.rs:253:5:256:5 | exit test_let_match (normal) | | +| test.rs:254:9:254:49 | LetStmt | test.rs:254:23:254:23 | a | | +| test.rs:254:13:254:19 | TupleStructPat | test.rs:254:32:254:46 | "Expected some" | no-match | +| test.rs:254:13:254:19 | TupleStructPat | test.rs:255:9:255:9 | n | match | +| test.rs:254:23:254:23 | a | test.rs:254:13:254:19 | TupleStructPat | | +| test.rs:254:32:254:46 | "Expected some" | test.rs:254:30:254:48 | BlockExpr | | +| test.rs:255:9:255:9 | n | test.rs:253:39:256:5 | BlockExpr | | +| test.rs:259:1:264:1 | enter dead_code | test.rs:260:5:262:5 | ExprStmt | | +| test.rs:259:1:264:1 | exit dead_code (normal) | test.rs:259:1:264:1 | exit dead_code | | +| test.rs:260:5:262:5 | ExprStmt | test.rs:260:9:260:12 | true | | +| test.rs:260:8:260:13 | ParenExpr | test.rs:261:9:261:17 | ExprStmt | true | +| test.rs:260:9:260:12 | true | test.rs:260:8:260:13 | ParenExpr | | +| test.rs:261:9:261:16 | ReturnExpr | test.rs:259:1:264:1 | exit dead_code (normal) | return | +| test.rs:261:9:261:17 | ExprStmt | test.rs:261:16:261:16 | 0 | | +| test.rs:261:16:261:16 | 0 | test.rs:261:9:261:16 | ReturnExpr | | +| test.rs:266:1:279:1 | enter labelled_block1 | test.rs:267:5:278:6 | LetStmt | | +| test.rs:266:1:279:1 | exit labelled_block1 (normal) | test.rs:266:1:279:1 | exit labelled_block1 | | +| test.rs:266:29:279:1 | BlockExpr | test.rs:266:1:279:1 | exit labelled_block1 (normal) | | +| test.rs:267:5:278:6 | LetStmt | test.rs:268:9:268:19 | ExprStmt | | +| test.rs:267:9:267:14 | result | test.rs:266:29:279:1 | BlockExpr | match, no-match | +| test.rs:267:18:278:5 | BlockExpr | test.rs:267:9:267:14 | result | | +| test.rs:268:9:268:16 | PathExpr | test.rs:268:9:268:18 | CallExpr | | +| test.rs:268:9:268:18 | CallExpr | test.rs:269:9:271:9 | ExprStmt | | +| test.rs:268:9:268:19 | ExprStmt | test.rs:268:9:268:16 | PathExpr | | +| test.rs:269:9:271:9 | ExprStmt | test.rs:269:12:269:28 | PathExpr | | +| test.rs:269:9:271:9 | IfExpr | test.rs:272:9:272:24 | ExprStmt | | +| test.rs:269:12:269:28 | PathExpr | test.rs:269:12:269:30 | CallExpr | | +| test.rs:269:12:269:30 | CallExpr | test.rs:269:9:271:9 | IfExpr | false | +| test.rs:269:12:269:30 | CallExpr | test.rs:270:13:270:27 | ExprStmt | true | +| test.rs:270:13:270:26 | BreakExpr | test.rs:266:1:279:1 | exit labelled_block1 (normal) | break('block) | +| test.rs:270:13:270:27 | ExprStmt | test.rs:270:26:270:26 | 1 | | +| test.rs:270:26:270:26 | 1 | test.rs:270:13:270:26 | BreakExpr | | +| test.rs:272:9:272:21 | PathExpr | test.rs:272:9:272:23 | CallExpr | | +| test.rs:272:9:272:23 | CallExpr | test.rs:273:9:275:9 | ExprStmt | | +| test.rs:272:9:272:24 | ExprStmt | test.rs:272:9:272:21 | PathExpr | | +| test.rs:273:9:275:9 | ExprStmt | test.rs:273:12:273:28 | PathExpr | | +| test.rs:273:9:275:9 | IfExpr | test.rs:276:9:276:24 | ExprStmt | | +| test.rs:273:12:273:28 | PathExpr | test.rs:273:12:273:30 | CallExpr | | +| test.rs:273:12:273:30 | CallExpr | test.rs:273:9:275:9 | IfExpr | false | +| test.rs:273:12:273:30 | CallExpr | test.rs:274:13:274:27 | ExprStmt | true | +| test.rs:274:13:274:26 | BreakExpr | test.rs:266:1:279:1 | exit labelled_block1 (normal) | break('block) | +| test.rs:274:13:274:27 | ExprStmt | test.rs:274:26:274:26 | 2 | | +| test.rs:274:26:274:26 | 2 | test.rs:274:13:274:26 | BreakExpr | | +| test.rs:276:9:276:21 | PathExpr | test.rs:276:9:276:23 | CallExpr | | +| test.rs:276:9:276:23 | CallExpr | test.rs:277:9:277:9 | 3 | | +| test.rs:276:9:276:24 | ExprStmt | test.rs:276:9:276:21 | PathExpr | | +| test.rs:277:9:277:9 | 3 | test.rs:267:18:278:5 | BlockExpr | | +| test.rs:281:1:289:1 | enter labelled_block2 | test.rs:282:5:288:6 | LetStmt | | +| test.rs:281:1:289:1 | exit labelled_block2 (normal) | test.rs:281:1:289:1 | exit labelled_block2 | | +| test.rs:281:29:289:1 | BlockExpr | test.rs:281:1:289:1 | exit labelled_block2 (normal) | | +| test.rs:282:5:288:6 | LetStmt | test.rs:283:9:283:34 | LetStmt | | +| test.rs:282:9:282:14 | result | test.rs:281:29:289:1 | BlockExpr | match, no-match | +| test.rs:282:18:288:5 | BlockExpr | test.rs:282:9:282:14 | result | | +| test.rs:283:9:283:34 | LetStmt | test.rs:283:30:283:33 | PathExpr | | +| test.rs:283:13:283:13 | x | test.rs:284:9:286:10 | LetStmt | match, no-match | +| test.rs:283:30:283:33 | PathExpr | test.rs:283:13:283:13 | x | | +| test.rs:284:9:286:10 | LetStmt | test.rs:284:23:284:23 | x | | +| test.rs:284:13:284:19 | TupleStructPat | test.rs:285:13:285:27 | ExprStmt | no-match | +| test.rs:284:13:284:19 | TupleStructPat | test.rs:287:9:287:9 | x | match | +| test.rs:284:23:284:23 | x | test.rs:284:13:284:19 | TupleStructPat | | +| test.rs:285:13:285:26 | BreakExpr | test.rs:281:1:289:1 | exit labelled_block2 (normal) | break('block) | +| test.rs:285:13:285:27 | ExprStmt | test.rs:285:26:285:26 | 1 | | +| test.rs:285:26:285:26 | 1 | test.rs:285:13:285:26 | BreakExpr | | +| test.rs:287:9:287:9 | x | test.rs:282:18:288:5 | BlockExpr | | diff --git a/rust/ql/test/library-tests/controlflow/test.rs b/rust/ql/test/library-tests/controlflow/test.rs index dd1659ee997b..22d8b9f24a60 100644 --- a/rust/ql/test/library-tests/controlflow/test.rs +++ b/rust/ql/test/library-tests/controlflow/test.rs @@ -62,6 +62,15 @@ mod loop_expression { } } + fn test_while_let() { + let mut iter = 1..10; + while let Some(x) = iter.next() { + if (i = 5) { + break; + } + } + } + fn test_for(j: i64) { for i in 0..10 { if (i == j) { @@ -254,7 +263,7 @@ fn dead_code() -> i64 { return 1; } -fn labelled_block() -> i64 { +fn labelled_block1() -> i64 { let result = 'block: { do_thing(); if condition_not_met() { @@ -268,3 +277,13 @@ fn labelled_block() -> i64 { 3 }; } + +fn labelled_block2() -> i64 { + let result = 'block: { + let x: Option = None; + let Some(y) = x else { + break 'block 1; + }; + x + }; +} From 071076875cf5a6f7e133f08fab6ed403ffbf3f64 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Oct 2024 15:02:00 +0200 Subject: [PATCH 103/347] Rust: Make more CFG nodes leaves --- .../internal/ControlFlowGraphImpl.qll | 26 ++----------------- 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 177651bf1ca8..62a58df2d1f0 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -230,6 +230,8 @@ class IndexExprTree extends StandardPostOrderTree instanceof IndexExpr { } } +class ItemTree extends LeafTree, Item { } + // `LetExpr` is a pre-order tree such that the pattern itself ends up // dominating successors in the graph in the same way that patterns do in // `match` expressions. @@ -472,18 +474,6 @@ class ParenExprTree extends StandardPostOrderTree, ParenExpr { // This covers all patterns as they all extend `Pat` class PatExprTree extends LeafTree instanceof Pat { } -class PathTree extends StandardPostOrderTree, Path { - override AstNode getChildNode(int i) { - i = 0 and result = this.getQualifier() - or - i = 1 and result = this.getPart() - } -} - -class PathSegmentTree extends StandardPostOrderTree, PathSegment { - override AstNode getChildNode(int i) { i = 0 and result = this.getNameRef() } -} - class PathExprTree extends LeafTree instanceof PathExpr { } class PrefixExprTree extends StandardPostOrderTree instanceof PrefixExpr { @@ -522,14 +512,6 @@ class ReturnExprTree extends PostOrderTree instanceof ReturnExpr { } } -class StaticTree extends StandardPostOrderTree, Static { - override AstNode getChildNode(int i) { - i = 0 and result = this.getName() - or - i = 1 and result = this.getBody() - } -} - class TupleExprTree extends StandardPostOrderTree instanceof TupleExpr { override AstNode getChildNode(int i) { result = super.getField(i) } } @@ -538,10 +520,6 @@ class TypeRefTree extends LeafTree instanceof TypeRef { } class UnderscoreExprTree extends LeafTree instanceof UnderscoreExpr { } -class UseTree_ extends StandardPreOrderTree, Use { - override AstNode getChildNode(int i) { i = 0 and result = this.getUseTree().getPath() } -} - // NOTE: `yield` is a reserved but unused keyword. class YieldExprTree extends StandardPostOrderTree instanceof YieldExpr { override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() } From 85957767c99b5c78900886f6be95b11af650b9a0 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Oct 2024 15:07:35 +0200 Subject: [PATCH 104/347] Rust: Fix CFG for `while let` loops --- .../controlflow/internal/ControlFlowGraphImpl.qll | 12 +++++++++--- .../ql/test/library-tests/controlflow/Cfg.expected | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 62a58df2d1f0..c32e828a5584 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -193,7 +193,7 @@ class IfExprTree extends PostOrderTree instanceof IfExpr { child = [super.getCondition(), super.getThen(), super.getElse()] } - ConditionalCompletion conditionCompletion(Completion c) { + private ConditionalCompletion conditionCompletion(Completion c) { if super.getCondition() instanceof LetExpr then result = c.(MatchCompletion) else result = c.(BooleanCompletion) @@ -345,15 +345,21 @@ class WhileExprTree extends LoopingExprTree instanceof WhileExpr { override predicate first(AstNode node) { first(super.getCondition(), node) } + private ConditionalCompletion conditionCompletion(Completion c) { + if super.getCondition() instanceof LetExpr + then result = c.(MatchCompletion) + else result = c.(BooleanCompletion) + } + override predicate succ(AstNode pred, AstNode succ, Completion c) { super.succ(pred, succ, c) or last(super.getCondition(), pred, c) and - c.(BooleanCompletion).succeeded() and + this.conditionCompletion(c).succeeded() and first(this.getLoopBody(), succ) or last(super.getCondition(), pred, c) and - c.(BooleanCompletion).failed() and + this.conditionCompletion(c).failed() and succ = this } diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index d5097158874d..c04e7e20be2f 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -123,12 +123,26 @@ | test.rs:61:13:61:22 | ExprStmt | test.rs:61:13:61:13 | PathExpr | | | test.rs:61:17:61:21 | false | test.rs:61:13:61:21 | ... = ... | | | test.rs:65:5:72:5 | enter test_while_let | test.rs:66:9:66:29 | LetStmt | | +| test.rs:65:5:72:5 | exit test_while_let (normal) | test.rs:65:5:72:5 | exit test_while_let | | +| test.rs:65:25:72:5 | BlockExpr | test.rs:65:5:72:5 | exit test_while_let (normal) | | | test.rs:66:9:66:29 | LetStmt | test.rs:66:24:66:24 | 1 | | | test.rs:66:13:66:20 | iter | test.rs:67:15:67:39 | LetExpr | match, no-match | | test.rs:66:24:66:24 | 1 | test.rs:66:27:66:28 | 10 | | | test.rs:66:24:66:28 | RangeExpr | test.rs:66:13:66:20 | iter | | | test.rs:66:27:66:28 | 10 | test.rs:66:24:66:28 | RangeExpr | | +| test.rs:67:9:71:9 | WhileExpr | test.rs:65:25:72:5 | BlockExpr | | | test.rs:67:15:67:39 | LetExpr | test.rs:67:19:67:25 | TupleStructPat | | +| test.rs:67:19:67:25 | TupleStructPat | test.rs:67:9:71:9 | WhileExpr | no-match | +| test.rs:67:19:67:25 | TupleStructPat | test.rs:68:17:68:17 | PathExpr | match | +| test.rs:67:41:71:9 | BlockExpr | test.rs:67:15:67:39 | LetExpr | | +| test.rs:68:13:70:13 | IfExpr | test.rs:67:41:71:9 | BlockExpr | | +| test.rs:68:16:68:22 | ParenExpr | test.rs:68:13:70:13 | IfExpr | false | +| test.rs:68:16:68:22 | ParenExpr | test.rs:69:17:69:22 | ExprStmt | true | +| test.rs:68:17:68:17 | PathExpr | test.rs:68:21:68:21 | 5 | | +| test.rs:68:17:68:21 | ... = ... | test.rs:68:16:68:22 | ParenExpr | | +| test.rs:68:21:68:21 | 5 | test.rs:68:17:68:21 | ... = ... | | +| test.rs:69:17:69:21 | BreakExpr | test.rs:67:9:71:9 | WhileExpr | break | +| test.rs:69:17:69:22 | ExprStmt | test.rs:69:17:69:21 | BreakExpr | | | test.rs:74:5:81:5 | enter test_for | test.rs:75:18:75:18 | 0 | | | test.rs:74:5:81:5 | exit test_for (normal) | test.rs:74:5:81:5 | exit test_for | | | test.rs:74:25:81:5 | BlockExpr | test.rs:74:5:81:5 | exit test_for (normal) | | From e8cb3490e6aac54fe2da5a7de908399b34aca237 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Oct 2024 20:21:49 +0200 Subject: [PATCH 105/347] Rust: Refine `deadEnd` consistency check --- rust/ql/consistency-queries/CfgConsistency.ql | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/rust/ql/consistency-queries/CfgConsistency.ql b/rust/ql/consistency-queries/CfgConsistency.ql index 52b44170a397..68e0e82076eb 100644 --- a/rust/ql/consistency-queries/CfgConsistency.ql +++ b/rust/ql/consistency-queries/CfgConsistency.ql @@ -26,8 +26,13 @@ query predicate scopeNoFirst(CfgScope scope) { not scope = any(ClosureExpr c | not exists(c.getBody())) } +/** Holds if `be` is the `else` branch of a `let` statement that results in a panic. */ +private predicate letElsePanic(BlockExpr be) { + be = any(LetStmt let).getLetElse().getBlockExpr() and + exists(Completion c | CfgImpl::last(be, _, c) | completionIsNormal(c)) +} + query predicate deadEnd(CfgImpl::Node node) { Consistency::deadEnd(node) and - // `else` blocks in `let` statements diverge, so they are by definition dead ends - not node.getAstNode() = any(LetStmt let).getLetElse().getBlockExpr() + not letElsePanic(node.getAstNode()) } From 8b66dc16adbb77b62bfa9d5cfe2a47a7e639ac12 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Oct 2024 20:47:42 +0200 Subject: [PATCH 106/347] Rust: Fix CFG for labelled block expressions --- .../internal/ControlFlowGraphImpl.qll | 30 +++++++++++++++++-- .../library-tests/controlflow/Cfg.expected | 17 ++++++++--- 2 files changed, 41 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 c32e828a5584..89d6750f1e28 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -136,7 +136,7 @@ class LogicalAndBinaryOpExprTree extends PreOrderTree, LogicalAndExpr { } } -class BlockExprBaseTree extends StandardPostOrderTree instanceof BlockExpr { +class BlockExprTree extends StandardPostOrderTree, BlockExpr { override AstNode getChildNode(int i) { result = super.getStmtList().getStatement(i) or @@ -144,6 +144,32 @@ class BlockExprBaseTree extends StandardPostOrderTree instanceof BlockExpr { (exists(super.getStmtList().getStatement(i - 1)) or i = 0) and result = super.getStmtList().getTailExpr() } + + override predicate propagatesAbnormal(AstNode child) { none() } + + /** Holds if this block captures the break completion `c`. */ + private predicate capturesBreakCompletion(LoopJumpCompletion c) { + c.isBreak() and + c.getLabelName() = this.getLabel().getLifetime().getText() + } + + override predicate succ(AstNode pred, AstNode succ, Completion c) { + super.succ(pred, succ, c) + or + // Edge for exiting the block with a break expressions + last(this.getChildNode(_), pred, c) and + this.capturesBreakCompletion(c) and + succ = this + } + + override predicate last(AstNode last, Completion c) { + super.last(last, c) + or + // Any abnormal completions that this block does not capture should propagate + last(this.getChildNode(_), last, c) and + not completionIsNormal(c) and + not this.capturesBreakCompletion(c) + } } class BreakExprTree extends PostOrderTree instanceof BreakExpr { @@ -293,7 +319,7 @@ abstract class LoopingExprTree extends PostOrderTree { abstract predicate entry(AstNode node); /** Holds if this loop captures the `c` completion. */ - predicate capturesLoopJumpCompletion(LoopJumpCompletion c) { + private predicate capturesLoopJumpCompletion(LoopJumpCompletion c) { not c.hasLabel() or c.getLabelName() = this.getLabel().getLifetime().getText() diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index c04e7e20be2f..e9e0addf52be 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -343,11 +343,20 @@ | test.rs:175:13:175:13 | 0 | test.rs:174:16:176:9 | BlockExpr | | | test.rs:179:5:187:5 | enter test_labelled_block | test.rs:181:13:181:31 | ExprStmt | | | test.rs:179:5:187:5 | exit test_labelled_block (normal) | test.rs:179:5:187:5 | exit test_labelled_block | | -| test.rs:181:13:181:30 | BreakExpr | test.rs:179:5:187:5 | exit test_labelled_block (normal) | break('block) | +| test.rs:179:43:187:5 | BlockExpr | test.rs:179:5:187:5 | exit test_labelled_block (normal) | | +| test.rs:180:9:186:9 | IfExpr | test.rs:179:43:187:5 | BlockExpr | | +| test.rs:180:12:182:10 | ParenExpr | test.rs:183:13:183:13 | 1 | true | +| test.rs:180:12:182:10 | ParenExpr | test.rs:185:13:185:13 | 0 | false | +| test.rs:180:13:182:9 | BlockExpr | test.rs:180:12:182:10 | ParenExpr | | +| test.rs:181:13:181:30 | BreakExpr | test.rs:180:13:182:9 | BlockExpr | break('block) | | test.rs:181:13:181:31 | ExprStmt | test.rs:181:26:181:26 | a | | | test.rs:181:26:181:26 | a | test.rs:181:30:181:30 | 0 | | | test.rs:181:26:181:30 | ... > ... | test.rs:181:13:181:30 | BreakExpr | | | test.rs:181:30:181:30 | 0 | test.rs:181:26:181:30 | ... > ... | | +| test.rs:182:12:184:9 | BlockExpr | test.rs:180:9:186:9 | IfExpr | | +| test.rs:183:13:183:13 | 1 | test.rs:182:12:184:9 | BlockExpr | | +| test.rs:184:16:186:9 | BlockExpr | test.rs:180:9:186:9 | IfExpr | | +| test.rs:185:13:185:13 | 0 | test.rs:184:16:186:9 | BlockExpr | | | test.rs:192:5:195:5 | enter test_and_operator | test.rs:193:9:193:28 | LetStmt | | | test.rs:192:5:195:5 | exit test_and_operator (normal) | test.rs:192:5:195:5 | exit test_and_operator | | | test.rs:192:61:195:5 | BlockExpr | test.rs:192:5:195:5 | exit test_and_operator (normal) | | @@ -495,7 +504,7 @@ | test.rs:269:12:269:28 | PathExpr | test.rs:269:12:269:30 | CallExpr | | | test.rs:269:12:269:30 | CallExpr | test.rs:269:9:271:9 | IfExpr | false | | test.rs:269:12:269:30 | CallExpr | test.rs:270:13:270:27 | ExprStmt | true | -| test.rs:270:13:270:26 | BreakExpr | test.rs:266:1:279:1 | exit labelled_block1 (normal) | break('block) | +| test.rs:270:13:270:26 | BreakExpr | test.rs:267:18:278:5 | BlockExpr | break('block) | | test.rs:270:13:270:27 | ExprStmt | test.rs:270:26:270:26 | 1 | | | test.rs:270:26:270:26 | 1 | test.rs:270:13:270:26 | BreakExpr | | | test.rs:272:9:272:21 | PathExpr | test.rs:272:9:272:23 | CallExpr | | @@ -506,7 +515,7 @@ | test.rs:273:12:273:28 | PathExpr | test.rs:273:12:273:30 | CallExpr | | | test.rs:273:12:273:30 | CallExpr | test.rs:273:9:275:9 | IfExpr | false | | test.rs:273:12:273:30 | CallExpr | test.rs:274:13:274:27 | ExprStmt | true | -| test.rs:274:13:274:26 | BreakExpr | test.rs:266:1:279:1 | exit labelled_block1 (normal) | break('block) | +| test.rs:274:13:274:26 | BreakExpr | test.rs:267:18:278:5 | BlockExpr | break('block) | | test.rs:274:13:274:27 | ExprStmt | test.rs:274:26:274:26 | 2 | | | test.rs:274:26:274:26 | 2 | test.rs:274:13:274:26 | BreakExpr | | | test.rs:276:9:276:21 | PathExpr | test.rs:276:9:276:23 | CallExpr | | @@ -526,7 +535,7 @@ | test.rs:284:13:284:19 | TupleStructPat | test.rs:285:13:285:27 | ExprStmt | no-match | | test.rs:284:13:284:19 | TupleStructPat | test.rs:287:9:287:9 | x | match | | test.rs:284:23:284:23 | x | test.rs:284:13:284:19 | TupleStructPat | | -| test.rs:285:13:285:26 | BreakExpr | test.rs:281:1:289:1 | exit labelled_block2 (normal) | break('block) | +| test.rs:285:13:285:26 | BreakExpr | test.rs:282:18:288:5 | BlockExpr | break('block) | | test.rs:285:13:285:27 | ExprStmt | test.rs:285:26:285:26 | 1 | | | test.rs:285:26:285:26 | 1 | test.rs:285:13:285:26 | BreakExpr | | | test.rs:287:9:287:9 | x | test.rs:282:18:288:5 | BlockExpr | | From c4eafb2cf3c91f8bac9e7059c01a2b0fda961f94 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Oct 2024 21:13:38 +0200 Subject: [PATCH 107/347] Rust: Skip `ParenExpr`s in the CFG --- rust/ql/consistency-queries/CfgConsistency.ql | 1 + .../rust/controlflow/internal/Completion.qll | 2 + .../internal/ControlFlowGraphImpl.qll | 14 ++++- .../library-tests/controlflow/Cfg.expected | 56 ++++++++----------- 4 files changed, 38 insertions(+), 35 deletions(-) diff --git a/rust/ql/consistency-queries/CfgConsistency.ql b/rust/ql/consistency-queries/CfgConsistency.ql index 68e0e82076eb..6964b7bbcb18 100644 --- a/rust/ql/consistency-queries/CfgConsistency.ql +++ b/rust/ql/consistency-queries/CfgConsistency.ql @@ -11,6 +11,7 @@ import codeql.rust.controlflow.internal.Completion query predicate nonPostOrderExpr(Expr e, string cls) { cls = e.getPrimaryQlClasses() and not e instanceof LetExpr and + not e instanceof ParenExpr and not e instanceof LogicalAndExpr and // todo not e instanceof LogicalOrExpr and exists(AstNode last, Completion c | diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll index facb3849f71f..4034db5fe288 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll @@ -94,6 +94,8 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion { ) or exists(Expr parent | this.isValidForSpecific0(parent) | + e = parent.(ParenExpr).getExpr() + or parent = any(PrefixExpr expr | expr.getOperatorName() = "!" and diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 89d6750f1e28..236d848c70e4 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -499,8 +499,18 @@ class NameRefTree extends LeafTree, NameRef { } class OffsetOfExprTree extends LeafTree instanceof OffsetOfExpr { } -class ParenExprTree extends StandardPostOrderTree, ParenExpr { - override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() } +class ParenExprTree extends ControlFlowTree, ParenExpr { + private ControlFlowTree expr; + + ParenExprTree() { expr = super.getExpr() } + + override predicate propagatesAbnormal(AstNode child) { expr.propagatesAbnormal(child) } + + override predicate first(AstNode first) { expr.first(first) } + + override predicate last(AstNode last, Completion c) { expr.last(last, c) } + + override predicate succ(AstNode pred, AstNode succ, Completion c) { none() } } // This covers all patterns as they all extend `Pat` diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index e9e0addf52be..aff1576a8294 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -111,10 +111,9 @@ | test.rs:57:13:57:14 | ExprStmt | test.rs:57:13:57:13 | 1 | | | test.rs:58:13:60:13 | ExprStmt | test.rs:58:17:58:17 | i | | | test.rs:58:13:60:13 | IfExpr | test.rs:61:13:61:22 | ExprStmt | | -| test.rs:58:16:58:22 | ParenExpr | test.rs:58:13:60:13 | IfExpr | false | -| test.rs:58:16:58:22 | ParenExpr | test.rs:59:17:59:22 | ExprStmt | true | | test.rs:58:17:58:17 | i | test.rs:58:21:58:21 | 0 | | -| test.rs:58:17:58:21 | ... > ... | test.rs:58:16:58:22 | ParenExpr | | +| test.rs:58:17:58:21 | ... > ... | test.rs:58:13:60:13 | IfExpr | false | +| test.rs:58:17:58:21 | ... > ... | test.rs:59:17:59:22 | ExprStmt | true | | test.rs:58:21:58:21 | 0 | test.rs:58:17:58:21 | ... > ... | | | test.rs:59:17:59:21 | BreakExpr | test.rs:56:9:62:9 | WhileExpr | break | | test.rs:59:17:59:22 | ExprStmt | test.rs:59:17:59:21 | BreakExpr | | @@ -136,10 +135,9 @@ | test.rs:67:19:67:25 | TupleStructPat | test.rs:68:17:68:17 | PathExpr | match | | test.rs:67:41:71:9 | BlockExpr | test.rs:67:15:67:39 | LetExpr | | | test.rs:68:13:70:13 | IfExpr | test.rs:67:41:71:9 | BlockExpr | | -| test.rs:68:16:68:22 | ParenExpr | test.rs:68:13:70:13 | IfExpr | false | -| test.rs:68:16:68:22 | ParenExpr | test.rs:69:17:69:22 | ExprStmt | true | | test.rs:68:17:68:17 | PathExpr | test.rs:68:21:68:21 | 5 | | -| test.rs:68:17:68:21 | ... = ... | test.rs:68:16:68:22 | ParenExpr | | +| test.rs:68:17:68:21 | ... = ... | test.rs:68:13:70:13 | IfExpr | false | +| test.rs:68:17:68:21 | ... = ... | test.rs:69:17:69:22 | ExprStmt | true | | test.rs:68:21:68:21 | 5 | test.rs:68:17:68:21 | ... = ... | | | test.rs:69:17:69:21 | BreakExpr | test.rs:67:9:71:9 | WhileExpr | break | | test.rs:69:17:69:22 | ExprStmt | test.rs:69:17:69:21 | BreakExpr | | @@ -155,10 +153,9 @@ | test.rs:75:24:80:9 | BlockExpr | test.rs:75:13:75:13 | i | | | test.rs:76:13:78:13 | ExprStmt | test.rs:76:17:76:17 | i | | | test.rs:76:13:78:13 | IfExpr | test.rs:79:13:79:14 | ExprStmt | | -| test.rs:76:16:76:23 | ParenExpr | test.rs:76:13:78:13 | IfExpr | false | -| test.rs:76:16:76:23 | ParenExpr | test.rs:77:17:77:22 | ExprStmt | true | | test.rs:76:17:76:17 | i | test.rs:76:22:76:22 | j | | -| test.rs:76:17:76:22 | ... == ... | test.rs:76:16:76:23 | ParenExpr | | +| test.rs:76:17:76:22 | ... == ... | test.rs:76:13:78:13 | IfExpr | false | +| test.rs:76:17:76:22 | ... == ... | test.rs:77:17:77:22 | ExprStmt | true | | test.rs:76:22:76:22 | j | test.rs:76:17:76:22 | ... == ... | | | test.rs:77:17:77:21 | BreakExpr | test.rs:75:9:80:9 | ForExpr | break | | test.rs:77:17:77:22 | ExprStmt | test.rs:77:17:77:21 | BreakExpr | | @@ -220,21 +217,20 @@ | test.rs:114:5:120:5 | exit test_nested_if (normal) | test.rs:114:5:120:5 | exit test_nested_if | | | test.rs:114:38:120:5 | BlockExpr | test.rs:114:5:120:5 | exit test_nested_if (normal) | | | test.rs:115:9:119:9 | IfExpr | test.rs:114:38:120:5 | BlockExpr | | -| test.rs:115:12:115:49 | ParenExpr | test.rs:116:13:116:13 | 1 | true | -| test.rs:115:12:115:49 | ParenExpr | test.rs:118:13:118:13 | 0 | false | -| test.rs:115:13:115:48 | IfExpr | test.rs:115:12:115:49 | ParenExpr | | +| test.rs:115:13:115:48 | IfExpr | test.rs:116:13:116:13 | 1 | true | +| test.rs:115:13:115:48 | IfExpr | test.rs:118:13:118:13 | 0 | false | | test.rs:115:16:115:16 | PathExpr | test.rs:115:20:115:20 | 0 | | | test.rs:115:16:115:20 | ... < ... | test.rs:115:24:115:24 | a | true | | test.rs:115:16:115:20 | ... < ... | test.rs:115:41:115:41 | a | false | | test.rs:115:20:115:20 | 0 | test.rs:115:16:115:20 | ... < ... | | -| test.rs:115:22:115:32 | BlockExpr | test.rs:115:13:115:48 | IfExpr | | +| test.rs:115:22:115:32 | BlockExpr | test.rs:115:13:115:48 | IfExpr | false, true | | test.rs:115:24:115:24 | a | test.rs:115:29:115:30 | 10 | | -| test.rs:115:24:115:30 | ... < ... | test.rs:115:22:115:32 | BlockExpr | | +| test.rs:115:24:115:30 | ... < ... | test.rs:115:22:115:32 | BlockExpr | false, true | | test.rs:115:28:115:30 | - ... | test.rs:115:24:115:30 | ... < ... | | | test.rs:115:29:115:30 | 10 | test.rs:115:28:115:30 | - ... | | -| test.rs:115:39:115:48 | BlockExpr | test.rs:115:13:115:48 | IfExpr | | +| test.rs:115:39:115:48 | BlockExpr | test.rs:115:13:115:48 | IfExpr | false, true | | test.rs:115:41:115:41 | a | test.rs:115:45:115:46 | 10 | | -| test.rs:115:41:115:46 | ... > ... | test.rs:115:39:115:48 | BlockExpr | | +| test.rs:115:41:115:46 | ... > ... | test.rs:115:39:115:48 | BlockExpr | false, true | | test.rs:115:45:115:46 | 10 | test.rs:115:41:115:46 | ... > ... | | | test.rs:115:51:117:9 | BlockExpr | test.rs:115:9:119:9 | IfExpr | | | test.rs:116:13:116:13 | 1 | test.rs:115:51:117:9 | BlockExpr | | @@ -244,9 +240,8 @@ | test.rs:122:5:131:5 | exit test_nested_if_match (normal) | test.rs:122:5:131:5 | exit test_nested_if_match | | | test.rs:122:44:131:5 | BlockExpr | test.rs:122:5:131:5 | exit test_nested_if_match (normal) | | | test.rs:123:9:130:9 | IfExpr | test.rs:122:44:131:5 | BlockExpr | | -| test.rs:123:12:126:10 | ParenExpr | test.rs:127:13:127:13 | 1 | true | -| test.rs:123:12:126:10 | ParenExpr | test.rs:129:13:129:13 | 0 | false | -| test.rs:123:13:126:9 | MatchExpr | test.rs:123:12:126:10 | ParenExpr | | +| test.rs:123:13:126:9 | MatchExpr | test.rs:127:13:127:13 | 1 | true | +| test.rs:123:13:126:9 | MatchExpr | test.rs:129:13:129:13 | 0 | false | | test.rs:123:19:123:19 | a | test.rs:124:13:124:13 | LiteralPat | | | test.rs:124:13:124:13 | LiteralPat | test.rs:124:18:124:21 | true | match | | test.rs:124:13:124:13 | LiteralPat | test.rs:125:13:125:13 | WildcardPat | no-match | @@ -291,9 +286,8 @@ | test.rs:153:5:164:5 | exit test_if_loop1 (normal) | test.rs:153:5:164:5 | exit test_if_loop1 | | | test.rs:153:37:164:5 | BlockExpr | test.rs:153:5:164:5 | exit test_if_loop1 (normal) | | | test.rs:154:9:163:9 | IfExpr | test.rs:153:37:164:5 | BlockExpr | | -| test.rs:154:12:159:10 | ParenExpr | test.rs:160:13:160:13 | 1 | true | -| test.rs:154:12:159:10 | ParenExpr | test.rs:162:13:162:13 | 0 | false | -| test.rs:154:13:159:9 | LoopExpr | test.rs:154:12:159:10 | ParenExpr | | +| test.rs:154:13:159:9 | LoopExpr | test.rs:160:13:160:13 | 1 | true | +| test.rs:154:13:159:9 | LoopExpr | test.rs:162:13:162:13 | 0 | false | | test.rs:154:18:159:9 | BlockExpr | test.rs:155:13:157:14 | ExprStmt | | | test.rs:155:13:157:13 | IfExpr | test.rs:158:13:158:19 | ExprStmt | | | test.rs:155:13:157:14 | ExprStmt | test.rs:155:16:155:16 | a | | @@ -318,9 +312,8 @@ | test.rs:166:5:177:5 | exit test_if_loop2 (normal) | test.rs:166:5:177:5 | exit test_if_loop2 | | | test.rs:166:37:177:5 | BlockExpr | test.rs:166:5:177:5 | exit test_if_loop2 (normal) | | | test.rs:167:9:176:9 | IfExpr | test.rs:166:37:177:5 | BlockExpr | | -| test.rs:167:12:172:10 | ParenExpr | test.rs:173:13:173:13 | 1 | true | -| test.rs:167:12:172:10 | ParenExpr | test.rs:175:13:175:13 | 0 | false | -| test.rs:167:13:172:9 | LoopExpr | test.rs:167:12:172:10 | ParenExpr | | +| test.rs:167:13:172:9 | LoopExpr | test.rs:173:13:173:13 | 1 | true | +| test.rs:167:13:172:9 | LoopExpr | test.rs:175:13:175:13 | 0 | false | | test.rs:167:26:172:9 | BlockExpr | test.rs:168:13:170:14 | ExprStmt | | | test.rs:168:13:170:13 | IfExpr | test.rs:171:13:171:19 | ExprStmt | | | test.rs:168:13:170:14 | ExprStmt | test.rs:168:16:168:16 | a | | @@ -345,9 +338,8 @@ | test.rs:179:5:187:5 | exit test_labelled_block (normal) | test.rs:179:5:187:5 | exit test_labelled_block | | | test.rs:179:43:187:5 | BlockExpr | test.rs:179:5:187:5 | exit test_labelled_block (normal) | | | test.rs:180:9:186:9 | IfExpr | test.rs:179:43:187:5 | BlockExpr | | -| test.rs:180:12:182:10 | ParenExpr | test.rs:183:13:183:13 | 1 | true | -| test.rs:180:12:182:10 | ParenExpr | test.rs:185:13:185:13 | 0 | false | -| test.rs:180:13:182:9 | BlockExpr | test.rs:180:12:182:10 | ParenExpr | | +| test.rs:180:13:182:9 | BlockExpr | test.rs:183:13:183:13 | 1 | true | +| test.rs:180:13:182:9 | BlockExpr | test.rs:185:13:185:13 | 0 | false | | test.rs:181:13:181:30 | BreakExpr | test.rs:180:13:182:9 | BlockExpr | break('block) | | test.rs:181:13:181:31 | ExprStmt | test.rs:181:26:181:26 | a | | | test.rs:181:26:181:26 | a | test.rs:181:30:181:30 | 0 | | @@ -392,10 +384,9 @@ | test.rs:203:17:203:17 | a | test.rs:203:23:203:23 | b | false | | test.rs:203:17:203:30 | ... \|\| ... | test.rs:203:17:203:17 | a | | | test.rs:203:17:203:35 | ... \|\| ... | test.rs:203:17:203:30 | ... \|\| ... | | -| test.rs:203:22:203:30 | ParenExpr | test.rs:203:13:203:13 | d | true | -| test.rs:203:22:203:30 | ParenExpr | test.rs:203:35:203:35 | c | false | | test.rs:203:23:203:23 | b | test.rs:203:28:203:29 | 28 | | -| test.rs:203:23:203:29 | ... == ... | test.rs:203:22:203:30 | ParenExpr | | +| test.rs:203:23:203:29 | ... == ... | test.rs:203:13:203:13 | d | true | +| test.rs:203:23:203:29 | ... == ... | test.rs:203:35:203:35 | c | false | | test.rs:203:28:203:29 | 28 | test.rs:203:23:203:29 | ... == ... | | | test.rs:203:35:203:35 | c | test.rs:203:13:203:13 | d | | | test.rs:204:9:204:9 | d | test.rs:202:61:205:5 | BlockExpr | | @@ -485,8 +476,7 @@ | test.rs:259:1:264:1 | enter dead_code | test.rs:260:5:262:5 | ExprStmt | | | test.rs:259:1:264:1 | exit dead_code (normal) | test.rs:259:1:264:1 | exit dead_code | | | test.rs:260:5:262:5 | ExprStmt | test.rs:260:9:260:12 | true | | -| test.rs:260:8:260:13 | ParenExpr | test.rs:261:9:261:17 | ExprStmt | true | -| test.rs:260:9:260:12 | true | test.rs:260:8:260:13 | ParenExpr | | +| test.rs:260:9:260:12 | true | test.rs:261:9:261:17 | ExprStmt | true | | test.rs:261:9:261:16 | ReturnExpr | test.rs:259:1:264:1 | exit dead_code (normal) | return | | test.rs:261:9:261:17 | ExprStmt | test.rs:261:16:261:16 | 0 | | | test.rs:261:16:261:16 | 0 | test.rs:261:9:261:16 | ReturnExpr | | From 8f0b7f0969fd9d0f1cdd2811fdc807d4e3283e7f Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Oct 2024 21:27:36 +0200 Subject: [PATCH 108/347] Rust: Use `propagatesAbnormal` in two places --- .../internal/ControlFlowGraphImpl.qll | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 236d848c70e4..da156cd7767c 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -369,6 +369,8 @@ class WhileExprTree extends LoopingExprTree instanceof WhileExpr { override predicate entry(AstNode node) { this.first(node) } + override predicate propagatesAbnormal(AstNode child) { child = super.getCondition() } + override predicate first(AstNode node) { first(super.getCondition(), node) } private ConditionalCompletion conditionCompletion(Completion c) { @@ -388,13 +390,6 @@ class WhileExprTree extends LoopingExprTree instanceof WhileExpr { this.conditionCompletion(c).failed() and succ = this } - - override predicate last(AstNode last, Completion c) { - super.last(last, c) - or - last(super.getCondition(), last, c) and - not completionIsNormal(c) - } } class ForExprTree extends LoopingExprTree instanceof ForExpr { @@ -404,6 +399,8 @@ class ForExprTree extends LoopingExprTree instanceof ForExpr { override predicate entry(AstNode n) { first(super.getPat(), n) } + override predicate propagatesAbnormal(AstNode child) { child = super.getIterable() } + override predicate first(AstNode node) { first(super.getIterable(), node) } override predicate succ(AstNode pred, AstNode succ, Completion c) { @@ -421,13 +418,6 @@ class ForExprTree extends LoopingExprTree instanceof ForExpr { c.(MatchCompletion).failed() and succ = this } - - override predicate last(AstNode last, Completion c) { - super.last(last, c) - or - last(super.getIterable(), last, c) and - not completionIsNormal(c) - } } // TODO: replace with expanded macro once the extractor supports it From e18389718c87b60696db70c65b02cfb4a8526212 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Thu, 29 Aug 2024 13:34:55 -0400 Subject: [PATCH 109/347] Implement stdin models Unfortunately due to how variable and varargs work, these are better done in QL --- go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll | 9 ++++ go/ql/lib/semmle/go/frameworks/stdlib/Os.qll | 10 ++++ .../dataflow/flowsources/local/stdin/go.mod | 3 ++ .../flowsources/local/stdin/source.ext.yml | 7 +++ .../flowsources/local/stdin/source.ql | 19 ++++++++ .../flowsources/local/stdin/test.expected | 2 + .../flowsources/local/stdin/test.ext.yml | 7 +++ .../dataflow/flowsources/local/stdin/test.go | 48 +++++++++++++++++++ .../dataflow/flowsources/local/stdin/test.ql | 15 ++++++ 9 files changed, 120 insertions(+) create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/go.mod create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.ext.yml create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.ql create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.expected create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.ext.yml create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.go create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.ql diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll index 950b67483f00..54794ea21c9e 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll @@ -112,6 +112,15 @@ module Fmt { Scanner() { this.hasQualifiedName("fmt", ["Scan", "Scanf", "Scanln"]) } } + private class ScannerSource extends SourceNode { + ScannerSource() { + // All of the arguments which are sources are varargs. + this.asExpr() = any(Scanner s).getACall().getAnImplicitVarargsArgument().asExpr() + } + + override string getThreatModel() { result = "stdin" } + } + /** * The `Fscan` function or one of its variants, * all of which read from a specified `io.Reader`. diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll index 72ea4cc6c573..3e443d942b16 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll @@ -43,4 +43,14 @@ module Os { input = inp and output = outp } } + + private class Stdin extends SourceNode { + Stdin() { + exists(Variable osStdin | osStdin.hasQualifiedName("os", "Stdin") | + this.asExpr() = osStdin.getARead().asExpr() + ) + } + + override string getThreatModel() { result = "stdin" } + } } diff --git a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/go.mod b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/go.mod new file mode 100644 index 000000000000..2334541a2f0d --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/go.mod @@ -0,0 +1,3 @@ +module test + +go 1.22.6 diff --git a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.ext.yml new file mode 100644 index 000000000000..92156e87f400 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.ext.yml @@ -0,0 +1,7 @@ +extensions: + + - addsTo: + pack: codeql/threat-models + extensible: threatModelConfiguration + data: + - ["stdin", true, 0] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.ql b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.ql new file mode 100644 index 000000000000..db6bbb1a2d16 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.ql @@ -0,0 +1,19 @@ +import go +import ModelValidation +import TestUtilities.InlineExpectationsTest + +module SourceTest implements TestSig { + string getARelevantTag() { result = "source" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(ThreatModelFlowSource s | + s.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = s.toString() and + value = "" and + tag = "source" + ) + } +} + +import MakeTest diff --git a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.expected b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.expected new file mode 100644 index 000000000000..55e9aed2e93c --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.expected @@ -0,0 +1,2 @@ +testFailures +invalidModelRow diff --git a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.ext.yml new file mode 100644 index 000000000000..92156e87f400 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.ext.yml @@ -0,0 +1,7 @@ +extensions: + + - addsTo: + pack: codeql/threat-models + extensible: threatModelConfiguration + data: + - ["stdin", true, 0] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.go b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.go new file mode 100644 index 000000000000..4166dc4000b0 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.go @@ -0,0 +1,48 @@ +package test + +import ( + "bufio" + "fmt" + "os" +) + +func sink(string) { + +} + +func readStdinBuffer() { + buf := make([]byte, 1024) + n, err := os.Stdin.Read(buf) // $source + if err != nil { + return + } + sink(string(buf[:n])) // $hasTaintFlow="type conversion" +} + +func readStdinBuffReader() { + buf := make([]byte, 1024) + r := bufio.NewReader(os.Stdin) // $source + n, err := r.Read(buf) + if err != nil { + return + } + sink(string(buf[:n])) // $hasTaintFlow="type conversion" +} + +func scan() { + var username, email string + fmt.Scan(&username, &email) // $source + sink(username) // $hasTaintFlow="username" +} + +func scanf() { + var s string + fmt.Scanf("%s", &s) // $source + sink(s) // $hasTaintFlow="s" +} + +func scanl() { + var s string + fmt.Scanln(&s) // $source + sink(s) // $hasTaintFlow="s" +} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.ql b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.ql new file mode 100644 index 000000000000..7c7f587de571 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/test.ql @@ -0,0 +1,15 @@ +import go +import semmle.go.dataflow.ExternalFlow +import ModelValidation +import experimental.frameworks.CleverGo +import TestUtilities.InlineFlowTest + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof ThreatModelFlowSource } + + predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(CallExpr c | c.getTarget().getName() = "sink").getArgument(0) + } +} + +import TaintFlowTest From d80a1487bed5e3f26ac96ecc24fe2433d14aefde Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Thu, 29 Aug 2024 14:27:45 -0400 Subject: [PATCH 110/347] Add change note --- go/ql/lib/change-notes/2024-08-29-add-stdin-threat-models.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 go/ql/lib/change-notes/2024-08-29-add-stdin-threat-models.md diff --git a/go/ql/lib/change-notes/2024-08-29-add-stdin-threat-models.md b/go/ql/lib/change-notes/2024-08-29-add-stdin-threat-models.md new file mode 100644 index 000000000000..f01c843320de --- /dev/null +++ b/go/ql/lib/change-notes/2024-08-29-add-stdin-threat-models.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Local source models with the `stdin` source kind have been added for `os.Stdin`, `fmt.Scan`, `fmt.Scanf`, `fmt.Scanln`. You can optionally include threat models as appropriate when using the CodeQL CLI and in GitHub code scanning. For more information, see [Analyzing your code with CodeQL queries](https://docs.github.com/code-security/codeql-cli/getting-started-with-the-codeql-cli/analyzing-your-code-with-codeql-queries#including-model-packs-to-add-potential-sources-of-tainted-data>) and [Customizing your advanced setup for code scanning](https://docs.github.com/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning#extending-codeql-coverage-with-threat-models). From 26b49dd0dfaa267b502a1f430b899e42ec3aeb2d Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Thu, 29 Aug 2024 15:06:19 -0400 Subject: [PATCH 111/347] Fix test expectation --- .../semmle/go/dataflow/flowsources/local/stdin/source.expected | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.expected diff --git a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.expected b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.expected new file mode 100644 index 000000000000..db33d6d2504a --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.expected @@ -0,0 +1,3 @@ +testFailures +invalidModelRow +failures From 1f932d407f9a38282f4b6c74ee197e9250942443 Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Wed, 4 Sep 2024 09:48:02 -0400 Subject: [PATCH 112/347] Remove unnecessary `asExpr()` Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- go/ql/lib/semmle/go/frameworks/stdlib/Os.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll index 3e443d942b16..492e4b002411 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll @@ -47,7 +47,7 @@ module Os { private class Stdin extends SourceNode { Stdin() { exists(Variable osStdin | osStdin.hasQualifiedName("os", "Stdin") | - this.asExpr() = osStdin.getARead().asExpr() + this = osStdin.getARead() ) } From 91b7a6cbd801a035ec492bd82c6eed1eda9cd759 Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Wed, 4 Sep 2024 09:48:25 -0400 Subject: [PATCH 113/347] Wording of change note Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- go/ql/lib/change-notes/2024-08-29-add-stdin-threat-models.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/ql/lib/change-notes/2024-08-29-add-stdin-threat-models.md b/go/ql/lib/change-notes/2024-08-29-add-stdin-threat-models.md index f01c843320de..d98ac68f1edc 100644 --- a/go/ql/lib/change-notes/2024-08-29-add-stdin-threat-models.md +++ b/go/ql/lib/change-notes/2024-08-29-add-stdin-threat-models.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* Local source models with the `stdin` source kind have been added for `os.Stdin`, `fmt.Scan`, `fmt.Scanf`, `fmt.Scanln`. You can optionally include threat models as appropriate when using the CodeQL CLI and in GitHub code scanning. For more information, see [Analyzing your code with CodeQL queries](https://docs.github.com/code-security/codeql-cli/getting-started-with-the-codeql-cli/analyzing-your-code-with-codeql-queries#including-model-packs-to-add-potential-sources-of-tainted-data>) and [Customizing your advanced setup for code scanning](https://docs.github.com/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning#extending-codeql-coverage-with-threat-models). +* Local source models with the `stdin` source kind have been added for the variable `os.Stdin` and the functions `fmt.Scan`, `fmt.Scanf` and `fmt.Scanln`. You can optionally include threat models as appropriate when using the CodeQL CLI and in GitHub code scanning. For more information, see [Analyzing your code with CodeQL queries](https://docs.github.com/code-security/codeql-cli/getting-started-with-the-codeql-cli/analyzing-your-code-with-codeql-queries#including-model-packs-to-add-potential-sources-of-tainted-data>) and [Customizing your advanced setup for code scanning](https://docs.github.com/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning#extending-codeql-coverage-with-threat-models). From f8335e6163d73d38ff2071573611598e600be68c Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 1 Oct 2024 15:58:07 -0400 Subject: [PATCH 114/347] Fix formatting --- go/ql/lib/semmle/go/frameworks/stdlib/Os.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll index 492e4b002411..fb153451c597 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll @@ -46,9 +46,7 @@ module Os { private class Stdin extends SourceNode { Stdin() { - exists(Variable osStdin | osStdin.hasQualifiedName("os", "Stdin") | - this = osStdin.getARead() - ) + exists(Variable osStdin | osStdin.hasQualifiedName("os", "Stdin") | this = osStdin.getARead()) } override string getThreatModel() { result = "stdin" } From 2458d1642670d0ceb8edcf47bcf34006ef2be84e Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Tue, 1 Oct 2024 23:04:22 -0400 Subject: [PATCH 115/347] Clarify threat model flow sources comment in LogForgingQuery.qll --- .../semmle/code/csharp/security/dataflow/LogForgingQuery.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll index 8181c9bcb74a..ebb481d2525e 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll @@ -42,7 +42,7 @@ private module LogForgingConfig implements DataFlow::ConfigSig { */ module LogForging = TaintTracking::Global; -/** A source of remote user input. */ +/** A source supported by the current threat model. */ private class ThreatModelSource extends Source instanceof ActiveThreatModelSource { } private class HtmlSanitizer extends Sanitizer { From d3695dce4dcfc0332389f1afe9e03dd588f98862 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Wed, 2 Oct 2024 08:14:23 +0100 Subject: [PATCH 116/347] C++: Add change note --- cpp/ql/src/change-notes/2024-10-02-uninitialized-local.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/src/change-notes/2024-10-02-uninitialized-local.md diff --git a/cpp/ql/src/change-notes/2024-10-02-uninitialized-local.md b/cpp/ql/src/change-notes/2024-10-02-uninitialized-local.md new file mode 100644 index 000000000000..e34a942f38a6 --- /dev/null +++ b/cpp/ql/src/change-notes/2024-10-02-uninitialized-local.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Fixed false positives in the `cpp/uninitialized-local` ("Potentially uninitialized local variable") query if there are extraction errors in the function. From 69e0ad01818ee0f0237a1ccee26d732dbf29e43c Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Oct 2024 10:55:52 +0200 Subject: [PATCH 117/347] Rust: Refactor CFG implementation for loops --- .../controlflow/internal/ControlFlowGraphImpl.qll | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index da156cd7767c..971e4910fabe 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -316,7 +316,11 @@ abstract class LoopingExprTree extends PostOrderTree { abstract Label getLabel(); - abstract predicate entry(AstNode node); + /** + * Gets the node to execute when continuing the loop; either after + * executing the last node in the body or after an explicit `continue`. + */ + abstract AstNode getLoopContinue(); /** Holds if this loop captures the `c` completion. */ private predicate capturesLoopJumpCompletion(LoopJumpCompletion c) { @@ -339,7 +343,7 @@ abstract class LoopingExprTree extends PostOrderTree { or c.(LoopJumpCompletion).isContinue() and this.capturesLoopJumpCompletion(c) ) and - this.entry(succ) + first(this.getLoopContinue(), succ) } override predicate last(AstNode last, Completion c) { @@ -357,7 +361,7 @@ class LoopExprTree extends LoopingExprTree instanceof LoopExpr { override Label getLabel() { result = LoopExpr.super.getLabel() } - override predicate entry(AstNode node) { this.first(node) } + override AstNode getLoopContinue() { result = this.getLoopBody() } override predicate first(AstNode node) { first(this.getLoopBody(), node) } } @@ -367,7 +371,7 @@ class WhileExprTree extends LoopingExprTree instanceof WhileExpr { override Label getLabel() { result = WhileExpr.super.getLabel() } - override predicate entry(AstNode node) { this.first(node) } + override AstNode getLoopContinue() { result = super.getCondition() } override predicate propagatesAbnormal(AstNode child) { child = super.getCondition() } @@ -397,7 +401,7 @@ class ForExprTree extends LoopingExprTree instanceof ForExpr { override Label getLabel() { result = ForExpr.super.getLabel() } - override predicate entry(AstNode n) { first(super.getPat(), n) } + override AstNode getLoopContinue() { result = super.getPat() } override predicate propagatesAbnormal(AstNode child) { child = super.getIterable() } From 9c7216fe4ffde832c9980572629f4a64c7bda734 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Oct 2024 10:59:26 +0200 Subject: [PATCH 118/347] Rust: Add another CFG test --- .../library-tests/controlflow/Cfg.expected | 880 +++++++++--------- .../ql/test/library-tests/controlflow/test.rs | 14 + 2 files changed, 462 insertions(+), 432 deletions(-) diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index aff1576a8294..0e7bf44925cc 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -97,435 +97,451 @@ | test.rs:47:21:47:36 | ExprStmt | test.rs:47:21:47:35 | ContinueExpr | | | test.rs:49:17:49:31 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | continue('inner) | | test.rs:49:17:49:32 | ExprStmt | test.rs:49:17:49:31 | ContinueExpr | | -| test.rs:54:5:63:5 | enter test_while | test.rs:55:9:55:25 | LetStmt | | -| test.rs:54:5:63:5 | exit test_while (normal) | test.rs:54:5:63:5 | exit test_while | | -| test.rs:54:27:63:5 | BlockExpr | test.rs:54:5:63:5 | exit test_while (normal) | | -| test.rs:55:9:55:25 | LetStmt | test.rs:55:21:55:24 | true | | -| test.rs:55:13:55:17 | b | test.rs:56:15:56:15 | b | match, no-match | -| test.rs:55:21:55:24 | true | test.rs:55:13:55:17 | b | | -| test.rs:56:9:62:9 | WhileExpr | test.rs:54:27:63:5 | BlockExpr | | -| test.rs:56:15:56:15 | b | test.rs:56:9:62:9 | WhileExpr | false | -| test.rs:56:15:56:15 | b | test.rs:57:13:57:14 | ExprStmt | true | -| test.rs:56:17:62:9 | BlockExpr | test.rs:56:15:56:15 | b | | -| test.rs:57:13:57:13 | 1 | test.rs:58:13:60:13 | ExprStmt | | -| test.rs:57:13:57:14 | ExprStmt | test.rs:57:13:57:13 | 1 | | -| test.rs:58:13:60:13 | ExprStmt | test.rs:58:17:58:17 | i | | -| test.rs:58:13:60:13 | IfExpr | test.rs:61:13:61:22 | ExprStmt | | -| test.rs:58:17:58:17 | i | test.rs:58:21:58:21 | 0 | | -| test.rs:58:17:58:21 | ... > ... | test.rs:58:13:60:13 | IfExpr | false | -| test.rs:58:17:58:21 | ... > ... | test.rs:59:17:59:22 | ExprStmt | true | -| test.rs:58:21:58:21 | 0 | test.rs:58:17:58:21 | ... > ... | | -| test.rs:59:17:59:21 | BreakExpr | test.rs:56:9:62:9 | WhileExpr | break | -| test.rs:59:17:59:22 | ExprStmt | test.rs:59:17:59:21 | BreakExpr | | -| test.rs:61:13:61:13 | PathExpr | test.rs:61:17:61:21 | false | | -| test.rs:61:13:61:21 | ... = ... | test.rs:56:17:62:9 | BlockExpr | | -| test.rs:61:13:61:22 | ExprStmt | test.rs:61:13:61:13 | PathExpr | | -| test.rs:61:17:61:21 | false | test.rs:61:13:61:21 | ... = ... | | -| test.rs:65:5:72:5 | enter test_while_let | test.rs:66:9:66:29 | LetStmt | | -| test.rs:65:5:72:5 | exit test_while_let (normal) | test.rs:65:5:72:5 | exit test_while_let | | -| test.rs:65:25:72:5 | BlockExpr | test.rs:65:5:72:5 | exit test_while_let (normal) | | -| test.rs:66:9:66:29 | LetStmt | test.rs:66:24:66:24 | 1 | | -| test.rs:66:13:66:20 | iter | test.rs:67:15:67:39 | LetExpr | match, no-match | -| test.rs:66:24:66:24 | 1 | test.rs:66:27:66:28 | 10 | | -| test.rs:66:24:66:28 | RangeExpr | test.rs:66:13:66:20 | iter | | -| test.rs:66:27:66:28 | 10 | test.rs:66:24:66:28 | RangeExpr | | -| test.rs:67:9:71:9 | WhileExpr | test.rs:65:25:72:5 | BlockExpr | | -| test.rs:67:15:67:39 | LetExpr | test.rs:67:19:67:25 | TupleStructPat | | -| test.rs:67:19:67:25 | TupleStructPat | test.rs:67:9:71:9 | WhileExpr | no-match | -| test.rs:67:19:67:25 | TupleStructPat | test.rs:68:17:68:17 | PathExpr | match | -| test.rs:67:41:71:9 | BlockExpr | test.rs:67:15:67:39 | LetExpr | | -| test.rs:68:13:70:13 | IfExpr | test.rs:67:41:71:9 | BlockExpr | | -| test.rs:68:17:68:17 | PathExpr | test.rs:68:21:68:21 | 5 | | -| test.rs:68:17:68:21 | ... = ... | test.rs:68:13:70:13 | IfExpr | false | -| test.rs:68:17:68:21 | ... = ... | test.rs:69:17:69:22 | ExprStmt | true | -| test.rs:68:21:68:21 | 5 | test.rs:68:17:68:21 | ... = ... | | -| test.rs:69:17:69:21 | BreakExpr | test.rs:67:9:71:9 | WhileExpr | break | -| test.rs:69:17:69:22 | ExprStmt | test.rs:69:17:69:21 | BreakExpr | | -| test.rs:74:5:81:5 | enter test_for | test.rs:75:18:75:18 | 0 | | -| test.rs:74:5:81:5 | exit test_for (normal) | test.rs:74:5:81:5 | exit test_for | | -| test.rs:74:25:81:5 | BlockExpr | test.rs:74:5:81:5 | exit test_for (normal) | | -| test.rs:75:9:80:9 | ForExpr | test.rs:74:25:81:5 | BlockExpr | | -| test.rs:75:13:75:13 | i | test.rs:75:9:80:9 | ForExpr | no-match | -| test.rs:75:13:75:13 | i | test.rs:76:13:78:13 | ExprStmt | match | -| test.rs:75:18:75:18 | 0 | test.rs:75:21:75:22 | 10 | | -| test.rs:75:18:75:22 | RangeExpr | test.rs:75:13:75:13 | i | | -| test.rs:75:21:75:22 | 10 | test.rs:75:18:75:22 | RangeExpr | | -| test.rs:75:24:80:9 | BlockExpr | test.rs:75:13:75:13 | i | | -| test.rs:76:13:78:13 | ExprStmt | test.rs:76:17:76:17 | i | | -| test.rs:76:13:78:13 | IfExpr | test.rs:79:13:79:14 | ExprStmt | | -| test.rs:76:17:76:17 | i | test.rs:76:22:76:22 | j | | -| test.rs:76:17:76:22 | ... == ... | test.rs:76:13:78:13 | IfExpr | false | -| test.rs:76:17:76:22 | ... == ... | test.rs:77:17:77:22 | ExprStmt | true | -| test.rs:76:22:76:22 | j | test.rs:76:17:76:22 | ... == ... | | -| test.rs:77:17:77:21 | BreakExpr | test.rs:75:9:80:9 | ForExpr | break | -| test.rs:77:17:77:22 | ExprStmt | test.rs:77:17:77:21 | BreakExpr | | -| test.rs:79:13:79:13 | 1 | test.rs:75:24:80:9 | BlockExpr | | -| test.rs:79:13:79:14 | ExprStmt | test.rs:79:13:79:13 | 1 | | -| test.rs:84:1:87:1 | enter test_nested_function | test.rs:85:5:85:28 | LetStmt | | -| test.rs:84:1:87:1 | exit test_nested_function (normal) | test.rs:84:1:87:1 | exit test_nested_function | | -| test.rs:84:40:87:1 | BlockExpr | test.rs:84:1:87:1 | exit test_nested_function (normal) | | -| test.rs:85:5:85:28 | LetStmt | test.rs:85:19:85:27 | ClosureExpr | | -| test.rs:85:9:85:15 | add_one | test.rs:86:5:86:11 | add_one | match, no-match | -| test.rs:85:19:85:27 | ClosureExpr | test.rs:85:9:85:15 | add_one | | -| test.rs:85:19:85:27 | enter ClosureExpr | test.rs:85:23:85:23 | i | | -| test.rs:85:19:85:27 | exit ClosureExpr (normal) | test.rs:85:19:85:27 | exit ClosureExpr | | -| test.rs:85:23:85:23 | i | test.rs:85:27:85:27 | 1 | | -| test.rs:85:23:85:27 | ... + ... | test.rs:85:19:85:27 | exit ClosureExpr (normal) | | -| test.rs:85:27:85:27 | 1 | test.rs:85:23:85:27 | ... + ... | | -| test.rs:86:5:86:11 | add_one | test.rs:86:13:86:19 | add_one | | -| test.rs:86:5:86:23 | CallExpr | test.rs:84:40:87:1 | BlockExpr | | -| test.rs:86:13:86:19 | add_one | test.rs:86:21:86:21 | n | | -| test.rs:86:13:86:22 | CallExpr | test.rs:86:5:86:23 | CallExpr | | -| test.rs:86:21:86:21 | n | test.rs:86:13:86:22 | CallExpr | | -| test.rs:91:5:97:5 | enter test_if_else | test.rs:92:12:92:12 | n | | -| test.rs:91:5:97:5 | exit test_if_else (normal) | test.rs:91:5:97:5 | exit test_if_else | | -| test.rs:91:36:97:5 | BlockExpr | test.rs:91:5:97:5 | exit test_if_else (normal) | | -| test.rs:92:9:96:9 | IfExpr | test.rs:91:36:97:5 | BlockExpr | | -| test.rs:92:12:92:12 | n | test.rs:92:17:92:17 | 0 | | -| test.rs:92:12:92:17 | ... <= ... | test.rs:93:13:93:13 | 0 | true | -| test.rs:92:12:92:17 | ... <= ... | test.rs:95:13:95:13 | n | false | -| test.rs:92:17:92:17 | 0 | test.rs:92:12:92:17 | ... <= ... | | -| test.rs:92:19:94:9 | BlockExpr | test.rs:92:9:96:9 | IfExpr | | -| test.rs:93:13:93:13 | 0 | test.rs:92:19:94:9 | BlockExpr | | -| test.rs:94:16:96:9 | BlockExpr | test.rs:92:9:96:9 | IfExpr | | -| test.rs:95:13:95:13 | n | test.rs:95:17:95:17 | 1 | | -| test.rs:95:13:95:17 | ... - ... | test.rs:94:16:96:9 | BlockExpr | | -| test.rs:95:17:95:17 | 1 | test.rs:95:13:95:17 | ... - ... | | -| test.rs:99:5:105:5 | enter test_if_let_else | test.rs:100:12:100:26 | LetExpr | | -| test.rs:99:5:105:5 | exit test_if_let_else (normal) | test.rs:99:5:105:5 | exit test_if_let_else | | -| test.rs:99:48:105:5 | BlockExpr | test.rs:99:5:105:5 | exit test_if_let_else (normal) | | -| test.rs:100:9:104:9 | IfExpr | test.rs:99:48:105:5 | BlockExpr | | -| test.rs:100:12:100:26 | LetExpr | test.rs:100:16:100:22 | TupleStructPat | | -| test.rs:100:16:100:22 | TupleStructPat | test.rs:101:13:101:13 | n | match | -| test.rs:100:16:100:22 | TupleStructPat | test.rs:103:13:103:13 | 0 | no-match | -| test.rs:100:28:102:9 | BlockExpr | test.rs:100:9:104:9 | IfExpr | | -| test.rs:101:13:101:13 | n | test.rs:100:28:102:9 | BlockExpr | | -| test.rs:102:16:104:9 | BlockExpr | test.rs:100:9:104:9 | IfExpr | | -| test.rs:103:13:103:13 | 0 | test.rs:102:16:104:9 | BlockExpr | | -| test.rs:107:5:112:5 | enter test_if_let | test.rs:108:9:110:9 | ExprStmt | | -| test.rs:107:5:112:5 | exit test_if_let (normal) | test.rs:107:5:112:5 | exit test_if_let | | -| test.rs:107:43:112:5 | BlockExpr | test.rs:107:5:112:5 | exit test_if_let (normal) | | -| test.rs:108:9:110:9 | ExprStmt | test.rs:108:12:108:26 | LetExpr | | -| test.rs:108:9:110:9 | IfExpr | test.rs:111:9:111:9 | 0 | | -| test.rs:108:12:108:26 | LetExpr | test.rs:108:16:108:22 | TupleStructPat | | -| test.rs:108:16:108:22 | TupleStructPat | test.rs:108:9:110:9 | IfExpr | no-match | -| test.rs:108:16:108:22 | TupleStructPat | test.rs:109:13:109:13 | n | match | -| test.rs:108:28:110:9 | BlockExpr | test.rs:108:9:110:9 | IfExpr | | -| test.rs:109:13:109:13 | n | test.rs:108:28:110:9 | BlockExpr | | -| test.rs:111:9:111:9 | 0 | test.rs:107:43:112:5 | BlockExpr | | -| test.rs:114:5:120:5 | enter test_nested_if | test.rs:115:16:115:16 | PathExpr | | -| test.rs:114:5:120:5 | exit test_nested_if (normal) | test.rs:114:5:120:5 | exit test_nested_if | | -| test.rs:114:38:120:5 | BlockExpr | test.rs:114:5:120:5 | exit test_nested_if (normal) | | -| test.rs:115:9:119:9 | IfExpr | test.rs:114:38:120:5 | BlockExpr | | -| test.rs:115:13:115:48 | IfExpr | test.rs:116:13:116:13 | 1 | true | -| test.rs:115:13:115:48 | IfExpr | test.rs:118:13:118:13 | 0 | false | -| test.rs:115:16:115:16 | PathExpr | test.rs:115:20:115:20 | 0 | | -| test.rs:115:16:115:20 | ... < ... | test.rs:115:24:115:24 | a | true | -| test.rs:115:16:115:20 | ... < ... | test.rs:115:41:115:41 | a | false | -| test.rs:115:20:115:20 | 0 | test.rs:115:16:115:20 | ... < ... | | -| test.rs:115:22:115:32 | BlockExpr | test.rs:115:13:115:48 | IfExpr | false, true | -| test.rs:115:24:115:24 | a | test.rs:115:29:115:30 | 10 | | -| test.rs:115:24:115:30 | ... < ... | test.rs:115:22:115:32 | BlockExpr | false, true | -| test.rs:115:28:115:30 | - ... | test.rs:115:24:115:30 | ... < ... | | -| test.rs:115:29:115:30 | 10 | test.rs:115:28:115:30 | - ... | | -| test.rs:115:39:115:48 | BlockExpr | test.rs:115:13:115:48 | IfExpr | false, true | -| test.rs:115:41:115:41 | a | test.rs:115:45:115:46 | 10 | | -| test.rs:115:41:115:46 | ... > ... | test.rs:115:39:115:48 | BlockExpr | false, true | -| test.rs:115:45:115:46 | 10 | test.rs:115:41:115:46 | ... > ... | | -| test.rs:115:51:117:9 | BlockExpr | test.rs:115:9:119:9 | IfExpr | | -| test.rs:116:13:116:13 | 1 | test.rs:115:51:117:9 | BlockExpr | | -| test.rs:117:16:119:9 | BlockExpr | test.rs:115:9:119:9 | IfExpr | | -| test.rs:118:13:118:13 | 0 | test.rs:117:16:119:9 | BlockExpr | | -| test.rs:122:5:131:5 | enter test_nested_if_match | test.rs:123:19:123:19 | a | | -| test.rs:122:5:131:5 | exit test_nested_if_match (normal) | test.rs:122:5:131:5 | exit test_nested_if_match | | -| test.rs:122:44:131:5 | BlockExpr | test.rs:122:5:131:5 | exit test_nested_if_match (normal) | | -| test.rs:123:9:130:9 | IfExpr | test.rs:122:44:131:5 | BlockExpr | | -| test.rs:123:13:126:9 | MatchExpr | test.rs:127:13:127:13 | 1 | true | -| test.rs:123:13:126:9 | MatchExpr | test.rs:129:13:129:13 | 0 | false | -| test.rs:123:19:123:19 | a | test.rs:124:13:124:13 | LiteralPat | | -| test.rs:124:13:124:13 | LiteralPat | test.rs:124:18:124:21 | true | match | -| test.rs:124:13:124:13 | LiteralPat | test.rs:125:13:125:13 | WildcardPat | no-match | -| test.rs:124:18:124:21 | true | test.rs:123:13:126:9 | MatchExpr | | -| test.rs:125:13:125:13 | WildcardPat | test.rs:125:18:125:22 | false | match | -| test.rs:125:18:125:22 | false | test.rs:123:13:126:9 | MatchExpr | | -| test.rs:126:12:128:9 | BlockExpr | test.rs:123:9:130:9 | IfExpr | | -| test.rs:127:13:127:13 | 1 | test.rs:126:12:128:9 | BlockExpr | | -| test.rs:128:16:130:9 | BlockExpr | test.rs:123:9:130:9 | IfExpr | | -| test.rs:129:13:129:13 | 0 | test.rs:128:16:130:9 | BlockExpr | | -| test.rs:133:5:142:5 | enter test_nested_if_block | test.rs:135:13:135:15 | ExprStmt | | -| test.rs:133:5:142:5 | exit test_nested_if_block (normal) | test.rs:133:5:142:5 | exit test_nested_if_block | | -| test.rs:133:44:142:5 | BlockExpr | test.rs:133:5:142:5 | exit test_nested_if_block (normal) | | -| test.rs:134:9:141:9 | IfExpr | test.rs:133:44:142:5 | BlockExpr | | -| test.rs:134:12:137:9 | BlockExpr | test.rs:138:13:138:13 | 1 | true | -| test.rs:134:12:137:9 | BlockExpr | test.rs:140:13:140:13 | 0 | false | -| test.rs:135:13:135:14 | TupleExpr | test.rs:136:13:136:13 | a | | -| test.rs:135:13:135:15 | ExprStmt | test.rs:135:13:135:14 | TupleExpr | | -| test.rs:136:13:136:13 | a | test.rs:136:17:136:17 | 0 | | -| test.rs:136:13:136:17 | ... > ... | test.rs:134:12:137:9 | BlockExpr | false, true | -| test.rs:136:17:136:17 | 0 | test.rs:136:13:136:17 | ... > ... | | -| test.rs:137:11:139:9 | BlockExpr | test.rs:134:9:141:9 | IfExpr | | -| test.rs:138:13:138:13 | 1 | test.rs:137:11:139:9 | BlockExpr | | -| test.rs:139:16:141:9 | BlockExpr | test.rs:134:9:141:9 | IfExpr | | -| test.rs:140:13:140:13 | 0 | test.rs:139:16:141:9 | BlockExpr | | -| test.rs:144:5:151:5 | enter test_if_assignment | test.rs:145:9:145:26 | LetStmt | | -| test.rs:144:5:151:5 | exit test_if_assignment (normal) | test.rs:144:5:151:5 | exit test_if_assignment | | -| test.rs:144:42:151:5 | BlockExpr | test.rs:144:5:151:5 | exit test_if_assignment (normal) | | -| test.rs:145:9:145:26 | LetStmt | test.rs:145:21:145:25 | false | | -| test.rs:145:13:145:17 | x | test.rs:146:12:146:12 | x | match, no-match | -| test.rs:145:21:145:25 | false | test.rs:145:13:145:17 | x | | -| test.rs:146:9:150:9 | IfExpr | test.rs:144:42:151:5 | BlockExpr | | -| test.rs:146:12:146:12 | x | test.rs:146:16:146:19 | true | | -| test.rs:146:12:146:19 | ... = ... | test.rs:147:13:147:13 | 1 | true | -| test.rs:146:12:146:19 | ... = ... | test.rs:149:13:149:13 | 0 | false | -| test.rs:146:16:146:19 | true | test.rs:146:12:146:19 | ... = ... | | -| test.rs:146:21:148:9 | BlockExpr | test.rs:146:9:150:9 | IfExpr | | -| test.rs:147:13:147:13 | 1 | test.rs:146:21:148:9 | BlockExpr | | -| test.rs:148:16:150:9 | BlockExpr | test.rs:146:9:150:9 | IfExpr | | -| test.rs:149:13:149:13 | 0 | test.rs:148:16:150:9 | BlockExpr | | -| test.rs:153:5:164:5 | enter test_if_loop1 | test.rs:155:13:157:14 | ExprStmt | | -| test.rs:153:5:164:5 | exit test_if_loop1 (normal) | test.rs:153:5:164:5 | exit test_if_loop1 | | -| test.rs:153:37:164:5 | BlockExpr | test.rs:153:5:164:5 | exit test_if_loop1 (normal) | | -| test.rs:154:9:163:9 | IfExpr | test.rs:153:37:164:5 | BlockExpr | | -| test.rs:154:13:159:9 | LoopExpr | test.rs:160:13:160:13 | 1 | true | -| test.rs:154:13:159:9 | LoopExpr | test.rs:162:13:162:13 | 0 | false | -| test.rs:154:18:159:9 | BlockExpr | test.rs:155:13:157:14 | ExprStmt | | -| test.rs:155:13:157:13 | IfExpr | test.rs:158:13:158:19 | ExprStmt | | -| test.rs:155:13:157:14 | ExprStmt | test.rs:155:16:155:16 | a | | -| test.rs:155:16:155:16 | a | test.rs:155:20:155:20 | 0 | | -| test.rs:155:16:155:20 | ... > ... | test.rs:155:13:157:13 | IfExpr | false | -| test.rs:155:16:155:20 | ... > ... | test.rs:156:17:156:29 | ExprStmt | true | -| test.rs:155:20:155:20 | 0 | test.rs:155:16:155:20 | ... > ... | | -| test.rs:156:17:156:28 | BreakExpr | test.rs:154:13:159:9 | LoopExpr | break | -| test.rs:156:17:156:29 | ExprStmt | test.rs:156:23:156:23 | a | | -| test.rs:156:23:156:23 | a | test.rs:156:27:156:28 | 10 | | -| test.rs:156:23:156:28 | ... > ... | test.rs:156:17:156:28 | BreakExpr | | -| test.rs:156:27:156:28 | 10 | test.rs:156:23:156:28 | ... > ... | | -| test.rs:158:13:158:13 | a | test.rs:158:17:158:18 | 10 | | -| test.rs:158:13:158:18 | ... < ... | test.rs:154:18:159:9 | BlockExpr | | -| test.rs:158:13:158:19 | ExprStmt | test.rs:158:13:158:13 | a | | -| test.rs:158:17:158:18 | 10 | test.rs:158:13:158:18 | ... < ... | | -| test.rs:159:12:161:9 | BlockExpr | test.rs:154:9:163:9 | IfExpr | | -| test.rs:160:13:160:13 | 1 | test.rs:159:12:161:9 | BlockExpr | | -| test.rs:161:16:163:9 | BlockExpr | test.rs:154:9:163:9 | IfExpr | | -| test.rs:162:13:162:13 | 0 | test.rs:161:16:163:9 | BlockExpr | | -| test.rs:166:5:177:5 | enter test_if_loop2 | test.rs:168:13:170:14 | ExprStmt | | -| test.rs:166:5:177:5 | exit test_if_loop2 (normal) | test.rs:166:5:177:5 | exit test_if_loop2 | | -| test.rs:166:37:177:5 | BlockExpr | test.rs:166:5:177:5 | exit test_if_loop2 (normal) | | -| test.rs:167:9:176:9 | IfExpr | test.rs:166:37:177:5 | BlockExpr | | -| test.rs:167:13:172:9 | LoopExpr | test.rs:173:13:173:13 | 1 | true | -| test.rs:167:13:172:9 | LoopExpr | test.rs:175:13:175:13 | 0 | false | -| test.rs:167:26:172:9 | BlockExpr | test.rs:168:13:170:14 | ExprStmt | | -| test.rs:168:13:170:13 | IfExpr | test.rs:171:13:171:19 | ExprStmt | | -| test.rs:168:13:170:14 | ExprStmt | test.rs:168:16:168:16 | a | | -| test.rs:168:16:168:16 | a | test.rs:168:20:168:20 | 0 | | -| test.rs:168:16:168:20 | ... > ... | test.rs:168:13:170:13 | IfExpr | false | -| test.rs:168:16:168:20 | ... > ... | test.rs:169:17:169:36 | ExprStmt | true | -| test.rs:168:20:168:20 | 0 | test.rs:168:16:168:20 | ... > ... | | -| test.rs:169:17:169:35 | BreakExpr | test.rs:167:13:172:9 | LoopExpr | break('label) | -| test.rs:169:17:169:36 | ExprStmt | test.rs:169:30:169:30 | a | | -| test.rs:169:30:169:30 | a | test.rs:169:34:169:35 | 10 | | -| test.rs:169:30:169:35 | ... > ... | test.rs:169:17:169:35 | BreakExpr | | -| test.rs:169:34:169:35 | 10 | test.rs:169:30:169:35 | ... > ... | | -| test.rs:171:13:171:13 | a | test.rs:171:17:171:18 | 10 | | -| test.rs:171:13:171:18 | ... < ... | test.rs:167:26:172:9 | BlockExpr | | -| test.rs:171:13:171:19 | ExprStmt | test.rs:171:13:171:13 | a | | -| test.rs:171:17:171:18 | 10 | test.rs:171:13:171:18 | ... < ... | | -| test.rs:172:12:174:9 | BlockExpr | test.rs:167:9:176:9 | IfExpr | | -| test.rs:173:13:173:13 | 1 | test.rs:172:12:174:9 | BlockExpr | | -| test.rs:174:16:176:9 | BlockExpr | test.rs:167:9:176:9 | IfExpr | | -| test.rs:175:13:175:13 | 0 | test.rs:174:16:176:9 | BlockExpr | | -| test.rs:179:5:187:5 | enter test_labelled_block | test.rs:181:13:181:31 | ExprStmt | | -| test.rs:179:5:187:5 | exit test_labelled_block (normal) | test.rs:179:5:187:5 | exit test_labelled_block | | -| test.rs:179:43:187:5 | BlockExpr | test.rs:179:5:187:5 | exit test_labelled_block (normal) | | -| test.rs:180:9:186:9 | IfExpr | test.rs:179:43:187:5 | BlockExpr | | -| test.rs:180:13:182:9 | BlockExpr | test.rs:183:13:183:13 | 1 | true | -| test.rs:180:13:182:9 | BlockExpr | test.rs:185:13:185:13 | 0 | false | -| test.rs:181:13:181:30 | BreakExpr | test.rs:180:13:182:9 | BlockExpr | break('block) | -| test.rs:181:13:181:31 | ExprStmt | test.rs:181:26:181:26 | a | | -| test.rs:181:26:181:26 | a | test.rs:181:30:181:30 | 0 | | -| test.rs:181:26:181:30 | ... > ... | test.rs:181:13:181:30 | BreakExpr | | -| test.rs:181:30:181:30 | 0 | test.rs:181:26:181:30 | ... > ... | | -| test.rs:182:12:184:9 | BlockExpr | test.rs:180:9:186:9 | IfExpr | | -| test.rs:183:13:183:13 | 1 | test.rs:182:12:184:9 | BlockExpr | | -| test.rs:184:16:186:9 | BlockExpr | test.rs:180:9:186:9 | IfExpr | | -| test.rs:185:13:185:13 | 0 | test.rs:184:16:186:9 | BlockExpr | | -| test.rs:192:5:195:5 | enter test_and_operator | test.rs:193:9:193:28 | LetStmt | | -| test.rs:192:5:195:5 | exit test_and_operator (normal) | test.rs:192:5:195:5 | exit test_and_operator | | -| test.rs:192:61:195:5 | BlockExpr | test.rs:192:5:195:5 | exit test_and_operator (normal) | | -| test.rs:193:9:193:28 | LetStmt | test.rs:193:17:193:27 | ... && ... | | -| test.rs:193:13:193:13 | d | test.rs:194:9:194:9 | d | match, no-match | -| test.rs:193:17:193:17 | a | test.rs:193:13:193:13 | d | false | -| test.rs:193:17:193:17 | a | test.rs:193:22:193:22 | b | true | -| test.rs:193:17:193:22 | ... && ... | test.rs:193:17:193:17 | a | | -| test.rs:193:17:193:27 | ... && ... | test.rs:193:17:193:22 | ... && ... | | -| test.rs:193:22:193:22 | b | test.rs:193:13:193:13 | d | false | -| test.rs:193:22:193:22 | b | test.rs:193:27:193:27 | c | true | -| test.rs:193:27:193:27 | c | test.rs:193:13:193:13 | d | | -| test.rs:194:9:194:9 | d | test.rs:192:61:195:5 | BlockExpr | | -| test.rs:197:5:200:5 | enter test_or_operator | test.rs:198:9:198:28 | LetStmt | | -| test.rs:197:5:200:5 | exit test_or_operator (normal) | test.rs:197:5:200:5 | exit test_or_operator | | -| test.rs:197:60:200:5 | BlockExpr | test.rs:197:5:200:5 | exit test_or_operator (normal) | | -| test.rs:198:9:198:28 | LetStmt | test.rs:198:17:198:27 | ... \|\| ... | | -| test.rs:198:13:198:13 | d | test.rs:199:9:199:9 | d | match, no-match | -| test.rs:198:17:198:17 | a | test.rs:198:13:198:13 | d | true | -| test.rs:198:17:198:17 | a | test.rs:198:22:198:22 | b | false | -| test.rs:198:17:198:22 | ... \|\| ... | test.rs:198:17:198:17 | a | | -| test.rs:198:17:198:27 | ... \|\| ... | test.rs:198:17:198:22 | ... \|\| ... | | -| test.rs:198:22:198:22 | b | test.rs:198:13:198:13 | d | true | -| test.rs:198:22:198:22 | b | test.rs:198:27:198:27 | c | false | -| test.rs:198:27:198:27 | c | test.rs:198:13:198:13 | d | | -| test.rs:199:9:199:9 | d | test.rs:197:60:200:5 | BlockExpr | | -| test.rs:202:5:205:5 | enter test_or_operator_2 | test.rs:203:9:203:36 | LetStmt | | -| test.rs:202:5:205:5 | exit test_or_operator_2 (normal) | test.rs:202:5:205:5 | exit test_or_operator_2 | | -| test.rs:202:61:205:5 | BlockExpr | test.rs:202:5:205:5 | exit test_or_operator_2 (normal) | | -| test.rs:203:9:203:36 | LetStmt | test.rs:203:17:203:35 | ... \|\| ... | | -| test.rs:203:13:203:13 | d | test.rs:204:9:204:9 | d | match, no-match | -| test.rs:203:17:203:17 | a | test.rs:203:13:203:13 | d | true | -| test.rs:203:17:203:17 | a | test.rs:203:23:203:23 | b | false | -| test.rs:203:17:203:30 | ... \|\| ... | test.rs:203:17:203:17 | a | | -| test.rs:203:17:203:35 | ... \|\| ... | test.rs:203:17:203:30 | ... \|\| ... | | -| test.rs:203:23:203:23 | b | test.rs:203:28:203:29 | 28 | | -| test.rs:203:23:203:29 | ... == ... | test.rs:203:13:203:13 | d | true | -| test.rs:203:23:203:29 | ... == ... | test.rs:203:35:203:35 | c | false | -| test.rs:203:28:203:29 | 28 | test.rs:203:23:203:29 | ... == ... | | -| test.rs:203:35:203:35 | c | test.rs:203:13:203:13 | d | | -| test.rs:204:9:204:9 | d | test.rs:202:61:205:5 | BlockExpr | | -| test.rs:207:5:210:5 | enter test_not_operator | test.rs:208:9:208:19 | LetStmt | | -| test.rs:207:5:210:5 | exit test_not_operator (normal) | test.rs:207:5:210:5 | exit test_not_operator | | -| test.rs:207:43:210:5 | BlockExpr | test.rs:207:5:210:5 | exit test_not_operator (normal) | | -| test.rs:208:9:208:19 | LetStmt | test.rs:208:18:208:18 | a | | -| test.rs:208:13:208:13 | d | test.rs:209:9:209:9 | d | match, no-match | -| test.rs:208:17:208:18 | ! ... | test.rs:208:13:208:13 | d | | -| test.rs:208:18:208:18 | a | test.rs:208:17:208:18 | ! ... | | -| test.rs:209:9:209:9 | d | test.rs:207:43:210:5 | BlockExpr | | -| test.rs:212:5:218:5 | enter test_if_and_operator | test.rs:213:12:213:22 | ... && ... | | -| test.rs:212:5:218:5 | exit test_if_and_operator (normal) | test.rs:212:5:218:5 | exit test_if_and_operator | | -| test.rs:212:63:218:5 | BlockExpr | test.rs:212:5:218:5 | exit test_if_and_operator (normal) | | -| test.rs:213:9:217:9 | IfExpr | test.rs:212:63:218:5 | BlockExpr | | -| test.rs:213:12:213:12 | a | test.rs:213:17:213:17 | b | true | -| test.rs:213:12:213:12 | a | test.rs:216:13:216:17 | false | false | -| test.rs:213:12:213:17 | ... && ... | test.rs:213:12:213:12 | a | | -| test.rs:213:12:213:22 | ... && ... | test.rs:213:12:213:17 | ... && ... | | -| test.rs:213:17:213:17 | b | test.rs:213:22:213:22 | c | true | -| test.rs:213:17:213:17 | b | test.rs:216:13:216:17 | false | false | -| test.rs:213:22:213:22 | c | test.rs:214:13:214:16 | true | true | -| test.rs:213:22:213:22 | c | test.rs:216:13:216:17 | false | false | -| test.rs:213:24:215:9 | BlockExpr | test.rs:213:9:217:9 | IfExpr | | -| test.rs:214:13:214:16 | true | test.rs:213:24:215:9 | BlockExpr | | -| test.rs:215:16:217:9 | BlockExpr | test.rs:213:9:217:9 | IfExpr | | -| test.rs:216:13:216:17 | false | test.rs:215:16:217:9 | BlockExpr | | -| test.rs:220:5:226:5 | enter test_if_or_operator | test.rs:221:12:221:22 | ... \|\| ... | | -| test.rs:220:5:226:5 | exit test_if_or_operator (normal) | test.rs:220:5:226:5 | exit test_if_or_operator | | -| test.rs:220:62:226:5 | BlockExpr | test.rs:220:5:226:5 | exit test_if_or_operator (normal) | | -| test.rs:221:9:225:9 | IfExpr | test.rs:220:62:226:5 | BlockExpr | | -| test.rs:221:12:221:12 | a | test.rs:221:17:221:17 | b | false | -| test.rs:221:12:221:12 | a | test.rs:222:13:222:16 | true | true | -| test.rs:221:12:221:17 | ... \|\| ... | test.rs:221:12:221:12 | a | | -| test.rs:221:12:221:22 | ... \|\| ... | test.rs:221:12:221:17 | ... \|\| ... | | -| test.rs:221:17:221:17 | b | test.rs:221:22:221:22 | c | false | -| test.rs:221:17:221:17 | b | test.rs:222:13:222:16 | true | true | -| test.rs:221:22:221:22 | c | test.rs:222:13:222:16 | true | true | -| test.rs:221:22:221:22 | c | test.rs:224:13:224:17 | false | false | -| test.rs:221:24:223:9 | BlockExpr | test.rs:221:9:225:9 | IfExpr | | -| test.rs:222:13:222:16 | true | test.rs:221:24:223:9 | BlockExpr | | -| test.rs:223:16:225:9 | BlockExpr | test.rs:221:9:225:9 | IfExpr | | -| test.rs:224:13:224:17 | false | test.rs:223:16:225:9 | BlockExpr | | -| test.rs:228:5:234:5 | enter test_if_not_operator | test.rs:229:13:229:13 | a | | -| test.rs:228:5:234:5 | exit test_if_not_operator (normal) | test.rs:228:5:234:5 | exit test_if_not_operator | | -| test.rs:228:46:234:5 | BlockExpr | test.rs:228:5:234:5 | exit test_if_not_operator (normal) | | -| test.rs:229:9:233:9 | IfExpr | test.rs:228:46:234:5 | BlockExpr | | -| test.rs:229:12:229:13 | ! ... | test.rs:230:13:230:16 | true | true | -| test.rs:229:12:229:13 | ! ... | test.rs:232:13:232:17 | false | false | -| test.rs:229:13:229:13 | a | test.rs:229:12:229:13 | ! ... | false, true | -| test.rs:229:15:231:9 | BlockExpr | test.rs:229:9:233:9 | IfExpr | | -| test.rs:230:13:230:16 | true | test.rs:229:15:231:9 | BlockExpr | | -| test.rs:231:16:233:9 | BlockExpr | test.rs:229:9:233:9 | IfExpr | | -| test.rs:232:13:232:17 | false | test.rs:231:16:233:9 | BlockExpr | | -| test.rs:237:1:243:1 | enter test_match | test.rs:238:11:238:21 | maybe_digit | | -| test.rs:237:1:243:1 | exit test_match (normal) | test.rs:237:1:243:1 | exit test_match | | -| test.rs:237:48:243:1 | BlockExpr | test.rs:237:1:243:1 | exit test_match (normal) | | -| test.rs:238:5:242:5 | MatchExpr | test.rs:237:48:243:1 | BlockExpr | | -| test.rs:238:11:238:21 | maybe_digit | test.rs:239:9:239:23 | TupleStructPat | | -| test.rs:239:9:239:23 | TupleStructPat | test.rs:239:28:239:28 | x | match | -| test.rs:239:9:239:23 | TupleStructPat | test.rs:240:9:240:23 | TupleStructPat | no-match | -| test.rs:239:28:239:28 | x | test.rs:239:32:239:33 | 10 | | -| test.rs:239:28:239:33 | ... < ... | test.rs:239:38:239:38 | x | true | -| test.rs:239:28:239:33 | ... < ... | test.rs:240:9:240:23 | TupleStructPat | false | -| test.rs:239:32:239:33 | 10 | test.rs:239:28:239:33 | ... < ... | | -| test.rs:239:38:239:38 | x | test.rs:239:42:239:42 | 5 | | -| test.rs:239:38:239:42 | ... + ... | test.rs:238:5:242:5 | MatchExpr | | -| test.rs:239:42:239:42 | 5 | test.rs:239:38:239:42 | ... + ... | | -| test.rs:240:9:240:23 | TupleStructPat | test.rs:240:28:240:28 | x | match | -| test.rs:240:9:240:23 | TupleStructPat | test.rs:241:9:241:20 | PathPat | no-match | -| test.rs:240:28:240:28 | x | test.rs:238:5:242:5 | MatchExpr | | -| test.rs:241:9:241:20 | PathPat | test.rs:241:25:241:25 | 5 | match | -| test.rs:241:25:241:25 | 5 | test.rs:238:5:242:5 | MatchExpr | | -| test.rs:246:5:251:5 | enter test_infinite_loop | test.rs:247:9:249:9 | ExprStmt | | -| test.rs:247:9:249:9 | ExprStmt | test.rs:248:13:248:13 | 1 | | -| test.rs:247:14:249:9 | BlockExpr | test.rs:248:13:248:13 | 1 | | -| test.rs:248:13:248:13 | 1 | test.rs:247:14:249:9 | BlockExpr | | -| test.rs:253:5:256:5 | enter test_let_match | test.rs:254:9:254:49 | LetStmt | | -| test.rs:253:5:256:5 | exit test_let_match (normal) | test.rs:253:5:256:5 | exit test_let_match | | -| test.rs:253:39:256:5 | BlockExpr | test.rs:253:5:256:5 | exit test_let_match (normal) | | -| test.rs:254:9:254:49 | LetStmt | test.rs:254:23:254:23 | a | | -| test.rs:254:13:254:19 | TupleStructPat | test.rs:254:32:254:46 | "Expected some" | no-match | -| test.rs:254:13:254:19 | TupleStructPat | test.rs:255:9:255:9 | n | match | -| test.rs:254:23:254:23 | a | test.rs:254:13:254:19 | TupleStructPat | | -| test.rs:254:32:254:46 | "Expected some" | test.rs:254:30:254:48 | BlockExpr | | -| test.rs:255:9:255:9 | n | test.rs:253:39:256:5 | BlockExpr | | -| test.rs:259:1:264:1 | enter dead_code | test.rs:260:5:262:5 | ExprStmt | | -| test.rs:259:1:264:1 | exit dead_code (normal) | test.rs:259:1:264:1 | exit dead_code | | -| test.rs:260:5:262:5 | ExprStmt | test.rs:260:9:260:12 | true | | -| test.rs:260:9:260:12 | true | test.rs:261:9:261:17 | ExprStmt | true | -| test.rs:261:9:261:16 | ReturnExpr | test.rs:259:1:264:1 | exit dead_code (normal) | return | -| test.rs:261:9:261:17 | ExprStmt | test.rs:261:16:261:16 | 0 | | -| test.rs:261:16:261:16 | 0 | test.rs:261:9:261:16 | ReturnExpr | | -| test.rs:266:1:279:1 | enter labelled_block1 | test.rs:267:5:278:6 | LetStmt | | -| test.rs:266:1:279:1 | exit labelled_block1 (normal) | test.rs:266:1:279:1 | exit labelled_block1 | | -| test.rs:266:29:279:1 | BlockExpr | test.rs:266:1:279:1 | exit labelled_block1 (normal) | | -| test.rs:267:5:278:6 | LetStmt | test.rs:268:9:268:19 | ExprStmt | | -| test.rs:267:9:267:14 | result | test.rs:266:29:279:1 | BlockExpr | match, no-match | -| test.rs:267:18:278:5 | BlockExpr | test.rs:267:9:267:14 | result | | -| test.rs:268:9:268:16 | PathExpr | test.rs:268:9:268:18 | CallExpr | | -| test.rs:268:9:268:18 | CallExpr | test.rs:269:9:271:9 | ExprStmt | | -| test.rs:268:9:268:19 | ExprStmt | test.rs:268:9:268:16 | PathExpr | | -| test.rs:269:9:271:9 | ExprStmt | test.rs:269:12:269:28 | PathExpr | | -| test.rs:269:9:271:9 | IfExpr | test.rs:272:9:272:24 | ExprStmt | | -| test.rs:269:12:269:28 | PathExpr | test.rs:269:12:269:30 | CallExpr | | -| test.rs:269:12:269:30 | CallExpr | test.rs:269:9:271:9 | IfExpr | false | -| test.rs:269:12:269:30 | CallExpr | test.rs:270:13:270:27 | ExprStmt | true | -| test.rs:270:13:270:26 | BreakExpr | test.rs:267:18:278:5 | BlockExpr | break('block) | -| test.rs:270:13:270:27 | ExprStmt | test.rs:270:26:270:26 | 1 | | -| test.rs:270:26:270:26 | 1 | test.rs:270:13:270:26 | BreakExpr | | -| test.rs:272:9:272:21 | PathExpr | test.rs:272:9:272:23 | CallExpr | | -| test.rs:272:9:272:23 | CallExpr | test.rs:273:9:275:9 | ExprStmt | | -| test.rs:272:9:272:24 | ExprStmt | test.rs:272:9:272:21 | PathExpr | | -| test.rs:273:9:275:9 | ExprStmt | test.rs:273:12:273:28 | PathExpr | | -| test.rs:273:9:275:9 | IfExpr | test.rs:276:9:276:24 | ExprStmt | | -| test.rs:273:12:273:28 | PathExpr | test.rs:273:12:273:30 | CallExpr | | -| test.rs:273:12:273:30 | CallExpr | test.rs:273:9:275:9 | IfExpr | false | -| test.rs:273:12:273:30 | CallExpr | test.rs:274:13:274:27 | ExprStmt | true | -| test.rs:274:13:274:26 | BreakExpr | test.rs:267:18:278:5 | BlockExpr | break('block) | -| test.rs:274:13:274:27 | ExprStmt | test.rs:274:26:274:26 | 2 | | -| test.rs:274:26:274:26 | 2 | test.rs:274:13:274:26 | BreakExpr | | -| test.rs:276:9:276:21 | PathExpr | test.rs:276:9:276:23 | CallExpr | | -| test.rs:276:9:276:23 | CallExpr | test.rs:277:9:277:9 | 3 | | -| test.rs:276:9:276:24 | ExprStmt | test.rs:276:9:276:21 | PathExpr | | -| test.rs:277:9:277:9 | 3 | test.rs:267:18:278:5 | BlockExpr | | -| test.rs:281:1:289:1 | enter labelled_block2 | test.rs:282:5:288:6 | LetStmt | | -| test.rs:281:1:289:1 | exit labelled_block2 (normal) | test.rs:281:1:289:1 | exit labelled_block2 | | -| test.rs:281:29:289:1 | BlockExpr | test.rs:281:1:289:1 | exit labelled_block2 (normal) | | -| test.rs:282:5:288:6 | LetStmt | test.rs:283:9:283:34 | LetStmt | | -| test.rs:282:9:282:14 | result | test.rs:281:29:289:1 | BlockExpr | match, no-match | -| test.rs:282:18:288:5 | BlockExpr | test.rs:282:9:282:14 | result | | -| test.rs:283:9:283:34 | LetStmt | test.rs:283:30:283:33 | PathExpr | | -| test.rs:283:13:283:13 | x | test.rs:284:9:286:10 | LetStmt | match, no-match | -| test.rs:283:30:283:33 | PathExpr | test.rs:283:13:283:13 | x | | -| test.rs:284:9:286:10 | LetStmt | test.rs:284:23:284:23 | x | | -| test.rs:284:13:284:19 | TupleStructPat | test.rs:285:13:285:27 | ExprStmt | no-match | -| test.rs:284:13:284:19 | TupleStructPat | test.rs:287:9:287:9 | x | match | -| test.rs:284:23:284:23 | x | test.rs:284:13:284:19 | TupleStructPat | | -| test.rs:285:13:285:26 | BreakExpr | test.rs:282:18:288:5 | BlockExpr | break('block) | -| test.rs:285:13:285:27 | ExprStmt | test.rs:285:26:285:26 | 1 | | -| test.rs:285:26:285:26 | 1 | test.rs:285:13:285:26 | BreakExpr | | -| test.rs:287:9:287:9 | x | test.rs:282:18:288:5 | BlockExpr | | +| test.rs:54:5:66:5 | enter test_loop_label_shadowing | test.rs:56:13:56:14 | ExprStmt | | +| test.rs:56:13:56:13 | 1 | test.rs:58:17:62:17 | ExprStmt | | +| test.rs:56:13:56:14 | ExprStmt | test.rs:56:13:56:13 | 1 | | +| test.rs:58:17:62:17 | ExprStmt | test.rs:58:20:58:20 | b | | +| test.rs:58:17:62:17 | IfExpr | test.rs:63:17:63:31 | ExprStmt | | +| test.rs:58:20:58:20 | b | test.rs:59:21:59:29 | ExprStmt | true | +| test.rs:58:20:58:20 | b | test.rs:60:27:60:27 | b | false | +| test.rs:59:21:59:28 | ContinueExpr | test.rs:58:17:62:17 | ExprStmt | continue | +| test.rs:59:21:59:29 | ExprStmt | test.rs:59:21:59:28 | ContinueExpr | | +| test.rs:60:24:62:17 | IfExpr | test.rs:58:17:62:17 | IfExpr | | +| test.rs:60:27:60:27 | b | test.rs:60:24:62:17 | IfExpr | false | +| test.rs:60:27:60:27 | b | test.rs:61:21:61:35 | ExprStmt | true | +| test.rs:61:21:61:34 | ContinueExpr | test.rs:58:17:62:17 | ExprStmt | continue('loop) | +| test.rs:61:21:61:35 | ExprStmt | test.rs:61:21:61:34 | ContinueExpr | | +| test.rs:63:17:63:30 | ContinueExpr | test.rs:58:17:62:17 | ExprStmt | continue('loop) | +| test.rs:63:17:63:31 | ExprStmt | test.rs:63:17:63:30 | ContinueExpr | | +| test.rs:68:5:77:5 | enter test_while | test.rs:69:9:69:25 | LetStmt | | +| test.rs:68:5:77:5 | exit test_while (normal) | test.rs:68:5:77:5 | exit test_while | | +| test.rs:68:27:77:5 | BlockExpr | test.rs:68:5:77:5 | exit test_while (normal) | | +| test.rs:69:9:69:25 | LetStmt | test.rs:69:21:69:24 | true | | +| test.rs:69:13:69:17 | b | test.rs:70:15:70:15 | b | match, no-match | +| test.rs:69:21:69:24 | true | test.rs:69:13:69:17 | b | | +| test.rs:70:9:76:9 | WhileExpr | test.rs:68:27:77:5 | BlockExpr | | +| test.rs:70:15:70:15 | b | test.rs:70:9:76:9 | WhileExpr | false | +| test.rs:70:15:70:15 | b | test.rs:71:13:71:14 | ExprStmt | true | +| test.rs:70:17:76:9 | BlockExpr | test.rs:70:15:70:15 | b | | +| test.rs:71:13:71:13 | 1 | test.rs:72:13:74:13 | ExprStmt | | +| test.rs:71:13:71:14 | ExprStmt | test.rs:71:13:71:13 | 1 | | +| test.rs:72:13:74:13 | ExprStmt | test.rs:72:17:72:17 | i | | +| test.rs:72:13:74:13 | IfExpr | test.rs:75:13:75:22 | ExprStmt | | +| test.rs:72:17:72:17 | i | test.rs:72:21:72:21 | 0 | | +| test.rs:72:17:72:21 | ... > ... | test.rs:72:13:74:13 | IfExpr | false | +| test.rs:72:17:72:21 | ... > ... | test.rs:73:17:73:22 | ExprStmt | true | +| test.rs:72:21:72:21 | 0 | test.rs:72:17:72:21 | ... > ... | | +| test.rs:73:17:73:21 | BreakExpr | test.rs:70:9:76:9 | WhileExpr | break | +| test.rs:73:17:73:22 | ExprStmt | test.rs:73:17:73:21 | BreakExpr | | +| test.rs:75:13:75:13 | PathExpr | test.rs:75:17:75:21 | false | | +| test.rs:75:13:75:21 | ... = ... | test.rs:70:17:76:9 | BlockExpr | | +| test.rs:75:13:75:22 | ExprStmt | test.rs:75:13:75:13 | PathExpr | | +| test.rs:75:17:75:21 | false | test.rs:75:13:75:21 | ... = ... | | +| test.rs:79:5:86:5 | enter test_while_let | test.rs:80:9:80:29 | LetStmt | | +| test.rs:79:5:86:5 | exit test_while_let (normal) | test.rs:79:5:86:5 | exit test_while_let | | +| test.rs:79:25:86:5 | BlockExpr | test.rs:79:5:86:5 | exit test_while_let (normal) | | +| test.rs:80:9:80:29 | LetStmt | test.rs:80:24:80:24 | 1 | | +| test.rs:80:13:80:20 | iter | test.rs:81:15:81:39 | LetExpr | match, no-match | +| test.rs:80:24:80:24 | 1 | test.rs:80:27:80:28 | 10 | | +| test.rs:80:24:80:28 | RangeExpr | test.rs:80:13:80:20 | iter | | +| test.rs:80:27:80:28 | 10 | test.rs:80:24:80:28 | RangeExpr | | +| test.rs:81:9:85:9 | WhileExpr | test.rs:79:25:86:5 | BlockExpr | | +| test.rs:81:15:81:39 | LetExpr | test.rs:81:19:81:25 | TupleStructPat | | +| test.rs:81:19:81:25 | TupleStructPat | test.rs:81:9:85:9 | WhileExpr | no-match | +| test.rs:81:19:81:25 | TupleStructPat | test.rs:82:17:82:17 | PathExpr | match | +| test.rs:81:41:85:9 | BlockExpr | test.rs:81:15:81:39 | LetExpr | | +| test.rs:82:13:84:13 | IfExpr | test.rs:81:41:85:9 | BlockExpr | | +| test.rs:82:17:82:17 | PathExpr | test.rs:82:21:82:21 | 5 | | +| test.rs:82:17:82:21 | ... = ... | test.rs:82:13:84:13 | IfExpr | false | +| test.rs:82:17:82:21 | ... = ... | test.rs:83:17:83:22 | ExprStmt | true | +| test.rs:82:21:82:21 | 5 | test.rs:82:17:82:21 | ... = ... | | +| test.rs:83:17:83:21 | BreakExpr | test.rs:81:9:85:9 | WhileExpr | break | +| test.rs:83:17:83:22 | ExprStmt | test.rs:83:17:83:21 | BreakExpr | | +| test.rs:88:5:95:5 | enter test_for | test.rs:89:18:89:18 | 0 | | +| test.rs:88:5:95:5 | exit test_for (normal) | test.rs:88:5:95:5 | exit test_for | | +| test.rs:88:25:95:5 | BlockExpr | test.rs:88:5:95:5 | exit test_for (normal) | | +| test.rs:89:9:94:9 | ForExpr | test.rs:88:25:95:5 | BlockExpr | | +| test.rs:89:13:89:13 | i | test.rs:89:9:94:9 | ForExpr | no-match | +| test.rs:89:13:89:13 | i | test.rs:90:13:92:13 | ExprStmt | match | +| test.rs:89:18:89:18 | 0 | test.rs:89:21:89:22 | 10 | | +| test.rs:89:18:89:22 | RangeExpr | test.rs:89:13:89:13 | i | | +| test.rs:89:21:89:22 | 10 | test.rs:89:18:89:22 | RangeExpr | | +| test.rs:89:24:94:9 | BlockExpr | test.rs:89:13:89:13 | i | | +| 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:14 | ExprStmt | | +| test.rs:90:17:90:17 | i | test.rs:90:22:90:22 | j | | +| test.rs:90:17:90:22 | ... == ... | test.rs:90:13:92:13 | IfExpr | false | +| test.rs:90:17:90:22 | ... == ... | test.rs:91:17:91:22 | ExprStmt | true | +| test.rs:90:22:90:22 | j | test.rs:90:17:90:22 | ... == ... | | +| test.rs:91:17:91:21 | BreakExpr | test.rs:89:9:94:9 | ForExpr | break | +| test.rs:91:17:91:22 | ExprStmt | test.rs:91:17:91:21 | BreakExpr | | +| test.rs:93:13:93:13 | 1 | test.rs:89:24:94:9 | BlockExpr | | +| test.rs:93:13:93:14 | ExprStmt | test.rs:93:13:93:13 | 1 | | +| test.rs:98:1:101:1 | enter test_nested_function | test.rs:99:5:99:28 | LetStmt | | +| test.rs:98:1:101:1 | exit test_nested_function (normal) | test.rs:98:1:101:1 | exit test_nested_function | | +| test.rs:98:40:101:1 | BlockExpr | test.rs:98:1:101:1 | exit test_nested_function (normal) | | +| test.rs:99:5:99:28 | LetStmt | test.rs:99:19:99:27 | ClosureExpr | | +| test.rs:99:9:99:15 | add_one | test.rs:100:5:100:11 | add_one | match, no-match | +| test.rs:99:19:99:27 | ClosureExpr | test.rs:99:9:99:15 | add_one | | +| test.rs:99:19:99:27 | enter ClosureExpr | test.rs:99:23:99:23 | i | | +| test.rs:99:19:99:27 | exit ClosureExpr (normal) | test.rs:99:19:99:27 | exit ClosureExpr | | +| test.rs:99:23:99:23 | i | test.rs:99:27:99:27 | 1 | | +| test.rs:99:23:99:27 | ... + ... | test.rs:99:19:99:27 | exit ClosureExpr (normal) | | +| test.rs:99:27:99:27 | 1 | test.rs:99:23:99:27 | ... + ... | | +| test.rs:100:5:100:11 | add_one | test.rs:100:13:100:19 | add_one | | +| test.rs:100:5:100:23 | CallExpr | test.rs:98:40:101:1 | BlockExpr | | +| test.rs:100:13:100:19 | add_one | test.rs:100:21:100:21 | n | | +| test.rs:100:13:100:22 | CallExpr | test.rs:100:5:100:23 | CallExpr | | +| test.rs:100:21:100:21 | n | test.rs:100:13:100:22 | CallExpr | | +| test.rs:105:5:111:5 | enter test_if_else | test.rs:106:12:106:12 | n | | +| test.rs:105:5:111:5 | exit test_if_else (normal) | test.rs:105:5:111:5 | exit test_if_else | | +| test.rs:105:36:111:5 | BlockExpr | test.rs:105:5:111:5 | exit test_if_else (normal) | | +| test.rs:106:9:110:9 | IfExpr | test.rs:105:36:111:5 | BlockExpr | | +| test.rs:106:12:106:12 | n | test.rs:106:17:106:17 | 0 | | +| test.rs:106:12:106:17 | ... <= ... | test.rs:107:13:107:13 | 0 | true | +| test.rs:106:12:106:17 | ... <= ... | test.rs:109:13:109:13 | n | false | +| test.rs:106:17:106:17 | 0 | test.rs:106:12:106:17 | ... <= ... | | +| test.rs:106:19:108:9 | BlockExpr | test.rs:106:9:110:9 | IfExpr | | +| test.rs:107:13:107:13 | 0 | test.rs:106:19:108:9 | BlockExpr | | +| test.rs:108:16:110:9 | BlockExpr | test.rs:106:9:110:9 | IfExpr | | +| test.rs:109:13:109:13 | n | test.rs:109:17:109:17 | 1 | | +| test.rs:109:13:109:17 | ... - ... | test.rs:108:16:110:9 | BlockExpr | | +| test.rs:109:17:109:17 | 1 | test.rs:109:13:109:17 | ... - ... | | +| test.rs:113:5:119:5 | enter test_if_let_else | test.rs:114:12:114:26 | LetExpr | | +| test.rs:113:5:119:5 | exit test_if_let_else (normal) | test.rs:113:5:119:5 | exit test_if_let_else | | +| test.rs:113:48:119:5 | BlockExpr | test.rs:113:5:119:5 | exit test_if_let_else (normal) | | +| test.rs:114:9:118:9 | IfExpr | test.rs:113:48:119:5 | BlockExpr | | +| test.rs:114:12:114:26 | LetExpr | test.rs:114:16:114:22 | TupleStructPat | | +| test.rs:114:16:114:22 | TupleStructPat | test.rs:115:13:115:13 | n | match | +| test.rs:114:16:114:22 | TupleStructPat | test.rs:117:13:117:13 | 0 | no-match | +| test.rs:114:28:116:9 | BlockExpr | test.rs:114:9:118:9 | IfExpr | | +| test.rs:115:13:115:13 | n | test.rs:114:28:116:9 | BlockExpr | | +| test.rs:116:16:118:9 | BlockExpr | test.rs:114:9:118:9 | IfExpr | | +| test.rs:117:13:117:13 | 0 | test.rs:116:16:118:9 | BlockExpr | | +| test.rs:121:5:126:5 | enter test_if_let | test.rs:122:9:124:9 | ExprStmt | | +| test.rs:121:5:126:5 | exit test_if_let (normal) | test.rs:121:5:126:5 | exit test_if_let | | +| test.rs:121:43:126:5 | BlockExpr | test.rs:121:5:126:5 | exit test_if_let (normal) | | +| test.rs:122:9:124:9 | ExprStmt | test.rs:122:12:122:26 | LetExpr | | +| test.rs:122:9:124:9 | IfExpr | test.rs:125:9:125:9 | 0 | | +| test.rs:122:12:122:26 | LetExpr | test.rs:122:16:122:22 | TupleStructPat | | +| test.rs:122:16:122:22 | TupleStructPat | test.rs:122:9:124:9 | IfExpr | no-match | +| test.rs:122:16:122:22 | TupleStructPat | test.rs:123:13:123:13 | n | match | +| test.rs:122:28:124:9 | BlockExpr | test.rs:122:9:124:9 | IfExpr | | +| test.rs:123:13:123:13 | n | test.rs:122:28:124:9 | BlockExpr | | +| test.rs:125:9:125:9 | 0 | test.rs:121:43:126:5 | BlockExpr | | +| test.rs:128:5:134:5 | enter test_nested_if | test.rs:129:16:129:16 | PathExpr | | +| test.rs:128:5:134:5 | exit test_nested_if (normal) | test.rs:128:5:134:5 | exit test_nested_if | | +| test.rs:128:38:134:5 | BlockExpr | test.rs:128:5:134:5 | exit test_nested_if (normal) | | +| test.rs:129:9:133:9 | IfExpr | test.rs:128:38:134:5 | BlockExpr | | +| test.rs:129:13:129:48 | IfExpr | test.rs:130:13:130:13 | 1 | true | +| test.rs:129:13:129:48 | IfExpr | test.rs:132:13:132:13 | 0 | false | +| test.rs:129:16:129:16 | PathExpr | test.rs:129:20:129:20 | 0 | | +| test.rs:129:16:129:20 | ... < ... | test.rs:129:24:129:24 | a | true | +| test.rs:129:16:129:20 | ... < ... | test.rs:129:41:129:41 | a | false | +| test.rs:129:20:129:20 | 0 | test.rs:129:16:129:20 | ... < ... | | +| test.rs:129:22:129:32 | BlockExpr | test.rs:129:13:129:48 | IfExpr | false, true | +| test.rs:129:24:129:24 | a | test.rs:129:29:129:30 | 10 | | +| test.rs:129:24:129:30 | ... < ... | test.rs:129:22:129:32 | BlockExpr | false, true | +| test.rs:129:28:129:30 | - ... | test.rs:129:24:129:30 | ... < ... | | +| test.rs:129:29:129:30 | 10 | test.rs:129:28:129:30 | - ... | | +| test.rs:129:39:129:48 | BlockExpr | test.rs:129:13:129:48 | IfExpr | false, true | +| test.rs:129:41:129:41 | a | test.rs:129:45:129:46 | 10 | | +| test.rs:129:41:129:46 | ... > ... | test.rs:129:39:129:48 | BlockExpr | false, true | +| test.rs:129:45:129:46 | 10 | test.rs:129:41:129:46 | ... > ... | | +| test.rs:129:51:131:9 | BlockExpr | test.rs:129:9:133:9 | IfExpr | | +| test.rs:130:13:130:13 | 1 | test.rs:129:51:131:9 | BlockExpr | | +| test.rs:131:16:133:9 | BlockExpr | test.rs:129:9:133:9 | IfExpr | | +| test.rs:132:13:132:13 | 0 | test.rs:131:16:133:9 | BlockExpr | | +| test.rs:136:5:145:5 | enter test_nested_if_match | test.rs:137:19:137:19 | a | | +| test.rs:136:5:145:5 | exit test_nested_if_match (normal) | test.rs:136:5:145:5 | exit test_nested_if_match | | +| test.rs:136:44:145:5 | BlockExpr | test.rs:136:5:145:5 | exit test_nested_if_match (normal) | | +| test.rs:137:9:144:9 | IfExpr | test.rs:136:44:145:5 | BlockExpr | | +| test.rs:137:13:140:9 | MatchExpr | test.rs:141:13:141:13 | 1 | true | +| test.rs:137:13:140:9 | MatchExpr | test.rs:143:13:143:13 | 0 | false | +| test.rs:137:19:137:19 | a | test.rs:138:13:138:13 | LiteralPat | | +| test.rs:138:13:138:13 | LiteralPat | test.rs:138:18:138:21 | true | match | +| test.rs:138:13:138:13 | LiteralPat | test.rs:139:13:139:13 | WildcardPat | no-match | +| test.rs:138:18:138:21 | true | test.rs:137:13:140:9 | MatchExpr | | +| test.rs:139:13:139:13 | WildcardPat | test.rs:139:18:139:22 | false | match | +| test.rs:139:18:139:22 | false | test.rs:137:13:140:9 | MatchExpr | | +| test.rs:140:12:142:9 | BlockExpr | test.rs:137:9:144:9 | IfExpr | | +| test.rs:141:13:141:13 | 1 | test.rs:140:12:142:9 | BlockExpr | | +| test.rs:142:16:144:9 | BlockExpr | test.rs:137:9:144:9 | IfExpr | | +| test.rs:143:13:143:13 | 0 | test.rs:142:16:144:9 | BlockExpr | | +| test.rs:147:5:156:5 | enter test_nested_if_block | test.rs:149:13:149:15 | ExprStmt | | +| test.rs:147:5:156:5 | exit test_nested_if_block (normal) | test.rs:147:5:156:5 | exit test_nested_if_block | | +| test.rs:147:44:156:5 | BlockExpr | test.rs:147:5:156:5 | exit test_nested_if_block (normal) | | +| test.rs:148:9:155:9 | IfExpr | test.rs:147:44:156:5 | BlockExpr | | +| test.rs:148:12:151:9 | BlockExpr | test.rs:152:13:152:13 | 1 | true | +| test.rs:148:12:151:9 | BlockExpr | test.rs:154:13:154:13 | 0 | false | +| test.rs:149:13:149:14 | TupleExpr | test.rs:150:13:150:13 | a | | +| test.rs:149:13:149:15 | ExprStmt | test.rs:149:13:149:14 | TupleExpr | | +| test.rs:150:13:150:13 | a | test.rs:150:17:150:17 | 0 | | +| test.rs:150:13:150:17 | ... > ... | test.rs:148:12:151:9 | BlockExpr | false, true | +| test.rs:150:17:150:17 | 0 | test.rs:150:13:150:17 | ... > ... | | +| test.rs:151:11:153:9 | BlockExpr | test.rs:148:9:155:9 | IfExpr | | +| test.rs:152:13:152:13 | 1 | test.rs:151:11:153:9 | BlockExpr | | +| test.rs:153:16:155:9 | BlockExpr | test.rs:148:9:155:9 | IfExpr | | +| test.rs:154:13:154:13 | 0 | test.rs:153:16:155:9 | BlockExpr | | +| test.rs:158:5:165:5 | enter test_if_assignment | test.rs:159:9:159:26 | LetStmt | | +| test.rs:158:5:165:5 | exit test_if_assignment (normal) | test.rs:158:5:165:5 | exit test_if_assignment | | +| test.rs:158:42:165:5 | BlockExpr | test.rs:158:5:165:5 | exit test_if_assignment (normal) | | +| test.rs:159:9:159:26 | LetStmt | test.rs:159:21:159:25 | false | | +| test.rs:159:13:159:17 | x | test.rs:160:12:160:12 | x | match, no-match | +| test.rs:159:21:159:25 | false | test.rs:159:13:159:17 | x | | +| test.rs:160:9:164:9 | IfExpr | test.rs:158:42:165:5 | BlockExpr | | +| test.rs:160:12:160:12 | x | test.rs:160:16:160:19 | true | | +| test.rs:160:12:160:19 | ... = ... | test.rs:161:13:161:13 | 1 | true | +| test.rs:160:12:160:19 | ... = ... | test.rs:163:13:163:13 | 0 | false | +| test.rs:160:16:160:19 | true | test.rs:160:12:160:19 | ... = ... | | +| test.rs:160:21:162:9 | BlockExpr | test.rs:160:9:164:9 | IfExpr | | +| test.rs:161:13:161:13 | 1 | test.rs:160:21:162:9 | BlockExpr | | +| test.rs:162:16:164:9 | BlockExpr | test.rs:160:9:164:9 | IfExpr | | +| test.rs:163:13:163:13 | 0 | test.rs:162:16:164:9 | BlockExpr | | +| test.rs:167:5:178:5 | enter test_if_loop1 | test.rs:169:13:171:14 | ExprStmt | | +| test.rs:167:5:178:5 | exit test_if_loop1 (normal) | test.rs:167:5:178:5 | exit test_if_loop1 | | +| test.rs:167:37:178:5 | BlockExpr | test.rs:167:5:178:5 | exit test_if_loop1 (normal) | | +| test.rs:168:9:177:9 | IfExpr | test.rs:167:37:178:5 | BlockExpr | | +| test.rs:168:13:173:9 | LoopExpr | test.rs:174:13:174:13 | 1 | true | +| test.rs:168:13:173:9 | LoopExpr | test.rs:176:13:176:13 | 0 | false | +| test.rs:168:18:173:9 | BlockExpr | test.rs:169:13:171:14 | ExprStmt | | +| test.rs:169:13:171:13 | IfExpr | test.rs:172:13:172:19 | ExprStmt | | +| test.rs:169:13:171:14 | ExprStmt | test.rs:169:16:169:16 | a | | +| test.rs:169:16:169:16 | a | test.rs:169:20:169:20 | 0 | | +| test.rs:169:16:169:20 | ... > ... | test.rs:169:13:171:13 | IfExpr | false | +| test.rs:169:16:169:20 | ... > ... | test.rs:170:17:170:29 | ExprStmt | true | +| test.rs:169:20:169:20 | 0 | test.rs:169:16:169:20 | ... > ... | | +| test.rs:170:17:170:28 | BreakExpr | test.rs:168:13:173:9 | LoopExpr | break | +| test.rs:170:17:170:29 | ExprStmt | test.rs:170:23:170:23 | a | | +| test.rs:170:23:170:23 | a | test.rs:170:27:170:28 | 10 | | +| test.rs:170:23:170:28 | ... > ... | test.rs:170:17:170:28 | BreakExpr | | +| test.rs:170:27:170:28 | 10 | test.rs:170:23:170:28 | ... > ... | | +| test.rs:172:13:172:13 | a | test.rs:172:17:172:18 | 10 | | +| test.rs:172:13:172:18 | ... < ... | test.rs:168:18:173:9 | BlockExpr | | +| test.rs:172:13:172:19 | ExprStmt | test.rs:172:13:172:13 | a | | +| test.rs:172:17:172:18 | 10 | test.rs:172:13:172:18 | ... < ... | | +| test.rs:173:12:175:9 | BlockExpr | test.rs:168:9:177:9 | IfExpr | | +| test.rs:174:13:174:13 | 1 | test.rs:173:12:175:9 | BlockExpr | | +| test.rs:175:16:177:9 | BlockExpr | test.rs:168:9:177:9 | IfExpr | | +| test.rs:176:13:176:13 | 0 | test.rs:175:16:177:9 | BlockExpr | | +| test.rs:180:5:191:5 | enter test_if_loop2 | test.rs:182:13:184:14 | ExprStmt | | +| test.rs:180:5:191:5 | exit test_if_loop2 (normal) | test.rs:180:5:191:5 | exit test_if_loop2 | | +| test.rs:180:37:191:5 | BlockExpr | test.rs:180:5:191:5 | exit test_if_loop2 (normal) | | +| test.rs:181:9:190:9 | IfExpr | test.rs:180:37:191:5 | BlockExpr | | +| test.rs:181:13:186:9 | LoopExpr | test.rs:187:13:187:13 | 1 | true | +| test.rs:181:13:186:9 | LoopExpr | test.rs:189:13:189:13 | 0 | false | +| test.rs:181:26:186:9 | BlockExpr | test.rs:182:13:184:14 | ExprStmt | | +| test.rs:182:13:184:13 | IfExpr | test.rs:185:13:185:19 | ExprStmt | | +| test.rs:182:13:184:14 | ExprStmt | test.rs:182:16:182:16 | a | | +| test.rs:182:16:182:16 | a | test.rs:182:20:182:20 | 0 | | +| test.rs:182:16:182:20 | ... > ... | test.rs:182:13:184:13 | IfExpr | false | +| test.rs:182:16:182:20 | ... > ... | test.rs:183:17:183:36 | ExprStmt | true | +| test.rs:182:20:182:20 | 0 | test.rs:182:16:182:20 | ... > ... | | +| test.rs:183:17:183:35 | BreakExpr | test.rs:181:13:186:9 | LoopExpr | break('label) | +| test.rs:183:17:183:36 | ExprStmt | test.rs:183:30:183:30 | a | | +| test.rs:183:30:183:30 | a | test.rs:183:34:183:35 | 10 | | +| test.rs:183:30:183:35 | ... > ... | test.rs:183:17:183:35 | BreakExpr | | +| test.rs:183:34:183:35 | 10 | test.rs:183:30:183:35 | ... > ... | | +| test.rs:185:13:185:13 | a | test.rs:185:17:185:18 | 10 | | +| test.rs:185:13:185:18 | ... < ... | test.rs:181:26:186:9 | BlockExpr | | +| test.rs:185:13:185:19 | ExprStmt | test.rs:185:13:185:13 | a | | +| test.rs:185:17:185:18 | 10 | test.rs:185:13:185:18 | ... < ... | | +| test.rs:186:12:188:9 | BlockExpr | test.rs:181:9:190:9 | IfExpr | | +| test.rs:187:13:187:13 | 1 | test.rs:186:12:188:9 | BlockExpr | | +| test.rs:188:16:190:9 | BlockExpr | test.rs:181:9:190:9 | IfExpr | | +| test.rs:189:13:189:13 | 0 | test.rs:188:16:190:9 | BlockExpr | | +| test.rs:193:5:201:5 | enter test_labelled_block | test.rs:195:13:195:31 | ExprStmt | | +| test.rs:193:5:201:5 | exit test_labelled_block (normal) | test.rs:193:5:201:5 | exit test_labelled_block | | +| test.rs:193:43:201:5 | BlockExpr | test.rs:193:5:201:5 | exit test_labelled_block (normal) | | +| test.rs:194:9:200:9 | IfExpr | test.rs:193:43:201:5 | BlockExpr | | +| test.rs:194:13:196:9 | BlockExpr | test.rs:197:13:197:13 | 1 | true | +| test.rs:194:13:196:9 | BlockExpr | test.rs:199:13:199:13 | 0 | false | +| test.rs:195:13:195:30 | BreakExpr | test.rs:194:13:196:9 | BlockExpr | break('block) | +| test.rs:195:13:195:31 | ExprStmt | test.rs:195:26:195:26 | a | | +| test.rs:195:26:195:26 | a | test.rs:195:30:195:30 | 0 | | +| test.rs:195:26:195:30 | ... > ... | test.rs:195:13:195:30 | BreakExpr | | +| test.rs:195:30:195:30 | 0 | test.rs:195:26:195:30 | ... > ... | | +| test.rs:196:12:198:9 | BlockExpr | test.rs:194:9:200:9 | IfExpr | | +| test.rs:197:13:197:13 | 1 | test.rs:196:12:198:9 | BlockExpr | | +| test.rs:198:16:200:9 | BlockExpr | test.rs:194:9:200:9 | IfExpr | | +| test.rs:199:13:199:13 | 0 | test.rs:198:16:200:9 | BlockExpr | | +| test.rs:206:5:209:5 | enter test_and_operator | test.rs:207:9:207:28 | LetStmt | | +| test.rs:206:5:209:5 | exit test_and_operator (normal) | test.rs:206:5:209:5 | exit test_and_operator | | +| test.rs:206:61:209:5 | BlockExpr | test.rs:206:5:209:5 | exit test_and_operator (normal) | | +| test.rs:207:9:207:28 | LetStmt | test.rs:207:17:207:27 | ... && ... | | +| test.rs:207:13:207:13 | d | test.rs:208:9:208:9 | d | match, no-match | +| test.rs:207:17:207:17 | a | test.rs:207:13:207:13 | d | false | +| test.rs:207:17:207:17 | a | test.rs:207:22:207:22 | b | true | +| test.rs:207:17:207:22 | ... && ... | test.rs:207:17:207:17 | a | | +| test.rs:207:17:207:27 | ... && ... | test.rs:207:17:207:22 | ... && ... | | +| test.rs:207:22:207:22 | b | test.rs:207:13:207:13 | d | false | +| test.rs:207:22:207:22 | b | test.rs:207:27:207:27 | c | true | +| test.rs:207:27:207:27 | c | test.rs:207:13:207:13 | d | | +| test.rs:208:9:208:9 | d | test.rs:206:61:209:5 | BlockExpr | | +| test.rs:211:5:214:5 | enter test_or_operator | test.rs:212:9:212:28 | LetStmt | | +| test.rs:211:5:214:5 | exit test_or_operator (normal) | test.rs:211:5:214:5 | exit test_or_operator | | +| test.rs:211:60:214:5 | BlockExpr | test.rs:211:5:214:5 | exit test_or_operator (normal) | | +| test.rs:212:9:212:28 | LetStmt | test.rs:212:17:212:27 | ... \|\| ... | | +| test.rs:212:13:212:13 | d | test.rs:213:9:213:9 | d | match, no-match | +| test.rs:212:17:212:17 | a | test.rs:212:13:212:13 | d | true | +| test.rs:212:17:212:17 | a | test.rs:212:22:212:22 | b | false | +| test.rs:212:17:212:22 | ... \|\| ... | test.rs:212:17:212:17 | a | | +| test.rs:212:17:212:27 | ... \|\| ... | test.rs:212:17:212:22 | ... \|\| ... | | +| test.rs:212:22:212:22 | b | test.rs:212:13:212:13 | d | true | +| test.rs:212:22:212:22 | b | test.rs:212:27:212:27 | c | false | +| test.rs:212:27:212:27 | c | test.rs:212:13:212:13 | d | | +| test.rs:213:9:213:9 | d | test.rs:211:60:214:5 | BlockExpr | | +| test.rs:216:5:219:5 | enter test_or_operator_2 | test.rs:217:9:217:36 | LetStmt | | +| test.rs:216:5:219:5 | exit test_or_operator_2 (normal) | test.rs:216:5:219:5 | exit test_or_operator_2 | | +| test.rs:216:61:219:5 | BlockExpr | test.rs:216:5:219:5 | exit test_or_operator_2 (normal) | | +| test.rs:217:9:217:36 | LetStmt | test.rs:217:17:217:35 | ... \|\| ... | | +| test.rs:217:13:217:13 | d | test.rs:218:9:218:9 | d | match, no-match | +| test.rs:217:17:217:17 | a | test.rs:217:13:217:13 | d | true | +| test.rs:217:17:217:17 | a | test.rs:217:23:217:23 | b | false | +| test.rs:217:17:217:30 | ... \|\| ... | test.rs:217:17:217:17 | a | | +| test.rs:217:17:217:35 | ... \|\| ... | test.rs:217:17:217:30 | ... \|\| ... | | +| test.rs:217:23:217:23 | b | test.rs:217:28:217:29 | 28 | | +| test.rs:217:23:217:29 | ... == ... | test.rs:217:13:217:13 | d | true | +| test.rs:217:23:217:29 | ... == ... | test.rs:217:35:217:35 | c | false | +| test.rs:217:28:217:29 | 28 | test.rs:217:23:217:29 | ... == ... | | +| test.rs:217:35:217:35 | c | test.rs:217:13:217:13 | d | | +| test.rs:218:9:218:9 | d | test.rs:216:61:219:5 | BlockExpr | | +| test.rs:221:5:224:5 | enter test_not_operator | test.rs:222:9:222:19 | LetStmt | | +| test.rs:221:5:224:5 | exit test_not_operator (normal) | test.rs:221:5:224:5 | exit test_not_operator | | +| test.rs:221:43:224:5 | BlockExpr | test.rs:221:5:224:5 | exit test_not_operator (normal) | | +| test.rs:222:9:222:19 | LetStmt | test.rs:222:18:222:18 | a | | +| test.rs:222:13:222:13 | d | test.rs:223:9:223:9 | d | match, no-match | +| test.rs:222:17:222:18 | ! ... | test.rs:222:13:222:13 | d | | +| test.rs:222:18:222:18 | a | test.rs:222:17:222:18 | ! ... | | +| test.rs:223:9:223:9 | d | test.rs:221:43:224:5 | BlockExpr | | +| test.rs:226:5:232:5 | enter test_if_and_operator | test.rs:227:12:227:22 | ... && ... | | +| test.rs:226:5:232:5 | exit test_if_and_operator (normal) | test.rs:226:5:232:5 | exit test_if_and_operator | | +| test.rs:226:63:232:5 | BlockExpr | test.rs:226:5:232:5 | exit test_if_and_operator (normal) | | +| test.rs:227:9:231:9 | IfExpr | test.rs:226:63:232:5 | BlockExpr | | +| test.rs:227:12:227:12 | a | test.rs:227:17:227:17 | b | true | +| test.rs:227:12:227:12 | a | test.rs:230:13:230:17 | false | false | +| test.rs:227:12:227:17 | ... && ... | test.rs:227:12:227:12 | a | | +| test.rs:227:12:227:22 | ... && ... | test.rs:227:12:227:17 | ... && ... | | +| test.rs:227:17:227:17 | b | test.rs:227:22:227:22 | c | true | +| test.rs:227:17:227:17 | b | test.rs:230:13:230:17 | false | false | +| test.rs:227:22:227:22 | c | test.rs:228:13:228:16 | true | true | +| test.rs:227:22:227:22 | c | test.rs:230:13:230:17 | false | false | +| test.rs:227:24:229:9 | BlockExpr | test.rs:227:9:231:9 | IfExpr | | +| test.rs:228:13:228:16 | true | test.rs:227:24:229:9 | BlockExpr | | +| test.rs:229:16:231:9 | BlockExpr | test.rs:227:9:231:9 | IfExpr | | +| test.rs:230:13:230:17 | false | test.rs:229:16:231:9 | BlockExpr | | +| test.rs:234:5:240:5 | enter test_if_or_operator | test.rs:235:12:235:22 | ... \|\| ... | | +| test.rs:234:5:240:5 | exit test_if_or_operator (normal) | test.rs:234:5:240:5 | exit test_if_or_operator | | +| test.rs:234:62:240:5 | BlockExpr | test.rs:234:5:240:5 | exit test_if_or_operator (normal) | | +| test.rs:235:9:239:9 | IfExpr | test.rs:234:62:240:5 | BlockExpr | | +| test.rs:235:12:235:12 | a | test.rs:235:17:235:17 | b | false | +| test.rs:235:12:235:12 | a | test.rs:236:13:236:16 | true | true | +| test.rs:235:12:235:17 | ... \|\| ... | test.rs:235:12:235:12 | a | | +| test.rs:235:12:235:22 | ... \|\| ... | test.rs:235:12:235:17 | ... \|\| ... | | +| test.rs:235:17:235:17 | b | test.rs:235:22:235:22 | c | false | +| test.rs:235:17:235:17 | b | test.rs:236:13:236:16 | true | true | +| test.rs:235:22:235:22 | c | test.rs:236:13:236:16 | true | true | +| test.rs:235:22:235:22 | c | test.rs:238:13:238:17 | false | false | +| test.rs:235:24:237:9 | BlockExpr | test.rs:235:9:239:9 | IfExpr | | +| test.rs:236:13:236:16 | true | test.rs:235:24:237:9 | BlockExpr | | +| test.rs:237:16:239:9 | BlockExpr | test.rs:235:9:239:9 | IfExpr | | +| test.rs:238:13:238:17 | false | test.rs:237:16:239:9 | BlockExpr | | +| test.rs:242:5:248:5 | enter test_if_not_operator | test.rs:243:13:243:13 | a | | +| test.rs:242:5:248:5 | exit test_if_not_operator (normal) | test.rs:242:5:248:5 | exit test_if_not_operator | | +| test.rs:242:46:248:5 | BlockExpr | test.rs:242:5:248:5 | exit test_if_not_operator (normal) | | +| test.rs:243:9:247:9 | IfExpr | test.rs:242:46:248:5 | BlockExpr | | +| test.rs:243:12:243:13 | ! ... | test.rs:244:13:244:16 | true | true | +| test.rs:243:12:243:13 | ! ... | test.rs:246:13:246:17 | false | false | +| test.rs:243:13:243:13 | a | test.rs:243:12:243:13 | ! ... | false, true | +| test.rs:243:15:245:9 | BlockExpr | test.rs:243:9:247:9 | IfExpr | | +| test.rs:244:13:244:16 | true | test.rs:243:15:245:9 | BlockExpr | | +| test.rs:245:16:247:9 | BlockExpr | test.rs:243:9:247:9 | IfExpr | | +| test.rs:246:13:246:17 | false | test.rs:245:16:247:9 | BlockExpr | | +| test.rs:251:1:257:1 | enter test_match | test.rs:252:11:252:21 | maybe_digit | | +| test.rs:251:1:257:1 | exit test_match (normal) | test.rs:251:1:257:1 | exit test_match | | +| test.rs:251:48:257:1 | BlockExpr | test.rs:251:1:257:1 | exit test_match (normal) | | +| test.rs:252:5:256:5 | MatchExpr | test.rs:251:48:257:1 | BlockExpr | | +| test.rs:252:11:252:21 | maybe_digit | test.rs:253:9:253:23 | TupleStructPat | | +| test.rs:253:9:253:23 | TupleStructPat | test.rs:253:28:253:28 | x | match | +| test.rs:253:9:253:23 | TupleStructPat | test.rs:254:9:254:23 | TupleStructPat | no-match | +| test.rs:253:28:253:28 | x | test.rs:253:32:253:33 | 10 | | +| test.rs:253:28:253:33 | ... < ... | test.rs:253:38:253:38 | x | true | +| test.rs:253:28:253:33 | ... < ... | test.rs:254:9:254:23 | TupleStructPat | false | +| test.rs:253:32:253:33 | 10 | test.rs:253:28:253:33 | ... < ... | | +| test.rs:253:38:253:38 | x | test.rs:253:42:253:42 | 5 | | +| test.rs:253:38:253:42 | ... + ... | test.rs:252:5:256:5 | MatchExpr | | +| test.rs:253:42:253:42 | 5 | test.rs:253:38:253:42 | ... + ... | | +| test.rs:254:9:254:23 | TupleStructPat | test.rs:254:28:254:28 | x | match | +| test.rs:254:9:254:23 | TupleStructPat | test.rs:255:9:255:20 | PathPat | no-match | +| test.rs:254:28:254:28 | x | test.rs:252:5:256:5 | MatchExpr | | +| test.rs:255:9:255:20 | PathPat | test.rs:255:25:255:25 | 5 | match | +| test.rs:255:25:255:25 | 5 | test.rs:252:5:256:5 | MatchExpr | | +| test.rs:260:5:265:5 | enter test_infinite_loop | test.rs:261:9:263:9 | ExprStmt | | +| test.rs:261:9:263:9 | ExprStmt | test.rs:262:13:262:13 | 1 | | +| test.rs:261:14:263:9 | BlockExpr | test.rs:262:13:262:13 | 1 | | +| test.rs:262:13:262:13 | 1 | test.rs:261:14:263:9 | BlockExpr | | +| test.rs:267:5:270:5 | enter test_let_match | test.rs:268:9:268:49 | LetStmt | | +| test.rs:267:5:270:5 | exit test_let_match (normal) | test.rs:267:5:270:5 | exit test_let_match | | +| test.rs:267:39:270:5 | BlockExpr | test.rs:267:5:270:5 | exit test_let_match (normal) | | +| test.rs:268:9:268:49 | LetStmt | test.rs:268:23:268:23 | a | | +| test.rs:268:13:268:19 | TupleStructPat | test.rs:268:32:268:46 | "Expected some" | no-match | +| test.rs:268:13:268:19 | TupleStructPat | test.rs:269:9:269:9 | n | match | +| test.rs:268:23:268:23 | a | test.rs:268:13:268:19 | TupleStructPat | | +| test.rs:268:32:268:46 | "Expected some" | test.rs:268:30:268:48 | BlockExpr | | +| test.rs:269:9:269:9 | n | test.rs:267:39:270:5 | BlockExpr | | +| test.rs:273:1:278:1 | enter dead_code | test.rs:274:5:276:5 | ExprStmt | | +| test.rs:273:1:278:1 | exit dead_code (normal) | test.rs:273:1:278:1 | exit dead_code | | +| test.rs:274:5:276:5 | ExprStmt | test.rs:274:9:274:12 | true | | +| test.rs:274:9:274:12 | true | test.rs:275:9:275:17 | ExprStmt | true | +| test.rs:275:9:275:16 | ReturnExpr | test.rs:273:1:278:1 | exit dead_code (normal) | return | +| test.rs:275:9:275:17 | ExprStmt | test.rs:275:16:275:16 | 0 | | +| test.rs:275:16:275:16 | 0 | test.rs:275:9:275:16 | ReturnExpr | | +| test.rs:280:1:293:1 | enter labelled_block1 | test.rs:281:5:292:6 | LetStmt | | +| test.rs:280:1:293:1 | exit labelled_block1 (normal) | test.rs:280:1:293:1 | exit labelled_block1 | | +| test.rs:280:29:293:1 | BlockExpr | test.rs:280:1:293:1 | exit labelled_block1 (normal) | | +| test.rs:281:5:292:6 | LetStmt | test.rs:282:9:282:19 | ExprStmt | | +| test.rs:281:9:281:14 | result | test.rs:280:29:293:1 | BlockExpr | match, no-match | +| test.rs:281:18:292:5 | BlockExpr | test.rs:281:9:281:14 | result | | +| test.rs:282:9:282:16 | PathExpr | test.rs:282:9:282:18 | CallExpr | | +| test.rs:282:9:282:18 | CallExpr | test.rs:283:9:285:9 | ExprStmt | | +| test.rs:282:9:282:19 | ExprStmt | test.rs:282:9:282:16 | PathExpr | | +| test.rs:283:9:285:9 | ExprStmt | test.rs:283:12:283:28 | PathExpr | | +| test.rs:283:9:285:9 | IfExpr | test.rs:286:9:286:24 | ExprStmt | | +| test.rs:283:12:283:28 | PathExpr | test.rs:283:12:283:30 | CallExpr | | +| test.rs:283:12:283:30 | CallExpr | test.rs:283:9:285:9 | IfExpr | false | +| test.rs:283:12:283:30 | CallExpr | test.rs:284:13:284:27 | ExprStmt | true | +| test.rs:284:13:284:26 | BreakExpr | test.rs:281:18:292:5 | BlockExpr | break('block) | +| test.rs:284:13:284:27 | ExprStmt | test.rs:284:26:284:26 | 1 | | +| test.rs:284:26:284:26 | 1 | test.rs:284:13:284:26 | BreakExpr | | +| test.rs:286:9:286:21 | PathExpr | test.rs:286:9:286:23 | CallExpr | | +| test.rs:286:9:286:23 | CallExpr | test.rs:287:9:289:9 | ExprStmt | | +| test.rs:286:9:286:24 | ExprStmt | test.rs:286:9:286:21 | PathExpr | | +| test.rs:287:9:289:9 | ExprStmt | test.rs:287:12:287:28 | PathExpr | | +| test.rs:287:9:289:9 | IfExpr | test.rs:290:9:290:24 | ExprStmt | | +| test.rs:287:12:287:28 | PathExpr | test.rs:287:12:287:30 | CallExpr | | +| test.rs:287:12:287:30 | CallExpr | test.rs:287:9:289:9 | IfExpr | false | +| test.rs:287:12:287:30 | CallExpr | test.rs:288:13:288:27 | ExprStmt | true | +| test.rs:288:13:288:26 | BreakExpr | test.rs:281:18:292:5 | BlockExpr | break('block) | +| test.rs:288:13:288:27 | ExprStmt | test.rs:288:26:288:26 | 2 | | +| test.rs:288:26:288:26 | 2 | test.rs:288:13:288:26 | BreakExpr | | +| test.rs:290:9:290:21 | PathExpr | test.rs:290:9:290:23 | CallExpr | | +| test.rs:290:9:290:23 | CallExpr | test.rs:291:9:291:9 | 3 | | +| test.rs:290:9:290:24 | ExprStmt | test.rs:290:9:290:21 | PathExpr | | +| test.rs:291:9:291:9 | 3 | test.rs:281:18:292:5 | BlockExpr | | +| test.rs:295:1:303:1 | enter labelled_block2 | test.rs:296:5:302:6 | LetStmt | | +| test.rs:295:1:303:1 | exit labelled_block2 (normal) | test.rs:295:1:303:1 | exit labelled_block2 | | +| test.rs:295:29:303:1 | BlockExpr | test.rs:295:1:303:1 | exit labelled_block2 (normal) | | +| test.rs:296:5:302:6 | LetStmt | test.rs:297:9:297:34 | LetStmt | | +| test.rs:296:9:296:14 | result | test.rs:295:29:303:1 | BlockExpr | match, no-match | +| test.rs:296:18:302:5 | BlockExpr | test.rs:296:9:296:14 | result | | +| test.rs:297:9:297:34 | LetStmt | test.rs:297:30:297:33 | PathExpr | | +| test.rs:297:13:297:13 | x | test.rs:298:9:300:10 | LetStmt | match, no-match | +| test.rs:297:30:297:33 | PathExpr | test.rs:297:13:297:13 | x | | +| test.rs:298:9:300:10 | LetStmt | test.rs:298:23:298:23 | x | | +| test.rs:298:13:298:19 | TupleStructPat | test.rs:299:13:299:27 | ExprStmt | no-match | +| test.rs:298:13:298:19 | TupleStructPat | test.rs:301:9:301:9 | x | match | +| test.rs:298:23:298:23 | x | test.rs:298:13:298:19 | TupleStructPat | | +| test.rs:299:13:299:26 | BreakExpr | test.rs:296:18:302:5 | BlockExpr | break('block) | +| test.rs:299:13:299:27 | ExprStmt | test.rs:299:26:299:26 | 1 | | +| test.rs:299:26:299:26 | 1 | test.rs:299:13:299:26 | BreakExpr | | +| test.rs:301:9:301:9 | x | test.rs:296:18:302:5 | BlockExpr | | diff --git a/rust/ql/test/library-tests/controlflow/test.rs b/rust/ql/test/library-tests/controlflow/test.rs index 22d8b9f24a60..4ad742b30444 100644 --- a/rust/ql/test/library-tests/controlflow/test.rs +++ b/rust/ql/test/library-tests/controlflow/test.rs @@ -51,6 +51,20 @@ mod loop_expression { } } + fn test_loop_label_shadowing(b: bool) -> ! { + 'loop: loop { + 1; + 'loop: loop { + if b { + continue; + } else if b { + continue 'loop; + } + continue 'loop; + } + } + } + fn test_while(i: i64) { let mut b = true; while b { From fb9ec2423cc1db4a9285afff76528c7042dd3ffd Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Oct 2024 09:54:09 +0200 Subject: [PATCH 119/347] Rust: Implement `UnusedVariable.ql` --- rust/ql/lib/codeql/rust/elements/Variable.qll | 4 + .../rust/elements/internal/VariableImpl.qll | 44 ++++ .../queries/unusedentities/UnusedVariable.ql | 11 +- .../variables/variables.expected | 106 +++++++++ .../test/library-tests/variables/variables.ql | 6 + .../unusedentities/UnusedVariable.expected | 4 + .../test/query-tests/unusedentities/main.rs | 204 +++++++++--------- 7 files changed, 273 insertions(+), 106 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/Variable.qll b/rust/ql/lib/codeql/rust/elements/Variable.qll index 76c2d9f19f72..31cc17a263f8 100644 --- a/rust/ql/lib/codeql/rust/elements/Variable.qll +++ b/rust/ql/lib/codeql/rust/elements/Variable.qll @@ -7,3 +7,7 @@ private import internal.VariableImpl final class Variable = Impl::Variable; final class VariableAccess = Impl::VariableAccess; + +final class VariableWriteAccess = Impl::VariableWriteAccess; + +final class VariableReadAccess = Impl::VariableReadAccess; diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index 58c9a4fb6ebf..0f7968079157 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -98,6 +98,27 @@ module Impl { /** Gets an access to this variable. */ VariableAccess getAnAccess() { result.getVariable() = this } + + /** + * Gets the pattern that declares this variable. + * + * Normally, the pattern is unique, except when introduced in an or pattern: + * + * ```rust + * match either { + * Either::Left(x) | Either::Right(x) => println!(x), + * } + * ``` + */ + IdentPat getPat() { variableDecl(definingNode, result, name) } + + /** Gets the initial value of this variable, if any. */ + Expr getInitializer() { + exists(LetStmt let | + this.getPat() = let.getPat() and + result = let.getInitializer() + ) + } } /** A path expression that may access a local variable. */ @@ -366,6 +387,29 @@ module Impl { override string getAPrimaryQlClass() { result = "VariableAccess" } } + /** Holds if `e` occurs in the LHS of a (compound) assignment. */ + private predicate assignLhs(Expr e) { + exists(BinaryExpr be | + be.getOperatorName().regexpMatch(".*=") and + e = be.getLhs() + ) + or + exists(Expr mid | + assignLhs(mid) and + getImmediateParent(e) = mid + ) + } + + /** A variable write. */ + class VariableWriteAccess extends VariableAccess { + VariableWriteAccess() { assignLhs(this) } + } + + /** A variable read. */ + class VariableReadAccess extends VariableAccess { + VariableReadAccess() { not this instanceof VariableWriteAccess } + } + cached private module Cached { cached diff --git a/rust/ql/src/queries/unusedentities/UnusedVariable.ql b/rust/ql/src/queries/unusedentities/UnusedVariable.ql index a057db7d1734..5fb0cdfecdc1 100644 --- a/rust/ql/src/queries/unusedentities/UnusedVariable.ql +++ b/rust/ql/src/queries/unusedentities/UnusedVariable.ql @@ -3,13 +3,16 @@ * @description Unused variables may be an indication that the code is incomplete or has a typo. * @kind problem * @problem.severity recommendation - * @precision medium + * @precision high * @id rust/unused-variable * @tags maintainability */ import rust -from Locatable e -where none() // TODO: implement query -select e, "Variable is not used." +from Variable v +where + not exists(v.getAnAccess()) and + not exists(v.getInitializer()) and + not v.getName().charAt(0) = "_" +select v, "Variable is not used." diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index ba563aeab6ef..c86e30d4bb57 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -146,3 +146,109 @@ variableAccess | variables.rs:306:15:306:16 | n2 | variables.rs:304:9:304:10 | n2 | | variables.rs:313:12:313:12 | v | variables.rs:310:9:310:9 | v | | variables.rs:314:19:314:22 | text | variables.rs:312:9:312:12 | text | +variableWriteAccess +| variables.rs:17:5:17:6 | x2 | variables.rs:15:13:15:14 | x2 | +| variables.rs:266:9:266:10 | c2 | variables.rs:259:13:259:14 | c2 | +| variables.rs:267:9:267:10 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:268:9:268:11 | a10 | variables.rs:257:13:257:15 | a10 | +variableReadAccess +| variables.rs:11:15:11:16 | x1 | variables.rs:10:9:10:10 | x1 | +| variables.rs:16:15:16:16 | x2 | variables.rs:15:13:15:14 | x2 | +| variables.rs:18:15:18:16 | x2 | variables.rs:15:13:15:14 | x2 | +| variables.rs:23:15:23:16 | x3 | variables.rs:22:9:22:10 | x3 | +| variables.rs:25:9:25:10 | x3 | variables.rs:22:9:22:10 | x3 | +| variables.rs:26:15:26:16 | x3 | variables.rs:24:9:24:10 | x3 | +| variables.rs:31:15:31:16 | x4 | variables.rs:30:9:30:10 | x4 | +| variables.rs:34:19:34:20 | x4 | variables.rs:33:13:33:14 | x4 | +| variables.rs:36:15:36:16 | x4 | variables.rs:30:9:30:10 | x4 | +| variables.rs:55:15:55:16 | a1 | variables.rs:47:13:47:14 | a1 | +| variables.rs:56:15:56:16 | b1 | variables.rs:48:13:48:14 | b1 | +| variables.rs:57:15:57:15 | x | variables.rs:51:13:51:13 | x | +| variables.rs:58:15:58:15 | y | variables.rs:52:13:52:13 | y | +| variables.rs:66:9:66:10 | p1 | variables.rs:62:9:62:10 | p1 | +| variables.rs:67:15:67:16 | a2 | variables.rs:64:12:64:13 | a2 | +| variables.rs:68:15:68:16 | b2 | variables.rs:65:12:65:13 | b2 | +| variables.rs:75:11:75:12 | s1 | variables.rs:72:9:72:10 | s1 | +| variables.rs:76:19:76:20 | s2 | variables.rs:74:21:74:22 | s2 | +| variables.rs:85:15:85:16 | x5 | variables.rs:81:14:81:15 | x5 | +| variables.rs:92:11:92:12 | x6 | variables.rs:89:9:89:10 | x6 | +| variables.rs:97:23:97:24 | y1 | variables.rs:94:14:94:15 | y1 | +| variables.rs:102:15:102:16 | y1 | variables.rs:90:9:90:10 | y1 | +| variables.rs:108:11:108:17 | numbers | variables.rs:106:9:106:15 | numbers | +| variables.rs:114:23:114:27 | first | variables.rs:110:13:110:17 | first | +| variables.rs:115:23:115:27 | third | variables.rs:111:13:111:17 | third | +| variables.rs:116:23:116:27 | fifth | variables.rs:112:13:112:17 | fifth | +| variables.rs:120:11:120:17 | numbers | variables.rs:106:9:106:15 | numbers | +| variables.rs:126:23:126:27 | first | variables.rs:122:13:122:17 | first | +| variables.rs:127:23:127:26 | last | variables.rs:124:13:124:16 | last | +| variables.rs:135:11:135:12 | p2 | variables.rs:133:9:133:10 | p2 | +| variables.rs:138:24:138:25 | x7 | variables.rs:137:16:137:17 | x7 | +| variables.rs:149:11:149:13 | msg | variables.rs:147:9:147:11 | msg | +| variables.rs:152:24:152:34 | id_variable | variables.rs:151:17:151:27 | id_variable | +| variables.rs:157:23:157:24 | id | variables.rs:156:26:156:27 | id | +| variables.rs:168:11:168:16 | either | variables.rs:167:9:167:14 | either | +| variables.rs:170:26:170:27 | a3 | variables.rs:169:9:169:44 | a3 | +| variables.rs:182:11:182:12 | tv | variables.rs:181:9:181:10 | tv | +| variables.rs:184:26:184:27 | a4 | variables.rs:183:9:183:81 | a4 | +| variables.rs:186:11:186:12 | tv | variables.rs:181:9:181:10 | tv | +| variables.rs:188:26:188:27 | a5 | variables.rs:187:9:187:83 | a5 | +| variables.rs:190:11:190:12 | tv | variables.rs:181:9:181:10 | tv | +| variables.rs:192:26:192:27 | a6 | variables.rs:191:9:191:83 | a6 | +| variables.rs:198:11:198:16 | either | variables.rs:197:9:197:14 | either | +| variables.rs:200:16:200:17 | a7 | variables.rs:199:9:199:44 | a7 | +| variables.rs:201:26:201:27 | a7 | variables.rs:199:9:199:44 | a7 | +| variables.rs:209:11:209:16 | either | variables.rs:207:9:207:14 | either | +| variables.rs:213:23:213:25 | a11 | variables.rs:211:14:211:51 | a11 | +| variables.rs:215:15:215:15 | e | variables.rs:210:13:210:13 | e | +| variables.rs:216:28:216:30 | a12 | variables.rs:214:33:214:35 | a12 | +| variables.rs:232:11:232:12 | fv | variables.rs:231:9:231:10 | fv | +| variables.rs:234:26:234:28 | a13 | variables.rs:233:9:233:109 | a13 | +| variables.rs:244:15:244:16 | a8 | variables.rs:239:5:239:6 | a8 | +| variables.rs:245:15:245:16 | b3 | variables.rs:241:9:241:10 | b3 | +| variables.rs:246:15:246:16 | c1 | variables.rs:242:9:242:10 | c1 | +| variables.rs:252:15:252:16 | a9 | variables.rs:250:6:250:41 | a9 | +| variables.rs:261:15:261:17 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:262:15:262:16 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:263:15:263:16 | c2 | variables.rs:259:13:259:14 | c2 | +| variables.rs:270:9:270:11 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:271:9:271:10 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:272:9:272:10 | c2 | variables.rs:259:13:259:14 | c2 | +| variables.rs:274:15:274:17 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:275:15:275:16 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:276:15:276:16 | c2 | variables.rs:259:13:259:14 | c2 | +| variables.rs:283:23:283:25 | a10 | variables.rs:280:13:280:15 | a10 | +| variables.rs:284:23:284:24 | b4 | variables.rs:281:13:281:14 | b4 | +| variables.rs:288:15:288:17 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:289:15:289:16 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:295:9:295:9 | x | variables.rs:294:10:294:10 | x | +| variables.rs:297:9:297:23 | example_closure | variables.rs:293:9:293:23 | example_closure | +| variables.rs:298:15:298:16 | n1 | variables.rs:296:9:296:10 | n1 | +| variables.rs:303:9:303:9 | x | variables.rs:302:10:302:10 | x | +| variables.rs:305:9:305:26 | immutable_variable | variables.rs:301:9:301:26 | immutable_variable | +| variables.rs:306:15:306:16 | n2 | variables.rs:304:9:304:10 | n2 | +| variables.rs:313:12:313:12 | v | variables.rs:310:9:310:9 | v | +| variables.rs:314:19:314:22 | text | variables.rs:312:9:312:12 | text | +variableInitializer +| variables.rs:10:9:10:10 | x1 | variables.rs:10:14:10:16 | "a" | +| variables.rs:15:13:15:14 | x2 | variables.rs:15:18:15:18 | 4 | +| variables.rs:22:9:22:10 | x3 | variables.rs:22:14:22:14 | 1 | +| variables.rs:24:9:24:10 | x3 | variables.rs:25:9:25:14 | ... + ... | +| variables.rs:30:9:30:10 | x4 | variables.rs:30:14:30:16 | "a" | +| variables.rs:33:13:33:14 | x4 | variables.rs:33:18:33:20 | "b" | +| variables.rs:62:9:62:10 | p1 | variables.rs:62:14:62:37 | RecordExpr | +| variables.rs:72:9:72:10 | s1 | variables.rs:72:14:72:41 | CallExpr | +| variables.rs:89:9:89:10 | x6 | variables.rs:89:14:89:20 | CallExpr | +| variables.rs:90:9:90:10 | y1 | variables.rs:90:14:90:15 | 10 | +| variables.rs:106:9:106:15 | numbers | variables.rs:106:19:106:35 | TupleExpr | +| variables.rs:133:9:133:10 | p2 | variables.rs:133:14:133:37 | RecordExpr | +| variables.rs:147:9:147:11 | msg | variables.rs:147:15:147:38 | RecordExpr | +| variables.rs:167:9:167:14 | either | variables.rs:167:18:167:33 | CallExpr | +| variables.rs:181:9:181:10 | tv | variables.rs:181:14:181:36 | CallExpr | +| variables.rs:197:9:197:14 | either | variables.rs:197:18:197:33 | CallExpr | +| variables.rs:207:9:207:14 | either | variables.rs:207:18:207:33 | CallExpr | +| variables.rs:231:9:231:10 | fv | variables.rs:231:14:231:35 | CallExpr | +| variables.rs:293:9:293:23 | example_closure | variables.rs:294:9:295:9 | ClosureExpr | +| variables.rs:296:9:296:10 | n1 | variables.rs:297:9:297:26 | CallExpr | +| variables.rs:301:9:301:26 | immutable_variable | variables.rs:302:9:303:9 | ClosureExpr | +| variables.rs:304:9:304:10 | n2 | variables.rs:305:9:305:29 | CallExpr | +| variables.rs:310:9:310:9 | v | variables.rs:310:13:310:41 | RefExpr | diff --git a/rust/ql/test/library-tests/variables/variables.ql b/rust/ql/test/library-tests/variables/variables.ql index b96f6ceabcae..dcca73d5cf28 100644 --- a/rust/ql/test/library-tests/variables/variables.ql +++ b/rust/ql/test/library-tests/variables/variables.ql @@ -5,6 +5,12 @@ query predicate variable(Variable v) { any() } query predicate variableAccess(VariableAccess va, Variable v) { v = va.getVariable() } +query predicate variableWriteAccess(VariableWriteAccess va, Variable v) { v = va.getVariable() } + +query predicate variableReadAccess(VariableReadAccess va, Variable v) { v = va.getVariable() } + +query predicate variableInitializer(Variable v, Expr e) { e = v.getInitializer() } + module VariableAccessTest implements TestSig { string getARelevantTag() { result = "access" } diff --git a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected index e69de29bb2d1..f3aadfdff0d8 100644 --- a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected +++ b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected @@ -0,0 +1,4 @@ +| main.rs:23:9:23:9 | a | Variable is not used. | +| main.rs:88:13:88:13 | d | Variable is not used. | +| main.rs:112:9:112:9 | k | Variable is not used. | +| main.rs:139:5:139:5 | y | Variable is not used. | diff --git a/rust/ql/test/query-tests/unusedentities/main.rs b/rust/ql/test/query-tests/unusedentities/main.rs index 8066f7c783e0..c58693ed8667 100644 --- a/rust/ql/test/query-tests/unusedentities/main.rs +++ b/rust/ql/test/query-tests/unusedentities/main.rs @@ -1,118 +1,119 @@ - //fn cond() -> bool; // --- locals --- fn locals_1() { - let a = 1; // BAD: unused value [NOT DETECTED] - let b = 1; - let c = 1; - let d = String::from("a"); // BAD: unused value [NOT DETECTED] - let e = String::from("b"); - let _ = 1; // (deliberately unused) + let a = 1; // BAD: unused value [NOT DETECTED] + let b = 1; + let c = 1; + let d = String::from("a"); // BAD: unused value [NOT DETECTED] + let e = String::from("b"); + let _ = 1; // (deliberately unused) - println!("use {}", b); + println!("use {}", b); - if cond() { - println!("use {}", c); - } + if cond() { + println!("use {}", c); + } - println!("use {}", e); + println!("use {}", e); } fn locals_2() { - let a: i32; - let b: i32; // BAD: unused variable [NOT DETECTED] - let mut c: i32; - let mut d: i32; - let mut e: i32; - let mut f: i32; - let g: i32; - let h: i32; - let i: i32; - - b = 1; // BAD: unused value [NOT DETECTED] - - c = 1; // BAD: unused value [NOT DETECTED] - c = 2; - println!("use {}", c); - c = 3; // BAD: unused value [NOT DETECTED] - - d = 1; - if cond() { - d = 2; // BAD: unused value [NOT DETECTED] - d = 3; - } else { - } - println!("use {}", d); - - e = 1; // BAD: unused value [NOT DETECTED] - if cond() { - e = 2; - } else { - e = 3; - } - println!("use {}", e); - - f = 1; - f += 1; - println!("use {}", f); - f += 1; // BAD: unused value [NOT DETECTED] - f = 1; - f += 1; // BAD: unused value [NOT DETECTED] - - g = if cond() { 1 } else { 2 }; // BAD: unused value (x2) [NOT DETECTED] - h = if cond() { 3 } else { 4 }; - i = if cond() { h } else { 5 }; - println!("use {}", i); - - _ = 1; // (deliberately unused) [NOT DETECTED] + let a: i32; // BAD: unused variable + let b: i32; + let mut c: i32; + let mut d: i32; + let mut e: i32; + let mut f: i32; + let g: i32; + let h: i32; + let i: i32; + + b = 1; // BAD: unused value [NOT DETECTED] + + c = 1; // BAD: unused value [NOT DETECTED] + c = 2; + println!("use {}", c); + c = 3; // BAD: unused value [NOT DETECTED] + + d = 1; + if cond() { + d = 2; // BAD: unused value [NOT DETECTED] + d = 3; + } else { + } + println!("use {}", d); + + e = 1; // BAD: unused value [NOT DETECTED] + if cond() { + e = 2; + } else { + e = 3; + } + println!("use {}", e); + + f = 1; + f += 1; + println!("use {}", f); + f += 1; // BAD: unused value [NOT DETECTED] + f = 1; + f += 1; // BAD: unused value [NOT DETECTED] + + g = if cond() { 1 } else { 2 }; // BAD: unused value (x2) [NOT DETECTED] + h = if cond() { 3 } else { 4 }; + i = if cond() { h } else { 5 }; + println!("use {}", i); + + _ = 1; // (deliberately unused) [NOT DETECTED] } // --- structs --- #[derive(Debug)] struct MyStruct { - val: i64 + val: i64, } impl MyStruct { - fn my_get(&mut self) -> i64 { - return self.val; - } + fn my_get(&mut self) -> i64 { + return self.val; + } } fn structs() { - let a = MyStruct {val : 1 }; // BAD: unused value [NOT DETECTED] - let b = MyStruct {val : 2 }; - let c = MyStruct {val : 3 }; - let mut d : MyStruct; // BAD: unused variable [NOT DETECTED] - let mut e : MyStruct; - let mut f : MyStruct; - - println!("lets use {:?} and {}", b, c.val); - - e = MyStruct {val : 4 }; - println!("lets use {}", e.my_get()); - e.val = 5; - println!("lets use {}", e.my_get()); - - f = MyStruct {val : 6 }; // BAD: unused value [NOT DETECTED] - f.val = 7; // BAD: unused value [NOT DETECTED] + let a = MyStruct { val: 1 }; // BAD: unused value [NOT DETECTED] + let b = MyStruct { val: 2 }; + let c = MyStruct { val: 3 }; + let mut d: MyStruct; // BAD: unused variable + let mut e: MyStruct; + let mut f: MyStruct; + + println!("lets use {:?} and {}", b, c.val); + + e = MyStruct { val: 4 }; + println!("lets use {}", e.my_get()); + e.val = 5; + println!("lets use {}", e.my_get()); + + f = MyStruct { val: 6 }; // BAD: unused value [NOT DETECTED] + f.val = 7; // BAD: unused value [NOT DETECTED] } // --- arrays --- fn arrays() { - let is = [1, 2, 3]; // BAD: unused values (x3) [NOT DETECTED] - let js = [1, 2, 3]; - let ks = [1, 2, 3]; + let is = [1, 2, 3]; // BAD: unused values (x3) [NOT DETECTED] + let js = [1, 2, 3]; + let ks = [1, 2, 3]; - println!("lets use {:?}", js); + println!("lets use {:?}", js); - for k in ks { - println!("lets use {}", k); - } + for k // BAD: unused variable [SPURIOUS: macros not yet supported] + in ks + { + println!("lets use {}", k); + } } // --- constants and statics --- @@ -123,30 +124,29 @@ static mut STAT1: i32 = 1; static mut STAT2: i32 = 2; // BAD: unused value [NOT DETECTED] fn statics() { - static mut STAT3: i32 = 0; - static mut STAT4: i32 = 0; // BAD: unused value [NOT DETECTED] + static mut STAT3: i32 = 0; + static mut STAT4: i32 = 0; // BAD: unused value [NOT DETECTED] - unsafe - { - let total = CON1 + STAT1 + STAT3; - } + unsafe { + let total = CON1 + STAT1 + STAT3; + } } // --- parameters --- fn parameters( - x: i32, - y: i32, // BAD: unused variable [NOT DETECTED] - _z: i32 // (`_` is asking the compiler, and by extension us, to not warn that this is unused) - ) -> i32 { - return x; + x: i32, + y: i32, // BAD: unused variable + _z: i32, // (`_` is asking the compiler, and by extension us, to not warn that this is unused) +) -> i32 { + return x; } fn main() { - locals_1(); - locals_2(); - structs(); - arrays(); - statics(); - println!("lets use result {}", parameters(1, 2, 3)); + locals_1(); + locals_2(); + structs(); + arrays(); + statics(); + println!("lets use result {}", parameters(1, 2, 3)); } From 8243f871791ba47aee375d97bd3aacf5c20786b4 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 2 Oct 2024 11:38:23 +0100 Subject: [PATCH 120/347] Rust: Modify the exclusion as suggested in comments. --- rust/ql/lib/codeql/files/FileSystem.qll | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rust/ql/lib/codeql/files/FileSystem.qll b/rust/ql/lib/codeql/files/FileSystem.qll index a5410ece9712..03b5cd0b183b 100644 --- a/rust/ql/lib/codeql/files/FileSystem.qll +++ b/rust/ql/lib/codeql/files/FileSystem.qll @@ -5,7 +5,6 @@ private import codeql.util.FileSystem private import codeql.rust.elements.SourceFile private import codeql.rust.elements.AstNode private import codeql.rust.elements.Comment -private import codeql.rust.elements.internal.generated.ParentChild private module Input implements InputSig { abstract class ContainerBase extends @container { @@ -48,7 +47,7 @@ class File extends Container, Impl::File { exists(AstNode node, Location loc | not node instanceof Comment and not node instanceof SourceFile and - not getImmediateParent(node) instanceof SourceFile and // ignore top-level elements for now as we're getting their locations wrong when a comment is attached + not node instanceof Item and // ignore Items for now as we're getting their locations wrong when a comment is attached loc = node.getLocation() | node.getFile() = this and From 3a1f6efce413cb8f841ae26a919c32dd6b87a152 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Oct 2024 13:37:24 +0200 Subject: [PATCH 121/347] Address review comments --- .../rust/elements/internal/VariableImpl.qll | 23 +++++++++++++------ .../test/query-tests/unusedentities/main.rs | 2 +- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index 0f7968079157..3f0cabc97b85 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -387,27 +387,36 @@ module Impl { override string getAPrimaryQlClass() { result = "VariableAccess" } } - /** Holds if `e` occurs in the LHS of a (compound) assignment. */ - private predicate assignLhs(Expr e) { - exists(BinaryExpr be | - be.getOperatorName().regexpMatch(".*=") and + /** Holds if `e` occurs in the LHS of an assignment or compound assignment. */ + private predicate assignLhs(Expr e, boolean compound) { + exists(BinaryExpr be, string op | + op = be.getOperatorName().regexpCapture("(.*)=", 1) and e = be.getLhs() + | + op = "" and compound = false + or + op != "" and compound = true ) or exists(Expr mid | - assignLhs(mid) and + assignLhs(mid, compound) and getImmediateParent(e) = mid ) } /** A variable write. */ class VariableWriteAccess extends VariableAccess { - VariableWriteAccess() { assignLhs(this) } + VariableWriteAccess() { assignLhs(this, _) } } /** A variable read. */ class VariableReadAccess extends VariableAccess { - VariableReadAccess() { not this instanceof VariableWriteAccess } + VariableReadAccess() { + not this instanceof VariableWriteAccess + or + // consider LHS in compound assignments both reads and writes + assignLhs(this, true) + } } cached diff --git a/rust/ql/test/query-tests/unusedentities/main.rs b/rust/ql/test/query-tests/unusedentities/main.rs index c58693ed8667..7280f6c2502b 100644 --- a/rust/ql/test/query-tests/unusedentities/main.rs +++ b/rust/ql/test/query-tests/unusedentities/main.rs @@ -109,7 +109,7 @@ fn arrays() { println!("lets use {:?}", js); - for k // BAD: unused variable [SPURIOUS: macros not yet supported] + for k // SPURIOUS: unused variable [macros not yet supported] in ks { println!("lets use {}", k); From 104d448b166d7644cf62b262b9ba3425ad6da57b Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 2 Oct 2024 14:39:27 +0200 Subject: [PATCH 122/347] Shared: Only use heuristic summary flow in case there is no content based flow. --- .../codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll index f56c1b8dfff0..8d4bb4cae5a0 100644 --- a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll +++ b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll @@ -881,7 +881,7 @@ module MakeModelGenerator< string captureMixedFlow(DataFlowSummaryTargetApi api, boolean lift) { result = ContentSensitive::captureFlow(api, lift) or - not exists(ContentSensitive::captureFlow(api, lift)) and + not exists(ContentSensitive::captureFlow(api, _)) and result = captureFlow(api) and lift = true } From 51623c3837091d55026f6c48440cb0f1b3a1040b Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 2 Oct 2024 11:05:20 +0200 Subject: [PATCH 123/347] Java: Consider all summarized callable with generated verification as generated when counting generated vs manual. --- .../src/Metrics/Summaries/GeneratedVsManualCoverageQuery.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Metrics/Summaries/GeneratedVsManualCoverageQuery.qll b/java/ql/src/Metrics/Summaries/GeneratedVsManualCoverageQuery.qll index 9a2a0201e803..8309126c06de 100644 --- a/java/ql/src/Metrics/Summaries/GeneratedVsManualCoverageQuery.qll +++ b/java/ql/src/Metrics/Summaries/GeneratedVsManualCoverageQuery.qll @@ -17,12 +17,12 @@ private int getNumMadModeledApis(string package, string provenance, string apiSu ( // "auto-only" not sc.hasManualModel() and - sc.hasProvenance("df-generated") and + sc.hasGeneratedModel() and provenance = "generated" or sc.hasManualModel() and ( - if sc.hasProvenance("df-generated") + if sc.hasGeneratedModel() then // "both" provenance = "both" From 000dedf3e851c4162d5551c8d48c2cec92df17f8 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 30 Sep 2024 09:48:59 +0200 Subject: [PATCH 124/347] Rust: Output CFG for `library-tests/variables` --- .../test/library-tests/controlflow/Cfg.qlref | 1 + .../test/library-tests/variables/Cfg.expected | 594 ++++++++++++++++++ .../ql/test/library-tests/variables/Cfg.qlref | 1 + rust/ql/test/utils/Cfg.expected | 3 + .../controlflow => utils}/Cfg.ql | 0 5 files changed, 599 insertions(+) create mode 100644 rust/ql/test/library-tests/controlflow/Cfg.qlref create mode 100644 rust/ql/test/library-tests/variables/Cfg.expected create mode 100644 rust/ql/test/library-tests/variables/Cfg.qlref create mode 100644 rust/ql/test/utils/Cfg.expected rename rust/ql/test/{library-tests/controlflow => utils}/Cfg.ql (100%) diff --git a/rust/ql/test/library-tests/controlflow/Cfg.qlref b/rust/ql/test/library-tests/controlflow/Cfg.qlref new file mode 100644 index 000000000000..ba4ee4b414f1 --- /dev/null +++ b/rust/ql/test/library-tests/controlflow/Cfg.qlref @@ -0,0 +1 @@ +query: utils/Cfg.ql \ No newline at end of file diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected new file mode 100644 index 000000000000..876e5fb52664 --- /dev/null +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -0,0 +1,594 @@ +| variables.rs:1:1:3:1 | enter print_str | variables.rs:2:5:2:22 | ExprStmt | | +| variables.rs:1:1:3:1 | exit print_str (normal) | variables.rs:1:1:3:1 | exit print_str | | +| variables.rs:1:23:3:1 | BlockExpr | variables.rs:1:1:3:1 | exit print_str (normal) | | +| variables.rs:2:5:2:21 | MacroExpr | variables.rs:1:23:3:1 | BlockExpr | | +| variables.rs:2:5:2:22 | ExprStmt | variables.rs:2:5:2:21 | MacroExpr | | +| variables.rs:5:1:7:1 | enter print_i64 | variables.rs:6:5:6:22 | ExprStmt | | +| variables.rs:5:1:7:1 | exit print_i64 (normal) | variables.rs:5:1:7:1 | exit print_i64 | | +| variables.rs:5:22:7:1 | BlockExpr | variables.rs:5:1:7:1 | exit print_i64 (normal) | | +| variables.rs:6:5:6:21 | MacroExpr | variables.rs:5:22:7:1 | BlockExpr | | +| variables.rs:6:5:6:22 | ExprStmt | variables.rs:6:5:6:21 | MacroExpr | | +| variables.rs:9:1:12:1 | enter immutable_variable | variables.rs:10:5:10:17 | LetStmt | | +| variables.rs:9:1:12:1 | exit immutable_variable (normal) | variables.rs:9:1:12:1 | exit immutable_variable | | +| variables.rs:9:25:12:1 | BlockExpr | variables.rs:9:1:12:1 | exit immutable_variable (normal) | | +| variables.rs:10:5:10:17 | LetStmt | variables.rs:10:14:10:16 | "a" | | +| variables.rs:10:9:10:10 | x1 | variables.rs:11:5:11:18 | ExprStmt | match, no-match | +| variables.rs:10:14:10:16 | "a" | variables.rs:10:9:10:10 | x1 | | +| variables.rs:11:5:11:13 | PathExpr | variables.rs:11:15:11:16 | x1 | | +| variables.rs:11:5:11:17 | CallExpr | variables.rs:9:25:12:1 | BlockExpr | | +| variables.rs:11:5:11:18 | ExprStmt | variables.rs:11:5:11:13 | PathExpr | | +| variables.rs:11:15:11:16 | x1 | variables.rs:11:5:11:17 | CallExpr | | +| variables.rs:14:1:19:1 | enter mutable_variable | variables.rs:15:5:15:19 | LetStmt | | +| variables.rs:14:1:19:1 | exit mutable_variable (normal) | variables.rs:14:1:19:1 | exit mutable_variable | | +| variables.rs:14:23:19:1 | BlockExpr | variables.rs:14:1:19:1 | exit mutable_variable (normal) | | +| variables.rs:15:5:15:19 | LetStmt | variables.rs:15:18:15:18 | 4 | | +| variables.rs:15:9:15:14 | x2 | variables.rs:16:5:16:18 | ExprStmt | match, no-match | +| variables.rs:15:18:15:18 | 4 | variables.rs:15:9:15:14 | x2 | | +| variables.rs:16:5:16:13 | PathExpr | variables.rs:16:15:16:16 | x2 | | +| variables.rs:16:5:16:17 | CallExpr | variables.rs:17:5:17:11 | ExprStmt | | +| variables.rs:16:5:16:18 | ExprStmt | variables.rs:16:5:16:13 | PathExpr | | +| variables.rs:16:15:16:16 | x2 | variables.rs:16:5:16:17 | CallExpr | | +| variables.rs:17:5:17:6 | x2 | variables.rs:17:10:17:10 | 5 | | +| variables.rs:17:5:17:10 | ... = ... | variables.rs:18:5:18:18 | ExprStmt | | +| variables.rs:17:5:17:11 | ExprStmt | variables.rs:17:5:17:6 | x2 | | +| variables.rs:17:10:17:10 | 5 | variables.rs:17:5:17:10 | ... = ... | | +| variables.rs:18:5:18:13 | PathExpr | variables.rs:18:15:18:16 | x2 | | +| variables.rs:18:5:18:17 | CallExpr | variables.rs:14:23:19:1 | BlockExpr | | +| variables.rs:18:5:18:18 | ExprStmt | variables.rs:18:5:18:13 | PathExpr | | +| variables.rs:18:15:18:16 | x2 | variables.rs:18:5:18:17 | CallExpr | | +| variables.rs:21:1:27:1 | enter variable_shadow1 | variables.rs:22:5:22:15 | LetStmt | | +| variables.rs:21:1:27:1 | exit variable_shadow1 (normal) | variables.rs:21:1:27:1 | exit variable_shadow1 | | +| variables.rs:21:23:27:1 | BlockExpr | variables.rs:21:1:27:1 | exit variable_shadow1 (normal) | | +| variables.rs:22:5:22:15 | LetStmt | variables.rs:22:14:22:14 | 1 | | +| variables.rs:22:9:22:10 | x3 | variables.rs:23:5:23:18 | ExprStmt | match, no-match | +| variables.rs:22:14:22:14 | 1 | variables.rs:22:9:22:10 | x3 | | +| variables.rs:23:5:23:13 | PathExpr | variables.rs:23:15:23:16 | x3 | | +| variables.rs:23:5:23:17 | CallExpr | variables.rs:24:5:25:15 | LetStmt | | +| variables.rs:23:5:23:18 | ExprStmt | variables.rs:23:5:23:13 | PathExpr | | +| variables.rs:23:15:23:16 | x3 | variables.rs:23:5:23:17 | CallExpr | | +| variables.rs:24:5:25:15 | LetStmt | variables.rs:25:9:25:10 | x3 | | +| variables.rs:24:9:24:10 | x3 | variables.rs:26:5:26:18 | ExprStmt | match, no-match | +| variables.rs:25:9:25:10 | x3 | variables.rs:25:14:25:14 | 1 | | +| variables.rs:25:9:25:14 | ... + ... | variables.rs:24:9:24:10 | x3 | | +| variables.rs:25:14:25:14 | 1 | variables.rs:25:9:25:14 | ... + ... | | +| variables.rs:26:5:26:13 | PathExpr | variables.rs:26:15:26:16 | x3 | | +| variables.rs:26:5:26:17 | CallExpr | variables.rs:21:23:27:1 | BlockExpr | | +| variables.rs:26:5:26:18 | ExprStmt | variables.rs:26:5:26:13 | PathExpr | | +| variables.rs:26:15:26:16 | x3 | variables.rs:26:5:26:17 | CallExpr | | +| variables.rs:29:1:37:1 | enter variable_shadow2 | variables.rs:30:5:30:17 | LetStmt | | +| variables.rs:29:1:37:1 | exit variable_shadow2 (normal) | variables.rs:29:1:37:1 | exit variable_shadow2 | | +| variables.rs:29:23:37:1 | BlockExpr | variables.rs:29:1:37:1 | exit variable_shadow2 (normal) | | +| variables.rs:30:5:30:17 | LetStmt | variables.rs:30:14:30:16 | "a" | | +| variables.rs:30:9:30:10 | x4 | variables.rs:31:5:31:18 | ExprStmt | match, no-match | +| variables.rs:30:14:30:16 | "a" | variables.rs:30:9:30:10 | x4 | | +| variables.rs:31:5:31:13 | PathExpr | variables.rs:31:15:31:16 | x4 | | +| variables.rs:31:5:31:17 | CallExpr | variables.rs:32:5:35:5 | ExprStmt | | +| variables.rs:31:5:31:18 | ExprStmt | variables.rs:31:5:31:13 | PathExpr | | +| variables.rs:31:15:31:16 | x4 | variables.rs:31:5:31:17 | CallExpr | | +| variables.rs:32:5:35:5 | BlockExpr | variables.rs:36:5:36:18 | ExprStmt | | +| variables.rs:32:5:35:5 | ExprStmt | variables.rs:33:9:33:21 | LetStmt | | +| variables.rs:33:9:33:21 | LetStmt | variables.rs:33:18:33:20 | "b" | | +| variables.rs:33:13:33:14 | x4 | variables.rs:34:9:34:22 | ExprStmt | match, no-match | +| variables.rs:33:18:33:20 | "b" | variables.rs:33:13:33:14 | x4 | | +| variables.rs:34:9:34:17 | PathExpr | variables.rs:34:19:34:20 | x4 | | +| variables.rs:34:9:34:21 | CallExpr | variables.rs:32:5:35:5 | BlockExpr | | +| variables.rs:34:9:34:22 | ExprStmt | variables.rs:34:9:34:17 | PathExpr | | +| variables.rs:34:19:34:20 | x4 | variables.rs:34:9:34:21 | CallExpr | | +| variables.rs:36:5:36:13 | PathExpr | variables.rs:36:15:36:16 | x4 | | +| variables.rs:36:5:36:17 | CallExpr | variables.rs:29:23:37:1 | BlockExpr | | +| variables.rs:36:5:36:18 | ExprStmt | variables.rs:36:5:36:13 | PathExpr | | +| variables.rs:36:15:36:16 | x4 | variables.rs:36:5:36:17 | CallExpr | | +| variables.rs:44:1:59:1 | enter let_pattern1 | variables.rs:45:5:54:47 | LetStmt | | +| variables.rs:44:1:59:1 | exit let_pattern1 (normal) | variables.rs:44:1:59:1 | exit let_pattern1 | | +| variables.rs:44:19:59:1 | BlockExpr | variables.rs:44:1:59:1 | exit let_pattern1 (normal) | | +| variables.rs:45:5:54:47 | LetStmt | variables.rs:54:11:54:13 | "a" | | +| variables.rs:45:9:54:5 | TuplePat | variables.rs:55:5:55:18 | ExprStmt | match | +| variables.rs:54:9:54:46 | TupleExpr | variables.rs:45:9:54:5 | TuplePat | | +| variables.rs:54:10:54:19 | TupleExpr | variables.rs:54:33:54:35 | "x" | | +| variables.rs:54:11:54:13 | "a" | variables.rs:54:16:54:18 | "b" | | +| variables.rs:54:16:54:18 | "b" | variables.rs:54:10:54:19 | TupleExpr | | +| variables.rs:54:22:54:45 | RecordExpr | variables.rs:54:9:54:46 | TupleExpr | | +| variables.rs:54:33:54:35 | "x" | variables.rs:54:41:54:43 | "y" | | +| variables.rs:54:41:54:43 | "y" | variables.rs:54:22:54:45 | RecordExpr | | +| variables.rs:55:5:55:13 | PathExpr | variables.rs:55:15:55:16 | a1 | | +| variables.rs:55:5:55:17 | CallExpr | variables.rs:56:5:56:18 | ExprStmt | | +| variables.rs:55:5:55:18 | ExprStmt | variables.rs:55:5:55:13 | PathExpr | | +| variables.rs:55:15:55:16 | a1 | variables.rs:55:5:55:17 | CallExpr | | +| variables.rs:56:5:56:13 | PathExpr | variables.rs:56:15:56:16 | b1 | | +| variables.rs:56:5:56:17 | CallExpr | variables.rs:57:5:57:17 | ExprStmt | | +| variables.rs:56:5:56:18 | ExprStmt | variables.rs:56:5:56:13 | PathExpr | | +| variables.rs:56:15:56:16 | b1 | variables.rs:56:5:56:17 | CallExpr | | +| variables.rs:57:5:57:13 | PathExpr | variables.rs:57:15:57:15 | x | | +| variables.rs:57:5:57:16 | CallExpr | variables.rs:58:5:58:17 | ExprStmt | | +| variables.rs:57:5:57:17 | ExprStmt | variables.rs:57:5:57:13 | PathExpr | | +| variables.rs:57:15:57:15 | x | variables.rs:57:5:57:16 | CallExpr | | +| variables.rs:58:5:58:13 | PathExpr | variables.rs:58:15:58:15 | y | | +| variables.rs:58:5:58:16 | CallExpr | variables.rs:44:19:59:1 | BlockExpr | | +| variables.rs:58:5:58:17 | ExprStmt | variables.rs:58:5:58:13 | PathExpr | | +| variables.rs:58:15:58:15 | y | variables.rs:58:5:58:16 | CallExpr | | +| variables.rs:61:1:69:1 | enter let_pattern2 | variables.rs:62:5:62:38 | LetStmt | | +| variables.rs:61:1:69:1 | exit let_pattern2 (normal) | variables.rs:61:1:69:1 | exit let_pattern2 | | +| variables.rs:61:19:69:1 | BlockExpr | variables.rs:61:1:69:1 | exit let_pattern2 (normal) | | +| variables.rs:62:5:62:38 | LetStmt | variables.rs:62:25:62:27 | "a" | | +| variables.rs:62:9:62:10 | p1 | variables.rs:63:5:66:11 | LetStmt | match, no-match | +| variables.rs:62:14:62:37 | RecordExpr | variables.rs:62:9:62:10 | p1 | | +| variables.rs:62:25:62:27 | "a" | variables.rs:62:33:62:35 | "b" | | +| variables.rs:62:33:62:35 | "b" | variables.rs:62:14:62:37 | RecordExpr | | +| variables.rs:63:5:66:11 | LetStmt | variables.rs:66:9:66:10 | p1 | | +| variables.rs:63:9:66:5 | RecordPat | variables.rs:67:5:67:18 | ExprStmt | match | +| variables.rs:66:9:66:10 | p1 | variables.rs:63:9:66:5 | RecordPat | | +| variables.rs:67:5:67:13 | PathExpr | variables.rs:67:15:67:16 | a2 | | +| variables.rs:67:5:67:17 | CallExpr | variables.rs:68:5:68:18 | ExprStmt | | +| variables.rs:67:5:67:18 | ExprStmt | variables.rs:67:5:67:13 | PathExpr | | +| variables.rs:67:15:67:16 | a2 | variables.rs:67:5:67:17 | CallExpr | | +| variables.rs:68:5:68:13 | PathExpr | variables.rs:68:15:68:16 | b2 | | +| variables.rs:68:5:68:17 | CallExpr | variables.rs:61:19:69:1 | BlockExpr | | +| variables.rs:68:5:68:18 | ExprStmt | variables.rs:68:5:68:13 | PathExpr | | +| variables.rs:68:15:68:16 | b2 | variables.rs:68:5:68:17 | CallExpr | | +| variables.rs:71:1:78:1 | enter let_pattern3 | variables.rs:72:5:72:42 | LetStmt | | +| variables.rs:71:1:78:1 | exit let_pattern3 (normal) | variables.rs:71:1:78:1 | exit let_pattern3 | | +| variables.rs:71:19:78:1 | BlockExpr | variables.rs:71:1:78:1 | exit let_pattern3 (normal) | | +| variables.rs:72:5:72:42 | LetStmt | variables.rs:72:14:72:17 | PathExpr | | +| variables.rs:72:9:72:10 | s1 | variables.rs:74:8:75:12 | LetExpr | match, no-match | +| variables.rs:72:14:72:17 | PathExpr | variables.rs:72:19:72:30 | PathExpr | | +| variables.rs:72:14:72:41 | CallExpr | variables.rs:72:9:72:10 | s1 | | +| variables.rs:72:19:72:30 | PathExpr | variables.rs:72:32:72:39 | "Hello!" | | +| variables.rs:72:19:72:40 | CallExpr | variables.rs:72:14:72:41 | CallExpr | | +| variables.rs:72:32:72:39 | "Hello!" | variables.rs:72:19:72:40 | CallExpr | | +| variables.rs:74:5:77:5 | IfExpr | variables.rs:71:19:78:1 | BlockExpr | | +| variables.rs:74:8:75:12 | LetExpr | variables.rs:74:12:74:23 | TupleStructPat | | +| variables.rs:74:12:74:23 | TupleStructPat | variables.rs:74:5:77:5 | IfExpr | no-match | +| variables.rs:74:12:74:23 | TupleStructPat | variables.rs:76:9:76:22 | ExprStmt | match | +| variables.rs:75:14:77:5 | BlockExpr | variables.rs:74:5:77:5 | IfExpr | | +| variables.rs:76:9:76:17 | PathExpr | variables.rs:76:19:76:20 | s2 | | +| variables.rs:76:9:76:21 | CallExpr | variables.rs:75:14:77:5 | BlockExpr | | +| variables.rs:76:9:76:22 | ExprStmt | variables.rs:76:9:76:17 | PathExpr | | +| variables.rs:76:19:76:20 | s2 | variables.rs:76:9:76:21 | CallExpr | | +| variables.rs:80:1:86:1 | enter let_pattern4 | variables.rs:81:5:84:6 | LetStmt | | +| variables.rs:80:1:86:1 | exit let_pattern4 (normal) | variables.rs:80:1:86:1 | exit let_pattern4 | | +| variables.rs:80:19:86:1 | BlockExpr | variables.rs:80:1:86:1 | exit let_pattern4 (normal) | | +| variables.rs:81:5:84:6 | LetStmt | variables.rs:81:34:81:37 | PathExpr | | +| variables.rs:81:9:81:16 | TupleStructPat | variables.rs:83:9:83:15 | MacroExpr | no-match | +| variables.rs:81:9:81:16 | TupleStructPat | variables.rs:85:5:85:18 | ExprStmt | match | +| variables.rs:81:34:81:37 | PathExpr | variables.rs:81:39:81:42 | "x5" | | +| variables.rs:81:34:81:43 | CallExpr | variables.rs:81:9:81:16 | TupleStructPat | | +| variables.rs:81:39:81:42 | "x5" | variables.rs:81:34:81:43 | CallExpr | | +| variables.rs:83:9:83:15 | MacroExpr | variables.rs:81:50:84:5 | BlockExpr | | +| variables.rs:85:5:85:13 | PathExpr | variables.rs:85:15:85:16 | x5 | | +| variables.rs:85:5:85:17 | CallExpr | variables.rs:80:19:86:1 | BlockExpr | | +| variables.rs:85:5:85:18 | ExprStmt | variables.rs:85:5:85:13 | PathExpr | | +| variables.rs:85:15:85:16 | x5 | variables.rs:85:5:85:17 | CallExpr | | +| variables.rs:88:1:103:1 | enter match_pattern1 | variables.rs:89:5:89:21 | LetStmt | | +| variables.rs:88:1:103:1 | exit match_pattern1 (normal) | variables.rs:88:1:103:1 | exit match_pattern1 | | +| variables.rs:88:21:103:1 | BlockExpr | variables.rs:88:1:103:1 | exit match_pattern1 (normal) | | +| variables.rs:89:5:89:21 | LetStmt | variables.rs:89:14:89:17 | PathExpr | | +| variables.rs:89:9:89:10 | x6 | variables.rs:90:5:90:16 | LetStmt | match, no-match | +| variables.rs:89:14:89:17 | PathExpr | variables.rs:89:19:89:19 | 5 | | +| variables.rs:89:14:89:20 | CallExpr | variables.rs:89:9:89:10 | x6 | | +| variables.rs:89:19:89:19 | 5 | variables.rs:89:14:89:20 | CallExpr | | +| variables.rs:90:5:90:16 | LetStmt | variables.rs:90:14:90:15 | 10 | | +| variables.rs:90:9:90:10 | y1 | variables.rs:92:5:100:5 | ExprStmt | match, no-match | +| variables.rs:90:14:90:15 | 10 | variables.rs:90:9:90:10 | y1 | | +| variables.rs:92:5:100:5 | ExprStmt | variables.rs:92:11:92:12 | x6 | | +| variables.rs:92:5:100:5 | MatchExpr | variables.rs:102:5:102:18 | ExprStmt | | +| variables.rs:92:11:92:12 | x6 | variables.rs:93:9:93:16 | TupleStructPat | | +| variables.rs:93:9:93:16 | TupleStructPat | variables.rs:93:21:93:29 | PathExpr | match | +| variables.rs:93:9:93:16 | TupleStructPat | variables.rs:94:9:94:16 | TupleStructPat | no-match | +| variables.rs:93:21:93:29 | PathExpr | variables.rs:93:31:93:38 | "Got 50" | | +| variables.rs:93:21:93:39 | CallExpr | variables.rs:92:5:100:5 | MatchExpr | | +| variables.rs:93:31:93:38 | "Got 50" | variables.rs:93:21:93:39 | CallExpr | | +| variables.rs:94:9:94:16 | TupleStructPat | variables.rs:97:13:97:21 | PathExpr | match | +| variables.rs:94:9:94:16 | TupleStructPat | variables.rs:99:9:99:12 | None | no-match | +| variables.rs:96:9:98:9 | BlockExpr | variables.rs:92:5:100:5 | MatchExpr | | +| variables.rs:97:13:97:21 | PathExpr | variables.rs:97:23:97:24 | y1 | | +| variables.rs:97:13:97:25 | CallExpr | variables.rs:96:9:98:9 | BlockExpr | | +| variables.rs:97:23:97:24 | y1 | variables.rs:97:13:97:25 | CallExpr | | +| variables.rs:99:9:99:12 | None | variables.rs:99:17:99:25 | PathExpr | match | +| variables.rs:99:17:99:25 | PathExpr | variables.rs:99:27:99:32 | "NONE" | | +| variables.rs:99:17:99:33 | CallExpr | variables.rs:92:5:100:5 | MatchExpr | | +| variables.rs:99:27:99:32 | "NONE" | variables.rs:99:17:99:33 | CallExpr | | +| variables.rs:102:5:102:13 | PathExpr | variables.rs:102:15:102:16 | y1 | | +| variables.rs:102:5:102:17 | CallExpr | variables.rs:88:21:103:1 | BlockExpr | | +| variables.rs:102:5:102:18 | ExprStmt | variables.rs:102:5:102:13 | PathExpr | | +| variables.rs:102:15:102:16 | y1 | variables.rs:102:5:102:17 | CallExpr | | +| variables.rs:105:1:130:1 | enter match_pattern2 | variables.rs:106:5:106:36 | LetStmt | | +| variables.rs:105:1:130:1 | exit match_pattern2 (normal) | variables.rs:105:1:130:1 | exit match_pattern2 | | +| variables.rs:105:21:130:1 | BlockExpr | variables.rs:105:1:130:1 | exit match_pattern2 (normal) | | +| variables.rs:106:5:106:36 | LetStmt | variables.rs:106:20:106:20 | 2 | | +| variables.rs:106:9:106:15 | numbers | variables.rs:108:5:118:5 | ExprStmt | match, no-match | +| variables.rs:106:19:106:35 | TupleExpr | variables.rs:106:9:106:15 | numbers | | +| variables.rs:106:20:106:20 | 2 | variables.rs:106:23:106:23 | 4 | | +| variables.rs:106:23:106:23 | 4 | variables.rs:106:26:106:26 | 8 | | +| variables.rs:106:26:106:26 | 8 | variables.rs:106:29:106:30 | 16 | | +| variables.rs:106:29:106:30 | 16 | variables.rs:106:33:106:34 | 32 | | +| variables.rs:106:33:106:34 | 32 | variables.rs:106:19:106:35 | TupleExpr | | +| variables.rs:108:5:118:5 | ExprStmt | variables.rs:108:11:108:17 | numbers | | +| variables.rs:108:5:118:5 | MatchExpr | variables.rs:120:11:120:17 | numbers | | +| variables.rs:108:11:108:17 | numbers | variables.rs:109:9:113:9 | TuplePat | | +| variables.rs:109:9:113:9 | TuplePat | variables.rs:114:13:114:29 | ExprStmt | match | +| variables.rs:113:14:117:9 | BlockExpr | variables.rs:108:5:118:5 | MatchExpr | | +| variables.rs:114:13:114:21 | PathExpr | variables.rs:114:23:114:27 | first | | +| variables.rs:114:13:114:28 | CallExpr | variables.rs:115:13:115:29 | ExprStmt | | +| variables.rs:114:13:114:29 | ExprStmt | variables.rs:114:13:114:21 | PathExpr | | +| variables.rs:114:23:114:27 | first | variables.rs:114:13:114:28 | CallExpr | | +| variables.rs:115:13:115:21 | PathExpr | variables.rs:115:23:115:27 | third | | +| variables.rs:115:13:115:28 | CallExpr | variables.rs:116:13:116:29 | ExprStmt | | +| variables.rs:115:13:115:29 | ExprStmt | variables.rs:115:13:115:21 | PathExpr | | +| variables.rs:115:23:115:27 | third | variables.rs:115:13:115:28 | CallExpr | | +| variables.rs:116:13:116:21 | PathExpr | variables.rs:116:23:116:27 | fifth | | +| variables.rs:116:13:116:28 | CallExpr | variables.rs:113:14:117:9 | BlockExpr | | +| variables.rs:116:13:116:29 | ExprStmt | variables.rs:116:13:116:21 | PathExpr | | +| variables.rs:116:23:116:27 | fifth | variables.rs:116:13:116:28 | CallExpr | | +| variables.rs:120:5:129:5 | MatchExpr | variables.rs:105:21:130:1 | BlockExpr | | +| variables.rs:120:11:120:17 | numbers | variables.rs:121:9:125:9 | TuplePat | | +| variables.rs:121:9:125:9 | TuplePat | variables.rs:126:13:126:29 | ExprStmt | match | +| variables.rs:125:14:128:9 | BlockExpr | variables.rs:120:5:129:5 | MatchExpr | | +| variables.rs:126:13:126:21 | PathExpr | variables.rs:126:23:126:27 | first | | +| variables.rs:126:13:126:28 | CallExpr | variables.rs:127:13:127:28 | ExprStmt | | +| variables.rs:126:13:126:29 | ExprStmt | variables.rs:126:13:126:21 | PathExpr | | +| variables.rs:126:23:126:27 | first | variables.rs:126:13:126:28 | CallExpr | | +| variables.rs:127:13:127:21 | PathExpr | variables.rs:127:23:127:26 | last | | +| variables.rs:127:13:127:27 | CallExpr | variables.rs:125:14:128:9 | BlockExpr | | +| variables.rs:127:13:127:28 | ExprStmt | variables.rs:127:13:127:21 | PathExpr | | +| variables.rs:127:23:127:26 | last | variables.rs:127:13:127:27 | CallExpr | | +| variables.rs:132:1:140:1 | enter match_pattern3 | variables.rs:133:5:133:38 | LetStmt | | +| variables.rs:132:1:140:1 | exit match_pattern3 (normal) | variables.rs:132:1:140:1 | exit match_pattern3 | | +| variables.rs:132:21:140:1 | BlockExpr | variables.rs:132:1:140:1 | exit match_pattern3 (normal) | | +| variables.rs:133:5:133:38 | LetStmt | variables.rs:133:25:133:27 | "x" | | +| variables.rs:133:9:133:10 | p2 | variables.rs:135:11:135:12 | p2 | match, no-match | +| variables.rs:133:14:133:37 | RecordExpr | variables.rs:133:9:133:10 | p2 | | +| variables.rs:133:25:133:27 | "x" | variables.rs:133:33:133:35 | "y" | | +| variables.rs:133:33:133:35 | "y" | variables.rs:133:14:133:37 | RecordExpr | | +| variables.rs:135:5:139:5 | MatchExpr | variables.rs:132:21:140:1 | BlockExpr | | +| variables.rs:135:11:135:12 | p2 | variables.rs:136:9:138:9 | RecordPat | | +| variables.rs:136:9:138:9 | RecordPat | variables.rs:138:14:138:22 | PathExpr | match | +| variables.rs:138:14:138:22 | PathExpr | variables.rs:138:24:138:25 | x7 | | +| variables.rs:138:14:138:26 | CallExpr | variables.rs:135:5:139:5 | MatchExpr | | +| variables.rs:138:24:138:25 | x7 | variables.rs:138:14:138:26 | CallExpr | | +| variables.rs:146:1:159:1 | enter match_pattern4 | variables.rs:147:5:147:39 | LetStmt | | +| variables.rs:146:1:159:1 | exit match_pattern4 (normal) | variables.rs:146:1:159:1 | exit match_pattern4 | | +| variables.rs:146:21:159:1 | BlockExpr | variables.rs:146:1:159:1 | exit match_pattern4 (normal) | | +| variables.rs:147:5:147:39 | LetStmt | variables.rs:147:36:147:36 | 0 | | +| variables.rs:147:9:147:11 | msg | variables.rs:149:11:149:13 | msg | match, no-match | +| variables.rs:147:15:147:38 | RecordExpr | variables.rs:147:9:147:11 | msg | | +| variables.rs:147:36:147:36 | 0 | variables.rs:147:15:147:38 | RecordExpr | | +| variables.rs:149:5:158:5 | MatchExpr | variables.rs:146:21:159:1 | BlockExpr | | +| variables.rs:149:11:149:13 | msg | variables.rs:150:9:152:9 | RecordPat | | +| variables.rs:150:9:152:9 | RecordPat | variables.rs:152:14:152:22 | PathExpr | match | +| variables.rs:150:9:152:9 | RecordPat | variables.rs:153:9:153:38 | RecordPat | no-match | +| variables.rs:152:14:152:22 | PathExpr | variables.rs:152:24:152:34 | id_variable | | +| variables.rs:152:14:152:35 | CallExpr | variables.rs:149:5:158:5 | MatchExpr | | +| variables.rs:152:24:152:34 | id_variable | variables.rs:152:14:152:35 | CallExpr | | +| variables.rs:153:9:153:38 | RecordPat | variables.rs:154:13:154:52 | MacroExpr | match | +| variables.rs:153:9:153:38 | RecordPat | variables.rs:156:9:156:29 | RecordPat | no-match | +| variables.rs:153:43:155:9 | BlockExpr | variables.rs:149:5:158:5 | MatchExpr | | +| variables.rs:154:13:154:52 | MacroExpr | variables.rs:153:43:155:9 | BlockExpr | | +| variables.rs:156:9:156:29 | RecordPat | variables.rs:157:13:157:21 | PathExpr | match | +| variables.rs:157:13:157:21 | PathExpr | variables.rs:157:23:157:24 | id | | +| variables.rs:157:13:157:25 | CallExpr | variables.rs:149:5:158:5 | MatchExpr | | +| variables.rs:157:23:157:24 | id | variables.rs:157:13:157:25 | CallExpr | | +| variables.rs:166:1:172:1 | enter match_pattern5 | variables.rs:167:5:167:34 | LetStmt | | +| variables.rs:166:1:172:1 | exit match_pattern5 (normal) | variables.rs:166:1:172:1 | exit match_pattern5 | | +| variables.rs:166:21:172:1 | BlockExpr | variables.rs:166:1:172:1 | exit match_pattern5 (normal) | | +| variables.rs:167:5:167:34 | LetStmt | variables.rs:167:18:167:29 | PathExpr | | +| variables.rs:167:9:167:14 | either | variables.rs:168:11:168:16 | either | match, no-match | +| variables.rs:167:18:167:29 | PathExpr | variables.rs:167:31:167:32 | 32 | | +| variables.rs:167:18:167:33 | CallExpr | variables.rs:167:9:167:14 | either | | +| variables.rs:167:31:167:32 | 32 | variables.rs:167:18:167:33 | CallExpr | | +| variables.rs:168:5:171:5 | MatchExpr | variables.rs:166:21:172:1 | BlockExpr | | +| variables.rs:168:11:168:16 | either | variables.rs:169:9:169:44 | OrPat | | +| variables.rs:169:9:169:44 | OrPat | variables.rs:170:16:170:24 | PathExpr | match | +| variables.rs:170:16:170:24 | PathExpr | variables.rs:170:26:170:27 | a3 | | +| variables.rs:170:16:170:28 | CallExpr | variables.rs:168:5:171:5 | MatchExpr | | +| variables.rs:170:26:170:27 | a3 | variables.rs:170:16:170:28 | CallExpr | | +| variables.rs:180:1:194:1 | enter match_pattern6 | variables.rs:181:5:181:37 | LetStmt | | +| variables.rs:180:1:194:1 | exit match_pattern6 (normal) | variables.rs:180:1:194:1 | exit match_pattern6 | | +| variables.rs:180:21:194:1 | BlockExpr | variables.rs:180:1:194:1 | exit match_pattern6 (normal) | | +| variables.rs:181:5:181:37 | LetStmt | variables.rs:181:14:181:32 | PathExpr | | +| variables.rs:181:9:181:10 | tv | variables.rs:182:5:185:5 | ExprStmt | match, no-match | +| variables.rs:181:14:181:32 | PathExpr | variables.rs:181:34:181:35 | 62 | | +| variables.rs:181:14:181:36 | CallExpr | variables.rs:181:9:181:10 | tv | | +| variables.rs:181:34:181:35 | 62 | variables.rs:181:14:181:36 | CallExpr | | +| variables.rs:182:5:185:5 | ExprStmt | variables.rs:182:11:182:12 | tv | | +| variables.rs:182:5:185:5 | MatchExpr | variables.rs:186:5:189:5 | ExprStmt | | +| variables.rs:182:11:182:12 | tv | variables.rs:183:9:183:81 | OrPat | | +| variables.rs:183:9:183:81 | OrPat | variables.rs:184:16:184:24 | PathExpr | match | +| variables.rs:184:16:184:24 | PathExpr | variables.rs:184:26:184:27 | a4 | | +| variables.rs:184:16:184:28 | CallExpr | variables.rs:182:5:185:5 | MatchExpr | | +| variables.rs:184:26:184:27 | a4 | variables.rs:184:16:184:28 | CallExpr | | +| variables.rs:186:5:189:5 | ExprStmt | variables.rs:186:11:186:12 | tv | | +| variables.rs:186:5:189:5 | MatchExpr | variables.rs:190:11:190:12 | tv | | +| variables.rs:186:11:186:12 | tv | variables.rs:187:9:187:83 | OrPat | | +| variables.rs:187:9:187:83 | OrPat | variables.rs:188:16:188:24 | PathExpr | match | +| variables.rs:188:16:188:24 | PathExpr | variables.rs:188:26:188:27 | a5 | | +| variables.rs:188:16:188:28 | CallExpr | variables.rs:186:5:189:5 | MatchExpr | | +| variables.rs:188:26:188:27 | a5 | variables.rs:188:16:188:28 | CallExpr | | +| variables.rs:190:5:193:5 | MatchExpr | variables.rs:180:21:194:1 | BlockExpr | | +| variables.rs:190:11:190:12 | tv | variables.rs:191:9:191:83 | OrPat | | +| variables.rs:191:9:191:83 | OrPat | variables.rs:192:16:192:24 | PathExpr | match | +| variables.rs:192:16:192:24 | PathExpr | variables.rs:192:26:192:27 | a6 | | +| variables.rs:192:16:192:28 | CallExpr | variables.rs:190:5:193:5 | MatchExpr | | +| variables.rs:192:26:192:27 | a6 | variables.rs:192:16:192:28 | CallExpr | | +| variables.rs:196:1:204:1 | enter match_pattern7 | variables.rs:197:5:197:34 | LetStmt | | +| variables.rs:196:1:204:1 | exit match_pattern7 (normal) | variables.rs:196:1:204:1 | exit match_pattern7 | | +| variables.rs:196:21:204:1 | BlockExpr | variables.rs:196:1:204:1 | exit match_pattern7 (normal) | | +| variables.rs:197:5:197:34 | LetStmt | variables.rs:197:18:197:29 | PathExpr | | +| variables.rs:197:9:197:14 | either | variables.rs:198:11:198:16 | either | match, no-match | +| variables.rs:197:18:197:29 | PathExpr | variables.rs:197:31:197:32 | 32 | | +| variables.rs:197:18:197:33 | CallExpr | variables.rs:197:9:197:14 | either | | +| variables.rs:197:31:197:32 | 32 | variables.rs:197:18:197:33 | CallExpr | | +| variables.rs:198:5:203:5 | MatchExpr | variables.rs:196:21:204:1 | BlockExpr | | +| variables.rs:198:11:198:16 | either | variables.rs:199:9:199:44 | OrPat | | +| variables.rs:199:9:199:44 | OrPat | variables.rs:200:16:200:17 | a7 | match | +| variables.rs:199:9:199:44 | OrPat | variables.rs:202:9:202:9 | WildcardPat | no-match | +| variables.rs:200:16:200:17 | a7 | variables.rs:200:21:200:21 | 0 | | +| variables.rs:200:16:200:21 | ... > ... | variables.rs:201:16:201:24 | PathExpr | true | +| variables.rs:200:16:200:21 | ... > ... | variables.rs:202:9:202:9 | WildcardPat | false | +| variables.rs:200:21:200:21 | 0 | variables.rs:200:16:200:21 | ... > ... | | +| variables.rs:201:16:201:24 | PathExpr | variables.rs:201:26:201:27 | a7 | | +| variables.rs:201:16:201:28 | CallExpr | variables.rs:198:5:203:5 | MatchExpr | | +| variables.rs:201:26:201:27 | a7 | variables.rs:201:16:201:28 | CallExpr | | +| variables.rs:202:9:202:9 | WildcardPat | variables.rs:202:14:202:15 | TupleExpr | match | +| variables.rs:202:14:202:15 | TupleExpr | variables.rs:198:5:203:5 | MatchExpr | | +| variables.rs:206:1:221:1 | enter match_pattern8 | variables.rs:207:5:207:34 | LetStmt | | +| variables.rs:206:1:221:1 | exit match_pattern8 (normal) | variables.rs:206:1:221:1 | exit match_pattern8 | | +| variables.rs:206:21:221:1 | BlockExpr | variables.rs:206:1:221:1 | exit match_pattern8 (normal) | | +| variables.rs:207:5:207:34 | LetStmt | variables.rs:207:18:207:29 | PathExpr | | +| variables.rs:207:9:207:14 | either | variables.rs:209:11:209:16 | either | match, no-match | +| variables.rs:207:18:207:29 | PathExpr | variables.rs:207:31:207:32 | 32 | | +| variables.rs:207:18:207:33 | CallExpr | variables.rs:207:9:207:14 | either | | +| variables.rs:207:31:207:32 | 32 | variables.rs:207:18:207:33 | CallExpr | | +| variables.rs:209:5:220:5 | MatchExpr | variables.rs:206:21:221:1 | BlockExpr | | +| variables.rs:209:11:209:16 | either | variables.rs:210:9:211:52 | e | | +| variables.rs:210:9:211:52 | e | variables.rs:213:13:213:27 | ExprStmt | match | +| variables.rs:210:9:211:52 | e | variables.rs:219:9:219:9 | WildcardPat | no-match | +| variables.rs:212:12:218:9 | BlockExpr | variables.rs:209:5:220:5 | MatchExpr | | +| variables.rs:213:13:213:21 | PathExpr | variables.rs:213:23:213:25 | a11 | | +| variables.rs:213:13:213:26 | CallExpr | variables.rs:214:16:215:15 | LetExpr | | +| variables.rs:213:13:213:27 | ExprStmt | variables.rs:213:13:213:21 | PathExpr | | +| variables.rs:213:23:213:25 | a11 | variables.rs:213:13:213:26 | CallExpr | | +| variables.rs:214:13:217:13 | IfExpr | variables.rs:212:12:218:9 | BlockExpr | | +| variables.rs:214:16:215:15 | LetExpr | variables.rs:214:20:214:36 | TupleStructPat | | +| variables.rs:214:20:214:36 | TupleStructPat | variables.rs:214:13:217:13 | IfExpr | no-match | +| variables.rs:214:20:214:36 | TupleStructPat | variables.rs:216:17:216:32 | ExprStmt | match | +| variables.rs:215:17:217:13 | BlockExpr | variables.rs:214:13:217:13 | IfExpr | | +| variables.rs:216:17:216:25 | PathExpr | variables.rs:216:28:216:30 | a12 | | +| variables.rs:216:17:216:31 | CallExpr | variables.rs:215:17:217:13 | BlockExpr | | +| variables.rs:216:17:216:32 | ExprStmt | variables.rs:216:17:216:25 | PathExpr | | +| variables.rs:216:27:216:30 | * ... | variables.rs:216:17:216:31 | CallExpr | | +| variables.rs:216:28:216:30 | a12 | variables.rs:216:27:216:30 | * ... | | +| variables.rs:219:9:219:9 | WildcardPat | variables.rs:219:14:219:15 | TupleExpr | match | +| variables.rs:219:14:219:15 | TupleExpr | variables.rs:209:5:220:5 | MatchExpr | | +| variables.rs:230:1:236:1 | enter match_pattern9 | variables.rs:231:5:231:36 | LetStmt | | +| variables.rs:230:1:236:1 | exit match_pattern9 (normal) | variables.rs:230:1:236:1 | exit match_pattern9 | | +| variables.rs:230:21:236:1 | BlockExpr | variables.rs:230:1:236:1 | exit match_pattern9 (normal) | | +| variables.rs:231:5:231:36 | LetStmt | variables.rs:231:14:231:31 | PathExpr | | +| variables.rs:231:9:231:10 | fv | variables.rs:232:11:232:12 | fv | match, no-match | +| variables.rs:231:14:231:31 | PathExpr | variables.rs:231:33:231:34 | 62 | | +| variables.rs:231:14:231:35 | CallExpr | variables.rs:231:9:231:10 | fv | | +| variables.rs:231:33:231:34 | 62 | variables.rs:231:14:231:35 | CallExpr | | +| variables.rs:232:5:235:5 | MatchExpr | variables.rs:230:21:236:1 | BlockExpr | | +| variables.rs:232:11:232:12 | fv | variables.rs:233:9:233:109 | OrPat | | +| variables.rs:233:9:233:109 | OrPat | variables.rs:234:16:234:24 | PathExpr | match | +| variables.rs:234:16:234:24 | PathExpr | variables.rs:234:26:234:28 | a13 | | +| variables.rs:234:16:234:29 | CallExpr | variables.rs:232:5:235:5 | MatchExpr | | +| variables.rs:234:26:234:28 | a13 | variables.rs:234:16:234:29 | CallExpr | | +| variables.rs:238:1:247:1 | enter param_pattern1 | variables.rs:244:5:244:18 | ExprStmt | | +| variables.rs:238:1:247:1 | exit param_pattern1 (normal) | variables.rs:238:1:247:1 | exit param_pattern1 | | +| variables.rs:243:28:247:1 | BlockExpr | variables.rs:238:1:247:1 | exit param_pattern1 (normal) | | +| variables.rs:244:5:244:13 | PathExpr | variables.rs:244:15:244:16 | a8 | | +| variables.rs:244:5:244:17 | CallExpr | variables.rs:245:5:245:18 | ExprStmt | | +| variables.rs:244:5:244:18 | ExprStmt | variables.rs:244:5:244:13 | PathExpr | | +| variables.rs:244:15:244:16 | a8 | variables.rs:244:5:244:17 | CallExpr | | +| variables.rs:245:5:245:13 | PathExpr | variables.rs:245:15:245:16 | b3 | | +| variables.rs:245:5:245:17 | CallExpr | variables.rs:246:5:246:18 | ExprStmt | | +| variables.rs:245:5:245:18 | ExprStmt | variables.rs:245:5:245:13 | PathExpr | | +| variables.rs:245:15:245:16 | b3 | variables.rs:245:5:245:17 | CallExpr | | +| variables.rs:246:5:246:13 | PathExpr | variables.rs:246:15:246:16 | c1 | | +| variables.rs:246:5:246:17 | CallExpr | variables.rs:243:28:247:1 | BlockExpr | | +| variables.rs:246:5:246:18 | ExprStmt | variables.rs:246:5:246:13 | PathExpr | | +| variables.rs:246:15:246:16 | c1 | variables.rs:246:5:246:17 | CallExpr | | +| variables.rs:249:1:253:1 | enter param_pattern2 | variables.rs:252:5:252:18 | ExprStmt | | +| variables.rs:249:1:253:1 | exit param_pattern2 (normal) | variables.rs:249:1:253:1 | exit param_pattern2 | | +| variables.rs:251:9:253:1 | BlockExpr | variables.rs:249:1:253:1 | exit param_pattern2 (normal) | | +| variables.rs:252:5:252:13 | PathExpr | variables.rs:252:15:252:16 | a9 | | +| variables.rs:252:5:252:17 | CallExpr | variables.rs:251:9:253:1 | BlockExpr | | +| variables.rs:252:5:252:18 | ExprStmt | variables.rs:252:5:252:13 | PathExpr | | +| variables.rs:252:15:252:16 | a9 | variables.rs:252:5:252:17 | CallExpr | | +| variables.rs:255:1:290:1 | enter destruct_assignment | variables.rs:256:5:260:18 | LetStmt | | +| variables.rs:255:1:290:1 | exit destruct_assignment (normal) | variables.rs:255:1:290:1 | exit destruct_assignment | | +| variables.rs:255:26:290:1 | BlockExpr | variables.rs:255:1:290:1 | exit destruct_assignment (normal) | | +| variables.rs:256:5:260:18 | LetStmt | variables.rs:260:10:260:10 | 1 | | +| variables.rs:256:9:260:5 | TuplePat | variables.rs:261:5:261:19 | ExprStmt | match | +| variables.rs:260:9:260:17 | TupleExpr | variables.rs:256:9:260:5 | TuplePat | | +| variables.rs:260:10:260:10 | 1 | variables.rs:260:13:260:13 | 2 | | +| variables.rs:260:13:260:13 | 2 | variables.rs:260:16:260:16 | 3 | | +| variables.rs:260:16:260:16 | 3 | variables.rs:260:9:260:17 | TupleExpr | | +| variables.rs:261:5:261:13 | PathExpr | variables.rs:261:15:261:17 | a10 | | +| variables.rs:261:5:261:18 | CallExpr | variables.rs:262:5:262:18 | ExprStmt | | +| variables.rs:261:5:261:19 | ExprStmt | variables.rs:261:5:261:13 | PathExpr | | +| variables.rs:261:15:261:17 | a10 | variables.rs:261:5:261:18 | CallExpr | | +| variables.rs:262:5:262:13 | PathExpr | variables.rs:262:15:262:16 | b4 | | +| variables.rs:262:5:262:17 | CallExpr | variables.rs:263:5:263:18 | ExprStmt | | +| variables.rs:262:5:262:18 | ExprStmt | variables.rs:262:5:262:13 | PathExpr | | +| variables.rs:262:15:262:16 | b4 | variables.rs:262:5:262:17 | CallExpr | | +| variables.rs:263:5:263:13 | PathExpr | variables.rs:263:15:263:16 | c2 | | +| variables.rs:263:5:263:17 | CallExpr | variables.rs:265:5:273:6 | ExprStmt | | +| variables.rs:263:5:263:18 | ExprStmt | variables.rs:263:5:263:13 | PathExpr | | +| variables.rs:263:15:263:16 | c2 | variables.rs:263:5:263:17 | CallExpr | | +| variables.rs:265:5:269:5 | TupleExpr | variables.rs:270:9:270:11 | a10 | | +| variables.rs:265:5:273:5 | ... = ... | variables.rs:274:5:274:19 | ExprStmt | | +| variables.rs:265:5:273:6 | ExprStmt | variables.rs:266:9:266:10 | c2 | | +| variables.rs:266:9:266:10 | c2 | variables.rs:267:9:267:10 | b4 | | +| variables.rs:267:9:267:10 | b4 | variables.rs:268:9:268:11 | a10 | | +| variables.rs:268:9:268:11 | a10 | variables.rs:265:5:269:5 | TupleExpr | | +| variables.rs:269:9:273:5 | TupleExpr | variables.rs:265:5:273:5 | ... = ... | | +| variables.rs:270:9:270:11 | a10 | variables.rs:271:9:271:10 | b4 | | +| variables.rs:271:9:271:10 | b4 | variables.rs:272:9:272:10 | c2 | | +| variables.rs:272:9:272:10 | c2 | variables.rs:269:9:273:5 | TupleExpr | | +| variables.rs:274:5:274:13 | PathExpr | variables.rs:274:15:274:17 | a10 | | +| variables.rs:274:5:274:18 | CallExpr | variables.rs:275:5:275:18 | ExprStmt | | +| variables.rs:274:5:274:19 | ExprStmt | variables.rs:274:5:274:13 | PathExpr | | +| variables.rs:274:15:274:17 | a10 | variables.rs:274:5:274:18 | CallExpr | | +| variables.rs:275:5:275:13 | PathExpr | variables.rs:275:15:275:16 | b4 | | +| variables.rs:275:5:275:17 | CallExpr | variables.rs:276:5:276:18 | ExprStmt | | +| variables.rs:275:5:275:18 | ExprStmt | variables.rs:275:5:275:13 | PathExpr | | +| variables.rs:275:15:275:16 | b4 | variables.rs:275:5:275:17 | CallExpr | | +| variables.rs:276:5:276:13 | PathExpr | variables.rs:276:15:276:16 | c2 | | +| variables.rs:276:5:276:17 | CallExpr | variables.rs:278:5:286:5 | ExprStmt | | +| variables.rs:276:5:276:18 | ExprStmt | variables.rs:276:5:276:13 | PathExpr | | +| variables.rs:276:15:276:16 | c2 | variables.rs:276:5:276:17 | CallExpr | | +| variables.rs:278:5:286:5 | ExprStmt | variables.rs:278:12:278:12 | 4 | | +| variables.rs:278:5:286:5 | MatchExpr | variables.rs:288:5:288:19 | ExprStmt | | +| variables.rs:278:11:278:16 | TupleExpr | variables.rs:279:9:282:9 | TuplePat | | +| variables.rs:278:12:278:12 | 4 | variables.rs:278:15:278:15 | 5 | | +| variables.rs:278:15:278:15 | 5 | variables.rs:278:11:278:16 | TupleExpr | | +| variables.rs:279:9:282:9 | TuplePat | variables.rs:283:13:283:27 | ExprStmt | match | +| variables.rs:282:14:285:9 | BlockExpr | variables.rs:278:5:286:5 | MatchExpr | | +| variables.rs:283:13:283:21 | PathExpr | variables.rs:283:23:283:25 | a10 | | +| variables.rs:283:13:283:26 | CallExpr | variables.rs:284:13:284:26 | ExprStmt | | +| variables.rs:283:13:283:27 | ExprStmt | variables.rs:283:13:283:21 | PathExpr | | +| variables.rs:283:23:283:25 | a10 | variables.rs:283:13:283:26 | CallExpr | | +| variables.rs:284:13:284:21 | PathExpr | variables.rs:284:23:284:24 | b4 | | +| variables.rs:284:13:284:25 | CallExpr | variables.rs:282:14:285:9 | BlockExpr | | +| variables.rs:284:13:284:26 | ExprStmt | variables.rs:284:13:284:21 | PathExpr | | +| variables.rs:284:23:284:24 | b4 | variables.rs:284:13:284:25 | CallExpr | | +| variables.rs:288:5:288:13 | PathExpr | variables.rs:288:15:288:17 | a10 | | +| variables.rs:288:5:288:18 | CallExpr | variables.rs:289:5:289:18 | ExprStmt | | +| variables.rs:288:5:288:19 | ExprStmt | variables.rs:288:5:288:13 | PathExpr | | +| variables.rs:288:15:288:17 | a10 | variables.rs:288:5:288:18 | CallExpr | | +| variables.rs:289:5:289:13 | PathExpr | variables.rs:289:15:289:16 | b4 | | +| variables.rs:289:5:289:17 | CallExpr | variables.rs:255:26:290:1 | BlockExpr | | +| variables.rs:289:5:289:18 | ExprStmt | variables.rs:289:5:289:13 | PathExpr | | +| variables.rs:289:15:289:16 | b4 | variables.rs:289:5:289:17 | CallExpr | | +| variables.rs:292:1:307:1 | enter closure_variable | variables.rs:293:5:295:10 | LetStmt | | +| variables.rs:292:1:307:1 | exit closure_variable (normal) | variables.rs:292:1:307:1 | exit closure_variable | | +| variables.rs:292:23:307:1 | BlockExpr | variables.rs:292:1:307:1 | exit closure_variable (normal) | | +| variables.rs:293:5:295:10 | LetStmt | variables.rs:294:9:295:9 | ClosureExpr | | +| variables.rs:293:9:293:23 | example_closure | variables.rs:296:5:297:27 | LetStmt | match, no-match | +| variables.rs:294:9:295:9 | ClosureExpr | variables.rs:293:9:293:23 | example_closure | | +| variables.rs:294:9:295:9 | enter ClosureExpr | variables.rs:295:9:295:9 | x | | +| variables.rs:294:9:295:9 | exit ClosureExpr (normal) | variables.rs:294:9:295:9 | exit ClosureExpr | | +| variables.rs:295:9:295:9 | x | variables.rs:294:9:295:9 | exit ClosureExpr (normal) | | +| variables.rs:296:5:297:27 | LetStmt | variables.rs:297:9:297:23 | example_closure | | +| variables.rs:296:9:296:10 | n1 | variables.rs:298:5:298:18 | ExprStmt | match, no-match | +| variables.rs:297:9:297:23 | example_closure | variables.rs:297:25:297:25 | 5 | | +| variables.rs:297:9:297:26 | CallExpr | variables.rs:296:9:296:10 | n1 | | +| variables.rs:297:25:297:25 | 5 | variables.rs:297:9:297:26 | CallExpr | | +| variables.rs:298:5:298:13 | PathExpr | variables.rs:298:15:298:16 | n1 | | +| variables.rs:298:5:298:17 | CallExpr | variables.rs:300:5:300:25 | ExprStmt | | +| variables.rs:298:5:298:18 | ExprStmt | variables.rs:298:5:298:13 | PathExpr | | +| variables.rs:298:15:298:16 | n1 | variables.rs:298:5:298:17 | CallExpr | | +| variables.rs:300:5:300:22 | PathExpr | variables.rs:300:5:300:24 | CallExpr | | +| variables.rs:300:5:300:24 | CallExpr | variables.rs:301:5:303:10 | LetStmt | | +| variables.rs:300:5:300:25 | ExprStmt | variables.rs:300:5:300:22 | PathExpr | | +| variables.rs:301:5:303:10 | LetStmt | variables.rs:302:9:303:9 | ClosureExpr | | +| variables.rs:301:9:301:26 | immutable_variable | variables.rs:304:5:305:30 | LetStmt | match, no-match | +| variables.rs:302:9:303:9 | ClosureExpr | variables.rs:301:9:301:26 | immutable_variable | | +| variables.rs:302:9:303:9 | enter ClosureExpr | variables.rs:303:9:303:9 | x | | +| variables.rs:302:9:303:9 | exit ClosureExpr (normal) | variables.rs:302:9:303:9 | exit ClosureExpr | | +| variables.rs:303:9:303:9 | x | variables.rs:302:9:303:9 | exit ClosureExpr (normal) | | +| variables.rs:304:5:305:30 | LetStmt | variables.rs:305:9:305:26 | immutable_variable | | +| variables.rs:304:9:304:10 | n2 | variables.rs:306:5:306:18 | ExprStmt | match, no-match | +| variables.rs:305:9:305:26 | immutable_variable | variables.rs:305:28:305:28 | 6 | | +| variables.rs:305:9:305:29 | CallExpr | variables.rs:304:9:304:10 | n2 | | +| variables.rs:305:28:305:28 | 6 | variables.rs:305:9:305:29 | CallExpr | | +| variables.rs:306:5:306:13 | PathExpr | variables.rs:306:15:306:16 | n2 | | +| variables.rs:306:5:306:17 | CallExpr | variables.rs:292:23:307:1 | BlockExpr | | +| variables.rs:306:5:306:18 | ExprStmt | variables.rs:306:5:306:13 | PathExpr | | +| variables.rs:306:15:306:16 | n2 | variables.rs:306:5:306:17 | CallExpr | | +| variables.rs:309:1:316:1 | enter for_variable | variables.rs:310:5:310:42 | LetStmt | | +| variables.rs:309:1:316:1 | exit for_variable (normal) | variables.rs:309:1:316:1 | exit for_variable | | +| variables.rs:309:19:316:1 | BlockExpr | variables.rs:309:1:316:1 | exit for_variable (normal) | | +| variables.rs:310:5:310:42 | LetStmt | variables.rs:310:15:310:22 | "apples" | | +| variables.rs:310:9:310:9 | v | variables.rs:313:12:313:12 | v | match, no-match | +| variables.rs:310:13:310:41 | RefExpr | variables.rs:310:9:310:9 | v | | +| variables.rs:310:14:310:41 | ArrayExpr | variables.rs:310:13:310:41 | RefExpr | | +| variables.rs:310:15:310:22 | "apples" | variables.rs:310:25:310:30 | "cake" | | +| variables.rs:310:25:310:30 | "cake" | variables.rs:310:33:310:40 | "coffee" | | +| variables.rs:310:33:310:40 | "coffee" | variables.rs:310:14:310:41 | ArrayExpr | | +| variables.rs:312:5:315:5 | ForExpr | variables.rs:309:19:316:1 | BlockExpr | | +| variables.rs:312:9:312:12 | text | variables.rs:312:5:315:5 | ForExpr | no-match | +| variables.rs:312:9:312:12 | text | variables.rs:314:9:314:24 | ExprStmt | match | +| variables.rs:313:12:313:12 | v | variables.rs:312:9:312:12 | text | | +| variables.rs:313:14:315:5 | BlockExpr | variables.rs:312:9:312:12 | text | | +| variables.rs:314:9:314:17 | PathExpr | variables.rs:314:19:314:22 | text | | +| variables.rs:314:9:314:23 | CallExpr | variables.rs:313:14:315:5 | BlockExpr | | +| variables.rs:314:9:314:24 | ExprStmt | variables.rs:314:9:314:17 | PathExpr | | +| variables.rs:314:19:314:22 | text | variables.rs:314:9:314:23 | CallExpr | | +| variables.rs:318:1:341:1 | enter main | variables.rs:319:5:319:25 | ExprStmt | | +| variables.rs:318:1:341:1 | exit main (normal) | variables.rs:318:1:341:1 | exit main | | +| variables.rs:318:11:341:1 | BlockExpr | variables.rs:318:1:341:1 | exit main (normal) | | +| variables.rs:319:5:319:22 | PathExpr | variables.rs:319:5:319:24 | CallExpr | | +| variables.rs:319:5:319:24 | CallExpr | variables.rs:320:5:320:23 | ExprStmt | | +| variables.rs:319:5:319:25 | ExprStmt | variables.rs:319:5:319:22 | PathExpr | | +| variables.rs:320:5:320:20 | PathExpr | variables.rs:320:5:320:22 | CallExpr | | +| variables.rs:320:5:320:22 | CallExpr | variables.rs:321:5:321:23 | ExprStmt | | +| variables.rs:320:5:320:23 | ExprStmt | variables.rs:320:5:320:20 | PathExpr | | +| variables.rs:321:5:321:20 | PathExpr | variables.rs:321:5:321:22 | CallExpr | | +| variables.rs:321:5:321:22 | CallExpr | variables.rs:322:5:322:23 | ExprStmt | | +| variables.rs:321:5:321:23 | ExprStmt | variables.rs:321:5:321:20 | PathExpr | | +| variables.rs:322:5:322:20 | PathExpr | variables.rs:322:5:322:22 | CallExpr | | +| variables.rs:322:5:322:22 | CallExpr | variables.rs:323:5:323:19 | ExprStmt | | +| variables.rs:322:5:322:23 | ExprStmt | variables.rs:322:5:322:20 | PathExpr | | +| variables.rs:323:5:323:16 | PathExpr | variables.rs:323:5:323:18 | CallExpr | | +| variables.rs:323:5:323:18 | CallExpr | variables.rs:324:5:324:19 | ExprStmt | | +| variables.rs:323:5:323:19 | ExprStmt | variables.rs:323:5:323:16 | PathExpr | | +| variables.rs:324:5:324:16 | PathExpr | variables.rs:324:5:324:18 | CallExpr | | +| variables.rs:324:5:324:18 | CallExpr | variables.rs:325:5:325:19 | ExprStmt | | +| variables.rs:324:5:324:19 | ExprStmt | variables.rs:324:5:324:16 | PathExpr | | +| variables.rs:325:5:325:16 | PathExpr | variables.rs:325:5:325:18 | CallExpr | | +| variables.rs:325:5:325:18 | CallExpr | variables.rs:326:5:326:19 | ExprStmt | | +| variables.rs:325:5:325:19 | ExprStmt | variables.rs:325:5:325:16 | PathExpr | | +| variables.rs:326:5:326:16 | PathExpr | variables.rs:326:5:326:18 | CallExpr | | +| variables.rs:326:5:326:18 | CallExpr | variables.rs:327:5:327:21 | ExprStmt | | +| variables.rs:326:5:326:19 | ExprStmt | variables.rs:326:5:326:16 | PathExpr | | +| variables.rs:327:5:327:18 | PathExpr | variables.rs:327:5:327:20 | CallExpr | | +| variables.rs:327:5:327:20 | CallExpr | variables.rs:328:5:328:21 | ExprStmt | | +| variables.rs:327:5:327:21 | ExprStmt | variables.rs:327:5:327:18 | PathExpr | | +| variables.rs:328:5:328:18 | PathExpr | variables.rs:328:5:328:20 | CallExpr | | +| variables.rs:328:5:328:20 | CallExpr | variables.rs:329:5:329:21 | ExprStmt | | +| variables.rs:328:5:328:21 | ExprStmt | variables.rs:328:5:328:18 | PathExpr | | +| variables.rs:329:5:329:18 | PathExpr | variables.rs:329:5:329:20 | CallExpr | | +| variables.rs:329:5:329:20 | CallExpr | variables.rs:330:5:330:21 | ExprStmt | | +| variables.rs:329:5:329:21 | ExprStmt | variables.rs:329:5:329:18 | PathExpr | | +| variables.rs:330:5:330:18 | PathExpr | variables.rs:330:5:330:20 | CallExpr | | +| variables.rs:330:5:330:20 | CallExpr | variables.rs:331:5:331:21 | ExprStmt | | +| variables.rs:330:5:330:21 | ExprStmt | variables.rs:330:5:330:18 | PathExpr | | +| variables.rs:331:5:331:18 | PathExpr | variables.rs:331:5:331:20 | CallExpr | | +| variables.rs:331:5:331:20 | CallExpr | variables.rs:332:5:332:21 | ExprStmt | | +| variables.rs:331:5:331:21 | ExprStmt | variables.rs:331:5:331:18 | PathExpr | | +| variables.rs:332:5:332:18 | PathExpr | variables.rs:332:5:332:20 | CallExpr | | +| variables.rs:332:5:332:20 | CallExpr | variables.rs:333:5:333:21 | ExprStmt | | +| variables.rs:332:5:332:21 | ExprStmt | variables.rs:332:5:332:18 | PathExpr | | +| variables.rs:333:5:333:18 | PathExpr | variables.rs:333:5:333:20 | CallExpr | | +| variables.rs:333:5:333:20 | CallExpr | variables.rs:334:5:334:21 | ExprStmt | | +| variables.rs:333:5:333:21 | ExprStmt | variables.rs:333:5:333:18 | PathExpr | | +| variables.rs:334:5:334:18 | PathExpr | variables.rs:334:5:334:20 | CallExpr | | +| variables.rs:334:5:334:20 | CallExpr | variables.rs:335:5:335:21 | ExprStmt | | +| variables.rs:334:5:334:21 | ExprStmt | variables.rs:334:5:334:18 | PathExpr | | +| variables.rs:335:5:335:18 | PathExpr | variables.rs:335:5:335:20 | CallExpr | | +| variables.rs:335:5:335:20 | CallExpr | variables.rs:336:5:336:36 | ExprStmt | | +| variables.rs:335:5:335:21 | ExprStmt | variables.rs:335:5:335:18 | PathExpr | | +| variables.rs:336:5:336:18 | PathExpr | variables.rs:336:20:336:22 | "a" | | +| variables.rs:336:5:336:35 | CallExpr | variables.rs:337:5:337:37 | ExprStmt | | +| variables.rs:336:5:336:36 | ExprStmt | variables.rs:336:5:336:18 | PathExpr | | +| variables.rs:336:20:336:22 | "a" | variables.rs:336:26:336:28 | "b" | | +| variables.rs:336:25:336:34 | TupleExpr | variables.rs:336:5:336:35 | CallExpr | | +| variables.rs:336:26:336:28 | "b" | variables.rs:336:31:336:33 | "c" | | +| variables.rs:336:31:336:33 | "c" | variables.rs:336:25:336:34 | TupleExpr | | +| variables.rs:337:5:337:18 | PathExpr | variables.rs:337:20:337:31 | PathExpr | | +| variables.rs:337:5:337:36 | CallExpr | variables.rs:338:5:338:26 | ExprStmt | | +| variables.rs:337:5:337:37 | ExprStmt | variables.rs:337:5:337:18 | PathExpr | | +| variables.rs:337:20:337:31 | PathExpr | variables.rs:337:33:337:34 | 45 | | +| variables.rs:337:20:337:35 | CallExpr | variables.rs:337:5:337:36 | CallExpr | | +| variables.rs:337:33:337:34 | 45 | variables.rs:337:20:337:35 | CallExpr | | +| variables.rs:338:5:338:23 | PathExpr | variables.rs:338:5:338:25 | CallExpr | | +| variables.rs:338:5:338:25 | CallExpr | variables.rs:339:5:339:23 | ExprStmt | | +| variables.rs:338:5:338:26 | ExprStmt | variables.rs:338:5:338:23 | PathExpr | | +| variables.rs:339:5:339:20 | PathExpr | variables.rs:339:5:339:22 | CallExpr | | +| variables.rs:339:5:339:22 | CallExpr | variables.rs:340:5:340:19 | ExprStmt | | +| variables.rs:339:5:339:23 | ExprStmt | variables.rs:339:5:339:20 | PathExpr | | +| variables.rs:340:5:340:16 | PathExpr | variables.rs:340:5:340:18 | CallExpr | | +| variables.rs:340:5:340:18 | CallExpr | variables.rs:318:11:341:1 | BlockExpr | | +| variables.rs:340:5:340:19 | ExprStmt | variables.rs:340:5:340:16 | PathExpr | | diff --git a/rust/ql/test/library-tests/variables/Cfg.qlref b/rust/ql/test/library-tests/variables/Cfg.qlref new file mode 100644 index 000000000000..ba4ee4b414f1 --- /dev/null +++ b/rust/ql/test/library-tests/variables/Cfg.qlref @@ -0,0 +1 @@ +query: utils/Cfg.ql \ No newline at end of file diff --git a/rust/ql/test/utils/Cfg.expected b/rust/ql/test/utils/Cfg.expected new file mode 100644 index 000000000000..f19a576c93ac --- /dev/null +++ b/rust/ql/test/utils/Cfg.expected @@ -0,0 +1,3 @@ +edges +breakTarget +continueTarget diff --git a/rust/ql/test/library-tests/controlflow/Cfg.ql b/rust/ql/test/utils/Cfg.ql similarity index 100% rename from rust/ql/test/library-tests/controlflow/Cfg.ql rename to rust/ql/test/utils/Cfg.ql From 1266f9757d3ff448a57cac1bbefd4a64292b6c3e Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Oct 2024 14:50:52 +0200 Subject: [PATCH 125/347] Rust: Add `{BreakExpr,ContinueExpr}.getTarget()` --- rust/ql/.generated.list | 2 - rust/ql/.gitattributes | 2 - .../internal/ControlFlowGraphImpl.qll | 103 ++++++------------ .../rust/elements/internal/BreakExprImpl.qll | 69 +++++++++++- .../elements/internal/ContinueExprImpl.qll | 36 +++++- .../library-tests/controlflow/Cfg.expected | 23 ++++ .../test/library-tests/variables/Cfg.expected | 3 + rust/ql/test/utils/Cfg.ql | 4 + 8 files changed, 166 insertions(+), 76 deletions(-) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 18337b8a6d78..e37f6947148d 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -183,7 +183,6 @@ lib/codeql/rust/elements/internal/BlockExprImpl.qll 36ac09e4a6eeeec22919b62b1d00 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/BreakExprImpl.qll 883ac0e2c0856c91f50747cf10cbcb3ecab535f6858913f2fa34236db8d211d6 5b20db08f16ea5ea3554ffbf6a2a69107e1ec8e3f31dd3935f8839b9a498f4bb lib/codeql/rust/elements/internal/CallExprConstructor.qll 742b38e862e2cf82fd1ecc4d4fc5b4782a9c7c07f031452b2bae7aa59d5aa13a cad6e0a8be21d91b20ac2ec16cab9c30eae810b452c0f1992ed87d5c7f4144dc lib/codeql/rust/elements/internal/CallExprImpl.qll 7e48610680ba6f2876a1a005ab0743496dd2364b9c44aca441bd33e11317e2d7 bb12c3c28156b40796fe3ba112760f87bb5abb323aab3c5b7bb3e0facaef8d35 lib/codeql/rust/elements/internal/CastExprConstructor.qll f3d6e10c4731f38a384675aeab3fba47d17b9e15648293787092bb3247ed808d d738a7751dbadb70aa1dcffcf8af7fa61d4cf8029798369a7e8620013afff4ed @@ -202,7 +201,6 @@ lib/codeql/rust/elements/internal/ConstImpl.qll 7aac2b441a41f21b7d788e3eb042554f lib/codeql/rust/elements/internal/ConstParamConstructor.qll f6645f952aac87c7e00e5e9661275312a1df47172088b4de6b5a253d5c4ed048 eda737470a7b89cf6a02715c9147d074041d6d00fd50d5b2d70266add6e4b571 lib/codeql/rust/elements/internal/ConstParamImpl.qll 909d85d857dfb973cd8e148744d3a88506d113d193d35ab0243be745d004ad45 c9e18170c5b4e4d5fca9f175bb139a248055b608ceafdd90c7182d06d67c3cba lib/codeql/rust/elements/internal/ContinueExprConstructor.qll cd93f1b35ccdb031d7e8deba92f6a76187f6009c454f3ea07e89ba459de57ca6 6f658e7d580c4c9068b01d6dd6f72888b8800860668a6653f8c3b27dc9996935 -lib/codeql/rust/elements/internal/ContinueExprImpl.qll 976890d17681315d2297b600a58c655ccc7c4db44cf587d7b5c359303f309acf 1ecae04df07ee20dcea4f00a9af33c108a0e15ed2ccf8b936804ad88ed66f883 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 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 8e15852654c4..e69d7ea5791b 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -185,7 +185,6 @@ /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/BreakExprImpl.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/CastExprConstructor.qll linguist-generated @@ -204,7 +203,6 @@ /lib/codeql/rust/elements/internal/ConstParamConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ConstParamImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ContinueExprConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/ContinueExprImpl.qll linguist-generated /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 diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 971e4910fabe..ea181764cefd 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -145,44 +145,26 @@ class BlockExprTree extends StandardPostOrderTree, BlockExpr { result = super.getStmtList().getTailExpr() } - override predicate propagatesAbnormal(AstNode child) { none() } - - /** Holds if this block captures the break completion `c`. */ - private predicate capturesBreakCompletion(LoopJumpCompletion c) { - c.isBreak() and - c.getLabelName() = this.getLabel().getLifetime().getText() - } - - override predicate succ(AstNode pred, AstNode succ, Completion c) { - super.succ(pred, succ, c) - or - // Edge for exiting the block with a break expressions - last(this.getChildNode(_), pred, c) and - this.capturesBreakCompletion(c) and - succ = this - } - - override predicate last(AstNode last, Completion c) { - super.last(last, c) - or - // Any abnormal completions that this block does not capture should propagate - last(this.getChildNode(_), last, c) and - not completionIsNormal(c) and - not this.capturesBreakCompletion(c) - } + override predicate propagatesAbnormal(AstNode child) { child = this.getChildNode(_) } } -class BreakExprTree extends PostOrderTree instanceof BreakExpr { - override predicate propagatesAbnormal(AstNode child) { child = super.getExpr() } +class BreakExprTree extends PostOrderTree, BreakExpr { + override predicate propagatesAbnormal(AstNode child) { child = this.getExpr() } override predicate first(AstNode node) { - first(super.getExpr(), node) + first(this.getExpr(), node) or - not super.hasExpr() and node = this + not this.hasExpr() and node = this } + override predicate last(AstNode last, Completion c) { none() } + override predicate succ(AstNode pred, AstNode succ, Completion c) { last(super.getExpr(), pred, c) and succ = this + or + pred = this and + c.isValidFor(pred) and + succ = this.getTarget() } } @@ -200,7 +182,18 @@ class CastExprTree extends StandardPostOrderTree instanceof CastExpr { class ClosureExprTree extends LeafTree instanceof ClosureExpr { } -class ContinueExprTree extends LeafTree instanceof ContinueExpr { } +class ContinueExprTree extends LeafTree, ContinueExpr { + override predicate last(AstNode last, Completion c) { none() } + + override predicate succ(AstNode pred, AstNode succ, Completion c) { + exists(Expr target | + pred = this and + c.isValidFor(pred) and + target = this.getTarget() and + first(target.(LoopingExprTree).getLoopContinue(), succ) + ) + } +} class ExprStmtTree extends StandardPreOrderTree instanceof ExprStmt { override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() } @@ -310,57 +303,27 @@ class LetStmtTree extends PreOrderTree instanceof LetStmt { class LiteralExprTree extends LeafTree instanceof LiteralExpr { } abstract class LoopingExprTree extends PostOrderTree { - override predicate propagatesAbnormal(AstNode child) { none() } + override predicate propagatesAbnormal(AstNode child) { child = this.getLoopBody() } abstract BlockExpr getLoopBody(); - abstract Label getLabel(); - /** * Gets the node to execute when continuing the loop; either after * executing the last node in the body or after an explicit `continue`. */ abstract AstNode getLoopContinue(); - /** Holds if this loop captures the `c` completion. */ - private predicate capturesLoopJumpCompletion(LoopJumpCompletion c) { - not c.hasLabel() - or - c.getLabelName() = this.getLabel().getLifetime().getText() - } - override predicate succ(AstNode pred, AstNode succ, Completion c) { - // Edge for exiting the loop with a break expressions - last(this.getLoopBody(), pred, c) and - c.(LoopJumpCompletion).isBreak() and - this.capturesLoopJumpCompletion(c) and - succ = this - or // Edge back to the start for final expression and continue expressions last(this.getLoopBody(), pred, c) and - ( - completionIsNormal(c) - or - c.(LoopJumpCompletion).isContinue() and this.capturesLoopJumpCompletion(c) - ) and + completionIsNormal(c) and first(this.getLoopContinue(), succ) } - - override predicate last(AstNode last, Completion c) { - super.last(last, c) - or - // Any abnormal completions that this loop does not capture should propagate - last(this.getLoopBody(), last, c) and - not completionIsNormal(c) and - not this.capturesLoopJumpCompletion(c) - } } class LoopExprTree extends LoopingExprTree instanceof LoopExpr { override BlockExpr getLoopBody() { result = LoopExpr.super.getLoopBody() } - override Label getLabel() { result = LoopExpr.super.getLabel() } - override AstNode getLoopContinue() { result = this.getLoopBody() } override predicate first(AstNode node) { first(this.getLoopBody(), node) } @@ -369,11 +332,13 @@ class LoopExprTree extends LoopingExprTree instanceof LoopExpr { class WhileExprTree extends LoopingExprTree instanceof WhileExpr { override BlockExpr getLoopBody() { result = WhileExpr.super.getLoopBody() } - override Label getLabel() { result = WhileExpr.super.getLabel() } - override AstNode getLoopContinue() { result = super.getCondition() } - override predicate propagatesAbnormal(AstNode child) { child = super.getCondition() } + override predicate propagatesAbnormal(AstNode child) { + super.propagatesAbnormal(child) + or + child = super.getCondition() + } override predicate first(AstNode node) { first(super.getCondition(), node) } @@ -399,11 +364,13 @@ class WhileExprTree extends LoopingExprTree instanceof WhileExpr { class ForExprTree extends LoopingExprTree instanceof ForExpr { override BlockExpr getLoopBody() { result = ForExpr.super.getLoopBody() } - override Label getLabel() { result = ForExpr.super.getLabel() } - override AstNode getLoopContinue() { result = super.getPat() } - override predicate propagatesAbnormal(AstNode child) { child = super.getIterable() } + override predicate propagatesAbnormal(AstNode child) { + super.propagatesAbnormal(child) + or + child = super.getIterable() + } override predicate first(AstNode node) { first(super.getIterable(), node) } diff --git a/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll index 031761d374ed..4b302674a444 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/BreakExprImpl.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 `BreakExpr`. * @@ -12,6 +11,58 @@ private import codeql.rust.elements.internal.generated.BreakExpr * be referenced directly. */ module Impl { + private import rust + private import codeql.rust.elements.internal.generated.ParentChild + + /** Holds if `e` is a loop labelled `label`. */ + pragma[nomagic] + predicate isLabelledLoop(Expr e, string label) { + e = + any(LoopExpr le | + label = le.getLabel().getLifetime().getText() + or + label = "" + ) + or + e = + any(ForExpr fe | + label = fe.getLabel().getLifetime().getText() + or + label = "" + ) + or + e = + any(WhileExpr we | + label = we.getLabel().getLifetime().getText() + or + label = "" + ) + } + + pragma[nomagic] + private predicate isLabelled(Expr e, string label) { + isLabelledLoop(e, label) + or + label = e.(BlockExpr).getLabel().getLifetime().getText() + } + + pragma[nomagic] + private AstNode getABreakAncestor(BreakExpr be, string label) { + ( + label = be.getLifetime().getText() + or + not be.hasLifetime() and + label = "" + ) and + exists(AstNode n0 | result = getImmediateParent(n0) | + n0 = be + or + n0 = getABreakAncestor(be, label) and + not isLabelled(n0, label) + ) + } + + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A break expression. For example: * ```rust @@ -37,5 +88,19 @@ module Impl { * }; * ``` */ - class BreakExpr extends Generated::BreakExpr { } + class BreakExpr extends Generated::BreakExpr { + /** + * Gets the target of this `break` expression. + * + * The target is either a `LoopExpr`, a `ForExpr`, a `WhileExpr`, or a + * `BlockExpr`. + */ + pragma[nomagic] + Expr getTarget() { + exists(string label | + result = getABreakAncestor(this, label) and + isLabelled(result, label) + ) + } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll index dd2476c79b7f..4328fdfc9f93 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ContinueExprImpl.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 `ContinueExpr`. * @@ -12,6 +11,26 @@ private import codeql.rust.elements.internal.generated.ContinueExpr * be referenced directly. */ module Impl { + private import codeql.rust.elements.internal.BreakExprImpl::Impl as BreakExprImpl + private import codeql.rust.elements.internal.generated.ParentChild + + pragma[nomagic] + private AstNode getAContinueAncestor(ContinueExpr ce, string label) { + ( + label = ce.getLifetime().getText() + or + not ce.hasLifetime() and + label = "" + ) and + exists(AstNode n0 | result = getImmediateParent(n0) | + n0 = ce + or + n0 = getAContinueAncestor(ce, label) and + not BreakExprImpl::isLabelledLoop(n0, label) + ) + } + + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A continue expression. For example: * ```rust @@ -29,5 +48,18 @@ module Impl { * } * ``` */ - class ContinueExpr extends Generated::ContinueExpr { } + class ContinueExpr extends Generated::ContinueExpr { + /** + * Gets the target of this `continue` expression. + * + * The target is either a `LoopExpr`, a `ForExpr`, or a `WhileExpr`. + */ + pragma[nomagic] + Expr getTarget() { + exists(string label | + result = getAContinueAncestor(this, label) and + BreakExprImpl::isLabelledLoop(result, label) + ) + } + } } diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 0e7bf44925cc..e2f3464800a0 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -1,3 +1,4 @@ +edges | test.rs:1:1:4:1 | enter test_call | test.rs:2:5:2:41 | ExprStmt | | | test.rs:1:1:4:1 | exit test_call (normal) | test.rs:1:1:4:1 | exit test_call | | | test.rs:1:24:4:1 | BlockExpr | test.rs:1:1:4:1 | exit test_call (normal) | | @@ -545,3 +546,25 @@ | test.rs:299:13:299:27 | ExprStmt | test.rs:299:26:299:26 | 1 | | | test.rs:299:26:299:26 | 1 | test.rs:299:13:299:26 | BreakExpr | | | test.rs:301:9:301:9 | x | test.rs:296:18:302:5 | BlockExpr | | +breakTarget +| test.rs:16:17:16:21 | BreakExpr | test.rs:10:9:22:9 | LoopExpr | +| test.rs:30:21:30:25 | BreakExpr | test.rs:28:13:35:13 | LoopExpr | +| test.rs:32:21:32:32 | BreakExpr | test.rs:27:9:36:9 | LoopExpr | +| test.rs:34:17:34:28 | BreakExpr | test.rs:28:13:35:13 | LoopExpr | +| test.rs:73:17:73:21 | BreakExpr | test.rs:70:9:76:9 | WhileExpr | +| test.rs:83:17:83:21 | BreakExpr | test.rs:81:9:85:9 | WhileExpr | +| test.rs:91:17:91:21 | BreakExpr | test.rs:89:9:94:9 | ForExpr | +| test.rs:170:17:170:28 | BreakExpr | test.rs:168:13:173:9 | LoopExpr | +| test.rs:183:17:183:35 | BreakExpr | test.rs:181:13:186:9 | LoopExpr | +| test.rs:195:13:195:30 | BreakExpr | test.rs:194:13:196:9 | BlockExpr | +| test.rs:284:13:284:26 | BreakExpr | test.rs:281:18:292:5 | BlockExpr | +| test.rs:288:13:288:26 | BreakExpr | test.rs:281:18:292:5 | BlockExpr | +| test.rs:299:13:299:26 | BreakExpr | test.rs:296:18:302:5 | BlockExpr | +continueTarget +| test.rs:19:17:19:24 | ContinueExpr | test.rs:10:9:22:9 | LoopExpr | +| test.rs:45:21:45:28 | ContinueExpr | test.rs:43:13:50:13 | LoopExpr | +| test.rs:47:21:47:35 | ContinueExpr | test.rs:41:9:51:9 | LoopExpr | +| test.rs:49:17:49:31 | ContinueExpr | test.rs:43:13:50:13 | LoopExpr | +| test.rs:59:21:59:28 | ContinueExpr | test.rs:57:13:64:13 | LoopExpr | +| test.rs:61:21:61:34 | ContinueExpr | test.rs:57:13:64:13 | LoopExpr | +| test.rs:63:17:63:30 | ContinueExpr | test.rs:57:13:64:13 | LoopExpr | diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected index 876e5fb52664..0a075ff054e3 100644 --- a/rust/ql/test/library-tests/variables/Cfg.expected +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -1,3 +1,4 @@ +edges | variables.rs:1:1:3:1 | enter print_str | variables.rs:2:5:2:22 | ExprStmt | | | variables.rs:1:1:3:1 | exit print_str (normal) | variables.rs:1:1:3:1 | exit print_str | | | variables.rs:1:23:3:1 | BlockExpr | variables.rs:1:1:3:1 | exit print_str (normal) | | @@ -592,3 +593,5 @@ | variables.rs:340:5:340:16 | PathExpr | variables.rs:340:5:340:18 | CallExpr | | | variables.rs:340:5:340:18 | CallExpr | variables.rs:318:11:341:1 | BlockExpr | | | variables.rs:340:5:340:19 | ExprStmt | variables.rs:340:5:340:16 | PathExpr | | +breakTarget +continueTarget diff --git a/rust/ql/test/utils/Cfg.ql b/rust/ql/test/utils/Cfg.ql index 23b047b5b2ec..ee9a967553d1 100644 --- a/rust/ql/test/utils/Cfg.ql +++ b/rust/ql/test/utils/Cfg.ql @@ -7,3 +7,7 @@ class MyRelevantNode extends CfgNode { } import codeql.rust.controlflow.internal.ControlFlowGraphImpl::TestOutput + +query predicate breakTarget(BreakExpr be, Expr target) { target = be.getTarget() } + +query predicate continueTarget(ContinueExpr ce, Expr target) { target = ce.getTarget() } From 6da39724335f9ac1e58f57333b4dd65621ba0337 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Oct 2024 15:02:26 +0200 Subject: [PATCH 126/347] Rust: Simplify break/continue CFG labels --- .../rust/controlflow/ControlFlowGraph.qll | 4 +- .../rust/controlflow/internal/Completion.qll | 52 +++++-------------- .../internal/ControlFlowGraphImpl.qll | 9 ++-- .../controlflow/internal/SuccessorType.qll | 32 ++++-------- .../library-tests/controlflow/Cfg.expected | 22 ++++---- 5 files changed, 42 insertions(+), 77 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/ControlFlowGraph.qll b/rust/ql/lib/codeql/rust/controlflow/ControlFlowGraph.qll index 18159ccea748..20f1af4a4afb 100644 --- a/rust/ql/lib/codeql/rust/controlflow/ControlFlowGraph.qll +++ b/rust/ql/lib/codeql/rust/controlflow/ControlFlowGraph.qll @@ -19,7 +19,9 @@ final class BooleanSuccessor = BooleanSuccessorImpl; final class MatchSuccessor = MatchSuccessorImpl; -final class LoopJumpSuccessor = LoopJumpSuccessorImpl; +final class BreakSuccessor = BreakSuccessorImpl; + +final class ContinueSuccessor = ContinueSuccessorImpl; final class ReturnSuccessor = ReturnSuccessorImpl; diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll index 4034db5fe288..15619f06a2fe 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll @@ -7,13 +7,8 @@ newtype TCompletion = TSimpleCompletion() or TBooleanCompletion(Boolean b) or TMatchCompletion(Boolean isMatch) or - TLoopCompletion(TLoopJumpType kind, TLabelType label) { - label = TNoLabel() - or - kind = TBreakJump() and label = TLabel(any(BreakExpr b).getLifetime().getText()) - or - kind = TContinueJump() and label = TLabel(any(ContinueExpr b).getLifetime().getText()) - } or + TBreakCompletion() or + TContinueCompletion() or TReturnCompletion() /** A completion of a statement or an expression. */ @@ -148,42 +143,23 @@ class MatchCompletion extends TMatchCompletion, ConditionalCompletion { } /** - * A completion that represents a break or a continue. + * A completion that represents a `break`. */ -class LoopJumpCompletion extends TLoopCompletion, Completion { - override LoopJumpSuccessor getAMatchingSuccessorType() { - result = TLoopSuccessor(this.getKind(), this.getLabelType()) - } - - final TLoopJumpType getKind() { this = TLoopCompletion(result, _) } - - final TLabelType getLabelType() { this = TLoopCompletion(_, result) } +class BreakCompletion extends TBreakCompletion, Completion { + override BreakSuccessor getAMatchingSuccessorType() { any() } - final predicate hasLabel() { this.getLabelType() = TLabel(_) } + override predicate isValidForSpecific(AstNode e) { e instanceof BreakExpr } - final string getLabelName() { TLabel(result) = this.getLabelType() } - - final predicate isContinue() { this.getKind() = TContinueJump() } + override string toString() { result = this.getAMatchingSuccessorType().toString() } +} - final predicate isBreak() { this.getKind() = TBreakJump() } +/** + * A completion that represents a `continue`. + */ +class ContinueCompletion extends TContinueCompletion, Completion { + override ContinueSuccessor getAMatchingSuccessorType() { any() } - override predicate isValidForSpecific(AstNode e) { - this.isBreak() and - e instanceof BreakExpr and - ( - not e.(BreakExpr).hasLifetime() and not this.hasLabel() - or - e.(BreakExpr).getLifetime().getText() = this.getLabelName() - ) - or - this.isContinue() and - e instanceof ContinueExpr and - ( - not e.(ContinueExpr).hasLifetime() and not this.hasLabel() - or - e.(ContinueExpr).getLifetime().getText() = this.getLabelName() - ) - } + override predicate isValidForSpecific(AstNode e) { e instanceof ContinueExpr } override string toString() { result = this.getAMatchingSuccessorType().toString() } } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index ea181764cefd..17add12b9404 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -186,12 +186,9 @@ class ContinueExprTree extends LeafTree, ContinueExpr { override predicate last(AstNode last, Completion c) { none() } override predicate succ(AstNode pred, AstNode succ, Completion c) { - exists(Expr target | - pred = this and - c.isValidFor(pred) and - target = this.getTarget() and - first(target.(LoopingExprTree).getLoopContinue(), succ) - ) + pred = this and + c.isValidFor(pred) and + first(this.getTarget().(LoopingExprTree).getLoopContinue(), succ) } } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/SuccessorType.qll b/rust/ql/lib/codeql/rust/controlflow/internal/SuccessorType.qll index 6bdd54c263dd..ba76888bd303 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/SuccessorType.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/SuccessorType.qll @@ -15,7 +15,8 @@ newtype TSuccessorType = TSuccessorSuccessor() or TBooleanSuccessor(Boolean b) or TMatchSuccessor(Boolean b) or - TLoopSuccessor(TLoopJumpType kind, TLabelType label) { exists(TLoopCompletion(kind, label)) } or + TBreakSuccessor() or + TContinueSuccessor() or TReturnSuccessor() /** The type of a control flow successor. */ @@ -59,28 +60,17 @@ class MatchSuccessorImpl extends ConditionalSuccessorImpl, TMatchSuccessor { } /** - * A control flow successor of a loop control flow expression, `continue` or `break`. + * A control flow successor of a `break` expression. */ -class LoopJumpSuccessorImpl extends SuccessorTypeImpl, TLoopSuccessor { - private TLoopJumpType getKind() { this = TLoopSuccessor(result, _) } - - private TLabelType getLabelType() { this = TLoopSuccessor(_, result) } - - predicate hasLabel() { this.getLabelType() = TLabel(_) } - - string getLabelName() { this = TLoopSuccessor(_, TLabel(result)) } - - predicate isContinue() { this.getKind() = TContinueJump() } - - predicate isBreak() { this.getKind() = TBreakJump() } +class BreakSuccessorImpl extends SuccessorTypeImpl, TBreakSuccessor { + override string toString() { result = "break" } +} - override string toString() { - exists(string kind, string label | - (if this.isContinue() then kind = "continue" else kind = "break") and - (if this.hasLabel() then label = "(" + this.getLabelName() + ")" else label = "") and - result = kind + label - ) - } +/** + * A control flow successor of a `continue` expression. + */ +class ContinueSuccessorImpl extends SuccessorTypeImpl, TContinueSuccessor { + override string toString() { result = "continue" } } /** diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index e2f3464800a0..39fc6b96b621 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -77,9 +77,9 @@ edges | test.rs:31:24:33:17 | IfExpr | test.rs:29:17:33:17 | IfExpr | | | test.rs:31:27:31:27 | b | test.rs:31:24:33:17 | IfExpr | false | | test.rs:31:27:31:27 | b | test.rs:32:21:32:33 | ExprStmt | true | -| test.rs:32:21:32:32 | BreakExpr | test.rs:27:9:36:9 | LoopExpr | break('outer) | +| test.rs:32:21:32:32 | BreakExpr | test.rs:27:9:36:9 | LoopExpr | break | | test.rs:32:21:32:33 | ExprStmt | test.rs:32:21:32:32 | BreakExpr | | -| test.rs:34:17:34:28 | BreakExpr | test.rs:28:13:35:13 | LoopExpr | break('inner) | +| test.rs:34:17:34:28 | BreakExpr | test.rs:28:13:35:13 | LoopExpr | break | | test.rs:34:17:34:29 | ExprStmt | test.rs:34:17:34:28 | BreakExpr | | | test.rs:37:9:37:12 | true | test.rs:26:48:38:5 | BlockExpr | | | test.rs:40:5:52:5 | enter test_continue_with_labels | test.rs:42:13:42:14 | ExprStmt | | @@ -94,9 +94,9 @@ edges | test.rs:46:24:48:17 | IfExpr | test.rs:44:17:48:17 | IfExpr | | | test.rs:46:27:46:27 | b | test.rs:46:24:48:17 | IfExpr | false | | test.rs:46:27:46:27 | b | test.rs:47:21:47:36 | ExprStmt | true | -| test.rs:47:21:47:35 | ContinueExpr | test.rs:42:13:42:14 | ExprStmt | continue('outer) | +| test.rs:47:21:47:35 | ContinueExpr | test.rs:42:13:42:14 | ExprStmt | continue | | test.rs:47:21:47:36 | ExprStmt | test.rs:47:21:47:35 | ContinueExpr | | -| test.rs:49:17:49:31 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | continue('inner) | +| test.rs:49:17:49:31 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | continue | | test.rs:49:17:49:32 | ExprStmt | test.rs:49:17:49:31 | ContinueExpr | | | test.rs:54:5:66:5 | enter test_loop_label_shadowing | test.rs:56:13:56:14 | ExprStmt | | | test.rs:56:13:56:13 | 1 | test.rs:58:17:62:17 | ExprStmt | | @@ -110,9 +110,9 @@ edges | test.rs:60:24:62:17 | IfExpr | test.rs:58:17:62:17 | IfExpr | | | test.rs:60:27:60:27 | b | test.rs:60:24:62:17 | IfExpr | false | | test.rs:60:27:60:27 | b | test.rs:61:21:61:35 | ExprStmt | true | -| test.rs:61:21:61:34 | ContinueExpr | test.rs:58:17:62:17 | ExprStmt | continue('loop) | +| test.rs:61:21:61:34 | ContinueExpr | test.rs:58:17:62:17 | ExprStmt | continue | | test.rs:61:21:61:35 | ExprStmt | test.rs:61:21:61:34 | ContinueExpr | | -| test.rs:63:17:63:30 | ContinueExpr | test.rs:58:17:62:17 | ExprStmt | continue('loop) | +| test.rs:63:17:63:30 | ContinueExpr | test.rs:58:17:62:17 | ExprStmt | continue | | test.rs:63:17:63:31 | ExprStmt | test.rs:63:17:63:30 | ContinueExpr | | | test.rs:68:5:77:5 | enter test_while | test.rs:69:9:69:25 | LetStmt | | | test.rs:68:5:77:5 | exit test_while (normal) | test.rs:68:5:77:5 | exit test_while | | @@ -338,7 +338,7 @@ edges | test.rs:182:16:182:20 | ... > ... | test.rs:182:13:184:13 | IfExpr | false | | test.rs:182:16:182:20 | ... > ... | test.rs:183:17:183:36 | ExprStmt | true | | test.rs:182:20:182:20 | 0 | test.rs:182:16:182:20 | ... > ... | | -| test.rs:183:17:183:35 | BreakExpr | test.rs:181:13:186:9 | LoopExpr | break('label) | +| test.rs:183:17:183:35 | BreakExpr | test.rs:181:13:186:9 | LoopExpr | break | | test.rs:183:17:183:36 | ExprStmt | test.rs:183:30:183:30 | a | | | test.rs:183:30:183:30 | a | test.rs:183:34:183:35 | 10 | | | test.rs:183:30:183:35 | ... > ... | test.rs:183:17:183:35 | BreakExpr | | @@ -357,7 +357,7 @@ edges | test.rs:194:9:200:9 | IfExpr | test.rs:193:43:201:5 | BlockExpr | | | test.rs:194:13:196:9 | BlockExpr | test.rs:197:13:197:13 | 1 | true | | test.rs:194:13:196:9 | BlockExpr | test.rs:199:13:199:13 | 0 | false | -| test.rs:195:13:195:30 | BreakExpr | test.rs:194:13:196:9 | BlockExpr | break('block) | +| test.rs:195:13:195:30 | BreakExpr | test.rs:194:13:196:9 | BlockExpr | break | | test.rs:195:13:195:31 | ExprStmt | test.rs:195:26:195:26 | a | | | test.rs:195:26:195:26 | a | test.rs:195:30:195:30 | 0 | | | test.rs:195:26:195:30 | ... > ... | test.rs:195:13:195:30 | BreakExpr | | @@ -511,7 +511,7 @@ edges | test.rs:283:12:283:28 | PathExpr | test.rs:283:12:283:30 | CallExpr | | | test.rs:283:12:283:30 | CallExpr | test.rs:283:9:285:9 | IfExpr | false | | test.rs:283:12:283:30 | CallExpr | test.rs:284:13:284:27 | ExprStmt | true | -| test.rs:284:13:284:26 | BreakExpr | test.rs:281:18:292:5 | BlockExpr | break('block) | +| test.rs:284:13:284:26 | BreakExpr | test.rs:281:18:292:5 | BlockExpr | break | | test.rs:284:13:284:27 | ExprStmt | test.rs:284:26:284:26 | 1 | | | test.rs:284:26:284:26 | 1 | test.rs:284:13:284:26 | BreakExpr | | | test.rs:286:9:286:21 | PathExpr | test.rs:286:9:286:23 | CallExpr | | @@ -522,7 +522,7 @@ edges | test.rs:287:12:287:28 | PathExpr | test.rs:287:12:287:30 | CallExpr | | | test.rs:287:12:287:30 | CallExpr | test.rs:287:9:289:9 | IfExpr | false | | test.rs:287:12:287:30 | CallExpr | test.rs:288:13:288:27 | ExprStmt | true | -| test.rs:288:13:288:26 | BreakExpr | test.rs:281:18:292:5 | BlockExpr | break('block) | +| test.rs:288:13:288:26 | BreakExpr | test.rs:281:18:292:5 | BlockExpr | break | | test.rs:288:13:288:27 | ExprStmt | test.rs:288:26:288:26 | 2 | | | test.rs:288:26:288:26 | 2 | test.rs:288:13:288:26 | BreakExpr | | | test.rs:290:9:290:21 | PathExpr | test.rs:290:9:290:23 | CallExpr | | @@ -542,7 +542,7 @@ edges | test.rs:298:13:298:19 | TupleStructPat | test.rs:299:13:299:27 | ExprStmt | no-match | | test.rs:298:13:298:19 | TupleStructPat | test.rs:301:9:301:9 | x | match | | test.rs:298:23:298:23 | x | test.rs:298:13:298:19 | TupleStructPat | | -| test.rs:299:13:299:26 | BreakExpr | test.rs:296:18:302:5 | BlockExpr | break('block) | +| test.rs:299:13:299:26 | BreakExpr | test.rs:296:18:302:5 | BlockExpr | break | | test.rs:299:13:299:27 | ExprStmt | test.rs:299:26:299:26 | 1 | | | test.rs:299:26:299:26 | 1 | test.rs:299:13:299:26 | BreakExpr | | | test.rs:301:9:301:9 | x | test.rs:296:18:302:5 | BlockExpr | | From 05d2e16de37fc6a004e9f86acd02bd87d37d3ac7 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 2 Oct 2024 15:25:36 +0100 Subject: [PATCH 127/347] autoformat --- go/ql/integration-tests/test-extraction/src/pkg1/def.go | 2 +- go/ql/integration-tests/test-extraction/test.expected | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/ql/integration-tests/test-extraction/src/pkg1/def.go b/go/ql/integration-tests/test-extraction/src/pkg1/def.go index 2492919f76df..e768e81b89d4 100644 --- a/go/ql/integration-tests/test-extraction/src/pkg1/def.go +++ b/go/ql/integration-tests/test-extraction/src/pkg1/def.go @@ -4,4 +4,4 @@ type Generic[T any] struct { element T } -func TestMe() { } +func TestMe() {} diff --git a/go/ql/integration-tests/test-extraction/test.expected b/go/ql/integration-tests/test-extraction/test.expected index eda27075ad43..77983c448071 100644 --- a/go/ql/integration-tests/test-extraction/test.expected +++ b/go/ql/integration-tests/test-extraction/test.expected @@ -7,8 +7,8 @@ | src/testme_blackbox_test.go:0:0:0:0 | src/testme_blackbox_test.go | | src/testme_test.go:0:0:0:0 | src/testme_test.go | calls -| src/pkg1/def_blackbox_test.go:8:2:8:14 | call to TestMe | src/pkg1/def.go:7:1:7:17 | function declaration | -| src/pkg1/def_test.go:4:2:4:9 | call to TestMe | src/pkg1/def.go:7:1:7:17 | function declaration | +| src/pkg1/def_blackbox_test.go:8:2:8:14 | call to TestMe | src/pkg1/def.go:7:1:7:16 | function declaration | +| src/pkg1/def_test.go:4:2:4:9 | call to TestMe | src/pkg1/def.go:7:1:7:16 | function declaration | | src/testme_blackbox_test.go:10:18:10:44 | call to PublicFunction | src/testme.go:3:1:3:38 | function declaration | | src/testme_test.go:9:18:9:33 | call to PublicFunction | src/testme.go:3:1:3:38 | function declaration | | src/testme_test.go:14:19:14:35 | call to privateFunction | src/testme.go:5:1:5:39 | function declaration | From 8c87b66bea97e8f379062f1be06f576fd0e428a5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 2 Oct 2024 16:50:24 +0100 Subject: [PATCH 128/347] Rust: Add more test cases for comments. --- .../diagnostics/ExtractedFiles.expected | 1 + .../diagnostics/LinesOfCode.expected | 2 +- .../diagnostics/LinesOfUserCode.expected | 2 +- .../LinesOfUserCodeInFiles.expected | 5 +- .../diagnostics/SummaryStats.expected | 8 +-- .../test/query-tests/diagnostics/comments.rs | 60 +++++++++++++++++++ rust/ql/test/query-tests/diagnostics/main.rs | 9 ++- 7 files changed, 74 insertions(+), 13 deletions(-) create mode 100644 rust/ql/test/query-tests/diagnostics/comments.rs diff --git a/rust/ql/test/query-tests/diagnostics/ExtractedFiles.expected b/rust/ql/test/query-tests/diagnostics/ExtractedFiles.expected index cc6f775e86d5..c5ebb7072304 100644 --- a/rust/ql/test/query-tests/diagnostics/ExtractedFiles.expected +++ b/rust/ql/test/query-tests/diagnostics/ExtractedFiles.expected @@ -1,3 +1,4 @@ +| comments.rs:0:0:0:0 | comments.rs | File successfully extracted. | | does_not_compile.rs:0:0:0:0 | does_not_compile.rs | File successfully extracted. | | error.rs:0:0:0:0 | error.rs | File successfully extracted. | | lib.rs:0:0:0:0 | lib.rs | File successfully extracted. | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected b/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected index 3885b955c3f3..f57679361dc0 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected @@ -1 +1 @@ -| 46 | +| 68 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected index 3885b955c3f3..f57679361dc0 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected @@ -1 +1 @@ -| 46 | +| 68 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected index 52ee2055e8fe..1b0edb495195 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected @@ -1,6 +1,7 @@ +| comments.rs:0:0:0:0 | comments.rs | 20 | | my_struct.rs:0:0:0:0 | my_struct.rs | 20 | -| main.rs:0:0:0:0 | main.rs | 7 | +| main.rs:0:0:0:0 | main.rs | 8 | +| lib.rs:0:0:0:0 | lib.rs | 7 | | my_macro.rs:0:0:0:0 | my_macro.rs | 7 | -| lib.rs:0:0:0:0 | lib.rs | 6 | | 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 da1e6cd7b60c..a39ccb0b44c5 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -1,5 +1,5 @@ -| Elements extracted | 216 | +| Elements extracted | 290 | | Elements unextracted | 0 | -| Files extracted | 6 | -| Lines of code extracted | 46 | -| Lines of user code extracted | 46 | +| Files extracted | 7 | +| Lines of code extracted | 68 | +| Lines of user code extracted | 68 | diff --git a/rust/ql/test/query-tests/diagnostics/comments.rs b/rust/ql/test/query-tests/diagnostics/comments.rs new file mode 100644 index 000000000000..bec721eed25f --- /dev/null +++ b/rust/ql/test/query-tests/diagnostics/comments.rs @@ -0,0 +1,60 @@ +/** + * total lines in this file: 61 + * of which code: 16 + * of which only comments: 33 + * of which blank: 12 + */ + +// a comment + +/** + * Comment attached to a struct. + */ +struct StructWithComments +{ + /** + * Another attached comment. + */ + a: i32, + + // And another attached comment. + b: i32, + + /* + * And yet another attached comment. + */ + c: i32, + + // informal + // comment + // block. + cd: i32, + + // Just a comment. +} + +pub fn my_simple_func() +{ +} + +/** + * Comment attached to a function. + */ +pub fn my_func_with_comments() +{ + // comment + let a = 1; // comment + // comment + let b = 2; + + // comment + + /* + * Comment. + */ + my_simple_func(); +} + +/** + * Comment. + */ diff --git a/rust/ql/test/query-tests/diagnostics/main.rs b/rust/ql/test/query-tests/diagnostics/main.rs index 6e0ddf695a3a..07dd4234a6e7 100644 --- a/rust/ql/test/query-tests/diagnostics/main.rs +++ b/rust/ql/test/query-tests/diagnostics/main.rs @@ -1,16 +1,15 @@ /** * total lines in this file: 18 - * of which code: 7 - * of which only comments: 7 + * of which code: 8 + * of which only comments: 6 * of which blank: 4 */ mod my_struct; mod my_macro; +mod comments; -// another comment - -fn main() { // another comment +fn main() { println!("Hello, world!"); my_struct::my_func(); From 01abcf8537f297ab169a5848803408065a041006 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 2 Oct 2024 16:54:02 +0100 Subject: [PATCH 129/347] Rust: Use just end locations for now, to avoid all false positive lines caused by attached comments. --- rust/ql/lib/codeql/files/FileSystem.qll | 3 +-- rust/ql/test/query-tests/diagnostics/LinesOfCode.expected | 2 +- rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected | 2 +- .../query-tests/diagnostics/LinesOfUserCodeInFiles.expected | 2 +- rust/ql/test/query-tests/diagnostics/SummaryStats.expected | 4 ++-- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/rust/ql/lib/codeql/files/FileSystem.qll b/rust/ql/lib/codeql/files/FileSystem.qll index 03b5cd0b183b..b78a993cb7e7 100644 --- a/rust/ql/lib/codeql/files/FileSystem.qll +++ b/rust/ql/lib/codeql/files/FileSystem.qll @@ -47,11 +47,10 @@ class File extends Container, Impl::File { exists(AstNode node, Location loc | not node instanceof Comment and not node instanceof SourceFile and - not node instanceof Item and // ignore Items for now as we're getting their locations wrong when a comment is attached loc = node.getLocation() | node.getFile() = this and - line = [loc.getStartLine(), loc.getEndLine()] and + line = [/*loc.getStartLine(), */loc.getEndLine()] and // ignore start locations for now as we're getting them wrong for things with a comment attached not loc instanceof EmptyLocation ) ) diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected b/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected index f57679361dc0..bf709e1ddc4d 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfCode.expected @@ -1 +1 @@ -| 68 | +| 61 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected index f57679361dc0..bf709e1ddc4d 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCode.expected @@ -1 +1 @@ -| 68 | +| 61 | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected index 1b0edb495195..b93473f7e04a 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected @@ -1,5 +1,5 @@ -| comments.rs:0:0:0:0 | comments.rs | 20 | | 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 | | lib.rs:0:0:0:0 | lib.rs | 7 | | my_macro.rs:0:0:0:0 | my_macro.rs | 7 | diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index a39ccb0b44c5..d9142bcadfed 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -1,5 +1,5 @@ | Elements extracted | 290 | | Elements unextracted | 0 | | Files extracted | 7 | -| Lines of code extracted | 68 | -| Lines of user code extracted | 68 | +| Lines of code extracted | 61 | +| Lines of user code extracted | 61 | From d6848f5c5d9ce2cdfb1eb149765ef82081923d70 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 2 Oct 2024 17:00:28 +0100 Subject: [PATCH 130/347] Rust: Apparently a doc comment here was illegal. --- rust/ql/test/query-tests/diagnostics/comments.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/test/query-tests/diagnostics/comments.rs b/rust/ql/test/query-tests/diagnostics/comments.rs index bec721eed25f..fe99fdd4e3e3 100644 --- a/rust/ql/test/query-tests/diagnostics/comments.rs +++ b/rust/ql/test/query-tests/diagnostics/comments.rs @@ -55,6 +55,6 @@ pub fn my_func_with_comments() my_simple_func(); } -/** +/* * Comment. */ From 0b6ec4624eeaf27f0d4fd715f8beb7ec9252f924 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 2 Oct 2024 17:05:01 +0100 Subject: [PATCH 131/347] Rust: Autoformat. --- rust/ql/lib/codeql/files/FileSystem.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/files/FileSystem.qll b/rust/ql/lib/codeql/files/FileSystem.qll index b78a993cb7e7..95ca925a8840 100644 --- a/rust/ql/lib/codeql/files/FileSystem.qll +++ b/rust/ql/lib/codeql/files/FileSystem.qll @@ -50,7 +50,7 @@ class File extends Container, Impl::File { loc = node.getLocation() | node.getFile() = this and - line = [/*loc.getStartLine(), */loc.getEndLine()] and // ignore start locations for now as we're getting them wrong for things with a comment attached + line = [/*loc.getStartLine(), */ loc.getEndLine()] and // ignore start locations for now as we're getting them wrong for things with a comment attached not loc instanceof EmptyLocation ) ) From ba9c2f1e3a743bb9efdd1010605ff50c90acb7a7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:31:14 +0100 Subject: [PATCH 132/347] Rust: Add extractor warnings query. --- rust/ql/lib/codeql/rust/Diagnostics.qll | 5 +++++ .../queries/diagnostics/ExtractionWarnings.ql | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 rust/ql/src/queries/diagnostics/ExtractionWarnings.ql diff --git a/rust/ql/lib/codeql/rust/Diagnostics.qll b/rust/ql/lib/codeql/rust/Diagnostics.qll index 5902bb594141..8c207e708889 100644 --- a/rust/ql/lib/codeql/rust/Diagnostics.qll +++ b/rust/ql/lib/codeql/rust/Diagnostics.qll @@ -52,3 +52,8 @@ class Diagnostic extends @diagnostic { class ExtractionError extends Diagnostic { ExtractionError() { this.getTag() = "parse_error" } } + +/** A diagnostic that is warning severity. */ +class ExtractionWarning extends Diagnostic { + ExtractionWarning() { this.getSeverity() = 30 } +} diff --git a/rust/ql/src/queries/diagnostics/ExtractionWarnings.ql b/rust/ql/src/queries/diagnostics/ExtractionWarnings.ql new file mode 100644 index 000000000000..99773cc6d53a --- /dev/null +++ b/rust/ql/src/queries/diagnostics/ExtractionWarnings.ql @@ -0,0 +1,19 @@ +/** + * @name Extraction warnings + * @description List all extraction warnings for files in the source code directory. + * @kind diagnostic + * @id rust/diagnostics/extraction-warnings + */ + +import codeql.rust.Diagnostics +import codeql.files.FileSystem + +/** Gets the SARIF severity to associate with a warning. */ +int getSeverity() { result = 1 } + +from ExtractionWarning warning, File f +where + f = warning.getLocation().getFile() and + exists(f.getRelativePath()) +select warning, "Extraction warning in " + f + " with message " + warning.getMessage(), + getSeverity() From f30a642c8fcc9b8c34493ea170b41fb38c91e93b Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:40:26 +0100 Subject: [PATCH 133/347] Rust: Add a test for the extractor warnings query. --- .../query-tests/diagnostics/ExtractionWarnings.expected | 6 ++++++ .../test/query-tests/diagnostics/ExtractionWarnings.qlref | 1 + 2 files changed, 7 insertions(+) create mode 100644 rust/ql/test/query-tests/diagnostics/ExtractionWarnings.expected create mode 100644 rust/ql/test/query-tests/diagnostics/ExtractionWarnings.qlref diff --git a/rust/ql/test/query-tests/diagnostics/ExtractionWarnings.expected b/rust/ql/test/query-tests/diagnostics/ExtractionWarnings.expected new file mode 100644 index 000000000000..0a68f2bce0ef --- /dev/null +++ b/rust/ql/test/query-tests/diagnostics/ExtractionWarnings.expected @@ -0,0 +1,6 @@ +| does_not_compile.rs:2:6:2:5 | expected SEMICOLON | Extraction warning in does_not_compile.rs with message expected SEMICOLON | 1 | +| does_not_compile.rs:2:9:2:8 | expected SEMICOLON | Extraction warning in does_not_compile.rs with message expected SEMICOLON | 1 | +| 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 | diff --git a/rust/ql/test/query-tests/diagnostics/ExtractionWarnings.qlref b/rust/ql/test/query-tests/diagnostics/ExtractionWarnings.qlref new file mode 100644 index 000000000000..ff6e566d20a7 --- /dev/null +++ b/rust/ql/test/query-tests/diagnostics/ExtractionWarnings.qlref @@ -0,0 +1 @@ +queries/diagnostics/ExtractionWarnings.ql From ad7c96554fbf05eb7b0519672ad2bcb84f95ad83 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:29:47 +0100 Subject: [PATCH 134/347] Rust: Correct extraction errors query to output only errors. --- rust/ql/lib/codeql/rust/Diagnostics.qll | 4 ++-- rust/ql/src/queries/diagnostics/ExtractionErrors.ql | 2 +- .../test/query-tests/diagnostics/ExtractionErrors.expected | 6 ------ 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/rust/ql/lib/codeql/rust/Diagnostics.qll b/rust/ql/lib/codeql/rust/Diagnostics.qll index 8c207e708889..8f77b64c5123 100644 --- a/rust/ql/lib/codeql/rust/Diagnostics.qll +++ b/rust/ql/lib/codeql/rust/Diagnostics.qll @@ -48,9 +48,9 @@ class Diagnostic extends @diagnostic { string toString() { result = this.getMessage() } } -/** A diagnostic relating to a particular error in extracting a file. */ +/** A diagnostic that is error severity. */ class ExtractionError extends Diagnostic { - ExtractionError() { this.getTag() = "parse_error" } + ExtractionError() { this.getSeverity() = 40 } } /** A diagnostic that is warning severity. */ diff --git a/rust/ql/src/queries/diagnostics/ExtractionErrors.ql b/rust/ql/src/queries/diagnostics/ExtractionErrors.ql index a04c4e618c41..68be66f8ca9b 100644 --- a/rust/ql/src/queries/diagnostics/ExtractionErrors.ql +++ b/rust/ql/src/queries/diagnostics/ExtractionErrors.ql @@ -8,7 +8,7 @@ import codeql.rust.Diagnostics import codeql.files.FileSystem -/** Gets the SARIF severity to associate an error. */ +/** Gets the SARIF severity to associate with an error. */ int getSeverity() { result = 2 } from ExtractionError error, File f diff --git a/rust/ql/test/query-tests/diagnostics/ExtractionErrors.expected b/rust/ql/test/query-tests/diagnostics/ExtractionErrors.expected index b6aaf7b6d373..e69de29bb2d1 100644 --- a/rust/ql/test/query-tests/diagnostics/ExtractionErrors.expected +++ b/rust/ql/test/query-tests/diagnostics/ExtractionErrors.expected @@ -1,6 +0,0 @@ -| does_not_compile.rs:2:6:2:5 | expected SEMICOLON | Extraction failed in does_not_compile.rs with error expected SEMICOLON | 2 | -| does_not_compile.rs:2:9:2:8 | expected SEMICOLON | Extraction failed in does_not_compile.rs with error expected SEMICOLON | 2 | -| does_not_compile.rs:2:13:2:12 | expected SEMICOLON | Extraction failed in does_not_compile.rs with error expected SEMICOLON | 2 | -| does_not_compile.rs:2:21:2:20 | expected SEMICOLON | Extraction failed in does_not_compile.rs with error expected SEMICOLON | 2 | -| does_not_compile.rs:2:26:2:25 | expected SEMICOLON | Extraction failed in does_not_compile.rs with error expected SEMICOLON | 2 | -| does_not_compile.rs:2:32:2:31 | expected field name or number | Extraction failed in does_not_compile.rs with error expected field name or number | 2 | From 12fbd18f3a9c8a08f548942ab732e565c8f3f7c2 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:32:25 +0100 Subject: [PATCH 135/347] Rust: Have ExtractionConsistency.ql report both. --- rust/ql/consistency-queries/ExtractionConsistency.ql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rust/ql/consistency-queries/ExtractionConsistency.ql b/rust/ql/consistency-queries/ExtractionConsistency.ql index b839f2ad783c..20148f0cea2d 100644 --- a/rust/ql/consistency-queries/ExtractionConsistency.ql +++ b/rust/ql/consistency-queries/ExtractionConsistency.ql @@ -1,3 +1,5 @@ import codeql.rust.Diagnostics query predicate extractionError(ExtractionError ee) { any() } + +query predicate extractionWarning(ExtractionWarning ew) { any() } From a4c06b2bbcb4c1942505e123546225142191aa9f Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:23:25 +0100 Subject: [PATCH 136/347] Rust: Define SuccessfullyExtractedFile and use it to simplify queries. --- rust/ql/lib/codeql/files/FileSystem.qll | 18 ++++++++++++++++++ .../NumberOfFilesExtractedWithErrors.ql | 7 ++++--- .../NumberOfSuccessfullyExtractedFiles.ql | 7 ++----- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/rust/ql/lib/codeql/files/FileSystem.qll b/rust/ql/lib/codeql/files/FileSystem.qll index ee7a2235476e..fd7ad56c74a0 100644 --- a/rust/ql/lib/codeql/files/FileSystem.qll +++ b/rust/ql/lib/codeql/files/FileSystem.qll @@ -5,6 +5,7 @@ private import codeql.util.FileSystem private import codeql.rust.elements.SourceFile private import codeql.rust.elements.AstNode private import codeql.rust.elements.Comment +private import codeql.rust.Diagnostics private module Input implements InputSig { abstract class ContainerBase extends @container { @@ -56,3 +57,20 @@ class File extends Container, Impl::File { ) } } + +/** + * A successfully extracted file, that is, a file that was extracted and + * contains no extraction errors or warnings. + */ +class SuccessfullyExtractedFile extends File { + SuccessfullyExtractedFile() { + not exists(Diagnostic d | + d.getLocation().getFile() = this and + ( + d instanceof ExtractionError + or + d instanceof ExtractionWarning + ) + ) + } +} diff --git a/rust/ql/src/queries/summary/NumberOfFilesExtractedWithErrors.ql b/rust/ql/src/queries/summary/NumberOfFilesExtractedWithErrors.ql index 1af3f0f88ec0..23db30f53e96 100644 --- a/rust/ql/src/queries/summary/NumberOfFilesExtractedWithErrors.ql +++ b/rust/ql/src/queries/summary/NumberOfFilesExtractedWithErrors.ql @@ -2,14 +2,15 @@ * @id rust/summary/number-of-files-extracted-with-errors * @name Total number of Rust files that were extracted with errors * @description The total number of Rust files in the source code directory that - * were extracted, but where at least one extraction error occurred in the process. + * were extracted, but where at least one extraction error (or warning) occurred + * in the process. * @kind metric * @tags summary */ import codeql.files.FileSystem -import codeql.rust.Diagnostics select count(File f | - exists(ExtractionError e | e.getLocation().getFile() = f) and exists(f.getRelativePath()) + exists(f.getRelativePath()) and + not f instanceof SuccessfullyExtractedFile ) diff --git a/rust/ql/src/queries/summary/NumberOfSuccessfullyExtractedFiles.ql b/rust/ql/src/queries/summary/NumberOfSuccessfullyExtractedFiles.ql index eb86577b4b80..c960599ad18f 100644 --- a/rust/ql/src/queries/summary/NumberOfSuccessfullyExtractedFiles.ql +++ b/rust/ql/src/queries/summary/NumberOfSuccessfullyExtractedFiles.ql @@ -2,14 +2,11 @@ * @id rust/summary/number-of-successfully-extracted-files * @name Total number of Rust files that were extracted without error * @description The total number of Rust files in the source code directory that - * were extracted without encountering any extraction errors. + * were extracted without encountering any extraction errors (or warnings). * @kind metric * @tags summary */ -import codeql.rust.Diagnostics import codeql.files.FileSystem -select count(File f | - not exists(ExtractionError e | e.getLocation().getFile() = f) and exists(f.getRelativePath()) - ) +select count(SuccessfullyExtractedFile f | exists(f.getRelativePath())) From 88abc8f72f8b96d139909bc97d4fb6137fb22334 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 2 Oct 2024 17:29:32 +0100 Subject: [PATCH 137/347] Rust: Add to summary stats. --- rust/ql/src/queries/summary/SummaryStats.ql | 17 +++++++++++++++-- .../diagnostics/SummaryStats.expected | 6 +++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/rust/ql/src/queries/summary/SummaryStats.ql b/rust/ql/src/queries/summary/SummaryStats.ql index 447325514cac..a3494ccb769c 100644 --- a/rust/ql/src/queries/summary/SummaryStats.ql +++ b/rust/ql/src/queries/summary/SummaryStats.ql @@ -7,16 +7,29 @@ */ import rust +import codeql.rust.Diagnostics import Stats from string key, string value where - key = "Files extracted" and value = count(File f | exists(f.getRelativePath())).toString() - or key = "Elements extracted" and value = count(Element e | not e instanceof Unextracted).toString() or key = "Elements unextracted" and value = count(Unextracted e).toString() or + key = "Extraction errors" and value = count(ExtractionError e).toString() + or + key = "Extraction warnings" and value = count(ExtractionWarning w).toString() + or + key = "Files extracted - total" and value = count(File f | exists(f.getRelativePath())).toString() + or + key = "Files extracted - with errors" and + value = + count(File f | exists(f.getRelativePath()) and not f instanceof SuccessfullyExtractedFile) + .toString() + or + key = "Files extracted - without errors" and + value = count(SuccessfullyExtractedFile f | exists(f.getRelativePath())).toString() + or key = "Lines of code extracted" and value = getLinesOfCode().toString() or key = "Lines of user code extracted" and value = getLinesOfUserCode().toString() diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index ff07c0f589a6..cc467865b00f 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -1,5 +1,9 @@ | Elements extracted | 210 | | Elements unextracted | 0 | -| Files extracted | 6 | +| Extraction errors | 6 | +| Extraction warnings | 0 | +| Files extracted - total | 6 | +| Files extracted - with errors | 1 | +| Files extracted - without errors | 5 | | Lines of code extracted | 48 | | Lines of user code extracted | 48 | From 98d587c482264fe107e47e866e25e01ebd7adc00 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 2 Oct 2024 22:40:35 +0000 Subject: [PATCH 138/347] Post-release preparation for codeql-cli-2.19.1 --- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/consistency-queries/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/automodel/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/controlflow/qlpack.yml | 2 +- shared/dataflow/qlpack.yml | 2 +- shared/mad/qlpack.yml | 2 +- shared/rangeanalysis/qlpack.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/threat-models/qlpack.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typeflow/qlpack.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/xml/qlpack.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 35 files changed, 35 insertions(+), 35 deletions(-) diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index f1a2ac3942f2..ba5db8c6e6f9 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 2.0.1 +version: 2.0.2-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index e541f95cd85f..d01ac2f048c2 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 1.2.4 +version: 1.2.5-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 871d2ed3619a..3cab08a0f3ec 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.7.26 +version: 1.7.27-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 00c3209afe98..c46baf0b2518 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.7.26 +version: 1.7.27-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index a8e9c68cfb44..55a99929ac87 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 3.0.0 +version: 3.0.1-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 82e9607d7ab7..6209cc5f88d5 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 1.0.9 +version: 1.0.10-dev groups: - csharp - queries diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index 9800f5090fac..5a7ca8082a53 100644 --- a/go/ql/consistency-queries/qlpack.yml +++ b/go/ql/consistency-queries/qlpack.yml @@ -1,5 +1,5 @@ name: codeql-go-consistency-queries -version: 1.0.9 +version: 1.0.10-dev groups: - go - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index b6987a250d1a..9cb5e3620117 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 2.1.0 +version: 2.1.1-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index e783026f6cfd..0b3f5076bb6d 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 1.1.0 +version: 1.1.1-dev groups: - go - queries diff --git a/java/ql/automodel/src/qlpack.yml b/java/ql/automodel/src/qlpack.yml index 1e1fdbb9f38d..fe961cb4392c 100644 --- a/java/ql/automodel/src/qlpack.yml +++ b/java/ql/automodel/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-automodel-queries -version: 1.0.9 +version: 1.0.10-dev groups: - java - automodel diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 9c69e18a30b8..0d4f67146c1b 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 4.1.0 +version: 4.1.1-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 635ef97836fe..c8e95f52ca4a 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 1.1.6 +version: 1.1.7-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index a93cb421a869..bea3bbacd5fa 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 2.0.1 +version: 2.0.2-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 49489696e79a..407aa03f7802 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 1.2.1 +version: 1.2.2-dev groups: - javascript - queries diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index a4d970e31297..76c86b26be6b 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 1.0.9 +version: 1.0.10-dev groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 316f7a1cc1e6..445940cdd889 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 2.1.0 +version: 2.1.1-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 02c861d40e1d..3f5ee4e78041 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 1.3.0 +version: 1.3.1-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index da808214ea50..dc0b471a171d 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 2.0.1 +version: 2.0.2-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 47651d248c01..b7eee713fbaa 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 1.1.4 +version: 1.1.5-dev groups: - ruby - queries diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index fc8bdde934d4..532b2fa69a09 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 2ad3f8bc73c0..df5c8c4c38af 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 1.1.3 +version: 1.1.4-dev groups: shared library: true dependencies: diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index ed0c1f7113c5..ef3755c80bc4 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index aaf1b1903576..b4deed51c9d8 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index d8b03f4ad2f5..5593197f674b 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 1bd2bea757b3..7bc3773a575f 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index 434466938b1c..dd4331d7e749 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 1.0.9 +version: 1.0.10-dev library: true groups: shared dataExtensions: diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index 9a89b262a321..2390ce7ad116 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,7 +1,7 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index 21b1ddbc9654..04f843aacb5f 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 6f7282c54e9e..e48446dc3e0b 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 3e644f92d6d1..5eccd54b2afa 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index ab191310e567..508143471db4 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: null diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index f43260879fb6..a81184e65886 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true dependencies: diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 4a63da564e55..1df4193b862f 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 1.0.9 +version: 1.0.10-dev groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index dd1896b3c291..1904a1b1ca48 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 2.0.1 +version: 2.0.2-dev groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 8f33acf16a69..6fbae9403605 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 1.0.9 +version: 1.0.10-dev groups: - swift - queries From 0dc036abd17ad23afa4bf9b64d935d6c86637eeb Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 3 Oct 2024 09:31:02 +0200 Subject: [PATCH 139/347] Python: Allow type tracking through comprehensions - the subscript operator is extended to comprehensions - the capture jump-step is extended to work for the functions generated inside comprehensions --- python/ql/lib/semmle/python/ApiGraphs.qll | 7 +++++++ .../python/dataflow/new/internal/TypeTrackingImpl.qll | 2 +- .../ql/test/library-tests/frameworks/stdlib/http_server.py | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll index 1ce04852f3ad..4385259ca9b3 100644 --- a/python/ql/lib/semmle/python/ApiGraphs.qll +++ b/python/ql/lib/semmle/python/ApiGraphs.qll @@ -843,6 +843,13 @@ module API { ref = pred.getSubscript(_) and ref.asCfgNode().isLoad() or + // Subscript via comprehension + lbl = Label::subscript() and + exists(PY::Comp comp | + pred.asExpr() = comp.getIterable() and + ref.asExpr() = comp.getNthInnerLoop(0).getTarget() + ) + or // Subclassing a node lbl = Label::subclass() and exists(PY::ClassExpr clsExpr, DataFlow::Node superclass | pred.flowsTo(superclass) | diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackingImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackingImpl.qll index f3e4ff40800b..415028ad8277 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackingImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackingImpl.qll @@ -304,7 +304,7 @@ module TypeTrackingInput implements Shared::TypeTrackingInput { var.hasDefiningNode(def) | nodeTo.(DataFlowPublic::ScopeEntryDefinitionNode).getDefinition() = e and - nodeFrom.asCfgNode() = def.getValue() and + nodeFrom.asCfgNode() = def and var.getScope().getScope*() = nodeFrom.getScope() ) } diff --git a/python/ql/test/library-tests/frameworks/stdlib/http_server.py b/python/ql/test/library-tests/frameworks/stdlib/http_server.py index 27ec2211f4bc..9110aa6a26a9 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/http_server.py +++ b/python/ql/test/library-tests/frameworks/stdlib/http_server.py @@ -30,7 +30,7 @@ def test_cgi_FieldStorage_taint(): form['key'][0].value, # $ tainted form['key'][0].file, # $ tainted form['key'][0].filename, # $ tainted - [field.value for field in form['key']], # $ MISSING: tainted + [field.value for field in form['key']], # $ tainted # `form.getvalue('key')` will be a list, if multiple fields named "key" are provided form.getvalue('key'), # $ tainted @@ -40,7 +40,7 @@ def test_cgi_FieldStorage_taint(): form.getlist('key'), # $ tainted form.getlist('key')[0], # $ tainted - [field.value for field in form.getlist('key')], # $ MISSING: tainted + [field.value for field in form.getlist('key')], # $ tainted ) From 9e808c17aff2aee6f74f4cf14972607c0744ab7d Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 3 Oct 2024 10:09:59 +0200 Subject: [PATCH 140/347] Python: add change note --- .../2024-10-03-typetracking-through-comprehensions.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python/ql/lib/change-notes/released/2024-10-03-typetracking-through-comprehensions.md diff --git a/python/ql/lib/change-notes/released/2024-10-03-typetracking-through-comprehensions.md b/python/ql/lib/change-notes/released/2024-10-03-typetracking-through-comprehensions.md new file mode 100644 index 000000000000..72d853460305 --- /dev/null +++ b/python/ql/lib/change-notes/released/2024-10-03-typetracking-through-comprehensions.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Type tracking, and hence the API graph, is now able to correctly trace trough comprehensions. \ No newline at end of file From 6d486f99319ce11fe7411ff9c28becc02c9dd5df Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 3 Oct 2024 10:15:55 +0200 Subject: [PATCH 141/347] Python: move change note to the right place --- .../2024-10-03-typetracking-through-comprehensions.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/lib/change-notes/{released => }/2024-10-03-typetracking-through-comprehensions.md (100%) diff --git a/python/ql/lib/change-notes/released/2024-10-03-typetracking-through-comprehensions.md b/python/ql/lib/change-notes/2024-10-03-typetracking-through-comprehensions.md similarity index 100% rename from python/ql/lib/change-notes/released/2024-10-03-typetracking-through-comprehensions.md rename to python/ql/lib/change-notes/2024-10-03-typetracking-through-comprehensions.md From 56d0affe38fbe469e241c7854232b4f43adde619 Mon Sep 17 00:00:00 2001 From: yoff Date: Thu, 3 Oct 2024 10:18:25 +0200 Subject: [PATCH 142/347] Update python/ql/lib/semmle/python/frameworks/Stdlib.model.yml Co-authored-by: Rasmus Wriedt Larsen --- python/ql/lib/semmle/python/frameworks/Stdlib.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml b/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml index 946c4d5ed4f6..107fffdbfb84 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml @@ -33,8 +33,8 @@ extensions: extensible: summaryModel data: # See https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser + # note: taint flow for attribute lookups on `argparse.ArgumentParser` is handled in QL - ["argparse.ArgumentParser", "Member[_parse_known_args,_read_args_from_files]", "Argument[0,arg_strings:]", "ReturnValue", "taint"] - # note: taint of attribute lookups is handled in QL - ["argparse.ArgumentParser", "Member[parse_args,parse_known_args]", "Argument[0,args:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/cgi.html#higher-level-interface - ["cgi.FieldStorage", "Member[getfirst,getlist,getvalue]", "Argument[self]", "ReturnValue", "taint"] From 5c68bad2f158d3a0f37d931fdf485d990e28097b Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 3 Oct 2024 12:17:59 +0200 Subject: [PATCH 143/347] Python: add comments --- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 37cb23a472db..038b3f851932 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4207,7 +4207,11 @@ module StdlibPrivate { // --------------------------------------------------------------------------- // Flow summaries for functions contructing containers // --------------------------------------------------------------------------- - /** A flow summary for `dict`. */ + /** + * A flow summary for `dict`. + * + * see https://docs.python.org/3/library/stdtypes.html#dict + */ class DictSummary extends SummarizedCallable { DictSummary() { this = "builtins.dict" } @@ -4218,18 +4222,23 @@ module StdlibPrivate { } override predicate propagatesFlow(string input, string output, boolean preservesValue) { + // The positional argument contains a mapping. + // TODO: Add the list-of-pairs version + // TODO: these values can be overwritten by keyword arguments exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() | input = "Argument[0].DictionaryElement[" + key + "]" and output = "ReturnValue.DictionaryElement[" + key + "]" and preservesValue = true ) or + // The keyword arguments are added to the dictionary. exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() | input = "Argument[" + key + ":]" and output = "ReturnValue.DictionaryElement[" + key + "]" and preservesValue = true ) or + // Imprecise content in any argument ends up on the container itself. input = "Argument[0..]" and output = "ReturnValue" and preservesValue = false From 0462809edcf42f6da8ea8b6dfa81505bb8a7e147 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 24 Sep 2024 20:49:05 +0200 Subject: [PATCH 144/347] Python: add taint test for urllib --- .../frameworks/urllib/InlineTaintTest.expected | 4 ++++ .../library-tests/frameworks/urllib/InlineTaintTest.ql | 2 ++ .../test/library-tests/frameworks/urllib/taint_test.py | 10 ++++++++++ 3 files changed, 16 insertions(+) create mode 100644 python/ql/test/library-tests/frameworks/urllib/InlineTaintTest.expected create mode 100644 python/ql/test/library-tests/frameworks/urllib/InlineTaintTest.ql create mode 100644 python/ql/test/library-tests/frameworks/urllib/taint_test.py diff --git a/python/ql/test/library-tests/frameworks/urllib/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/urllib/InlineTaintTest.expected new file mode 100644 index 000000000000..366de37b8677 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/urllib/InlineTaintTest.expected @@ -0,0 +1,4 @@ +argumentToEnsureNotTaintedNotMarkedAsSpurious +untaintedArgumentToEnsureTaintedNotMarkedAsMissing +testFailures +failures diff --git a/python/ql/test/library-tests/frameworks/urllib/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/urllib/InlineTaintTest.ql new file mode 100644 index 000000000000..8524da5fe7db --- /dev/null +++ b/python/ql/test/library-tests/frameworks/urllib/InlineTaintTest.ql @@ -0,0 +1,2 @@ +import experimental.meta.InlineTaintTest +import MakeInlineTaintTest diff --git a/python/ql/test/library-tests/frameworks/urllib/taint_test.py b/python/ql/test/library-tests/frameworks/urllib/taint_test.py new file mode 100644 index 000000000000..ad64ce37f24c --- /dev/null +++ b/python/ql/test/library-tests/frameworks/urllib/taint_test.py @@ -0,0 +1,10 @@ +import urllib.parse + +def test(): + ts = TAINTED_STRING + + params = urllib.parse.parse_qs(ts) + + ensure_tainted( + params, # $ MISSING: tainted + ) From 768d866e72da521f942c449c45aa0ec298fbe22e Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 24 Sep 2024 20:52:00 +0200 Subject: [PATCH 145/347] python: model `urllib.parse.parse_qs` --- python/ql/lib/semmle/python/frameworks/Stdlib.model.yml | 2 ++ python/ql/test/library-tests/frameworks/urllib/taint_test.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml b/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml index 107fffdbfb84..683b0aa9b3df 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml @@ -134,6 +134,8 @@ extensions: - ["traceback.StackSummary", "Member[from_list]", "Argument[0,a_list:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/typing.html#typing.cast - ["typing", "Member[cast]", "Argument[1,val:]", "ReturnValue", "value"] + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.parse_qs + - ["urllib", "Member[parse].Member[parse_qs]", "Argument[0,qs:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote - ["urllib", "Member[parse].Member[quote]", "Argument[0,string:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote_plus diff --git a/python/ql/test/library-tests/frameworks/urllib/taint_test.py b/python/ql/test/library-tests/frameworks/urllib/taint_test.py index ad64ce37f24c..b24c31be14c0 100644 --- a/python/ql/test/library-tests/frameworks/urllib/taint_test.py +++ b/python/ql/test/library-tests/frameworks/urllib/taint_test.py @@ -6,5 +6,5 @@ def test(): params = urllib.parse.parse_qs(ts) ensure_tainted( - params, # $ MISSING: tainted + params, # $ tainted ) From 821398715c5eb6361e42bd9b5e528254fce403a2 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 3 Oct 2024 11:55:11 +0100 Subject: [PATCH 146/347] Rust: Test spacing. --- .../query-tests/unusedentities/UnusedVariable.expected | 8 ++++---- rust/ql/test/query-tests/unusedentities/main.rs | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected index f3aadfdff0d8..b99d7892f8e8 100644 --- a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected +++ b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected @@ -1,4 +1,4 @@ -| main.rs:23:9:23:9 | a | Variable is not used. | -| main.rs:88:13:88:13 | d | Variable is not used. | -| main.rs:112:9:112:9 | k | Variable is not used. | -| main.rs:139:5:139:5 | y | Variable is not used. | +| main.rs:25:9:25:9 | a | Variable is not used. | +| main.rs:90:13:90:13 | d | Variable is not used. | +| main.rs:114:9:114:9 | k | Variable is not used. | +| main.rs:141:5:141:5 | y | Variable is not used. | diff --git a/rust/ql/test/query-tests/unusedentities/main.rs b/rust/ql/test/query-tests/unusedentities/main.rs index 7280f6c2502b..3d79206e903e 100644 --- a/rust/ql/test/query-tests/unusedentities/main.rs +++ b/rust/ql/test/query-tests/unusedentities/main.rs @@ -8,6 +8,7 @@ fn locals_1() { let c = 1; let d = String::from("a"); // BAD: unused value [NOT DETECTED] let e = String::from("b"); + let _ = 1; // (deliberately unused) println!("use {}", b); @@ -17,6 +18,7 @@ fn locals_1() { } println!("use {}", e); + } fn locals_2() { From 777279dc29cf812a6d3e50e06b692c0c0b3effcb Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 3 Oct 2024 13:29:56 +0200 Subject: [PATCH 147/347] Python: MaD test expectations --- .../Security/CWE-409/DecompressionBombs.expected | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected index 2b16f9ef178f..7763cf2ad151 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected @@ -1,23 +1,23 @@ edges | test.py:10:16:10:24 | ControlFlowNode for file_path | test.py:11:21:11:29 | ControlFlowNode for file_path | provenance | | | test.py:11:5:11:35 | ControlFlowNode for Attribute() | test.py:11:5:11:52 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:35 | ControlFlowNode for Attribute() | provenance | MaD:82 | +| test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:35 | ControlFlowNode for Attribute() | provenance | MaD:83 | | test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:52 | ControlFlowNode for Attribute() | provenance | Config | | test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:12:21:12:29 | ControlFlowNode for file_path | provenance | | | test.py:12:5:12:35 | ControlFlowNode for Attribute() | test.py:12:5:12:48 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:35 | ControlFlowNode for Attribute() | provenance | MaD:82 | +| test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:35 | ControlFlowNode for Attribute() | provenance | MaD:83 | | test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:48 | ControlFlowNode for Attribute() | provenance | Config | | test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:14:26:14:34 | ControlFlowNode for file_path | provenance | | | test.py:14:10:14:35 | ControlFlowNode for Attribute() | test.py:15:14:15:29 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:14:10:14:35 | ControlFlowNode for Attribute() | provenance | MaD:82 | +| test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:14:10:14:35 | ControlFlowNode for Attribute() | provenance | MaD:83 | | test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:15:14:15:29 | ControlFlowNode for Attribute() | provenance | Config | | test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:18:26:18:34 | ControlFlowNode for file_path | provenance | | | test.py:18:10:18:35 | ControlFlowNode for Attribute() | test.py:19:14:19:39 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:18:10:18:35 | ControlFlowNode for Attribute() | provenance | MaD:82 | +| test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:18:10:18:35 | ControlFlowNode for Attribute() | provenance | MaD:83 | | test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:19:14:19:39 | ControlFlowNode for Attribute() | provenance | Config | | test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:22:21:22:29 | ControlFlowNode for file_path | provenance | | | test.py:22:5:22:30 | ControlFlowNode for Attribute() | test.py:22:5:22:60 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:30 | ControlFlowNode for Attribute() | provenance | MaD:82 | +| test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:30 | ControlFlowNode for Attribute() | provenance | MaD:83 | | test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:60 | ControlFlowNode for Attribute() | provenance | Config | | test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:24:18:24:26 | ControlFlowNode for file_path | provenance | | | test.py:24:18:24:26 | ControlFlowNode for file_path | test.py:24:5:24:52 | ControlFlowNode for Attribute() | provenance | Config | From 0304aa846caddb81cf318164b08230bcb469114d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 3 Oct 2024 11:57:56 +0100 Subject: [PATCH 148/347] Rust: Add more tests for uused variables. --- .../unusedentities/UnusedVariable.expected | 10 ++ .../test/query-tests/unusedentities/main.rs | 106 +++++++++++++++++- 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected index b99d7892f8e8..4a35ca8a41d4 100644 --- a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected +++ b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected @@ -2,3 +2,13 @@ | main.rs:90:13:90:13 | d | Variable is not used. | | main.rs:114:9:114:9 | k | Variable is not used. | | main.rs:141:5:141:5 | y | Variable is not used. | +| main.rs:164:9:164:9 | x | Variable is not used. | +| main.rs:170:9:170:9 | x | Variable is not used. | +| main.rs:174:9:174:9 | x | Variable is not used. | +| main.rs:194:17:194:17 | a | Variable is not used. | +| main.rs:202:20:202:22 | val | Variable is not used. | +| main.rs:207:20:207:22 | val | Variable is not used. | +| main.rs:214:14:214:16 | val | Variable is not used. | +| main.rs:216:9:216:12 | None | Variable is not used. | +| main.rs:225:9:225:12 | None | Variable is not used. | +| main.rs:231:24:231:26 | val | Variable is not used. | diff --git a/rust/ql/test/query-tests/unusedentities/main.rs b/rust/ql/test/query-tests/unusedentities/main.rs index 3d79206e903e..46d1458b972e 100644 --- a/rust/ql/test/query-tests/unusedentities/main.rs +++ b/rust/ql/test/query-tests/unusedentities/main.rs @@ -8,7 +8,7 @@ fn locals_1() { let c = 1; let d = String::from("a"); // BAD: unused value [NOT DETECTED] let e = String::from("b"); - + let f = 1; let _ = 1; // (deliberately unused) println!("use {}", b); @@ -18,7 +18,7 @@ fn locals_1() { } println!("use {}", e); - + assert!(f == 1); } fn locals_2() { @@ -144,11 +144,113 @@ fn parameters( return x; } +// --- loops --- + +fn loops() { + let mut a: i64 = 10; + let b: i64 = 20; + let c: i64 = 30; + let d: i64 = 40; + let mut e: i64 = 50; + + while a < b { + a += 1; + } + + for x in c..d { + e += x; + } + + for x in 1..10 { // BAD: unused variable + } + + for _ in 1..10 { + } + + for x in 1..10 { // SPURIOUS: unused variable [macros not yet supported] + println!("x is {}", x); + } + + for x in 1..10 { // SPURIOUS: unused variable [macros not yet supported] + assert!(x != 11); + } +} + +// --- lets --- + +enum MyOption { + None, + Some(T), +} + +enum YesOrNo { + Yes, + No, +} + +fn if_lets() { + let mut total: i64 = 0; + + if let Some(a) = Some(10) { // BAD: unused variable + } + + if let Some(b) = Some(20) { + total += b; + } + + let mut next = Some(30); + while let Some(val) = next { // BAD: unused variable + next = None; + } + + let mut next2 = Some(40); + while let Some(val) = next2 { // SPURIOUS: unused variable 'val' + total += val; + next2 = None; + } + + let c = Some(60); + match c { + Some(val) => { // BAD: unused variable + }, + None => { // SPURIOUS: unused variable 'None' + } + } + + let d = Some(70); + match d { + Some(val) => { + total += val; + }, + None => { // SPURIOUS: unused variable 'None' + } + } + + let e = MyOption::Some(80); + match e { + MyOption::Some(val) => { // BAD: unused variable + }, + MyOption::None => { + } + } + + let f = YesOrNo::Yes; + match f { + YesOrNo::Yes => { + }, + YesOrNo::No => { + }, + } +} + fn main() { locals_1(); locals_2(); structs(); arrays(); statics(); + loops(); + if_lets(); + println!("lets use result {}", parameters(1, 2, 3)); } From 9902874dddfec7476100d57ca0a89760c8e2b0f7 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 3 Oct 2024 13:43:39 +0200 Subject: [PATCH 149/347] SSA: Add BarrierGuardWithState --- shared/ssa/codeql/ssa/Ssa.qll | 48 ++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/shared/ssa/codeql/ssa/Ssa.qll b/shared/ssa/codeql/ssa/Ssa.qll index fd785540a371..4b6ae906b823 100644 --- a/shared/ssa/codeql/ssa/Ssa.qll +++ b/shared/ssa/codeql/ssa/Ssa.qll @@ -4,6 +4,7 @@ */ private import codeql.util.Location +private import codeql.util.Unit /** Provides the input specification of the SSA implementation. */ signature module InputSig { @@ -1631,6 +1632,23 @@ module Make Input> { ) } + bindingset[this] + signature class StateSig; + + module WithState { + /** + * Holds if the guard `g` validates the expression `e` upon evaluating to `branch`, blocking + * flow in the given `state`. + * + * The expression `e` is expected to be a syntactic part of the guard `g`. + * For example, the guard `g` might be a call `isSafe(x)` and the expression `e` + * the argument `x`. + */ + signature predicate guardChecksSig( + DfInput::Guard g, DfInput::Expr e, boolean branch, State state + ); + } + /** * Provides a set of barrier nodes for a guard that validates an expression. * @@ -1638,16 +1656,38 @@ module Make Input> { * in data flow and taint tracking. */ module BarrierGuard { + private predicate guardChecksWithState( + DfInput::Guard g, DfInput::Expr e, boolean branch, Unit state + ) { + guardChecks(g, e, branch) and exists(state) + } + + private module StatefulBarrier = BarrierGuardWithState; + + /** Gets a node that is safely guarded by the given guard check. */ + pragma[nomagic] + Node getABarrierNode() { result = StatefulBarrier::getABarrierNode(_) } + } + + /** + * Provides a set of barrier nodes for a guard that validates an expression. + * + * This is expected to be used in `isBarrier`/`isSanitizer` definitions + * in data flow and taint tracking. + */ + module BarrierGuardWithState::guardChecksSig/4 guardChecks> { pragma[nomagic] - private predicate guardChecksSsaDef(DfInput::Guard g, Definition def, boolean branch) { - guardChecks(g, DfInput::getARead(def), branch) + private predicate guardChecksSsaDef( + DfInput::Guard g, Definition def, boolean branch, State state + ) { + guardChecks(g, DfInput::getARead(def), branch, state) } /** Gets a node that is safely guarded by the given guard check. */ pragma[nomagic] - Node getABarrierNode() { + Node getABarrierNode(State state) { exists(DfInput::Guard g, boolean branch, Definition def, BasicBlock bb | - guardChecksSsaDef(g, def, branch) + guardChecksSsaDef(g, def, branch, state) | // guard controls a read exists(DfInput::Expr e | From da84889242e786e7b2bdbd844e7bfdf7cef6fab6 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 3 Oct 2024 12:50:40 +0100 Subject: [PATCH 150/347] Rust: Use @diagnostic_error, @diagnostic_warning rather than constants. --- rust/ql/lib/codeql/rust/Diagnostics.qll | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/rust/ql/lib/codeql/rust/Diagnostics.qll b/rust/ql/lib/codeql/rust/Diagnostics.qll index 8f77b64c5123..58de14b8fcf5 100644 --- a/rust/ql/lib/codeql/rust/Diagnostics.qll +++ b/rust/ql/lib/codeql/rust/Diagnostics.qll @@ -49,11 +49,7 @@ class Diagnostic extends @diagnostic { } /** A diagnostic that is error severity. */ -class ExtractionError extends Diagnostic { - ExtractionError() { this.getSeverity() = 40 } -} +class ExtractionError extends Diagnostic, @diagnostic_error { } /** A diagnostic that is warning severity. */ -class ExtractionWarning extends Diagnostic { - ExtractionWarning() { this.getSeverity() = 30 } -} +class ExtractionWarning extends Diagnostic, @diagnostic_warning { } From 32dbdb39133c80ab29386d78cb62e96b8e68d5db Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 3 Oct 2024 12:50:59 +0100 Subject: [PATCH 151/347] Rust: Update summary stats .expected file. --- rust/ql/test/query-tests/diagnostics/SummaryStats.expected | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index cc467865b00f..8fe7ee7fb47c 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -1,7 +1,7 @@ | Elements extracted | 210 | | Elements unextracted | 0 | -| Extraction errors | 6 | -| Extraction warnings | 0 | +| Extraction errors | 0 | +| Extraction warnings | 6 | | Files extracted - total | 6 | | Files extracted - with errors | 1 | | Files extracted - without errors | 5 | From cd04500dd9393e613cd06b5747902c8f95ae4150 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 3 Oct 2024 14:05:24 +0200 Subject: [PATCH 152/347] Rust: Account for variables bound in `while let` expressions --- .../rust/elements/internal/VariableImpl.qll | 7 + .../test/library-tests/variables/Cfg.expected | 885 +++++++++--------- .../variables/variables.expected | 369 ++++---- .../test/library-tests/variables/variables.rs | 9 + .../unusedentities/UnusedVariable.expected | 15 +- .../test/query-tests/unusedentities/main.rs | 27 +- 6 files changed, 676 insertions(+), 636 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index 3f0cabc97b85..7a77c45fe2ae 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -218,6 +218,13 @@ module Impl { scope = ce.getBody() and scope.getLocation().hasLocationInfo(_, line, column, _, _) ) + or + exists(WhileExpr we, LetExpr let | + let.getPat() = pat and + we.getCondition() = let and + scope = we.getLoopBody() and + scope.getLocation().hasLocationInfo(_, line, column, _, _) + ) ) } diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected index 0a075ff054e3..1ae43dac402e 100644 --- a/rust/ql/test/library-tests/variables/Cfg.expected +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -159,439 +159,458 @@ edges | variables.rs:85:5:85:17 | CallExpr | variables.rs:80:19:86:1 | BlockExpr | | | variables.rs:85:5:85:18 | ExprStmt | variables.rs:85:5:85:13 | PathExpr | | | variables.rs:85:15:85:16 | x5 | variables.rs:85:5:85:17 | CallExpr | | -| variables.rs:88:1:103:1 | enter match_pattern1 | variables.rs:89:5:89:21 | LetStmt | | -| variables.rs:88:1:103:1 | exit match_pattern1 (normal) | variables.rs:88:1:103:1 | exit match_pattern1 | | -| variables.rs:88:21:103:1 | BlockExpr | variables.rs:88:1:103:1 | exit match_pattern1 (normal) | | -| variables.rs:89:5:89:21 | LetStmt | variables.rs:89:14:89:17 | PathExpr | | -| variables.rs:89:9:89:10 | x6 | variables.rs:90:5:90:16 | LetStmt | match, no-match | -| variables.rs:89:14:89:17 | PathExpr | variables.rs:89:19:89:19 | 5 | | -| variables.rs:89:14:89:20 | CallExpr | variables.rs:89:9:89:10 | x6 | | -| variables.rs:89:19:89:19 | 5 | variables.rs:89:14:89:20 | CallExpr | | -| variables.rs:90:5:90:16 | LetStmt | variables.rs:90:14:90:15 | 10 | | -| variables.rs:90:9:90:10 | y1 | variables.rs:92:5:100:5 | ExprStmt | match, no-match | -| variables.rs:90:14:90:15 | 10 | variables.rs:90:9:90:10 | y1 | | -| variables.rs:92:5:100:5 | ExprStmt | variables.rs:92:11:92:12 | x6 | | -| variables.rs:92:5:100:5 | MatchExpr | variables.rs:102:5:102:18 | ExprStmt | | -| variables.rs:92:11:92:12 | x6 | variables.rs:93:9:93:16 | TupleStructPat | | -| variables.rs:93:9:93:16 | TupleStructPat | variables.rs:93:21:93:29 | PathExpr | match | -| variables.rs:93:9:93:16 | TupleStructPat | variables.rs:94:9:94:16 | TupleStructPat | no-match | -| variables.rs:93:21:93:29 | PathExpr | variables.rs:93:31:93:38 | "Got 50" | | -| variables.rs:93:21:93:39 | CallExpr | variables.rs:92:5:100:5 | MatchExpr | | -| variables.rs:93:31:93:38 | "Got 50" | variables.rs:93:21:93:39 | CallExpr | | -| variables.rs:94:9:94:16 | TupleStructPat | variables.rs:97:13:97:21 | PathExpr | match | -| variables.rs:94:9:94:16 | TupleStructPat | variables.rs:99:9:99:12 | None | no-match | -| variables.rs:96:9:98:9 | BlockExpr | variables.rs:92:5:100:5 | MatchExpr | | -| variables.rs:97:13:97:21 | PathExpr | variables.rs:97:23:97:24 | y1 | | -| variables.rs:97:13:97:25 | CallExpr | variables.rs:96:9:98:9 | BlockExpr | | -| variables.rs:97:23:97:24 | y1 | variables.rs:97:13:97:25 | CallExpr | | -| variables.rs:99:9:99:12 | None | variables.rs:99:17:99:25 | PathExpr | match | -| variables.rs:99:17:99:25 | PathExpr | variables.rs:99:27:99:32 | "NONE" | | -| variables.rs:99:17:99:33 | CallExpr | variables.rs:92:5:100:5 | MatchExpr | | -| variables.rs:99:27:99:32 | "NONE" | variables.rs:99:17:99:33 | CallExpr | | -| variables.rs:102:5:102:13 | PathExpr | variables.rs:102:15:102:16 | y1 | | -| variables.rs:102:5:102:17 | CallExpr | variables.rs:88:21:103:1 | BlockExpr | | -| variables.rs:102:5:102:18 | ExprStmt | variables.rs:102:5:102:13 | PathExpr | | -| variables.rs:102:15:102:16 | y1 | variables.rs:102:5:102:17 | CallExpr | | -| variables.rs:105:1:130:1 | enter match_pattern2 | variables.rs:106:5:106:36 | LetStmt | | -| variables.rs:105:1:130:1 | exit match_pattern2 (normal) | variables.rs:105:1:130:1 | exit match_pattern2 | | -| variables.rs:105:21:130:1 | BlockExpr | variables.rs:105:1:130:1 | exit match_pattern2 (normal) | | -| variables.rs:106:5:106:36 | LetStmt | variables.rs:106:20:106:20 | 2 | | -| variables.rs:106:9:106:15 | numbers | variables.rs:108:5:118:5 | ExprStmt | match, no-match | -| variables.rs:106:19:106:35 | TupleExpr | variables.rs:106:9:106:15 | numbers | | -| variables.rs:106:20:106:20 | 2 | variables.rs:106:23:106:23 | 4 | | -| variables.rs:106:23:106:23 | 4 | variables.rs:106:26:106:26 | 8 | | -| variables.rs:106:26:106:26 | 8 | variables.rs:106:29:106:30 | 16 | | -| variables.rs:106:29:106:30 | 16 | variables.rs:106:33:106:34 | 32 | | -| variables.rs:106:33:106:34 | 32 | variables.rs:106:19:106:35 | TupleExpr | | -| variables.rs:108:5:118:5 | ExprStmt | variables.rs:108:11:108:17 | numbers | | -| variables.rs:108:5:118:5 | MatchExpr | variables.rs:120:11:120:17 | numbers | | -| variables.rs:108:11:108:17 | numbers | variables.rs:109:9:113:9 | TuplePat | | -| variables.rs:109:9:113:9 | TuplePat | variables.rs:114:13:114:29 | ExprStmt | match | -| variables.rs:113:14:117:9 | BlockExpr | variables.rs:108:5:118:5 | MatchExpr | | -| variables.rs:114:13:114:21 | PathExpr | variables.rs:114:23:114:27 | first | | -| variables.rs:114:13:114:28 | CallExpr | variables.rs:115:13:115:29 | ExprStmt | | -| variables.rs:114:13:114:29 | ExprStmt | variables.rs:114:13:114:21 | PathExpr | | -| variables.rs:114:23:114:27 | first | variables.rs:114:13:114:28 | CallExpr | | -| variables.rs:115:13:115:21 | PathExpr | variables.rs:115:23:115:27 | third | | -| variables.rs:115:13:115:28 | CallExpr | variables.rs:116:13:116:29 | ExprStmt | | -| variables.rs:115:13:115:29 | ExprStmt | variables.rs:115:13:115:21 | PathExpr | | -| variables.rs:115:23:115:27 | third | variables.rs:115:13:115:28 | CallExpr | | -| variables.rs:116:13:116:21 | PathExpr | variables.rs:116:23:116:27 | fifth | | -| variables.rs:116:13:116:28 | CallExpr | variables.rs:113:14:117:9 | BlockExpr | | -| variables.rs:116:13:116:29 | ExprStmt | variables.rs:116:13:116:21 | PathExpr | | -| variables.rs:116:23:116:27 | fifth | variables.rs:116:13:116:28 | CallExpr | | -| variables.rs:120:5:129:5 | MatchExpr | variables.rs:105:21:130:1 | BlockExpr | | -| variables.rs:120:11:120:17 | numbers | variables.rs:121:9:125:9 | TuplePat | | -| variables.rs:121:9:125:9 | TuplePat | variables.rs:126:13:126:29 | ExprStmt | match | -| variables.rs:125:14:128:9 | BlockExpr | variables.rs:120:5:129:5 | MatchExpr | | -| variables.rs:126:13:126:21 | PathExpr | variables.rs:126:23:126:27 | first | | -| variables.rs:126:13:126:28 | CallExpr | variables.rs:127:13:127:28 | ExprStmt | | -| variables.rs:126:13:126:29 | ExprStmt | variables.rs:126:13:126:21 | PathExpr | | -| variables.rs:126:23:126:27 | first | variables.rs:126:13:126:28 | CallExpr | | -| variables.rs:127:13:127:21 | PathExpr | variables.rs:127:23:127:26 | last | | -| variables.rs:127:13:127:27 | CallExpr | variables.rs:125:14:128:9 | BlockExpr | | -| variables.rs:127:13:127:28 | ExprStmt | variables.rs:127:13:127:21 | PathExpr | | -| variables.rs:127:23:127:26 | last | variables.rs:127:13:127:27 | CallExpr | | -| variables.rs:132:1:140:1 | enter match_pattern3 | variables.rs:133:5:133:38 | LetStmt | | -| variables.rs:132:1:140:1 | exit match_pattern3 (normal) | variables.rs:132:1:140:1 | exit match_pattern3 | | -| variables.rs:132:21:140:1 | BlockExpr | variables.rs:132:1:140:1 | exit match_pattern3 (normal) | | -| variables.rs:133:5:133:38 | LetStmt | variables.rs:133:25:133:27 | "x" | | -| variables.rs:133:9:133:10 | p2 | variables.rs:135:11:135:12 | p2 | match, no-match | -| variables.rs:133:14:133:37 | RecordExpr | variables.rs:133:9:133:10 | p2 | | -| variables.rs:133:25:133:27 | "x" | variables.rs:133:33:133:35 | "y" | | -| variables.rs:133:33:133:35 | "y" | variables.rs:133:14:133:37 | RecordExpr | | -| variables.rs:135:5:139:5 | MatchExpr | variables.rs:132:21:140:1 | BlockExpr | | -| variables.rs:135:11:135:12 | p2 | variables.rs:136:9:138:9 | RecordPat | | -| variables.rs:136:9:138:9 | RecordPat | variables.rs:138:14:138:22 | PathExpr | match | -| variables.rs:138:14:138:22 | PathExpr | variables.rs:138:24:138:25 | x7 | | -| variables.rs:138:14:138:26 | CallExpr | variables.rs:135:5:139:5 | MatchExpr | | -| variables.rs:138:24:138:25 | x7 | variables.rs:138:14:138:26 | CallExpr | | -| variables.rs:146:1:159:1 | enter match_pattern4 | variables.rs:147:5:147:39 | LetStmt | | -| variables.rs:146:1:159:1 | exit match_pattern4 (normal) | variables.rs:146:1:159:1 | exit match_pattern4 | | -| variables.rs:146:21:159:1 | BlockExpr | variables.rs:146:1:159:1 | exit match_pattern4 (normal) | | -| variables.rs:147:5:147:39 | LetStmt | variables.rs:147:36:147:36 | 0 | | -| variables.rs:147:9:147:11 | msg | variables.rs:149:11:149:13 | msg | match, no-match | -| variables.rs:147:15:147:38 | RecordExpr | variables.rs:147:9:147:11 | msg | | -| variables.rs:147:36:147:36 | 0 | variables.rs:147:15:147:38 | RecordExpr | | -| variables.rs:149:5:158:5 | MatchExpr | variables.rs:146:21:159:1 | BlockExpr | | -| variables.rs:149:11:149:13 | msg | variables.rs:150:9:152:9 | RecordPat | | -| variables.rs:150:9:152:9 | RecordPat | variables.rs:152:14:152:22 | PathExpr | match | -| variables.rs:150:9:152:9 | RecordPat | variables.rs:153:9:153:38 | RecordPat | no-match | -| variables.rs:152:14:152:22 | PathExpr | variables.rs:152:24:152:34 | id_variable | | -| variables.rs:152:14:152:35 | CallExpr | variables.rs:149:5:158:5 | MatchExpr | | -| variables.rs:152:24:152:34 | id_variable | variables.rs:152:14:152:35 | CallExpr | | -| variables.rs:153:9:153:38 | RecordPat | variables.rs:154:13:154:52 | MacroExpr | match | -| variables.rs:153:9:153:38 | RecordPat | variables.rs:156:9:156:29 | RecordPat | no-match | -| variables.rs:153:43:155:9 | BlockExpr | variables.rs:149:5:158:5 | MatchExpr | | -| variables.rs:154:13:154:52 | MacroExpr | variables.rs:153:43:155:9 | BlockExpr | | -| variables.rs:156:9:156:29 | RecordPat | variables.rs:157:13:157:21 | PathExpr | match | -| variables.rs:157:13:157:21 | PathExpr | variables.rs:157:23:157:24 | id | | -| variables.rs:157:13:157:25 | CallExpr | variables.rs:149:5:158:5 | MatchExpr | | -| variables.rs:157:23:157:24 | id | variables.rs:157:13:157:25 | CallExpr | | -| variables.rs:166:1:172:1 | enter match_pattern5 | variables.rs:167:5:167:34 | LetStmt | | -| variables.rs:166:1:172:1 | exit match_pattern5 (normal) | variables.rs:166:1:172:1 | exit match_pattern5 | | -| variables.rs:166:21:172:1 | BlockExpr | variables.rs:166:1:172:1 | exit match_pattern5 (normal) | | -| variables.rs:167:5:167:34 | LetStmt | variables.rs:167:18:167:29 | PathExpr | | -| variables.rs:167:9:167:14 | either | variables.rs:168:11:168:16 | either | match, no-match | -| variables.rs:167:18:167:29 | PathExpr | variables.rs:167:31:167:32 | 32 | | -| variables.rs:167:18:167:33 | CallExpr | variables.rs:167:9:167:14 | either | | -| variables.rs:167:31:167:32 | 32 | variables.rs:167:18:167:33 | CallExpr | | -| variables.rs:168:5:171:5 | MatchExpr | variables.rs:166:21:172:1 | BlockExpr | | -| variables.rs:168:11:168:16 | either | variables.rs:169:9:169:44 | OrPat | | -| variables.rs:169:9:169:44 | OrPat | variables.rs:170:16:170:24 | PathExpr | match | -| variables.rs:170:16:170:24 | PathExpr | variables.rs:170:26:170:27 | a3 | | -| variables.rs:170:16:170:28 | CallExpr | variables.rs:168:5:171:5 | MatchExpr | | -| variables.rs:170:26:170:27 | a3 | variables.rs:170:16:170:28 | CallExpr | | -| variables.rs:180:1:194:1 | enter match_pattern6 | variables.rs:181:5:181:37 | LetStmt | | -| variables.rs:180:1:194:1 | exit match_pattern6 (normal) | variables.rs:180:1:194:1 | exit match_pattern6 | | -| variables.rs:180:21:194:1 | BlockExpr | variables.rs:180:1:194:1 | exit match_pattern6 (normal) | | -| variables.rs:181:5:181:37 | LetStmt | variables.rs:181:14:181:32 | PathExpr | | -| variables.rs:181:9:181:10 | tv | variables.rs:182:5:185:5 | ExprStmt | match, no-match | -| variables.rs:181:14:181:32 | PathExpr | variables.rs:181:34:181:35 | 62 | | -| variables.rs:181:14:181:36 | CallExpr | variables.rs:181:9:181:10 | tv | | -| variables.rs:181:34:181:35 | 62 | variables.rs:181:14:181:36 | CallExpr | | -| variables.rs:182:5:185:5 | ExprStmt | variables.rs:182:11:182:12 | tv | | -| variables.rs:182:5:185:5 | MatchExpr | variables.rs:186:5:189:5 | ExprStmt | | -| variables.rs:182:11:182:12 | tv | variables.rs:183:9:183:81 | OrPat | | -| variables.rs:183:9:183:81 | OrPat | variables.rs:184:16:184:24 | PathExpr | match | -| variables.rs:184:16:184:24 | PathExpr | variables.rs:184:26:184:27 | a4 | | -| variables.rs:184:16:184:28 | CallExpr | variables.rs:182:5:185:5 | MatchExpr | | -| variables.rs:184:26:184:27 | a4 | variables.rs:184:16:184:28 | CallExpr | | -| variables.rs:186:5:189:5 | ExprStmt | variables.rs:186:11:186:12 | tv | | -| variables.rs:186:5:189:5 | MatchExpr | variables.rs:190:11:190:12 | tv | | -| variables.rs:186:11:186:12 | tv | variables.rs:187:9:187:83 | OrPat | | -| variables.rs:187:9:187:83 | OrPat | variables.rs:188:16:188:24 | PathExpr | match | -| variables.rs:188:16:188:24 | PathExpr | variables.rs:188:26:188:27 | a5 | | -| variables.rs:188:16:188:28 | CallExpr | variables.rs:186:5:189:5 | MatchExpr | | -| variables.rs:188:26:188:27 | a5 | variables.rs:188:16:188:28 | CallExpr | | -| variables.rs:190:5:193:5 | MatchExpr | variables.rs:180:21:194:1 | BlockExpr | | -| variables.rs:190:11:190:12 | tv | variables.rs:191:9:191:83 | OrPat | | -| variables.rs:191:9:191:83 | OrPat | variables.rs:192:16:192:24 | PathExpr | match | -| variables.rs:192:16:192:24 | PathExpr | variables.rs:192:26:192:27 | a6 | | -| variables.rs:192:16:192:28 | CallExpr | variables.rs:190:5:193:5 | MatchExpr | | -| variables.rs:192:26:192:27 | a6 | variables.rs:192:16:192:28 | CallExpr | | -| variables.rs:196:1:204:1 | enter match_pattern7 | variables.rs:197:5:197:34 | LetStmt | | -| variables.rs:196:1:204:1 | exit match_pattern7 (normal) | variables.rs:196:1:204:1 | exit match_pattern7 | | -| variables.rs:196:21:204:1 | BlockExpr | variables.rs:196:1:204:1 | exit match_pattern7 (normal) | | -| variables.rs:197:5:197:34 | LetStmt | variables.rs:197:18:197:29 | PathExpr | | -| variables.rs:197:9:197:14 | either | variables.rs:198:11:198:16 | either | match, no-match | -| variables.rs:197:18:197:29 | PathExpr | variables.rs:197:31:197:32 | 32 | | -| variables.rs:197:18:197:33 | CallExpr | variables.rs:197:9:197:14 | either | | -| variables.rs:197:31:197:32 | 32 | variables.rs:197:18:197:33 | CallExpr | | -| variables.rs:198:5:203:5 | MatchExpr | variables.rs:196:21:204:1 | BlockExpr | | -| variables.rs:198:11:198:16 | either | variables.rs:199:9:199:44 | OrPat | | -| variables.rs:199:9:199:44 | OrPat | variables.rs:200:16:200:17 | a7 | match | -| variables.rs:199:9:199:44 | OrPat | variables.rs:202:9:202:9 | WildcardPat | no-match | -| variables.rs:200:16:200:17 | a7 | variables.rs:200:21:200:21 | 0 | | -| variables.rs:200:16:200:21 | ... > ... | variables.rs:201:16:201:24 | PathExpr | true | -| variables.rs:200:16:200:21 | ... > ... | variables.rs:202:9:202:9 | WildcardPat | false | -| variables.rs:200:21:200:21 | 0 | variables.rs:200:16:200:21 | ... > ... | | -| variables.rs:201:16:201:24 | PathExpr | variables.rs:201:26:201:27 | a7 | | -| variables.rs:201:16:201:28 | CallExpr | variables.rs:198:5:203:5 | MatchExpr | | -| variables.rs:201:26:201:27 | a7 | variables.rs:201:16:201:28 | CallExpr | | -| variables.rs:202:9:202:9 | WildcardPat | variables.rs:202:14:202:15 | TupleExpr | match | -| variables.rs:202:14:202:15 | TupleExpr | variables.rs:198:5:203:5 | MatchExpr | | -| variables.rs:206:1:221:1 | enter match_pattern8 | variables.rs:207:5:207:34 | LetStmt | | -| variables.rs:206:1:221:1 | exit match_pattern8 (normal) | variables.rs:206:1:221:1 | exit match_pattern8 | | -| variables.rs:206:21:221:1 | BlockExpr | variables.rs:206:1:221:1 | exit match_pattern8 (normal) | | -| variables.rs:207:5:207:34 | LetStmt | variables.rs:207:18:207:29 | PathExpr | | -| variables.rs:207:9:207:14 | either | variables.rs:209:11:209:16 | either | match, no-match | -| variables.rs:207:18:207:29 | PathExpr | variables.rs:207:31:207:32 | 32 | | -| variables.rs:207:18:207:33 | CallExpr | variables.rs:207:9:207:14 | either | | -| variables.rs:207:31:207:32 | 32 | variables.rs:207:18:207:33 | CallExpr | | -| variables.rs:209:5:220:5 | MatchExpr | variables.rs:206:21:221:1 | BlockExpr | | -| variables.rs:209:11:209:16 | either | variables.rs:210:9:211:52 | e | | -| variables.rs:210:9:211:52 | e | variables.rs:213:13:213:27 | ExprStmt | match | -| variables.rs:210:9:211:52 | e | variables.rs:219:9:219:9 | WildcardPat | no-match | -| variables.rs:212:12:218:9 | BlockExpr | variables.rs:209:5:220:5 | MatchExpr | | -| variables.rs:213:13:213:21 | PathExpr | variables.rs:213:23:213:25 | a11 | | -| variables.rs:213:13:213:26 | CallExpr | variables.rs:214:16:215:15 | LetExpr | | -| variables.rs:213:13:213:27 | ExprStmt | variables.rs:213:13:213:21 | PathExpr | | -| variables.rs:213:23:213:25 | a11 | variables.rs:213:13:213:26 | CallExpr | | -| variables.rs:214:13:217:13 | IfExpr | variables.rs:212:12:218:9 | BlockExpr | | -| variables.rs:214:16:215:15 | LetExpr | variables.rs:214:20:214:36 | TupleStructPat | | -| variables.rs:214:20:214:36 | TupleStructPat | variables.rs:214:13:217:13 | IfExpr | no-match | -| variables.rs:214:20:214:36 | TupleStructPat | variables.rs:216:17:216:32 | ExprStmt | match | -| variables.rs:215:17:217:13 | BlockExpr | variables.rs:214:13:217:13 | IfExpr | | -| variables.rs:216:17:216:25 | PathExpr | variables.rs:216:28:216:30 | a12 | | -| variables.rs:216:17:216:31 | CallExpr | variables.rs:215:17:217:13 | BlockExpr | | -| variables.rs:216:17:216:32 | ExprStmt | variables.rs:216:17:216:25 | PathExpr | | -| variables.rs:216:27:216:30 | * ... | variables.rs:216:17:216:31 | CallExpr | | -| variables.rs:216:28:216:30 | a12 | variables.rs:216:27:216:30 | * ... | | -| variables.rs:219:9:219:9 | WildcardPat | variables.rs:219:14:219:15 | TupleExpr | match | -| variables.rs:219:14:219:15 | TupleExpr | variables.rs:209:5:220:5 | MatchExpr | | -| variables.rs:230:1:236:1 | enter match_pattern9 | variables.rs:231:5:231:36 | LetStmt | | -| variables.rs:230:1:236:1 | exit match_pattern9 (normal) | variables.rs:230:1:236:1 | exit match_pattern9 | | -| variables.rs:230:21:236:1 | BlockExpr | variables.rs:230:1:236:1 | exit match_pattern9 (normal) | | -| variables.rs:231:5:231:36 | LetStmt | variables.rs:231:14:231:31 | PathExpr | | -| variables.rs:231:9:231:10 | fv | variables.rs:232:11:232:12 | fv | match, no-match | -| variables.rs:231:14:231:31 | PathExpr | variables.rs:231:33:231:34 | 62 | | -| variables.rs:231:14:231:35 | CallExpr | variables.rs:231:9:231:10 | fv | | -| variables.rs:231:33:231:34 | 62 | variables.rs:231:14:231:35 | CallExpr | | -| variables.rs:232:5:235:5 | MatchExpr | variables.rs:230:21:236:1 | BlockExpr | | -| variables.rs:232:11:232:12 | fv | variables.rs:233:9:233:109 | OrPat | | -| variables.rs:233:9:233:109 | OrPat | variables.rs:234:16:234:24 | PathExpr | match | -| variables.rs:234:16:234:24 | PathExpr | variables.rs:234:26:234:28 | a13 | | -| variables.rs:234:16:234:29 | CallExpr | variables.rs:232:5:235:5 | MatchExpr | | -| variables.rs:234:26:234:28 | a13 | variables.rs:234:16:234:29 | CallExpr | | -| variables.rs:238:1:247:1 | enter param_pattern1 | variables.rs:244:5:244:18 | ExprStmt | | -| variables.rs:238:1:247:1 | exit param_pattern1 (normal) | variables.rs:238:1:247:1 | exit param_pattern1 | | -| variables.rs:243:28:247:1 | BlockExpr | variables.rs:238:1:247:1 | exit param_pattern1 (normal) | | -| variables.rs:244:5:244:13 | PathExpr | variables.rs:244:15:244:16 | a8 | | -| variables.rs:244:5:244:17 | CallExpr | variables.rs:245:5:245:18 | ExprStmt | | -| variables.rs:244:5:244:18 | ExprStmt | variables.rs:244:5:244:13 | PathExpr | | -| variables.rs:244:15:244:16 | a8 | variables.rs:244:5:244:17 | CallExpr | | -| variables.rs:245:5:245:13 | PathExpr | variables.rs:245:15:245:16 | b3 | | -| variables.rs:245:5:245:17 | CallExpr | variables.rs:246:5:246:18 | ExprStmt | | -| variables.rs:245:5:245:18 | ExprStmt | variables.rs:245:5:245:13 | PathExpr | | -| variables.rs:245:15:245:16 | b3 | variables.rs:245:5:245:17 | CallExpr | | -| variables.rs:246:5:246:13 | PathExpr | variables.rs:246:15:246:16 | c1 | | -| variables.rs:246:5:246:17 | CallExpr | variables.rs:243:28:247:1 | BlockExpr | | -| variables.rs:246:5:246:18 | ExprStmt | variables.rs:246:5:246:13 | PathExpr | | -| variables.rs:246:15:246:16 | c1 | variables.rs:246:5:246:17 | CallExpr | | -| variables.rs:249:1:253:1 | enter param_pattern2 | variables.rs:252:5:252:18 | ExprStmt | | -| variables.rs:249:1:253:1 | exit param_pattern2 (normal) | variables.rs:249:1:253:1 | exit param_pattern2 | | -| variables.rs:251:9:253:1 | BlockExpr | variables.rs:249:1:253:1 | exit param_pattern2 (normal) | | -| variables.rs:252:5:252:13 | PathExpr | variables.rs:252:15:252:16 | a9 | | -| variables.rs:252:5:252:17 | CallExpr | variables.rs:251:9:253:1 | BlockExpr | | -| variables.rs:252:5:252:18 | ExprStmt | variables.rs:252:5:252:13 | PathExpr | | -| variables.rs:252:15:252:16 | a9 | variables.rs:252:5:252:17 | CallExpr | | -| variables.rs:255:1:290:1 | enter destruct_assignment | variables.rs:256:5:260:18 | LetStmt | | -| variables.rs:255:1:290:1 | exit destruct_assignment (normal) | variables.rs:255:1:290:1 | exit destruct_assignment | | -| variables.rs:255:26:290:1 | BlockExpr | variables.rs:255:1:290:1 | exit destruct_assignment (normal) | | -| variables.rs:256:5:260:18 | LetStmt | variables.rs:260:10:260:10 | 1 | | -| variables.rs:256:9:260:5 | TuplePat | variables.rs:261:5:261:19 | ExprStmt | match | -| variables.rs:260:9:260:17 | TupleExpr | variables.rs:256:9:260:5 | TuplePat | | -| variables.rs:260:10:260:10 | 1 | variables.rs:260:13:260:13 | 2 | | -| variables.rs:260:13:260:13 | 2 | variables.rs:260:16:260:16 | 3 | | -| variables.rs:260:16:260:16 | 3 | variables.rs:260:9:260:17 | TupleExpr | | -| variables.rs:261:5:261:13 | PathExpr | variables.rs:261:15:261:17 | a10 | | -| variables.rs:261:5:261:18 | CallExpr | variables.rs:262:5:262:18 | ExprStmt | | -| variables.rs:261:5:261:19 | ExprStmt | variables.rs:261:5:261:13 | PathExpr | | -| variables.rs:261:15:261:17 | a10 | variables.rs:261:5:261:18 | CallExpr | | -| variables.rs:262:5:262:13 | PathExpr | variables.rs:262:15:262:16 | b4 | | -| variables.rs:262:5:262:17 | CallExpr | variables.rs:263:5:263:18 | ExprStmt | | -| variables.rs:262:5:262:18 | ExprStmt | variables.rs:262:5:262:13 | PathExpr | | -| variables.rs:262:15:262:16 | b4 | variables.rs:262:5:262:17 | CallExpr | | -| variables.rs:263:5:263:13 | PathExpr | variables.rs:263:15:263:16 | c2 | | -| variables.rs:263:5:263:17 | CallExpr | variables.rs:265:5:273:6 | ExprStmt | | -| variables.rs:263:5:263:18 | ExprStmt | variables.rs:263:5:263:13 | PathExpr | | -| variables.rs:263:15:263:16 | c2 | variables.rs:263:5:263:17 | CallExpr | | -| variables.rs:265:5:269:5 | TupleExpr | variables.rs:270:9:270:11 | a10 | | -| variables.rs:265:5:273:5 | ... = ... | variables.rs:274:5:274:19 | ExprStmt | | -| variables.rs:265:5:273:6 | ExprStmt | variables.rs:266:9:266:10 | c2 | | -| variables.rs:266:9:266:10 | c2 | variables.rs:267:9:267:10 | b4 | | -| variables.rs:267:9:267:10 | b4 | variables.rs:268:9:268:11 | a10 | | -| variables.rs:268:9:268:11 | a10 | variables.rs:265:5:269:5 | TupleExpr | | -| variables.rs:269:9:273:5 | TupleExpr | variables.rs:265:5:273:5 | ... = ... | | -| variables.rs:270:9:270:11 | a10 | variables.rs:271:9:271:10 | b4 | | -| variables.rs:271:9:271:10 | b4 | variables.rs:272:9:272:10 | c2 | | -| variables.rs:272:9:272:10 | c2 | variables.rs:269:9:273:5 | TupleExpr | | -| variables.rs:274:5:274:13 | PathExpr | variables.rs:274:15:274:17 | a10 | | -| variables.rs:274:5:274:18 | CallExpr | variables.rs:275:5:275:18 | ExprStmt | | -| variables.rs:274:5:274:19 | ExprStmt | variables.rs:274:5:274:13 | PathExpr | | -| variables.rs:274:15:274:17 | a10 | variables.rs:274:5:274:18 | CallExpr | | -| variables.rs:275:5:275:13 | PathExpr | variables.rs:275:15:275:16 | b4 | | -| variables.rs:275:5:275:17 | CallExpr | variables.rs:276:5:276:18 | ExprStmt | | -| variables.rs:275:5:275:18 | ExprStmt | variables.rs:275:5:275:13 | PathExpr | | -| variables.rs:275:15:275:16 | b4 | variables.rs:275:5:275:17 | CallExpr | | -| variables.rs:276:5:276:13 | PathExpr | variables.rs:276:15:276:16 | c2 | | -| variables.rs:276:5:276:17 | CallExpr | variables.rs:278:5:286:5 | ExprStmt | | -| variables.rs:276:5:276:18 | ExprStmt | variables.rs:276:5:276:13 | PathExpr | | -| variables.rs:276:15:276:16 | c2 | variables.rs:276:5:276:17 | CallExpr | | -| variables.rs:278:5:286:5 | ExprStmt | variables.rs:278:12:278:12 | 4 | | -| variables.rs:278:5:286:5 | MatchExpr | variables.rs:288:5:288:19 | ExprStmt | | -| variables.rs:278:11:278:16 | TupleExpr | variables.rs:279:9:282:9 | TuplePat | | -| variables.rs:278:12:278:12 | 4 | variables.rs:278:15:278:15 | 5 | | -| variables.rs:278:15:278:15 | 5 | variables.rs:278:11:278:16 | TupleExpr | | -| variables.rs:279:9:282:9 | TuplePat | variables.rs:283:13:283:27 | ExprStmt | match | -| variables.rs:282:14:285:9 | BlockExpr | variables.rs:278:5:286:5 | MatchExpr | | -| variables.rs:283:13:283:21 | PathExpr | variables.rs:283:23:283:25 | a10 | | -| variables.rs:283:13:283:26 | CallExpr | variables.rs:284:13:284:26 | ExprStmt | | -| variables.rs:283:13:283:27 | ExprStmt | variables.rs:283:13:283:21 | PathExpr | | -| variables.rs:283:23:283:25 | a10 | variables.rs:283:13:283:26 | CallExpr | | -| variables.rs:284:13:284:21 | PathExpr | variables.rs:284:23:284:24 | b4 | | -| variables.rs:284:13:284:25 | CallExpr | variables.rs:282:14:285:9 | BlockExpr | | -| variables.rs:284:13:284:26 | ExprStmt | variables.rs:284:13:284:21 | PathExpr | | -| variables.rs:284:23:284:24 | b4 | variables.rs:284:13:284:25 | CallExpr | | -| variables.rs:288:5:288:13 | PathExpr | variables.rs:288:15:288:17 | a10 | | -| variables.rs:288:5:288:18 | CallExpr | variables.rs:289:5:289:18 | ExprStmt | | -| variables.rs:288:5:288:19 | ExprStmt | variables.rs:288:5:288:13 | PathExpr | | -| variables.rs:288:15:288:17 | a10 | variables.rs:288:5:288:18 | CallExpr | | -| variables.rs:289:5:289:13 | PathExpr | variables.rs:289:15:289:16 | b4 | | -| variables.rs:289:5:289:17 | CallExpr | variables.rs:255:26:290:1 | BlockExpr | | -| variables.rs:289:5:289:18 | ExprStmt | variables.rs:289:5:289:13 | PathExpr | | -| variables.rs:289:15:289:16 | b4 | variables.rs:289:5:289:17 | CallExpr | | -| variables.rs:292:1:307:1 | enter closure_variable | variables.rs:293:5:295:10 | LetStmt | | -| variables.rs:292:1:307:1 | exit closure_variable (normal) | variables.rs:292:1:307:1 | exit closure_variable | | -| variables.rs:292:23:307:1 | BlockExpr | variables.rs:292:1:307:1 | exit closure_variable (normal) | | -| variables.rs:293:5:295:10 | LetStmt | variables.rs:294:9:295:9 | ClosureExpr | | -| variables.rs:293:9:293:23 | example_closure | variables.rs:296:5:297:27 | LetStmt | match, no-match | -| variables.rs:294:9:295:9 | ClosureExpr | variables.rs:293:9:293:23 | example_closure | | -| variables.rs:294:9:295:9 | enter ClosureExpr | variables.rs:295:9:295:9 | x | | -| variables.rs:294:9:295:9 | exit ClosureExpr (normal) | variables.rs:294:9:295:9 | exit ClosureExpr | | -| variables.rs:295:9:295:9 | x | variables.rs:294:9:295:9 | exit ClosureExpr (normal) | | -| variables.rs:296:5:297:27 | LetStmt | variables.rs:297:9:297:23 | example_closure | | -| variables.rs:296:9:296:10 | n1 | variables.rs:298:5:298:18 | ExprStmt | match, no-match | -| variables.rs:297:9:297:23 | example_closure | variables.rs:297:25:297:25 | 5 | | -| variables.rs:297:9:297:26 | CallExpr | variables.rs:296:9:296:10 | n1 | | -| variables.rs:297:25:297:25 | 5 | variables.rs:297:9:297:26 | CallExpr | | -| variables.rs:298:5:298:13 | PathExpr | variables.rs:298:15:298:16 | n1 | | -| variables.rs:298:5:298:17 | CallExpr | variables.rs:300:5:300:25 | ExprStmt | | +| variables.rs:88:1:95:1 | enter let_pattern5 | variables.rs:89:5:89:42 | LetStmt | | +| variables.rs:88:1:95:1 | exit let_pattern5 (normal) | variables.rs:88:1:95:1 | exit let_pattern5 | | +| variables.rs:88:19:95:1 | BlockExpr | variables.rs:88:1:95:1 | exit let_pattern5 (normal) | | +| variables.rs:89:5:89:42 | LetStmt | variables.rs:89:14:89:17 | PathExpr | | +| variables.rs:89:9:89:10 | s1 | variables.rs:91:11:92:12 | LetExpr | match, no-match | +| variables.rs:89:14:89:17 | PathExpr | variables.rs:89:19:89:30 | PathExpr | | +| variables.rs:89:14:89:41 | CallExpr | variables.rs:89:9:89:10 | s1 | | +| variables.rs:89:19:89:30 | PathExpr | variables.rs:89:32:89:39 | "Hello!" | | +| variables.rs:89:19:89:40 | CallExpr | variables.rs:89:14:89:41 | CallExpr | | +| variables.rs:89:32:89:39 | "Hello!" | variables.rs:89:19:89:40 | CallExpr | | +| variables.rs:91:5:94:5 | WhileExpr | variables.rs:88:19:95:1 | BlockExpr | | +| variables.rs:91:11:92:12 | LetExpr | variables.rs:91:15:91:26 | TupleStructPat | | +| variables.rs:91:15:91:26 | TupleStructPat | variables.rs:91:5:94:5 | WhileExpr | no-match | +| variables.rs:91:15:91:26 | TupleStructPat | variables.rs:93:9:93:22 | ExprStmt | match | +| variables.rs:92:14:94:5 | BlockExpr | variables.rs:91:11:92:12 | LetExpr | | +| variables.rs:93:9:93:17 | PathExpr | variables.rs:93:19:93:20 | s2 | | +| variables.rs:93:9:93:21 | CallExpr | variables.rs:92:14:94:5 | BlockExpr | | +| variables.rs:93:9:93:22 | ExprStmt | variables.rs:93:9:93:17 | PathExpr | | +| variables.rs:93:19:93:20 | s2 | variables.rs:93:9:93:21 | CallExpr | | +| variables.rs:97:1:112:1 | enter match_pattern1 | variables.rs:98:5:98:21 | LetStmt | | +| variables.rs:97:1:112:1 | exit match_pattern1 (normal) | variables.rs:97:1:112:1 | exit match_pattern1 | | +| variables.rs:97:21:112:1 | BlockExpr | variables.rs:97:1:112:1 | exit match_pattern1 (normal) | | +| variables.rs:98:5:98:21 | LetStmt | variables.rs:98:14:98:17 | PathExpr | | +| variables.rs:98:9:98:10 | x6 | variables.rs:99:5:99:16 | LetStmt | match, no-match | +| variables.rs:98:14:98:17 | PathExpr | variables.rs:98:19:98:19 | 5 | | +| variables.rs:98:14:98:20 | CallExpr | variables.rs:98:9:98:10 | x6 | | +| variables.rs:98:19:98:19 | 5 | variables.rs:98:14:98:20 | CallExpr | | +| variables.rs:99:5:99:16 | LetStmt | variables.rs:99:14:99:15 | 10 | | +| variables.rs:99:9:99:10 | y1 | variables.rs:101:5:109:5 | ExprStmt | match, no-match | +| variables.rs:99:14:99:15 | 10 | variables.rs:99:9:99:10 | y1 | | +| variables.rs:101:5:109:5 | ExprStmt | variables.rs:101:11:101:12 | x6 | | +| variables.rs:101:5:109:5 | MatchExpr | variables.rs:111:5:111:18 | ExprStmt | | +| variables.rs:101:11:101:12 | x6 | variables.rs:102:9:102:16 | TupleStructPat | | +| variables.rs:102:9:102:16 | TupleStructPat | variables.rs:102:21:102:29 | PathExpr | match | +| variables.rs:102:9:102:16 | TupleStructPat | variables.rs:103:9:103:16 | TupleStructPat | no-match | +| variables.rs:102:21:102:29 | PathExpr | variables.rs:102:31:102:38 | "Got 50" | | +| variables.rs:102:21:102:39 | CallExpr | variables.rs:101:5:109:5 | MatchExpr | | +| variables.rs:102:31:102:38 | "Got 50" | variables.rs:102:21:102:39 | CallExpr | | +| variables.rs:103:9:103:16 | TupleStructPat | variables.rs:106:13:106:21 | PathExpr | match | +| variables.rs:103:9:103:16 | TupleStructPat | variables.rs:108:9:108:12 | None | no-match | +| variables.rs:105:9:107:9 | BlockExpr | variables.rs:101:5:109:5 | MatchExpr | | +| variables.rs:106:13:106:21 | PathExpr | variables.rs:106:23:106:24 | y1 | | +| variables.rs:106:13:106:25 | CallExpr | variables.rs:105:9:107:9 | BlockExpr | | +| variables.rs:106:23:106:24 | y1 | variables.rs:106:13:106:25 | CallExpr | | +| variables.rs:108:9:108:12 | None | variables.rs:108:17:108:25 | PathExpr | match | +| variables.rs:108:17:108:25 | PathExpr | variables.rs:108:27:108:32 | "NONE" | | +| variables.rs:108:17:108:33 | CallExpr | variables.rs:101:5:109:5 | MatchExpr | | +| variables.rs:108:27:108:32 | "NONE" | variables.rs:108:17:108:33 | CallExpr | | +| variables.rs:111:5:111:13 | PathExpr | variables.rs:111:15:111:16 | y1 | | +| variables.rs:111:5:111:17 | CallExpr | variables.rs:97:21:112:1 | BlockExpr | | +| variables.rs:111:5:111:18 | ExprStmt | variables.rs:111:5:111:13 | PathExpr | | +| variables.rs:111:15:111:16 | y1 | variables.rs:111:5:111:17 | CallExpr | | +| variables.rs:114:1:139:1 | enter match_pattern2 | variables.rs:115:5:115:36 | LetStmt | | +| variables.rs:114:1:139:1 | exit match_pattern2 (normal) | variables.rs:114:1:139:1 | exit match_pattern2 | | +| variables.rs:114:21:139:1 | BlockExpr | variables.rs:114:1:139:1 | exit match_pattern2 (normal) | | +| variables.rs:115:5:115:36 | LetStmt | variables.rs:115:20:115:20 | 2 | | +| variables.rs:115:9:115:15 | numbers | variables.rs:117:5:127:5 | ExprStmt | match, no-match | +| variables.rs:115:19:115:35 | TupleExpr | variables.rs:115:9:115:15 | numbers | | +| variables.rs:115:20:115:20 | 2 | variables.rs:115:23:115:23 | 4 | | +| variables.rs:115:23:115:23 | 4 | variables.rs:115:26:115:26 | 8 | | +| variables.rs:115:26:115:26 | 8 | variables.rs:115:29:115:30 | 16 | | +| variables.rs:115:29:115:30 | 16 | variables.rs:115:33:115:34 | 32 | | +| variables.rs:115:33:115:34 | 32 | variables.rs:115:19:115:35 | TupleExpr | | +| variables.rs:117:5:127:5 | ExprStmt | variables.rs:117:11:117:17 | numbers | | +| variables.rs:117:5:127:5 | MatchExpr | variables.rs:129:11:129:17 | numbers | | +| variables.rs:117:11:117:17 | numbers | variables.rs:118:9:122:9 | TuplePat | | +| variables.rs:118:9:122:9 | TuplePat | variables.rs:123:13:123:29 | ExprStmt | match | +| variables.rs:122:14:126:9 | BlockExpr | variables.rs:117:5:127:5 | MatchExpr | | +| variables.rs:123:13:123:21 | PathExpr | variables.rs:123:23:123:27 | first | | +| variables.rs:123:13:123:28 | CallExpr | variables.rs:124:13:124:29 | ExprStmt | | +| variables.rs:123:13:123:29 | ExprStmt | variables.rs:123:13:123:21 | PathExpr | | +| variables.rs:123:23:123:27 | first | variables.rs:123:13:123:28 | CallExpr | | +| variables.rs:124:13:124:21 | PathExpr | variables.rs:124:23:124:27 | third | | +| variables.rs:124:13:124:28 | CallExpr | variables.rs:125:13:125:29 | ExprStmt | | +| variables.rs:124:13:124:29 | ExprStmt | variables.rs:124:13:124:21 | PathExpr | | +| variables.rs:124:23:124:27 | third | variables.rs:124:13:124:28 | CallExpr | | +| variables.rs:125:13:125:21 | PathExpr | variables.rs:125:23:125:27 | fifth | | +| variables.rs:125:13:125:28 | CallExpr | variables.rs:122:14:126:9 | BlockExpr | | +| variables.rs:125:13:125:29 | ExprStmt | variables.rs:125:13:125:21 | PathExpr | | +| variables.rs:125:23:125:27 | fifth | variables.rs:125:13:125:28 | CallExpr | | +| variables.rs:129:5:138:5 | MatchExpr | variables.rs:114:21:139:1 | BlockExpr | | +| variables.rs:129:11:129:17 | numbers | variables.rs:130:9:134:9 | TuplePat | | +| variables.rs:130:9:134:9 | TuplePat | variables.rs:135:13:135:29 | ExprStmt | match | +| variables.rs:134:14:137:9 | BlockExpr | variables.rs:129:5:138:5 | MatchExpr | | +| variables.rs:135:13:135:21 | PathExpr | variables.rs:135:23:135:27 | first | | +| variables.rs:135:13:135:28 | CallExpr | variables.rs:136:13:136:28 | ExprStmt | | +| variables.rs:135:13:135:29 | ExprStmt | variables.rs:135:13:135:21 | PathExpr | | +| variables.rs:135:23:135:27 | first | variables.rs:135:13:135:28 | CallExpr | | +| variables.rs:136:13:136:21 | PathExpr | variables.rs:136:23:136:26 | last | | +| variables.rs:136:13:136:27 | CallExpr | variables.rs:134:14:137:9 | BlockExpr | | +| variables.rs:136:13:136:28 | ExprStmt | variables.rs:136:13:136:21 | PathExpr | | +| variables.rs:136:23:136:26 | last | variables.rs:136:13:136:27 | CallExpr | | +| variables.rs:141:1:149:1 | enter match_pattern3 | variables.rs:142:5:142:38 | LetStmt | | +| variables.rs:141:1:149:1 | exit match_pattern3 (normal) | variables.rs:141:1:149:1 | exit match_pattern3 | | +| variables.rs:141:21:149:1 | BlockExpr | variables.rs:141:1:149:1 | exit match_pattern3 (normal) | | +| variables.rs:142:5:142:38 | LetStmt | variables.rs:142:25:142:27 | "x" | | +| variables.rs:142:9:142:10 | p2 | variables.rs:144:11:144:12 | p2 | match, no-match | +| variables.rs:142:14:142:37 | RecordExpr | variables.rs:142:9:142:10 | p2 | | +| variables.rs:142:25:142:27 | "x" | variables.rs:142:33:142:35 | "y" | | +| variables.rs:142:33:142:35 | "y" | variables.rs:142:14:142:37 | RecordExpr | | +| variables.rs:144:5:148:5 | MatchExpr | variables.rs:141:21:149:1 | BlockExpr | | +| variables.rs:144:11:144:12 | p2 | variables.rs:145:9:147:9 | RecordPat | | +| variables.rs:145:9:147:9 | RecordPat | variables.rs:147:14:147:22 | PathExpr | match | +| variables.rs:147:14:147:22 | PathExpr | variables.rs:147:24:147:25 | x7 | | +| variables.rs:147:14:147:26 | CallExpr | variables.rs:144:5:148:5 | MatchExpr | | +| variables.rs:147:24:147:25 | x7 | variables.rs:147:14:147:26 | CallExpr | | +| variables.rs:155:1:168:1 | enter match_pattern4 | variables.rs:156:5:156:39 | LetStmt | | +| variables.rs:155:1:168:1 | exit match_pattern4 (normal) | variables.rs:155:1:168:1 | exit match_pattern4 | | +| variables.rs:155:21:168:1 | BlockExpr | variables.rs:155:1:168:1 | exit match_pattern4 (normal) | | +| variables.rs:156:5:156:39 | LetStmt | variables.rs:156:36:156:36 | 0 | | +| variables.rs:156:9:156:11 | msg | variables.rs:158:11:158:13 | msg | match, no-match | +| variables.rs:156:15:156:38 | RecordExpr | variables.rs:156:9:156:11 | msg | | +| variables.rs:156:36:156:36 | 0 | variables.rs:156:15:156:38 | RecordExpr | | +| variables.rs:158:5:167:5 | MatchExpr | variables.rs:155:21:168:1 | BlockExpr | | +| variables.rs:158:11:158:13 | msg | variables.rs:159:9:161:9 | RecordPat | | +| variables.rs:159:9:161:9 | RecordPat | variables.rs:161:14:161:22 | PathExpr | match | +| variables.rs:159:9:161:9 | RecordPat | variables.rs:162:9:162:38 | RecordPat | no-match | +| variables.rs:161:14:161:22 | PathExpr | variables.rs:161:24:161:34 | id_variable | | +| variables.rs:161:14:161:35 | CallExpr | variables.rs:158:5:167:5 | MatchExpr | | +| variables.rs:161:24:161:34 | id_variable | variables.rs:161:14:161:35 | CallExpr | | +| variables.rs:162:9:162:38 | RecordPat | variables.rs:163:13:163:52 | MacroExpr | match | +| variables.rs:162:9:162:38 | RecordPat | variables.rs:165:9:165:29 | RecordPat | no-match | +| variables.rs:162:43:164:9 | BlockExpr | variables.rs:158:5:167:5 | MatchExpr | | +| variables.rs:163:13:163:52 | MacroExpr | variables.rs:162:43:164:9 | BlockExpr | | +| variables.rs:165:9:165:29 | RecordPat | variables.rs:166:13:166:21 | PathExpr | match | +| variables.rs:166:13:166:21 | PathExpr | variables.rs:166:23:166:24 | id | | +| variables.rs:166:13:166:25 | CallExpr | variables.rs:158:5:167:5 | MatchExpr | | +| variables.rs:166:23:166:24 | id | variables.rs:166:13:166:25 | CallExpr | | +| variables.rs:175:1:181:1 | enter match_pattern5 | variables.rs:176:5:176:34 | LetStmt | | +| variables.rs:175:1:181:1 | exit match_pattern5 (normal) | variables.rs:175:1:181:1 | exit match_pattern5 | | +| variables.rs:175:21:181:1 | BlockExpr | variables.rs:175:1:181:1 | exit match_pattern5 (normal) | | +| variables.rs:176:5:176:34 | LetStmt | variables.rs:176:18:176:29 | PathExpr | | +| variables.rs:176:9:176:14 | either | variables.rs:177:11:177:16 | either | match, no-match | +| variables.rs:176:18:176:29 | PathExpr | variables.rs:176:31:176:32 | 32 | | +| variables.rs:176:18:176:33 | CallExpr | variables.rs:176:9:176:14 | either | | +| variables.rs:176:31:176:32 | 32 | variables.rs:176:18:176:33 | CallExpr | | +| variables.rs:177:5:180:5 | MatchExpr | variables.rs:175:21:181:1 | BlockExpr | | +| variables.rs:177:11:177:16 | either | variables.rs:178:9:178:44 | OrPat | | +| variables.rs:178:9:178:44 | OrPat | variables.rs:179:16:179:24 | PathExpr | match | +| variables.rs:179:16:179:24 | PathExpr | variables.rs:179:26:179:27 | a3 | | +| variables.rs:179:16:179:28 | CallExpr | variables.rs:177:5:180:5 | MatchExpr | | +| variables.rs:179:26:179:27 | a3 | variables.rs:179:16:179:28 | CallExpr | | +| variables.rs:189:1:203:1 | enter match_pattern6 | variables.rs:190:5:190:37 | LetStmt | | +| variables.rs:189:1:203:1 | exit match_pattern6 (normal) | variables.rs:189:1:203:1 | exit match_pattern6 | | +| variables.rs:189:21:203:1 | BlockExpr | variables.rs:189:1:203:1 | exit match_pattern6 (normal) | | +| variables.rs:190:5:190:37 | LetStmt | variables.rs:190:14:190:32 | PathExpr | | +| variables.rs:190:9:190:10 | tv | variables.rs:191:5:194:5 | ExprStmt | match, no-match | +| variables.rs:190:14:190:32 | PathExpr | variables.rs:190:34:190:35 | 62 | | +| variables.rs:190:14:190:36 | CallExpr | variables.rs:190:9:190:10 | tv | | +| variables.rs:190:34:190:35 | 62 | variables.rs:190:14:190:36 | CallExpr | | +| variables.rs:191:5:194:5 | ExprStmt | variables.rs:191:11:191:12 | tv | | +| variables.rs:191:5:194:5 | MatchExpr | variables.rs:195:5:198:5 | ExprStmt | | +| variables.rs:191:11:191:12 | tv | variables.rs:192:9:192:81 | OrPat | | +| variables.rs:192:9:192:81 | OrPat | variables.rs:193:16:193:24 | PathExpr | match | +| variables.rs:193:16:193:24 | PathExpr | variables.rs:193:26:193:27 | a4 | | +| variables.rs:193:16:193:28 | CallExpr | variables.rs:191:5:194:5 | MatchExpr | | +| variables.rs:193:26:193:27 | a4 | variables.rs:193:16:193:28 | CallExpr | | +| variables.rs:195:5:198:5 | ExprStmt | variables.rs:195:11:195:12 | tv | | +| variables.rs:195:5:198:5 | MatchExpr | variables.rs:199:11:199:12 | tv | | +| variables.rs:195:11:195:12 | tv | variables.rs:196:9:196:83 | OrPat | | +| variables.rs:196:9:196:83 | OrPat | variables.rs:197:16:197:24 | PathExpr | match | +| variables.rs:197:16:197:24 | PathExpr | variables.rs:197:26:197:27 | a5 | | +| variables.rs:197:16:197:28 | CallExpr | variables.rs:195:5:198:5 | MatchExpr | | +| variables.rs:197:26:197:27 | a5 | variables.rs:197:16:197:28 | CallExpr | | +| variables.rs:199:5:202:5 | MatchExpr | variables.rs:189:21:203:1 | BlockExpr | | +| variables.rs:199:11:199:12 | tv | variables.rs:200:9:200:83 | OrPat | | +| variables.rs:200:9:200:83 | OrPat | variables.rs:201:16:201:24 | PathExpr | match | +| variables.rs:201:16:201:24 | PathExpr | variables.rs:201:26:201:27 | a6 | | +| variables.rs:201:16:201:28 | CallExpr | variables.rs:199:5:202:5 | MatchExpr | | +| variables.rs:201:26:201:27 | a6 | variables.rs:201:16:201:28 | CallExpr | | +| variables.rs:205:1:213:1 | enter match_pattern7 | variables.rs:206:5:206:34 | LetStmt | | +| variables.rs:205:1:213:1 | exit match_pattern7 (normal) | variables.rs:205:1:213:1 | exit match_pattern7 | | +| variables.rs:205:21:213:1 | BlockExpr | variables.rs:205:1:213:1 | exit match_pattern7 (normal) | | +| variables.rs:206:5:206:34 | LetStmt | variables.rs:206:18:206:29 | PathExpr | | +| variables.rs:206:9:206:14 | either | variables.rs:207:11:207:16 | either | match, no-match | +| variables.rs:206:18:206:29 | PathExpr | variables.rs:206:31:206:32 | 32 | | +| variables.rs:206:18:206:33 | CallExpr | variables.rs:206:9:206:14 | either | | +| variables.rs:206:31:206:32 | 32 | variables.rs:206:18:206:33 | CallExpr | | +| variables.rs:207:5:212:5 | MatchExpr | variables.rs:205:21:213:1 | BlockExpr | | +| variables.rs:207:11:207:16 | either | variables.rs:208:9:208:44 | OrPat | | +| variables.rs:208:9:208:44 | OrPat | variables.rs:209:16:209:17 | a7 | match | +| variables.rs:208:9:208:44 | OrPat | variables.rs:211:9:211:9 | WildcardPat | no-match | +| variables.rs:209:16:209:17 | a7 | variables.rs:209:21:209:21 | 0 | | +| variables.rs:209:16:209:21 | ... > ... | variables.rs:210:16:210:24 | PathExpr | true | +| variables.rs:209:16:209:21 | ... > ... | variables.rs:211:9:211:9 | WildcardPat | false | +| variables.rs:209:21:209:21 | 0 | variables.rs:209:16:209:21 | ... > ... | | +| variables.rs:210:16:210:24 | PathExpr | variables.rs:210:26:210:27 | a7 | | +| variables.rs:210:16:210:28 | CallExpr | variables.rs:207:5:212:5 | MatchExpr | | +| variables.rs:210:26:210:27 | a7 | variables.rs:210:16:210:28 | CallExpr | | +| variables.rs:211:9:211:9 | WildcardPat | variables.rs:211:14:211:15 | TupleExpr | match | +| variables.rs:211:14:211:15 | TupleExpr | variables.rs:207:5:212:5 | MatchExpr | | +| variables.rs:215:1:230:1 | enter match_pattern8 | variables.rs:216:5:216:34 | LetStmt | | +| variables.rs:215:1:230:1 | exit match_pattern8 (normal) | variables.rs:215:1:230:1 | exit match_pattern8 | | +| variables.rs:215:21:230:1 | BlockExpr | variables.rs:215:1:230:1 | exit match_pattern8 (normal) | | +| variables.rs:216:5:216:34 | LetStmt | variables.rs:216:18:216:29 | PathExpr | | +| variables.rs:216:9:216:14 | either | variables.rs:218:11:218:16 | either | match, no-match | +| variables.rs:216:18:216:29 | PathExpr | variables.rs:216:31:216:32 | 32 | | +| variables.rs:216:18:216:33 | CallExpr | variables.rs:216:9:216:14 | either | | +| variables.rs:216:31:216:32 | 32 | variables.rs:216:18:216:33 | CallExpr | | +| variables.rs:218:5:229:5 | MatchExpr | variables.rs:215:21:230:1 | BlockExpr | | +| variables.rs:218:11:218:16 | either | variables.rs:219:9:220:52 | e | | +| variables.rs:219:9:220:52 | e | variables.rs:222:13:222:27 | ExprStmt | match | +| variables.rs:219:9:220:52 | e | variables.rs:228:9:228:9 | WildcardPat | no-match | +| variables.rs:221:12:227:9 | BlockExpr | variables.rs:218:5:229:5 | MatchExpr | | +| variables.rs:222:13:222:21 | PathExpr | variables.rs:222:23:222:25 | a11 | | +| variables.rs:222:13:222:26 | CallExpr | variables.rs:223:16:224:15 | LetExpr | | +| variables.rs:222:13:222:27 | ExprStmt | variables.rs:222:13:222:21 | PathExpr | | +| variables.rs:222:23:222:25 | a11 | variables.rs:222:13:222:26 | CallExpr | | +| variables.rs:223:13:226:13 | IfExpr | variables.rs:221:12:227:9 | BlockExpr | | +| variables.rs:223:16:224:15 | LetExpr | variables.rs:223:20:223:36 | TupleStructPat | | +| variables.rs:223:20:223:36 | TupleStructPat | variables.rs:223:13:226:13 | IfExpr | no-match | +| variables.rs:223:20:223:36 | TupleStructPat | variables.rs:225:17:225:32 | ExprStmt | match | +| variables.rs:224:17:226:13 | BlockExpr | variables.rs:223:13:226:13 | IfExpr | | +| variables.rs:225:17:225:25 | PathExpr | variables.rs:225:28:225:30 | a12 | | +| variables.rs:225:17:225:31 | CallExpr | variables.rs:224:17:226:13 | BlockExpr | | +| variables.rs:225:17:225:32 | ExprStmt | variables.rs:225:17:225:25 | PathExpr | | +| variables.rs:225:27:225:30 | * ... | variables.rs:225:17:225:31 | CallExpr | | +| variables.rs:225:28:225:30 | a12 | variables.rs:225:27:225:30 | * ... | | +| variables.rs:228:9:228:9 | WildcardPat | variables.rs:228:14:228:15 | TupleExpr | match | +| variables.rs:228:14:228:15 | TupleExpr | variables.rs:218:5:229:5 | MatchExpr | | +| variables.rs:239:1:245:1 | enter match_pattern9 | variables.rs:240:5:240:36 | LetStmt | | +| variables.rs:239:1:245:1 | exit match_pattern9 (normal) | variables.rs:239:1:245:1 | exit match_pattern9 | | +| variables.rs:239:21:245:1 | BlockExpr | variables.rs:239:1:245:1 | exit match_pattern9 (normal) | | +| variables.rs:240:5:240:36 | LetStmt | variables.rs:240:14:240:31 | PathExpr | | +| variables.rs:240:9:240:10 | fv | variables.rs:241:11:241:12 | fv | match, no-match | +| variables.rs:240:14:240:31 | PathExpr | variables.rs:240:33:240:34 | 62 | | +| variables.rs:240:14:240:35 | CallExpr | variables.rs:240:9:240:10 | fv | | +| variables.rs:240:33:240:34 | 62 | variables.rs:240:14:240:35 | CallExpr | | +| variables.rs:241:5:244:5 | MatchExpr | variables.rs:239:21:245:1 | BlockExpr | | +| variables.rs:241:11:241:12 | fv | variables.rs:242:9:242:109 | OrPat | | +| variables.rs:242:9:242:109 | OrPat | variables.rs:243:16:243:24 | PathExpr | match | +| variables.rs:243:16:243:24 | PathExpr | variables.rs:243:26:243:28 | a13 | | +| variables.rs:243:16:243:29 | CallExpr | variables.rs:241:5:244:5 | MatchExpr | | +| variables.rs:243:26:243:28 | a13 | variables.rs:243:16:243:29 | CallExpr | | +| variables.rs:247:1:256:1 | enter param_pattern1 | variables.rs:253:5:253:18 | ExprStmt | | +| variables.rs:247:1:256:1 | exit param_pattern1 (normal) | variables.rs:247:1:256:1 | exit param_pattern1 | | +| variables.rs:252:28:256:1 | BlockExpr | variables.rs:247:1:256:1 | exit param_pattern1 (normal) | | +| variables.rs:253:5:253:13 | PathExpr | variables.rs:253:15:253:16 | a8 | | +| variables.rs:253:5:253:17 | CallExpr | variables.rs:254:5:254:18 | ExprStmt | | +| variables.rs:253:5:253:18 | ExprStmt | variables.rs:253:5:253:13 | PathExpr | | +| variables.rs:253:15:253:16 | a8 | variables.rs:253:5:253:17 | CallExpr | | +| variables.rs:254:5:254:13 | PathExpr | variables.rs:254:15:254:16 | b3 | | +| variables.rs:254:5:254:17 | CallExpr | variables.rs:255:5:255:18 | ExprStmt | | +| variables.rs:254:5:254:18 | ExprStmt | variables.rs:254:5:254:13 | PathExpr | | +| variables.rs:254:15:254:16 | b3 | variables.rs:254:5:254:17 | CallExpr | | +| variables.rs:255:5:255:13 | PathExpr | variables.rs:255:15:255:16 | c1 | | +| variables.rs:255:5:255:17 | CallExpr | variables.rs:252:28:256:1 | BlockExpr | | +| variables.rs:255:5:255:18 | ExprStmt | variables.rs:255:5:255:13 | PathExpr | | +| variables.rs:255:15:255:16 | c1 | variables.rs:255:5:255:17 | CallExpr | | +| variables.rs:258:1:262:1 | enter param_pattern2 | variables.rs:261:5:261:18 | ExprStmt | | +| variables.rs:258:1:262:1 | exit param_pattern2 (normal) | variables.rs:258:1:262:1 | exit param_pattern2 | | +| variables.rs:260:9:262:1 | BlockExpr | variables.rs:258:1:262:1 | exit param_pattern2 (normal) | | +| variables.rs:261:5:261:13 | PathExpr | variables.rs:261:15:261:16 | a9 | | +| variables.rs:261:5:261:17 | CallExpr | variables.rs:260:9:262:1 | BlockExpr | | +| variables.rs:261:5:261:18 | ExprStmt | variables.rs:261:5:261:13 | PathExpr | | +| variables.rs:261:15:261:16 | a9 | variables.rs:261:5:261:17 | CallExpr | | +| variables.rs:264:1:299:1 | enter destruct_assignment | variables.rs:265:5:269:18 | LetStmt | | +| variables.rs:264:1:299:1 | exit destruct_assignment (normal) | variables.rs:264:1:299:1 | exit destruct_assignment | | +| variables.rs:264:26:299:1 | BlockExpr | variables.rs:264:1:299:1 | exit destruct_assignment (normal) | | +| variables.rs:265:5:269:18 | LetStmt | variables.rs:269:10:269:10 | 1 | | +| variables.rs:265:9:269:5 | TuplePat | variables.rs:270:5:270:19 | ExprStmt | match | +| variables.rs:269:9:269:17 | TupleExpr | variables.rs:265:9:269:5 | TuplePat | | +| variables.rs:269:10:269:10 | 1 | variables.rs:269:13:269:13 | 2 | | +| variables.rs:269:13:269:13 | 2 | variables.rs:269:16:269:16 | 3 | | +| variables.rs:269:16:269:16 | 3 | variables.rs:269:9:269:17 | TupleExpr | | +| variables.rs:270:5:270:13 | PathExpr | variables.rs:270:15:270:17 | a10 | | +| variables.rs:270:5:270:18 | CallExpr | variables.rs:271:5:271:18 | ExprStmt | | +| variables.rs:270:5:270:19 | ExprStmt | variables.rs:270:5:270:13 | PathExpr | | +| variables.rs:270:15:270:17 | a10 | variables.rs:270:5:270:18 | CallExpr | | +| variables.rs:271:5:271:13 | PathExpr | variables.rs:271:15:271:16 | b4 | | +| variables.rs:271:5:271:17 | CallExpr | variables.rs:272:5:272:18 | ExprStmt | | +| variables.rs:271:5:271:18 | ExprStmt | variables.rs:271:5:271:13 | PathExpr | | +| variables.rs:271:15:271:16 | b4 | variables.rs:271:5:271:17 | CallExpr | | +| variables.rs:272:5:272:13 | PathExpr | variables.rs:272:15:272:16 | c2 | | +| variables.rs:272:5:272:17 | CallExpr | variables.rs:274:5:282:6 | ExprStmt | | +| variables.rs:272:5:272:18 | ExprStmt | variables.rs:272:5:272:13 | PathExpr | | +| variables.rs:272:15:272:16 | c2 | variables.rs:272:5:272:17 | CallExpr | | +| variables.rs:274:5:278:5 | TupleExpr | variables.rs:279:9:279:11 | a10 | | +| variables.rs:274:5:282:5 | ... = ... | variables.rs:283:5:283:19 | ExprStmt | | +| variables.rs:274:5:282:6 | ExprStmt | variables.rs:275:9:275:10 | c2 | | +| variables.rs:275:9:275:10 | c2 | variables.rs:276:9:276:10 | b4 | | +| variables.rs:276:9:276:10 | b4 | variables.rs:277:9:277:11 | a10 | | +| variables.rs:277:9:277:11 | a10 | variables.rs:274:5:278:5 | TupleExpr | | +| variables.rs:278:9:282:5 | TupleExpr | variables.rs:274:5:282:5 | ... = ... | | +| variables.rs:279:9:279:11 | a10 | variables.rs:280:9:280:10 | b4 | | +| variables.rs:280:9:280:10 | b4 | variables.rs:281:9:281:10 | c2 | | +| variables.rs:281:9:281:10 | c2 | variables.rs:278:9:282:5 | TupleExpr | | +| variables.rs:283:5:283:13 | PathExpr | 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:19 | ExprStmt | variables.rs:283:5:283:13 | PathExpr | | +| variables.rs:283:15:283:17 | a10 | variables.rs:283:5:283:18 | CallExpr | | +| variables.rs:284:5:284:13 | PathExpr | 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:18 | ExprStmt | variables.rs:284:5:284:13 | PathExpr | | +| variables.rs:284:15:284:16 | b4 | variables.rs:284:5:284:17 | CallExpr | | +| variables.rs:285:5:285:13 | PathExpr | variables.rs:285:15:285:16 | c2 | | +| variables.rs:285:5:285:17 | CallExpr | variables.rs:287:5:295:5 | ExprStmt | | +| variables.rs:285:5:285:18 | ExprStmt | variables.rs:285:5:285:13 | PathExpr | | +| variables.rs:285:15:285:16 | c2 | variables.rs:285:5:285:17 | CallExpr | | +| variables.rs:287:5:295:5 | ExprStmt | variables.rs:287:12:287:12 | 4 | | +| variables.rs:287:5:295:5 | MatchExpr | variables.rs:297:5:297:19 | ExprStmt | | +| variables.rs:287:11:287:16 | TupleExpr | variables.rs:288:9:291:9 | TuplePat | | +| variables.rs:287:12:287:12 | 4 | variables.rs:287:15:287:15 | 5 | | +| variables.rs:287:15:287:15 | 5 | variables.rs:287:11:287:16 | TupleExpr | | +| variables.rs:288:9:291:9 | TuplePat | variables.rs:292:13:292:27 | ExprStmt | match | +| variables.rs:291:14:294:9 | BlockExpr | variables.rs:287:5:295:5 | MatchExpr | | +| variables.rs:292:13:292:21 | PathExpr | variables.rs:292:23:292:25 | a10 | | +| variables.rs:292:13:292:26 | CallExpr | variables.rs:293:13:293:26 | ExprStmt | | +| variables.rs:292:13:292:27 | ExprStmt | variables.rs:292:13:292:21 | PathExpr | | +| variables.rs:292:23:292:25 | a10 | variables.rs:292:13:292:26 | CallExpr | | +| variables.rs:293:13:293:21 | PathExpr | variables.rs:293:23:293:24 | b4 | | +| variables.rs:293:13:293:25 | CallExpr | variables.rs:291:14:294:9 | BlockExpr | | +| variables.rs:293:13:293:26 | ExprStmt | variables.rs:293:13:293:21 | PathExpr | | +| variables.rs:293:23:293:24 | b4 | variables.rs:293:13:293:25 | CallExpr | | +| variables.rs:297:5:297:13 | PathExpr | variables.rs:297:15:297:17 | a10 | | +| variables.rs:297:5:297:18 | CallExpr | variables.rs:298:5:298:18 | ExprStmt | | +| variables.rs:297:5:297:19 | ExprStmt | variables.rs:297:5:297:13 | PathExpr | | +| variables.rs:297:15:297:17 | a10 | variables.rs:297:5:297:18 | CallExpr | | +| variables.rs:298:5:298:13 | PathExpr | variables.rs:298:15:298:16 | b4 | | +| variables.rs:298:5:298:17 | CallExpr | variables.rs:264:26:299:1 | BlockExpr | | | variables.rs:298:5:298:18 | ExprStmt | variables.rs:298:5:298:13 | PathExpr | | -| variables.rs:298:15:298:16 | n1 | variables.rs:298:5:298:17 | CallExpr | | -| variables.rs:300:5:300:22 | PathExpr | variables.rs:300:5:300:24 | CallExpr | | -| variables.rs:300:5:300:24 | CallExpr | variables.rs:301:5:303:10 | LetStmt | | -| variables.rs:300:5:300:25 | ExprStmt | variables.rs:300:5:300:22 | PathExpr | | -| variables.rs:301:5:303:10 | LetStmt | variables.rs:302:9:303:9 | ClosureExpr | | -| variables.rs:301:9:301:26 | immutable_variable | variables.rs:304:5:305:30 | LetStmt | match, no-match | -| variables.rs:302:9:303:9 | ClosureExpr | variables.rs:301:9:301:26 | immutable_variable | | -| variables.rs:302:9:303:9 | enter ClosureExpr | variables.rs:303:9:303:9 | x | | -| variables.rs:302:9:303:9 | exit ClosureExpr (normal) | variables.rs:302:9:303:9 | exit ClosureExpr | | -| variables.rs:303:9:303:9 | x | variables.rs:302:9:303:9 | exit ClosureExpr (normal) | | -| variables.rs:304:5:305:30 | LetStmt | variables.rs:305:9:305:26 | immutable_variable | | -| variables.rs:304:9:304:10 | n2 | variables.rs:306:5:306:18 | ExprStmt | match, no-match | -| variables.rs:305:9:305:26 | immutable_variable | variables.rs:305:28:305:28 | 6 | | -| variables.rs:305:9:305:29 | CallExpr | variables.rs:304:9:304:10 | n2 | | -| variables.rs:305:28:305:28 | 6 | variables.rs:305:9:305:29 | CallExpr | | -| variables.rs:306:5:306:13 | PathExpr | variables.rs:306:15:306:16 | n2 | | -| variables.rs:306:5:306:17 | CallExpr | variables.rs:292:23:307:1 | BlockExpr | | -| variables.rs:306:5:306:18 | ExprStmt | variables.rs:306:5:306:13 | PathExpr | | -| variables.rs:306:15:306:16 | n2 | variables.rs:306:5:306:17 | CallExpr | | -| variables.rs:309:1:316:1 | enter for_variable | variables.rs:310:5:310:42 | LetStmt | | -| variables.rs:309:1:316:1 | exit for_variable (normal) | variables.rs:309:1:316:1 | exit for_variable | | -| variables.rs:309:19:316:1 | BlockExpr | variables.rs:309:1:316:1 | exit for_variable (normal) | | -| variables.rs:310:5:310:42 | LetStmt | variables.rs:310:15:310:22 | "apples" | | -| variables.rs:310:9:310:9 | v | variables.rs:313:12:313:12 | v | match, no-match | -| variables.rs:310:13:310:41 | RefExpr | variables.rs:310:9:310:9 | v | | -| variables.rs:310:14:310:41 | ArrayExpr | variables.rs:310:13:310:41 | RefExpr | | -| variables.rs:310:15:310:22 | "apples" | variables.rs:310:25:310:30 | "cake" | | -| variables.rs:310:25:310:30 | "cake" | variables.rs:310:33:310:40 | "coffee" | | -| variables.rs:310:33:310:40 | "coffee" | variables.rs:310:14:310:41 | ArrayExpr | | -| variables.rs:312:5:315:5 | ForExpr | variables.rs:309:19:316:1 | BlockExpr | | -| variables.rs:312:9:312:12 | text | variables.rs:312:5:315:5 | ForExpr | no-match | -| variables.rs:312:9:312:12 | text | variables.rs:314:9:314:24 | ExprStmt | match | -| variables.rs:313:12:313:12 | v | variables.rs:312:9:312:12 | text | | -| variables.rs:313:14:315:5 | BlockExpr | variables.rs:312:9:312:12 | text | | -| variables.rs:314:9:314:17 | PathExpr | variables.rs:314:19:314:22 | text | | -| variables.rs:314:9:314:23 | CallExpr | variables.rs:313:14:315:5 | BlockExpr | | -| variables.rs:314:9:314:24 | ExprStmt | variables.rs:314:9:314:17 | PathExpr | | -| variables.rs:314:19:314:22 | text | variables.rs:314:9:314:23 | CallExpr | | -| variables.rs:318:1:341:1 | enter main | variables.rs:319:5:319:25 | ExprStmt | | -| variables.rs:318:1:341:1 | exit main (normal) | variables.rs:318:1:341:1 | exit main | | -| variables.rs:318:11:341:1 | BlockExpr | variables.rs:318:1:341:1 | exit main (normal) | | -| variables.rs:319:5:319:22 | PathExpr | variables.rs:319:5:319:24 | CallExpr | | -| variables.rs:319:5:319:24 | CallExpr | variables.rs:320:5:320:23 | ExprStmt | | -| variables.rs:319:5:319:25 | ExprStmt | variables.rs:319:5:319:22 | PathExpr | | -| variables.rs:320:5:320:20 | PathExpr | variables.rs:320:5:320:22 | CallExpr | | -| variables.rs:320:5:320:22 | CallExpr | variables.rs:321:5:321:23 | ExprStmt | | -| variables.rs:320:5:320:23 | ExprStmt | variables.rs:320:5:320:20 | PathExpr | | -| variables.rs:321:5:321:20 | PathExpr | variables.rs:321:5:321:22 | CallExpr | | -| variables.rs:321:5:321:22 | CallExpr | variables.rs:322:5:322:23 | ExprStmt | | -| variables.rs:321:5:321:23 | ExprStmt | variables.rs:321:5:321:20 | PathExpr | | -| variables.rs:322:5:322:20 | PathExpr | variables.rs:322:5:322:22 | CallExpr | | -| variables.rs:322:5:322:22 | CallExpr | variables.rs:323:5:323:19 | ExprStmt | | -| variables.rs:322:5:322:23 | ExprStmt | variables.rs:322:5:322:20 | PathExpr | | -| variables.rs:323:5:323:16 | PathExpr | variables.rs:323:5:323:18 | CallExpr | | -| variables.rs:323:5:323:18 | CallExpr | variables.rs:324:5:324:19 | ExprStmt | | -| variables.rs:323:5:323:19 | ExprStmt | variables.rs:323:5:323:16 | PathExpr | | -| variables.rs:324:5:324:16 | PathExpr | variables.rs:324:5:324:18 | CallExpr | | -| variables.rs:324:5:324:18 | CallExpr | variables.rs:325:5:325:19 | ExprStmt | | -| variables.rs:324:5:324:19 | ExprStmt | variables.rs:324:5:324:16 | PathExpr | | -| variables.rs:325:5:325:16 | PathExpr | variables.rs:325:5:325:18 | CallExpr | | -| variables.rs:325:5:325:18 | CallExpr | variables.rs:326:5:326:19 | ExprStmt | | -| variables.rs:325:5:325:19 | ExprStmt | variables.rs:325:5:325:16 | PathExpr | | -| variables.rs:326:5:326:16 | PathExpr | variables.rs:326:5:326:18 | CallExpr | | -| variables.rs:326:5:326:18 | CallExpr | variables.rs:327:5:327:21 | ExprStmt | | -| variables.rs:326:5:326:19 | ExprStmt | variables.rs:326:5:326:16 | PathExpr | | -| variables.rs:327:5:327:18 | PathExpr | variables.rs:327:5:327:20 | CallExpr | | -| variables.rs:327:5:327:20 | CallExpr | variables.rs:328:5:328:21 | ExprStmt | | -| variables.rs:327:5:327:21 | ExprStmt | variables.rs:327:5:327:18 | PathExpr | | -| variables.rs:328:5:328:18 | PathExpr | variables.rs:328:5:328:20 | CallExpr | | -| variables.rs:328:5:328:20 | CallExpr | variables.rs:329:5:329:21 | ExprStmt | | -| variables.rs:328:5:328:21 | ExprStmt | variables.rs:328:5:328:18 | PathExpr | | -| variables.rs:329:5:329:18 | PathExpr | variables.rs:329:5:329:20 | CallExpr | | -| variables.rs:329:5:329:20 | CallExpr | variables.rs:330:5:330:21 | ExprStmt | | -| variables.rs:329:5:329:21 | ExprStmt | variables.rs:329:5:329:18 | PathExpr | | -| variables.rs:330:5:330:18 | PathExpr | variables.rs:330:5:330:20 | CallExpr | | -| variables.rs:330:5:330:20 | CallExpr | variables.rs:331:5:331:21 | ExprStmt | | -| variables.rs:330:5:330:21 | ExprStmt | variables.rs:330:5:330:18 | PathExpr | | -| variables.rs:331:5:331:18 | PathExpr | variables.rs:331:5:331:20 | CallExpr | | -| variables.rs:331:5:331:20 | CallExpr | variables.rs:332:5:332:21 | ExprStmt | | -| variables.rs:331:5:331:21 | ExprStmt | variables.rs:331:5:331:18 | PathExpr | | -| variables.rs:332:5:332:18 | PathExpr | variables.rs:332:5:332:20 | CallExpr | | -| variables.rs:332:5:332:20 | CallExpr | variables.rs:333:5:333:21 | ExprStmt | | -| variables.rs:332:5:332:21 | ExprStmt | variables.rs:332:5:332:18 | PathExpr | | -| variables.rs:333:5:333:18 | PathExpr | variables.rs:333:5:333:20 | CallExpr | | -| variables.rs:333:5:333:20 | CallExpr | variables.rs:334:5:334:21 | ExprStmt | | -| variables.rs:333:5:333:21 | ExprStmt | variables.rs:333:5:333:18 | PathExpr | | -| variables.rs:334:5:334:18 | PathExpr | variables.rs:334:5:334:20 | CallExpr | | -| variables.rs:334:5:334:20 | CallExpr | variables.rs:335:5:335:21 | ExprStmt | | -| variables.rs:334:5:334:21 | ExprStmt | variables.rs:334:5:334:18 | PathExpr | | -| variables.rs:335:5:335:18 | PathExpr | variables.rs:335:5:335:20 | CallExpr | | -| variables.rs:335:5:335:20 | CallExpr | variables.rs:336:5:336:36 | ExprStmt | | -| variables.rs:335:5:335:21 | ExprStmt | variables.rs:335:5:335:18 | PathExpr | | -| variables.rs:336:5:336:18 | PathExpr | variables.rs:336:20:336:22 | "a" | | -| variables.rs:336:5:336:35 | CallExpr | variables.rs:337:5:337:37 | ExprStmt | | -| variables.rs:336:5:336:36 | ExprStmt | variables.rs:336:5:336:18 | PathExpr | | -| variables.rs:336:20:336:22 | "a" | variables.rs:336:26:336:28 | "b" | | -| variables.rs:336:25:336:34 | TupleExpr | variables.rs:336:5:336:35 | CallExpr | | -| variables.rs:336:26:336:28 | "b" | variables.rs:336:31:336:33 | "c" | | -| variables.rs:336:31:336:33 | "c" | variables.rs:336:25:336:34 | TupleExpr | | -| variables.rs:337:5:337:18 | PathExpr | variables.rs:337:20:337:31 | PathExpr | | -| variables.rs:337:5:337:36 | CallExpr | variables.rs:338:5:338:26 | ExprStmt | | -| variables.rs:337:5:337:37 | ExprStmt | variables.rs:337:5:337:18 | PathExpr | | -| variables.rs:337:20:337:31 | PathExpr | variables.rs:337:33:337:34 | 45 | | -| variables.rs:337:20:337:35 | CallExpr | variables.rs:337:5:337:36 | CallExpr | | -| variables.rs:337:33:337:34 | 45 | variables.rs:337:20:337:35 | CallExpr | | -| variables.rs:338:5:338:23 | PathExpr | variables.rs:338:5:338:25 | CallExpr | | -| variables.rs:338:5:338:25 | CallExpr | variables.rs:339:5:339:23 | ExprStmt | | -| variables.rs:338:5:338:26 | ExprStmt | variables.rs:338:5:338:23 | PathExpr | | -| variables.rs:339:5:339:20 | PathExpr | variables.rs:339:5:339:22 | CallExpr | | -| variables.rs:339:5:339:22 | CallExpr | variables.rs:340:5:340:19 | ExprStmt | | -| variables.rs:339:5:339:23 | ExprStmt | variables.rs:339:5:339:20 | PathExpr | | -| variables.rs:340:5:340:16 | PathExpr | variables.rs:340:5:340:18 | CallExpr | | -| variables.rs:340:5:340:18 | CallExpr | variables.rs:318:11:341:1 | BlockExpr | | -| variables.rs:340:5:340:19 | ExprStmt | variables.rs:340:5:340:16 | PathExpr | | +| variables.rs:298:15:298:16 | b4 | variables.rs:298:5:298:17 | CallExpr | | +| variables.rs:301:1:316:1 | enter closure_variable | variables.rs:302:5:304:10 | LetStmt | | +| variables.rs:301:1:316:1 | exit closure_variable (normal) | variables.rs:301:1:316:1 | exit closure_variable | | +| variables.rs:301:23:316:1 | BlockExpr | variables.rs:301:1:316:1 | exit closure_variable (normal) | | +| variables.rs:302:5:304:10 | LetStmt | variables.rs:303:9:304:9 | ClosureExpr | | +| variables.rs:302:9:302:23 | example_closure | variables.rs:305:5:306:27 | LetStmt | match, no-match | +| variables.rs:303:9:304:9 | ClosureExpr | variables.rs:302:9:302:23 | example_closure | | +| variables.rs:303:9:304:9 | enter ClosureExpr | variables.rs:304:9:304:9 | x | | +| variables.rs:303:9:304:9 | exit ClosureExpr (normal) | variables.rs:303:9:304:9 | exit ClosureExpr | | +| variables.rs:304:9:304:9 | x | variables.rs:303:9:304:9 | exit ClosureExpr (normal) | | +| variables.rs:305:5:306:27 | LetStmt | variables.rs:306:9:306:23 | example_closure | | +| variables.rs:305:9:305:10 | n1 | variables.rs:307:5:307:18 | ExprStmt | match, no-match | +| variables.rs:306:9:306:23 | example_closure | variables.rs:306:25:306:25 | 5 | | +| variables.rs:306:9:306:26 | CallExpr | variables.rs:305:9:305:10 | n1 | | +| variables.rs:306:25:306:25 | 5 | variables.rs:306:9:306:26 | CallExpr | | +| variables.rs:307:5:307:13 | PathExpr | variables.rs:307:15:307:16 | n1 | | +| variables.rs:307:5:307:17 | CallExpr | variables.rs:309:5:309:25 | ExprStmt | | +| variables.rs:307:5:307:18 | ExprStmt | variables.rs:307:5:307:13 | PathExpr | | +| variables.rs:307:15:307:16 | n1 | variables.rs:307:5:307:17 | CallExpr | | +| variables.rs:309:5:309:22 | PathExpr | variables.rs:309:5:309:24 | CallExpr | | +| variables.rs:309:5:309:24 | CallExpr | variables.rs:310:5:312:10 | LetStmt | | +| variables.rs:309:5:309:25 | ExprStmt | variables.rs:309:5:309:22 | PathExpr | | +| variables.rs:310:5:312:10 | LetStmt | variables.rs:311:9:312:9 | ClosureExpr | | +| variables.rs:310:9:310:26 | immutable_variable | variables.rs:313:5:314:30 | LetStmt | match, no-match | +| variables.rs:311:9:312:9 | ClosureExpr | variables.rs:310:9:310:26 | immutable_variable | | +| variables.rs:311:9:312:9 | enter ClosureExpr | variables.rs:312:9:312:9 | x | | +| variables.rs:311:9:312:9 | exit ClosureExpr (normal) | variables.rs:311:9:312:9 | exit ClosureExpr | | +| variables.rs:312:9:312:9 | x | variables.rs:311:9:312:9 | exit ClosureExpr (normal) | | +| variables.rs:313:5:314:30 | LetStmt | variables.rs:314:9:314:26 | immutable_variable | | +| variables.rs:313:9:313:10 | n2 | variables.rs:315:5:315:18 | ExprStmt | match, no-match | +| variables.rs:314:9:314:26 | immutable_variable | variables.rs:314:28:314:28 | 6 | | +| variables.rs:314:9:314:29 | CallExpr | variables.rs:313:9:313:10 | n2 | | +| variables.rs:314:28:314:28 | 6 | variables.rs:314:9:314:29 | CallExpr | | +| variables.rs:315:5:315:13 | PathExpr | variables.rs:315:15:315:16 | n2 | | +| variables.rs:315:5:315:17 | CallExpr | variables.rs:301:23:316:1 | BlockExpr | | +| variables.rs:315:5:315:18 | ExprStmt | variables.rs:315:5:315:13 | PathExpr | | +| variables.rs:315:15:315:16 | n2 | variables.rs:315:5:315:17 | CallExpr | | +| variables.rs:318:1:325:1 | enter for_variable | variables.rs:319:5:319:42 | LetStmt | | +| variables.rs:318:1:325:1 | exit for_variable (normal) | variables.rs:318:1:325:1 | exit for_variable | | +| variables.rs:318:19:325:1 | BlockExpr | variables.rs:318:1:325:1 | exit for_variable (normal) | | +| variables.rs:319:5:319:42 | LetStmt | variables.rs:319:15:319:22 | "apples" | | +| variables.rs:319:9:319:9 | v | variables.rs:322:12:322:12 | v | match, no-match | +| variables.rs:319:13:319:41 | RefExpr | variables.rs:319:9:319:9 | v | | +| variables.rs:319:14:319:41 | ArrayExpr | variables.rs:319:13:319:41 | RefExpr | | +| variables.rs:319:15:319:22 | "apples" | variables.rs:319:25:319:30 | "cake" | | +| variables.rs:319:25:319:30 | "cake" | variables.rs:319:33:319:40 | "coffee" | | +| variables.rs:319:33:319:40 | "coffee" | variables.rs:319:14:319:41 | ArrayExpr | | +| variables.rs:321:5:324:5 | ForExpr | variables.rs:318:19:325:1 | BlockExpr | | +| variables.rs:321:9:321:12 | text | variables.rs:321:5:324:5 | ForExpr | no-match | +| variables.rs:321:9:321:12 | text | variables.rs:323:9:323:24 | ExprStmt | match | +| variables.rs:322:12:322:12 | v | variables.rs:321:9:321:12 | text | | +| variables.rs:322:14:324:5 | BlockExpr | variables.rs:321:9:321:12 | text | | +| variables.rs:323:9:323:17 | PathExpr | variables.rs:323:19:323:22 | text | | +| variables.rs:323:9:323:23 | CallExpr | variables.rs:322:14:324:5 | BlockExpr | | +| variables.rs:323:9:323:24 | ExprStmt | variables.rs:323:9:323:17 | PathExpr | | +| variables.rs:323:19:323:22 | text | variables.rs:323:9:323:23 | CallExpr | | +| variables.rs:327:1:350:1 | enter main | variables.rs:328:5:328:25 | ExprStmt | | +| variables.rs:327:1:350:1 | exit main (normal) | variables.rs:327:1:350:1 | exit main | | +| variables.rs:327:11:350:1 | BlockExpr | variables.rs:327:1:350:1 | exit main (normal) | | +| variables.rs:328:5:328:22 | PathExpr | variables.rs:328:5:328:24 | CallExpr | | +| variables.rs:328:5:328:24 | CallExpr | variables.rs:329:5:329:23 | ExprStmt | | +| variables.rs:328:5:328:25 | ExprStmt | variables.rs:328:5:328:22 | PathExpr | | +| variables.rs:329:5:329:20 | PathExpr | variables.rs:329:5:329:22 | CallExpr | | +| variables.rs:329:5:329:22 | CallExpr | variables.rs:330:5:330:23 | ExprStmt | | +| variables.rs:329:5:329:23 | ExprStmt | variables.rs:329:5:329:20 | PathExpr | | +| variables.rs:330:5:330:20 | PathExpr | variables.rs:330:5:330:22 | CallExpr | | +| variables.rs:330:5:330:22 | CallExpr | variables.rs:331:5:331:23 | ExprStmt | | +| variables.rs:330:5:330:23 | ExprStmt | variables.rs:330:5:330:20 | PathExpr | | +| variables.rs:331:5:331:20 | PathExpr | variables.rs:331:5:331:22 | CallExpr | | +| variables.rs:331:5:331:22 | CallExpr | variables.rs:332:5:332:19 | ExprStmt | | +| variables.rs:331:5:331:23 | ExprStmt | variables.rs:331:5:331:20 | PathExpr | | +| variables.rs:332:5:332:16 | PathExpr | variables.rs:332:5:332:18 | CallExpr | | +| variables.rs:332:5:332:18 | CallExpr | variables.rs:333:5:333:19 | ExprStmt | | +| variables.rs:332:5:332:19 | ExprStmt | variables.rs:332:5:332:16 | PathExpr | | +| variables.rs:333:5:333:16 | PathExpr | variables.rs:333:5:333:18 | CallExpr | | +| variables.rs:333:5:333:18 | CallExpr | variables.rs:334:5:334:19 | ExprStmt | | +| variables.rs:333:5:333:19 | ExprStmt | variables.rs:333:5:333:16 | PathExpr | | +| variables.rs:334:5:334:16 | PathExpr | variables.rs:334:5:334:18 | CallExpr | | +| variables.rs:334:5:334:18 | CallExpr | variables.rs:335:5:335:19 | ExprStmt | | +| variables.rs:334:5:334:19 | ExprStmt | variables.rs:334:5:334:16 | PathExpr | | +| variables.rs:335:5:335:16 | PathExpr | variables.rs:335:5:335:18 | CallExpr | | +| variables.rs:335:5:335:18 | CallExpr | variables.rs:336:5:336:21 | ExprStmt | | +| variables.rs:335:5:335:19 | ExprStmt | variables.rs:335:5:335:16 | PathExpr | | +| variables.rs:336:5:336:18 | PathExpr | variables.rs:336:5:336:20 | CallExpr | | +| variables.rs:336:5:336:20 | CallExpr | variables.rs:337:5:337:21 | ExprStmt | | +| variables.rs:336:5:336:21 | ExprStmt | variables.rs:336:5:336:18 | PathExpr | | +| variables.rs:337:5:337:18 | PathExpr | variables.rs:337:5:337:20 | CallExpr | | +| variables.rs:337:5:337:20 | CallExpr | variables.rs:338:5:338:21 | ExprStmt | | +| variables.rs:337:5:337:21 | ExprStmt | variables.rs:337:5:337:18 | PathExpr | | +| variables.rs:338:5:338:18 | PathExpr | variables.rs:338:5:338:20 | CallExpr | | +| variables.rs:338:5:338:20 | CallExpr | variables.rs:339:5:339:21 | ExprStmt | | +| variables.rs:338:5:338:21 | ExprStmt | variables.rs:338:5:338:18 | PathExpr | | +| variables.rs:339:5:339:18 | PathExpr | variables.rs:339:5:339:20 | CallExpr | | +| variables.rs:339:5:339:20 | CallExpr | variables.rs:340:5:340:21 | ExprStmt | | +| variables.rs:339:5:339:21 | ExprStmt | variables.rs:339:5:339:18 | PathExpr | | +| variables.rs:340:5:340:18 | PathExpr | variables.rs:340:5:340:20 | CallExpr | | +| variables.rs:340:5:340:20 | CallExpr | variables.rs:341:5:341:21 | ExprStmt | | +| variables.rs:340:5:340:21 | ExprStmt | variables.rs:340:5:340:18 | PathExpr | | +| variables.rs:341:5:341:18 | PathExpr | variables.rs:341:5:341:20 | CallExpr | | +| variables.rs:341:5:341:20 | CallExpr | variables.rs:342:5:342:21 | ExprStmt | | +| variables.rs:341:5:341:21 | ExprStmt | variables.rs:341:5:341:18 | PathExpr | | +| variables.rs:342:5:342:18 | PathExpr | variables.rs:342:5:342:20 | CallExpr | | +| variables.rs:342:5:342:20 | CallExpr | variables.rs:343:5:343:21 | ExprStmt | | +| variables.rs:342:5:342:21 | ExprStmt | variables.rs:342:5:342:18 | PathExpr | | +| variables.rs:343:5:343:18 | PathExpr | variables.rs:343:5:343:20 | CallExpr | | +| variables.rs:343:5:343:20 | CallExpr | variables.rs:344:5:344:21 | ExprStmt | | +| variables.rs:343:5:343:21 | ExprStmt | variables.rs:343:5:343:18 | PathExpr | | +| variables.rs:344:5:344:18 | PathExpr | variables.rs:344:5:344:20 | CallExpr | | +| variables.rs:344:5:344:20 | CallExpr | variables.rs:345:5:345:36 | ExprStmt | | +| variables.rs:344:5:344:21 | ExprStmt | variables.rs:344:5:344:18 | PathExpr | | +| variables.rs:345:5:345:18 | PathExpr | variables.rs:345:20:345:22 | "a" | | +| variables.rs:345:5:345:35 | CallExpr | variables.rs:346:5:346:37 | ExprStmt | | +| variables.rs:345:5:345:36 | ExprStmt | variables.rs:345:5:345:18 | PathExpr | | +| variables.rs:345:20:345:22 | "a" | variables.rs:345:26:345:28 | "b" | | +| variables.rs:345:25:345:34 | TupleExpr | variables.rs:345:5:345:35 | CallExpr | | +| variables.rs:345:26:345:28 | "b" | variables.rs:345:31:345:33 | "c" | | +| variables.rs:345:31:345:33 | "c" | variables.rs:345:25:345:34 | TupleExpr | | +| variables.rs:346:5:346:18 | PathExpr | variables.rs:346:20:346:31 | PathExpr | | +| variables.rs:346:5:346:36 | CallExpr | variables.rs:347:5:347:26 | ExprStmt | | +| variables.rs:346:5:346:37 | ExprStmt | variables.rs:346:5:346:18 | PathExpr | | +| variables.rs:346:20:346:31 | PathExpr | variables.rs:346:33:346:34 | 45 | | +| variables.rs:346:20:346:35 | CallExpr | variables.rs:346:5:346:36 | CallExpr | | +| variables.rs:346:33:346:34 | 45 | variables.rs:346:20:346:35 | CallExpr | | +| variables.rs:347:5:347:23 | PathExpr | variables.rs:347:5:347:25 | CallExpr | | +| variables.rs:347:5:347:25 | CallExpr | variables.rs:348:5:348:23 | ExprStmt | | +| variables.rs:347:5:347:26 | ExprStmt | variables.rs:347:5:347:23 | PathExpr | | +| variables.rs:348:5:348:20 | PathExpr | variables.rs:348:5:348:22 | CallExpr | | +| variables.rs:348:5:348:22 | CallExpr | variables.rs:349:5:349:19 | ExprStmt | | +| variables.rs:348:5:348:23 | ExprStmt | variables.rs:348:5:348:20 | PathExpr | | +| variables.rs:349:5:349:16 | PathExpr | variables.rs:349:5:349:18 | CallExpr | | +| variables.rs:349:5:349:18 | CallExpr | variables.rs:327:11:350:1 | BlockExpr | | +| variables.rs:349:5:349:19 | ExprStmt | variables.rs:349:5:349:16 | PathExpr | | breakTarget continueTarget diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index c86e30d4bb57..ad85ccfbfcc8 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -19,52 +19,54 @@ variable | variables.rs:72:9:72:10 | s1 | | variables.rs:74:21:74:22 | s2 | | variables.rs:81:14:81:15 | x5 | -| variables.rs:89:9:89:10 | x6 | -| variables.rs:90:9:90:10 | y1 | -| variables.rs:94:14:94:15 | y1 | -| variables.rs:99:9:99:12 | None | -| variables.rs:106:9:106:15 | numbers | -| variables.rs:110:13:110:17 | first | -| variables.rs:111:13:111:17 | third | -| variables.rs:112:13:112:17 | fifth | -| variables.rs:122:13:122:17 | first | -| variables.rs:124:13:124:16 | last | -| variables.rs:133:9:133:10 | p2 | -| variables.rs:137:16:137:17 | x7 | -| variables.rs:147:9:147:11 | msg | -| variables.rs:151:17:151:27 | id_variable | -| variables.rs:156:26:156:27 | id | -| variables.rs:167:9:167:14 | either | -| variables.rs:169:9:169:44 | a3 | -| variables.rs:181:9:181:10 | tv | -| variables.rs:183:9:183:81 | a4 | -| variables.rs:187:9:187:83 | a5 | -| variables.rs:191:9:191:83 | a6 | -| variables.rs:197:9:197:14 | either | -| variables.rs:199:9:199:44 | a7 | -| variables.rs:207:9:207:14 | either | -| variables.rs:210:13:210:13 | e | -| variables.rs:211:14:211:51 | a11 | -| variables.rs:214:33:214:35 | a12 | -| variables.rs:231:9:231:10 | fv | -| variables.rs:233:9:233:109 | a13 | -| variables.rs:239:5:239:6 | a8 | -| variables.rs:241:9:241:10 | b3 | -| variables.rs:242:9:242:10 | c1 | -| variables.rs:250:6:250:41 | a9 | -| variables.rs:257:13:257:15 | a10 | -| variables.rs:258:13:258:14 | b4 | -| variables.rs:259:13:259:14 | c2 | -| variables.rs:280:13:280:15 | a10 | -| variables.rs:281:13:281:14 | b4 | -| variables.rs:293:9:293:23 | example_closure | -| variables.rs:294:10:294:10 | x | -| variables.rs:296:9:296:10 | n1 | -| variables.rs:301:9:301:26 | immutable_variable | -| variables.rs:302:10:302:10 | x | -| variables.rs:304:9:304:10 | n2 | -| variables.rs:310:9:310:9 | v | -| variables.rs:312:9:312:12 | text | +| variables.rs:89:9:89:10 | s1 | +| variables.rs:91:24:91:25 | s2 | +| variables.rs:98:9:98:10 | x6 | +| variables.rs:99:9:99:10 | y1 | +| variables.rs:103:14:103:15 | y1 | +| variables.rs:108:9:108:12 | None | +| variables.rs:115:9:115:15 | numbers | +| variables.rs:119:13:119:17 | first | +| variables.rs:120:13:120:17 | third | +| variables.rs:121:13:121:17 | fifth | +| variables.rs:131:13:131:17 | first | +| variables.rs:133:13:133:16 | last | +| variables.rs:142:9:142:10 | p2 | +| variables.rs:146:16:146:17 | x7 | +| variables.rs:156:9:156:11 | msg | +| variables.rs:160:17:160:27 | id_variable | +| variables.rs:165:26:165:27 | id | +| variables.rs:176:9:176:14 | either | +| variables.rs:178:9:178:44 | a3 | +| variables.rs:190:9:190:10 | tv | +| variables.rs:192:9:192:81 | a4 | +| variables.rs:196:9:196:83 | a5 | +| variables.rs:200:9:200:83 | a6 | +| variables.rs:206:9:206:14 | either | +| variables.rs:208:9:208:44 | a7 | +| variables.rs:216:9:216:14 | either | +| variables.rs:219:13:219:13 | e | +| variables.rs:220:14:220:51 | a11 | +| variables.rs:223:33:223:35 | a12 | +| variables.rs:240:9:240:10 | fv | +| variables.rs:242:9:242:109 | a13 | +| variables.rs:248:5:248:6 | a8 | +| variables.rs:250:9:250:10 | b3 | +| variables.rs:251:9:251:10 | c1 | +| variables.rs:259:6:259:41 | a9 | +| variables.rs:266:13:266:15 | a10 | +| variables.rs:267:13:267:14 | b4 | +| variables.rs:268:13:268:14 | c2 | +| variables.rs:289:13:289:15 | a10 | +| variables.rs:290:13:290:14 | b4 | +| variables.rs:302:9:302:23 | example_closure | +| variables.rs:303:10:303:10 | x | +| variables.rs:305:9:305:10 | n1 | +| variables.rs:310:9:310:26 | immutable_variable | +| variables.rs:311:10:311:10 | x | +| variables.rs:313:9:313:10 | n2 | +| variables.rs:319:9:319:9 | v | +| variables.rs:321:9:321:12 | text | variableAccess | variables.rs:11:15:11:16 | x1 | variables.rs:10:9:10:10 | x1 | | variables.rs:16:15:16:16 | x2 | variables.rs:15:13:15:14 | x2 | @@ -86,71 +88,73 @@ variableAccess | variables.rs:75:11:75:12 | s1 | variables.rs:72:9:72:10 | s1 | | variables.rs:76:19:76:20 | s2 | variables.rs:74:21:74:22 | s2 | | variables.rs:85:15:85:16 | x5 | variables.rs:81:14:81:15 | x5 | -| variables.rs:92:11:92:12 | x6 | variables.rs:89:9:89:10 | x6 | -| variables.rs:97:23:97:24 | y1 | variables.rs:94:14:94:15 | y1 | -| variables.rs:102:15:102:16 | y1 | variables.rs:90:9:90:10 | y1 | -| variables.rs:108:11:108:17 | numbers | variables.rs:106:9:106:15 | numbers | -| variables.rs:114:23:114:27 | first | variables.rs:110:13:110:17 | first | -| variables.rs:115:23:115:27 | third | variables.rs:111:13:111:17 | third | -| variables.rs:116:23:116:27 | fifth | variables.rs:112:13:112:17 | fifth | -| variables.rs:120:11:120:17 | numbers | variables.rs:106:9:106:15 | numbers | -| variables.rs:126:23:126:27 | first | variables.rs:122:13:122:17 | first | -| variables.rs:127:23:127:26 | last | variables.rs:124:13:124:16 | last | -| variables.rs:135:11:135:12 | p2 | variables.rs:133:9:133:10 | p2 | -| variables.rs:138:24:138:25 | x7 | variables.rs:137:16:137:17 | x7 | -| variables.rs:149:11:149:13 | msg | variables.rs:147:9:147:11 | msg | -| variables.rs:152:24:152:34 | id_variable | variables.rs:151:17:151:27 | id_variable | -| variables.rs:157:23:157:24 | id | variables.rs:156:26:156:27 | id | -| variables.rs:168:11:168:16 | either | variables.rs:167:9:167:14 | either | -| variables.rs:170:26:170:27 | a3 | variables.rs:169:9:169:44 | a3 | -| variables.rs:182:11:182:12 | tv | variables.rs:181:9:181:10 | tv | -| variables.rs:184:26:184:27 | a4 | variables.rs:183:9:183:81 | a4 | -| variables.rs:186:11:186:12 | tv | variables.rs:181:9:181:10 | tv | -| variables.rs:188:26:188:27 | a5 | variables.rs:187:9:187:83 | a5 | -| variables.rs:190:11:190:12 | tv | variables.rs:181:9:181:10 | tv | -| variables.rs:192:26:192:27 | a6 | variables.rs:191:9:191:83 | a6 | -| variables.rs:198:11:198:16 | either | variables.rs:197:9:197:14 | either | -| variables.rs:200:16:200:17 | a7 | variables.rs:199:9:199:44 | a7 | -| variables.rs:201:26:201:27 | a7 | variables.rs:199:9:199:44 | a7 | -| variables.rs:209:11:209:16 | either | variables.rs:207:9:207:14 | either | -| variables.rs:213:23:213:25 | a11 | variables.rs:211:14:211:51 | a11 | -| variables.rs:215:15:215:15 | e | variables.rs:210:13:210:13 | e | -| variables.rs:216:28:216:30 | a12 | variables.rs:214:33:214:35 | a12 | -| variables.rs:232:11:232:12 | fv | variables.rs:231:9:231:10 | fv | -| variables.rs:234:26:234:28 | a13 | variables.rs:233:9:233:109 | a13 | -| variables.rs:244:15:244:16 | a8 | variables.rs:239:5:239:6 | a8 | -| variables.rs:245:15:245:16 | b3 | variables.rs:241:9:241:10 | b3 | -| variables.rs:246:15:246:16 | c1 | variables.rs:242:9:242:10 | c1 | -| variables.rs:252:15:252:16 | a9 | variables.rs:250:6:250:41 | a9 | -| variables.rs:261:15:261:17 | a10 | variables.rs:257:13:257:15 | a10 | -| variables.rs:262:15:262:16 | b4 | variables.rs:258:13:258:14 | b4 | -| variables.rs:263:15:263:16 | c2 | variables.rs:259:13:259:14 | c2 | -| variables.rs:266:9:266:10 | c2 | variables.rs:259:13:259:14 | c2 | -| variables.rs:267:9:267:10 | b4 | variables.rs:258:13:258:14 | b4 | -| variables.rs:268:9:268:11 | a10 | variables.rs:257:13:257:15 | a10 | -| variables.rs:270:9:270:11 | a10 | variables.rs:257:13:257:15 | a10 | -| variables.rs:271:9:271:10 | b4 | variables.rs:258:13:258:14 | b4 | -| variables.rs:272:9:272:10 | c2 | variables.rs:259:13:259:14 | c2 | -| variables.rs:274:15:274:17 | a10 | variables.rs:257:13:257:15 | a10 | -| variables.rs:275:15:275:16 | b4 | variables.rs:258:13:258:14 | b4 | -| variables.rs:276:15:276:16 | c2 | variables.rs:259:13:259:14 | c2 | -| variables.rs:283:23:283:25 | a10 | variables.rs:280:13:280:15 | a10 | -| variables.rs:284:23:284:24 | b4 | variables.rs:281:13:281:14 | b4 | -| variables.rs:288:15:288:17 | a10 | variables.rs:257:13:257:15 | a10 | -| variables.rs:289:15:289:16 | b4 | variables.rs:258:13:258:14 | b4 | -| variables.rs:295:9:295:9 | x | variables.rs:294:10:294:10 | x | -| variables.rs:297:9:297:23 | example_closure | variables.rs:293:9:293:23 | example_closure | -| variables.rs:298:15:298:16 | n1 | variables.rs:296:9:296:10 | n1 | -| variables.rs:303:9:303:9 | x | variables.rs:302:10:302:10 | x | -| variables.rs:305:9:305:26 | immutable_variable | variables.rs:301:9:301:26 | immutable_variable | -| variables.rs:306:15:306:16 | n2 | variables.rs:304:9:304:10 | n2 | -| variables.rs:313:12:313:12 | v | variables.rs:310:9:310:9 | v | -| variables.rs:314:19:314:22 | text | variables.rs:312:9:312:12 | text | +| variables.rs:92:11:92:12 | s1 | variables.rs:89:9:89:10 | s1 | +| variables.rs:93:19:93:20 | s2 | variables.rs:91:24:91:25 | s2 | +| variables.rs:101:11:101:12 | x6 | variables.rs:98:9:98:10 | x6 | +| variables.rs:106:23:106:24 | y1 | variables.rs:103:14:103:15 | y1 | +| variables.rs:111:15:111:16 | y1 | variables.rs:99:9:99:10 | y1 | +| variables.rs:117:11:117:17 | numbers | variables.rs:115:9:115:15 | numbers | +| variables.rs:123:23:123:27 | first | variables.rs:119:13:119:17 | first | +| variables.rs:124:23:124:27 | third | variables.rs:120:13:120:17 | third | +| variables.rs:125:23:125:27 | fifth | variables.rs:121:13:121:17 | fifth | +| variables.rs:129:11:129:17 | numbers | variables.rs:115:9:115:15 | numbers | +| variables.rs:135:23:135:27 | first | variables.rs:131:13:131:17 | first | +| variables.rs:136:23:136:26 | last | variables.rs:133:13:133:16 | last | +| variables.rs:144:11:144:12 | p2 | variables.rs:142:9:142:10 | p2 | +| variables.rs:147:24:147:25 | x7 | variables.rs:146:16:146:17 | x7 | +| variables.rs:158:11:158:13 | msg | variables.rs:156:9:156:11 | msg | +| variables.rs:161:24:161:34 | id_variable | variables.rs:160:17:160:27 | id_variable | +| variables.rs:166:23:166:24 | id | variables.rs:165:26:165:27 | id | +| variables.rs:177:11:177:16 | either | variables.rs:176:9:176:14 | either | +| variables.rs:179:26:179:27 | a3 | variables.rs:178:9:178:44 | a3 | +| variables.rs:191:11:191:12 | tv | variables.rs:190:9:190:10 | tv | +| variables.rs:193:26:193:27 | a4 | variables.rs:192:9:192:81 | a4 | +| variables.rs:195:11:195:12 | tv | variables.rs:190:9:190:10 | tv | +| variables.rs:197:26:197:27 | a5 | variables.rs:196:9:196:83 | a5 | +| variables.rs:199:11:199:12 | tv | variables.rs:190:9:190:10 | tv | +| variables.rs:201:26:201:27 | a6 | variables.rs:200:9:200:83 | a6 | +| variables.rs:207:11:207:16 | either | variables.rs:206:9:206:14 | either | +| variables.rs:209:16:209:17 | a7 | variables.rs:208:9:208:44 | a7 | +| variables.rs:210:26:210:27 | a7 | variables.rs:208:9:208:44 | a7 | +| variables.rs:218:11:218:16 | either | variables.rs:216:9:216:14 | either | +| variables.rs:222:23:222:25 | a11 | variables.rs:220:14:220:51 | a11 | +| variables.rs:224:15:224:15 | e | variables.rs:219:13:219:13 | e | +| variables.rs:225:28:225:30 | a12 | variables.rs:223:33:223:35 | a12 | +| variables.rs:241:11:241:12 | fv | variables.rs:240:9:240:10 | fv | +| variables.rs:243:26:243:28 | a13 | variables.rs:242:9:242:109 | a13 | +| variables.rs:253:15:253:16 | a8 | variables.rs:248:5:248:6 | a8 | +| variables.rs:254:15:254:16 | b3 | variables.rs:250:9:250:10 | b3 | +| variables.rs:255:15:255:16 | c1 | variables.rs:251:9:251:10 | c1 | +| variables.rs:261:15:261:16 | a9 | variables.rs:259:6:259:41 | a9 | +| variables.rs:270:15:270:17 | a10 | variables.rs:266:13:266:15 | a10 | +| variables.rs:271:15:271:16 | b4 | variables.rs:267:13:267:14 | b4 | +| variables.rs:272:15:272:16 | c2 | variables.rs:268:13:268:14 | c2 | +| variables.rs:275:9:275:10 | c2 | variables.rs:268:13:268:14 | c2 | +| variables.rs:276:9:276:10 | b4 | variables.rs:267:13:267:14 | b4 | +| variables.rs:277:9:277:11 | a10 | variables.rs:266:13:266:15 | a10 | +| variables.rs:279:9:279:11 | a10 | variables.rs:266:13:266:15 | a10 | +| variables.rs:280:9:280:10 | b4 | variables.rs:267:13:267:14 | b4 | +| variables.rs:281:9:281:10 | c2 | variables.rs:268:13:268:14 | c2 | +| variables.rs:283:15:283:17 | a10 | variables.rs:266:13:266:15 | a10 | +| variables.rs:284:15:284:16 | b4 | variables.rs:267:13:267:14 | b4 | +| variables.rs:285:15:285:16 | c2 | variables.rs:268:13:268:14 | c2 | +| variables.rs:292:23:292:25 | a10 | variables.rs:289:13:289:15 | a10 | +| variables.rs:293:23:293:24 | b4 | variables.rs:290:13:290:14 | b4 | +| variables.rs:297:15:297:17 | a10 | variables.rs:266:13:266:15 | a10 | +| variables.rs:298:15:298:16 | b4 | variables.rs:267:13:267:14 | b4 | +| variables.rs:304:9:304:9 | x | variables.rs:303:10:303:10 | x | +| variables.rs:306:9:306:23 | example_closure | variables.rs:302:9:302:23 | example_closure | +| variables.rs:307:15:307:16 | n1 | variables.rs:305:9:305:10 | n1 | +| variables.rs:312:9:312:9 | x | variables.rs:311:10:311:10 | x | +| variables.rs:314:9:314:26 | immutable_variable | variables.rs:310:9:310:26 | immutable_variable | +| variables.rs:315:15:315:16 | n2 | variables.rs:313:9:313:10 | n2 | +| variables.rs:322:12:322:12 | v | variables.rs:319:9:319:9 | v | +| variables.rs:323:19:323:22 | text | variables.rs:321:9:321:12 | text | variableWriteAccess | variables.rs:17:5:17:6 | x2 | variables.rs:15:13:15:14 | x2 | -| variables.rs:266:9:266:10 | c2 | variables.rs:259:13:259:14 | c2 | -| variables.rs:267:9:267:10 | b4 | variables.rs:258:13:258:14 | b4 | -| variables.rs:268:9:268:11 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:275:9:275:10 | c2 | variables.rs:268:13:268:14 | c2 | +| variables.rs:276:9:276:10 | b4 | variables.rs:267:13:267:14 | b4 | +| variables.rs:277:9:277:11 | a10 | variables.rs:266:13:266:15 | a10 | variableReadAccess | variables.rs:11:15:11:16 | x1 | variables.rs:10:9:10:10 | x1 | | variables.rs:16:15:16:16 | x2 | variables.rs:15:13:15:14 | x2 | @@ -171,63 +175,65 @@ variableReadAccess | variables.rs:75:11:75:12 | s1 | variables.rs:72:9:72:10 | s1 | | variables.rs:76:19:76:20 | s2 | variables.rs:74:21:74:22 | s2 | | variables.rs:85:15:85:16 | x5 | variables.rs:81:14:81:15 | x5 | -| variables.rs:92:11:92:12 | x6 | variables.rs:89:9:89:10 | x6 | -| variables.rs:97:23:97:24 | y1 | variables.rs:94:14:94:15 | y1 | -| variables.rs:102:15:102:16 | y1 | variables.rs:90:9:90:10 | y1 | -| variables.rs:108:11:108:17 | numbers | variables.rs:106:9:106:15 | numbers | -| variables.rs:114:23:114:27 | first | variables.rs:110:13:110:17 | first | -| variables.rs:115:23:115:27 | third | variables.rs:111:13:111:17 | third | -| variables.rs:116:23:116:27 | fifth | variables.rs:112:13:112:17 | fifth | -| variables.rs:120:11:120:17 | numbers | variables.rs:106:9:106:15 | numbers | -| variables.rs:126:23:126:27 | first | variables.rs:122:13:122:17 | first | -| variables.rs:127:23:127:26 | last | variables.rs:124:13:124:16 | last | -| variables.rs:135:11:135:12 | p2 | variables.rs:133:9:133:10 | p2 | -| variables.rs:138:24:138:25 | x7 | variables.rs:137:16:137:17 | x7 | -| variables.rs:149:11:149:13 | msg | variables.rs:147:9:147:11 | msg | -| variables.rs:152:24:152:34 | id_variable | variables.rs:151:17:151:27 | id_variable | -| variables.rs:157:23:157:24 | id | variables.rs:156:26:156:27 | id | -| variables.rs:168:11:168:16 | either | variables.rs:167:9:167:14 | either | -| variables.rs:170:26:170:27 | a3 | variables.rs:169:9:169:44 | a3 | -| variables.rs:182:11:182:12 | tv | variables.rs:181:9:181:10 | tv | -| variables.rs:184:26:184:27 | a4 | variables.rs:183:9:183:81 | a4 | -| variables.rs:186:11:186:12 | tv | variables.rs:181:9:181:10 | tv | -| variables.rs:188:26:188:27 | a5 | variables.rs:187:9:187:83 | a5 | -| variables.rs:190:11:190:12 | tv | variables.rs:181:9:181:10 | tv | -| variables.rs:192:26:192:27 | a6 | variables.rs:191:9:191:83 | a6 | -| variables.rs:198:11:198:16 | either | variables.rs:197:9:197:14 | either | -| variables.rs:200:16:200:17 | a7 | variables.rs:199:9:199:44 | a7 | -| variables.rs:201:26:201:27 | a7 | variables.rs:199:9:199:44 | a7 | -| variables.rs:209:11:209:16 | either | variables.rs:207:9:207:14 | either | -| variables.rs:213:23:213:25 | a11 | variables.rs:211:14:211:51 | a11 | -| variables.rs:215:15:215:15 | e | variables.rs:210:13:210:13 | e | -| variables.rs:216:28:216:30 | a12 | variables.rs:214:33:214:35 | a12 | -| variables.rs:232:11:232:12 | fv | variables.rs:231:9:231:10 | fv | -| variables.rs:234:26:234:28 | a13 | variables.rs:233:9:233:109 | a13 | -| variables.rs:244:15:244:16 | a8 | variables.rs:239:5:239:6 | a8 | -| variables.rs:245:15:245:16 | b3 | variables.rs:241:9:241:10 | b3 | -| variables.rs:246:15:246:16 | c1 | variables.rs:242:9:242:10 | c1 | -| variables.rs:252:15:252:16 | a9 | variables.rs:250:6:250:41 | a9 | -| variables.rs:261:15:261:17 | a10 | variables.rs:257:13:257:15 | a10 | -| variables.rs:262:15:262:16 | b4 | variables.rs:258:13:258:14 | b4 | -| variables.rs:263:15:263:16 | c2 | variables.rs:259:13:259:14 | c2 | -| variables.rs:270:9:270:11 | a10 | variables.rs:257:13:257:15 | a10 | -| variables.rs:271:9:271:10 | b4 | variables.rs:258:13:258:14 | b4 | -| variables.rs:272:9:272:10 | c2 | variables.rs:259:13:259:14 | c2 | -| variables.rs:274:15:274:17 | a10 | variables.rs:257:13:257:15 | a10 | -| variables.rs:275:15:275:16 | b4 | variables.rs:258:13:258:14 | b4 | -| variables.rs:276:15:276:16 | c2 | variables.rs:259:13:259:14 | c2 | -| variables.rs:283:23:283:25 | a10 | variables.rs:280:13:280:15 | a10 | -| variables.rs:284:23:284:24 | b4 | variables.rs:281:13:281:14 | b4 | -| variables.rs:288:15:288:17 | a10 | variables.rs:257:13:257:15 | a10 | -| variables.rs:289:15:289:16 | b4 | variables.rs:258:13:258:14 | b4 | -| variables.rs:295:9:295:9 | x | variables.rs:294:10:294:10 | x | -| variables.rs:297:9:297:23 | example_closure | variables.rs:293:9:293:23 | example_closure | -| variables.rs:298:15:298:16 | n1 | variables.rs:296:9:296:10 | n1 | -| variables.rs:303:9:303:9 | x | variables.rs:302:10:302:10 | x | -| variables.rs:305:9:305:26 | immutable_variable | variables.rs:301:9:301:26 | immutable_variable | -| variables.rs:306:15:306:16 | n2 | variables.rs:304:9:304:10 | n2 | -| variables.rs:313:12:313:12 | v | variables.rs:310:9:310:9 | v | -| variables.rs:314:19:314:22 | text | variables.rs:312:9:312:12 | text | +| variables.rs:92:11:92:12 | s1 | variables.rs:89:9:89:10 | s1 | +| variables.rs:93:19:93:20 | s2 | variables.rs:91:24:91:25 | s2 | +| variables.rs:101:11:101:12 | x6 | variables.rs:98:9:98:10 | x6 | +| variables.rs:106:23:106:24 | y1 | variables.rs:103:14:103:15 | y1 | +| variables.rs:111:15:111:16 | y1 | variables.rs:99:9:99:10 | y1 | +| variables.rs:117:11:117:17 | numbers | variables.rs:115:9:115:15 | numbers | +| variables.rs:123:23:123:27 | first | variables.rs:119:13:119:17 | first | +| variables.rs:124:23:124:27 | third | variables.rs:120:13:120:17 | third | +| variables.rs:125:23:125:27 | fifth | variables.rs:121:13:121:17 | fifth | +| variables.rs:129:11:129:17 | numbers | variables.rs:115:9:115:15 | numbers | +| variables.rs:135:23:135:27 | first | variables.rs:131:13:131:17 | first | +| variables.rs:136:23:136:26 | last | variables.rs:133:13:133:16 | last | +| variables.rs:144:11:144:12 | p2 | variables.rs:142:9:142:10 | p2 | +| variables.rs:147:24:147:25 | x7 | variables.rs:146:16:146:17 | x7 | +| variables.rs:158:11:158:13 | msg | variables.rs:156:9:156:11 | msg | +| variables.rs:161:24:161:34 | id_variable | variables.rs:160:17:160:27 | id_variable | +| variables.rs:166:23:166:24 | id | variables.rs:165:26:165:27 | id | +| variables.rs:177:11:177:16 | either | variables.rs:176:9:176:14 | either | +| variables.rs:179:26:179:27 | a3 | variables.rs:178:9:178:44 | a3 | +| variables.rs:191:11:191:12 | tv | variables.rs:190:9:190:10 | tv | +| variables.rs:193:26:193:27 | a4 | variables.rs:192:9:192:81 | a4 | +| variables.rs:195:11:195:12 | tv | variables.rs:190:9:190:10 | tv | +| variables.rs:197:26:197:27 | a5 | variables.rs:196:9:196:83 | a5 | +| variables.rs:199:11:199:12 | tv | variables.rs:190:9:190:10 | tv | +| variables.rs:201:26:201:27 | a6 | variables.rs:200:9:200:83 | a6 | +| variables.rs:207:11:207:16 | either | variables.rs:206:9:206:14 | either | +| variables.rs:209:16:209:17 | a7 | variables.rs:208:9:208:44 | a7 | +| variables.rs:210:26:210:27 | a7 | variables.rs:208:9:208:44 | a7 | +| variables.rs:218:11:218:16 | either | variables.rs:216:9:216:14 | either | +| variables.rs:222:23:222:25 | a11 | variables.rs:220:14:220:51 | a11 | +| variables.rs:224:15:224:15 | e | variables.rs:219:13:219:13 | e | +| variables.rs:225:28:225:30 | a12 | variables.rs:223:33:223:35 | a12 | +| variables.rs:241:11:241:12 | fv | variables.rs:240:9:240:10 | fv | +| variables.rs:243:26:243:28 | a13 | variables.rs:242:9:242:109 | a13 | +| variables.rs:253:15:253:16 | a8 | variables.rs:248:5:248:6 | a8 | +| variables.rs:254:15:254:16 | b3 | variables.rs:250:9:250:10 | b3 | +| variables.rs:255:15:255:16 | c1 | variables.rs:251:9:251:10 | c1 | +| variables.rs:261:15:261:16 | a9 | variables.rs:259:6:259:41 | a9 | +| variables.rs:270:15:270:17 | a10 | variables.rs:266:13:266:15 | a10 | +| variables.rs:271:15:271:16 | b4 | variables.rs:267:13:267:14 | b4 | +| variables.rs:272:15:272:16 | c2 | variables.rs:268:13:268:14 | c2 | +| variables.rs:279:9:279:11 | a10 | variables.rs:266:13:266:15 | a10 | +| variables.rs:280:9:280:10 | b4 | variables.rs:267:13:267:14 | b4 | +| variables.rs:281:9:281:10 | c2 | variables.rs:268:13:268:14 | c2 | +| variables.rs:283:15:283:17 | a10 | variables.rs:266:13:266:15 | a10 | +| variables.rs:284:15:284:16 | b4 | variables.rs:267:13:267:14 | b4 | +| variables.rs:285:15:285:16 | c2 | variables.rs:268:13:268:14 | c2 | +| variables.rs:292:23:292:25 | a10 | variables.rs:289:13:289:15 | a10 | +| variables.rs:293:23:293:24 | b4 | variables.rs:290:13:290:14 | b4 | +| variables.rs:297:15:297:17 | a10 | variables.rs:266:13:266:15 | a10 | +| variables.rs:298:15:298:16 | b4 | variables.rs:267:13:267:14 | b4 | +| variables.rs:304:9:304:9 | x | variables.rs:303:10:303:10 | x | +| variables.rs:306:9:306:23 | example_closure | variables.rs:302:9:302:23 | example_closure | +| variables.rs:307:15:307:16 | n1 | variables.rs:305:9:305:10 | n1 | +| variables.rs:312:9:312:9 | x | variables.rs:311:10:311:10 | x | +| variables.rs:314:9:314:26 | immutable_variable | variables.rs:310:9:310:26 | immutable_variable | +| variables.rs:315:15:315:16 | n2 | variables.rs:313:9:313:10 | n2 | +| variables.rs:322:12:322:12 | v | variables.rs:319:9:319:9 | v | +| variables.rs:323:19:323:22 | text | variables.rs:321:9:321:12 | text | variableInitializer | variables.rs:10:9:10:10 | x1 | variables.rs:10:14:10:16 | "a" | | variables.rs:15:13:15:14 | x2 | variables.rs:15:18:15:18 | 4 | @@ -237,18 +243,19 @@ variableInitializer | variables.rs:33:13:33:14 | x4 | variables.rs:33:18:33:20 | "b" | | variables.rs:62:9:62:10 | p1 | variables.rs:62:14:62:37 | RecordExpr | | variables.rs:72:9:72:10 | s1 | variables.rs:72:14:72:41 | CallExpr | -| variables.rs:89:9:89:10 | x6 | variables.rs:89:14:89:20 | CallExpr | -| variables.rs:90:9:90:10 | y1 | variables.rs:90:14:90:15 | 10 | -| variables.rs:106:9:106:15 | numbers | variables.rs:106:19:106:35 | TupleExpr | -| variables.rs:133:9:133:10 | p2 | variables.rs:133:14:133:37 | RecordExpr | -| variables.rs:147:9:147:11 | msg | variables.rs:147:15:147:38 | RecordExpr | -| variables.rs:167:9:167:14 | either | variables.rs:167:18:167:33 | CallExpr | -| variables.rs:181:9:181:10 | tv | variables.rs:181:14:181:36 | CallExpr | -| variables.rs:197:9:197:14 | either | variables.rs:197:18:197:33 | CallExpr | -| variables.rs:207:9:207:14 | either | variables.rs:207:18:207:33 | CallExpr | -| variables.rs:231:9:231:10 | fv | variables.rs:231:14:231:35 | CallExpr | -| variables.rs:293:9:293:23 | example_closure | variables.rs:294:9:295:9 | ClosureExpr | -| variables.rs:296:9:296:10 | n1 | variables.rs:297:9:297:26 | CallExpr | -| variables.rs:301:9:301:26 | immutable_variable | variables.rs:302:9:303:9 | ClosureExpr | -| variables.rs:304:9:304:10 | n2 | variables.rs:305:9:305:29 | CallExpr | -| variables.rs:310:9:310:9 | v | variables.rs:310:13:310:41 | RefExpr | +| variables.rs:89:9:89:10 | s1 | variables.rs:89:14:89:41 | CallExpr | +| variables.rs:98:9:98:10 | x6 | variables.rs:98:14:98:20 | CallExpr | +| variables.rs:99:9:99:10 | y1 | variables.rs:99:14:99:15 | 10 | +| variables.rs:115:9:115:15 | numbers | variables.rs:115:19:115:35 | TupleExpr | +| variables.rs:142:9:142:10 | p2 | variables.rs:142:14:142:37 | RecordExpr | +| variables.rs:156:9:156:11 | msg | variables.rs:156:15:156:38 | RecordExpr | +| variables.rs:176:9:176:14 | either | variables.rs:176:18:176:33 | CallExpr | +| variables.rs:190:9:190:10 | tv | variables.rs:190:14:190:36 | CallExpr | +| variables.rs:206:9:206:14 | either | variables.rs:206:18:206:33 | CallExpr | +| variables.rs:216:9:216:14 | either | variables.rs:216:18:216:33 | CallExpr | +| variables.rs:240:9:240:10 | fv | variables.rs:240:14:240:35 | CallExpr | +| variables.rs:302:9:302:23 | example_closure | variables.rs:303:9:304:9 | ClosureExpr | +| variables.rs:305:9:305:10 | n1 | variables.rs:306:9:306:26 | CallExpr | +| variables.rs:310:9:310:26 | immutable_variable | variables.rs:311:9:312:9 | ClosureExpr | +| variables.rs:313:9:313:10 | n2 | variables.rs:314:9:314:29 | CallExpr | +| variables.rs:319:9:319:9 | v | variables.rs:319:13:319:41 | RefExpr | diff --git a/rust/ql/test/library-tests/variables/variables.rs b/rust/ql/test/library-tests/variables/variables.rs index 8a0e83c9eff7..85fa052a7aa2 100644 --- a/rust/ql/test/library-tests/variables/variables.rs +++ b/rust/ql/test/library-tests/variables/variables.rs @@ -85,6 +85,15 @@ fn let_pattern4() { print_str(x5); // $ access=x5 } +fn let_pattern5() { + let s1 = Some(String::from("Hello!")); // s1 + + while let Some(ref s2) // s2 + = s1 { // $ access=s1 + print_str(s2); // $ access=s2 + } +} + fn match_pattern1() { let x6 = Some(5); // x6 let y1 = 10; // y1_1 diff --git a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected index 4a35ca8a41d4..fd4b8d3d2b46 100644 --- a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected +++ b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected @@ -3,12 +3,11 @@ | main.rs:114:9:114:9 | k | Variable is not used. | | main.rs:141:5:141:5 | y | Variable is not used. | | main.rs:164:9:164:9 | x | Variable is not used. | -| main.rs:170:9:170:9 | x | Variable is not used. | +| main.rs:169:9:169:9 | x | Variable is not used. | | main.rs:174:9:174:9 | x | Variable is not used. | -| main.rs:194:17:194:17 | a | Variable is not used. | -| main.rs:202:20:202:22 | val | Variable is not used. | -| main.rs:207:20:207:22 | val | Variable is not used. | -| main.rs:214:14:214:16 | val | Variable is not used. | -| main.rs:216:9:216:12 | None | Variable is not used. | -| main.rs:225:9:225:12 | None | Variable is not used. | -| main.rs:231:24:231:26 | val | Variable is not used. | +| main.rs:195:17:195:17 | a | Variable is not used. | +| main.rs:203:20:203:22 | val | Variable is not used. | +| main.rs:216:14:216:16 | val | Variable is not used. | +| main.rs:218:9:218:12 | None | Variable is not used. | +| main.rs:227:9:227:12 | None | Variable is not used. | +| main.rs:233:24:233:26 | val | Variable is not used. | diff --git a/rust/ql/test/query-tests/unusedentities/main.rs b/rust/ql/test/query-tests/unusedentities/main.rs index 46d1458b972e..a34219f8a7ab 100644 --- a/rust/ql/test/query-tests/unusedentities/main.rs +++ b/rust/ql/test/query-tests/unusedentities/main.rs @@ -164,14 +164,15 @@ fn loops() { for x in 1..10 { // BAD: unused variable } - for _ in 1..10 { - } + for _ in 1..10 {} - for x in 1..10 { // SPURIOUS: unused variable [macros not yet supported] + for x // SPURIOUS: unused variable [macros not yet supported] + in 1..10 { println!("x is {}", x); } - for x in 1..10 { // SPURIOUS: unused variable [macros not yet supported] + for x // SPURIOUS: unused variable [macros not yet supported] + in 1..10 { assert!(x != 11); } } @@ -199,12 +200,13 @@ fn if_lets() { } let mut next = Some(30); - while let Some(val) = next { // BAD: unused variable + while let Some(val) = next // BAD: unused variable + { next = None; } let mut next2 = Some(40); - while let Some(val) = next2 { // SPURIOUS: unused variable 'val' + while let Some(val) = next2 { total += val; next2 = None; } @@ -212,7 +214,7 @@ fn if_lets() { let c = Some(60); match c { Some(val) => { // BAD: unused variable - }, + } None => { // SPURIOUS: unused variable 'None' } } @@ -221,7 +223,7 @@ fn if_lets() { match d { Some(val) => { total += val; - }, + } None => { // SPURIOUS: unused variable 'None' } } @@ -229,17 +231,14 @@ fn if_lets() { let e = MyOption::Some(80); match e { MyOption::Some(val) => { // BAD: unused variable - }, - MyOption::None => { } + MyOption::None => {} } let f = YesOrNo::Yes; match f { - YesOrNo::Yes => { - }, - YesOrNo::No => { - }, + YesOrNo::Yes => {} + YesOrNo::No => {} } } From ccaf2dd9ea1e381d75b38f478ac9d183e8b871cb Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 3 Oct 2024 13:37:15 +0100 Subject: [PATCH 153/347] Rust: Temporarily limit results (hopefully enough for the DCA job to cope). --- rust/ql/src/queries/unusedentities/UnusedVariable.ql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rust/ql/src/queries/unusedentities/UnusedVariable.ql b/rust/ql/src/queries/unusedentities/UnusedVariable.ql index 5fb0cdfecdc1..f6be18b76e15 100644 --- a/rust/ql/src/queries/unusedentities/UnusedVariable.ql +++ b/rust/ql/src/queries/unusedentities/UnusedVariable.ql @@ -14,5 +14,6 @@ from Variable v where not exists(v.getAnAccess()) and not exists(v.getInitializer()) and - not v.getName().charAt(0) = "_" + not v.getName().charAt(0) = "_" and + exists(File f | f.getBaseName() = "main.rs" | v.getLocation().getFile() = f) // temporarily severely limit results select v, "Variable is not used." From 2e772a80c4bed04c04083e6f8eb2c20e4dc8effb Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:15:32 +0100 Subject: [PATCH 154/347] Rust: Accept minor consistency .expected changes. --- .../utf8/CONSISTENCY/ExtractionConsistency.expected | 1 + .../diagnostics/CONSISTENCY/ExtractionConsistency.expected | 1 + 2 files changed, 2 insertions(+) diff --git a/rust/ql/test/extractor-tests/utf8/CONSISTENCY/ExtractionConsistency.expected b/rust/ql/test/extractor-tests/utf8/CONSISTENCY/ExtractionConsistency.expected index 23b423a489a1..45026be3af2b 100644 --- a/rust/ql/test/extractor-tests/utf8/CONSISTENCY/ExtractionConsistency.expected +++ b/rust/ql/test/extractor-tests/utf8/CONSISTENCY/ExtractionConsistency.expected @@ -1,3 +1,4 @@ +extractionWarning | lib.rs:3:9:3:8 | expected `;` or `{` | | lib.rs:3:9:3:8 | expected an item | | lib.rs:3:21:3:20 | expected BANG | diff --git a/rust/ql/test/query-tests/diagnostics/CONSISTENCY/ExtractionConsistency.expected b/rust/ql/test/query-tests/diagnostics/CONSISTENCY/ExtractionConsistency.expected index 157aafc87852..0d5ffb095614 100644 --- a/rust/ql/test/query-tests/diagnostics/CONSISTENCY/ExtractionConsistency.expected +++ b/rust/ql/test/query-tests/diagnostics/CONSISTENCY/ExtractionConsistency.expected @@ -1,3 +1,4 @@ +extractionWarning | does_not_compile.rs:2:6:2:5 | expected SEMICOLON | | does_not_compile.rs:2:9:2:8 | expected SEMICOLON | | does_not_compile.rs:2:13:2:12 | expected SEMICOLON | From 4c7ec59306a432242f510618611f4fddf3099cc3 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 3 Oct 2024 14:16:12 +0100 Subject: [PATCH 155/347] Ruby: Sync identical files. --- ruby/ql/lib/codeql/ruby/Diagnostics.qll | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/Diagnostics.qll b/ruby/ql/lib/codeql/ruby/Diagnostics.qll index 5902bb594141..58de14b8fcf5 100644 --- a/ruby/ql/lib/codeql/ruby/Diagnostics.qll +++ b/ruby/ql/lib/codeql/ruby/Diagnostics.qll @@ -48,7 +48,8 @@ class Diagnostic extends @diagnostic { string toString() { result = this.getMessage() } } -/** A diagnostic relating to a particular error in extracting a file. */ -class ExtractionError extends Diagnostic { - ExtractionError() { this.getTag() = "parse_error" } -} +/** A diagnostic that is error severity. */ +class ExtractionError extends Diagnostic, @diagnostic_error { } + +/** A diagnostic that is warning severity. */ +class ExtractionWarning extends Diagnostic, @diagnostic_warning { } From 1ea94faccf7113ae339190c1151926184fbbfe7d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 3 Oct 2024 17:27:52 +0100 Subject: [PATCH 156/347] Ruby: Make similar changes to differentiate extraction errors and warnings, and mostly restore original behaviour. --- ruby/ql/consistency-queries/AstConsistency.ql | 2 ++ ruby/ql/lib/codeql/files/FileSystem.qll | 18 ++++++++++++++++++ .../NumberOfFilesExtractedWithErrors.ql | 7 ++++--- .../NumberOfSuccessfullyExtractedFiles.ql | 8 +++----- .../CONSISTENCY/AstConsistency.expected | 2 +- .../diagnostics/ExtractionErrors.expected | 1 - 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/ruby/ql/consistency-queries/AstConsistency.ql b/ruby/ql/consistency-queries/AstConsistency.ql index 2a9fea8fea90..d7792a8ae4d0 100644 --- a/ruby/ql/consistency-queries/AstConsistency.ql +++ b/ruby/ql/consistency-queries/AstConsistency.ql @@ -31,3 +31,5 @@ query predicate multipleToString(AstNode n, string s) { } query predicate extractionError(ExtractionError error) { any() } + +query predicate extractionWarning(ExtractionWarning error) { any() } diff --git a/ruby/ql/lib/codeql/files/FileSystem.qll b/ruby/ql/lib/codeql/files/FileSystem.qll index 528dde52fd91..8985cc333447 100644 --- a/ruby/ql/lib/codeql/files/FileSystem.qll +++ b/ruby/ql/lib/codeql/files/FileSystem.qll @@ -2,6 +2,7 @@ private import codeql.Locations private import codeql.util.FileSystem +private import codeql.ruby.Diagnostics private module Input implements InputSig { abstract class ContainerBase extends @container { @@ -34,3 +35,20 @@ class File extends Container, Impl::File { /** Holds if this file was extracted from ordinary source code. */ predicate fromSource() { any() } } + +/** + * A successfully extracted file, that is, a file that was extracted and + * contains no extraction errors or warnings. + */ +class SuccessfullyExtractedFile extends File { + SuccessfullyExtractedFile() { + not exists(Diagnostic d | + d.getLocation().getFile() = this and + ( + d instanceof ExtractionError + or + d instanceof ExtractionWarning + ) + ) + } +} diff --git a/ruby/ql/src/queries/summary/NumberOfFilesExtractedWithErrors.ql b/ruby/ql/src/queries/summary/NumberOfFilesExtractedWithErrors.ql index 8623ed911d5a..1cbc28b6cc6b 100644 --- a/ruby/ql/src/queries/summary/NumberOfFilesExtractedWithErrors.ql +++ b/ruby/ql/src/queries/summary/NumberOfFilesExtractedWithErrors.ql @@ -2,14 +2,15 @@ * @id rb/summary/number-of-files-extracted-with-errors * @name Total number of Ruby files that were extracted with errors * @description The total number of Ruby code files that we extracted, but where - * at least one extraction error occurred in the process. + * at least one extraction error (or warning) occurred in the process. * @kind metric * @tags summary */ import codeql.ruby.AST -import codeql.ruby.Diagnostics +import codeql.files.FileSystem select count(File f | - exists(ExtractionError e | e.getLocation().getFile() = f) and exists(f.getRelativePath()) + exists(f.getRelativePath()) and + not f instanceof SuccessfullyExtractedFile ) diff --git a/ruby/ql/src/queries/summary/NumberOfSuccessfullyExtractedFiles.ql b/ruby/ql/src/queries/summary/NumberOfSuccessfullyExtractedFiles.ql index 236374ff2261..afd667cf58c5 100644 --- a/ruby/ql/src/queries/summary/NumberOfSuccessfullyExtractedFiles.ql +++ b/ruby/ql/src/queries/summary/NumberOfSuccessfullyExtractedFiles.ql @@ -2,14 +2,12 @@ * @id rb/summary/number-of-successfully-extracted-files * @name Total number of Ruby files that were extracted without error * @description The total number of Ruby code files that we extracted without - * encountering any extraction errors + * encountering any extraction errors (or warnings). * @kind metric * @tags summary */ import codeql.ruby.AST -import codeql.ruby.Diagnostics +import codeql.files.FileSystem -select count(File f | - not exists(ExtractionError e | e.getLocation().getFile() = f) and exists(f.getRelativePath()) - ) +select count(SuccessfullyExtractedFile f | exists(f.getRelativePath())) diff --git a/ruby/ql/test/query-tests/diagnostics/CONSISTENCY/AstConsistency.expected b/ruby/ql/test/query-tests/diagnostics/CONSISTENCY/AstConsistency.expected index 5dc14116b917..93df75151a77 100644 --- a/ruby/ql/test/query-tests/diagnostics/CONSISTENCY/AstConsistency.expected +++ b/ruby/ql/test/query-tests/diagnostics/CONSISTENCY/AstConsistency.expected @@ -1,2 +1,2 @@ -extractionError +extractionWarning | src/not_ruby.rb:5:25:5:26 | A parse error occurred. Check the syntax of the file. If the file is invalid, correct the error or exclude the file from analysis. | diff --git a/ruby/ql/test/query-tests/diagnostics/ExtractionErrors.expected b/ruby/ql/test/query-tests/diagnostics/ExtractionErrors.expected index dc37ca3642b3..e69de29bb2d1 100644 --- a/ruby/ql/test/query-tests/diagnostics/ExtractionErrors.expected +++ b/ruby/ql/test/query-tests/diagnostics/ExtractionErrors.expected @@ -1 +0,0 @@ -| src/not_ruby.rb:5:25:5:26 | A parse error occurred. Check the syntax of the file. If the file is invalid, correct the error or exclude the file from analysis. | Extraction failed in src/not_ruby.rb with error A parse error occurred. Check the syntax of the file. If the file is invalid, correct the error or exclude the file from analysis. | 2 | From 86cc2dc5a1e117b8a9f3e58c639c41d1509593d3 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 3 Oct 2024 17:29:25 +0100 Subject: [PATCH 157/347] Ruby: Add rb/diagnostics/extraction-warnings so that we don't miss anything we had before. --- .../queries/diagnostics/ExtractionWarnings.ql | 19 +++++++++++++++++++ .../diagnostics/ExtractionWarnings.expected | 1 + .../diagnostics/ExtractionWarnings.qlref | 1 + 3 files changed, 21 insertions(+) create mode 100644 ruby/ql/src/queries/diagnostics/ExtractionWarnings.ql create mode 100644 ruby/ql/test/query-tests/diagnostics/ExtractionWarnings.expected create mode 100644 ruby/ql/test/query-tests/diagnostics/ExtractionWarnings.qlref diff --git a/ruby/ql/src/queries/diagnostics/ExtractionWarnings.ql b/ruby/ql/src/queries/diagnostics/ExtractionWarnings.ql new file mode 100644 index 000000000000..74f007390567 --- /dev/null +++ b/ruby/ql/src/queries/diagnostics/ExtractionWarnings.ql @@ -0,0 +1,19 @@ +/** + * @name Extraction warnings + * @description List all extraction warnings for files in the source code directory. + * @kind diagnostic + * @id rb/diagnostics/extraction-warnings + */ + +import codeql.ruby.AST +import codeql.ruby.Diagnostics + +/** Gets the SARIF severity to associate with a warning. */ +int getSeverity() { result = 1 } + +from ExtractionWarning warning, File f +where + f = warning.getLocation().getFile() and + exists(f.getRelativePath()) +select warning, "Extraction warning in " + f + " with message " + warning.getMessage(), + getSeverity() diff --git a/ruby/ql/test/query-tests/diagnostics/ExtractionWarnings.expected b/ruby/ql/test/query-tests/diagnostics/ExtractionWarnings.expected new file mode 100644 index 000000000000..c47ec9c5d365 --- /dev/null +++ b/ruby/ql/test/query-tests/diagnostics/ExtractionWarnings.expected @@ -0,0 +1 @@ +| src/not_ruby.rb:5:25:5:26 | A parse error occurred. Check the syntax of the file. If the file is invalid, correct the error or exclude the file from analysis. | Extraction warning in src/not_ruby.rb with message A parse error occurred. Check the syntax of the file. If the file is invalid, correct the error or exclude the file from analysis. | 1 | diff --git a/ruby/ql/test/query-tests/diagnostics/ExtractionWarnings.qlref b/ruby/ql/test/query-tests/diagnostics/ExtractionWarnings.qlref new file mode 100644 index 000000000000..ff6e566d20a7 --- /dev/null +++ b/ruby/ql/test/query-tests/diagnostics/ExtractionWarnings.qlref @@ -0,0 +1 @@ +queries/diagnostics/ExtractionWarnings.ql From d4414dabff35e74aace2743596d31108ad4cdb5e Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 3 Oct 2024 17:38:28 +0100 Subject: [PATCH 158/347] Ruby: Add change notes. --- ruby/ql/lib/change-notes/2024-10-03-extraction-warnings.md | 4 ++++ ruby/ql/src/change-notes/2024-10-03-extraction-warnings.md | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 ruby/ql/lib/change-notes/2024-10-03-extraction-warnings.md create mode 100644 ruby/ql/src/change-notes/2024-10-03-extraction-warnings.md diff --git a/ruby/ql/lib/change-notes/2024-10-03-extraction-warnings.md b/ruby/ql/lib/change-notes/2024-10-03-extraction-warnings.md new file mode 100644 index 000000000000..5d6128354c3b --- /dev/null +++ b/ruby/ql/lib/change-notes/2024-10-03-extraction-warnings.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `ExtractionError` class has been split into `ExtractionError` and `ExtractionWarning`, reporting extraction errors and warnings respectively. diff --git a/ruby/ql/src/change-notes/2024-10-03-extraction-warnings.md b/ruby/ql/src/change-notes/2024-10-03-extraction-warnings.md new file mode 100644 index 000000000000..ac97cd1e7ba2 --- /dev/null +++ b/ruby/ql/src/change-notes/2024-10-03-extraction-warnings.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `rb/diagnostics/extraction-errors` diagnostic query has been split into `rb/diagnostics/extraction-errors` and `rb/diagnostics/extraction-warnings`, counting extraction errors and warnings respectively. From 05f85497ed8fd150e639a66bc47e6af65252e006 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 3 Oct 2024 13:33:13 +0200 Subject: [PATCH 159/347] Rust: Add `&mut` variable tests --- .../test/library-tests/variables/Cfg.expected | 1291 +++++++++-------- .../variables/variables.expected | 553 +++---- .../test/library-tests/variables/variables.ql | 11 +- .../test/library-tests/variables/variables.rs | 205 +-- 4 files changed, 1111 insertions(+), 949 deletions(-) diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected index 1ae43dac402e..55b09cf6ace7 100644 --- a/rust/ql/test/library-tests/variables/Cfg.expected +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -1,616 +1,691 @@ edges -| variables.rs:1:1:3:1 | enter print_str | variables.rs:2:5:2:22 | ExprStmt | | -| variables.rs:1:1:3:1 | exit print_str (normal) | variables.rs:1:1:3:1 | exit print_str | | -| variables.rs:1:23:3:1 | BlockExpr | variables.rs:1:1:3:1 | exit print_str (normal) | | -| variables.rs:2:5:2:21 | MacroExpr | variables.rs:1:23:3:1 | BlockExpr | | -| variables.rs:2:5:2:22 | ExprStmt | variables.rs:2:5:2:21 | MacroExpr | | -| variables.rs:5:1:7:1 | enter print_i64 | variables.rs:6:5:6:22 | ExprStmt | | -| variables.rs:5:1:7:1 | exit print_i64 (normal) | variables.rs:5:1:7:1 | exit print_i64 | | -| variables.rs:5:22:7:1 | BlockExpr | variables.rs:5:1:7:1 | exit print_i64 (normal) | | -| variables.rs:6:5:6:21 | MacroExpr | variables.rs:5:22:7:1 | BlockExpr | | -| variables.rs:6:5:6:22 | ExprStmt | variables.rs:6:5:6:21 | MacroExpr | | -| variables.rs:9:1:12:1 | enter immutable_variable | variables.rs:10:5:10:17 | LetStmt | | -| variables.rs:9:1:12:1 | exit immutable_variable (normal) | variables.rs:9:1:12:1 | exit immutable_variable | | -| variables.rs:9:25:12:1 | BlockExpr | variables.rs:9:1:12:1 | exit immutable_variable (normal) | | -| variables.rs:10:5:10:17 | LetStmt | variables.rs:10:14:10:16 | "a" | | -| variables.rs:10:9:10:10 | x1 | variables.rs:11:5:11:18 | ExprStmt | match, no-match | -| variables.rs:10:14:10:16 | "a" | variables.rs:10:9:10:10 | x1 | | -| variables.rs:11:5:11:13 | PathExpr | variables.rs:11:15:11:16 | x1 | | -| variables.rs:11:5:11:17 | CallExpr | variables.rs:9:25:12:1 | BlockExpr | | -| variables.rs:11:5:11:18 | ExprStmt | variables.rs:11:5:11:13 | PathExpr | | -| variables.rs:11:15:11:16 | x1 | variables.rs:11:5:11:17 | CallExpr | | -| variables.rs:14:1:19:1 | enter mutable_variable | variables.rs:15:5:15:19 | LetStmt | | -| variables.rs:14:1:19:1 | exit mutable_variable (normal) | variables.rs:14:1:19:1 | exit mutable_variable | | -| variables.rs:14:23:19:1 | BlockExpr | variables.rs:14:1:19:1 | exit mutable_variable (normal) | | -| variables.rs:15:5:15:19 | LetStmt | variables.rs:15:18:15:18 | 4 | | -| variables.rs:15:9:15:14 | x2 | variables.rs:16:5:16:18 | ExprStmt | match, no-match | -| variables.rs:15:18:15:18 | 4 | variables.rs:15:9:15:14 | x2 | | -| variables.rs:16:5:16:13 | PathExpr | variables.rs:16:15:16:16 | x2 | | -| variables.rs:16:5:16:17 | CallExpr | variables.rs:17:5:17:11 | ExprStmt | | -| variables.rs:16:5:16:18 | ExprStmt | variables.rs:16:5:16:13 | PathExpr | | -| variables.rs:16:15:16:16 | x2 | variables.rs:16:5:16:17 | CallExpr | | -| variables.rs:17:5:17:6 | x2 | variables.rs:17:10:17:10 | 5 | | -| variables.rs:17:5:17:10 | ... = ... | variables.rs:18:5:18:18 | ExprStmt | | -| variables.rs:17:5:17:11 | ExprStmt | variables.rs:17:5:17:6 | x2 | | -| variables.rs:17:10:17:10 | 5 | variables.rs:17:5:17:10 | ... = ... | | +| variables.rs:3:1:5:1 | enter print_str | variables.rs:4:5:4:22 | ExprStmt | | +| variables.rs:3:1:5:1 | exit print_str (normal) | variables.rs:3:1:5:1 | exit print_str | | +| variables.rs:3:23:5:1 | BlockExpr | variables.rs:3:1:5:1 | exit print_str (normal) | | +| variables.rs:4:5:4:21 | MacroExpr | variables.rs:3:23:5:1 | BlockExpr | | +| variables.rs:4:5:4:22 | ExprStmt | variables.rs:4:5:4:21 | MacroExpr | | +| variables.rs:7:1:9:1 | enter print_i64 | variables.rs:8:5:8:22 | ExprStmt | | +| variables.rs:7:1:9:1 | exit print_i64 (normal) | variables.rs:7:1:9:1 | exit print_i64 | | +| variables.rs:7:22:9:1 | BlockExpr | variables.rs:7:1:9:1 | exit print_i64 (normal) | | +| variables.rs:8:5:8:21 | MacroExpr | variables.rs:7:22:9:1 | BlockExpr | | +| variables.rs:8:5:8:22 | ExprStmt | variables.rs:8:5:8:21 | MacroExpr | | +| variables.rs:11:1:14:1 | enter immutable_variable | variables.rs:12:5:12:17 | LetStmt | | +| variables.rs:11:1:14:1 | exit immutable_variable (normal) | variables.rs:11:1:14:1 | exit immutable_variable | | +| variables.rs:11:25:14:1 | BlockExpr | variables.rs:11:1:14:1 | exit immutable_variable (normal) | | +| variables.rs:12:5:12:17 | LetStmt | variables.rs:12:14:12:16 | "a" | | +| variables.rs:12:9:12:10 | x1 | variables.rs:13:5:13:18 | ExprStmt | match, no-match | +| variables.rs:12:14:12:16 | "a" | variables.rs:12:9:12:10 | x1 | | +| variables.rs:13:5:13:13 | PathExpr | variables.rs:13:15:13:16 | x1 | | +| variables.rs:13:5:13:17 | CallExpr | variables.rs:11:25:14:1 | BlockExpr | | +| variables.rs:13:5:13:18 | ExprStmt | variables.rs:13:5:13:13 | PathExpr | | +| variables.rs:13:15:13:16 | x1 | variables.rs:13:5:13:17 | CallExpr | | +| variables.rs:16:1:21:1 | enter mutable_variable | variables.rs:17:5:17:19 | LetStmt | | +| variables.rs:16:1:21:1 | exit mutable_variable (normal) | variables.rs:16:1:21:1 | exit mutable_variable | | +| variables.rs:16:23:21:1 | BlockExpr | variables.rs:16:1:21:1 | exit mutable_variable (normal) | | +| variables.rs:17:5:17:19 | LetStmt | variables.rs:17:18:17:18 | 4 | | +| variables.rs:17:9:17:14 | x2 | variables.rs:18:5:18:18 | ExprStmt | match, no-match | +| variables.rs:17:18:17:18 | 4 | variables.rs:17:9:17:14 | x2 | | | variables.rs:18:5:18:13 | PathExpr | variables.rs:18:15:18:16 | x2 | | -| variables.rs:18:5:18:17 | CallExpr | variables.rs:14:23:19:1 | BlockExpr | | +| variables.rs:18:5:18:17 | CallExpr | variables.rs:19:5:19:11 | ExprStmt | | | variables.rs:18:5:18:18 | ExprStmt | variables.rs:18:5:18:13 | PathExpr | | | variables.rs:18:15:18:16 | x2 | variables.rs:18:5:18:17 | CallExpr | | -| variables.rs:21:1:27:1 | enter variable_shadow1 | variables.rs:22:5:22:15 | LetStmt | | -| variables.rs:21:1:27:1 | exit variable_shadow1 (normal) | variables.rs:21:1:27:1 | exit variable_shadow1 | | -| variables.rs:21:23:27:1 | BlockExpr | variables.rs:21:1:27:1 | exit variable_shadow1 (normal) | | -| variables.rs:22:5:22:15 | LetStmt | variables.rs:22:14:22:14 | 1 | | -| variables.rs:22:9:22:10 | x3 | variables.rs:23:5:23:18 | ExprStmt | match, no-match | -| variables.rs:22:14:22:14 | 1 | variables.rs:22:9:22:10 | x3 | | -| variables.rs:23:5:23:13 | PathExpr | variables.rs:23:15:23:16 | x3 | | -| variables.rs:23:5:23:17 | CallExpr | variables.rs:24:5:25:15 | LetStmt | | -| variables.rs:23:5:23:18 | ExprStmt | variables.rs:23:5:23:13 | PathExpr | | -| variables.rs:23:15:23:16 | x3 | variables.rs:23:5:23:17 | CallExpr | | -| variables.rs:24:5:25:15 | LetStmt | variables.rs:25:9:25:10 | x3 | | -| variables.rs:24:9:24:10 | x3 | variables.rs:26:5:26:18 | ExprStmt | match, no-match | -| variables.rs:25:9:25:10 | x3 | variables.rs:25:14:25:14 | 1 | | -| variables.rs:25:9:25:14 | ... + ... | variables.rs:24:9:24:10 | x3 | | -| variables.rs:25:14:25:14 | 1 | variables.rs:25:9:25:14 | ... + ... | | -| variables.rs:26:5:26:13 | PathExpr | variables.rs:26:15:26:16 | x3 | | -| variables.rs:26:5:26:17 | CallExpr | variables.rs:21:23:27:1 | BlockExpr | | -| variables.rs:26:5:26:18 | ExprStmt | variables.rs:26:5:26:13 | PathExpr | | -| variables.rs:26:15:26:16 | x3 | variables.rs:26:5:26:17 | CallExpr | | -| variables.rs:29:1:37:1 | enter variable_shadow2 | variables.rs:30:5:30:17 | LetStmt | | -| variables.rs:29:1:37:1 | exit variable_shadow2 (normal) | variables.rs:29:1:37:1 | exit variable_shadow2 | | -| variables.rs:29:23:37:1 | BlockExpr | variables.rs:29:1:37:1 | exit variable_shadow2 (normal) | | -| variables.rs:30:5:30:17 | LetStmt | variables.rs:30:14:30:16 | "a" | | -| variables.rs:30:9:30:10 | x4 | variables.rs:31:5:31:18 | ExprStmt | match, no-match | -| variables.rs:30:14:30:16 | "a" | variables.rs:30:9:30:10 | x4 | | -| variables.rs:31:5:31:13 | PathExpr | variables.rs:31:15:31:16 | x4 | | -| variables.rs:31:5:31:17 | CallExpr | variables.rs:32:5:35:5 | ExprStmt | | -| variables.rs:31:5:31:18 | ExprStmt | variables.rs:31:5:31:13 | PathExpr | | -| variables.rs:31:15:31:16 | x4 | variables.rs:31:5:31:17 | CallExpr | | -| variables.rs:32:5:35:5 | BlockExpr | variables.rs:36:5:36:18 | ExprStmt | | -| variables.rs:32:5:35:5 | ExprStmt | variables.rs:33:9:33:21 | LetStmt | | -| variables.rs:33:9:33:21 | LetStmt | variables.rs:33:18:33:20 | "b" | | -| variables.rs:33:13:33:14 | x4 | variables.rs:34:9:34:22 | ExprStmt | match, no-match | -| variables.rs:33:18:33:20 | "b" | variables.rs:33:13:33:14 | x4 | | -| variables.rs:34:9:34:17 | PathExpr | variables.rs:34:19:34:20 | x4 | | -| variables.rs:34:9:34:21 | CallExpr | variables.rs:32:5:35:5 | BlockExpr | | -| variables.rs:34:9:34:22 | ExprStmt | variables.rs:34:9:34:17 | PathExpr | | -| variables.rs:34:19:34:20 | x4 | variables.rs:34:9:34:21 | CallExpr | | -| variables.rs:36:5:36:13 | PathExpr | variables.rs:36:15:36:16 | x4 | | -| variables.rs:36:5:36:17 | CallExpr | variables.rs:29:23:37:1 | BlockExpr | | -| variables.rs:36:5:36:18 | ExprStmt | variables.rs:36:5:36:13 | PathExpr | | -| variables.rs:36:15:36:16 | x4 | variables.rs:36:5:36:17 | CallExpr | | -| variables.rs:44:1:59:1 | enter let_pattern1 | variables.rs:45:5:54:47 | LetStmt | | -| variables.rs:44:1:59:1 | exit let_pattern1 (normal) | variables.rs:44:1:59:1 | exit let_pattern1 | | -| variables.rs:44:19:59:1 | BlockExpr | variables.rs:44:1:59:1 | exit let_pattern1 (normal) | | -| variables.rs:45:5:54:47 | LetStmt | variables.rs:54:11:54:13 | "a" | | -| variables.rs:45:9:54:5 | TuplePat | variables.rs:55:5:55:18 | ExprStmt | match | -| variables.rs:54:9:54:46 | TupleExpr | variables.rs:45:9:54:5 | TuplePat | | -| variables.rs:54:10:54:19 | TupleExpr | variables.rs:54:33:54:35 | "x" | | -| variables.rs:54:11:54:13 | "a" | variables.rs:54:16:54:18 | "b" | | -| variables.rs:54:16:54:18 | "b" | variables.rs:54:10:54:19 | TupleExpr | | -| variables.rs:54:22:54:45 | RecordExpr | variables.rs:54:9:54:46 | TupleExpr | | -| variables.rs:54:33:54:35 | "x" | variables.rs:54:41:54:43 | "y" | | -| variables.rs:54:41:54:43 | "y" | variables.rs:54:22:54:45 | RecordExpr | | -| variables.rs:55:5:55:13 | PathExpr | variables.rs:55:15:55:16 | a1 | | -| variables.rs:55:5:55:17 | CallExpr | variables.rs:56:5:56:18 | ExprStmt | | -| variables.rs:55:5:55:18 | ExprStmt | variables.rs:55:5:55:13 | PathExpr | | -| variables.rs:55:15:55:16 | a1 | variables.rs:55:5:55:17 | CallExpr | | -| variables.rs:56:5:56:13 | PathExpr | variables.rs:56:15:56:16 | b1 | | -| variables.rs:56:5:56:17 | CallExpr | variables.rs:57:5:57:17 | ExprStmt | | -| variables.rs:56:5:56:18 | ExprStmt | variables.rs:56:5:56:13 | PathExpr | | -| variables.rs:56:15:56:16 | b1 | variables.rs:56:5:56:17 | CallExpr | | -| variables.rs:57:5:57:13 | PathExpr | variables.rs:57:15:57:15 | x | | -| variables.rs:57:5:57:16 | CallExpr | variables.rs:58:5:58:17 | ExprStmt | | -| variables.rs:57:5:57:17 | ExprStmt | variables.rs:57:5:57:13 | PathExpr | | -| variables.rs:57:15:57:15 | x | variables.rs:57:5:57:16 | CallExpr | | -| variables.rs:58:5:58:13 | PathExpr | variables.rs:58:15:58:15 | y | | -| variables.rs:58:5:58:16 | CallExpr | variables.rs:44:19:59:1 | BlockExpr | | -| variables.rs:58:5:58:17 | ExprStmt | variables.rs:58:5:58:13 | PathExpr | | -| variables.rs:58:15:58:15 | y | variables.rs:58:5:58:16 | CallExpr | | -| variables.rs:61:1:69:1 | enter let_pattern2 | variables.rs:62:5:62:38 | LetStmt | | -| variables.rs:61:1:69:1 | exit let_pattern2 (normal) | variables.rs:61:1:69:1 | exit let_pattern2 | | -| variables.rs:61:19:69:1 | BlockExpr | variables.rs:61:1:69:1 | exit let_pattern2 (normal) | | -| variables.rs:62:5:62:38 | LetStmt | variables.rs:62:25:62:27 | "a" | | -| variables.rs:62:9:62:10 | p1 | variables.rs:63:5:66:11 | LetStmt | match, no-match | -| variables.rs:62:14:62:37 | RecordExpr | variables.rs:62:9:62:10 | p1 | | -| variables.rs:62:25:62:27 | "a" | variables.rs:62:33:62:35 | "b" | | -| variables.rs:62:33:62:35 | "b" | variables.rs:62:14:62:37 | RecordExpr | | -| variables.rs:63:5:66:11 | LetStmt | variables.rs:66:9:66:10 | p1 | | -| variables.rs:63:9:66:5 | RecordPat | variables.rs:67:5:67:18 | ExprStmt | match | -| variables.rs:66:9:66:10 | p1 | variables.rs:63:9:66:5 | RecordPat | | -| variables.rs:67:5:67:13 | PathExpr | variables.rs:67:15:67:16 | a2 | | -| variables.rs:67:5:67:17 | CallExpr | variables.rs:68:5:68:18 | ExprStmt | | -| variables.rs:67:5:67:18 | ExprStmt | variables.rs:67:5:67:13 | PathExpr | | -| variables.rs:67:15:67:16 | a2 | variables.rs:67:5:67:17 | CallExpr | | -| variables.rs:68:5:68:13 | PathExpr | variables.rs:68:15:68:16 | b2 | | -| variables.rs:68:5:68:17 | CallExpr | variables.rs:61:19:69:1 | BlockExpr | | -| variables.rs:68:5:68:18 | ExprStmt | variables.rs:68:5:68:13 | PathExpr | | -| variables.rs:68:15:68:16 | b2 | variables.rs:68:5:68:17 | CallExpr | | -| variables.rs:71:1:78:1 | enter let_pattern3 | variables.rs:72:5:72:42 | LetStmt | | -| variables.rs:71:1:78:1 | exit let_pattern3 (normal) | variables.rs:71:1:78:1 | exit let_pattern3 | | -| variables.rs:71:19:78:1 | BlockExpr | variables.rs:71:1:78:1 | exit let_pattern3 (normal) | | -| variables.rs:72:5:72:42 | LetStmt | variables.rs:72:14:72:17 | PathExpr | | -| variables.rs:72:9:72:10 | s1 | variables.rs:74:8:75:12 | LetExpr | match, no-match | -| variables.rs:72:14:72:17 | PathExpr | variables.rs:72:19:72:30 | PathExpr | | -| variables.rs:72:14:72:41 | CallExpr | variables.rs:72:9:72:10 | s1 | | -| variables.rs:72:19:72:30 | PathExpr | variables.rs:72:32:72:39 | "Hello!" | | -| variables.rs:72:19:72:40 | CallExpr | variables.rs:72:14:72:41 | CallExpr | | -| variables.rs:72:32:72:39 | "Hello!" | variables.rs:72:19:72:40 | CallExpr | | -| variables.rs:74:5:77:5 | IfExpr | variables.rs:71:19:78:1 | BlockExpr | | -| variables.rs:74:8:75:12 | LetExpr | variables.rs:74:12:74:23 | TupleStructPat | | -| variables.rs:74:12:74:23 | TupleStructPat | variables.rs:74:5:77:5 | IfExpr | no-match | -| variables.rs:74:12:74:23 | TupleStructPat | variables.rs:76:9:76:22 | ExprStmt | match | -| variables.rs:75:14:77:5 | BlockExpr | variables.rs:74:5:77:5 | IfExpr | | -| variables.rs:76:9:76:17 | PathExpr | variables.rs:76:19:76:20 | s2 | | -| variables.rs:76:9:76:21 | CallExpr | variables.rs:75:14:77:5 | BlockExpr | | -| variables.rs:76:9:76:22 | ExprStmt | variables.rs:76:9:76:17 | PathExpr | | -| variables.rs:76:19:76:20 | s2 | variables.rs:76:9:76:21 | CallExpr | | -| variables.rs:80:1:86:1 | enter let_pattern4 | variables.rs:81:5:84:6 | LetStmt | | -| variables.rs:80:1:86:1 | exit let_pattern4 (normal) | variables.rs:80:1:86:1 | exit let_pattern4 | | -| variables.rs:80:19:86:1 | BlockExpr | variables.rs:80:1:86:1 | exit let_pattern4 (normal) | | -| variables.rs:81:5:84:6 | LetStmt | variables.rs:81:34:81:37 | PathExpr | | -| variables.rs:81:9:81:16 | TupleStructPat | variables.rs:83:9:83:15 | MacroExpr | no-match | -| variables.rs:81:9:81:16 | TupleStructPat | variables.rs:85:5:85:18 | ExprStmt | match | -| variables.rs:81:34:81:37 | PathExpr | variables.rs:81:39:81:42 | "x5" | | -| variables.rs:81:34:81:43 | CallExpr | variables.rs:81:9:81:16 | TupleStructPat | | -| variables.rs:81:39:81:42 | "x5" | variables.rs:81:34:81:43 | CallExpr | | -| variables.rs:83:9:83:15 | MacroExpr | variables.rs:81:50:84:5 | BlockExpr | | -| variables.rs:85:5:85:13 | PathExpr | variables.rs:85:15:85:16 | x5 | | -| variables.rs:85:5:85:17 | CallExpr | variables.rs:80:19:86:1 | BlockExpr | | -| variables.rs:85:5:85:18 | ExprStmt | variables.rs:85:5:85:13 | PathExpr | | -| variables.rs:85:15:85:16 | x5 | variables.rs:85:5:85:17 | CallExpr | | -| variables.rs:88:1:95:1 | enter let_pattern5 | variables.rs:89:5:89:42 | LetStmt | | -| variables.rs:88:1:95:1 | exit let_pattern5 (normal) | variables.rs:88:1:95:1 | exit let_pattern5 | | -| variables.rs:88:19:95:1 | BlockExpr | variables.rs:88:1:95:1 | exit let_pattern5 (normal) | | -| variables.rs:89:5:89:42 | LetStmt | variables.rs:89:14:89:17 | PathExpr | | -| variables.rs:89:9:89:10 | s1 | variables.rs:91:11:92:12 | LetExpr | match, no-match | -| variables.rs:89:14:89:17 | PathExpr | variables.rs:89:19:89:30 | PathExpr | | -| variables.rs:89:14:89:41 | CallExpr | variables.rs:89:9:89:10 | s1 | | -| variables.rs:89:19:89:30 | PathExpr | variables.rs:89:32:89:39 | "Hello!" | | -| variables.rs:89:19:89:40 | CallExpr | variables.rs:89:14:89:41 | CallExpr | | -| variables.rs:89:32:89:39 | "Hello!" | variables.rs:89:19:89:40 | CallExpr | | -| variables.rs:91:5:94:5 | WhileExpr | variables.rs:88:19:95:1 | BlockExpr | | -| variables.rs:91:11:92:12 | LetExpr | variables.rs:91:15:91:26 | TupleStructPat | | -| variables.rs:91:15:91:26 | TupleStructPat | variables.rs:91:5:94:5 | WhileExpr | no-match | -| variables.rs:91:15:91:26 | TupleStructPat | variables.rs:93:9:93:22 | ExprStmt | match | -| variables.rs:92:14:94:5 | BlockExpr | variables.rs:91:11:92:12 | LetExpr | | -| variables.rs:93:9:93:17 | PathExpr | variables.rs:93:19:93:20 | s2 | | -| variables.rs:93:9:93:21 | CallExpr | variables.rs:92:14:94:5 | BlockExpr | | -| variables.rs:93:9:93:22 | ExprStmt | variables.rs:93:9:93:17 | PathExpr | | -| variables.rs:93:19:93:20 | s2 | variables.rs:93:9:93:21 | CallExpr | | -| variables.rs:97:1:112:1 | enter match_pattern1 | variables.rs:98:5:98:21 | LetStmt | | -| variables.rs:97:1:112:1 | exit match_pattern1 (normal) | variables.rs:97:1:112:1 | exit match_pattern1 | | -| variables.rs:97:21:112:1 | BlockExpr | variables.rs:97:1:112:1 | exit match_pattern1 (normal) | | -| variables.rs:98:5:98:21 | LetStmt | variables.rs:98:14:98:17 | PathExpr | | -| variables.rs:98:9:98:10 | x6 | variables.rs:99:5:99:16 | LetStmt | match, no-match | -| variables.rs:98:14:98:17 | PathExpr | variables.rs:98:19:98:19 | 5 | | -| variables.rs:98:14:98:20 | CallExpr | variables.rs:98:9:98:10 | x6 | | -| variables.rs:98:19:98:19 | 5 | variables.rs:98:14:98:20 | CallExpr | | -| variables.rs:99:5:99:16 | LetStmt | variables.rs:99:14:99:15 | 10 | | -| variables.rs:99:9:99:10 | y1 | variables.rs:101:5:109:5 | ExprStmt | match, no-match | -| variables.rs:99:14:99:15 | 10 | variables.rs:99:9:99:10 | y1 | | -| variables.rs:101:5:109:5 | ExprStmt | variables.rs:101:11:101:12 | x6 | | -| variables.rs:101:5:109:5 | MatchExpr | variables.rs:111:5:111:18 | ExprStmt | | -| variables.rs:101:11:101:12 | x6 | variables.rs:102:9:102:16 | TupleStructPat | | -| variables.rs:102:9:102:16 | TupleStructPat | variables.rs:102:21:102:29 | PathExpr | match | -| variables.rs:102:9:102:16 | TupleStructPat | variables.rs:103:9:103:16 | TupleStructPat | no-match | -| variables.rs:102:21:102:29 | PathExpr | variables.rs:102:31:102:38 | "Got 50" | | -| variables.rs:102:21:102:39 | CallExpr | variables.rs:101:5:109:5 | MatchExpr | | -| variables.rs:102:31:102:38 | "Got 50" | variables.rs:102:21:102:39 | CallExpr | | -| variables.rs:103:9:103:16 | TupleStructPat | variables.rs:106:13:106:21 | PathExpr | match | -| variables.rs:103:9:103:16 | TupleStructPat | variables.rs:108:9:108:12 | None | no-match | -| variables.rs:105:9:107:9 | BlockExpr | variables.rs:101:5:109:5 | MatchExpr | | -| variables.rs:106:13:106:21 | PathExpr | variables.rs:106:23:106:24 | y1 | | -| variables.rs:106:13:106:25 | CallExpr | variables.rs:105:9:107:9 | BlockExpr | | -| variables.rs:106:23:106:24 | y1 | variables.rs:106:13:106:25 | CallExpr | | -| variables.rs:108:9:108:12 | None | variables.rs:108:17:108:25 | PathExpr | match | -| variables.rs:108:17:108:25 | PathExpr | variables.rs:108:27:108:32 | "NONE" | | -| variables.rs:108:17:108:33 | CallExpr | variables.rs:101:5:109:5 | MatchExpr | | -| variables.rs:108:27:108:32 | "NONE" | variables.rs:108:17:108:33 | CallExpr | | -| variables.rs:111:5:111:13 | PathExpr | variables.rs:111:15:111:16 | y1 | | -| variables.rs:111:5:111:17 | CallExpr | variables.rs:97:21:112:1 | BlockExpr | | -| variables.rs:111:5:111:18 | ExprStmt | variables.rs:111:5:111:13 | PathExpr | | -| variables.rs:111:15:111:16 | y1 | variables.rs:111:5:111:17 | CallExpr | | -| variables.rs:114:1:139:1 | enter match_pattern2 | variables.rs:115:5:115:36 | LetStmt | | -| variables.rs:114:1:139:1 | exit match_pattern2 (normal) | variables.rs:114:1:139:1 | exit match_pattern2 | | -| variables.rs:114:21:139:1 | BlockExpr | variables.rs:114:1:139:1 | exit match_pattern2 (normal) | | -| variables.rs:115:5:115:36 | LetStmt | variables.rs:115:20:115:20 | 2 | | -| variables.rs:115:9:115:15 | numbers | variables.rs:117:5:127:5 | ExprStmt | match, no-match | -| variables.rs:115:19:115:35 | TupleExpr | variables.rs:115:9:115:15 | numbers | | -| variables.rs:115:20:115:20 | 2 | variables.rs:115:23:115:23 | 4 | | -| variables.rs:115:23:115:23 | 4 | variables.rs:115:26:115:26 | 8 | | -| variables.rs:115:26:115:26 | 8 | variables.rs:115:29:115:30 | 16 | | -| variables.rs:115:29:115:30 | 16 | variables.rs:115:33:115:34 | 32 | | -| variables.rs:115:33:115:34 | 32 | variables.rs:115:19:115:35 | TupleExpr | | -| variables.rs:117:5:127:5 | ExprStmt | variables.rs:117:11:117:17 | numbers | | -| variables.rs:117:5:127:5 | MatchExpr | variables.rs:129:11:129:17 | numbers | | -| variables.rs:117:11:117:17 | numbers | variables.rs:118:9:122:9 | TuplePat | | -| variables.rs:118:9:122:9 | TuplePat | variables.rs:123:13:123:29 | ExprStmt | match | -| variables.rs:122:14:126:9 | BlockExpr | variables.rs:117:5:127:5 | MatchExpr | | -| variables.rs:123:13:123:21 | PathExpr | variables.rs:123:23:123:27 | first | | -| variables.rs:123:13:123:28 | CallExpr | variables.rs:124:13:124:29 | ExprStmt | | -| variables.rs:123:13:123:29 | ExprStmt | variables.rs:123:13:123:21 | PathExpr | | -| variables.rs:123:23:123:27 | first | variables.rs:123:13:123:28 | CallExpr | | -| variables.rs:124:13:124:21 | PathExpr | variables.rs:124:23:124:27 | third | | -| variables.rs:124:13:124:28 | CallExpr | variables.rs:125:13:125:29 | ExprStmt | | -| variables.rs:124:13:124:29 | ExprStmt | variables.rs:124:13:124:21 | PathExpr | | -| variables.rs:124:23:124:27 | third | variables.rs:124:13:124:28 | CallExpr | | -| variables.rs:125:13:125:21 | PathExpr | variables.rs:125:23:125:27 | fifth | | -| variables.rs:125:13:125:28 | CallExpr | variables.rs:122:14:126:9 | BlockExpr | | +| variables.rs:19:5:19:6 | x2 | variables.rs:19:10:19:10 | 5 | | +| variables.rs:19:5:19:10 | ... = ... | variables.rs:20:5:20:18 | ExprStmt | | +| variables.rs:19:5:19:11 | ExprStmt | variables.rs:19:5:19:6 | x2 | | +| variables.rs:19:10:19:10 | 5 | variables.rs:19:5:19:10 | ... = ... | | +| variables.rs:20:5:20:13 | PathExpr | variables.rs:20:15:20:16 | x2 | | +| variables.rs:20:5:20:17 | CallExpr | variables.rs:16:23:21:1 | BlockExpr | | +| variables.rs:20:5:20:18 | ExprStmt | variables.rs:20:5:20:13 | PathExpr | | +| variables.rs:20:15:20:16 | x2 | variables.rs:20:5:20:17 | CallExpr | | +| variables.rs:23:1:29:1 | enter variable_shadow1 | variables.rs:24:5:24:15 | LetStmt | | +| variables.rs:23:1:29:1 | exit variable_shadow1 (normal) | variables.rs:23:1:29:1 | exit variable_shadow1 | | +| variables.rs:23:23:29:1 | BlockExpr | variables.rs:23:1:29:1 | exit variable_shadow1 (normal) | | +| variables.rs:24:5:24:15 | LetStmt | variables.rs:24:14:24:14 | 1 | | +| variables.rs:24:9:24:10 | x3 | variables.rs:25:5:25:18 | ExprStmt | match, no-match | +| variables.rs:24:14:24:14 | 1 | variables.rs:24:9:24:10 | x3 | | +| variables.rs:25:5:25:13 | PathExpr | variables.rs:25:15:25:16 | x3 | | +| variables.rs:25:5:25:17 | CallExpr | variables.rs:26:5:27:15 | LetStmt | | +| variables.rs:25:5:25:18 | ExprStmt | variables.rs:25:5:25:13 | PathExpr | | +| variables.rs:25:15:25:16 | x3 | variables.rs:25:5:25:17 | CallExpr | | +| variables.rs:26:5:27:15 | LetStmt | variables.rs:27:9:27:10 | x3 | | +| variables.rs:26:9:26:10 | x3 | variables.rs:28:5:28:18 | ExprStmt | match, no-match | +| variables.rs:27:9:27:10 | x3 | variables.rs:27:14:27:14 | 1 | | +| variables.rs:27:9:27:14 | ... + ... | variables.rs:26:9:26:10 | x3 | | +| variables.rs:27:14:27:14 | 1 | variables.rs:27:9:27:14 | ... + ... | | +| variables.rs:28:5:28:13 | PathExpr | variables.rs:28:15:28:16 | x3 | | +| variables.rs:28:5:28:17 | CallExpr | variables.rs:23:23:29:1 | BlockExpr | | +| variables.rs:28:5:28:18 | ExprStmt | variables.rs:28:5:28:13 | PathExpr | | +| variables.rs:28:15:28:16 | x3 | variables.rs:28:5:28:17 | CallExpr | | +| variables.rs:31:1:39:1 | enter variable_shadow2 | variables.rs:32:5:32:17 | LetStmt | | +| variables.rs:31:1:39:1 | exit variable_shadow2 (normal) | variables.rs:31:1:39:1 | exit variable_shadow2 | | +| variables.rs:31:23:39:1 | BlockExpr | variables.rs:31:1:39:1 | exit variable_shadow2 (normal) | | +| variables.rs:32:5:32:17 | LetStmt | variables.rs:32:14:32:16 | "a" | | +| variables.rs:32:9:32:10 | x4 | variables.rs:33:5:33:18 | ExprStmt | match, no-match | +| variables.rs:32:14:32:16 | "a" | variables.rs:32:9:32:10 | x4 | | +| variables.rs:33:5:33:13 | PathExpr | variables.rs:33:15:33:16 | x4 | | +| variables.rs:33:5:33:17 | CallExpr | variables.rs:34:5:37:5 | ExprStmt | | +| variables.rs:33:5:33:18 | ExprStmt | variables.rs:33:5:33:13 | PathExpr | | +| variables.rs:33:15:33:16 | x4 | variables.rs:33:5:33:17 | CallExpr | | +| variables.rs:34:5:37:5 | BlockExpr | variables.rs:38:5:38:18 | ExprStmt | | +| variables.rs:34:5:37:5 | ExprStmt | variables.rs:35:9:35:21 | LetStmt | | +| variables.rs:35:9:35:21 | LetStmt | variables.rs:35:18:35:20 | "b" | | +| variables.rs:35:13:35:14 | x4 | variables.rs:36:9:36:22 | ExprStmt | match, no-match | +| variables.rs:35:18:35:20 | "b" | variables.rs:35:13:35:14 | x4 | | +| variables.rs:36:9:36:17 | PathExpr | variables.rs:36:19:36:20 | x4 | | +| variables.rs:36:9:36:21 | CallExpr | variables.rs:34:5:37:5 | BlockExpr | | +| variables.rs:36:9:36:22 | ExprStmt | variables.rs:36:9:36:17 | PathExpr | | +| variables.rs:36:19:36:20 | x4 | variables.rs:36:9:36:21 | CallExpr | | +| variables.rs:38:5:38:13 | PathExpr | variables.rs:38:15:38:16 | x4 | | +| variables.rs:38:5:38:17 | CallExpr | variables.rs:31:23:39:1 | BlockExpr | | +| variables.rs:38:5:38:18 | ExprStmt | variables.rs:38:5:38:13 | PathExpr | | +| variables.rs:38:15:38:16 | x4 | variables.rs:38:5:38:17 | CallExpr | | +| variables.rs:46:1:61:1 | enter let_pattern1 | variables.rs:47:5:56:47 | LetStmt | | +| variables.rs:46:1:61:1 | exit let_pattern1 (normal) | variables.rs:46:1:61:1 | exit let_pattern1 | | +| variables.rs:46:19:61:1 | BlockExpr | variables.rs:46:1:61:1 | exit let_pattern1 (normal) | | +| variables.rs:47:5:56:47 | LetStmt | variables.rs:56:11:56:13 | "a" | | +| variables.rs:47:9:56:5 | TuplePat | variables.rs:57:5:57:18 | ExprStmt | match | +| variables.rs:56:9:56:46 | TupleExpr | variables.rs:47:9:56:5 | TuplePat | | +| variables.rs:56:10:56:19 | TupleExpr | variables.rs:56:33:56:35 | "x" | | +| variables.rs:56:11:56:13 | "a" | variables.rs:56:16:56:18 | "b" | | +| variables.rs:56:16:56:18 | "b" | variables.rs:56:10:56:19 | TupleExpr | | +| variables.rs:56:22:56:45 | RecordExpr | variables.rs:56:9:56:46 | TupleExpr | | +| variables.rs:56:33:56:35 | "x" | variables.rs:56:41:56:43 | "y" | | +| variables.rs:56:41:56:43 | "y" | variables.rs:56:22:56:45 | RecordExpr | | +| variables.rs:57:5:57:13 | PathExpr | variables.rs:57:15:57:16 | a1 | | +| variables.rs:57:5:57:17 | CallExpr | variables.rs:58:5:58:18 | ExprStmt | | +| variables.rs:57:5:57:18 | ExprStmt | variables.rs:57:5:57:13 | PathExpr | | +| variables.rs:57:15:57:16 | a1 | variables.rs:57:5:57:17 | CallExpr | | +| variables.rs:58:5:58:13 | PathExpr | variables.rs:58:15:58:16 | b1 | | +| variables.rs:58:5:58:17 | CallExpr | variables.rs:59:5:59:17 | ExprStmt | | +| variables.rs:58:5:58:18 | ExprStmt | variables.rs:58:5:58:13 | PathExpr | | +| variables.rs:58:15:58:16 | b1 | variables.rs:58:5:58:17 | CallExpr | | +| variables.rs:59:5:59:13 | PathExpr | variables.rs:59:15:59:15 | x | | +| variables.rs:59:5:59:16 | CallExpr | variables.rs:60:5:60:17 | ExprStmt | | +| variables.rs:59:5:59:17 | ExprStmt | variables.rs:59:5:59:13 | PathExpr | | +| variables.rs:59:15:59:15 | x | variables.rs:59:5:59:16 | CallExpr | | +| variables.rs:60:5:60:13 | PathExpr | variables.rs:60:15:60:15 | y | | +| variables.rs:60:5:60:16 | CallExpr | variables.rs:46:19:61:1 | BlockExpr | | +| variables.rs:60:5:60:17 | ExprStmt | variables.rs:60:5:60:13 | PathExpr | | +| variables.rs:60:15:60:15 | y | variables.rs:60:5:60:16 | CallExpr | | +| variables.rs:63:1:71:1 | enter let_pattern2 | variables.rs:64:5:64:38 | LetStmt | | +| variables.rs:63:1:71:1 | exit let_pattern2 (normal) | variables.rs:63:1:71:1 | exit let_pattern2 | | +| variables.rs:63:19:71:1 | BlockExpr | variables.rs:63:1:71:1 | exit let_pattern2 (normal) | | +| variables.rs:64:5:64:38 | LetStmt | variables.rs:64:25:64:27 | "a" | | +| variables.rs:64:9:64:10 | p1 | variables.rs:65:5:68:11 | LetStmt | match, no-match | +| variables.rs:64:14:64:37 | RecordExpr | variables.rs:64:9:64:10 | p1 | | +| variables.rs:64:25:64:27 | "a" | variables.rs:64:33:64:35 | "b" | | +| variables.rs:64:33:64:35 | "b" | variables.rs:64:14:64:37 | RecordExpr | | +| variables.rs:65:5:68:11 | LetStmt | variables.rs:68:9:68:10 | p1 | | +| variables.rs:65:9:68:5 | RecordPat | variables.rs:69:5:69:18 | ExprStmt | match | +| variables.rs:68:9:68:10 | p1 | variables.rs:65:9:68:5 | RecordPat | | +| variables.rs:69:5:69:13 | PathExpr | variables.rs:69:15:69:16 | a2 | | +| variables.rs:69:5:69:17 | CallExpr | variables.rs:70:5:70:18 | ExprStmt | | +| variables.rs:69:5:69:18 | ExprStmt | variables.rs:69:5:69:13 | PathExpr | | +| variables.rs:69:15:69:16 | a2 | variables.rs:69:5:69:17 | CallExpr | | +| variables.rs:70:5:70:13 | PathExpr | variables.rs:70:15:70:16 | b2 | | +| variables.rs:70:5:70:17 | CallExpr | variables.rs:63:19:71:1 | BlockExpr | | +| variables.rs:70:5:70:18 | ExprStmt | variables.rs:70:5:70:13 | PathExpr | | +| variables.rs:70:15:70:16 | b2 | variables.rs:70:5:70:17 | CallExpr | | +| variables.rs:73:1:80:1 | enter let_pattern3 | variables.rs:74:5:74:42 | LetStmt | | +| variables.rs:73:1:80:1 | exit let_pattern3 (normal) | variables.rs:73:1:80:1 | exit let_pattern3 | | +| variables.rs:73:19:80:1 | BlockExpr | variables.rs:73:1:80:1 | exit let_pattern3 (normal) | | +| variables.rs:74:5:74:42 | LetStmt | variables.rs:74:14:74:17 | PathExpr | | +| variables.rs:74:9:74:10 | s1 | variables.rs:76:8:77:12 | LetExpr | match, no-match | +| variables.rs:74:14:74:17 | PathExpr | variables.rs:74:19:74:30 | PathExpr | | +| variables.rs:74:14:74:41 | CallExpr | variables.rs:74:9:74:10 | s1 | | +| variables.rs:74:19:74:30 | PathExpr | variables.rs:74:32:74:39 | "Hello!" | | +| variables.rs:74:19:74:40 | CallExpr | variables.rs:74:14:74:41 | CallExpr | | +| variables.rs:74:32:74:39 | "Hello!" | variables.rs:74:19:74:40 | CallExpr | | +| variables.rs:76:5:79:5 | IfExpr | variables.rs:73:19:80:1 | BlockExpr | | +| variables.rs:76:8:77:12 | LetExpr | variables.rs:76:12:76:23 | TupleStructPat | | +| variables.rs:76:12:76:23 | TupleStructPat | variables.rs:76:5:79:5 | IfExpr | no-match | +| variables.rs:76:12:76:23 | TupleStructPat | variables.rs:78:9:78:22 | ExprStmt | match | +| variables.rs:77:14:79:5 | BlockExpr | variables.rs:76:5:79:5 | IfExpr | | +| variables.rs:78:9:78:17 | PathExpr | variables.rs:78:19:78:20 | s2 | | +| variables.rs:78:9:78:21 | CallExpr | variables.rs:77:14:79:5 | BlockExpr | | +| variables.rs:78:9:78:22 | ExprStmt | variables.rs:78:9:78:17 | PathExpr | | +| variables.rs:78:19:78:20 | s2 | variables.rs:78:9:78:21 | CallExpr | | +| variables.rs:82:1:88:1 | enter let_pattern4 | variables.rs:83:5:86:10 | LetStmt | | +| variables.rs:82:1:88:1 | exit let_pattern4 (normal) | variables.rs:82:1:88:1 | exit let_pattern4 | | +| variables.rs:82:19:88:1 | BlockExpr | variables.rs:82:1:88:1 | exit let_pattern4 (normal) | | +| variables.rs:83:5:86:10 | LetStmt | variables.rs:83:34:83:37 | PathExpr | | +| variables.rs:83:9:83:16 | TupleStructPat | variables.rs:85:13:85:19 | MacroExpr | no-match | +| variables.rs:83:9:83:16 | TupleStructPat | variables.rs:87:5:87:18 | ExprStmt | match | +| variables.rs:83:34:83:37 | PathExpr | variables.rs:83:39:83:42 | "x5" | | +| variables.rs:83:34:83:43 | CallExpr | variables.rs:83:9:83:16 | TupleStructPat | | +| variables.rs:83:39:83:42 | "x5" | variables.rs:83:34:83:43 | CallExpr | | +| variables.rs:85:13:85:19 | MacroExpr | variables.rs:84:14:86:9 | BlockExpr | | +| variables.rs:87:5:87:13 | PathExpr | variables.rs:87:15:87:16 | x5 | | +| variables.rs:87:5:87:17 | CallExpr | variables.rs:82:19:88:1 | BlockExpr | | +| variables.rs:87:5:87:18 | ExprStmt | variables.rs:87:5:87:13 | PathExpr | | +| variables.rs:87:15:87:16 | x5 | variables.rs:87:5:87:17 | CallExpr | | +| variables.rs:90:1:97:1 | enter let_pattern5 | variables.rs:91:5:91:42 | LetStmt | | +| variables.rs:90:1:97:1 | exit let_pattern5 (normal) | variables.rs:90:1:97:1 | exit let_pattern5 | | +| variables.rs:90:19:97:1 | BlockExpr | variables.rs:90:1:97:1 | exit let_pattern5 (normal) | | +| variables.rs:91:5:91:42 | LetStmt | variables.rs:91:14:91:17 | PathExpr | | +| variables.rs:91:9:91:10 | s1 | variables.rs:93:11:94:12 | LetExpr | match, no-match | +| variables.rs:91:14:91:17 | PathExpr | variables.rs:91:19:91:30 | PathExpr | | +| variables.rs:91:14:91:41 | CallExpr | variables.rs:91:9:91:10 | s1 | | +| variables.rs:91:19:91:30 | PathExpr | variables.rs:91:32:91:39 | "Hello!" | | +| variables.rs:91:19:91:40 | CallExpr | variables.rs:91:14:91:41 | CallExpr | | +| variables.rs:91:32:91:39 | "Hello!" | variables.rs:91:19:91:40 | CallExpr | | +| variables.rs:93:5:96:5 | WhileExpr | variables.rs:90:19:97:1 | BlockExpr | | +| variables.rs:93:11:94:12 | LetExpr | variables.rs:93:15:93:26 | TupleStructPat | | +| variables.rs:93:15:93:26 | TupleStructPat | variables.rs:93:5:96:5 | WhileExpr | no-match | +| variables.rs:93:15:93:26 | TupleStructPat | variables.rs:95:9:95:22 | ExprStmt | match | +| variables.rs:94:14:96:5 | BlockExpr | variables.rs:93:11:94:12 | LetExpr | | +| variables.rs:95:9:95:17 | PathExpr | variables.rs:95:19:95:20 | s2 | | +| variables.rs:95:9:95:21 | CallExpr | variables.rs:94:14:96:5 | BlockExpr | | +| variables.rs:95:9:95:22 | ExprStmt | variables.rs:95:9:95:17 | PathExpr | | +| variables.rs:95:19:95:20 | s2 | variables.rs:95:9:95:21 | CallExpr | | +| variables.rs:99:1:114:1 | enter match_pattern1 | variables.rs:100:5:100:21 | LetStmt | | +| variables.rs:99:1:114:1 | exit match_pattern1 (normal) | variables.rs:99:1:114:1 | exit match_pattern1 | | +| variables.rs:99:21:114:1 | BlockExpr | variables.rs:99:1:114:1 | exit match_pattern1 (normal) | | +| variables.rs:100:5:100:21 | LetStmt | variables.rs:100:14:100:17 | PathExpr | | +| variables.rs:100:9:100:10 | x6 | variables.rs:101:5:101:16 | LetStmt | match, no-match | +| variables.rs:100:14:100:17 | PathExpr | variables.rs:100:19:100:19 | 5 | | +| variables.rs:100:14:100:20 | CallExpr | variables.rs:100:9:100:10 | x6 | | +| variables.rs:100:19:100:19 | 5 | variables.rs:100:14:100:20 | CallExpr | | +| variables.rs:101:5:101:16 | LetStmt | variables.rs:101:14:101:15 | 10 | | +| variables.rs:101:9:101:10 | y1 | variables.rs:103:5:111:5 | ExprStmt | match, no-match | +| variables.rs:101:14:101:15 | 10 | variables.rs:101:9:101:10 | y1 | | +| variables.rs:103:5:111:5 | ExprStmt | variables.rs:103:11:103:12 | x6 | | +| variables.rs:103:5:111:5 | MatchExpr | variables.rs:113:5:113:18 | ExprStmt | | +| variables.rs:103:11:103:12 | x6 | variables.rs:104:9:104:16 | TupleStructPat | | +| variables.rs:104:9:104:16 | TupleStructPat | variables.rs:104:21:104:29 | PathExpr | match | +| variables.rs:104:9:104:16 | TupleStructPat | variables.rs:105:9:105:16 | TupleStructPat | no-match | +| variables.rs:104:21:104:29 | PathExpr | variables.rs:104:31:104:38 | "Got 50" | | +| variables.rs:104:21:104:39 | CallExpr | variables.rs:103:5:111:5 | MatchExpr | | +| variables.rs:104:31:104:38 | "Got 50" | variables.rs:104:21:104:39 | CallExpr | | +| variables.rs:105:9:105:16 | TupleStructPat | variables.rs:108:13:108:21 | PathExpr | match | +| variables.rs:105:9:105:16 | TupleStructPat | variables.rs:110:9:110:12 | None | no-match | +| variables.rs:107:9:109:9 | BlockExpr | variables.rs:103:5:111:5 | MatchExpr | | +| variables.rs:108:13:108:21 | PathExpr | variables.rs:108:23:108:24 | y1 | | +| variables.rs:108:13:108:25 | CallExpr | variables.rs:107:9:109:9 | BlockExpr | | +| variables.rs:108:23:108:24 | y1 | variables.rs:108:13:108:25 | CallExpr | | +| variables.rs:110:9:110:12 | None | variables.rs:110:17:110:25 | PathExpr | match | +| variables.rs:110:17:110:25 | PathExpr | variables.rs:110:27:110:32 | "NONE" | | +| variables.rs:110:17:110:33 | CallExpr | variables.rs:103:5:111:5 | MatchExpr | | +| variables.rs:110:27:110:32 | "NONE" | variables.rs:110:17:110:33 | CallExpr | | +| variables.rs:113:5:113:13 | PathExpr | variables.rs:113:15:113:16 | y1 | | +| variables.rs:113:5:113:17 | CallExpr | variables.rs:99:21:114:1 | BlockExpr | | +| variables.rs:113:5:113:18 | ExprStmt | variables.rs:113:5:113:13 | PathExpr | | +| variables.rs:113:15:113:16 | y1 | variables.rs:113:5:113:17 | CallExpr | | +| variables.rs:116:1:141:1 | enter match_pattern2 | variables.rs:117:5:117:36 | LetStmt | | +| variables.rs:116:1:141:1 | exit match_pattern2 (normal) | variables.rs:116:1:141:1 | exit match_pattern2 | | +| variables.rs:116:21:141:1 | BlockExpr | variables.rs:116:1:141:1 | exit match_pattern2 (normal) | | +| variables.rs:117:5:117:36 | LetStmt | variables.rs:117:20:117:20 | 2 | | +| variables.rs:117:9:117:15 | numbers | variables.rs:119:5:129:5 | ExprStmt | match, no-match | +| variables.rs:117:19:117:35 | TupleExpr | variables.rs:117:9:117:15 | numbers | | +| variables.rs:117:20:117:20 | 2 | variables.rs:117:23:117:23 | 4 | | +| variables.rs:117:23:117:23 | 4 | variables.rs:117:26:117:26 | 8 | | +| variables.rs:117:26:117:26 | 8 | variables.rs:117:29:117:30 | 16 | | +| variables.rs:117:29:117:30 | 16 | variables.rs:117:33:117:34 | 32 | | +| variables.rs:117:33:117:34 | 32 | variables.rs:117:19:117:35 | TupleExpr | | +| variables.rs:119:5:129:5 | ExprStmt | variables.rs:119:11:119:17 | numbers | | +| variables.rs:119:5:129:5 | MatchExpr | variables.rs:131:11:131:17 | numbers | | +| variables.rs:119:11:119:17 | numbers | variables.rs:120:9:124:9 | TuplePat | | +| variables.rs:120:9:124:9 | TuplePat | variables.rs:125:13:125:29 | ExprStmt | match | +| variables.rs:124:14:128:9 | BlockExpr | variables.rs:119:5:129:5 | MatchExpr | | +| variables.rs:125:13:125:21 | PathExpr | variables.rs:125:23:125:27 | first | | +| variables.rs:125:13:125:28 | CallExpr | variables.rs:126:13:126:29 | ExprStmt | | | variables.rs:125:13:125:29 | ExprStmt | variables.rs:125:13:125:21 | PathExpr | | -| variables.rs:125:23:125:27 | fifth | variables.rs:125:13:125:28 | CallExpr | | -| variables.rs:129:5:138:5 | MatchExpr | variables.rs:114:21:139:1 | BlockExpr | | -| variables.rs:129:11:129:17 | numbers | variables.rs:130:9:134:9 | TuplePat | | -| variables.rs:130:9:134:9 | TuplePat | variables.rs:135:13:135:29 | ExprStmt | match | -| variables.rs:134:14:137:9 | BlockExpr | variables.rs:129:5:138:5 | MatchExpr | | -| variables.rs:135:13:135:21 | PathExpr | variables.rs:135:23:135:27 | first | | -| variables.rs:135:13:135:28 | CallExpr | variables.rs:136:13:136:28 | ExprStmt | | -| variables.rs:135:13:135:29 | ExprStmt | variables.rs:135:13:135:21 | PathExpr | | -| variables.rs:135:23:135:27 | first | variables.rs:135:13:135:28 | CallExpr | | -| variables.rs:136:13:136:21 | PathExpr | variables.rs:136:23:136:26 | last | | -| variables.rs:136:13:136:27 | CallExpr | variables.rs:134:14:137:9 | BlockExpr | | -| variables.rs:136:13:136:28 | ExprStmt | variables.rs:136:13:136:21 | PathExpr | | -| variables.rs:136:23:136:26 | last | variables.rs:136:13:136:27 | CallExpr | | -| variables.rs:141:1:149:1 | enter match_pattern3 | variables.rs:142:5:142:38 | LetStmt | | -| variables.rs:141:1:149:1 | exit match_pattern3 (normal) | variables.rs:141:1:149:1 | exit match_pattern3 | | -| variables.rs:141:21:149:1 | BlockExpr | variables.rs:141:1:149:1 | exit match_pattern3 (normal) | | -| variables.rs:142:5:142:38 | LetStmt | variables.rs:142:25:142:27 | "x" | | -| variables.rs:142:9:142:10 | p2 | variables.rs:144:11:144:12 | p2 | match, no-match | -| variables.rs:142:14:142:37 | RecordExpr | variables.rs:142:9:142:10 | p2 | | -| variables.rs:142:25:142:27 | "x" | variables.rs:142:33:142:35 | "y" | | -| variables.rs:142:33:142:35 | "y" | variables.rs:142:14:142:37 | RecordExpr | | -| variables.rs:144:5:148:5 | MatchExpr | variables.rs:141:21:149:1 | BlockExpr | | -| variables.rs:144:11:144:12 | p2 | variables.rs:145:9:147:9 | RecordPat | | -| variables.rs:145:9:147:9 | RecordPat | variables.rs:147:14:147:22 | PathExpr | match | -| variables.rs:147:14:147:22 | PathExpr | variables.rs:147:24:147:25 | x7 | | -| variables.rs:147:14:147:26 | CallExpr | variables.rs:144:5:148:5 | MatchExpr | | -| variables.rs:147:24:147:25 | x7 | variables.rs:147:14:147:26 | CallExpr | | -| variables.rs:155:1:168:1 | enter match_pattern4 | variables.rs:156:5:156:39 | LetStmt | | -| variables.rs:155:1:168:1 | exit match_pattern4 (normal) | variables.rs:155:1:168:1 | exit match_pattern4 | | -| variables.rs:155:21:168:1 | BlockExpr | variables.rs:155:1:168:1 | exit match_pattern4 (normal) | | -| variables.rs:156:5:156:39 | LetStmt | variables.rs:156:36:156:36 | 0 | | -| variables.rs:156:9:156:11 | msg | variables.rs:158:11:158:13 | msg | match, no-match | -| variables.rs:156:15:156:38 | RecordExpr | variables.rs:156:9:156:11 | msg | | -| variables.rs:156:36:156:36 | 0 | variables.rs:156:15:156:38 | RecordExpr | | -| variables.rs:158:5:167:5 | MatchExpr | variables.rs:155:21:168:1 | BlockExpr | | -| variables.rs:158:11:158:13 | msg | variables.rs:159:9:161:9 | RecordPat | | -| variables.rs:159:9:161:9 | RecordPat | variables.rs:161:14:161:22 | PathExpr | match | -| variables.rs:159:9:161:9 | RecordPat | variables.rs:162:9:162:38 | RecordPat | no-match | -| variables.rs:161:14:161:22 | PathExpr | variables.rs:161:24:161:34 | id_variable | | -| variables.rs:161:14:161:35 | CallExpr | variables.rs:158:5:167:5 | MatchExpr | | -| variables.rs:161:24:161:34 | id_variable | variables.rs:161:14:161:35 | CallExpr | | -| variables.rs:162:9:162:38 | RecordPat | variables.rs:163:13:163:52 | MacroExpr | match | -| variables.rs:162:9:162:38 | RecordPat | variables.rs:165:9:165:29 | RecordPat | no-match | -| variables.rs:162:43:164:9 | BlockExpr | variables.rs:158:5:167:5 | MatchExpr | | -| variables.rs:163:13:163:52 | MacroExpr | variables.rs:162:43:164:9 | BlockExpr | | -| variables.rs:165:9:165:29 | RecordPat | variables.rs:166:13:166:21 | PathExpr | match | -| variables.rs:166:13:166:21 | PathExpr | variables.rs:166:23:166:24 | id | | -| variables.rs:166:13:166:25 | CallExpr | variables.rs:158:5:167:5 | MatchExpr | | -| variables.rs:166:23:166:24 | id | variables.rs:166:13:166:25 | CallExpr | | -| variables.rs:175:1:181:1 | enter match_pattern5 | variables.rs:176:5:176:34 | LetStmt | | -| variables.rs:175:1:181:1 | exit match_pattern5 (normal) | variables.rs:175:1:181:1 | exit match_pattern5 | | -| variables.rs:175:21:181:1 | BlockExpr | variables.rs:175:1:181:1 | exit match_pattern5 (normal) | | -| variables.rs:176:5:176:34 | LetStmt | variables.rs:176:18:176:29 | PathExpr | | -| variables.rs:176:9:176:14 | either | variables.rs:177:11:177:16 | either | match, no-match | -| variables.rs:176:18:176:29 | PathExpr | variables.rs:176:31:176:32 | 32 | | -| variables.rs:176:18:176:33 | CallExpr | variables.rs:176:9:176:14 | either | | -| variables.rs:176:31:176:32 | 32 | variables.rs:176:18:176:33 | CallExpr | | -| variables.rs:177:5:180:5 | MatchExpr | variables.rs:175:21:181:1 | BlockExpr | | -| variables.rs:177:11:177:16 | either | variables.rs:178:9:178:44 | OrPat | | -| variables.rs:178:9:178:44 | OrPat | variables.rs:179:16:179:24 | PathExpr | match | -| variables.rs:179:16:179:24 | PathExpr | variables.rs:179:26:179:27 | a3 | | -| variables.rs:179:16:179:28 | CallExpr | variables.rs:177:5:180:5 | MatchExpr | | -| variables.rs:179:26:179:27 | a3 | variables.rs:179:16:179:28 | CallExpr | | -| variables.rs:189:1:203:1 | enter match_pattern6 | variables.rs:190:5:190:37 | LetStmt | | -| variables.rs:189:1:203:1 | exit match_pattern6 (normal) | variables.rs:189:1:203:1 | exit match_pattern6 | | -| variables.rs:189:21:203:1 | BlockExpr | variables.rs:189:1:203:1 | exit match_pattern6 (normal) | | -| variables.rs:190:5:190:37 | LetStmt | variables.rs:190:14:190:32 | PathExpr | | -| variables.rs:190:9:190:10 | tv | variables.rs:191:5:194:5 | ExprStmt | match, no-match | -| variables.rs:190:14:190:32 | PathExpr | variables.rs:190:34:190:35 | 62 | | -| variables.rs:190:14:190:36 | CallExpr | variables.rs:190:9:190:10 | tv | | -| variables.rs:190:34:190:35 | 62 | variables.rs:190:14:190:36 | CallExpr | | -| variables.rs:191:5:194:5 | ExprStmt | variables.rs:191:11:191:12 | tv | | -| variables.rs:191:5:194:5 | MatchExpr | variables.rs:195:5:198:5 | ExprStmt | | -| variables.rs:191:11:191:12 | tv | variables.rs:192:9:192:81 | OrPat | | -| variables.rs:192:9:192:81 | OrPat | variables.rs:193:16:193:24 | PathExpr | match | -| variables.rs:193:16:193:24 | PathExpr | variables.rs:193:26:193:27 | a4 | | -| variables.rs:193:16:193:28 | CallExpr | variables.rs:191:5:194:5 | MatchExpr | | -| variables.rs:193:26:193:27 | a4 | variables.rs:193:16:193:28 | CallExpr | | -| variables.rs:195:5:198:5 | ExprStmt | variables.rs:195:11:195:12 | tv | | -| variables.rs:195:5:198:5 | MatchExpr | variables.rs:199:11:199:12 | tv | | -| variables.rs:195:11:195:12 | tv | variables.rs:196:9:196:83 | OrPat | | -| variables.rs:196:9:196:83 | OrPat | variables.rs:197:16:197:24 | PathExpr | match | -| variables.rs:197:16:197:24 | PathExpr | variables.rs:197:26:197:27 | a5 | | -| variables.rs:197:16:197:28 | CallExpr | variables.rs:195:5:198:5 | MatchExpr | | -| variables.rs:197:26:197:27 | a5 | variables.rs:197:16:197:28 | CallExpr | | -| variables.rs:199:5:202:5 | MatchExpr | variables.rs:189:21:203:1 | BlockExpr | | -| variables.rs:199:11:199:12 | tv | variables.rs:200:9:200:83 | OrPat | | -| variables.rs:200:9:200:83 | OrPat | variables.rs:201:16:201:24 | PathExpr | match | -| variables.rs:201:16:201:24 | PathExpr | variables.rs:201:26:201:27 | a6 | | -| variables.rs:201:16:201:28 | CallExpr | variables.rs:199:5:202:5 | MatchExpr | | -| variables.rs:201:26:201:27 | a6 | variables.rs:201:16:201:28 | CallExpr | | -| variables.rs:205:1:213:1 | enter match_pattern7 | variables.rs:206:5:206:34 | LetStmt | | -| variables.rs:205:1:213:1 | exit match_pattern7 (normal) | variables.rs:205:1:213:1 | exit match_pattern7 | | -| variables.rs:205:21:213:1 | BlockExpr | variables.rs:205:1:213:1 | exit match_pattern7 (normal) | | -| variables.rs:206:5:206:34 | LetStmt | variables.rs:206:18:206:29 | PathExpr | | -| variables.rs:206:9:206:14 | either | variables.rs:207:11:207:16 | either | match, no-match | -| variables.rs:206:18:206:29 | PathExpr | variables.rs:206:31:206:32 | 32 | | -| variables.rs:206:18:206:33 | CallExpr | variables.rs:206:9:206:14 | either | | -| variables.rs:206:31:206:32 | 32 | variables.rs:206:18:206:33 | CallExpr | | -| variables.rs:207:5:212:5 | MatchExpr | variables.rs:205:21:213:1 | BlockExpr | | -| variables.rs:207:11:207:16 | either | variables.rs:208:9:208:44 | OrPat | | -| variables.rs:208:9:208:44 | OrPat | variables.rs:209:16:209:17 | a7 | match | -| variables.rs:208:9:208:44 | OrPat | variables.rs:211:9:211:9 | WildcardPat | no-match | -| variables.rs:209:16:209:17 | a7 | variables.rs:209:21:209:21 | 0 | | -| variables.rs:209:16:209:21 | ... > ... | variables.rs:210:16:210:24 | PathExpr | true | -| variables.rs:209:16:209:21 | ... > ... | variables.rs:211:9:211:9 | WildcardPat | false | -| variables.rs:209:21:209:21 | 0 | variables.rs:209:16:209:21 | ... > ... | | -| variables.rs:210:16:210:24 | PathExpr | variables.rs:210:26:210:27 | a7 | | -| variables.rs:210:16:210:28 | CallExpr | variables.rs:207:5:212:5 | MatchExpr | | -| variables.rs:210:26:210:27 | a7 | variables.rs:210:16:210:28 | CallExpr | | -| variables.rs:211:9:211:9 | WildcardPat | variables.rs:211:14:211:15 | TupleExpr | match | -| variables.rs:211:14:211:15 | TupleExpr | variables.rs:207:5:212:5 | MatchExpr | | -| variables.rs:215:1:230:1 | enter match_pattern8 | variables.rs:216:5:216:34 | LetStmt | | -| variables.rs:215:1:230:1 | exit match_pattern8 (normal) | variables.rs:215:1:230:1 | exit match_pattern8 | | -| variables.rs:215:21:230:1 | BlockExpr | variables.rs:215:1:230:1 | exit match_pattern8 (normal) | | -| variables.rs:216:5:216:34 | LetStmt | variables.rs:216:18:216:29 | PathExpr | | -| variables.rs:216:9:216:14 | either | variables.rs:218:11:218:16 | either | match, no-match | -| variables.rs:216:18:216:29 | PathExpr | variables.rs:216:31:216:32 | 32 | | -| variables.rs:216:18:216:33 | CallExpr | variables.rs:216:9:216:14 | either | | -| variables.rs:216:31:216:32 | 32 | variables.rs:216:18:216:33 | CallExpr | | -| variables.rs:218:5:229:5 | MatchExpr | variables.rs:215:21:230:1 | BlockExpr | | -| variables.rs:218:11:218:16 | either | variables.rs:219:9:220:52 | e | | -| variables.rs:219:9:220:52 | e | variables.rs:222:13:222:27 | ExprStmt | match | -| variables.rs:219:9:220:52 | e | variables.rs:228:9:228:9 | WildcardPat | no-match | -| variables.rs:221:12:227:9 | BlockExpr | variables.rs:218:5:229:5 | MatchExpr | | -| variables.rs:222:13:222:21 | PathExpr | variables.rs:222:23:222:25 | a11 | | -| variables.rs:222:13:222:26 | CallExpr | variables.rs:223:16:224:15 | LetExpr | | -| variables.rs:222:13:222:27 | ExprStmt | variables.rs:222:13:222:21 | PathExpr | | -| variables.rs:222:23:222:25 | a11 | variables.rs:222:13:222:26 | CallExpr | | -| variables.rs:223:13:226:13 | IfExpr | variables.rs:221:12:227:9 | BlockExpr | | -| variables.rs:223:16:224:15 | LetExpr | variables.rs:223:20:223:36 | TupleStructPat | | -| variables.rs:223:20:223:36 | TupleStructPat | variables.rs:223:13:226:13 | IfExpr | no-match | -| variables.rs:223:20:223:36 | TupleStructPat | variables.rs:225:17:225:32 | ExprStmt | match | -| variables.rs:224:17:226:13 | BlockExpr | variables.rs:223:13:226:13 | IfExpr | | -| variables.rs:225:17:225:25 | PathExpr | variables.rs:225:28:225:30 | a12 | | -| variables.rs:225:17:225:31 | CallExpr | variables.rs:224:17:226:13 | BlockExpr | | -| variables.rs:225:17:225:32 | ExprStmt | variables.rs:225:17:225:25 | PathExpr | | -| variables.rs:225:27:225:30 | * ... | variables.rs:225:17:225:31 | CallExpr | | -| variables.rs:225:28:225:30 | a12 | variables.rs:225:27:225:30 | * ... | | -| variables.rs:228:9:228:9 | WildcardPat | variables.rs:228:14:228:15 | TupleExpr | match | -| variables.rs:228:14:228:15 | TupleExpr | variables.rs:218:5:229:5 | MatchExpr | | -| variables.rs:239:1:245:1 | enter match_pattern9 | variables.rs:240:5:240:36 | LetStmt | | -| variables.rs:239:1:245:1 | exit match_pattern9 (normal) | variables.rs:239:1:245:1 | exit match_pattern9 | | -| variables.rs:239:21:245:1 | BlockExpr | variables.rs:239:1:245:1 | exit match_pattern9 (normal) | | -| variables.rs:240:5:240:36 | LetStmt | variables.rs:240:14:240:31 | PathExpr | | -| variables.rs:240:9:240:10 | fv | variables.rs:241:11:241:12 | fv | match, no-match | -| variables.rs:240:14:240:31 | PathExpr | variables.rs:240:33:240:34 | 62 | | -| variables.rs:240:14:240:35 | CallExpr | variables.rs:240:9:240:10 | fv | | -| variables.rs:240:33:240:34 | 62 | variables.rs:240:14:240:35 | CallExpr | | -| variables.rs:241:5:244:5 | MatchExpr | variables.rs:239:21:245:1 | BlockExpr | | -| variables.rs:241:11:241:12 | fv | variables.rs:242:9:242:109 | OrPat | | -| variables.rs:242:9:242:109 | OrPat | variables.rs:243:16:243:24 | PathExpr | match | -| variables.rs:243:16:243:24 | PathExpr | variables.rs:243:26:243:28 | a13 | | -| variables.rs:243:16:243:29 | CallExpr | variables.rs:241:5:244:5 | MatchExpr | | -| variables.rs:243:26:243:28 | a13 | variables.rs:243:16:243:29 | CallExpr | | -| variables.rs:247:1:256:1 | enter param_pattern1 | variables.rs:253:5:253:18 | ExprStmt | | -| variables.rs:247:1:256:1 | exit param_pattern1 (normal) | variables.rs:247:1:256:1 | exit param_pattern1 | | -| variables.rs:252:28:256:1 | BlockExpr | variables.rs:247:1:256:1 | exit param_pattern1 (normal) | | -| variables.rs:253:5:253:13 | PathExpr | variables.rs:253:15:253:16 | a8 | | -| variables.rs:253:5:253:17 | CallExpr | variables.rs:254:5:254:18 | ExprStmt | | -| variables.rs:253:5:253:18 | ExprStmt | variables.rs:253:5:253:13 | PathExpr | | -| variables.rs:253:15:253:16 | a8 | variables.rs:253:5:253:17 | CallExpr | | -| variables.rs:254:5:254:13 | PathExpr | variables.rs:254:15:254:16 | b3 | | -| variables.rs:254:5:254:17 | CallExpr | variables.rs:255:5:255:18 | ExprStmt | | -| variables.rs:254:5:254:18 | ExprStmt | variables.rs:254:5:254:13 | PathExpr | | -| variables.rs:254:15:254:16 | b3 | variables.rs:254:5:254:17 | CallExpr | | -| variables.rs:255:5:255:13 | PathExpr | variables.rs:255:15:255:16 | c1 | | -| variables.rs:255:5:255:17 | CallExpr | variables.rs:252:28:256:1 | BlockExpr | | +| variables.rs:125:23:125:27 | first | variables.rs:125:13:125:28 | CallExpr | | +| variables.rs:126:13:126:21 | PathExpr | variables.rs:126:23:126:27 | third | | +| variables.rs:126:13:126:28 | CallExpr | variables.rs:127:13:127:29 | ExprStmt | | +| variables.rs:126:13:126:29 | ExprStmt | variables.rs:126:13:126:21 | PathExpr | | +| variables.rs:126:23:126:27 | third | variables.rs:126:13:126:28 | CallExpr | | +| variables.rs:127:13:127:21 | PathExpr | variables.rs:127:23:127:27 | fifth | | +| variables.rs:127:13:127:28 | CallExpr | variables.rs:124:14:128:9 | BlockExpr | | +| variables.rs:127:13:127:29 | ExprStmt | variables.rs:127:13:127:21 | PathExpr | | +| variables.rs:127:23:127:27 | fifth | variables.rs:127:13:127:28 | CallExpr | | +| variables.rs:131:5:140:5 | MatchExpr | variables.rs:116:21:141:1 | BlockExpr | | +| variables.rs:131:11:131:17 | numbers | variables.rs:132:9:136:9 | TuplePat | | +| variables.rs:132:9:136:9 | TuplePat | variables.rs:137:13:137:29 | ExprStmt | match | +| variables.rs:136:14:139:9 | BlockExpr | variables.rs:131:5:140:5 | MatchExpr | | +| variables.rs:137:13:137:21 | PathExpr | variables.rs:137:23:137:27 | first | | +| variables.rs:137:13:137:28 | CallExpr | variables.rs:138:13:138:28 | ExprStmt | | +| variables.rs:137:13:137:29 | ExprStmt | variables.rs:137:13:137:21 | PathExpr | | +| variables.rs:137:23:137:27 | first | variables.rs:137:13:137:28 | CallExpr | | +| variables.rs:138:13:138:21 | PathExpr | variables.rs:138:23:138:26 | last | | +| variables.rs:138:13:138:27 | CallExpr | variables.rs:136:14:139:9 | BlockExpr | | +| variables.rs:138:13:138:28 | ExprStmt | variables.rs:138:13:138:21 | PathExpr | | +| variables.rs:138:23:138:26 | last | variables.rs:138:13:138:27 | CallExpr | | +| variables.rs:143:1:151:1 | enter match_pattern3 | variables.rs:144:5:144:38 | LetStmt | | +| variables.rs:143:1:151:1 | exit match_pattern3 (normal) | variables.rs:143:1:151:1 | exit match_pattern3 | | +| variables.rs:143:21:151:1 | BlockExpr | variables.rs:143:1:151:1 | exit match_pattern3 (normal) | | +| variables.rs:144:5:144:38 | LetStmt | variables.rs:144:25:144:27 | "x" | | +| variables.rs:144:9:144:10 | p2 | variables.rs:146:11:146:12 | p2 | match, no-match | +| variables.rs:144:14:144:37 | RecordExpr | variables.rs:144:9:144:10 | p2 | | +| variables.rs:144:25:144:27 | "x" | variables.rs:144:33:144:35 | "y" | | +| variables.rs:144:33:144:35 | "y" | variables.rs:144:14:144:37 | RecordExpr | | +| variables.rs:146:5:150:5 | MatchExpr | variables.rs:143:21:151:1 | BlockExpr | | +| variables.rs:146:11:146:12 | p2 | variables.rs:147:9:149:9 | RecordPat | | +| variables.rs:147:9:149:9 | RecordPat | variables.rs:149:14:149:22 | PathExpr | match | +| variables.rs:149:14:149:22 | PathExpr | variables.rs:149:24:149:25 | x7 | | +| variables.rs:149:14:149:26 | CallExpr | variables.rs:146:5:150:5 | MatchExpr | | +| variables.rs:149:24:149:25 | x7 | variables.rs:149:14:149:26 | CallExpr | | +| variables.rs:157:1:170:1 | enter match_pattern4 | variables.rs:158:5:158:39 | LetStmt | | +| variables.rs:157:1:170:1 | exit match_pattern4 (normal) | variables.rs:157:1:170:1 | exit match_pattern4 | | +| variables.rs:157:21:170:1 | BlockExpr | variables.rs:157:1:170:1 | exit match_pattern4 (normal) | | +| variables.rs:158:5:158:39 | LetStmt | variables.rs:158:36:158:36 | 0 | | +| variables.rs:158:9:158:11 | msg | variables.rs:160:11:160:13 | msg | match, no-match | +| variables.rs:158:15:158:38 | RecordExpr | variables.rs:158:9:158:11 | msg | | +| variables.rs:158:36:158:36 | 0 | variables.rs:158:15:158:38 | RecordExpr | | +| variables.rs:160:5:169:5 | MatchExpr | variables.rs:157:21:170:1 | BlockExpr | | +| variables.rs:160:11:160:13 | msg | variables.rs:161:9:163:9 | RecordPat | | +| variables.rs:161:9:163:9 | RecordPat | variables.rs:163:14:163:22 | PathExpr | match | +| variables.rs:161:9:163:9 | RecordPat | variables.rs:164:9:164:38 | RecordPat | no-match | +| variables.rs:163:14:163:22 | PathExpr | variables.rs:163:24:163:34 | id_variable | | +| variables.rs:163:14:163:35 | CallExpr | variables.rs:160:5:169:5 | MatchExpr | | +| variables.rs:163:24:163:34 | id_variable | variables.rs:163:14:163:35 | CallExpr | | +| variables.rs:164:9:164:38 | RecordPat | variables.rs:165:13:165:52 | MacroExpr | match | +| variables.rs:164:9:164:38 | RecordPat | variables.rs:167:9:167:29 | RecordPat | no-match | +| variables.rs:164:43:166:9 | BlockExpr | variables.rs:160:5:169:5 | MatchExpr | | +| variables.rs:165:13:165:52 | MacroExpr | variables.rs:164:43:166:9 | BlockExpr | | +| variables.rs:167:9:167:29 | RecordPat | variables.rs:168:13:168:21 | PathExpr | match | +| variables.rs:168:13:168:21 | PathExpr | variables.rs:168:23:168:24 | id | | +| variables.rs:168:13:168:25 | CallExpr | variables.rs:160:5:169:5 | MatchExpr | | +| variables.rs:168:23:168:24 | id | variables.rs:168:13:168:25 | CallExpr | | +| variables.rs:177:1:183:1 | enter match_pattern5 | variables.rs:178:5:178:34 | LetStmt | | +| variables.rs:177:1:183:1 | exit match_pattern5 (normal) | variables.rs:177:1:183:1 | exit match_pattern5 | | +| variables.rs:177:21:183:1 | BlockExpr | variables.rs:177:1:183:1 | exit match_pattern5 (normal) | | +| variables.rs:178:5:178:34 | LetStmt | variables.rs:178:18:178:29 | PathExpr | | +| variables.rs:178:9:178:14 | either | variables.rs:179:11:179:16 | either | match, no-match | +| variables.rs:178:18:178:29 | PathExpr | variables.rs:178:31:178:32 | 32 | | +| variables.rs:178:18:178:33 | CallExpr | variables.rs:178:9:178:14 | either | | +| variables.rs:178:31:178:32 | 32 | variables.rs:178:18:178:33 | CallExpr | | +| variables.rs:179:5:182:5 | MatchExpr | variables.rs:177:21:183:1 | BlockExpr | | +| variables.rs:179:11:179:16 | either | variables.rs:180:9:180:44 | OrPat | | +| variables.rs:180:9:180:44 | OrPat | variables.rs:181:16:181:24 | PathExpr | match | +| variables.rs:181:16:181:24 | PathExpr | variables.rs:181:26:181:27 | a3 | | +| variables.rs:181:16:181:28 | CallExpr | variables.rs:179:5:182:5 | MatchExpr | | +| variables.rs:181:26:181:27 | a3 | variables.rs:181:16:181:28 | CallExpr | | +| variables.rs:191:1:205:1 | enter match_pattern6 | variables.rs:192:5:192:37 | LetStmt | | +| variables.rs:191:1:205:1 | exit match_pattern6 (normal) | variables.rs:191:1:205:1 | exit match_pattern6 | | +| variables.rs:191:21:205:1 | BlockExpr | variables.rs:191:1:205:1 | exit match_pattern6 (normal) | | +| variables.rs:192:5:192:37 | LetStmt | variables.rs:192:14:192:32 | PathExpr | | +| variables.rs:192:9:192:10 | tv | variables.rs:193:5:196:5 | ExprStmt | match, no-match | +| variables.rs:192:14:192:32 | PathExpr | variables.rs:192:34:192:35 | 62 | | +| variables.rs:192:14:192:36 | CallExpr | variables.rs:192:9:192:10 | tv | | +| variables.rs:192:34:192:35 | 62 | variables.rs:192:14:192:36 | CallExpr | | +| variables.rs:193:5:196:5 | ExprStmt | variables.rs:193:11:193:12 | tv | | +| variables.rs:193:5:196:5 | MatchExpr | variables.rs:197:5:200:5 | ExprStmt | | +| variables.rs:193:11:193:12 | tv | variables.rs:194:9:194:81 | OrPat | | +| variables.rs:194:9:194:81 | OrPat | variables.rs:195:16:195:24 | PathExpr | match | +| variables.rs:195:16:195:24 | PathExpr | variables.rs:195:26:195:27 | a4 | | +| variables.rs:195:16:195:28 | CallExpr | variables.rs:193:5:196:5 | MatchExpr | | +| variables.rs:195:26:195:27 | a4 | variables.rs:195:16:195:28 | CallExpr | | +| variables.rs:197:5:200:5 | ExprStmt | variables.rs:197:11:197:12 | tv | | +| variables.rs:197:5:200:5 | MatchExpr | variables.rs:201:11:201:12 | tv | | +| variables.rs:197:11:197:12 | tv | variables.rs:198:9:198:83 | OrPat | | +| variables.rs:198:9:198:83 | OrPat | variables.rs:199:16:199:24 | PathExpr | match | +| variables.rs:199:16:199:24 | PathExpr | variables.rs:199:26:199:27 | a5 | | +| variables.rs:199:16:199:28 | CallExpr | variables.rs:197:5:200:5 | MatchExpr | | +| variables.rs:199:26:199:27 | a5 | variables.rs:199:16:199:28 | CallExpr | | +| variables.rs:201:5:204:5 | MatchExpr | variables.rs:191:21:205:1 | BlockExpr | | +| variables.rs:201:11:201:12 | tv | variables.rs:202:9:202:83 | OrPat | | +| variables.rs:202:9:202:83 | OrPat | variables.rs:203:16:203:24 | PathExpr | match | +| variables.rs:203:16:203:24 | PathExpr | variables.rs:203:26:203:27 | a6 | | +| variables.rs:203:16:203:28 | CallExpr | variables.rs:201:5:204:5 | MatchExpr | | +| variables.rs:203:26:203:27 | a6 | variables.rs:203:16:203:28 | CallExpr | | +| variables.rs:207:1:215:1 | enter match_pattern7 | variables.rs:208:5:208:34 | LetStmt | | +| variables.rs:207:1:215:1 | exit match_pattern7 (normal) | variables.rs:207:1:215:1 | exit match_pattern7 | | +| variables.rs:207:21:215:1 | BlockExpr | variables.rs:207:1:215:1 | exit match_pattern7 (normal) | | +| variables.rs:208:5:208:34 | LetStmt | variables.rs:208:18:208:29 | PathExpr | | +| variables.rs:208:9:208:14 | either | variables.rs:209:11:209:16 | either | match, no-match | +| variables.rs:208:18:208:29 | PathExpr | variables.rs:208:31:208:32 | 32 | | +| variables.rs:208:18:208:33 | CallExpr | variables.rs:208:9:208:14 | either | | +| variables.rs:208:31:208:32 | 32 | variables.rs:208:18:208:33 | CallExpr | | +| variables.rs:209:5:214:5 | MatchExpr | variables.rs:207:21:215:1 | BlockExpr | | +| variables.rs:209:11:209:16 | either | variables.rs:210:9:210:44 | OrPat | | +| variables.rs:210:9:210:44 | OrPat | variables.rs:211:16:211:17 | a7 | match | +| variables.rs:210:9:210:44 | OrPat | variables.rs:213:9:213:9 | WildcardPat | no-match | +| variables.rs:211:16:211:17 | a7 | variables.rs:211:21:211:21 | 0 | | +| variables.rs:211:16:211:21 | ... > ... | variables.rs:212:16:212:24 | PathExpr | true | +| variables.rs:211:16:211:21 | ... > ... | variables.rs:213:9:213:9 | WildcardPat | false | +| variables.rs:211:21:211:21 | 0 | variables.rs:211:16:211:21 | ... > ... | | +| variables.rs:212:16:212:24 | PathExpr | variables.rs:212:26:212:27 | a7 | | +| variables.rs:212:16:212:28 | CallExpr | variables.rs:209:5:214:5 | MatchExpr | | +| variables.rs:212:26:212:27 | a7 | variables.rs:212:16:212:28 | CallExpr | | +| variables.rs:213:9:213:9 | WildcardPat | variables.rs:213:14:213:15 | TupleExpr | match | +| variables.rs:213:14:213:15 | TupleExpr | variables.rs:209:5:214:5 | MatchExpr | | +| variables.rs:217:1:232:1 | enter match_pattern8 | variables.rs:218:5:218:34 | LetStmt | | +| variables.rs:217:1:232:1 | exit match_pattern8 (normal) | variables.rs:217:1:232:1 | exit match_pattern8 | | +| variables.rs:217:21:232:1 | BlockExpr | variables.rs:217:1:232:1 | exit match_pattern8 (normal) | | +| variables.rs:218:5:218:34 | LetStmt | variables.rs:218:18:218:29 | PathExpr | | +| variables.rs:218:9:218:14 | either | variables.rs:220:11:220:16 | either | match, no-match | +| variables.rs:218:18:218:29 | PathExpr | variables.rs:218:31:218:32 | 32 | | +| variables.rs:218:18:218:33 | CallExpr | variables.rs:218:9:218:14 | either | | +| variables.rs:218:31:218:32 | 32 | variables.rs:218:18:218:33 | CallExpr | | +| variables.rs:220:5:231:5 | MatchExpr | variables.rs:217:21:232:1 | BlockExpr | | +| variables.rs:220:11:220:16 | either | variables.rs:221:9:222:52 | e | | +| variables.rs:221:9:222:52 | e | variables.rs:224:13:224:27 | ExprStmt | match | +| variables.rs:221:9:222:52 | e | variables.rs:230:9:230:9 | WildcardPat | no-match | +| variables.rs:223:12:229:9 | BlockExpr | variables.rs:220:5:231:5 | MatchExpr | | +| variables.rs:224:13:224:21 | PathExpr | variables.rs:224:23:224:25 | a11 | | +| variables.rs:224:13:224:26 | CallExpr | variables.rs:225:16:226:15 | LetExpr | | +| variables.rs:224:13:224:27 | ExprStmt | variables.rs:224:13:224:21 | PathExpr | | +| variables.rs:224:23:224:25 | a11 | variables.rs:224:13:224:26 | CallExpr | | +| variables.rs:225:13:228:13 | IfExpr | variables.rs:223:12:229:9 | BlockExpr | | +| variables.rs:225:16:226:15 | LetExpr | variables.rs:225:20:225:36 | TupleStructPat | | +| variables.rs:225:20:225:36 | TupleStructPat | variables.rs:225:13:228:13 | IfExpr | no-match | +| variables.rs:225:20:225:36 | TupleStructPat | variables.rs:227:17:227:32 | ExprStmt | match | +| variables.rs:226:17:228:13 | BlockExpr | variables.rs:225:13:228:13 | IfExpr | | +| variables.rs:227:17:227:25 | PathExpr | variables.rs:227:28:227:30 | a12 | | +| variables.rs:227:17:227:31 | CallExpr | variables.rs:226:17:228:13 | BlockExpr | | +| variables.rs:227:17:227:32 | ExprStmt | variables.rs:227:17:227:25 | PathExpr | | +| variables.rs:227:27:227:30 | * ... | variables.rs:227:17:227:31 | CallExpr | | +| variables.rs:227:28:227:30 | a12 | variables.rs:227:27:227:30 | * ... | | +| variables.rs:230:9:230:9 | WildcardPat | variables.rs:230:14:230:15 | TupleExpr | match | +| variables.rs:230:14:230:15 | TupleExpr | variables.rs:220:5:231:5 | MatchExpr | | +| variables.rs:241:1:247:1 | enter match_pattern9 | variables.rs:242:5:242:36 | LetStmt | | +| variables.rs:241:1:247:1 | exit match_pattern9 (normal) | variables.rs:241:1:247:1 | exit match_pattern9 | | +| variables.rs:241:21:247:1 | BlockExpr | variables.rs:241:1:247:1 | exit match_pattern9 (normal) | | +| variables.rs:242:5:242:36 | LetStmt | variables.rs:242:14:242:31 | PathExpr | | +| variables.rs:242:9:242:10 | fv | variables.rs:243:11:243:12 | fv | match, no-match | +| variables.rs:242:14:242:31 | PathExpr | variables.rs:242:33:242:34 | 62 | | +| variables.rs:242:14:242:35 | CallExpr | variables.rs:242:9:242:10 | fv | | +| variables.rs:242:33:242:34 | 62 | variables.rs:242:14:242:35 | CallExpr | | +| variables.rs:243:5:246:5 | MatchExpr | variables.rs:241:21:247:1 | BlockExpr | | +| variables.rs:243:11:243:12 | fv | variables.rs:244:9:244:109 | OrPat | | +| variables.rs:244:9:244:109 | OrPat | variables.rs:245:16:245:24 | PathExpr | match | +| variables.rs:245:16:245:24 | PathExpr | variables.rs:245:26:245:28 | a13 | | +| variables.rs:245:16:245:29 | CallExpr | variables.rs:243:5:246:5 | MatchExpr | | +| variables.rs:245:26:245:28 | a13 | variables.rs:245:16:245:29 | CallExpr | | +| variables.rs:249:1:258:1 | enter param_pattern1 | variables.rs:255:5:255:18 | ExprStmt | | +| variables.rs:249:1:258:1 | exit param_pattern1 (normal) | variables.rs:249:1:258:1 | exit param_pattern1 | | +| variables.rs:254:28:258:1 | BlockExpr | variables.rs:249:1:258:1 | exit param_pattern1 (normal) | | +| variables.rs:255:5:255:13 | PathExpr | variables.rs:255:15:255:16 | a8 | | +| variables.rs:255:5:255:17 | CallExpr | variables.rs:256:5:256:18 | ExprStmt | | | variables.rs:255:5:255:18 | ExprStmt | variables.rs:255:5:255:13 | PathExpr | | -| variables.rs:255:15:255:16 | c1 | variables.rs:255:5:255:17 | CallExpr | | -| variables.rs:258:1:262:1 | enter param_pattern2 | variables.rs:261:5:261:18 | ExprStmt | | -| variables.rs:258:1:262:1 | exit param_pattern2 (normal) | variables.rs:258:1:262:1 | exit param_pattern2 | | -| variables.rs:260:9:262:1 | BlockExpr | variables.rs:258:1:262:1 | exit param_pattern2 (normal) | | -| variables.rs:261:5:261:13 | PathExpr | variables.rs:261:15:261:16 | a9 | | -| variables.rs:261:5:261:17 | CallExpr | variables.rs:260:9:262:1 | BlockExpr | | -| variables.rs:261:5:261:18 | ExprStmt | variables.rs:261:5:261:13 | PathExpr | | -| variables.rs:261:15:261:16 | a9 | variables.rs:261:5:261:17 | CallExpr | | -| variables.rs:264:1:299:1 | enter destruct_assignment | variables.rs:265:5:269:18 | LetStmt | | -| variables.rs:264:1:299:1 | exit destruct_assignment (normal) | variables.rs:264:1:299:1 | exit destruct_assignment | | -| variables.rs:264:26:299:1 | BlockExpr | variables.rs:264:1:299:1 | exit destruct_assignment (normal) | | -| variables.rs:265:5:269:18 | LetStmt | variables.rs:269:10:269:10 | 1 | | -| variables.rs:265:9:269:5 | TuplePat | variables.rs:270:5:270:19 | ExprStmt | match | -| variables.rs:269:9:269:17 | TupleExpr | variables.rs:265:9:269:5 | TuplePat | | -| variables.rs:269:10:269:10 | 1 | variables.rs:269:13:269:13 | 2 | | -| variables.rs:269:13:269:13 | 2 | variables.rs:269:16:269:16 | 3 | | -| variables.rs:269:16:269:16 | 3 | variables.rs:269:9:269:17 | TupleExpr | | -| variables.rs:270:5:270:13 | PathExpr | variables.rs:270:15:270:17 | a10 | | -| variables.rs:270:5:270:18 | CallExpr | variables.rs:271:5:271:18 | ExprStmt | | -| variables.rs:270:5:270:19 | ExprStmt | variables.rs:270:5:270:13 | PathExpr | | -| variables.rs:270:15:270:17 | a10 | variables.rs:270:5:270:18 | CallExpr | | -| variables.rs:271:5:271:13 | PathExpr | variables.rs:271:15:271:16 | b4 | | -| variables.rs:271:5:271:17 | CallExpr | variables.rs:272:5:272:18 | ExprStmt | | -| variables.rs:271:5:271:18 | ExprStmt | variables.rs:271:5:271:13 | PathExpr | | -| variables.rs:271:15:271:16 | b4 | variables.rs:271:5:271:17 | CallExpr | | -| variables.rs:272:5:272:13 | PathExpr | variables.rs:272:15:272:16 | c2 | | -| variables.rs:272:5:272:17 | CallExpr | variables.rs:274:5:282:6 | ExprStmt | | -| variables.rs:272:5:272:18 | ExprStmt | variables.rs:272:5:272:13 | PathExpr | | -| variables.rs:272:15:272:16 | c2 | variables.rs:272:5:272:17 | CallExpr | | -| variables.rs:274:5:278:5 | TupleExpr | variables.rs:279:9:279:11 | a10 | | -| variables.rs:274:5:282:5 | ... = ... | variables.rs:283:5:283:19 | ExprStmt | | -| variables.rs:274:5:282:6 | ExprStmt | variables.rs:275:9:275:10 | c2 | | -| variables.rs:275:9:275:10 | c2 | variables.rs:276:9:276:10 | b4 | | -| variables.rs:276:9:276:10 | b4 | variables.rs:277:9:277:11 | a10 | | -| variables.rs:277:9:277:11 | a10 | variables.rs:274:5:278:5 | TupleExpr | | -| variables.rs:278:9:282:5 | TupleExpr | variables.rs:274:5:282:5 | ... = ... | | -| variables.rs:279:9:279:11 | a10 | variables.rs:280:9:280:10 | b4 | | -| variables.rs:280:9:280:10 | b4 | variables.rs:281:9:281:10 | c2 | | -| variables.rs:281:9:281:10 | c2 | variables.rs:278:9:282:5 | TupleExpr | | -| variables.rs:283:5:283:13 | PathExpr | 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:19 | ExprStmt | variables.rs:283:5:283:13 | PathExpr | | -| variables.rs:283:15:283:17 | a10 | variables.rs:283:5:283:18 | CallExpr | | -| variables.rs:284:5:284:13 | PathExpr | 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:18 | ExprStmt | variables.rs:284:5:284:13 | PathExpr | | -| variables.rs:284:15:284:16 | b4 | variables.rs:284:5:284:17 | CallExpr | | -| variables.rs:285:5:285:13 | PathExpr | variables.rs:285:15:285:16 | c2 | | -| variables.rs:285:5:285:17 | CallExpr | variables.rs:287:5:295:5 | ExprStmt | | -| variables.rs:285:5:285:18 | ExprStmt | variables.rs:285:5:285:13 | PathExpr | | -| variables.rs:285:15:285:16 | c2 | variables.rs:285:5:285:17 | CallExpr | | -| variables.rs:287:5:295:5 | ExprStmt | variables.rs:287:12:287:12 | 4 | | -| variables.rs:287:5:295:5 | MatchExpr | variables.rs:297:5:297:19 | ExprStmt | | -| variables.rs:287:11:287:16 | TupleExpr | variables.rs:288:9:291:9 | TuplePat | | -| variables.rs:287:12:287:12 | 4 | variables.rs:287:15:287:15 | 5 | | -| variables.rs:287:15:287:15 | 5 | variables.rs:287:11:287:16 | TupleExpr | | -| variables.rs:288:9:291:9 | TuplePat | variables.rs:292:13:292:27 | ExprStmt | match | -| variables.rs:291:14:294:9 | BlockExpr | variables.rs:287:5:295:5 | MatchExpr | | -| variables.rs:292:13:292:21 | PathExpr | variables.rs:292:23:292:25 | a10 | | -| variables.rs:292:13:292:26 | CallExpr | variables.rs:293:13:293:26 | ExprStmt | | -| variables.rs:292:13:292:27 | ExprStmt | variables.rs:292:13:292:21 | PathExpr | | -| variables.rs:292:23:292:25 | a10 | variables.rs:292:13:292:26 | CallExpr | | -| variables.rs:293:13:293:21 | PathExpr | variables.rs:293:23:293:24 | b4 | | -| variables.rs:293:13:293:25 | CallExpr | variables.rs:291:14:294:9 | BlockExpr | | -| variables.rs:293:13:293:26 | ExprStmt | variables.rs:293:13:293:21 | PathExpr | | -| variables.rs:293:23:293:24 | b4 | variables.rs:293:13:293:25 | CallExpr | | -| variables.rs:297:5:297:13 | PathExpr | variables.rs:297:15:297:17 | a10 | | -| variables.rs:297:5:297:18 | CallExpr | variables.rs:298:5:298:18 | ExprStmt | | -| variables.rs:297:5:297:19 | ExprStmt | variables.rs:297:5:297:13 | PathExpr | | -| variables.rs:297:15:297:17 | a10 | variables.rs:297:5:297:18 | CallExpr | | -| variables.rs:298:5:298:13 | PathExpr | variables.rs:298:15:298:16 | b4 | | -| variables.rs:298:5:298:17 | CallExpr | variables.rs:264:26:299:1 | BlockExpr | | -| variables.rs:298:5:298:18 | ExprStmt | variables.rs:298:5:298:13 | PathExpr | | -| variables.rs:298:15:298:16 | b4 | variables.rs:298:5:298:17 | CallExpr | | -| variables.rs:301:1:316:1 | enter closure_variable | variables.rs:302:5:304:10 | LetStmt | | -| variables.rs:301:1:316:1 | exit closure_variable (normal) | variables.rs:301:1:316:1 | exit closure_variable | | -| variables.rs:301:23:316:1 | BlockExpr | variables.rs:301:1:316:1 | exit closure_variable (normal) | | -| variables.rs:302:5:304:10 | LetStmt | variables.rs:303:9:304:9 | ClosureExpr | | -| variables.rs:302:9:302:23 | example_closure | variables.rs:305:5:306:27 | LetStmt | match, no-match | -| variables.rs:303:9:304:9 | ClosureExpr | variables.rs:302:9:302:23 | example_closure | | -| variables.rs:303:9:304:9 | enter ClosureExpr | variables.rs:304:9:304:9 | x | | -| variables.rs:303:9:304:9 | exit ClosureExpr (normal) | variables.rs:303:9:304:9 | exit ClosureExpr | | -| variables.rs:304:9:304:9 | x | variables.rs:303:9:304:9 | exit ClosureExpr (normal) | | -| variables.rs:305:5:306:27 | LetStmt | variables.rs:306:9:306:23 | example_closure | | -| variables.rs:305:9:305:10 | n1 | variables.rs:307:5:307:18 | ExprStmt | match, no-match | -| variables.rs:306:9:306:23 | example_closure | variables.rs:306:25:306:25 | 5 | | -| variables.rs:306:9:306:26 | CallExpr | variables.rs:305:9:305:10 | n1 | | -| variables.rs:306:25:306:25 | 5 | variables.rs:306:9:306:26 | CallExpr | | -| variables.rs:307:5:307:13 | PathExpr | variables.rs:307:15:307:16 | n1 | | -| variables.rs:307:5:307:17 | CallExpr | variables.rs:309:5:309:25 | ExprStmt | | -| variables.rs:307:5:307:18 | ExprStmt | variables.rs:307:5:307:13 | PathExpr | | -| variables.rs:307:15:307:16 | n1 | variables.rs:307:5:307:17 | CallExpr | | -| variables.rs:309:5:309:22 | PathExpr | variables.rs:309:5:309:24 | CallExpr | | -| variables.rs:309:5:309:24 | CallExpr | variables.rs:310:5:312:10 | LetStmt | | -| variables.rs:309:5:309:25 | ExprStmt | variables.rs:309:5:309:22 | PathExpr | | -| variables.rs:310:5:312:10 | LetStmt | variables.rs:311:9:312:9 | ClosureExpr | | -| variables.rs:310:9:310:26 | immutable_variable | variables.rs:313:5:314:30 | LetStmt | match, no-match | -| variables.rs:311:9:312:9 | ClosureExpr | variables.rs:310:9:310:26 | immutable_variable | | -| variables.rs:311:9:312:9 | enter ClosureExpr | variables.rs:312:9:312:9 | x | | -| variables.rs:311:9:312:9 | exit ClosureExpr (normal) | variables.rs:311:9:312:9 | exit ClosureExpr | | -| variables.rs:312:9:312:9 | x | variables.rs:311:9:312:9 | exit ClosureExpr (normal) | | -| variables.rs:313:5:314:30 | LetStmt | variables.rs:314:9:314:26 | immutable_variable | | -| variables.rs:313:9:313:10 | n2 | variables.rs:315:5:315:18 | ExprStmt | match, no-match | -| variables.rs:314:9:314:26 | immutable_variable | variables.rs:314:28:314:28 | 6 | | -| variables.rs:314:9:314:29 | CallExpr | variables.rs:313:9:313:10 | n2 | | -| variables.rs:314:28:314:28 | 6 | variables.rs:314:9:314:29 | CallExpr | | -| variables.rs:315:5:315:13 | PathExpr | variables.rs:315:15:315:16 | n2 | | -| variables.rs:315:5:315:17 | CallExpr | variables.rs:301:23:316:1 | BlockExpr | | -| variables.rs:315:5:315:18 | ExprStmt | variables.rs:315:5:315:13 | PathExpr | | -| variables.rs:315:15:315:16 | n2 | variables.rs:315:5:315:17 | CallExpr | | -| variables.rs:318:1:325:1 | enter for_variable | variables.rs:319:5:319:42 | LetStmt | | -| variables.rs:318:1:325:1 | exit for_variable (normal) | variables.rs:318:1:325:1 | exit for_variable | | -| variables.rs:318:19:325:1 | BlockExpr | variables.rs:318:1:325:1 | exit for_variable (normal) | | -| variables.rs:319:5:319:42 | LetStmt | variables.rs:319:15:319:22 | "apples" | | -| variables.rs:319:9:319:9 | v | variables.rs:322:12:322:12 | v | match, no-match | -| variables.rs:319:13:319:41 | RefExpr | variables.rs:319:9:319:9 | v | | -| variables.rs:319:14:319:41 | ArrayExpr | variables.rs:319:13:319:41 | RefExpr | | -| variables.rs:319:15:319:22 | "apples" | variables.rs:319:25:319:30 | "cake" | | -| variables.rs:319:25:319:30 | "cake" | variables.rs:319:33:319:40 | "coffee" | | -| variables.rs:319:33:319:40 | "coffee" | variables.rs:319:14:319:41 | ArrayExpr | | -| variables.rs:321:5:324:5 | ForExpr | variables.rs:318:19:325:1 | BlockExpr | | -| variables.rs:321:9:321:12 | text | variables.rs:321:5:324:5 | ForExpr | no-match | -| variables.rs:321:9:321:12 | text | variables.rs:323:9:323:24 | ExprStmt | match | -| variables.rs:322:12:322:12 | v | variables.rs:321:9:321:12 | text | | -| variables.rs:322:14:324:5 | BlockExpr | variables.rs:321:9:321:12 | text | | -| variables.rs:323:9:323:17 | PathExpr | variables.rs:323:19:323:22 | text | | -| variables.rs:323:9:323:23 | CallExpr | variables.rs:322:14:324:5 | BlockExpr | | -| variables.rs:323:9:323:24 | ExprStmt | variables.rs:323:9:323:17 | PathExpr | | -| variables.rs:323:19:323:22 | text | variables.rs:323:9:323:23 | CallExpr | | -| variables.rs:327:1:350:1 | enter main | variables.rs:328:5:328:25 | ExprStmt | | -| variables.rs:327:1:350:1 | exit main (normal) | variables.rs:327:1:350:1 | exit main | | -| variables.rs:327:11:350:1 | BlockExpr | variables.rs:327:1:350:1 | exit main (normal) | | -| variables.rs:328:5:328:22 | PathExpr | variables.rs:328:5:328:24 | CallExpr | | -| variables.rs:328:5:328:24 | CallExpr | variables.rs:329:5:329:23 | ExprStmt | | -| variables.rs:328:5:328:25 | ExprStmt | variables.rs:328:5:328:22 | PathExpr | | -| variables.rs:329:5:329:20 | PathExpr | variables.rs:329:5:329:22 | CallExpr | | -| variables.rs:329:5:329:22 | CallExpr | variables.rs:330:5:330:23 | ExprStmt | | -| variables.rs:329:5:329:23 | ExprStmt | variables.rs:329:5:329:20 | PathExpr | | -| variables.rs:330:5:330:20 | PathExpr | variables.rs:330:5:330:22 | CallExpr | | -| variables.rs:330:5:330:22 | CallExpr | variables.rs:331:5:331:23 | ExprStmt | | -| variables.rs:330:5:330:23 | ExprStmt | variables.rs:330:5:330:20 | PathExpr | | -| variables.rs:331:5:331:20 | PathExpr | variables.rs:331:5:331:22 | CallExpr | | -| variables.rs:331:5:331:22 | CallExpr | variables.rs:332:5:332:19 | ExprStmt | | -| variables.rs:331:5:331:23 | ExprStmt | variables.rs:331:5:331:20 | PathExpr | | -| variables.rs:332:5:332:16 | PathExpr | variables.rs:332:5:332:18 | CallExpr | | -| variables.rs:332:5:332:18 | CallExpr | variables.rs:333:5:333:19 | ExprStmt | | -| variables.rs:332:5:332:19 | ExprStmt | variables.rs:332:5:332:16 | PathExpr | | -| variables.rs:333:5:333:16 | PathExpr | variables.rs:333:5:333:18 | CallExpr | | -| variables.rs:333:5:333:18 | CallExpr | variables.rs:334:5:334:19 | ExprStmt | | -| variables.rs:333:5:333:19 | ExprStmt | variables.rs:333:5:333:16 | PathExpr | | -| variables.rs:334:5:334:16 | PathExpr | variables.rs:334:5:334:18 | CallExpr | | -| variables.rs:334:5:334:18 | CallExpr | variables.rs:335:5:335:19 | ExprStmt | | -| variables.rs:334:5:334:19 | ExprStmt | variables.rs:334:5:334:16 | PathExpr | | -| variables.rs:335:5:335:16 | PathExpr | variables.rs:335:5:335:18 | CallExpr | | -| variables.rs:335:5:335:18 | CallExpr | variables.rs:336:5:336:21 | ExprStmt | | -| variables.rs:335:5:335:19 | ExprStmt | variables.rs:335:5:335:16 | PathExpr | | -| variables.rs:336:5:336:18 | PathExpr | variables.rs:336:5:336:20 | CallExpr | | -| variables.rs:336:5:336:20 | CallExpr | variables.rs:337:5:337:21 | ExprStmt | | -| variables.rs:336:5:336:21 | ExprStmt | variables.rs:336:5:336:18 | PathExpr | | -| variables.rs:337:5:337:18 | PathExpr | variables.rs:337:5:337:20 | CallExpr | | -| variables.rs:337:5:337:20 | CallExpr | variables.rs:338:5:338:21 | ExprStmt | | -| variables.rs:337:5:337:21 | ExprStmt | variables.rs:337:5:337:18 | PathExpr | | -| variables.rs:338:5:338:18 | PathExpr | variables.rs:338:5:338:20 | CallExpr | | -| variables.rs:338:5:338:20 | CallExpr | variables.rs:339:5:339:21 | ExprStmt | | -| variables.rs:338:5:338:21 | ExprStmt | variables.rs:338:5:338:18 | PathExpr | | -| variables.rs:339:5:339:18 | PathExpr | variables.rs:339:5:339:20 | CallExpr | | -| variables.rs:339:5:339:20 | CallExpr | variables.rs:340:5:340:21 | ExprStmt | | -| variables.rs:339:5:339:21 | ExprStmt | variables.rs:339:5:339:18 | PathExpr | | -| variables.rs:340:5:340:18 | PathExpr | variables.rs:340:5:340:20 | CallExpr | | -| variables.rs:340:5:340:20 | CallExpr | variables.rs:341:5:341:21 | ExprStmt | | -| variables.rs:340:5:340:21 | ExprStmt | variables.rs:340:5:340:18 | PathExpr | | -| variables.rs:341:5:341:18 | PathExpr | variables.rs:341:5:341:20 | CallExpr | | -| variables.rs:341:5:341:20 | CallExpr | variables.rs:342:5:342:21 | ExprStmt | | -| variables.rs:341:5:341:21 | ExprStmt | variables.rs:341:5:341:18 | PathExpr | | -| variables.rs:342:5:342:18 | PathExpr | variables.rs:342:5:342:20 | CallExpr | | -| variables.rs:342:5:342:20 | CallExpr | variables.rs:343:5:343:21 | ExprStmt | | -| variables.rs:342:5:342:21 | ExprStmt | variables.rs:342:5:342:18 | PathExpr | | -| variables.rs:343:5:343:18 | PathExpr | variables.rs:343:5:343:20 | CallExpr | | -| variables.rs:343:5:343:20 | CallExpr | variables.rs:344:5:344:21 | ExprStmt | | -| variables.rs:343:5:343:21 | ExprStmt | variables.rs:343:5:343:18 | PathExpr | | -| variables.rs:344:5:344:18 | PathExpr | variables.rs:344:5:344:20 | CallExpr | | -| variables.rs:344:5:344:20 | CallExpr | variables.rs:345:5:345:36 | ExprStmt | | -| variables.rs:344:5:344:21 | ExprStmt | variables.rs:344:5:344:18 | PathExpr | | -| variables.rs:345:5:345:18 | PathExpr | variables.rs:345:20:345:22 | "a" | | -| variables.rs:345:5:345:35 | CallExpr | variables.rs:346:5:346:37 | ExprStmt | | -| variables.rs:345:5:345:36 | ExprStmt | variables.rs:345:5:345:18 | PathExpr | | -| variables.rs:345:20:345:22 | "a" | variables.rs:345:26:345:28 | "b" | | -| variables.rs:345:25:345:34 | TupleExpr | variables.rs:345:5:345:35 | CallExpr | | -| variables.rs:345:26:345:28 | "b" | variables.rs:345:31:345:33 | "c" | | -| variables.rs:345:31:345:33 | "c" | variables.rs:345:25:345:34 | TupleExpr | | -| variables.rs:346:5:346:18 | PathExpr | variables.rs:346:20:346:31 | PathExpr | | -| variables.rs:346:5:346:36 | CallExpr | variables.rs:347:5:347:26 | ExprStmt | | -| variables.rs:346:5:346:37 | ExprStmt | variables.rs:346:5:346:18 | PathExpr | | -| variables.rs:346:20:346:31 | PathExpr | variables.rs:346:33:346:34 | 45 | | -| variables.rs:346:20:346:35 | CallExpr | variables.rs:346:5:346:36 | CallExpr | | -| variables.rs:346:33:346:34 | 45 | variables.rs:346:20:346:35 | CallExpr | | -| variables.rs:347:5:347:23 | PathExpr | variables.rs:347:5:347:25 | CallExpr | | -| variables.rs:347:5:347:25 | CallExpr | variables.rs:348:5:348:23 | ExprStmt | | -| variables.rs:347:5:347:26 | ExprStmt | variables.rs:347:5:347:23 | PathExpr | | -| variables.rs:348:5:348:20 | PathExpr | variables.rs:348:5:348:22 | CallExpr | | -| variables.rs:348:5:348:22 | CallExpr | variables.rs:349:5:349:19 | ExprStmt | | -| variables.rs:348:5:348:23 | ExprStmt | variables.rs:348:5:348:20 | PathExpr | | -| variables.rs:349:5:349:16 | PathExpr | variables.rs:349:5:349:18 | CallExpr | | -| variables.rs:349:5:349:18 | CallExpr | variables.rs:327:11:350:1 | BlockExpr | | -| variables.rs:349:5:349:19 | ExprStmt | variables.rs:349:5:349:16 | PathExpr | | +| variables.rs:255:15:255:16 | a8 | variables.rs:255:5:255:17 | CallExpr | | +| variables.rs:256:5:256:13 | PathExpr | variables.rs:256:15:256:16 | b3 | | +| variables.rs:256:5:256:17 | CallExpr | variables.rs:257:5:257:18 | ExprStmt | | +| variables.rs:256:5:256:18 | ExprStmt | variables.rs:256:5:256:13 | PathExpr | | +| variables.rs:256:15:256:16 | b3 | variables.rs:256:5:256:17 | CallExpr | | +| variables.rs:257:5:257:13 | PathExpr | variables.rs:257:15:257:16 | c1 | | +| variables.rs:257:5:257:17 | CallExpr | variables.rs:254:28:258:1 | BlockExpr | | +| variables.rs:257:5:257:18 | ExprStmt | variables.rs:257:5:257:13 | PathExpr | | +| variables.rs:257:15:257:16 | c1 | variables.rs:257:5:257:17 | CallExpr | | +| variables.rs:260:1:264:1 | enter param_pattern2 | variables.rs:263:5:263:18 | ExprStmt | | +| variables.rs:260:1:264:1 | exit param_pattern2 (normal) | variables.rs:260:1:264:1 | exit param_pattern2 | | +| variables.rs:262:9:264:1 | BlockExpr | variables.rs:260:1:264:1 | exit param_pattern2 (normal) | | +| variables.rs:263:5:263:13 | PathExpr | variables.rs:263:15:263:16 | a9 | | +| variables.rs:263:5:263:17 | CallExpr | variables.rs:262:9:264:1 | BlockExpr | | +| variables.rs:263:5:263:18 | ExprStmt | variables.rs:263:5:263:13 | PathExpr | | +| variables.rs:263:15:263:16 | a9 | variables.rs:263:5:263:17 | CallExpr | | +| variables.rs:266:1:301:1 | enter destruct_assignment | variables.rs:267:5:271:18 | LetStmt | | +| variables.rs:266:1:301:1 | exit destruct_assignment (normal) | variables.rs:266:1:301:1 | exit destruct_assignment | | +| variables.rs:266:26:301:1 | BlockExpr | variables.rs:266:1:301:1 | exit destruct_assignment (normal) | | +| variables.rs:267:5:271:18 | LetStmt | variables.rs:271:10:271:10 | 1 | | +| variables.rs:267:9:271:5 | TuplePat | variables.rs:272:5:272:19 | ExprStmt | match | +| variables.rs:271:9:271:17 | TupleExpr | variables.rs:267:9:271:5 | TuplePat | | +| variables.rs:271:10:271:10 | 1 | variables.rs:271:13:271:13 | 2 | | +| variables.rs:271:13:271:13 | 2 | variables.rs:271:16:271:16 | 3 | | +| variables.rs:271:16:271:16 | 3 | variables.rs:271:9:271:17 | TupleExpr | | +| variables.rs:272:5:272:13 | PathExpr | variables.rs:272:15:272:17 | a10 | | +| variables.rs:272:5:272:18 | CallExpr | variables.rs:273:5:273:18 | ExprStmt | | +| variables.rs:272:5:272:19 | ExprStmt | variables.rs:272:5:272:13 | PathExpr | | +| variables.rs:272:15:272:17 | a10 | variables.rs:272:5:272:18 | CallExpr | | +| variables.rs:273:5:273:13 | PathExpr | variables.rs:273:15:273:16 | b4 | | +| variables.rs:273:5:273:17 | CallExpr | variables.rs:274:5:274:18 | ExprStmt | | +| variables.rs:273:5:273:18 | ExprStmt | variables.rs:273:5:273:13 | PathExpr | | +| variables.rs:273:15:273:16 | b4 | variables.rs:273:5:273:17 | CallExpr | | +| variables.rs:274:5:274:13 | PathExpr | variables.rs:274:15:274:16 | c2 | | +| variables.rs:274:5:274:17 | CallExpr | variables.rs:276:5:284:6 | ExprStmt | | +| variables.rs:274:5:274:18 | ExprStmt | variables.rs:274:5:274:13 | PathExpr | | +| variables.rs:274:15:274:16 | c2 | variables.rs:274:5:274:17 | CallExpr | | +| variables.rs:276:5:280:5 | TupleExpr | variables.rs:281:9:281:11 | a10 | | +| variables.rs:276:5:284:5 | ... = ... | variables.rs:285:5:285:19 | ExprStmt | | +| variables.rs:276:5:284:6 | ExprStmt | variables.rs:277:9:277:10 | c2 | | +| variables.rs:277:9:277:10 | c2 | variables.rs:278:9:278:10 | b4 | | +| variables.rs:278:9:278:10 | b4 | variables.rs:279:9:279:11 | a10 | | +| variables.rs:279:9:279:11 | a10 | variables.rs:276:5:280:5 | TupleExpr | | +| variables.rs:280:9:284:5 | TupleExpr | variables.rs:276:5:284:5 | ... = ... | | +| variables.rs:281:9:281:11 | a10 | variables.rs:282:9:282:10 | b4 | | +| variables.rs:282:9:282:10 | b4 | variables.rs:283:9:283:10 | c2 | | +| variables.rs:283:9:283:10 | c2 | variables.rs:280:9:284:5 | TupleExpr | | +| variables.rs:285:5:285:13 | PathExpr | variables.rs:285:15:285:17 | a10 | | +| variables.rs:285:5:285:18 | CallExpr | variables.rs:286:5:286:18 | ExprStmt | | +| variables.rs:285:5:285:19 | ExprStmt | variables.rs:285:5:285:13 | PathExpr | | +| variables.rs:285:15:285:17 | a10 | variables.rs:285:5:285:18 | CallExpr | | +| variables.rs:286:5:286:13 | PathExpr | variables.rs:286:15:286:16 | b4 | | +| variables.rs:286:5:286:17 | CallExpr | variables.rs:287:5:287:18 | ExprStmt | | +| variables.rs:286:5:286:18 | ExprStmt | variables.rs:286:5:286:13 | PathExpr | | +| variables.rs:286:15:286:16 | b4 | variables.rs:286:5:286:17 | CallExpr | | +| variables.rs:287:5:287:13 | PathExpr | variables.rs:287:15:287:16 | c2 | | +| variables.rs:287:5:287:17 | CallExpr | variables.rs:289:5:297:5 | ExprStmt | | +| variables.rs:287:5:287:18 | ExprStmt | variables.rs:287:5:287:13 | PathExpr | | +| variables.rs:287:15:287:16 | c2 | variables.rs:287:5:287:17 | CallExpr | | +| variables.rs:289:5:297:5 | ExprStmt | variables.rs:289:12:289:12 | 4 | | +| variables.rs:289:5:297:5 | MatchExpr | variables.rs:299:5:299:19 | ExprStmt | | +| variables.rs:289:11:289:16 | TupleExpr | variables.rs:290:9:293:9 | TuplePat | | +| variables.rs:289:12:289:12 | 4 | variables.rs:289:15:289:15 | 5 | | +| variables.rs:289:15:289:15 | 5 | variables.rs:289:11:289:16 | TupleExpr | | +| variables.rs:290:9:293:9 | TuplePat | variables.rs:294:13:294:27 | ExprStmt | match | +| variables.rs:293:14:296:9 | BlockExpr | variables.rs:289:5:297:5 | MatchExpr | | +| variables.rs:294:13:294:21 | PathExpr | variables.rs:294:23:294:25 | a10 | | +| variables.rs:294:13:294:26 | CallExpr | variables.rs:295:13:295:26 | ExprStmt | | +| variables.rs:294:13:294:27 | ExprStmt | variables.rs:294:13:294:21 | PathExpr | | +| variables.rs:294:23:294:25 | a10 | variables.rs:294:13:294:26 | CallExpr | | +| variables.rs:295:13:295:21 | PathExpr | variables.rs:295:23:295:24 | b4 | | +| variables.rs:295:13:295:25 | CallExpr | variables.rs:293:14:296:9 | BlockExpr | | +| variables.rs:295:13:295:26 | ExprStmt | variables.rs:295:13:295:21 | PathExpr | | +| variables.rs:295:23:295:24 | b4 | variables.rs:295:13:295:25 | CallExpr | | +| variables.rs:299:5:299:13 | PathExpr | variables.rs:299:15:299:17 | a10 | | +| variables.rs:299:5:299:18 | CallExpr | variables.rs:300:5:300:18 | ExprStmt | | +| variables.rs:299:5:299:19 | ExprStmt | variables.rs:299:5:299:13 | PathExpr | | +| variables.rs:299:15:299:17 | a10 | variables.rs:299:5:299:18 | CallExpr | | +| variables.rs:300:5:300:13 | PathExpr | variables.rs:300:15:300:16 | b4 | | +| variables.rs:300:5:300:17 | CallExpr | variables.rs:266:26:301:1 | BlockExpr | | +| variables.rs:300:5:300:18 | ExprStmt | variables.rs:300:5:300:13 | PathExpr | | +| variables.rs:300:15:300:16 | b4 | variables.rs:300:5:300:17 | CallExpr | | +| variables.rs:303:1:318:1 | enter closure_variable | variables.rs:304:5:306:10 | LetStmt | | +| variables.rs:303:1:318:1 | exit closure_variable (normal) | variables.rs:303:1:318:1 | exit closure_variable | | +| variables.rs:303:23:318:1 | BlockExpr | variables.rs:303:1:318:1 | exit closure_variable (normal) | | +| variables.rs:304:5:306:10 | LetStmt | variables.rs:305:9:306:9 | ClosureExpr | | +| variables.rs:304:9:304:23 | example_closure | variables.rs:307:5:308:27 | LetStmt | match, no-match | +| variables.rs:305:9:306:9 | ClosureExpr | variables.rs:304:9:304:23 | example_closure | | +| variables.rs:305:9:306:9 | enter ClosureExpr | variables.rs:306:9:306:9 | x | | +| variables.rs:305:9:306:9 | exit ClosureExpr (normal) | variables.rs:305:9:306:9 | exit ClosureExpr | | +| variables.rs:306:9:306:9 | x | variables.rs:305:9:306:9 | exit ClosureExpr (normal) | | +| variables.rs:307:5:308:27 | LetStmt | variables.rs:308:9:308:23 | example_closure | | +| variables.rs:307:9:307:10 | n1 | variables.rs:309:5:309:18 | ExprStmt | match, no-match | +| variables.rs:308:9:308:23 | example_closure | variables.rs:308:25:308:25 | 5 | | +| variables.rs:308:9:308:26 | CallExpr | variables.rs:307:9:307:10 | n1 | | +| variables.rs:308:25:308:25 | 5 | variables.rs:308:9:308:26 | CallExpr | | +| variables.rs:309:5:309:13 | PathExpr | variables.rs:309:15:309:16 | n1 | | +| variables.rs:309:5:309:17 | CallExpr | variables.rs:311:5:311:25 | ExprStmt | | +| variables.rs:309:5:309:18 | ExprStmt | variables.rs:309:5:309:13 | PathExpr | | +| variables.rs:309:15:309:16 | n1 | variables.rs:309:5:309:17 | CallExpr | | +| variables.rs:311:5:311:22 | PathExpr | variables.rs:311:5:311:24 | CallExpr | | +| variables.rs:311:5:311:24 | CallExpr | variables.rs:312:5:314:10 | LetStmt | | +| variables.rs:311:5:311:25 | ExprStmt | variables.rs:311:5:311:22 | PathExpr | | +| variables.rs:312:5:314:10 | LetStmt | variables.rs:313:9:314:9 | ClosureExpr | | +| variables.rs:312:9:312:26 | immutable_variable | variables.rs:315:5:316:30 | LetStmt | match, no-match | +| variables.rs:313:9:314:9 | ClosureExpr | variables.rs:312:9:312:26 | immutable_variable | | +| variables.rs:313:9:314:9 | enter ClosureExpr | variables.rs:314:9:314:9 | x | | +| variables.rs:313:9:314:9 | exit ClosureExpr (normal) | variables.rs:313:9:314:9 | exit ClosureExpr | | +| variables.rs:314:9:314:9 | x | variables.rs:313:9:314:9 | exit ClosureExpr (normal) | | +| variables.rs:315:5:316:30 | LetStmt | variables.rs:316:9:316:26 | immutable_variable | | +| variables.rs:315:9:315:10 | n2 | variables.rs:317:5:317:18 | ExprStmt | match, no-match | +| variables.rs:316:9:316:26 | immutable_variable | variables.rs:316:28:316:28 | 6 | | +| variables.rs:316:9:316:29 | CallExpr | variables.rs:315:9:315:10 | n2 | | +| variables.rs:316:28:316:28 | 6 | variables.rs:316:9:316:29 | CallExpr | | +| variables.rs:317:5:317:13 | PathExpr | variables.rs:317:15:317:16 | n2 | | +| variables.rs:317:5:317:17 | CallExpr | variables.rs:303:23:318:1 | BlockExpr | | +| variables.rs:317:5:317:18 | ExprStmt | variables.rs:317:5:317:13 | PathExpr | | +| variables.rs:317:15:317:16 | n2 | variables.rs:317:5:317:17 | CallExpr | | +| variables.rs:320:1:327:1 | enter for_variable | variables.rs:321:5:321:42 | LetStmt | | +| variables.rs:320:1:327:1 | exit for_variable (normal) | variables.rs:320:1:327:1 | exit for_variable | | +| variables.rs:320:19:327:1 | BlockExpr | variables.rs:320:1:327:1 | exit for_variable (normal) | | +| variables.rs:321:5:321:42 | LetStmt | variables.rs:321:15:321:22 | "apples" | | +| variables.rs:321:9:321:9 | v | variables.rs:324:12:324:12 | v | match, no-match | +| variables.rs:321:13:321:41 | RefExpr | variables.rs:321:9:321:9 | v | | +| variables.rs:321:14:321:41 | ArrayExpr | variables.rs:321:13:321:41 | RefExpr | | +| variables.rs:321:15:321:22 | "apples" | variables.rs:321:25:321:30 | "cake" | | +| variables.rs:321:25:321:30 | "cake" | variables.rs:321:33:321:40 | "coffee" | | +| variables.rs:321:33:321:40 | "coffee" | variables.rs:321:14:321:41 | ArrayExpr | | +| variables.rs:323:5:326:5 | ForExpr | variables.rs:320:19:327:1 | BlockExpr | | +| variables.rs:323:9:323:12 | text | variables.rs:323:5:326:5 | ForExpr | no-match | +| variables.rs:323:9:323:12 | text | variables.rs:325:9:325:24 | ExprStmt | match | +| variables.rs:324:12:324:12 | v | variables.rs:323:9:323:12 | text | | +| variables.rs:324:14:326:5 | BlockExpr | variables.rs:323:9:323:12 | text | | +| variables.rs:325:9:325:17 | PathExpr | variables.rs:325:19:325:22 | text | | +| variables.rs:325:9:325:23 | CallExpr | variables.rs:324:14:326:5 | BlockExpr | | +| variables.rs:325:9:325:24 | ExprStmt | variables.rs:325:9:325:17 | PathExpr | | +| variables.rs:325:19:325:22 | text | variables.rs:325:9:325:23 | CallExpr | | +| variables.rs:329:1:335:1 | enter add_assign | variables.rs:330:5:330:18 | LetStmt | | +| variables.rs:329:1:335:1 | exit add_assign (normal) | variables.rs:329:1:335:1 | exit add_assign | | +| variables.rs:329:17:335:1 | BlockExpr | variables.rs:329:1:335:1 | exit add_assign (normal) | | +| variables.rs:330:5:330:18 | LetStmt | variables.rs:330:17:330:17 | 0 | | +| variables.rs:330:9:330:13 | a | variables.rs:331:5:331:11 | ExprStmt | match, no-match | +| variables.rs:330:17:330:17 | 0 | variables.rs:330:9:330:13 | a | | +| variables.rs:331:5:331:5 | a | variables.rs:331:10:331:10 | 1 | | +| variables.rs:331:5:331:10 | ... += ... | variables.rs:332:5:332:17 | ExprStmt | | +| variables.rs:331:5:331:11 | ExprStmt | variables.rs:331:5:331:5 | a | | +| variables.rs:331:10:331:10 | 1 | variables.rs:331:5:331:10 | ... += ... | | +| variables.rs:332:5:332:13 | PathExpr | variables.rs:332:15:332:15 | a | | +| variables.rs:332:5:332:16 | CallExpr | variables.rs:333:5:333:28 | ExprStmt | | +| variables.rs:332:5:332:17 | ExprStmt | variables.rs:332:5:332:13 | PathExpr | | +| variables.rs:332:15:332:15 | a | variables.rs:332:5:332:16 | CallExpr | | +| variables.rs:333:5:333:27 | MethodCallExpr | variables.rs:334:5:334:17 | ExprStmt | | +| variables.rs:333:5:333:28 | ExprStmt | variables.rs:333:5:333:27 | MethodCallExpr | | +| variables.rs:334:5:334:13 | PathExpr | variables.rs:334:15:334:15 | a | | +| variables.rs:334:5:334:16 | CallExpr | variables.rs:329:17:335:1 | BlockExpr | | +| variables.rs:334:5:334:17 | ExprStmt | variables.rs:334:5:334:13 | PathExpr | | +| variables.rs:334:15:334:15 | a | variables.rs:334:5:334:16 | CallExpr | | +| variables.rs:337:1:343:1 | enter mutate | variables.rs:338:5:338:18 | LetStmt | | +| variables.rs:337:1:343:1 | exit mutate (normal) | variables.rs:337:1:343:1 | exit mutate | | +| variables.rs:337:13:343:1 | BlockExpr | variables.rs:337:1:343:1 | exit mutate (normal) | | +| variables.rs:338:5:338:18 | LetStmt | variables.rs:338:17:338:17 | 1 | | +| variables.rs:338:9:338:13 | i | variables.rs:339:5:340:15 | LetStmt | match, no-match | +| variables.rs:338:17:338:17 | 1 | variables.rs:338:9:338:13 | i | | +| variables.rs:339:5:340:15 | LetStmt | variables.rs:340:14:340:14 | i | | +| variables.rs:339:9:339:13 | ref_i | variables.rs:341:5:341:15 | ExprStmt | match, no-match | +| variables.rs:340:9:340:14 | RefExpr | variables.rs:339:9:339:13 | ref_i | | +| variables.rs:340:14:340:14 | i | variables.rs:340:9:340:14 | RefExpr | | +| variables.rs:341:5:341:10 | * ... | variables.rs:341:14:341:14 | 2 | | +| variables.rs:341:5:341:14 | ... = ... | variables.rs:342:5:342:17 | ExprStmt | | +| variables.rs:341:5:341:15 | ExprStmt | variables.rs:341:6:341:10 | ref_i | | +| variables.rs:341:6:341:10 | ref_i | variables.rs:341:5:341:10 | * ... | | +| variables.rs:341:14:341:14 | 2 | variables.rs:341:5:341:14 | ... = ... | | +| variables.rs:342:5:342:13 | PathExpr | variables.rs:342:15:342:15 | i | | +| variables.rs:342:5:342:16 | CallExpr | variables.rs:337:13:343:1 | BlockExpr | | +| variables.rs:342:5:342:17 | ExprStmt | variables.rs:342:5:342:13 | PathExpr | | +| variables.rs:342:15:342:15 | i | variables.rs:342:5:342:16 | CallExpr | | +| variables.rs:345:1:349:1 | enter mutate_param | variables.rs:346:5:348:11 | ExprStmt | | +| variables.rs:345:1:349:1 | exit mutate_param (normal) | variables.rs:345:1:349:1 | exit mutate_param | | +| variables.rs:345:31:349:1 | BlockExpr | variables.rs:345:1:349:1 | exit mutate_param (normal) | | +| variables.rs:346:5:346:6 | * ... | variables.rs:347:10:347:10 | x | | +| variables.rs:346:5:348:10 | ... = ... | variables.rs:345:31:349:1 | BlockExpr | | +| variables.rs:346:5:348:11 | ExprStmt | variables.rs:346:6:346:6 | x | | +| variables.rs:346:6:346:6 | x | variables.rs:346:5:346:6 | * ... | | +| variables.rs:347:9:347:10 | * ... | variables.rs:348:10:348:10 | x | | +| variables.rs:347:9:348:10 | ... + ... | variables.rs:346:5:348:10 | ... = ... | | +| variables.rs:347:10:347:10 | x | variables.rs:347:9:347:10 | * ... | | +| variables.rs:348:9:348:10 | * ... | variables.rs:347:9:348:10 | ... + ... | | +| variables.rs:348:10:348:10 | x | variables.rs:348:9:348:10 | * ... | | +| variables.rs:351:1:355:1 | enter mutate_arg | variables.rs:352:5:352:18 | LetStmt | | +| variables.rs:351:1:355:1 | exit mutate_arg (normal) | variables.rs:351:1:355:1 | exit mutate_arg | | +| variables.rs:351:17:355:1 | BlockExpr | variables.rs:351:1:355:1 | exit mutate_arg (normal) | | +| variables.rs:352:5:352:18 | LetStmt | variables.rs:352:17:352:17 | 2 | | +| variables.rs:352:9:352:13 | x | variables.rs:353:5:353:25 | ExprStmt | match, no-match | +| variables.rs:352:17:352:17 | 2 | variables.rs:352:9:352:13 | x | | +| variables.rs:353:5:353:16 | PathExpr | variables.rs:353:23:353:23 | x | | +| variables.rs:353:5:353:24 | CallExpr | variables.rs:354:5:354:17 | ExprStmt | | +| variables.rs:353:5:353:25 | ExprStmt | variables.rs:353:5:353:16 | PathExpr | | +| variables.rs:353:18:353:23 | RefExpr | variables.rs:353:5:353:24 | CallExpr | | +| variables.rs:353:23:353:23 | x | variables.rs:353:18:353:23 | RefExpr | | +| variables.rs:354:5:354:13 | PathExpr | variables.rs:354:15:354:15 | x | | +| variables.rs:354:5:354:16 | CallExpr | variables.rs:351:17:355:1 | BlockExpr | | +| variables.rs:354:5:354:17 | ExprStmt | variables.rs:354:5:354:13 | PathExpr | | +| variables.rs:354:15:354:15 | x | variables.rs:354:5:354:16 | CallExpr | | +| variables.rs:357:1:383:1 | enter main | variables.rs:358:5:358:25 | ExprStmt | | +| variables.rs:357:1:383:1 | exit main (normal) | variables.rs:357:1:383:1 | exit main | | +| variables.rs:357:11:383:1 | BlockExpr | variables.rs:357:1:383:1 | exit main (normal) | | +| variables.rs:358:5:358:22 | PathExpr | variables.rs:358:5:358:24 | CallExpr | | +| variables.rs:358:5:358:24 | CallExpr | variables.rs:359:5:359:23 | ExprStmt | | +| variables.rs:358:5:358:25 | ExprStmt | variables.rs:358:5:358:22 | PathExpr | | +| variables.rs:359:5:359:20 | PathExpr | variables.rs:359:5:359:22 | CallExpr | | +| variables.rs:359:5:359:22 | CallExpr | variables.rs:360:5:360:23 | ExprStmt | | +| variables.rs:359:5:359:23 | ExprStmt | variables.rs:359:5:359:20 | PathExpr | | +| variables.rs:360:5:360:20 | PathExpr | variables.rs:360:5:360:22 | CallExpr | | +| variables.rs:360:5:360:22 | CallExpr | variables.rs:361:5:361:23 | ExprStmt | | +| variables.rs:360:5:360:23 | ExprStmt | variables.rs:360:5:360:20 | PathExpr | | +| variables.rs:361:5:361:20 | PathExpr | variables.rs:361:5:361:22 | CallExpr | | +| variables.rs:361:5:361:22 | CallExpr | variables.rs:362:5:362:19 | ExprStmt | | +| variables.rs:361:5:361:23 | ExprStmt | variables.rs:361:5:361:20 | PathExpr | | +| variables.rs:362:5:362:16 | PathExpr | variables.rs:362:5:362:18 | CallExpr | | +| variables.rs:362:5:362:18 | CallExpr | variables.rs:363:5:363:19 | ExprStmt | | +| variables.rs:362:5:362:19 | ExprStmt | variables.rs:362:5:362:16 | PathExpr | | +| variables.rs:363:5:363:16 | PathExpr | variables.rs:363:5:363:18 | CallExpr | | +| variables.rs:363:5:363:18 | CallExpr | variables.rs:364:5:364:19 | ExprStmt | | +| variables.rs:363:5:363:19 | ExprStmt | variables.rs:363:5:363:16 | PathExpr | | +| variables.rs:364:5:364:16 | PathExpr | variables.rs:364:5:364:18 | CallExpr | | +| variables.rs:364:5:364:18 | CallExpr | variables.rs:365:5:365:19 | ExprStmt | | +| variables.rs:364:5:364:19 | ExprStmt | variables.rs:364:5:364:16 | PathExpr | | +| variables.rs:365:5:365:16 | PathExpr | variables.rs:365:5:365:18 | CallExpr | | +| variables.rs:365:5:365:18 | CallExpr | variables.rs:366:5:366:21 | ExprStmt | | +| variables.rs:365:5:365:19 | ExprStmt | variables.rs:365:5:365:16 | PathExpr | | +| variables.rs:366:5:366:18 | PathExpr | variables.rs:366:5:366:20 | CallExpr | | +| variables.rs:366:5:366:20 | CallExpr | variables.rs:367:5:367:21 | ExprStmt | | +| variables.rs:366:5:366:21 | ExprStmt | variables.rs:366:5:366:18 | PathExpr | | +| variables.rs:367:5:367:18 | PathExpr | variables.rs:367:5:367:20 | CallExpr | | +| variables.rs:367:5:367:20 | CallExpr | variables.rs:368:5:368:21 | ExprStmt | | +| variables.rs:367:5:367:21 | ExprStmt | variables.rs:367:5:367:18 | PathExpr | | +| variables.rs:368:5:368:18 | PathExpr | variables.rs:368:5:368:20 | CallExpr | | +| variables.rs:368:5:368:20 | CallExpr | variables.rs:369:5:369:21 | ExprStmt | | +| variables.rs:368:5:368:21 | ExprStmt | variables.rs:368:5:368:18 | PathExpr | | +| variables.rs:369:5:369:18 | PathExpr | variables.rs:369:5:369:20 | CallExpr | | +| variables.rs:369:5:369:20 | CallExpr | variables.rs:370:5:370:21 | ExprStmt | | +| variables.rs:369:5:369:21 | ExprStmt | variables.rs:369:5:369:18 | PathExpr | | +| variables.rs:370:5:370:18 | PathExpr | variables.rs:370:5:370:20 | CallExpr | | +| variables.rs:370:5:370:20 | CallExpr | variables.rs:371:5:371:21 | ExprStmt | | +| variables.rs:370:5:370:21 | ExprStmt | variables.rs:370:5:370:18 | PathExpr | | +| variables.rs:371:5:371:18 | PathExpr | variables.rs:371:5:371:20 | CallExpr | | +| variables.rs:371:5:371:20 | CallExpr | variables.rs:372:5:372:21 | ExprStmt | | +| variables.rs:371:5:371:21 | ExprStmt | variables.rs:371:5:371:18 | PathExpr | | +| variables.rs:372:5:372:18 | PathExpr | variables.rs:372:5:372:20 | CallExpr | | +| variables.rs:372:5:372:20 | CallExpr | variables.rs:373:5:373:21 | ExprStmt | | +| variables.rs:372:5:372:21 | ExprStmt | variables.rs:372:5:372:18 | PathExpr | | +| variables.rs:373:5:373:18 | PathExpr | variables.rs:373:5:373:20 | CallExpr | | +| variables.rs:373:5:373:20 | CallExpr | variables.rs:374:5:374:21 | ExprStmt | | +| variables.rs:373:5:373:21 | ExprStmt | variables.rs:373:5:373:18 | PathExpr | | +| variables.rs:374:5:374:18 | PathExpr | variables.rs:374:5:374:20 | CallExpr | | +| variables.rs:374:5:374:20 | CallExpr | variables.rs:375:5:375:36 | ExprStmt | | +| variables.rs:374:5:374:21 | ExprStmt | variables.rs:374:5:374:18 | PathExpr | | +| variables.rs:375:5:375:18 | PathExpr | variables.rs:375:20:375:22 | "a" | | +| variables.rs:375:5:375:35 | CallExpr | variables.rs:376:5:376:37 | ExprStmt | | +| variables.rs:375:5:375:36 | ExprStmt | variables.rs:375:5:375:18 | PathExpr | | +| variables.rs:375:20:375:22 | "a" | variables.rs:375:26:375:28 | "b" | | +| variables.rs:375:25:375:34 | TupleExpr | variables.rs:375:5:375:35 | CallExpr | | +| variables.rs:375:26:375:28 | "b" | variables.rs:375:31:375:33 | "c" | | +| variables.rs:375:31:375:33 | "c" | variables.rs:375:25:375:34 | TupleExpr | | +| variables.rs:376:5:376:18 | PathExpr | variables.rs:376:20:376:31 | PathExpr | | +| variables.rs:376:5:376:36 | CallExpr | variables.rs:377:5:377:26 | ExprStmt | | +| variables.rs:376:5:376:37 | ExprStmt | variables.rs:376:5:376:18 | PathExpr | | +| variables.rs:376:20:376:31 | PathExpr | variables.rs:376:33:376:34 | 45 | | +| variables.rs:376:20:376:35 | CallExpr | variables.rs:376:5:376:36 | CallExpr | | +| variables.rs:376:33:376:34 | 45 | variables.rs:376:20:376:35 | CallExpr | | +| variables.rs:377:5:377:23 | PathExpr | variables.rs:377:5:377:25 | CallExpr | | +| variables.rs:377:5:377:25 | CallExpr | variables.rs:378:5:378:23 | ExprStmt | | +| variables.rs:377:5:377:26 | ExprStmt | variables.rs:377:5:377:23 | PathExpr | | +| variables.rs:378:5:378:20 | PathExpr | variables.rs:378:5:378:22 | CallExpr | | +| variables.rs:378:5:378:22 | CallExpr | variables.rs:379:5:379:19 | ExprStmt | | +| variables.rs:378:5:378:23 | ExprStmt | variables.rs:378:5:378:20 | PathExpr | | +| variables.rs:379:5:379:16 | PathExpr | variables.rs:379:5:379:18 | CallExpr | | +| variables.rs:379:5:379:18 | CallExpr | variables.rs:380:5:380:17 | ExprStmt | | +| variables.rs:379:5:379:19 | ExprStmt | variables.rs:379:5:379:16 | PathExpr | | +| variables.rs:380:5:380:14 | PathExpr | variables.rs:380:5:380:16 | CallExpr | | +| variables.rs:380:5:380:16 | CallExpr | variables.rs:381:5:381:13 | ExprStmt | | +| variables.rs:380:5:380:17 | ExprStmt | variables.rs:380:5:380:14 | PathExpr | | +| variables.rs:381:5:381:10 | PathExpr | variables.rs:381:5:381:12 | CallExpr | | +| variables.rs:381:5:381:12 | CallExpr | variables.rs:382:5:382:17 | ExprStmt | | +| variables.rs:381:5:381:13 | ExprStmt | variables.rs:381:5:381:10 | PathExpr | | +| variables.rs:382:5:382:14 | PathExpr | variables.rs:382:5:382:16 | CallExpr | | +| variables.rs:382:5:382:16 | CallExpr | variables.rs:357:11:383:1 | BlockExpr | | +| variables.rs:382:5:382:17 | ExprStmt | variables.rs:382:5:382:14 | PathExpr | | breakTarget continueTarget diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index ad85ccfbfcc8..807fc9ff8919 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -1,261 +1,308 @@ testFailures +| variables.rs:331:5:331:5 | a | Unexpected result: read_access=a | +| variables.rs:331:5:331:5 | a | Unexpected result: write_access=a | +| variables.rs:331:13:331:25 | Comment | Missing result:access=a | +| variables.rs:333:11:333:11 | a | Unexpected result: read_access=a | +| variables.rs:333:30:333:42 | Comment | Missing result:access=a | +| variables.rs:340:14:340:14 | i | Unexpected result: read_access=i | +| variables.rs:340:17:340:29 | Comment | Missing result:access=i | +| variables.rs:341:6:341:10 | ref_i | Unexpected result: write_access=ref_i | +| variables.rs:341:17:341:38 | Comment | Missing result:read_access=ref_i | +| variables.rs:346:6:346:6 | x | Unexpected result: write_access=x | +| variables.rs:346:10:346:27 | Comment | Missing result:read_access=x | +| variables.rs:353:23:353:23 | x | Unexpected result: read_access=x | +| variables.rs:353:27:353:39 | Comment | Missing result:access=x | failures variable -| variables.rs:1:14:1:14 | s | -| variables.rs:5:14:5:14 | i | -| variables.rs:10:9:10:10 | x1 | -| variables.rs:15:13:15:14 | x2 | -| variables.rs:22:9:22:10 | x3 | +| variables.rs:3:14:3:14 | s | +| variables.rs:7:14:7:14 | i | +| variables.rs:12:9:12:10 | x1 | +| variables.rs:17:13:17:14 | x2 | | variables.rs:24:9:24:10 | x3 | -| variables.rs:30:9:30:10 | x4 | -| variables.rs:33:13:33:14 | x4 | -| variables.rs:47:13:47:14 | a1 | -| variables.rs:48:13:48:14 | b1 | -| variables.rs:51:13:51:13 | x | -| variables.rs:52:13:52:13 | y | -| variables.rs:62:9:62:10 | p1 | -| variables.rs:64:12:64:13 | a2 | -| variables.rs:65:12:65:13 | b2 | -| variables.rs:72:9:72:10 | s1 | -| variables.rs:74:21:74:22 | s2 | -| variables.rs:81:14:81:15 | x5 | -| variables.rs:89:9:89:10 | s1 | -| variables.rs:91:24:91:25 | s2 | -| variables.rs:98:9:98:10 | x6 | -| variables.rs:99:9:99:10 | y1 | -| variables.rs:103:14:103:15 | y1 | -| variables.rs:108:9:108:12 | None | -| variables.rs:115:9:115:15 | numbers | -| variables.rs:119:13:119:17 | first | -| variables.rs:120:13:120:17 | third | -| variables.rs:121:13:121:17 | fifth | -| variables.rs:131:13:131:17 | first | -| variables.rs:133:13:133:16 | last | -| variables.rs:142:9:142:10 | p2 | -| variables.rs:146:16:146:17 | x7 | -| variables.rs:156:9:156:11 | msg | -| variables.rs:160:17:160:27 | id_variable | -| variables.rs:165:26:165:27 | id | -| variables.rs:176:9:176:14 | either | -| variables.rs:178:9:178:44 | a3 | -| variables.rs:190:9:190:10 | tv | -| variables.rs:192:9:192:81 | a4 | -| variables.rs:196:9:196:83 | a5 | -| variables.rs:200:9:200:83 | a6 | -| variables.rs:206:9:206:14 | either | -| variables.rs:208:9:208:44 | a7 | -| variables.rs:216:9:216:14 | either | -| variables.rs:219:13:219:13 | e | -| variables.rs:220:14:220:51 | a11 | -| variables.rs:223:33:223:35 | a12 | -| variables.rs:240:9:240:10 | fv | -| variables.rs:242:9:242:109 | a13 | -| variables.rs:248:5:248:6 | a8 | -| variables.rs:250:9:250:10 | b3 | -| variables.rs:251:9:251:10 | c1 | -| variables.rs:259:6:259:41 | a9 | -| variables.rs:266:13:266:15 | a10 | -| variables.rs:267:13:267:14 | b4 | -| variables.rs:268:13:268:14 | c2 | -| variables.rs:289:13:289:15 | a10 | -| variables.rs:290:13:290:14 | b4 | -| variables.rs:302:9:302:23 | example_closure | -| variables.rs:303:10:303:10 | x | -| variables.rs:305:9:305:10 | n1 | -| variables.rs:310:9:310:26 | immutable_variable | -| variables.rs:311:10:311:10 | x | -| variables.rs:313:9:313:10 | n2 | -| variables.rs:319:9:319:9 | v | -| variables.rs:321:9:321:12 | text | +| variables.rs:26:9:26:10 | x3 | +| variables.rs:32:9:32:10 | x4 | +| variables.rs:35:13:35:14 | x4 | +| variables.rs:49:13:49:14 | a1 | +| variables.rs:50:13:50:14 | b1 | +| variables.rs:53:13:53:13 | x | +| variables.rs:54:13:54:13 | y | +| variables.rs:64:9:64:10 | p1 | +| variables.rs:66:12:66:13 | a2 | +| variables.rs:67:12:67:13 | b2 | +| variables.rs:74:9:74:10 | s1 | +| variables.rs:76:21:76:22 | s2 | +| variables.rs:83:14:83:15 | x5 | +| variables.rs:91:9:91:10 | s1 | +| variables.rs:93:24:93:25 | s2 | +| variables.rs:100:9:100:10 | x6 | +| variables.rs:101:9:101:10 | y1 | +| variables.rs:105:14:105:15 | y1 | +| variables.rs:110:9:110:12 | None | +| variables.rs:117:9:117:15 | numbers | +| variables.rs:121:13:121:17 | first | +| variables.rs:122:13:122:17 | third | +| variables.rs:123:13:123:17 | fifth | +| variables.rs:133:13:133:17 | first | +| variables.rs:135:13:135:16 | last | +| variables.rs:144:9:144:10 | p2 | +| variables.rs:148:16:148:17 | x7 | +| variables.rs:158:9:158:11 | msg | +| variables.rs:162:17:162:27 | id_variable | +| variables.rs:167:26:167:27 | id | +| variables.rs:178:9:178:14 | either | +| variables.rs:180:9:180:44 | a3 | +| variables.rs:192:9:192:10 | tv | +| variables.rs:194:9:194:81 | a4 | +| variables.rs:198:9:198:83 | a5 | +| variables.rs:202:9:202:83 | a6 | +| variables.rs:208:9:208:14 | either | +| variables.rs:210:9:210:44 | a7 | +| variables.rs:218:9:218:14 | either | +| variables.rs:221:13:221:13 | e | +| variables.rs:222:14:222:51 | a11 | +| variables.rs:225:33:225:35 | a12 | +| variables.rs:242:9:242:10 | fv | +| variables.rs:244:9:244:109 | a13 | +| variables.rs:250:5:250:6 | a8 | +| variables.rs:252:9:252:10 | b3 | +| variables.rs:253:9:253:10 | c1 | +| variables.rs:261:6:261:41 | a9 | +| variables.rs:268:13:268:15 | a10 | +| variables.rs:269:13:269:14 | b4 | +| variables.rs:270:13:270:14 | c2 | +| variables.rs:291:13:291:15 | a10 | +| variables.rs:292:13:292:14 | b4 | +| variables.rs:304:9:304:23 | example_closure | +| variables.rs:305:10:305:10 | x | +| variables.rs:307:9:307:10 | n1 | +| variables.rs:312:9:312:26 | immutable_variable | +| variables.rs:313:10:313:10 | x | +| variables.rs:315:9:315:10 | n2 | +| variables.rs:321:9:321:9 | v | +| variables.rs:323:9:323:12 | text | +| variables.rs:330:13:330:13 | a | +| variables.rs:338:13:338:13 | i | +| variables.rs:339:9:339:13 | ref_i | +| variables.rs:345:17:345:17 | x | +| variables.rs:352:13:352:13 | x | variableAccess -| variables.rs:11:15:11:16 | x1 | variables.rs:10:9:10:10 | x1 | -| variables.rs:16:15:16:16 | x2 | variables.rs:15:13:15:14 | x2 | -| variables.rs:17:5:17:6 | x2 | variables.rs:15:13:15:14 | x2 | -| variables.rs:18:15:18:16 | x2 | variables.rs:15:13:15:14 | x2 | -| variables.rs:23:15:23:16 | x3 | variables.rs:22:9:22:10 | x3 | -| variables.rs:25:9:25:10 | x3 | variables.rs:22:9:22:10 | x3 | -| variables.rs:26:15:26:16 | x3 | variables.rs:24:9:24:10 | x3 | -| variables.rs:31:15:31:16 | x4 | variables.rs:30:9:30:10 | x4 | -| variables.rs:34:19:34:20 | x4 | variables.rs:33:13:33:14 | x4 | -| variables.rs:36:15:36:16 | x4 | variables.rs:30:9:30:10 | x4 | -| variables.rs:55:15:55:16 | a1 | variables.rs:47:13:47:14 | a1 | -| variables.rs:56:15:56:16 | b1 | variables.rs:48:13:48:14 | b1 | -| variables.rs:57:15:57:15 | x | variables.rs:51:13:51:13 | x | -| variables.rs:58:15:58:15 | y | variables.rs:52:13:52:13 | y | -| variables.rs:66:9:66:10 | p1 | variables.rs:62:9:62:10 | p1 | -| variables.rs:67:15:67:16 | a2 | variables.rs:64:12:64:13 | a2 | -| variables.rs:68:15:68:16 | b2 | variables.rs:65:12:65:13 | b2 | -| variables.rs:75:11:75:12 | s1 | variables.rs:72:9:72:10 | s1 | -| variables.rs:76:19:76:20 | s2 | variables.rs:74:21:74:22 | s2 | -| variables.rs:85:15:85:16 | x5 | variables.rs:81:14:81:15 | x5 | -| variables.rs:92:11:92:12 | s1 | variables.rs:89:9:89:10 | s1 | -| variables.rs:93:19:93:20 | s2 | variables.rs:91:24:91:25 | s2 | -| variables.rs:101:11:101:12 | x6 | variables.rs:98:9:98:10 | x6 | -| variables.rs:106:23:106:24 | y1 | variables.rs:103:14:103:15 | y1 | -| variables.rs:111:15:111:16 | y1 | variables.rs:99:9:99:10 | y1 | -| variables.rs:117:11:117:17 | numbers | variables.rs:115:9:115:15 | numbers | -| variables.rs:123:23:123:27 | first | variables.rs:119:13:119:17 | first | -| variables.rs:124:23:124:27 | third | variables.rs:120:13:120:17 | third | -| variables.rs:125:23:125:27 | fifth | variables.rs:121:13:121:17 | fifth | -| variables.rs:129:11:129:17 | numbers | variables.rs:115:9:115:15 | numbers | -| variables.rs:135:23:135:27 | first | variables.rs:131:13:131:17 | first | -| variables.rs:136:23:136:26 | last | variables.rs:133:13:133:16 | last | -| variables.rs:144:11:144:12 | p2 | variables.rs:142:9:142:10 | p2 | -| variables.rs:147:24:147:25 | x7 | variables.rs:146:16:146:17 | x7 | -| variables.rs:158:11:158:13 | msg | variables.rs:156:9:156:11 | msg | -| variables.rs:161:24:161:34 | id_variable | variables.rs:160:17:160:27 | id_variable | -| variables.rs:166:23:166:24 | id | variables.rs:165:26:165:27 | id | -| variables.rs:177:11:177:16 | either | variables.rs:176:9:176:14 | either | -| variables.rs:179:26:179:27 | a3 | variables.rs:178:9:178:44 | a3 | -| variables.rs:191:11:191:12 | tv | variables.rs:190:9:190:10 | tv | -| variables.rs:193:26:193:27 | a4 | variables.rs:192:9:192:81 | a4 | -| variables.rs:195:11:195:12 | tv | variables.rs:190:9:190:10 | tv | -| variables.rs:197:26:197:27 | a5 | variables.rs:196:9:196:83 | a5 | -| variables.rs:199:11:199:12 | tv | variables.rs:190:9:190:10 | tv | -| variables.rs:201:26:201:27 | a6 | variables.rs:200:9:200:83 | a6 | -| variables.rs:207:11:207:16 | either | variables.rs:206:9:206:14 | either | -| variables.rs:209:16:209:17 | a7 | variables.rs:208:9:208:44 | a7 | -| variables.rs:210:26:210:27 | a7 | variables.rs:208:9:208:44 | a7 | -| variables.rs:218:11:218:16 | either | variables.rs:216:9:216:14 | either | -| variables.rs:222:23:222:25 | a11 | variables.rs:220:14:220:51 | a11 | -| variables.rs:224:15:224:15 | e | variables.rs:219:13:219:13 | e | -| variables.rs:225:28:225:30 | a12 | variables.rs:223:33:223:35 | a12 | -| variables.rs:241:11:241:12 | fv | variables.rs:240:9:240:10 | fv | -| variables.rs:243:26:243:28 | a13 | variables.rs:242:9:242:109 | a13 | -| variables.rs:253:15:253:16 | a8 | variables.rs:248:5:248:6 | a8 | -| variables.rs:254:15:254:16 | b3 | variables.rs:250:9:250:10 | b3 | -| variables.rs:255:15:255:16 | c1 | variables.rs:251:9:251:10 | c1 | -| variables.rs:261:15:261:16 | a9 | variables.rs:259:6:259:41 | a9 | -| variables.rs:270:15:270:17 | a10 | variables.rs:266:13:266:15 | a10 | -| variables.rs:271:15:271:16 | b4 | variables.rs:267:13:267:14 | b4 | -| variables.rs:272:15:272:16 | c2 | variables.rs:268:13:268:14 | c2 | -| variables.rs:275:9:275:10 | c2 | variables.rs:268:13:268:14 | c2 | -| variables.rs:276:9:276:10 | b4 | variables.rs:267:13:267:14 | b4 | -| variables.rs:277:9:277:11 | a10 | variables.rs:266:13:266:15 | a10 | -| variables.rs:279:9:279:11 | a10 | variables.rs:266:13:266:15 | a10 | -| variables.rs:280:9:280:10 | b4 | variables.rs:267:13:267:14 | b4 | -| variables.rs:281:9:281:10 | c2 | variables.rs:268:13:268:14 | c2 | -| variables.rs:283:15:283:17 | a10 | variables.rs:266:13:266:15 | a10 | -| variables.rs:284:15:284:16 | b4 | variables.rs:267:13:267:14 | b4 | -| variables.rs:285:15:285:16 | c2 | variables.rs:268:13:268:14 | c2 | -| variables.rs:292:23:292:25 | a10 | variables.rs:289:13:289:15 | a10 | -| variables.rs:293:23:293:24 | b4 | variables.rs:290:13:290:14 | b4 | -| variables.rs:297:15:297:17 | a10 | variables.rs:266:13:266:15 | a10 | -| variables.rs:298:15:298:16 | b4 | variables.rs:267:13:267:14 | b4 | -| variables.rs:304:9:304:9 | x | variables.rs:303:10:303:10 | x | -| variables.rs:306:9:306:23 | example_closure | variables.rs:302:9:302:23 | example_closure | -| variables.rs:307:15:307:16 | n1 | variables.rs:305:9:305:10 | n1 | -| variables.rs:312:9:312:9 | x | variables.rs:311:10:311:10 | x | -| variables.rs:314:9:314:26 | immutable_variable | variables.rs:310:9:310:26 | immutable_variable | -| variables.rs:315:15:315:16 | n2 | variables.rs:313:9:313:10 | n2 | -| variables.rs:322:12:322:12 | v | variables.rs:319:9:319:9 | v | -| variables.rs:323:19:323:22 | text | variables.rs:321:9:321:12 | text | +| variables.rs:13:15:13:16 | x1 | variables.rs:12:9:12:10 | x1 | +| variables.rs:18:15:18:16 | x2 | variables.rs:17:13:17:14 | x2 | +| variables.rs:19:5:19:6 | x2 | variables.rs:17:13:17:14 | x2 | +| variables.rs:20:15:20:16 | x2 | variables.rs:17:13:17:14 | x2 | +| variables.rs:25:15:25:16 | x3 | variables.rs:24:9:24:10 | x3 | +| variables.rs:27:9:27:10 | x3 | variables.rs:24:9:24:10 | x3 | +| variables.rs:28:15:28:16 | x3 | variables.rs:26:9:26:10 | x3 | +| variables.rs:33:15:33:16 | x4 | variables.rs:32:9:32:10 | x4 | +| variables.rs:36:19:36:20 | x4 | variables.rs:35:13:35:14 | x4 | +| variables.rs:38:15:38:16 | x4 | variables.rs:32:9:32:10 | x4 | +| variables.rs:57:15:57:16 | a1 | variables.rs:49:13:49:14 | a1 | +| variables.rs:58:15:58:16 | b1 | variables.rs:50:13:50:14 | b1 | +| variables.rs:59:15:59:15 | x | variables.rs:53:13:53:13 | x | +| variables.rs:60:15:60:15 | y | variables.rs:54:13:54:13 | y | +| variables.rs:68:9:68:10 | p1 | variables.rs:64:9:64:10 | p1 | +| variables.rs:69:15:69:16 | a2 | variables.rs:66:12:66:13 | a2 | +| variables.rs:70:15:70:16 | b2 | variables.rs:67:12:67:13 | b2 | +| variables.rs:77:11:77:12 | s1 | variables.rs:74:9:74:10 | s1 | +| variables.rs:78:19:78:20 | s2 | variables.rs:76:21:76:22 | s2 | +| variables.rs:87:15:87:16 | x5 | variables.rs:83:14:83:15 | x5 | +| variables.rs:94:11:94:12 | s1 | variables.rs:91:9:91:10 | s1 | +| variables.rs:95:19:95:20 | s2 | variables.rs:93:24:93:25 | s2 | +| variables.rs:103:11:103:12 | x6 | variables.rs:100:9:100:10 | x6 | +| variables.rs:108:23:108:24 | y1 | variables.rs:105:14:105:15 | y1 | +| variables.rs:113:15:113:16 | y1 | variables.rs:101:9:101:10 | y1 | +| variables.rs:119:11:119:17 | numbers | variables.rs:117:9:117:15 | numbers | +| variables.rs:125:23:125:27 | first | variables.rs:121:13:121:17 | first | +| variables.rs:126:23:126:27 | third | variables.rs:122:13:122:17 | third | +| variables.rs:127:23:127:27 | fifth | variables.rs:123:13:123:17 | fifth | +| variables.rs:131:11:131:17 | numbers | variables.rs:117:9:117:15 | numbers | +| variables.rs:137:23:137:27 | first | variables.rs:133:13:133:17 | first | +| variables.rs:138:23:138:26 | last | variables.rs:135:13:135:16 | last | +| variables.rs:146:11:146:12 | p2 | variables.rs:144:9:144:10 | p2 | +| variables.rs:149:24:149:25 | x7 | variables.rs:148:16:148:17 | x7 | +| variables.rs:160:11:160:13 | msg | variables.rs:158:9:158:11 | msg | +| variables.rs:163:24:163:34 | id_variable | variables.rs:162:17:162:27 | id_variable | +| variables.rs:168:23:168:24 | id | variables.rs:167:26:167:27 | id | +| variables.rs:179:11:179:16 | either | variables.rs:178:9:178:14 | either | +| variables.rs:181:26:181:27 | a3 | variables.rs:180:9:180:44 | a3 | +| variables.rs:193:11:193:12 | tv | variables.rs:192:9:192:10 | tv | +| variables.rs:195:26:195:27 | a4 | variables.rs:194:9:194:81 | a4 | +| variables.rs:197:11:197:12 | tv | variables.rs:192:9:192:10 | tv | +| variables.rs:199:26:199:27 | a5 | variables.rs:198:9:198:83 | a5 | +| variables.rs:201:11:201:12 | tv | variables.rs:192:9:192:10 | tv | +| variables.rs:203:26:203:27 | a6 | variables.rs:202:9:202:83 | a6 | +| variables.rs:209:11:209:16 | either | variables.rs:208:9:208:14 | either | +| variables.rs:211:16:211:17 | a7 | variables.rs:210:9:210:44 | a7 | +| variables.rs:212:26:212:27 | a7 | variables.rs:210:9:210:44 | a7 | +| variables.rs:220:11:220:16 | either | variables.rs:218:9:218:14 | either | +| variables.rs:224:23:224:25 | a11 | variables.rs:222:14:222:51 | a11 | +| variables.rs:226:15:226:15 | e | variables.rs:221:13:221:13 | e | +| variables.rs:227:28:227:30 | a12 | variables.rs:225:33:225:35 | a12 | +| variables.rs:243:11:243:12 | fv | variables.rs:242:9:242:10 | fv | +| variables.rs:245:26:245:28 | a13 | variables.rs:244:9:244:109 | a13 | +| variables.rs:255:15:255:16 | a8 | variables.rs:250:5:250:6 | a8 | +| variables.rs:256:15:256:16 | b3 | variables.rs:252:9:252:10 | b3 | +| variables.rs:257:15:257:16 | c1 | variables.rs:253:9:253:10 | c1 | +| variables.rs:263:15:263:16 | a9 | variables.rs:261:6:261:41 | a9 | +| variables.rs:272:15:272:17 | a10 | variables.rs:268:13:268:15 | a10 | +| variables.rs:273:15:273:16 | b4 | variables.rs:269:13:269:14 | b4 | +| variables.rs:274:15:274:16 | c2 | variables.rs:270:13:270:14 | c2 | +| variables.rs:277:9:277:10 | c2 | variables.rs:270:13:270:14 | c2 | +| variables.rs:278:9:278:10 | b4 | variables.rs:269:13:269:14 | b4 | +| variables.rs:279:9:279:11 | a10 | variables.rs:268:13:268:15 | a10 | +| variables.rs:281:9:281:11 | a10 | variables.rs:268:13:268:15 | a10 | +| variables.rs:282:9:282:10 | b4 | variables.rs:269:13:269:14 | b4 | +| variables.rs:283:9:283:10 | c2 | variables.rs:270:13:270:14 | c2 | +| variables.rs:285:15:285:17 | a10 | variables.rs:268:13:268:15 | a10 | +| variables.rs:286:15:286:16 | b4 | variables.rs:269:13:269:14 | b4 | +| variables.rs:287:15:287:16 | c2 | variables.rs:270:13:270:14 | c2 | +| variables.rs:294:23:294:25 | a10 | variables.rs:291:13:291:15 | a10 | +| variables.rs:295:23:295:24 | b4 | variables.rs:292:13:292:14 | b4 | +| variables.rs:299:15:299:17 | a10 | variables.rs:268:13:268:15 | a10 | +| variables.rs:300:15:300:16 | b4 | variables.rs:269:13:269:14 | b4 | +| variables.rs:306:9:306:9 | x | variables.rs:305:10:305:10 | x | +| variables.rs:308:9:308:23 | example_closure | variables.rs:304:9:304:23 | example_closure | +| variables.rs:309:15:309:16 | n1 | variables.rs:307:9:307:10 | n1 | +| variables.rs:314:9:314:9 | x | variables.rs:313:10:313:10 | x | +| variables.rs:316:9:316:26 | immutable_variable | variables.rs:312:9:312:26 | immutable_variable | +| variables.rs:317:15:317:16 | n2 | variables.rs:315:9:315:10 | n2 | +| variables.rs:324:12:324:12 | v | variables.rs:321:9:321:9 | v | +| variables.rs:325:19:325:22 | text | variables.rs:323:9:323:12 | text | +| variables.rs:331:5:331:5 | a | variables.rs:330:13:330:13 | a | +| variables.rs:332:15:332:15 | a | variables.rs:330:13:330:13 | a | +| variables.rs:333:11:333:11 | a | variables.rs:330:13:330:13 | a | +| variables.rs:334:15:334:15 | a | variables.rs:330:13:330:13 | a | +| variables.rs:340:14:340:14 | i | variables.rs:338:13:338:13 | i | +| variables.rs:341:6:341:10 | ref_i | variables.rs:339:9:339:13 | ref_i | +| variables.rs:342:15:342:15 | i | variables.rs:338:13:338:13 | i | +| variables.rs:346:6:346:6 | x | variables.rs:345:17:345:17 | x | +| variables.rs:347:10:347:10 | x | variables.rs:345:17:345:17 | x | +| variables.rs:348:10:348:10 | x | variables.rs:345:17:345:17 | x | +| variables.rs:353:23:353:23 | x | variables.rs:352:13:352:13 | x | +| variables.rs:354:15:354:15 | x | variables.rs:352:13:352:13 | x | variableWriteAccess -| variables.rs:17:5:17:6 | x2 | variables.rs:15:13:15:14 | x2 | -| variables.rs:275:9:275:10 | c2 | variables.rs:268:13:268:14 | c2 | -| variables.rs:276:9:276:10 | b4 | variables.rs:267:13:267:14 | b4 | -| variables.rs:277:9:277:11 | a10 | variables.rs:266:13:266:15 | a10 | +| variables.rs:19:5:19:6 | x2 | variables.rs:17:13:17:14 | x2 | +| variables.rs:277:9:277:10 | c2 | variables.rs:270:13:270:14 | c2 | +| variables.rs:278:9:278:10 | b4 | variables.rs:269:13:269:14 | b4 | +| variables.rs:279:9:279:11 | a10 | variables.rs:268:13:268:15 | a10 | +| variables.rs:331:5:331:5 | a | variables.rs:330:13:330:13 | a | +| variables.rs:341:6:341:10 | ref_i | variables.rs:339:9:339:13 | ref_i | +| variables.rs:346:6:346:6 | x | variables.rs:345:17:345:17 | x | variableReadAccess -| variables.rs:11:15:11:16 | x1 | variables.rs:10:9:10:10 | x1 | -| variables.rs:16:15:16:16 | x2 | variables.rs:15:13:15:14 | x2 | -| variables.rs:18:15:18:16 | x2 | variables.rs:15:13:15:14 | x2 | -| variables.rs:23:15:23:16 | x3 | variables.rs:22:9:22:10 | x3 | -| variables.rs:25:9:25:10 | x3 | variables.rs:22:9:22:10 | x3 | -| variables.rs:26:15:26:16 | x3 | variables.rs:24:9:24:10 | x3 | -| variables.rs:31:15:31:16 | x4 | variables.rs:30:9:30:10 | x4 | -| variables.rs:34:19:34:20 | x4 | variables.rs:33:13:33:14 | x4 | -| variables.rs:36:15:36:16 | x4 | variables.rs:30:9:30:10 | x4 | -| variables.rs:55:15:55:16 | a1 | variables.rs:47:13:47:14 | a1 | -| variables.rs:56:15:56:16 | b1 | variables.rs:48:13:48:14 | b1 | -| variables.rs:57:15:57:15 | x | variables.rs:51:13:51:13 | x | -| variables.rs:58:15:58:15 | y | variables.rs:52:13:52:13 | y | -| variables.rs:66:9:66:10 | p1 | variables.rs:62:9:62:10 | p1 | -| variables.rs:67:15:67:16 | a2 | variables.rs:64:12:64:13 | a2 | -| variables.rs:68:15:68:16 | b2 | variables.rs:65:12:65:13 | b2 | -| variables.rs:75:11:75:12 | s1 | variables.rs:72:9:72:10 | s1 | -| variables.rs:76:19:76:20 | s2 | variables.rs:74:21:74:22 | s2 | -| variables.rs:85:15:85:16 | x5 | variables.rs:81:14:81:15 | x5 | -| variables.rs:92:11:92:12 | s1 | variables.rs:89:9:89:10 | s1 | -| variables.rs:93:19:93:20 | s2 | variables.rs:91:24:91:25 | s2 | -| variables.rs:101:11:101:12 | x6 | variables.rs:98:9:98:10 | x6 | -| variables.rs:106:23:106:24 | y1 | variables.rs:103:14:103:15 | y1 | -| variables.rs:111:15:111:16 | y1 | variables.rs:99:9:99:10 | y1 | -| variables.rs:117:11:117:17 | numbers | variables.rs:115:9:115:15 | numbers | -| variables.rs:123:23:123:27 | first | variables.rs:119:13:119:17 | first | -| variables.rs:124:23:124:27 | third | variables.rs:120:13:120:17 | third | -| variables.rs:125:23:125:27 | fifth | variables.rs:121:13:121:17 | fifth | -| variables.rs:129:11:129:17 | numbers | variables.rs:115:9:115:15 | numbers | -| variables.rs:135:23:135:27 | first | variables.rs:131:13:131:17 | first | -| variables.rs:136:23:136:26 | last | variables.rs:133:13:133:16 | last | -| variables.rs:144:11:144:12 | p2 | variables.rs:142:9:142:10 | p2 | -| variables.rs:147:24:147:25 | x7 | variables.rs:146:16:146:17 | x7 | -| variables.rs:158:11:158:13 | msg | variables.rs:156:9:156:11 | msg | -| variables.rs:161:24:161:34 | id_variable | variables.rs:160:17:160:27 | id_variable | -| variables.rs:166:23:166:24 | id | variables.rs:165:26:165:27 | id | -| variables.rs:177:11:177:16 | either | variables.rs:176:9:176:14 | either | -| variables.rs:179:26:179:27 | a3 | variables.rs:178:9:178:44 | a3 | -| variables.rs:191:11:191:12 | tv | variables.rs:190:9:190:10 | tv | -| variables.rs:193:26:193:27 | a4 | variables.rs:192:9:192:81 | a4 | -| variables.rs:195:11:195:12 | tv | variables.rs:190:9:190:10 | tv | -| variables.rs:197:26:197:27 | a5 | variables.rs:196:9:196:83 | a5 | -| variables.rs:199:11:199:12 | tv | variables.rs:190:9:190:10 | tv | -| variables.rs:201:26:201:27 | a6 | variables.rs:200:9:200:83 | a6 | -| variables.rs:207:11:207:16 | either | variables.rs:206:9:206:14 | either | -| variables.rs:209:16:209:17 | a7 | variables.rs:208:9:208:44 | a7 | -| variables.rs:210:26:210:27 | a7 | variables.rs:208:9:208:44 | a7 | -| variables.rs:218:11:218:16 | either | variables.rs:216:9:216:14 | either | -| variables.rs:222:23:222:25 | a11 | variables.rs:220:14:220:51 | a11 | -| variables.rs:224:15:224:15 | e | variables.rs:219:13:219:13 | e | -| variables.rs:225:28:225:30 | a12 | variables.rs:223:33:223:35 | a12 | -| variables.rs:241:11:241:12 | fv | variables.rs:240:9:240:10 | fv | -| variables.rs:243:26:243:28 | a13 | variables.rs:242:9:242:109 | a13 | -| variables.rs:253:15:253:16 | a8 | variables.rs:248:5:248:6 | a8 | -| variables.rs:254:15:254:16 | b3 | variables.rs:250:9:250:10 | b3 | -| variables.rs:255:15:255:16 | c1 | variables.rs:251:9:251:10 | c1 | -| variables.rs:261:15:261:16 | a9 | variables.rs:259:6:259:41 | a9 | -| variables.rs:270:15:270:17 | a10 | variables.rs:266:13:266:15 | a10 | -| variables.rs:271:15:271:16 | b4 | variables.rs:267:13:267:14 | b4 | -| variables.rs:272:15:272:16 | c2 | variables.rs:268:13:268:14 | c2 | -| variables.rs:279:9:279:11 | a10 | variables.rs:266:13:266:15 | a10 | -| variables.rs:280:9:280:10 | b4 | variables.rs:267:13:267:14 | b4 | -| variables.rs:281:9:281:10 | c2 | variables.rs:268:13:268:14 | c2 | -| variables.rs:283:15:283:17 | a10 | variables.rs:266:13:266:15 | a10 | -| variables.rs:284:15:284:16 | b4 | variables.rs:267:13:267:14 | b4 | -| variables.rs:285:15:285:16 | c2 | variables.rs:268:13:268:14 | c2 | -| variables.rs:292:23:292:25 | a10 | variables.rs:289:13:289:15 | a10 | -| variables.rs:293:23:293:24 | b4 | variables.rs:290:13:290:14 | b4 | -| variables.rs:297:15:297:17 | a10 | variables.rs:266:13:266:15 | a10 | -| variables.rs:298:15:298:16 | b4 | variables.rs:267:13:267:14 | b4 | -| variables.rs:304:9:304:9 | x | variables.rs:303:10:303:10 | x | -| variables.rs:306:9:306:23 | example_closure | variables.rs:302:9:302:23 | example_closure | -| variables.rs:307:15:307:16 | n1 | variables.rs:305:9:305:10 | n1 | -| variables.rs:312:9:312:9 | x | variables.rs:311:10:311:10 | x | -| variables.rs:314:9:314:26 | immutable_variable | variables.rs:310:9:310:26 | immutable_variable | -| variables.rs:315:15:315:16 | n2 | variables.rs:313:9:313:10 | n2 | -| variables.rs:322:12:322:12 | v | variables.rs:319:9:319:9 | v | -| variables.rs:323:19:323:22 | text | variables.rs:321:9:321:12 | text | +| variables.rs:13:15:13:16 | x1 | variables.rs:12:9:12:10 | x1 | +| variables.rs:18:15:18:16 | x2 | variables.rs:17:13:17:14 | x2 | +| variables.rs:20:15:20:16 | x2 | variables.rs:17:13:17:14 | x2 | +| variables.rs:25:15:25:16 | x3 | variables.rs:24:9:24:10 | x3 | +| variables.rs:27:9:27:10 | x3 | variables.rs:24:9:24:10 | x3 | +| variables.rs:28:15:28:16 | x3 | variables.rs:26:9:26:10 | x3 | +| variables.rs:33:15:33:16 | x4 | variables.rs:32:9:32:10 | x4 | +| variables.rs:36:19:36:20 | x4 | variables.rs:35:13:35:14 | x4 | +| variables.rs:38:15:38:16 | x4 | variables.rs:32:9:32:10 | x4 | +| variables.rs:57:15:57:16 | a1 | variables.rs:49:13:49:14 | a1 | +| variables.rs:58:15:58:16 | b1 | variables.rs:50:13:50:14 | b1 | +| variables.rs:59:15:59:15 | x | variables.rs:53:13:53:13 | x | +| variables.rs:60:15:60:15 | y | variables.rs:54:13:54:13 | y | +| variables.rs:68:9:68:10 | p1 | variables.rs:64:9:64:10 | p1 | +| variables.rs:69:15:69:16 | a2 | variables.rs:66:12:66:13 | a2 | +| variables.rs:70:15:70:16 | b2 | variables.rs:67:12:67:13 | b2 | +| variables.rs:77:11:77:12 | s1 | variables.rs:74:9:74:10 | s1 | +| variables.rs:78:19:78:20 | s2 | variables.rs:76:21:76:22 | s2 | +| variables.rs:87:15:87:16 | x5 | variables.rs:83:14:83:15 | x5 | +| variables.rs:94:11:94:12 | s1 | variables.rs:91:9:91:10 | s1 | +| variables.rs:95:19:95:20 | s2 | variables.rs:93:24:93:25 | s2 | +| variables.rs:103:11:103:12 | x6 | variables.rs:100:9:100:10 | x6 | +| variables.rs:108:23:108:24 | y1 | variables.rs:105:14:105:15 | y1 | +| variables.rs:113:15:113:16 | y1 | variables.rs:101:9:101:10 | y1 | +| variables.rs:119:11:119:17 | numbers | variables.rs:117:9:117:15 | numbers | +| variables.rs:125:23:125:27 | first | variables.rs:121:13:121:17 | first | +| variables.rs:126:23:126:27 | third | variables.rs:122:13:122:17 | third | +| variables.rs:127:23:127:27 | fifth | variables.rs:123:13:123:17 | fifth | +| variables.rs:131:11:131:17 | numbers | variables.rs:117:9:117:15 | numbers | +| variables.rs:137:23:137:27 | first | variables.rs:133:13:133:17 | first | +| variables.rs:138:23:138:26 | last | variables.rs:135:13:135:16 | last | +| variables.rs:146:11:146:12 | p2 | variables.rs:144:9:144:10 | p2 | +| variables.rs:149:24:149:25 | x7 | variables.rs:148:16:148:17 | x7 | +| variables.rs:160:11:160:13 | msg | variables.rs:158:9:158:11 | msg | +| variables.rs:163:24:163:34 | id_variable | variables.rs:162:17:162:27 | id_variable | +| variables.rs:168:23:168:24 | id | variables.rs:167:26:167:27 | id | +| variables.rs:179:11:179:16 | either | variables.rs:178:9:178:14 | either | +| variables.rs:181:26:181:27 | a3 | variables.rs:180:9:180:44 | a3 | +| variables.rs:193:11:193:12 | tv | variables.rs:192:9:192:10 | tv | +| variables.rs:195:26:195:27 | a4 | variables.rs:194:9:194:81 | a4 | +| variables.rs:197:11:197:12 | tv | variables.rs:192:9:192:10 | tv | +| variables.rs:199:26:199:27 | a5 | variables.rs:198:9:198:83 | a5 | +| variables.rs:201:11:201:12 | tv | variables.rs:192:9:192:10 | tv | +| variables.rs:203:26:203:27 | a6 | variables.rs:202:9:202:83 | a6 | +| variables.rs:209:11:209:16 | either | variables.rs:208:9:208:14 | either | +| variables.rs:211:16:211:17 | a7 | variables.rs:210:9:210:44 | a7 | +| variables.rs:212:26:212:27 | a7 | variables.rs:210:9:210:44 | a7 | +| variables.rs:220:11:220:16 | either | variables.rs:218:9:218:14 | either | +| variables.rs:224:23:224:25 | a11 | variables.rs:222:14:222:51 | a11 | +| variables.rs:226:15:226:15 | e | variables.rs:221:13:221:13 | e | +| variables.rs:227:28:227:30 | a12 | variables.rs:225:33:225:35 | a12 | +| variables.rs:243:11:243:12 | fv | variables.rs:242:9:242:10 | fv | +| variables.rs:245:26:245:28 | a13 | variables.rs:244:9:244:109 | a13 | +| variables.rs:255:15:255:16 | a8 | variables.rs:250:5:250:6 | a8 | +| variables.rs:256:15:256:16 | b3 | variables.rs:252:9:252:10 | b3 | +| variables.rs:257:15:257:16 | c1 | variables.rs:253:9:253:10 | c1 | +| variables.rs:263:15:263:16 | a9 | variables.rs:261:6:261:41 | a9 | +| variables.rs:272:15:272:17 | a10 | variables.rs:268:13:268:15 | a10 | +| variables.rs:273:15:273:16 | b4 | variables.rs:269:13:269:14 | b4 | +| variables.rs:274:15:274:16 | c2 | variables.rs:270:13:270:14 | c2 | +| variables.rs:281:9:281:11 | a10 | variables.rs:268:13:268:15 | a10 | +| variables.rs:282:9:282:10 | b4 | variables.rs:269:13:269:14 | b4 | +| variables.rs:283:9:283:10 | c2 | variables.rs:270:13:270:14 | c2 | +| variables.rs:285:15:285:17 | a10 | variables.rs:268:13:268:15 | a10 | +| variables.rs:286:15:286:16 | b4 | variables.rs:269:13:269:14 | b4 | +| variables.rs:287:15:287:16 | c2 | variables.rs:270:13:270:14 | c2 | +| variables.rs:294:23:294:25 | a10 | variables.rs:291:13:291:15 | a10 | +| variables.rs:295:23:295:24 | b4 | variables.rs:292:13:292:14 | b4 | +| variables.rs:299:15:299:17 | a10 | variables.rs:268:13:268:15 | a10 | +| variables.rs:300:15:300:16 | b4 | variables.rs:269:13:269:14 | b4 | +| variables.rs:306:9:306:9 | x | variables.rs:305:10:305:10 | x | +| variables.rs:308:9:308:23 | example_closure | variables.rs:304:9:304:23 | example_closure | +| variables.rs:309:15:309:16 | n1 | variables.rs:307:9:307:10 | n1 | +| variables.rs:314:9:314:9 | x | variables.rs:313:10:313:10 | x | +| variables.rs:316:9:316:26 | immutable_variable | variables.rs:312:9:312:26 | immutable_variable | +| variables.rs:317:15:317:16 | n2 | variables.rs:315:9:315:10 | n2 | +| variables.rs:324:12:324:12 | v | variables.rs:321:9:321:9 | v | +| variables.rs:325:19:325:22 | text | variables.rs:323:9:323:12 | text | +| variables.rs:331:5:331:5 | a | variables.rs:330:13:330:13 | a | +| variables.rs:332:15:332:15 | a | variables.rs:330:13:330:13 | a | +| variables.rs:333:11:333:11 | a | variables.rs:330:13:330:13 | a | +| variables.rs:334:15:334:15 | a | variables.rs:330:13:330:13 | a | +| variables.rs:340:14:340:14 | i | variables.rs:338:13:338:13 | i | +| variables.rs:342:15:342:15 | i | variables.rs:338:13:338:13 | i | +| variables.rs:347:10:347:10 | x | variables.rs:345:17:345:17 | x | +| variables.rs:348:10:348:10 | x | variables.rs:345:17:345:17 | x | +| variables.rs:353:23:353:23 | x | variables.rs:352:13:352:13 | x | +| variables.rs:354:15:354:15 | x | variables.rs:352:13:352:13 | x | variableInitializer -| variables.rs:10:9:10:10 | x1 | variables.rs:10:14:10:16 | "a" | -| variables.rs:15:13:15:14 | x2 | variables.rs:15:18:15:18 | 4 | -| variables.rs:22:9:22:10 | x3 | variables.rs:22:14:22:14 | 1 | -| variables.rs:24:9:24:10 | x3 | variables.rs:25:9:25:14 | ... + ... | -| variables.rs:30:9:30:10 | x4 | variables.rs:30:14:30:16 | "a" | -| variables.rs:33:13:33:14 | x4 | variables.rs:33:18:33:20 | "b" | -| variables.rs:62:9:62:10 | p1 | variables.rs:62:14:62:37 | RecordExpr | -| variables.rs:72:9:72:10 | s1 | variables.rs:72:14:72:41 | CallExpr | -| variables.rs:89:9:89:10 | s1 | variables.rs:89:14:89:41 | CallExpr | -| variables.rs:98:9:98:10 | x6 | variables.rs:98:14:98:20 | CallExpr | -| variables.rs:99:9:99:10 | y1 | variables.rs:99:14:99:15 | 10 | -| variables.rs:115:9:115:15 | numbers | variables.rs:115:19:115:35 | TupleExpr | -| variables.rs:142:9:142:10 | p2 | variables.rs:142:14:142:37 | RecordExpr | -| variables.rs:156:9:156:11 | msg | variables.rs:156:15:156:38 | RecordExpr | -| variables.rs:176:9:176:14 | either | variables.rs:176:18:176:33 | CallExpr | -| variables.rs:190:9:190:10 | tv | variables.rs:190:14:190:36 | CallExpr | -| variables.rs:206:9:206:14 | either | variables.rs:206:18:206:33 | CallExpr | -| variables.rs:216:9:216:14 | either | variables.rs:216:18:216:33 | CallExpr | -| variables.rs:240:9:240:10 | fv | variables.rs:240:14:240:35 | CallExpr | -| variables.rs:302:9:302:23 | example_closure | variables.rs:303:9:304:9 | ClosureExpr | -| variables.rs:305:9:305:10 | n1 | variables.rs:306:9:306:26 | CallExpr | -| variables.rs:310:9:310:26 | immutable_variable | variables.rs:311:9:312:9 | ClosureExpr | -| variables.rs:313:9:313:10 | n2 | variables.rs:314:9:314:29 | CallExpr | -| variables.rs:319:9:319:9 | v | variables.rs:319:13:319:41 | RefExpr | +| variables.rs:12:9:12:10 | x1 | variables.rs:12:14:12:16 | "a" | +| variables.rs:17:13:17:14 | x2 | variables.rs:17:18:17:18 | 4 | +| variables.rs:24:9:24:10 | x3 | variables.rs:24:14:24:14 | 1 | +| variables.rs:26:9:26:10 | x3 | variables.rs:27:9:27:14 | ... + ... | +| variables.rs:32:9:32:10 | x4 | variables.rs:32:14:32:16 | "a" | +| variables.rs:35:13:35:14 | x4 | variables.rs:35:18:35:20 | "b" | +| variables.rs:64:9:64:10 | p1 | variables.rs:64:14:64:37 | RecordExpr | +| variables.rs:74:9:74:10 | s1 | variables.rs:74:14:74:41 | CallExpr | +| variables.rs:91:9:91:10 | s1 | variables.rs:91:14:91:41 | CallExpr | +| variables.rs:100:9:100:10 | x6 | variables.rs:100:14:100:20 | CallExpr | +| variables.rs:101:9:101:10 | y1 | variables.rs:101:14:101:15 | 10 | +| variables.rs:117:9:117:15 | numbers | variables.rs:117:19:117:35 | TupleExpr | +| variables.rs:144:9:144:10 | p2 | variables.rs:144:14:144:37 | RecordExpr | +| variables.rs:158:9:158:11 | msg | variables.rs:158:15:158:38 | RecordExpr | +| variables.rs:178:9:178:14 | either | variables.rs:178:18:178:33 | CallExpr | +| variables.rs:192:9:192:10 | tv | variables.rs:192:14:192:36 | CallExpr | +| variables.rs:208:9:208:14 | either | variables.rs:208:18:208:33 | CallExpr | +| variables.rs:218:9:218:14 | either | variables.rs:218:18:218:33 | CallExpr | +| variables.rs:242:9:242:10 | fv | variables.rs:242:14:242:35 | CallExpr | +| variables.rs:304:9:304:23 | example_closure | variables.rs:305:9:306:9 | ClosureExpr | +| variables.rs:307:9:307:10 | n1 | variables.rs:308:9:308:26 | CallExpr | +| variables.rs:312:9:312:26 | immutable_variable | variables.rs:313:9:314:9 | ClosureExpr | +| variables.rs:315:9:315:10 | n2 | variables.rs:316:9:316:29 | CallExpr | +| variables.rs:321:9:321:9 | v | variables.rs:321:13:321:41 | RefExpr | +| variables.rs:330:13:330:13 | a | variables.rs:330:17:330:17 | 0 | +| variables.rs:338:13:338:13 | i | variables.rs:338:17:338:17 | 1 | +| variables.rs:339:9:339:13 | ref_i | variables.rs:340:9:340:14 | RefExpr | +| variables.rs:352:13:352:13 | x | variables.rs:352:17:352:17 | 2 | diff --git a/rust/ql/test/library-tests/variables/variables.ql b/rust/ql/test/library-tests/variables/variables.ql index dcca73d5cf28..9657c361fd59 100644 --- a/rust/ql/test/library-tests/variables/variables.ql +++ b/rust/ql/test/library-tests/variables/variables.ql @@ -12,7 +12,7 @@ query predicate variableReadAccess(VariableReadAccess va, Variable v) { v = va.g query predicate variableInitializer(Variable v, Expr e) { e = v.getInitializer() } module VariableAccessTest implements TestSig { - string getARelevantTag() { result = "access" } + string getARelevantTag() { result = ["", "write_", "read_"] + "access" } private predicate declAt(Variable v, string filepath, int line) { v.getLocation().hasLocationInfo(filepath, _, _, line, _) @@ -38,8 +38,15 @@ module VariableAccessTest implements TestSig { exists(VariableAccess va | location = va.getLocation() and element = va.toString() and - tag = "access" and decl(va.getVariable(), value) + | + va instanceof VariableWriteAccess and tag = "write_access" + or + va instanceof VariableReadAccess and tag = "read_access" + or + not va instanceof VariableWriteAccess and + not va instanceof VariableReadAccess and + tag = "access" ) } } diff --git a/rust/ql/test/library-tests/variables/variables.rs b/rust/ql/test/library-tests/variables/variables.rs index 85fa052a7aa2..52c5288a6b32 100644 --- a/rust/ql/test/library-tests/variables/variables.rs +++ b/rust/ql/test/library-tests/variables/variables.rs @@ -1,3 +1,5 @@ +use std::ops::AddAssign; + fn print_str(s: &str) { println!("{}", s); } @@ -8,32 +10,32 @@ fn print_i64(i: i64) { fn immutable_variable() { let x1 = "a"; // x1 - print_str(x1); // $ access=x1 + print_str(x1); // $ read_access=x1 } fn mutable_variable() { let mut x2 = 4; // x2 - print_i64(x2); // $ access=x2 - x2 = 5; // $ access=x2 - print_i64(x2); // $ access=x2 + print_i64(x2); // $ read_access=x2 + x2 = 5; // $ write_access=x2 + print_i64(x2); // $ read_access=x2 } fn variable_shadow1() { let x3 = 1; // x3_1 - print_i64(x3); // $ access=x3_1 + print_i64(x3); // $ read_access=x3_1 let x3 = // x3_2 - x3 + 1; // $ access=x3_1 - print_i64(x3); // $ access=x3_2 + x3 + 1; // $ read_access=x3_1 + print_i64(x3); // $ read_access=x3_2 } fn variable_shadow2() { let x4 = "a"; // x4_1 - print_str(x4); // $ access=x4_1 + print_str(x4); // $ read_access=x4_1 { let x4 = "b"; // x4_2 - print_str(x4); // $ access=x4_2 + print_str(x4); // $ read_access=x4_2 } - print_str(x4); // $ access=x4_1 + print_str(x4); // $ read_access=x4_1 } struct Point<'a> { @@ -52,10 +54,10 @@ fn let_pattern1() { y, // y }, ) = (("a", "b"), Point { x: "x", y: "y" }); - print_str(a1); // $ access=a1 - print_str(b1); // $ access=b1 - print_str(x); // $ access=x - print_str(y); // $ access=y + print_str(a1); // $ read_access=a1 + print_str(b1); // $ read_access=b1 + print_str(x); // $ read_access=x + print_str(y); // $ read_access=y } fn let_pattern2() { @@ -63,34 +65,34 @@ fn let_pattern2() { let Point { x: a2, // a2 y: b2, // b2 - } = p1; // $ access=p1 - print_str(a2); // $ access=a2 - print_str(b2); // $ access=b2 + } = p1; // $ read_access=p1 + print_str(a2); // $ read_access=a2 + print_str(b2); // $ read_access=b2 } fn let_pattern3() { let s1 = Some(String::from("Hello!")); // s1 if let Some(ref s2) // s2 - = s1 { // $ access=s1 - print_str(s2); // $ access=s2 + = s1 { // $ read_access=s1 + print_str(s2); // $ read_access=s2 } } fn let_pattern4() { - let Some(x5): Option<&str> = Some("x5") else { - // x5 - todo!() - }; - print_str(x5); // $ access=x5 + let Some(x5): Option<&str> = Some("x5") // x5 + else { + todo!() + }; + print_str(x5); // $ read_access=x5 } fn let_pattern5() { let s1 = Some(String::from("Hello!")); // s1 while let Some(ref s2) // s2 - = s1 { // $ access=s1 - print_str(s2); // $ access=s2 + = s1 { // $ read_access=s1 + print_str(s2); // $ read_access=s2 } } @@ -98,42 +100,42 @@ fn match_pattern1() { let x6 = Some(5); // x6 let y1 = 10; // y1_1 - match x6 { // $ access=x6 + match x6 { // $ read_access=x6 Some(50) => print_str("Got 50"), Some(y1) // y1_2 => { - print_i64(y1)// $ access=y1_2 + print_i64(y1)// $ read_access=y1_2 } None => print_str("NONE"), } - print_i64(y1); // $ access=y1_1 + print_i64(y1); // $ read_access=y1_1 } fn match_pattern2() { let numbers = (2, 4, 8, 16, 32); // numbers - match numbers { // $ access=numbers + match numbers { // $ read_access=numbers ( first, _, // first third, _, // third fifth // fifth ) => { - print_i64(first); // $ access=first - print_i64(third); // $ access=third - print_i64(fifth); // $ access=fifth + print_i64(first); // $ read_access=first + print_i64(third); // $ read_access=third + print_i64(fifth); // $ read_access=fifth } } - match numbers { // $ access=numbers + match numbers { // $ read_access=numbers ( first, // first .., last // last ) => { - print_i64(first); // $ access=first - print_i64(last); // $ access=last + print_i64(first); // $ read_access=first + print_i64(last); // $ read_access=last } } } @@ -141,10 +143,10 @@ fn match_pattern2() { fn match_pattern3() { let p2 = Point { x: "x", y: "y" }; // p2 - match p2 { // $ access=p2 + match p2 { // $ read_access=p2 Point { x: x7, .. // x7 - } => print_str(x7), // $ access=x7 + } => print_str(x7), // $ read_access=x7 } } @@ -155,15 +157,15 @@ enum Message { fn match_pattern4() { let msg = Message::Hello { id: 0 }; // msg - match msg { // $ access=msg + match msg { // $ read_access=msg Message::Hello { id: id_variable @ 3..=7, // id_variable - } => print_i64(id_variable), // $ access=id_variable + } => print_i64(id_variable), // $ read_access=id_variable Message::Hello { id: 10..=12 } => { println!("Found an id in another range") } Message::Hello { id } => // id - print_i64(id), // $ access=id + print_i64(id), // $ read_access=id } } @@ -174,9 +176,9 @@ enum Either { fn match_pattern5() { let either = Either::Left(32); // either - match either { // $ access=either + match either { // $ read_access=either Either::Left(a3) | Either::Right(a3) // a3 - => print_i64(a3), // $ access=a3 + => print_i64(a3), // $ read_access=a3 } } @@ -188,26 +190,26 @@ enum ThreeValued { fn match_pattern6() { let tv = ThreeValued::Second(62); // tv - match tv { // $ access=tv + match tv { // $ read_access=tv ThreeValued::First(a4) | ThreeValued::Second(a4) | ThreeValued::Third(a4) // a4 - => print_i64(a4), // $ access=a4 + => print_i64(a4), // $ read_access=a4 } - match tv { // $ access=tv + match tv { // $ read_access=tv (ThreeValued::First(a5) | ThreeValued::Second(a5)) | ThreeValued::Third(a5) // a5 - => print_i64(a5), // $ access=a5 + => print_i64(a5), // $ read_access=a5 } - match tv { // $ access=tv + match tv { // $ read_access=tv ThreeValued::First(a6) | (ThreeValued::Second(a6) | ThreeValued::Third(a6)) // a6 - => print_i64(a6), // $ access=a6 + => print_i64(a6), // $ read_access=a6 } } fn match_pattern7() { let either = Either::Left(32); // either - match either { // $ access=either + match either { // $ read_access=either Either::Left(a7) | Either::Right(a7) // a7 - if a7 > 0 // $ access=a7 - => print_i64(a7), // $ access=a7 + if a7 > 0 // $ read_access=a7 + => print_i64(a7), // $ read_access=a7 _ => (), } } @@ -215,14 +217,14 @@ fn match_pattern7() { fn match_pattern8() { let either = Either::Left(32); // either - match either { // $ access=either + match either { // $ read_access=either ref e @ // e (Either::Left(a11) | Either::Right(a11)) // a11 => { - print_i64(a11); // $ access=a11 + print_i64(a11); // $ read_access=a11 if let Either::Left(a12) // a12 - = e { // $ access=e - print_i64(*a12); // $ access=a12 + = e { // $ read_access=e + print_i64(*a12); // $ read_access=a12 } } _ => (), @@ -238,9 +240,9 @@ enum FourValued { fn match_pattern9() { let fv = FourValued::Second(62); // tv - match fv { // $ access=tv + match fv { // $ read_access=tv FourValued::First(a13) | (FourValued::Second(a13) | FourValued::Third(a13)) | FourValued::Fourth(a13) // a13 - => print_i64(a13), // $ access=a13 + => print_i64(a13), // $ read_access=a13 } } @@ -250,15 +252,15 @@ fn param_pattern1( b3, // b3 c1, // c1 ): (&str, &str)) -> () { - print_str(a8); // $ access=a8 - print_str(b3); // $ access=b3 - print_str(c1); // $ access=c1 + print_str(a8); // $ read_access=a8 + print_str(b3); // $ read_access=b3 + print_str(c1); // $ read_access=c1 } fn param_pattern2( (Either::Left(a9) | Either::Right(a9)): Either // a9 ) -> () { - print_i64(a9); // $ access=a9 + print_i64(a9); // $ read_access=a9 } fn destruct_assignment() { @@ -267,63 +269,91 @@ fn destruct_assignment() { mut b4, // b4 mut c2 // c2 ) = (1, 2, 3); - print_i64(a10); // $ access=a10 - print_i64(b4); // $ access=b4 - print_i64(c2); // $ access=c2 + print_i64(a10); // $ read_access=a10 + print_i64(b4); // $ read_access=b4 + print_i64(c2); // $ read_access=c2 ( - c2, // $ access=c2 - b4, // $ access=b4 - a10 // $ access=a10 + c2, // $ write_access=c2 + b4, // $ write_access=b4 + a10 // $ write_access=a10 ) = ( - a10, // $ access=a10 - b4, // $ access=b4 - c2 // $ access=c2 + a10, // $ read_access=a10 + b4, // $ read_access=b4 + c2 // $ read_access=c2 ); - print_i64(a10); // $ access=a10 - print_i64(b4); // $ access=b4 - print_i64(c2); // $ access=c2 + print_i64(a10); // $ read_access=a10 + print_i64(b4); // $ read_access=b4 + print_i64(c2); // $ read_access=c2 match (4, 5) { ( a10, // a10_2 b4 // b4 ) => { - print_i64(a10); // $ access=a10_2 - print_i64(b4); // $ access=b4 + print_i64(a10); // $ read_access=a10_2 + print_i64(b4); // $ read_access=b4 } } - print_i64(a10); // $ access=a10 - print_i64(b4); // $ access=b4 + print_i64(a10); // $ read_access=a10 + print_i64(b4); // $ read_access=b4 } fn closure_variable() { let example_closure = // example_closure |x: i64| // x_1 - x; // $ access=x_1 + x; // $ read_access=x_1 let n1 = // n1 - example_closure(5); // $ access=example_closure - print_i64(n1); // $ access=n1 + example_closure(5); // $ read_access=example_closure + print_i64(n1); // $ read_access=n1 immutable_variable(); let immutable_variable = |x: i64| // x_2 - x; // $ access=x_2 + x; // $ read_access=x_2 let n2 = // n2 - immutable_variable(6); // $ access=immutable_variable - print_i64(n2); // $ access=n2 + immutable_variable(6); // $ read_access=immutable_variable + print_i64(n2); // $ read_access=n2 } fn for_variable() { let v = &["apples", "cake", "coffee"]; // v for text // text - in v { // $ access=v - print_str(text); // $ access=text + in v { // $ read_access=v + print_str(text); // $ read_access=text } } +fn add_assign() { + let mut a = 0; // a + a += 1; // $ access=a + print_i64(a); // $ read_access=a + (&mut a).add_assign(10); // $ access=a + print_i64(a); // $ read_access=a +} + +fn mutate() { + let mut i = 1; // i + let ref_i = // ref_i + &mut i; // $ access=i + *ref_i = 2; // $ read_access=ref_i + print_i64(i); // $ read_access=i +} + +fn mutate_param(x : &mut i64) { // x + *x = // $ read_access=x + *x + // $ read_access=x + *x; // $ read_access=x +} + +fn mutate_arg() { + let mut x = 2; // x + mutate_param(&mut x); // $ access=x + print_i64(x); // $ read_access=x +} + fn main() { immutable_variable(); mutable_variable(); @@ -347,4 +377,7 @@ fn main() { destruct_assignment(); closure_variable(); for_variable(); + add_assign(); + mutate(); + mutate_arg(); } From a9cf33ce185aa585936fec173f48275cd188f602 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 3 Oct 2024 13:33:22 +0200 Subject: [PATCH 160/347] Rust: `&x` is neither a read nor a write --- .../rust/elements/AssignmentOperation.qll | 49 +++++++++++++++++++ .../rust/elements/internal/VariableImpl.qll | 25 ++++------ rust/ql/lib/rust.qll | 1 + .../variables/variables.expected | 22 +-------- 4 files changed, 61 insertions(+), 36 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/elements/AssignmentOperation.qll diff --git a/rust/ql/lib/codeql/rust/elements/AssignmentOperation.qll b/rust/ql/lib/codeql/rust/elements/AssignmentOperation.qll new file mode 100644 index 000000000000..be7b2c82cf47 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/AssignmentOperation.qll @@ -0,0 +1,49 @@ +/** Provides classes for assignment operations. */ + +private import rust +private import codeql.rust.elements.internal.BinaryExprImpl + +/** An assignment operation. */ +abstract private class AssignmentOperationImpl extends Impl::BinaryExpr { } + +final class AssignmentOperation = AssignmentOperationImpl; + +/** + * An assignment expression, for example + * + * ```rust + * x = y; + * ``` + */ +final class AssignmentExpr extends AssignmentOperationImpl { + AssignmentExpr() { this.getOperatorName() = "=" } + + override string getAPrimaryQlClass() { result = "AssignmentExpr" } +} + +/** + * A compound assignment expression, for example + * + * ```rust + * x += y; + * ``` + * + * Note that compound assignment expressions are syntatic sugar for + * trait invocations, i.e., the above actually means + * + * ```rust + * (&mut x).add_assign(y); + * ``` + */ +final class CompoundAssignmentExpr extends AssignmentOperationImpl { + private string operator; + + CompoundAssignmentExpr() { this.getOperatorName().regexpCapture("(.)=", 1) = operator } + + /** + * Gets the operator of this compound assignment expression. + */ + string getOperator() { result = operator } + + override string getAPrimaryQlClass() { result = "CompoundAssignmentExpr" } +} diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index 7a77c45fe2ae..b9e9bb7cb48a 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -395,34 +395,27 @@ module Impl { } /** Holds if `e` occurs in the LHS of an assignment or compound assignment. */ - private predicate assignLhs(Expr e, boolean compound) { - exists(BinaryExpr be, string op | - op = be.getOperatorName().regexpCapture("(.*)=", 1) and - e = be.getLhs() - | - op = "" and compound = false - or - op != "" and compound = true - ) + private predicate assignmentExprDescendant(Expr e) { + e = any(AssignmentExpr ae).getLhs() or exists(Expr mid | - assignLhs(mid, compound) and - getImmediateParent(e) = mid + assignmentExprDescendant(mid) and + getImmediateParent(e) = mid and + not mid.(PrefixExpr).getOperatorName() = "*" ) } /** A variable write. */ class VariableWriteAccess extends VariableAccess { - VariableWriteAccess() { assignLhs(this, _) } + VariableWriteAccess() { assignmentExprDescendant(this) } } /** A variable read. */ class VariableReadAccess extends VariableAccess { VariableReadAccess() { - not this instanceof VariableWriteAccess - or - // consider LHS in compound assignments both reads and writes - assignLhs(this, true) + not this instanceof VariableWriteAccess and + not this = any(RefExpr re).getExpr() and + not this = any(CompoundAssignmentExpr cae).getLhs() } } diff --git a/rust/ql/lib/rust.qll b/rust/ql/lib/rust.qll index 7723400c41b6..58425b6490e8 100644 --- a/rust/ql/lib/rust.qll +++ b/rust/ql/lib/rust.qll @@ -3,5 +3,6 @@ import codeql.rust.elements import codeql.Locations import codeql.files.FileSystem +import codeql.rust.elements.AssignmentOperation import codeql.rust.elements.LogicalOperation import codeql.rust.elements.Variable diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index 807fc9ff8919..ccc1cd6072be 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -1,17 +1,4 @@ testFailures -| variables.rs:331:5:331:5 | a | Unexpected result: read_access=a | -| variables.rs:331:5:331:5 | a | Unexpected result: write_access=a | -| variables.rs:331:13:331:25 | Comment | Missing result:access=a | -| variables.rs:333:11:333:11 | a | Unexpected result: read_access=a | -| variables.rs:333:30:333:42 | Comment | Missing result:access=a | -| variables.rs:340:14:340:14 | i | Unexpected result: read_access=i | -| variables.rs:340:17:340:29 | Comment | Missing result:access=i | -| variables.rs:341:6:341:10 | ref_i | Unexpected result: write_access=ref_i | -| variables.rs:341:17:341:38 | Comment | Missing result:read_access=ref_i | -| variables.rs:346:6:346:6 | x | Unexpected result: write_access=x | -| variables.rs:346:10:346:27 | Comment | Missing result:read_access=x | -| variables.rs:353:23:353:23 | x | Unexpected result: read_access=x | -| variables.rs:353:27:353:39 | Comment | Missing result:access=x | failures variable | variables.rs:3:14:3:14 | s | @@ -185,9 +172,6 @@ variableWriteAccess | variables.rs:277:9:277:10 | c2 | variables.rs:270:13:270:14 | c2 | | variables.rs:278:9:278:10 | b4 | variables.rs:269:13:269:14 | b4 | | variables.rs:279:9:279:11 | a10 | variables.rs:268:13:268:15 | a10 | -| variables.rs:331:5:331:5 | a | variables.rs:330:13:330:13 | a | -| variables.rs:341:6:341:10 | ref_i | variables.rs:339:9:339:13 | ref_i | -| variables.rs:346:6:346:6 | x | variables.rs:345:17:345:17 | x | variableReadAccess | variables.rs:13:15:13:16 | x1 | variables.rs:12:9:12:10 | x1 | | variables.rs:18:15:18:16 | x2 | variables.rs:17:13:17:14 | x2 | @@ -267,15 +251,13 @@ variableReadAccess | variables.rs:317:15:317:16 | n2 | variables.rs:315:9:315:10 | n2 | | variables.rs:324:12:324:12 | v | variables.rs:321:9:321:9 | v | | variables.rs:325:19:325:22 | text | variables.rs:323:9:323:12 | text | -| variables.rs:331:5:331:5 | a | variables.rs:330:13:330:13 | a | | variables.rs:332:15:332:15 | a | variables.rs:330:13:330:13 | a | -| variables.rs:333:11:333:11 | a | variables.rs:330:13:330:13 | a | | variables.rs:334:15:334:15 | a | variables.rs:330:13:330:13 | a | -| variables.rs:340:14:340:14 | i | variables.rs:338:13:338:13 | i | +| variables.rs:341:6:341:10 | ref_i | variables.rs:339:9:339:13 | ref_i | | variables.rs:342:15:342:15 | i | variables.rs:338:13:338:13 | i | +| variables.rs:346:6:346:6 | x | variables.rs:345:17:345:17 | x | | variables.rs:347:10:347:10 | x | variables.rs:345:17:345:17 | x | | variables.rs:348:10:348:10 | x | variables.rs:345:17:345:17 | x | -| variables.rs:353:23:353:23 | x | variables.rs:352:13:352:13 | x | | variables.rs:354:15:354:15 | x | variables.rs:352:13:352:13 | x | variableInitializer | variables.rs:12:9:12:10 | x1 | variables.rs:12:14:12:16 | "a" | From aa5e0c39ba23a26eadf51bbfa2f0e11c63052995 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Oct 2024 14:52:32 +0200 Subject: [PATCH 161/347] Rust: Implement `ConditionalCompletionSplitting` --- rust/ql/consistency-queries/CfgConsistency.ql | 2 - .../rust/controlflow/internal/Completion.qll | 29 ++-- .../internal/ControlFlowGraphImpl.qll | 63 ++++---- .../rust/controlflow/internal/Splitting.qll | 108 ++++++++++++- .../library-tests/controlflow/Cfg.expected | 149 ++++++++++-------- 5 files changed, 225 insertions(+), 126 deletions(-) diff --git a/rust/ql/consistency-queries/CfgConsistency.ql b/rust/ql/consistency-queries/CfgConsistency.ql index 6964b7bbcb18..3a95fde507b4 100644 --- a/rust/ql/consistency-queries/CfgConsistency.ql +++ b/rust/ql/consistency-queries/CfgConsistency.ql @@ -12,8 +12,6 @@ query predicate nonPostOrderExpr(Expr e, string cls) { cls = e.getPrimaryQlClasses() and not e instanceof LetExpr and not e instanceof ParenExpr and - not e instanceof LogicalAndExpr and // todo - not e instanceof LogicalOrExpr and exists(AstNode last, Completion c | CfgImpl::last(e, last, c) and last != e and diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll index 15619f06a2fe..fc427ce32f88 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll @@ -63,10 +63,8 @@ abstract class ConditionalCompletion extends NormalCompletion { } /** Holds if node `n` has the Boolean constant value `value`. */ -private predicate isBooleanConstant(AstNode n, Boolean value) { - n.(LiteralExpr).getTextValue() = value.toString() - or - isBooleanConstant(n.(ParenExpr).getExpr(), value) +private predicate isBooleanConstant(LiteralExpr le, Boolean value) { + le.getTextValue() = value.toString() } /** @@ -83,29 +81,22 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion { or any(MatchGuard guard).getCondition() = e or - exists(BinaryExpr expr | - expr.getOperatorName() = ["&&", "||"] and - e = expr.getLhs() - ) + e = any(BinaryLogicalOperation blo).getLhs() or exists(Expr parent | this.isValidForSpecific0(parent) | e = parent.(ParenExpr).getExpr() or - parent = - any(PrefixExpr expr | - expr.getOperatorName() = "!" and - e = expr.getExpr() - ) + e = parent.(LogicalNotExpr).getExpr() or - parent = - any(BinaryExpr expr | - expr.getOperatorName() = ["&&", "||"] and - e = expr.getRhs() - ) + e = parent.(BinaryLogicalOperation).getRhs() or parent = any(IfExpr ie | e = [ie.getThen(), ie.getElse()]) or - parent = any(BlockExpr be | e = be.getStmtList().getTailExpr()) + e = parent.(MatchExpr).getAnArm().getExpr() + or + e = parent.(BlockExpr).getStmtList().getTailExpr() + or + e = any(BreakExpr be | be.getTarget() = parent).getExpr() ) } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 17add12b9404..6ade39203c96 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -44,9 +44,6 @@ private module CfgInput implements InputSig { /** Hold if `t` represents a conditional successor type. */ predicate successorTypeIsCondition(SuccessorType t) { t instanceof Cfg::BooleanSuccessor } - /** Gets the maximum number of splits allowed for a given node. */ - int maxSplits() { result = 0 } - /** Holds if `first` is first executed when entering `scope`. */ predicate scopeFirst(CfgScope scope, AstNode first) { scope.scopeFirst(first) } @@ -86,53 +83,49 @@ class BinaryOpExprTree extends StandardPostOrderTree instanceof BinaryExpr { } } -class LogicalOrBinaryOpExprTree extends PreOrderTree, LogicalOrExpr { +class LogicalOrTree extends PostOrderTree, LogicalOrExpr { final override predicate propagatesAbnormal(AstNode child) { child = this.getAnOperand() } + override predicate first(AstNode node) { first(this.getLhs(), node) } + override predicate succ(AstNode pred, AstNode succ, Completion c) { - // Edge to the first node in the lhs - pred = this and - first(this.getLhs(), succ) and - completionIsSimple(c) + // Edge from lhs to rhs + last(this.getLhs(), pred, c) and + c.(BooleanCompletion).failed() and + first(this.getRhs(), succ) or - // Edge from the last node in the lhs to the first node in the rhs + // Edge from lhs to this last(this.getLhs(), pred, c) and - first(this.getRhs(), succ) and - c.(BooleanCompletion).failed() - } - - override predicate last(AstNode node, Completion c) { - // Lhs. as the last node - last(this.getLhs(), node, c) and - c.(BooleanCompletion).succeeded() + c.(BooleanCompletion).succeeded() and + succ = this or - // Rhs. as the last node - last(this.getRhs(), node, c) + // Edge from rhs to this + last(this.getRhs(), pred, c) and + succ = this and + completionIsNormal(c) } } -class LogicalAndBinaryOpExprTree extends PreOrderTree, LogicalAndExpr { +class LogicalAndTree extends PostOrderTree, LogicalAndExpr { final override predicate propagatesAbnormal(AstNode child) { child = this.getAnOperand() } + override predicate first(AstNode node) { first(this.getLhs(), node) } + override predicate succ(AstNode pred, AstNode succ, Completion c) { - // Edge to the first node in the lhs - pred = this and - first(this.getLhs(), succ) and - completionIsSimple(c) + // Edge from lhs to rhs + last(this.getLhs(), pred, c) and + c.(BooleanCompletion).succeeded() and + first(this.getRhs(), succ) or - // Edge from the last node in the lhs to the first node in the rhs + // Edge from lhs to this last(this.getLhs(), pred, c) and - first(this.getRhs(), succ) and - c.(BooleanCompletion).succeeded() - } - - override predicate last(AstNode node, Completion c) { - // Lhs. as the last node - last(this.getLhs(), node, c) and - c.(BooleanCompletion).failed() + c.(BooleanCompletion).failed() and + succ = this or - // Rhs. as the last node - last(this.getRhs(), node, c) + // Edge from rhs to this + last(this.getRhs(), pred, c) and + succ = this and + completionIsNormal(c) } } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Splitting.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Splitting.qll index b4f0a060be6d..10965649caa5 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/Splitting.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/Splitting.qll @@ -1,17 +1,115 @@ +private import rust +private import ControlFlowGraphImpl +private import Scope + cached private module Cached { - // Not using CFG splitting, so the following are just placeholder types. cached - newtype TSplitKind = TSplitKindUnit() + newtype TSplitKind = TConditionalCompletionSplitKind() cached - newtype TSplit = TSplitUnit() + newtype TSplit = TConditionalCompletionSplit(ConditionalCompletion c) } import Cached /** A split for a control flow node. */ -class Split extends TSplit { +abstract private class Split_ extends TSplit { /** Gets a textual representation of this split. */ - string toString() { none() } + abstract string toString(); +} + +final class Split = Split_; + +private module ConditionalCompletionSplitting { + /** + * A split for conditional completions. For example, in + * + * ```rust + * if x && !y { + * // ... + * } + * ``` + * + * we record whether `x`, `y`, and `!y` evaluate to `true` or `false`, and restrict + * the edges out of `!y` and `x && !y` accordingly. + */ + class ConditionalCompletionSplit extends Split_, TConditionalCompletionSplit { + ConditionalCompletion completion; + + ConditionalCompletionSplit() { this = TConditionalCompletionSplit(completion) } + + override string toString() { result = completion.toString() } + } + + private class ConditionalCompletionSplitKind extends SplitKind, TConditionalCompletionSplitKind { + override int getListOrder() { result = 0 } + + override predicate isEnabled(AstNode cfe) { this.appliesTo(cfe) } + + override string toString() { result = "ConditionalCompletion" } + } + + private class ConditionalCompletionSplitImpl extends SplitImpl instanceof ConditionalCompletionSplit + { + ConditionalCompletion completion; + + ConditionalCompletionSplitImpl() { this = TConditionalCompletionSplit(completion) } + + override ConditionalCompletionSplitKind getKind() { any() } + + override predicate hasEntry(AstNode pred, AstNode succ, Completion c) { + succ(pred, succ, c) and + last(succ, _, completion) and + ( + last(succ.(LogicalNotExpr).getExpr(), pred, c) and + completion.(BooleanCompletion).getDual() = c + or + last(succ.(BinaryLogicalOperation).getAnOperand(), pred, c) and + completion = c + or + succ = + any(IfExpr ie | + last([ie.getThen(), ie.getElse()], pred, c) and + completion = c + ) + or + last(succ.(MatchExpr).getAnArm().getExpr(), pred, c) and + completion = c + or + last(succ.(BlockExpr).getStmtList().getTailExpr(), pred, c) and + completion = c + ) + or + succ(pred, succ, c) and + last(succ.(BreakExpr).getExpr(), pred, c) and + exists(AstNode target | + succ(succ, target, _) and + last(target, _, completion) + ) and + completion = c + } + + override predicate hasEntryScope(CfgScope scope, AstNode first) { none() } + + override predicate hasExit(AstNode pred, AstNode succ, Completion c) { + this.appliesTo(pred) and + succ(pred, succ, c) and + if c instanceof ConditionalCompletion + then completion = c + else not this.hasSuccessor(pred, succ, c) + } + + override predicate hasExitScope(CfgScope scope, AstNode last, Completion c) { + this.appliesTo(last) and + scope.scopeLast(last, c) and + if c instanceof ConditionalCompletion then completion = c else any() + } + + override predicate hasSuccessor(AstNode pred, AstNode succ, Completion c) { + this.appliesTo(pred) and + succ(pred, succ, c) and + not c instanceof ConditionalCompletion + } + } } diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 39fc6b96b621..61b71f15118d 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -234,20 +234,24 @@ edges | test.rs:128:5:134:5 | exit test_nested_if (normal) | test.rs:128:5:134:5 | exit test_nested_if | | | test.rs:128:38:134:5 | BlockExpr | test.rs:128:5:134:5 | exit test_nested_if (normal) | | | test.rs:129:9:133:9 | IfExpr | test.rs:128:38:134:5 | BlockExpr | | -| test.rs:129:13:129:48 | IfExpr | test.rs:130:13:130:13 | 1 | true | -| test.rs:129:13:129:48 | IfExpr | test.rs:132:13:132:13 | 0 | false | +| test.rs:129:13:129:48 | [boolean(false)] IfExpr | test.rs:132:13:132:13 | 0 | false | +| test.rs:129:13:129:48 | [boolean(true)] IfExpr | test.rs:130:13:130:13 | 1 | true | | test.rs:129:16:129:16 | PathExpr | test.rs:129:20:129:20 | 0 | | | test.rs:129:16:129:20 | ... < ... | test.rs:129:24:129:24 | a | true | | test.rs:129:16:129:20 | ... < ... | test.rs:129:41:129:41 | a | false | | test.rs:129:20:129:20 | 0 | test.rs:129:16:129:20 | ... < ... | | -| test.rs:129:22:129:32 | BlockExpr | test.rs:129:13:129:48 | IfExpr | false, true | +| test.rs:129:22:129:32 | [boolean(false)] BlockExpr | test.rs:129:13:129:48 | [boolean(false)] IfExpr | false | +| test.rs:129:22:129:32 | [boolean(true)] BlockExpr | test.rs:129:13:129:48 | [boolean(true)] IfExpr | true | | test.rs:129:24:129:24 | a | test.rs:129:29:129:30 | 10 | | -| test.rs:129:24:129:30 | ... < ... | test.rs:129:22:129:32 | BlockExpr | false, true | +| test.rs:129:24:129:30 | ... < ... | test.rs:129:22:129:32 | [boolean(false)] BlockExpr | false | +| test.rs:129:24:129:30 | ... < ... | test.rs:129:22:129:32 | [boolean(true)] BlockExpr | true | | test.rs:129:28:129:30 | - ... | test.rs:129:24:129:30 | ... < ... | | | test.rs:129:29:129:30 | 10 | test.rs:129:28:129:30 | - ... | | -| test.rs:129:39:129:48 | BlockExpr | test.rs:129:13:129:48 | IfExpr | false, true | +| test.rs:129:39:129:48 | [boolean(false)] BlockExpr | test.rs:129:13:129:48 | [boolean(false)] IfExpr | false | +| test.rs:129:39:129:48 | [boolean(true)] BlockExpr | test.rs:129:13:129:48 | [boolean(true)] IfExpr | true | | test.rs:129:41:129:41 | a | test.rs:129:45:129:46 | 10 | | -| test.rs:129:41:129:46 | ... > ... | test.rs:129:39:129:48 | BlockExpr | false, true | +| test.rs:129:41:129:46 | ... > ... | test.rs:129:39:129:48 | [boolean(false)] BlockExpr | false | +| test.rs:129:41:129:46 | ... > ... | test.rs:129:39:129:48 | [boolean(true)] BlockExpr | true | | test.rs:129:45:129:46 | 10 | test.rs:129:41:129:46 | ... > ... | | | test.rs:129:51:131:9 | BlockExpr | test.rs:129:9:133:9 | IfExpr | | | test.rs:130:13:130:13 | 1 | test.rs:129:51:131:9 | BlockExpr | | @@ -257,14 +261,14 @@ edges | test.rs:136:5:145:5 | exit test_nested_if_match (normal) | test.rs:136:5:145:5 | exit test_nested_if_match | | | test.rs:136:44:145:5 | BlockExpr | test.rs:136:5:145:5 | exit test_nested_if_match (normal) | | | test.rs:137:9:144:9 | IfExpr | test.rs:136:44:145:5 | BlockExpr | | -| test.rs:137:13:140:9 | MatchExpr | test.rs:141:13:141:13 | 1 | true | -| test.rs:137:13:140:9 | MatchExpr | test.rs:143:13:143:13 | 0 | false | +| test.rs:137:13:140:9 | [boolean(false)] MatchExpr | test.rs:143:13:143:13 | 0 | false | +| test.rs:137:13:140:9 | [boolean(true)] MatchExpr | test.rs:141:13:141:13 | 1 | true | | test.rs:137:19:137:19 | a | test.rs:138:13:138:13 | LiteralPat | | | test.rs:138:13:138:13 | LiteralPat | test.rs:138:18:138:21 | true | match | | test.rs:138:13:138:13 | LiteralPat | test.rs:139:13:139:13 | WildcardPat | no-match | -| test.rs:138:18:138:21 | true | test.rs:137:13:140:9 | MatchExpr | | +| test.rs:138:18:138:21 | true | test.rs:137:13:140:9 | [boolean(true)] MatchExpr | true | | test.rs:139:13:139:13 | WildcardPat | test.rs:139:18:139:22 | false | match | -| test.rs:139:18:139:22 | false | test.rs:137:13:140:9 | MatchExpr | | +| test.rs:139:18:139:22 | false | test.rs:137:13:140:9 | [boolean(false)] MatchExpr | false | | test.rs:140:12:142:9 | BlockExpr | test.rs:137:9:144:9 | IfExpr | | | test.rs:141:13:141:13 | 1 | test.rs:140:12:142:9 | BlockExpr | | | test.rs:142:16:144:9 | BlockExpr | test.rs:137:9:144:9 | IfExpr | | @@ -273,12 +277,13 @@ edges | test.rs:147:5:156:5 | exit test_nested_if_block (normal) | test.rs:147:5:156:5 | exit test_nested_if_block | | | test.rs:147:44:156:5 | BlockExpr | test.rs:147:5:156:5 | exit test_nested_if_block (normal) | | | test.rs:148:9:155:9 | IfExpr | test.rs:147:44:156:5 | BlockExpr | | -| test.rs:148:12:151:9 | BlockExpr | test.rs:152:13:152:13 | 1 | true | -| test.rs:148:12:151:9 | BlockExpr | test.rs:154:13:154:13 | 0 | false | +| test.rs:148:12:151:9 | [boolean(false)] BlockExpr | test.rs:154:13:154:13 | 0 | false | +| test.rs:148:12:151:9 | [boolean(true)] BlockExpr | test.rs:152:13:152:13 | 1 | true | | test.rs:149:13:149:14 | TupleExpr | test.rs:150:13:150:13 | a | | | test.rs:149:13:149:15 | ExprStmt | test.rs:149:13:149:14 | TupleExpr | | | test.rs:150:13:150:13 | a | test.rs:150:17:150:17 | 0 | | -| test.rs:150:13:150:17 | ... > ... | test.rs:148:12:151:9 | BlockExpr | false, true | +| test.rs:150:13:150:17 | ... > ... | test.rs:148:12:151:9 | [boolean(false)] BlockExpr | false | +| test.rs:150:13:150:17 | ... > ... | test.rs:148:12:151:9 | [boolean(true)] BlockExpr | true | | test.rs:150:17:150:17 | 0 | test.rs:150:13:150:17 | ... > ... | | | test.rs:151:11:153:9 | BlockExpr | test.rs:148:9:155:9 | IfExpr | | | test.rs:152:13:152:13 | 1 | test.rs:151:11:153:9 | BlockExpr | | @@ -303,8 +308,8 @@ edges | test.rs:167:5:178:5 | exit test_if_loop1 (normal) | test.rs:167:5:178:5 | exit test_if_loop1 | | | test.rs:167:37:178:5 | BlockExpr | test.rs:167:5:178:5 | exit test_if_loop1 (normal) | | | test.rs:168:9:177:9 | IfExpr | test.rs:167:37:178:5 | BlockExpr | | -| test.rs:168:13:173:9 | LoopExpr | test.rs:174:13:174:13 | 1 | true | -| test.rs:168:13:173:9 | LoopExpr | test.rs:176:13:176:13 | 0 | false | +| test.rs:168:13:173:9 | [boolean(false)] LoopExpr | test.rs:176:13:176:13 | 0 | false | +| test.rs:168:13:173:9 | [boolean(true)] LoopExpr | test.rs:174:13:174:13 | 1 | true | | test.rs:168:18:173:9 | BlockExpr | test.rs:169:13:171:14 | ExprStmt | | | test.rs:169:13:171:13 | IfExpr | test.rs:172:13:172:19 | ExprStmt | | | test.rs:169:13:171:14 | ExprStmt | test.rs:169:16:169:16 | a | | @@ -312,10 +317,12 @@ edges | test.rs:169:16:169:20 | ... > ... | test.rs:169:13:171:13 | IfExpr | false | | test.rs:169:16:169:20 | ... > ... | test.rs:170:17:170:29 | ExprStmt | true | | test.rs:169:20:169:20 | 0 | test.rs:169:16:169:20 | ... > ... | | -| test.rs:170:17:170:28 | BreakExpr | test.rs:168:13:173:9 | LoopExpr | break | +| test.rs:170:17:170:28 | [boolean(false)] BreakExpr | test.rs:168:13:173:9 | [boolean(false)] LoopExpr | break | +| test.rs:170:17:170:28 | [boolean(true)] BreakExpr | test.rs:168:13:173:9 | [boolean(true)] LoopExpr | break | | test.rs:170:17:170:29 | ExprStmt | test.rs:170:23:170:23 | a | | | test.rs:170:23:170:23 | a | test.rs:170:27:170:28 | 10 | | -| test.rs:170:23:170:28 | ... > ... | test.rs:170:17:170:28 | BreakExpr | | +| test.rs:170:23:170:28 | ... > ... | test.rs:170:17:170:28 | [boolean(false)] BreakExpr | false | +| test.rs:170:23:170:28 | ... > ... | test.rs:170:17:170:28 | [boolean(true)] BreakExpr | true | | test.rs:170:27:170:28 | 10 | test.rs:170:23:170:28 | ... > ... | | | test.rs:172:13:172:13 | a | test.rs:172:17:172:18 | 10 | | | test.rs:172:13:172:18 | ... < ... | test.rs:168:18:173:9 | BlockExpr | | @@ -329,8 +336,8 @@ edges | test.rs:180:5:191:5 | exit test_if_loop2 (normal) | test.rs:180:5:191:5 | exit test_if_loop2 | | | test.rs:180:37:191:5 | BlockExpr | test.rs:180:5:191:5 | exit test_if_loop2 (normal) | | | test.rs:181:9:190:9 | IfExpr | test.rs:180:37:191:5 | BlockExpr | | -| test.rs:181:13:186:9 | LoopExpr | test.rs:187:13:187:13 | 1 | true | -| test.rs:181:13:186:9 | LoopExpr | test.rs:189:13:189:13 | 0 | false | +| test.rs:181:13:186:9 | [boolean(false)] LoopExpr | test.rs:189:13:189:13 | 0 | false | +| test.rs:181:13:186:9 | [boolean(true)] LoopExpr | test.rs:187:13:187:13 | 1 | true | | test.rs:181:26:186:9 | BlockExpr | test.rs:182:13:184:14 | ExprStmt | | | test.rs:182:13:184:13 | IfExpr | test.rs:185:13:185:19 | ExprStmt | | | test.rs:182:13:184:14 | ExprStmt | test.rs:182:16:182:16 | a | | @@ -338,10 +345,12 @@ edges | test.rs:182:16:182:20 | ... > ... | test.rs:182:13:184:13 | IfExpr | false | | test.rs:182:16:182:20 | ... > ... | test.rs:183:17:183:36 | ExprStmt | true | | test.rs:182:20:182:20 | 0 | test.rs:182:16:182:20 | ... > ... | | -| test.rs:183:17:183:35 | BreakExpr | test.rs:181:13:186:9 | LoopExpr | break | +| test.rs:183:17:183:35 | [boolean(false)] BreakExpr | test.rs:181:13:186:9 | [boolean(false)] LoopExpr | break | +| test.rs:183:17:183:35 | [boolean(true)] BreakExpr | test.rs:181:13:186:9 | [boolean(true)] LoopExpr | break | | test.rs:183:17:183:36 | ExprStmt | test.rs:183:30:183:30 | a | | | test.rs:183:30:183:30 | a | test.rs:183:34:183:35 | 10 | | -| test.rs:183:30:183:35 | ... > ... | test.rs:183:17:183:35 | BreakExpr | | +| test.rs:183:30:183:35 | ... > ... | test.rs:183:17:183:35 | [boolean(false)] BreakExpr | false | +| test.rs:183:30:183:35 | ... > ... | test.rs:183:17:183:35 | [boolean(true)] BreakExpr | true | | test.rs:183:34:183:35 | 10 | test.rs:183:30:183:35 | ... > ... | | | test.rs:185:13:185:13 | a | test.rs:185:17:185:18 | 10 | | | test.rs:185:13:185:18 | ... < ... | test.rs:181:26:186:9 | BlockExpr | | @@ -355,12 +364,14 @@ edges | test.rs:193:5:201:5 | exit test_labelled_block (normal) | test.rs:193:5:201:5 | exit test_labelled_block | | | test.rs:193:43:201:5 | BlockExpr | test.rs:193:5:201:5 | exit test_labelled_block (normal) | | | test.rs:194:9:200:9 | IfExpr | test.rs:193:43:201:5 | BlockExpr | | -| test.rs:194:13:196:9 | BlockExpr | test.rs:197:13:197:13 | 1 | true | -| test.rs:194:13:196:9 | BlockExpr | test.rs:199:13:199:13 | 0 | false | -| test.rs:195:13:195:30 | BreakExpr | test.rs:194:13:196:9 | BlockExpr | break | +| test.rs:194:13:196:9 | [boolean(false)] BlockExpr | test.rs:199:13:199:13 | 0 | false | +| test.rs:194:13:196:9 | [boolean(true)] BlockExpr | test.rs:197:13:197:13 | 1 | true | +| test.rs:195:13:195:30 | [boolean(false)] BreakExpr | test.rs:194:13:196:9 | [boolean(false)] BlockExpr | break | +| test.rs:195:13:195:30 | [boolean(true)] BreakExpr | test.rs:194:13:196:9 | [boolean(true)] BlockExpr | break | | test.rs:195:13:195:31 | ExprStmt | test.rs:195:26:195:26 | a | | | test.rs:195:26:195:26 | a | test.rs:195:30:195:30 | 0 | | -| test.rs:195:26:195:30 | ... > ... | test.rs:195:13:195:30 | BreakExpr | | +| test.rs:195:26:195:30 | ... > ... | test.rs:195:13:195:30 | [boolean(false)] BreakExpr | false | +| test.rs:195:26:195:30 | ... > ... | test.rs:195:13:195:30 | [boolean(true)] BreakExpr | true | | test.rs:195:30:195:30 | 0 | test.rs:195:26:195:30 | ... > ... | | | test.rs:196:12:198:9 | BlockExpr | test.rs:194:9:200:9 | IfExpr | | | test.rs:197:13:197:13 | 1 | test.rs:196:12:198:9 | BlockExpr | | @@ -369,43 +380,46 @@ edges | test.rs:206:5:209:5 | enter test_and_operator | test.rs:207:9:207:28 | LetStmt | | | test.rs:206:5:209:5 | exit test_and_operator (normal) | test.rs:206:5:209:5 | exit test_and_operator | | | test.rs:206:61:209:5 | BlockExpr | test.rs:206:5:209:5 | exit test_and_operator (normal) | | -| test.rs:207:9:207:28 | LetStmt | test.rs:207:17:207:27 | ... && ... | | +| test.rs:207:9:207:28 | LetStmt | test.rs:207:17:207:17 | a | | | test.rs:207:13:207:13 | d | test.rs:208:9:208:9 | d | match, no-match | -| test.rs:207:17:207:17 | a | test.rs:207:13:207:13 | d | false | +| test.rs:207:17:207:17 | a | test.rs:207:17:207:22 | [boolean(false)] ... && ... | false | | test.rs:207:17:207:17 | a | test.rs:207:22:207:22 | b | true | -| test.rs:207:17:207:22 | ... && ... | test.rs:207:17:207:17 | a | | -| test.rs:207:17:207:27 | ... && ... | test.rs:207:17:207:22 | ... && ... | | -| test.rs:207:22:207:22 | b | test.rs:207:13:207:13 | d | false | -| test.rs:207:22:207:22 | b | test.rs:207:27:207:27 | c | true | -| test.rs:207:27:207:27 | c | test.rs:207:13:207:13 | d | | +| test.rs:207:17:207:22 | [boolean(false)] ... && ... | test.rs:207:17:207:27 | ... && ... | false | +| test.rs:207:17:207:22 | [boolean(true)] ... && ... | test.rs:207:27:207:27 | c | true | +| test.rs:207:17:207:27 | ... && ... | test.rs:207:13:207:13 | d | | +| test.rs:207:22:207:22 | b | test.rs:207:17:207:22 | [boolean(false)] ... && ... | false | +| test.rs:207:22:207:22 | b | test.rs:207:17:207:22 | [boolean(true)] ... && ... | true | +| test.rs:207:27:207:27 | c | test.rs:207:17:207:27 | ... && ... | | | test.rs:208:9:208:9 | d | test.rs:206:61:209:5 | BlockExpr | | | test.rs:211:5:214:5 | enter test_or_operator | test.rs:212:9:212:28 | LetStmt | | | test.rs:211:5:214:5 | exit test_or_operator (normal) | test.rs:211:5:214:5 | exit test_or_operator | | | test.rs:211:60:214:5 | BlockExpr | test.rs:211:5:214:5 | exit test_or_operator (normal) | | -| test.rs:212:9:212:28 | LetStmt | test.rs:212:17:212:27 | ... \|\| ... | | +| test.rs:212:9:212:28 | LetStmt | test.rs:212:17:212:17 | a | | | test.rs:212:13:212:13 | d | test.rs:213:9:213:9 | d | match, no-match | -| test.rs:212:17:212:17 | a | test.rs:212:13:212:13 | d | true | +| test.rs:212:17:212:17 | a | test.rs:212:17:212:22 | [boolean(true)] ... \|\| ... | true | | test.rs:212:17:212:17 | a | test.rs:212:22:212:22 | b | false | -| test.rs:212:17:212:22 | ... \|\| ... | test.rs:212:17:212:17 | a | | -| test.rs:212:17:212:27 | ... \|\| ... | test.rs:212:17:212:22 | ... \|\| ... | | -| test.rs:212:22:212:22 | b | test.rs:212:13:212:13 | d | true | -| test.rs:212:22:212:22 | b | test.rs:212:27:212:27 | c | false | -| test.rs:212:27:212:27 | c | test.rs:212:13:212:13 | d | | +| test.rs:212:17:212:22 | [boolean(false)] ... \|\| ... | test.rs:212:27:212:27 | c | false | +| test.rs:212:17:212:22 | [boolean(true)] ... \|\| ... | test.rs:212:17:212:27 | ... \|\| ... | true | +| test.rs:212:17:212:27 | ... \|\| ... | test.rs:212:13:212:13 | d | | +| test.rs:212:22:212:22 | b | test.rs:212:17:212:22 | [boolean(false)] ... \|\| ... | false | +| test.rs:212:22:212:22 | b | test.rs:212:17:212:22 | [boolean(true)] ... \|\| ... | true | +| test.rs:212:27:212:27 | c | test.rs:212:17:212:27 | ... \|\| ... | | | test.rs:213:9:213:9 | d | test.rs:211:60:214:5 | BlockExpr | | | test.rs:216:5:219:5 | enter test_or_operator_2 | test.rs:217:9:217:36 | LetStmt | | | test.rs:216:5:219:5 | exit test_or_operator_2 (normal) | test.rs:216:5:219:5 | exit test_or_operator_2 | | | test.rs:216:61:219:5 | BlockExpr | test.rs:216:5:219:5 | exit test_or_operator_2 (normal) | | -| test.rs:217:9:217:36 | LetStmt | test.rs:217:17:217:35 | ... \|\| ... | | +| test.rs:217:9:217:36 | LetStmt | test.rs:217:17:217:17 | a | | | test.rs:217:13:217:13 | d | test.rs:218:9:218:9 | d | match, no-match | -| test.rs:217:17:217:17 | a | test.rs:217:13:217:13 | d | true | +| test.rs:217:17:217:17 | a | test.rs:217:17:217:30 | [boolean(true)] ... \|\| ... | true | | test.rs:217:17:217:17 | a | test.rs:217:23:217:23 | b | false | -| test.rs:217:17:217:30 | ... \|\| ... | test.rs:217:17:217:17 | a | | -| test.rs:217:17:217:35 | ... \|\| ... | test.rs:217:17:217:30 | ... \|\| ... | | +| test.rs:217:17:217:30 | [boolean(false)] ... \|\| ... | test.rs:217:35:217:35 | c | false | +| test.rs:217:17:217:30 | [boolean(true)] ... \|\| ... | test.rs:217:17:217:35 | ... \|\| ... | true | +| test.rs:217:17:217:35 | ... \|\| ... | test.rs:217:13:217:13 | d | | | test.rs:217:23:217:23 | b | test.rs:217:28:217:29 | 28 | | -| test.rs:217:23:217:29 | ... == ... | test.rs:217:13:217:13 | d | true | -| test.rs:217:23:217:29 | ... == ... | test.rs:217:35:217:35 | c | false | +| test.rs:217:23:217:29 | ... == ... | test.rs:217:17:217:30 | [boolean(false)] ... \|\| ... | false | +| test.rs:217:23:217:29 | ... == ... | test.rs:217:17:217:30 | [boolean(true)] ... \|\| ... | true | | test.rs:217:28:217:29 | 28 | test.rs:217:23:217:29 | ... == ... | | -| test.rs:217:35:217:35 | c | test.rs:217:13:217:13 | d | | +| test.rs:217:35:217:35 | c | test.rs:217:17:217:35 | ... \|\| ... | | | test.rs:218:9:218:9 | d | test.rs:216:61:219:5 | BlockExpr | | | test.rs:221:5:224:5 | enter test_not_operator | test.rs:222:9:222:19 | LetStmt | | | test.rs:221:5:224:5 | exit test_not_operator (normal) | test.rs:221:5:224:5 | exit test_not_operator | | @@ -415,34 +429,38 @@ edges | test.rs:222:17:222:18 | ! ... | test.rs:222:13:222:13 | d | | | test.rs:222:18:222:18 | a | test.rs:222:17:222:18 | ! ... | | | test.rs:223:9:223:9 | d | test.rs:221:43:224:5 | BlockExpr | | -| test.rs:226:5:232:5 | enter test_if_and_operator | test.rs:227:12:227:22 | ... && ... | | +| test.rs:226:5:232:5 | enter test_if_and_operator | test.rs:227:12:227:12 | a | | | test.rs:226:5:232:5 | exit test_if_and_operator (normal) | test.rs:226:5:232:5 | exit test_if_and_operator | | | test.rs:226:63:232:5 | BlockExpr | test.rs:226:5:232:5 | exit test_if_and_operator (normal) | | | test.rs:227:9:231:9 | IfExpr | test.rs:226:63:232:5 | BlockExpr | | +| test.rs:227:12:227:12 | a | test.rs:227:12:227:17 | [boolean(false)] ... && ... | false | | test.rs:227:12:227:12 | a | test.rs:227:17:227:17 | b | true | -| test.rs:227:12:227:12 | a | test.rs:230:13:230:17 | false | false | -| test.rs:227:12:227:17 | ... && ... | test.rs:227:12:227:12 | a | | -| test.rs:227:12:227:22 | ... && ... | test.rs:227:12:227:17 | ... && ... | | -| test.rs:227:17:227:17 | b | test.rs:227:22:227:22 | c | true | -| test.rs:227:17:227:17 | b | test.rs:230:13:230:17 | false | false | -| test.rs:227:22:227:22 | c | test.rs:228:13:228:16 | true | true | -| test.rs:227:22:227:22 | c | test.rs:230:13:230:17 | false | false | +| test.rs:227:12:227:17 | [boolean(false)] ... && ... | test.rs:227:12:227:22 | [boolean(false)] ... && ... | false | +| test.rs:227:12:227:17 | [boolean(true)] ... && ... | test.rs:227:22:227:22 | c | true | +| test.rs:227:12:227:22 | [boolean(false)] ... && ... | test.rs:230:13:230:17 | false | false | +| test.rs:227:12:227:22 | [boolean(true)] ... && ... | test.rs:228:13:228:16 | true | true | +| test.rs:227:17:227:17 | b | test.rs:227:12:227:17 | [boolean(false)] ... && ... | false | +| test.rs:227:17:227:17 | b | test.rs:227:12:227:17 | [boolean(true)] ... && ... | true | +| test.rs:227:22:227:22 | c | test.rs:227:12:227:22 | [boolean(false)] ... && ... | false | +| test.rs:227:22:227:22 | c | test.rs:227:12:227:22 | [boolean(true)] ... && ... | true | | test.rs:227:24:229:9 | BlockExpr | test.rs:227:9:231:9 | IfExpr | | | test.rs:228:13:228:16 | true | test.rs:227:24:229:9 | BlockExpr | | | test.rs:229:16:231:9 | BlockExpr | test.rs:227:9:231:9 | IfExpr | | | test.rs:230:13:230:17 | false | test.rs:229:16:231:9 | BlockExpr | | -| test.rs:234:5:240:5 | enter test_if_or_operator | test.rs:235:12:235:22 | ... \|\| ... | | +| test.rs:234:5:240:5 | enter test_if_or_operator | test.rs:235:12:235:12 | a | | | test.rs:234:5:240:5 | exit test_if_or_operator (normal) | test.rs:234:5:240:5 | exit test_if_or_operator | | | test.rs:234:62:240:5 | BlockExpr | test.rs:234:5:240:5 | exit test_if_or_operator (normal) | | | test.rs:235:9:239:9 | IfExpr | test.rs:234:62:240:5 | BlockExpr | | +| test.rs:235:12:235:12 | a | test.rs:235:12:235:17 | [boolean(true)] ... \|\| ... | true | | test.rs:235:12:235:12 | a | test.rs:235:17:235:17 | b | false | -| test.rs:235:12:235:12 | a | test.rs:236:13:236:16 | true | true | -| test.rs:235:12:235:17 | ... \|\| ... | test.rs:235:12:235:12 | a | | -| test.rs:235:12:235:22 | ... \|\| ... | test.rs:235:12:235:17 | ... \|\| ... | | -| test.rs:235:17:235:17 | b | test.rs:235:22:235:22 | c | false | -| test.rs:235:17:235:17 | b | test.rs:236:13:236:16 | true | true | -| test.rs:235:22:235:22 | c | test.rs:236:13:236:16 | true | true | -| test.rs:235:22:235:22 | c | test.rs:238:13:238:17 | false | false | +| test.rs:235:12:235:17 | [boolean(false)] ... \|\| ... | test.rs:235:22:235:22 | c | false | +| test.rs:235:12:235:17 | [boolean(true)] ... \|\| ... | test.rs:235:12:235:22 | [boolean(true)] ... \|\| ... | true | +| test.rs:235:12:235:22 | [boolean(false)] ... \|\| ... | test.rs:238:13:238:17 | false | false | +| test.rs:235:12:235:22 | [boolean(true)] ... \|\| ... | test.rs:236:13:236:16 | true | true | +| test.rs:235:17:235:17 | b | test.rs:235:12:235:17 | [boolean(false)] ... \|\| ... | false | +| test.rs:235:17:235:17 | b | test.rs:235:12:235:17 | [boolean(true)] ... \|\| ... | true | +| test.rs:235:22:235:22 | c | test.rs:235:12:235:22 | [boolean(false)] ... \|\| ... | false | +| test.rs:235:22:235:22 | c | test.rs:235:12:235:22 | [boolean(true)] ... \|\| ... | true | | test.rs:235:24:237:9 | BlockExpr | test.rs:235:9:239:9 | IfExpr | | | test.rs:236:13:236:16 | true | test.rs:235:24:237:9 | BlockExpr | | | test.rs:237:16:239:9 | BlockExpr | test.rs:235:9:239:9 | IfExpr | | @@ -451,9 +469,10 @@ edges | test.rs:242:5:248:5 | exit test_if_not_operator (normal) | test.rs:242:5:248:5 | exit test_if_not_operator | | | test.rs:242:46:248:5 | BlockExpr | test.rs:242:5:248:5 | exit test_if_not_operator (normal) | | | test.rs:243:9:247:9 | IfExpr | test.rs:242:46:248:5 | BlockExpr | | -| test.rs:243:12:243:13 | ! ... | test.rs:244:13:244:16 | true | true | -| test.rs:243:12:243:13 | ! ... | test.rs:246:13:246:17 | false | false | -| test.rs:243:13:243:13 | a | test.rs:243:12:243:13 | ! ... | false, true | +| test.rs:243:12:243:13 | [boolean(false)] ! ... | test.rs:246:13:246:17 | false | false | +| test.rs:243:12:243:13 | [boolean(true)] ! ... | test.rs:244:13:244:16 | true | true | +| test.rs:243:13:243:13 | a | test.rs:243:12:243:13 | [boolean(false)] ! ... | true | +| test.rs:243:13:243:13 | a | test.rs:243:12:243:13 | [boolean(true)] ! ... | false | | test.rs:243:15:245:9 | BlockExpr | test.rs:243:9:247:9 | IfExpr | | | test.rs:244:13:244:16 | true | test.rs:243:15:245:9 | BlockExpr | | | test.rs:245:16:247:9 | BlockExpr | test.rs:243:9:247:9 | IfExpr | | From 2832318711852c0b0c14d4ca690830cbd7d64e53 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 20 Sep 2024 14:39:21 +0200 Subject: [PATCH 162/347] Java: Account for top-level `res` folders in `AndroidLayoutXmlFile` --- java/ql/lib/semmle/code/java/frameworks/android/Layout.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll b/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll index d7f0b0e2e6cb..ee430b62d577 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll @@ -6,7 +6,7 @@ private import semmle.code.java.dataflow.DataFlow /** An Android Layout XML file. */ class AndroidLayoutXmlFile extends XmlFile { - AndroidLayoutXmlFile() { this.getRelativePath().matches("%/res/layout/%.xml") } + AndroidLayoutXmlFile() { this.getRelativePath().regexpMatch("(.*/)?res/layout/.*\\.xml") } } /** A component declared in an Android layout file. */ From bf0675e5bac2f47c3dd385185511e79d35f7924c Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 23 Sep 2024 10:17:52 +0200 Subject: [PATCH 163/347] Kotlin: Update two tests --- java/ql/test-kotlin1/library-tests/classes/local_anonymous.ql | 4 +--- java/ql/test-kotlin2/library-tests/classes/local_anonymous.ql | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/java/ql/test-kotlin1/library-tests/classes/local_anonymous.ql b/java/ql/test-kotlin1/library-tests/classes/local_anonymous.ql index af8e63e50d8d..479c6111d42e 100644 --- a/java/ql/test-kotlin1/library-tests/classes/local_anonymous.ql +++ b/java/ql/test-kotlin1/library-tests/classes/local_anonymous.ql @@ -1,8 +1,6 @@ import java -private predicate filterFile(Top t) { - t.getFile().getRelativePath().matches("%/local_anonymous.kt") -} +private predicate filterFile(Top t) { t.getFile().getRelativePath().matches("%local_anonymous.kt") } private string isAnonymousType(Type t) { if t instanceof AnonymousClass then result = "anonymous" else result = "not anonymous" diff --git a/java/ql/test-kotlin2/library-tests/classes/local_anonymous.ql b/java/ql/test-kotlin2/library-tests/classes/local_anonymous.ql index af8e63e50d8d..479c6111d42e 100644 --- a/java/ql/test-kotlin2/library-tests/classes/local_anonymous.ql +++ b/java/ql/test-kotlin2/library-tests/classes/local_anonymous.ql @@ -1,8 +1,6 @@ import java -private predicate filterFile(Top t) { - t.getFile().getRelativePath().matches("%/local_anonymous.kt") -} +private predicate filterFile(Top t) { t.getFile().getRelativePath().matches("%local_anonymous.kt") } private string isAnonymousType(Type t) { if t instanceof AnonymousClass then result = "anonymous" else result = "not anonymous" From 953461d1aaf05b63104c61cf31cbbda77f8d0b3a Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 23 Sep 2024 11:51:00 +0200 Subject: [PATCH 164/347] C++: Update expected test output --- .../test/library-tests/files/Files.expected | 8 ++--- .../query-tests/Diagnostics/Info.expected | 10 +++--- .../DocumentApi/DocumentApi.expected | 32 +++++++++---------- .../ExternalDependencies.expected | 8 ++--- .../ExternalDependenciesSourceLinks.expected | 8 ++--- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/cpp/ql/test/library-tests/files/Files.expected b/cpp/ql/test/library-tests/files/Files.expected index 68187793433b..13f3a6b2da17 100644 --- a/cpp/ql/test/library-tests/files/Files.expected +++ b/cpp/ql/test/library-tests/files/Files.expected @@ -1,4 +1,4 @@ -| c.c | library-tests/files/c.c | CFile, MetricFile | C | | | -| files1.cpp | library-tests/files/files1.cpp | CppFile, MetricFile | C++ | swap | t | -| files1.h | library-tests/files/files1.h | HeaderFile, MetricFile | | swap | | -| files2.cpp | library-tests/files/files2.cpp | CppFile, MetricFile | C++ | g | x, y | +| c.c | c.c | CFile, MetricFile | C | | | +| files1.cpp | files1.cpp | CppFile, MetricFile | C++ | swap | t | +| files1.h | files1.h | HeaderFile, MetricFile | | swap | | +| files2.cpp | files2.cpp | CppFile, MetricFile | C++ | g | x, y | diff --git a/cpp/ql/test/query-tests/Diagnostics/Info.expected b/cpp/ql/test/query-tests/Diagnostics/Info.expected index 55e3310fd19b..a32541303609 100644 --- a/cpp/ql/test/query-tests/Diagnostics/Info.expected +++ b/cpp/ql/test/query-tests/Diagnostics/Info.expected @@ -1,6 +1,6 @@ -| containserror.cpp:0:0:0:0 | containserror.cpp | query-tests/Diagnostics/containserror.cpp | fromSource, normalTermination | -| containswarning.cpp:0:0:0:0 | containswarning.cpp | query-tests/Diagnostics/containswarning.cpp | fromSource, normalTermination | -| doesnotcompile.cpp:0:0:0:0 | doesnotcompile.cpp | query-tests/Diagnostics/doesnotcompile.cpp | ExtractionProblem (severity 1), fromSource, normalTermination | +| containserror.cpp:0:0:0:0 | containserror.cpp | containserror.cpp | fromSource, normalTermination | +| containswarning.cpp:0:0:0:0 | containswarning.cpp | containswarning.cpp | fromSource, normalTermination | +| doesnotcompile.cpp:0:0:0:0 | doesnotcompile.cpp | doesnotcompile.cpp | ExtractionProblem (severity 1), fromSource, normalTermination | | file://:0:0:0:0 | | | | -| header.h:0:0:0:0 | header.h | query-tests/Diagnostics/header.h | fromSource | -| successful.cpp:0:0:0:0 | successful.cpp | query-tests/Diagnostics/successful.cpp | fromSource, normalTermination | +| header.h:0:0:0:0 | header.h | header.h | fromSource | +| successful.cpp:0:0:0:0 | successful.cpp | successful.cpp | fromSource, normalTermination | diff --git a/cpp/ql/test/query-tests/Documentation/DocumentApi/DocumentApi.expected b/cpp/ql/test/query-tests/Documentation/DocumentApi/DocumentApi.expected index b19d88acdc28..62d47bc8db0b 100644 --- a/cpp/ql/test/query-tests/Documentation/DocumentApi/DocumentApi.expected +++ b/cpp/ql/test/query-tests/Documentation/DocumentApi/DocumentApi.expected @@ -1,16 +1,16 @@ -| comment_prototypes.c:29:6:29:11 | proto6 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller1.c:9:5:9:10 | call to proto6 | query-tests/Documentation/DocumentApi/comment_prototypes_caller1.c | -| comment_prototypes.c:29:6:29:11 | proto6 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller2.c:9:5:9:10 | call to proto6 | query-tests/Documentation/DocumentApi/comment_prototypes_caller2.c | -| comment_prototypes.c:34:6:34:11 | proto7 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller1.c:10:5:10:10 | call to proto7 | query-tests/Documentation/DocumentApi/comment_prototypes_caller1.c | -| comment_prototypes.c:34:6:34:11 | proto7 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller2.c:10:5:10:10 | call to proto7 | query-tests/Documentation/DocumentApi/comment_prototypes_caller2.c | -| comment_prototypes.c:45:6:45:11 | proto9 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller1.c:12:5:12:10 | call to proto9 | query-tests/Documentation/DocumentApi/comment_prototypes_caller1.c | -| comment_prototypes.c:45:6:45:11 | proto9 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller2.c:12:5:12:10 | call to proto9 | query-tests/Documentation/DocumentApi/comment_prototypes_caller2.c | -| comment_prototypes.c:50:6:50:12 | proto10 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller1.c:13:5:13:11 | call to proto10 | query-tests/Documentation/DocumentApi/comment_prototypes_caller1.c | -| comment_prototypes.c:50:6:50:12 | proto10 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller2.c:13:5:13:11 | call to proto10 | query-tests/Documentation/DocumentApi/comment_prototypes_caller2.c | -| comment_prototypes.c:55:6:55:12 | proto11 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller1.c:14:5:14:11 | call to proto11 | query-tests/Documentation/DocumentApi/comment_prototypes_caller1.c | -| comment_prototypes.c:55:6:55:12 | proto11 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller2.c:14:5:14:11 | call to proto11 | query-tests/Documentation/DocumentApi/comment_prototypes_caller2.c | -| comment_prototypes.c:66:6:66:12 | proto13 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller1.c:16:5:16:11 | call to proto13 | query-tests/Documentation/DocumentApi/comment_prototypes_caller1.c | -| comment_prototypes.c:66:6:66:12 | proto13 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller2.c:16:5:16:11 | call to proto13 | query-tests/Documentation/DocumentApi/comment_prototypes_caller2.c | -| definition.c:2:6:2:7 | f1 | Functions called from other files should be documented (called from $@). | user1.c:9:5:9:6 | call to f1 | query-tests/Documentation/DocumentApi/user1.c | -| definition.c:2:6:2:7 | f1 | Functions called from other files should be documented (called from $@). | user2.c:7:5:7:6 | call to f1 | query-tests/Documentation/DocumentApi/user2.c | -| definition.c:32:6:32:7 | f6 | Functions called from other files should be documented (called from $@). | user1.c:14:5:14:6 | call to f6 | query-tests/Documentation/DocumentApi/user1.c | -| definition.c:32:6:32:7 | f6 | Functions called from other files should be documented (called from $@). | user2.c:10:5:10:6 | call to f6 | query-tests/Documentation/DocumentApi/user2.c | +| comment_prototypes.c:29:6:29:11 | proto6 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller1.c:9:5:9:10 | call to proto6 | comment_prototypes_caller1.c | +| comment_prototypes.c:29:6:29:11 | proto6 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller2.c:9:5:9:10 | call to proto6 | comment_prototypes_caller2.c | +| comment_prototypes.c:34:6:34:11 | proto7 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller1.c:10:5:10:10 | call to proto7 | comment_prototypes_caller1.c | +| comment_prototypes.c:34:6:34:11 | proto7 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller2.c:10:5:10:10 | call to proto7 | comment_prototypes_caller2.c | +| comment_prototypes.c:45:6:45:11 | proto9 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller1.c:12:5:12:10 | call to proto9 | comment_prototypes_caller1.c | +| comment_prototypes.c:45:6:45:11 | proto9 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller2.c:12:5:12:10 | call to proto9 | comment_prototypes_caller2.c | +| comment_prototypes.c:50:6:50:12 | proto10 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller1.c:13:5:13:11 | call to proto10 | comment_prototypes_caller1.c | +| comment_prototypes.c:50:6:50:12 | proto10 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller2.c:13:5:13:11 | call to proto10 | comment_prototypes_caller2.c | +| comment_prototypes.c:55:6:55:12 | proto11 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller1.c:14:5:14:11 | call to proto11 | comment_prototypes_caller1.c | +| comment_prototypes.c:55:6:55:12 | proto11 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller2.c:14:5:14:11 | call to proto11 | comment_prototypes_caller2.c | +| comment_prototypes.c:66:6:66:12 | proto13 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller1.c:16:5:16:11 | call to proto13 | comment_prototypes_caller1.c | +| comment_prototypes.c:66:6:66:12 | proto13 | Functions called from other files should be documented (called from $@). | comment_prototypes_caller2.c:16:5:16:11 | call to proto13 | comment_prototypes_caller2.c | +| definition.c:2:6:2:7 | f1 | Functions called from other files should be documented (called from $@). | user1.c:9:5:9:6 | call to f1 | user1.c | +| definition.c:2:6:2:7 | f1 | Functions called from other files should be documented (called from $@). | user2.c:7:5:7:6 | call to f1 | user2.c | +| definition.c:32:6:32:7 | f6 | Functions called from other files should be documented (called from $@). | user1.c:14:5:14:6 | call to f6 | user1.c | +| definition.c:32:6:32:7 | f6 | Functions called from other files should be documented (called from $@). | user2.c:10:5:10:6 | call to f6 | user2.c | diff --git a/cpp/ql/test/query-tests/Metrics/Dependencies/ExternalDependencies.expected b/cpp/ql/test/query-tests/Metrics/Dependencies/ExternalDependencies.expected index a42506f8be11..795f6dba431a 100644 --- a/cpp/ql/test/query-tests/Metrics/Dependencies/ExternalDependencies.expected +++ b/cpp/ql/test/query-tests/Metrics/Dependencies/ExternalDependencies.expected @@ -1,4 +1,4 @@ -| /query-tests/Metrics/Dependencies/main.cpp<\|>LibC<\|>unknown | 5 | -| /query-tests/Metrics/Dependencies/include.h<\|>LibD<\|>unknown | 1 | -| /query-tests/Metrics/Dependencies/main.cpp<\|>LibA<\|>unknown | 1 | -| /query-tests/Metrics/Dependencies/main.cpp<\|>LibB<\|>unknown | 1 | +| /main.cpp<\|>LibC<\|>unknown | 5 | +| /include.h<\|>LibD<\|>unknown | 1 | +| /main.cpp<\|>LibA<\|>unknown | 1 | +| /main.cpp<\|>LibB<\|>unknown | 1 | diff --git a/cpp/ql/test/query-tests/Metrics/Dependencies/ExternalDependenciesSourceLinks.expected b/cpp/ql/test/query-tests/Metrics/Dependencies/ExternalDependenciesSourceLinks.expected index f5399bf6ac31..b00deb76d7d8 100644 --- a/cpp/ql/test/query-tests/Metrics/Dependencies/ExternalDependenciesSourceLinks.expected +++ b/cpp/ql/test/query-tests/Metrics/Dependencies/ExternalDependenciesSourceLinks.expected @@ -1,4 +1,4 @@ -| /query-tests/Metrics/Dependencies/include.h<\|>LibD<\|>unknown | include.h:0:0:0:0 | include.h | -| /query-tests/Metrics/Dependencies/main.cpp<\|>LibA<\|>unknown | main.cpp:0:0:0:0 | main.cpp | -| /query-tests/Metrics/Dependencies/main.cpp<\|>LibB<\|>unknown | main.cpp:0:0:0:0 | main.cpp | -| /query-tests/Metrics/Dependencies/main.cpp<\|>LibC<\|>unknown | main.cpp:0:0:0:0 | main.cpp | +| /include.h<\|>LibD<\|>unknown | include.h:0:0:0:0 | include.h | +| /main.cpp<\|>LibA<\|>unknown | main.cpp:0:0:0:0 | main.cpp | +| /main.cpp<\|>LibB<\|>unknown | main.cpp:0:0:0:0 | main.cpp | +| /main.cpp<\|>LibC<\|>unknown | main.cpp:0:0:0:0 | main.cpp | From b3b9406e4563c8457670e7bf99279921b54289f3 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 23 Sep 2024 16:38:10 +0200 Subject: [PATCH 165/347] Python: Update test --- .../experimental/library-tests/CallGraph/InlineCallGraphTest.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql index 1f2b37168b73..e1b14363639b 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql +++ b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql @@ -65,7 +65,7 @@ string getCallEdgeValue(CallNode call, Function target) { else exists(string fixedRelativePath | fixedRelativePath = - target.getLocation().getFile().getRelativePath().regexpCapture(".*/CallGraph[^/]*/(.*)", 1) + target.getLocation().getFile().getAbsolutePath().regexpCapture(".*/CallGraph[^/]*/(.*)", 1) | // the value needs to be enclosed in quotes to allow special characters result = "\"" + fixedRelativePath + ":" + betterQualName(target) + "\"" From d0ca39fb03ea11f164023b6b991fd78fad3d91af Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 26 Sep 2024 12:52:54 +0200 Subject: [PATCH 166/347] JS: Update expected test output --- .../Files/relativePaths.expected | 4 +- .../test/library-tests/Modules/tests.expected | 20 +++---- .../test/library-tests/NodeJS/tests.expected | 6 +- .../TypeScript/EmbeddedInScript/Test.expected | 18 +++--- .../HasQualifiedNameFallback/Test.expected | 2 +- .../TypeScript/PathMapping/Imports.expected | 14 ++--- .../Namespaces.expected | 42 +++++++------- .../ResolveNamespace.expected | 56 +++++++++---------- .../ResolveTypeName.expected | 38 ++++++------- .../RegressionTests/EmptyName/test.expected | 6 +- .../ExportEqualsExpr/test.expected | 4 +- .../SemicolonInName/test.expected | 2 +- .../SyntaxErrors/SyntaxErrors.expected | 2 +- .../TypeScript/Types/tests.expected | 50 ++++++++--------- .../ExternalDependencies.expected | 18 +++--- .../NodeJS/CyclicImport/CyclicImport.expected | 4 +- .../CWE-200/PrivateFileExposure.expected | 8 +-- .../tests.expected | 4 +- 18 files changed, 148 insertions(+), 150 deletions(-) diff --git a/javascript/ql/test/library-tests/Files/relativePaths.expected b/javascript/ql/test/library-tests/Files/relativePaths.expected index d70416666954..16c365fdbb13 100644 --- a/javascript/ql/test/library-tests/Files/relativePaths.expected +++ b/javascript/ql/test/library-tests/Files/relativePaths.expected @@ -1,2 +1,2 @@ -| a.js:0:0:0:0 | a.js | library-tests/Files/a.js | -| b/c.js:0:0:0:0 | b/c.js | library-tests/Files/b/c.js | +| a.js:0:0:0:0 | a.js | a.js | +| b/c.js:0:0:0:0 | b/c.js | b/c.js | diff --git a/javascript/ql/test/library-tests/Modules/tests.expected b/javascript/ql/test/library-tests/Modules/tests.expected index cec0b96049e8..bf0efddba553 100644 --- a/javascript/ql/test/library-tests/Modules/tests.expected +++ b/javascript/ql/test/library-tests/Modules/tests.expected @@ -115,16 +115,16 @@ test_ReExportDeclarations | m/c.js:5:1:5:30 | export ... '../b'; | m/c.js:5:24:5:29 | '../b' | | reExportNamespace.js:1:1:1:26 | export ... "./a"; | reExportNamespace.js:1:21:1:25 | "./a" | test_getAnImportedModule -| library-tests/Modules/b.js | library-tests/Modules/a.js | -| library-tests/Modules/d.js | library-tests/Modules/a.js | -| library-tests/Modules/d.js | library-tests/Modules/b.js | -| library-tests/Modules/es2015_require.js | library-tests/Modules/d.js | -| library-tests/Modules/f.ts | library-tests/Modules/e.js | -| library-tests/Modules/g.ts | library-tests/Modules/f.ts | -| library-tests/Modules/import-indirect-path.js | library-tests/Modules/a.js | -| library-tests/Modules/import-ts-with-js-extension.ts | library-tests/Modules/f.ts | -| library-tests/Modules/m/c.js | library-tests/Modules/b.js | -| library-tests/Modules/reExportNamespaceClient.js | library-tests/Modules/reExportNamespace.js | +| b.js | a.js | +| d.js | a.js | +| d.js | b.js | +| es2015_require.js | d.js | +| f.ts | e.js | +| g.ts | f.ts | +| import-indirect-path.js | a.js | +| import-ts-with-js-extension.ts | f.ts | +| m/c.js | b.js | +| reExportNamespaceClient.js | reExportNamespace.js | test_getExportedName | arbitrarySpecifier.ts:5:10:5:30 | Foo_new ... o::new" | Foo::new | | arbitrarySpecifier.ts:6:13:6:28 | * as "Foo_types" | Foo_types | diff --git a/javascript/ql/test/library-tests/NodeJS/tests.expected b/javascript/ql/test/library-tests/NodeJS/tests.expected index 2f5d09245ec8..b97c6a345e8f 100644 --- a/javascript/ql/test/library-tests/NodeJS/tests.expected +++ b/javascript/ql/test/library-tests/NodeJS/tests.expected @@ -94,12 +94,12 @@ requireImport | a.js:3:6:3:23 | require('./sub/c') | ./sub/c | sub/c.js:1:1:4:0 | | | a.js:4:6:4:29 | require ... /d.js') | ./sub/../d.js | d.js:1:1:7:15 | | | a.js:7:1:7:18 | require('./sub/c') | ./sub/c | sub/c.js:1:1:4:0 | | -| a.js:10:1:10:18 | require(__dirname) | /library-tests/NodeJS | index.js:1:1:3:0 | | -| a.js:11:1:11:25 | require ... + '/e') | /library-tests/NodeJS/e | e.js:1:1:6:0 | | +| a.js:10:1:10:18 | require(__dirname) | | index.js:1:1:3:0 | | +| a.js:11:1:11:25 | require ... + '/e') | /e | e.js:1:1:6:0 | | | a.js:12:1:12:28 | require ... + 'c') | ./sub/c | sub/c.js:1:1:4:0 | | | b.js:1:1:1:18 | require('./sub/c') | ./sub/c | sub/c.js:1:1:4:0 | | | d.js:7:1:7:14 | require('foo') | foo | sub/f.js:1:1:4:17 | | -| index.js:2:1:2:41 | require ... b.js")) | /library-tests/NodeJS/index.js/../b.js | b.js:1:1:8:0 | | +| index.js:2:1:2:41 | require ... b.js")) | /index.js/../b.js | b.js:1:1:8:0 | | | mjs-files/require-from-js.js:1:12:1:36 | require ... on-me') | ./depend-on-me | mjs-files/depend-on-me.mjs:1:1:7:1 | | | mjs-files/require-from-js.js:2:12:2:39 | require ... me.js') | ./depend-on-me.js | mjs-files/depend-on-me.js:1:1:8:0 | | | mjs-files/require-from-js.js:3:12:3:40 | require ... e.mjs') | ./depend-on-me.mjs | mjs-files/depend-on-me.mjs:1:1:7:1 | | diff --git a/javascript/ql/test/library-tests/TypeScript/EmbeddedInScript/Test.expected b/javascript/ql/test/library-tests/TypeScript/EmbeddedInScript/Test.expected index 711e94cfdaa1..2bb7faf59eb9 100644 --- a/javascript/ql/test/library-tests/TypeScript/EmbeddedInScript/Test.expected +++ b/javascript/ql/test/library-tests/TypeScript/EmbeddedInScript/Test.expected @@ -8,27 +8,27 @@ exprType | htmlfile.html:5:26:5:28 | foo | () => void | | htmlfile.html:5:26:5:30 | foo() | void | | htmlfile.html:5:26:5:42 | foo() as number[] | number[] | -| other.ts:1:8:1:16 | Component | typeof default in library-tests/TypeScript/EmbeddedInScript/test.vue | +| other.ts:1:8:1:16 | Component | typeof default in test.vue | | other.ts:1:23:1:34 | "./test.vue" | any | -| other.ts:2:8:2:19 | ComponentTsx | typeof default in library-tests/TypeScript/EmbeddedInScript/test_tsx.vue | +| other.ts:2:8:2:19 | ComponentTsx | typeof default in test_tsx.vue | | other.ts:2:26:2:41 | "./test_tsx.vue" | any | | other.ts:4:1:4:15 | new Component() | MyComponent | -| other.ts:4:5:4:13 | Component | typeof default in library-tests/TypeScript/EmbeddedInScript/test.vue | +| other.ts:4:5:4:13 | Component | typeof default in test.vue | | other.ts:5:1:5:18 | new ComponentTsx() | MyComponentTsx | -| other.ts:5:5:5:16 | ComponentTsx | typeof default in library-tests/TypeScript/EmbeddedInScript/test_tsx.vue | +| other.ts:5:5:5:16 | ComponentTsx | typeof default in test_tsx.vue | | other.ts:7:17:7:19 | foo | () => void | -| test.vue:2:15:2:19 | other | typeof library-tests/TypeScript/EmbeddedInScript/other.ts | +| test.vue:2:15:2:19 | other | typeof other.ts | | test.vue:2:26:2:34 | "./other" | any | | test.vue:3:24:3:34 | MyComponent | MyComponent | | test.vue:4:7:4:7 | x | number | -| test_tsx.vue:2:15:2:19 | other | typeof library-tests/TypeScript/EmbeddedInScript/other.ts | +| test_tsx.vue:2:15:2:19 | other | typeof other.ts | | test_tsx.vue:2:26:2:34 | "./other" | any | | test_tsx.vue:3:24:3:37 | MyComponentTsx | MyComponentTsx | | test_tsx.vue:4:7:4:7 | x | number | symbols -| other.ts:1:1:8:0 | | library-tests/TypeScript/EmbeddedInScript/other.ts | -| test.vue:2:3:6:0 | | library-tests/TypeScript/EmbeddedInScript/test.vue | -| test_tsx.vue:2:3:6:0 | | library-tests/TypeScript/EmbeddedInScript/test_tsx.vue | +| other.ts:1:1:8:0 | | other.ts | +| test.vue:2:3:6:0 | | test.vue | +| test_tsx.vue:2:3:6:0 | | test_tsx.vue | importTarget | htmlfile.html:4:13:4:42 | import ... other"; | other.ts:1:1:8:0 | | | other.ts:1:1:1:35 | import ... t.vue"; | test.vue:2:3:6:0 | | diff --git a/javascript/ql/test/library-tests/TypeScript/HasQualifiedNameFallback/Test.expected b/javascript/ql/test/library-tests/TypeScript/HasQualifiedNameFallback/Test.expected index 5da73c5cfe45..5ee97e2dfb59 100644 --- a/javascript/ql/test/library-tests/TypeScript/HasQualifiedNameFallback/Test.expected +++ b/javascript/ql/test/library-tests/TypeScript/HasQualifiedNameFallback/Test.expected @@ -1,12 +1,12 @@ hasQualifiedNameModule | default-import | default | tst.ts:11:9:11:21 | DefaultImport | | import-assign | Foo | tst.ts:10:9:10:15 | asn.Foo | -| library-tests/TypeScript/HasQualifiedNameFallback/tst.ts | ExportedClass | relative.ts:4:8:4:20 | ExportedClass | | named-import | Name1 | tst.ts:7:9:7:13 | Name1 | | named-import | Name1 | tst.ts:13:9:13:13 | Name1 | | named-import | Name1 | tst.ts:13:9:13:21 | Name1 | | named-import | Name2 | tst.ts:8:9:8:13 | Name2 | | namespace-import | Foo | tst.ts:9:9:9:21 | namespace.Foo | +| tst.ts | ExportedClass | relative.ts:4:8:4:20 | ExportedClass | hasQualifiedNameGlobal | UnresolvedName | tst.ts:12:9:12:22 | UnresolvedName | paramExample diff --git a/javascript/ql/test/library-tests/TypeScript/PathMapping/Imports.expected b/javascript/ql/test/library-tests/TypeScript/PathMapping/Imports.expected index c608ea2c7b61..886391b14552 100644 --- a/javascript/ql/test/library-tests/TypeScript/PathMapping/Imports.expected +++ b/javascript/ql/test/library-tests/TypeScript/PathMapping/Imports.expected @@ -1,11 +1,11 @@ symbols -| src/lib/foo.ts:1:1:4:0 | | library-tests/TypeScript/PathMapping/src/lib/foo.ts | -| src/lib/foo.ts:1:8:3:1 | functio ... 123;\\n} | foo in library-tests/TypeScript/PathMapping/src/lib/foo.ts | -| test/test_foo.ts:1:1:1:28 | import ... @/foo"; | library-tests/TypeScript/PathMapping/src/lib/foo.ts | -| test/test_foo.ts:1:1:7:0 | | library-tests/TypeScript/PathMapping/test/test_foo.ts | -| test/test_foo.ts:2:17:2:32 | require("@/foo") | library-tests/TypeScript/PathMapping/src/lib/foo.ts | -| test/test_foo.ts:4:1:4:5 | foo() | foo in library-tests/TypeScript/PathMapping/src/lib/foo.ts | -| test/test_foo.ts:6:1:6:12 | foolib.foo() | foo in library-tests/TypeScript/PathMapping/src/lib/foo.ts | +| src/lib/foo.ts:1:1:4:0 | | src/lib/foo.ts | +| src/lib/foo.ts:1:8:3:1 | functio ... 123;\\n} | foo in src/lib/foo.ts | +| test/test_foo.ts:1:1:1:28 | import ... @/foo"; | src/lib/foo.ts | +| test/test_foo.ts:1:1:7:0 | | test/test_foo.ts | +| test/test_foo.ts:2:17:2:32 | require("@/foo") | src/lib/foo.ts | +| test/test_foo.ts:4:1:4:5 | foo() | foo in src/lib/foo.ts | +| test/test_foo.ts:6:1:6:12 | foolib.foo() | foo in src/lib/foo.ts | #select | test/test_foo.ts:1:1:1:28 | import ... @/foo"; | src/lib/foo.ts:1:1:4:0 | | | test/test_foo.ts:2:17:2:32 | require("@/foo") | src/lib/foo.ts:1:1:4:0 | | diff --git a/javascript/ql/test/library-tests/TypeScript/QualifiedNameResolution/Namespaces.expected b/javascript/ql/test/library-tests/TypeScript/QualifiedNameResolution/Namespaces.expected index 214b23594e7f..0494011bc70a 100644 --- a/javascript/ql/test/library-tests/TypeScript/QualifiedNameResolution/Namespaces.expected +++ b/javascript/ql/test/library-tests/TypeScript/QualifiedNameResolution/Namespaces.expected @@ -1,33 +1,33 @@ -| A in library-tests/TypeScript/QualifiedNameResolution/enums.ts | -| A in library-tests/TypeScript/QualifiedNameResolution/export-qualified.ts | -| A in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| A.B in library-tests/TypeScript/QualifiedNameResolution/export-qualified.ts | -| A.C in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| A.E in library-tests/TypeScript/QualifiedNameResolution/enums.ts | +| A in enums.ts | +| A in export-qualified.ts | +| A in namespaces.ts | +| A.B in export-qualified.ts | +| A.C in namespaces.ts | +| A.E in enums.ts | | B in namespaces.ts:3 | | B in namespaces.ts:10 | | B.Bx in namespaces.ts:3 | | B.Bx in namespaces.ts:10 | -| D in library-tests/TypeScript/QualifiedNameResolution/export-specifiers.ts | -| D in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| D in library-tests/TypeScript/QualifiedNameResolution/otherlib.ts | -| D.F in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | +| D in export-specifiers.ts | +| D in namespaces.ts | +| D in otherlib.ts | +| D.F in namespaces.ts | | E in namespaces.ts:17 | | E in namespaces.ts:22 | | Foo in global scope | -| G in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| G.J in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | +| G in namespaces.ts | +| G.J in namespaces.ts | | Glob in global scope | | H in namespaces.ts:27 | | H.I in namespaces.ts:27 | -| N in library-tests/TypeScript/QualifiedNameResolution/export-specifiers.ts | +| N in export-specifiers.ts | | X in global scope | -| X in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| X.Y in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| X.Y.Z in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | +| X in namespaces.ts | +| X.Y in namespaces.ts | +| X.Y.Z in namespaces.ts | | Y in global scope | -| library-tests/TypeScript/QualifiedNameResolution/export-class.ts | -| library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| library-tests/TypeScript/QualifiedNameResolution/otherlib.ts | -| library-tests/TypeScript/QualifiedNameResolution/reexport-all.ts | -| library-tests/TypeScript/QualifiedNameResolution/reexport-named.ts | +| export-class.ts | +| namespaces.ts | +| otherlib.ts | +| reexport-all.ts | +| reexport-named.ts | diff --git a/javascript/ql/test/library-tests/TypeScript/QualifiedNameResolution/ResolveNamespace.expected b/javascript/ql/test/library-tests/TypeScript/QualifiedNameResolution/ResolveNamespace.expected index 20df7b95bd9a..7ec8faec19ff 100644 --- a/javascript/ql/test/library-tests/TypeScript/QualifiedNameResolution/ResolveNamespace.expected +++ b/javascript/ql/test/library-tests/TypeScript/QualifiedNameResolution/ResolveNamespace.expected @@ -1,31 +1,31 @@ | ambient.ts:5:16:5:18 | Foo | Foo in global scope | -| enums.ts:9:8:9:8 | A | A in library-tests/TypeScript/QualifiedNameResolution/enums.ts | -| enums.ts:9:8:9:10 | A.E | A.E in library-tests/TypeScript/QualifiedNameResolution/enums.ts | -| enums.ts:10:8:10:8 | A | A in library-tests/TypeScript/QualifiedNameResolution/enums.ts | -| export-qualified-client.ts:3:8:3:9 | AB | A.B in library-tests/TypeScript/QualifiedNameResolution/export-qualified.ts | -| export-specifiers-client.ts:4:8:4:8 | N | N in library-tests/TypeScript/QualifiedNameResolution/export-specifiers.ts | -| export-specifiers-client.ts:5:8:5:8 | D | D in library-tests/TypeScript/QualifiedNameResolution/export-specifiers.ts | +| enums.ts:9:8:9:8 | A | A in enums.ts | +| enums.ts:9:8:9:10 | A.E | A.E in enums.ts | +| enums.ts:10:8:10:8 | A | A in enums.ts | +| export-qualified-client.ts:3:8:3:9 | AB | A.B in export-qualified.ts | +| export-specifiers-client.ts:4:8:4:8 | N | N in export-specifiers.ts | +| export-specifiers-client.ts:5:8:5:8 | D | D in export-specifiers.ts | | global.ts:5:9:5:12 | Glob | Glob in global scope | | import-in-namespace.ts:9:13:9:13 | A | X in global scope | -| namespaces-client.ts:4:9:4:10 | ns | library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| namespaces-client.ts:4:9:4:12 | ns.G | G in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| namespaces-client.ts:5:9:5:9 | G | G in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| namespaces-client.ts:6:9:6:9 | G | G in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| namespaces-client.ts:6:9:6:11 | G.J | G.J in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-all-client.ts:4:9:4:10 | ns | library-tests/TypeScript/QualifiedNameResolution/reexport-all.ts | -| reexport-all-client.ts:4:9:4:12 | ns.G | G in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-all-client.ts:5:9:5:9 | G | G in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-all-client.ts:6:9:6:9 | G | G in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-all-client.ts:6:9:6:11 | G.J | G.J in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-all-client.ts:8:8:8:8 | D | D in library-tests/TypeScript/QualifiedNameResolution/otherlib.ts | -| reexport-all-client.ts:9:8:9:9 | ns | library-tests/TypeScript/QualifiedNameResolution/reexport-all.ts | -| reexport-all-client.ts:9:8:9:11 | ns.D | D in library-tests/TypeScript/QualifiedNameResolution/otherlib.ts | -| reexport-all-client.ts:11:8:11:9 | ns | library-tests/TypeScript/QualifiedNameResolution/reexport-all.ts | -| reexport-named-client.ts:4:9:4:10 | ns | library-tests/TypeScript/QualifiedNameResolution/reexport-named.ts | -| reexport-named-client.ts:4:9:4:12 | ns.G | G in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-named-client.ts:5:9:5:9 | G | G in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-named-client.ts:6:9:6:9 | G | G in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-named-client.ts:6:9:6:11 | G.J | G.J in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-named-client.ts:8:8:8:8 | X | D in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-named-client.ts:9:8:9:9 | ns | library-tests/TypeScript/QualifiedNameResolution/reexport-named.ts | -| reexport-named-client.ts:9:8:9:11 | ns.X | D in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | +| namespaces-client.ts:4:9:4:10 | ns | namespaces.ts | +| namespaces-client.ts:4:9:4:12 | ns.G | G in namespaces.ts | +| namespaces-client.ts:5:9:5:9 | G | G in namespaces.ts | +| namespaces-client.ts:6:9:6:9 | G | G in namespaces.ts | +| namespaces-client.ts:6:9:6:11 | G.J | G.J in namespaces.ts | +| reexport-all-client.ts:4:9:4:10 | ns | reexport-all.ts | +| reexport-all-client.ts:4:9:4:12 | ns.G | G in namespaces.ts | +| reexport-all-client.ts:5:9:5:9 | G | G in namespaces.ts | +| reexport-all-client.ts:6:9:6:9 | G | G in namespaces.ts | +| reexport-all-client.ts:6:9:6:11 | G.J | G.J in namespaces.ts | +| reexport-all-client.ts:8:8:8:8 | D | D in otherlib.ts | +| reexport-all-client.ts:9:8:9:9 | ns | reexport-all.ts | +| reexport-all-client.ts:9:8:9:11 | ns.D | D in otherlib.ts | +| reexport-all-client.ts:11:8:11:9 | ns | reexport-all.ts | +| reexport-named-client.ts:4:9:4:10 | ns | reexport-named.ts | +| reexport-named-client.ts:4:9:4:12 | ns.G | G in namespaces.ts | +| reexport-named-client.ts:5:9:5:9 | G | G in namespaces.ts | +| reexport-named-client.ts:6:9:6:9 | G | G in namespaces.ts | +| reexport-named-client.ts:6:9:6:11 | G.J | G.J in namespaces.ts | +| reexport-named-client.ts:8:8:8:8 | X | D in namespaces.ts | +| reexport-named-client.ts:9:8:9:9 | ns | reexport-named.ts | +| reexport-named-client.ts:9:8:9:11 | ns.X | D in namespaces.ts | diff --git a/javascript/ql/test/library-tests/TypeScript/QualifiedNameResolution/ResolveTypeName.expected b/javascript/ql/test/library-tests/TypeScript/QualifiedNameResolution/ResolveTypeName.expected index 008b2cbbbeb0..1629bdac5b15 100644 --- a/javascript/ql/test/library-tests/TypeScript/QualifiedNameResolution/ResolveTypeName.expected +++ b/javascript/ql/test/library-tests/TypeScript/QualifiedNameResolution/ResolveTypeName.expected @@ -1,27 +1,27 @@ | ambient.ts:5:16:5:20 | Foo.C | Foo.C in global scope | -| enums.ts:9:8:9:12 | A.E.x | A.E.x in library-tests/TypeScript/QualifiedNameResolution/enums.ts | -| enums.ts:10:8:10:10 | A.E | A.E in library-tests/TypeScript/QualifiedNameResolution/enums.ts | -| export-class-client-renamed.ts:3:8:3:8 | X | Banana in library-tests/TypeScript/QualifiedNameResolution/export-class.ts | -| export-class-client.ts:3:8:3:13 | Banana | Banana in library-tests/TypeScript/QualifiedNameResolution/export-class.ts | -| export-qualified-client.ts:3:8:3:11 | AB.C | A.B.C in library-tests/TypeScript/QualifiedNameResolution/export-qualified.ts | -| export-specifiers-client.ts:4:8:4:10 | N.C | N.C in library-tests/TypeScript/QualifiedNameResolution/export-specifiers.ts | -| export-specifiers-client.ts:5:8:5:10 | D.C | D.C in library-tests/TypeScript/QualifiedNameResolution/export-specifiers.ts | -| export-specifiers-client.ts:6:8:6:8 | C | C in library-tests/TypeScript/QualifiedNameResolution/export-specifiers.ts | +| enums.ts:9:8:9:12 | A.E.x | A.E.x in enums.ts | +| enums.ts:10:8:10:10 | A.E | A.E in enums.ts | +| export-class-client-renamed.ts:3:8:3:8 | X | Banana in export-class.ts | +| export-class-client.ts:3:8:3:13 | Banana | Banana in export-class.ts | +| export-qualified-client.ts:3:8:3:11 | AB.C | A.B.C in export-qualified.ts | +| export-specifiers-client.ts:4:8:4:10 | N.C | N.C in export-specifiers.ts | +| export-specifiers-client.ts:5:8:5:10 | D.C | D.C in export-specifiers.ts | +| export-specifiers-client.ts:6:8:6:8 | C | C in export-specifiers.ts | | global.ts:5:9:5:14 | Glob.C | Glob.C in global scope | | import-in-namespace.ts:9:13:9:15 | A.C | X.C in global scope | | import-in-namespace.ts:10:13:10:13 | D | X.C in global scope | -| namespaces-client.ts:4:9:4:14 | ns.G.C | G.C in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| namespaces-client.ts:5:9:5:11 | G.C | G.C in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| namespaces-client.ts:6:9:6:13 | G.J.C | G.J.C in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-all-client.ts:4:9:4:14 | ns.G.C | G.C in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-all-client.ts:5:9:5:11 | G.C | G.C in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-all-client.ts:6:9:6:13 | G.J.C | G.J.C in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | +| namespaces-client.ts:4:9:4:14 | ns.G.C | G.C in namespaces.ts | +| namespaces-client.ts:5:9:5:11 | G.C | G.C in namespaces.ts | +| namespaces-client.ts:6:9:6:13 | G.J.C | G.J.C in namespaces.ts | +| reexport-all-client.ts:4:9:4:14 | ns.G.C | G.C in namespaces.ts | +| reexport-all-client.ts:5:9:5:11 | G.C | G.C in namespaces.ts | +| reexport-all-client.ts:6:9:6:13 | G.J.C | G.J.C in namespaces.ts | | reexport-all-client.ts:8:8:8:10 | D.F | D.F in unknown scope | | reexport-all-client.ts:9:8:9:13 | ns.D.F | ns.D.F in unknown scope | -| reexport-all-client.ts:11:8:11:16 | ns.Banana | Banana in library-tests/TypeScript/QualifiedNameResolution/export-class.ts | -| reexport-named-client.ts:4:9:4:14 | ns.G.C | G.C in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-named-client.ts:5:9:5:11 | G.C | G.C in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | -| reexport-named-client.ts:6:9:6:13 | G.J.C | G.J.C in library-tests/TypeScript/QualifiedNameResolution/namespaces.ts | +| reexport-all-client.ts:11:8:11:16 | ns.Banana | Banana in export-class.ts | +| reexport-named-client.ts:4:9:4:14 | ns.G.C | G.C in namespaces.ts | +| reexport-named-client.ts:5:9:5:11 | G.C | G.C in namespaces.ts | +| reexport-named-client.ts:6:9:6:13 | G.J.C | G.J.C in namespaces.ts | | reexport-named-client.ts:8:8:8:10 | X.F | X.F in unknown scope | | reexport-named-client.ts:9:8:9:13 | ns.X.F | ns.X.F in unknown scope | -| reexport-named-client.ts:11:9:11:9 | Y | Banana in library-tests/TypeScript/QualifiedNameResolution/export-class.ts | +| reexport-named-client.ts:11:9:11:9 | Y | Banana in export-class.ts | diff --git a/javascript/ql/test/library-tests/TypeScript/RegressionTests/EmptyName/test.expected b/javascript/ql/test/library-tests/TypeScript/RegressionTests/EmptyName/test.expected index 47317a00a867..85cb86df42a2 100644 --- a/javascript/ql/test/library-tests/TypeScript/RegressionTests/EmptyName/test.expected +++ b/javascript/ql/test/library-tests/TypeScript/RegressionTests/EmptyName/test.expected @@ -1,4 +1,4 @@ | MK in unknown scope | -| Mapped in library-tests/TypeScript/RegressionTests/EmptyName/test.ts | -| fn in library-tests/TypeScript/RegressionTests/EmptyName/test.ts | -| library-tests/TypeScript/RegressionTests/EmptyName/test.ts | +| Mapped in test.ts | +| fn in test.ts | +| test.ts | diff --git a/javascript/ql/test/library-tests/TypeScript/RegressionTests/ExportEqualsExpr/test.expected b/javascript/ql/test/library-tests/TypeScript/RegressionTests/ExportEqualsExpr/test.expected index 3736c602bc32..24fc12058753 100644 --- a/javascript/ql/test/library-tests/TypeScript/RegressionTests/ExportEqualsExpr/test.expected +++ b/javascript/ql/test/library-tests/TypeScript/RegressionTests/ExportEqualsExpr/test.expected @@ -1,7 +1,7 @@ | "bar" in global scope | | C in module 'bar' | | Foo in global scope | -| Foo in library-tests/TypeScript/RegressionTests/ExportEqualsExpr/tst.ts | -| library-tests/TypeScript/RegressionTests/ExportEqualsExpr/tst.ts | +| Foo in tst.ts | | module 'bar' | | module 'foo' | +| tst.ts | diff --git a/javascript/ql/test/library-tests/TypeScript/RegressionTests/SemicolonInName/test.expected b/javascript/ql/test/library-tests/TypeScript/RegressionTests/SemicolonInName/test.expected index 074e6d0c2777..603eaba0d279 100644 --- a/javascript/ql/test/library-tests/TypeScript/RegressionTests/SemicolonInName/test.expected +++ b/javascript/ql/test/library-tests/TypeScript/RegressionTests/SemicolonInName/test.expected @@ -1,2 +1,2 @@ | Bar.Foo in global scope | Bar in global scope | -| fn in library-tests/TypeScript/RegressionTests/SemicolonInName/test.ts | library-tests/TypeScript/RegressionTests/SemicolonInName/test.ts | +| fn in test.ts | test.ts | diff --git a/javascript/ql/test/library-tests/TypeScript/SyntaxErrors/SyntaxErrors.expected b/javascript/ql/test/library-tests/TypeScript/SyntaxErrors/SyntaxErrors.expected index 58e88ed6fe11..cca870438e91 100644 --- a/javascript/ql/test/library-tests/TypeScript/SyntaxErrors/SyntaxErrors.expected +++ b/javascript/ql/test/library-tests/TypeScript/SyntaxErrors/SyntaxErrors.expected @@ -1 +1 @@ -| library-tests/TypeScript/SyntaxErrors/jsdocTypes.ts | This file contains a parse error | +| jsdocTypes.ts | This file contains a parse error | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/tests.expected b/javascript/ql/test/library-tests/TypeScript/Types/tests.expected index 1cf1ca607ae3..b786fae3713e 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/tests.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/tests.expected @@ -1,7 +1,7 @@ booleans | boolean | getExprType -| boolean-type.ts:1:13:1:17 | dummy | typeof library-tests/TypeScript/Types/dummy.ts | +| boolean-type.ts:1:13:1:17 | dummy | typeof dummy.ts | | boolean-type.ts:1:24:1:32 | "./dummy" | any | | boolean-type.ts:3:5:3:9 | true1 | true | | boolean-type.ts:4:5:4:9 | true2 | true | @@ -24,7 +24,7 @@ getExprType | middle-rest.ts:3:8:3:11 | true | true | | middle-rest.ts:3:14:3:20 | "hello" | "hello" | | middle-rest.ts:3:23:3:25 | 123 | 123 | -| tst.ts:1:13:1:17 | dummy | typeof library-tests/TypeScript/Types/dummy.ts | +| tst.ts:1:13:1:17 | dummy | typeof dummy.ts | | tst.ts:1:24:1:32 | "./dummy" | any | | tst.ts:3:5:3:10 | numVar | number | | tst.ts:5:5:5:8 | num1 | number | @@ -127,7 +127,7 @@ getExprType | tst.ts:69:24:69:45 | {yetAno ... : true} | MyUnion2 | | tst.ts:69:25:69:38 | yetAnotherType | true | | tst.ts:69:41:69:44 | true | true | -| tst.ts:71:8:71:11 | TS43 | typeof TS43 in library-tests/TypeScript/Types/tst.ts | +| tst.ts:71:8:71:11 | TS43 | typeof TS43 in tst.ts | | tst.ts:74:5:74:22 | get size(): number | number | | tst.ts:74:9:74:12 | size | number | | tst.ts:75:5:75:47 | set siz ... olean); | number | @@ -175,7 +175,7 @@ getExprType | tst.ts:126:7:126:22 | this.#someMethod | () => number | | tst.ts:126:7:126:24 | this.#someMethod() | number | | tst.ts:127:14:127:28 | this.#someValue | number | -| tst.ts:132:8:132:11 | TS44 | typeof TS44 in library-tests/TypeScript/Types/tst.ts | +| tst.ts:132:8:132:11 | TS44 | typeof TS44 in tst.ts | | tst.ts:133:12:133:14 | foo | (arg: unknown) => void | | tst.ts:133:16:133:18 | arg | unknown | | tst.ts:134:11:134:21 | argIsString | boolean | @@ -260,7 +260,7 @@ getExprType | tst.ts:189:11:189:15 | count | number | | tst.ts:189:19:189:21 | Foo | typeof Foo in tst.ts:132 | | tst.ts:189:19:189:28 | Foo.#count | number | -| tst.ts:195:8:195:11 | TS45 | typeof TS45 in library-tests/TypeScript/Types/tst.ts | +| tst.ts:195:8:195:11 | TS45 | typeof TS45 in tst.ts | | tst.ts:207:5:207:8 | body | string | | tst.ts:212:7:212:13 | message | string | | tst.ts:215:19:215:25 | handler | (r: Success \| Error) => void | @@ -301,7 +301,7 @@ getExprType | tst.ts:238:11:238:14 | Foo3 | { foo: string; } | | tst.ts:238:11:238:18 | Foo3.foo | string | | tst.ts:238:16:238:18 | foo | string | -| tst.ts:240:8:240:11 | TS46 | typeof TS46 in library-tests/TypeScript/Types/tst.ts | +| tst.ts:240:8:240:11 | TS46 | typeof TS46 in tst.ts | | tst.ts:241:9:241:12 | Base | Base | | tst.ts:243:9:243:15 | Derived | Derived | | tst.ts:243:25:243:28 | Base | Base | @@ -481,27 +481,27 @@ getExprType | tst.ts:362:9:362:11 | log | (...data: any[]) => void | | tst.ts:362:13:362:24 | tstModuleCJS | () => "a" \| "b" | | tst.ts:362:13:362:26 | tstModuleCJS() | "a" \| "b" | -| tst.ts:368:13:368:13 | A | typeof library-tests/TypeScript/Types/tstSuffixA.ts | +| tst.ts:368:13:368:13 | A | typeof tstSuffixA.ts | | tst.ts:368:20:368:33 | './tstSuffixA' | any | | tst.ts:370:1:370:7 | console | Console | | tst.ts:370:1:370:11 | console.log | (...data: any[]) => void | | tst.ts:370:1:370:29 | console ... File()) | void | | tst.ts:370:9:370:11 | log | (...data: any[]) => void | -| tst.ts:370:13:370:13 | A | typeof library-tests/TypeScript/Types/tstSuffixA.ts | +| tst.ts:370:13:370:13 | A | typeof tstSuffixA.ts | | tst.ts:370:13:370:26 | A.resolvedFile | () => "tstSuffixA.ts" | | tst.ts:370:13:370:28 | A.resolvedFile() | "tstSuffixA.ts" | | tst.ts:370:15:370:26 | resolvedFile | () => "tstSuffixA.ts" | -| tst.ts:372:13:372:13 | B | typeof library-tests/TypeScript/Types/tstSuffixB.ios.ts | +| tst.ts:372:13:372:13 | B | typeof tstSuffixB.ios.ts | | tst.ts:372:20:372:33 | './tstSuffixB' | any | | tst.ts:374:1:374:7 | console | Console | | tst.ts:374:1:374:11 | console.log | (...data: any[]) => void | | tst.ts:374:1:374:29 | console ... File()) | void | | tst.ts:374:9:374:11 | log | (...data: any[]) => void | -| tst.ts:374:13:374:13 | B | typeof library-tests/TypeScript/Types/tstSuffixB.ios.ts | +| tst.ts:374:13:374:13 | B | typeof tstSuffixB.ios.ts | | tst.ts:374:13:374:26 | B.resolvedFile | () => "tstSuffixB.ios.ts" | | tst.ts:374:13:374:28 | B.resolvedFile() | "tstSuffixB.ios.ts" | | tst.ts:374:15:374:26 | resolvedFile | () => "tstSuffixB.ios.ts" | -| tst.ts:379:8:379:11 | TS48 | typeof TS48 in library-tests/TypeScript/Types/tst.ts | +| tst.ts:379:8:379:11 | TS48 | typeof TS48 in tst.ts | | tst.ts:383:22:383:35 | chooseRandomly | (x: T, y: T) => T | | tst.ts:383:40:383:40 | x | T | | tst.ts:383:46:383:46 | y | T | @@ -518,7 +518,7 @@ getExprType | tst.ts:385:56:385:56 | 0 | 0 | | tst.ts:385:59:385:63 | false | false | | tst.ts:385:66:385:71 | "bye!" | "bye!" | -| tst.ts:390:8:390:11 | TS49 | typeof TS49 in library-tests/TypeScript/Types/tst.ts | +| tst.ts:390:8:390:11 | TS49 | typeof TS49 in tst.ts | | tst.ts:395:9:395:15 | palette | { red: [number, number, number]; green: string;... | | tst.ts:395:19:399:3 | {\\n r ... 5],\\n } | Record | | tst.ts:395:19:399:42 | {\\n r ... \| RGB> | { red: [number, number, number]; green: string;... | @@ -559,7 +559,7 @@ getExprType | tst.ts:423:7:423:22 | this.name = name | string | | tst.ts:423:12:423:15 | name | string | | tst.ts:423:19:423:22 | name | string | -| tst.ts:430:8:430:11 | TS50 | typeof TS50 in library-tests/TypeScript/Types/tst.ts | +| tst.ts:430:8:430:11 | TS50 | typeof TS50 in tst.ts | | tst.ts:432:33:432:36 | args | Args | | tst.ts:433:68:433:71 | args | Args | | tst.ts:435:15:435:24 | methodName | string | @@ -632,7 +632,7 @@ getExprType | tst.ts:467:15:467:17 | foo | readonly ["a", "b", "c"] | | tst.ts:467:15:467:20 | foo[1] | "b" | | tst.ts:467:19:467:19 | 1 | 1 | -| tst.ts:472:8:472:11 | TS52 | typeof TS52 in library-tests/TypeScript/Types/tst.ts | +| tst.ts:472:8:472:11 | TS52 | typeof TS52 in tst.ts | | tst.ts:473:11:473:19 | SomeClass | SomeClass | | tst.ts:474:10:474:36 | ((_targ ... => {}) | (_target: undefined, _context: ClassFieldDecora... | | tst.ts:474:11:474:35 | (_targe ... ) => {} | (_target: undefined, _context: ClassFieldDecora... | @@ -657,7 +657,7 @@ getExprType | tst.ts:483:17:483:58 | ["hello ... string> | [first: string, string] | | tst.ts:483:18:483:24 | "hello" | "hello" | | tst.ts:483:27:483:33 | "world" | "world" | -| tst.ts:486:8:486:11 | TS54 | typeof TS54 in library-tests/TypeScript/Types/tst.ts | +| tst.ts:486:8:486:11 | TS54 | typeof TS54 in tst.ts | | tst.ts:487:48:487:53 | colors | C[] | | tst.ts:488:12:488:17 | colors | C[] | | tst.ts:488:12:488:20 | colors[0] | C | @@ -691,7 +691,7 @@ getExprType | tst.ts:494:24:494:24 | 0 | 0 | | tst.ts:494:28:494:33 | "even" | "even" | | tst.ts:494:36:494:40 | "odd" | "odd" | -| tst.ts:498:8:498:11 | TS55 | typeof TS55 in library-tests/TypeScript/Types/tst.ts | +| tst.ts:498:8:498:11 | TS55 | typeof TS55 in tst.ts | | tst.ts:499:9:499:15 | strings | string[] | | tst.ts:499:19:499:32 | (["foo", 123]) | (string \| number)[] | | tst.ts:499:19:500:11 | (["foo" ... .filter | { (predicate: (value... | @@ -779,18 +779,18 @@ getExprType | type_alias.ts:26:19:26:20 | id | string | | type_alias.ts:26:23:26:36 | "second-child" | "second-child" | | type_alias.ts:26:41:26:62 | "I'm th ... child" | "I'm the second child" | -| type_definition_objects.ts:1:13:1:17 | dummy | typeof library-tests/TypeScript/Types/dummy.ts | +| type_definition_objects.ts:1:13:1:17 | dummy | typeof dummy.ts | | type_definition_objects.ts:1:24:1:32 | "./dummy" | any | | type_definition_objects.ts:3:14:3:14 | C | C | -| type_definition_objects.ts:4:5:4:12 | classObj | typeof C in library-tests/TypeScript/Types/type_definition_objects.ts | -| type_definition_objects.ts:4:16:4:16 | C | typeof C in library-tests/TypeScript/Types/type_definition_objects.ts | +| type_definition_objects.ts:4:5:4:12 | classObj | typeof C in type_definition_objects.ts | +| type_definition_objects.ts:4:16:4:16 | C | typeof C in type_definition_objects.ts | | type_definition_objects.ts:6:13:6:13 | E | E | -| type_definition_objects.ts:7:5:7:11 | enumObj | typeof E in library-tests/TypeScript/Types/type_definition_objects.ts | -| type_definition_objects.ts:7:15:7:15 | E | typeof E in library-tests/TypeScript/Types/type_definition_objects.ts | -| type_definition_objects.ts:9:18:9:18 | N | typeof N in library-tests/TypeScript/Types/type_definition_objects.ts | -| type_definition_objects.ts:10:5:10:16 | namespaceObj | typeof N in library-tests/TypeScript/Types/type_definition_objects.ts | -| type_definition_objects.ts:10:20:10:20 | N | typeof N in library-tests/TypeScript/Types/type_definition_objects.ts | -| type_definitions.ts:1:13:1:17 | dummy | typeof library-tests/TypeScript/Types/dummy.ts | +| type_definition_objects.ts:7:5:7:11 | enumObj | typeof E in type_definition_objects.ts | +| type_definition_objects.ts:7:15:7:15 | E | typeof E in type_definition_objects.ts | +| type_definition_objects.ts:9:18:9:18 | N | typeof N in type_definition_objects.ts | +| type_definition_objects.ts:10:5:10:16 | namespaceObj | typeof N in type_definition_objects.ts | +| type_definition_objects.ts:10:20:10:20 | N | typeof N in type_definition_objects.ts | +| type_definitions.ts:1:13:1:17 | dummy | typeof dummy.ts | | type_definitions.ts:1:24:1:32 | "./dummy" | any | | type_definitions.ts:4:3:4:3 | x | S | | type_definitions.ts:6:5:6:5 | i | I | diff --git a/javascript/ql/test/query-tests/Metrics/ExternalDependencies/ExternalDependencies.expected b/javascript/ql/test/query-tests/Metrics/ExternalDependencies/ExternalDependencies.expected index d690d12e11b1..39b6d8ffcad8 100644 --- a/javascript/ql/test/query-tests/Metrics/ExternalDependencies/ExternalDependencies.expected +++ b/javascript/ql/test/query-tests/Metrics/ExternalDependencies/ExternalDependencies.expected @@ -1,9 +1,9 @@ -| /query-tests/Metrics/ExternalDependencies/src/tst.html<\|>jquery<\|>23.0.0 | 4 | -| /query-tests/Metrics/ExternalDependencies/src/a.js<\|>lib3<\|>unknown | 3 | -| /query-tests/Metrics/ExternalDependencies/src/tst.html<\|>jquery<\|>42.0.0 | 3 | -| /query-tests/Metrics/ExternalDependencies/src/a.js<\|>lib1<\|>1.0.2 | 2 | -| /query-tests/Metrics/ExternalDependencies/src/b.js<\|>lib3<\|>unknown | 2 | -| /query-tests/Metrics/ExternalDependencies/src/a.js<\|>lib2<\|>1.0.0 | 1 | -| /query-tests/Metrics/ExternalDependencies/src/b.js<\|>lib2<\|>1.0.0 | 1 | -| /query-tests/Metrics/ExternalDependencies/src/sub/c.js<\|>lib1<\|>1.0.2 | 1 | -| /query-tests/Metrics/ExternalDependencies/src/sub/subsub/d.js<\|>lib1<\|>1.0.3 | 1 | +| /src/tst.html<\|>jquery<\|>23.0.0 | 4 | +| /src/a.js<\|>lib3<\|>unknown | 3 | +| /src/tst.html<\|>jquery<\|>42.0.0 | 3 | +| /src/a.js<\|>lib1<\|>1.0.2 | 2 | +| /src/b.js<\|>lib3<\|>unknown | 2 | +| /src/a.js<\|>lib2<\|>1.0.0 | 1 | +| /src/b.js<\|>lib2<\|>1.0.0 | 1 | +| /src/sub/c.js<\|>lib1<\|>1.0.2 | 1 | +| /src/sub/subsub/d.js<\|>lib1<\|>1.0.3 | 1 | diff --git a/javascript/ql/test/query-tests/NodeJS/CyclicImport/CyclicImport.expected b/javascript/ql/test/query-tests/NodeJS/CyclicImport/CyclicImport.expected index c19bb2303441..2fb5f863389e 100644 --- a/javascript/ql/test/query-tests/NodeJS/CyclicImport/CyclicImport.expected +++ b/javascript/ql/test/query-tests/NodeJS/CyclicImport/CyclicImport.expected @@ -1,7 +1,7 @@ | a.js:4:9:4:25 | require('./b.js') | Module a imports module b, which in turn $@ it. | b.js:4:9:4:25 | require('./a.js') | imports | | b.js:4:9:4:25 | require('./a.js') | Module b imports module a, which in turn $@ it. | a.js:4:9:4:25 | require('./b.js') | imports | | selfimport.js:1:1:1:23 | require ... mport') | Module selfimport directly imports itself. | selfimport.js:1:1:1:24 | | | -| test1/a.js:1:1:1:27 | require ... ner/a') | Module .../test1/a.js imports module .../inner/a.js, which in turn $@ it. | test2/inner/a.js:1:1:1:24 | require ... st1/a') | imports | +| test1/a.js:1:1:1:27 | require ... ner/a') | Module /test1/a.js imports module .../inner/a.js, which in turn $@ it. | test2/inner/a.js:1:1:1:24 | require ... st1/a') | imports | | test1/a.js:2:1:2:14 | require('./b') | Module a imports module b, which in turn $@ it. | test1/b.js:1:1:1:27 | require ... ner/a') | indirectly imports | | test1/b.js:1:1:1:27 | require ... ner/a') | Module b imports module a, which in turn $@ it. | test2/inner/a.js:1:1:1:24 | require ... st1/a') | indirectly imports | -| test2/inner/a.js:1:1:1:24 | require ... st1/a') | Module .../inner/a.js imports module .../test1/a.js, which in turn $@ it. | test1/a.js:1:1:1:27 | require ... ner/a') | imports | +| test2/inner/a.js:1:1:1:24 | require ... st1/a') | Module .../inner/a.js imports module /test1/a.js, which in turn $@ it. | test1/a.js:1:1:1:27 | require ... ner/a') | imports | diff --git a/javascript/ql/test/query-tests/Security/CWE-200/PrivateFileExposure.expected b/javascript/ql/test/query-tests/Security/CWE-200/PrivateFileExposure.expected index 3cf199ce3714..39a5a884af13 100644 --- a/javascript/ql/test/query-tests/Security/CWE-200/PrivateFileExposure.expected +++ b/javascript/ql/test/query-tests/Security/CWE-200/PrivateFileExposure.expected @@ -1,6 +1,6 @@ -| lib/tst.js:7:1:7:45 | app.use ... rname)) | Serves the folder query-tests/Security/CWE-200/lib, which can contain private information. | -| lib/tst.js:9:1:9:43 | app.use ... otDir)) | Serves the folder query-tests/Security/CWE-200/lib, which can contain private information. | -| lib/tst.js:11:1:11:52 | app.use ... + '/')) | Serves the folder query-tests/Security/CWE-200/lib, which can contain private information. | +| lib/tst.js:7:1:7:45 | app.use ... rname)) | Serves the folder lib, which can contain private information. | +| lib/tst.js:9:1:9:43 | app.use ... otDir)) | Serves the folder lib, which can contain private information. | +| lib/tst.js:11:1:11:52 | app.use ... + '/')) | Serves the folder lib, which can contain private information. | | private-file-exposure.js:8:1:8:49 | app.use ... ular')) | Serves the folder "./node_modules/angular", which can contain private information. | | private-file-exposure.js:9:1:9:59 | app.use ... ular')) | Serves the folder "node_modules/angular", which can contain private information. | | private-file-exposure.js:10:1:10:67 | app.use ... mate')) | Serves the folder "node_modules/angular-animate", which can contain private information. | @@ -20,4 +20,4 @@ | private-file-exposure.js:43:1:43:46 | app.use ... )("/")) | Serves the root folder, which can contain private information. | | private-file-exposure.js:51:5:51:88 | app.use ... les'))) | Serves the folder "../node_modules", which can contain private information. | | private-file-exposure.js:70:5:70:71 | serveHa ... ular"}) | Serves the folder "./node_modules/angular", which can contain private information. | -| subfolder/private-file-exposure-2.js:6:1:6:34 | app.use ... rname)) | Serves the folder query-tests/Security/CWE-200/subfolder, which can contain private information. | +| subfolder/private-file-exposure-2.js:6:1:6:34 | app.use ... rname)) | Serves the folder subfolder, which can contain private information. | diff --git a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/tests.expected b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/tests.expected index d9f7f8005021..bd22abd7c823 100644 --- a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/tests.expected +++ b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/tests.expected @@ -1,7 +1,5 @@ test_query1 -| | 0 | -| tutorials | 0 | -| tutorials/Introducing the JavaScript libraries | 2 | +| | 2 | test_query3 | tst.js:27:1:27:4 |