Rust: Avoid location-based variable analysis

This commit is contained in:
Tom Hvitved
2025-01-08 13:57:57 +01:00
parent d03b284a0a
commit 33e6d6392c
10 changed files with 336 additions and 187 deletions

View File

@@ -165,7 +165,7 @@ module Impl {
/**
* A path expression that may access a local variable. These are paths that
* only consists of a simple name (i.e., without generic arguments,
* only consist of a simple name (i.e., without generic arguments,
* qualifiers, etc.).
*/
private class VariableAccessCand extends PathExprBase {
@@ -231,23 +231,115 @@ module Impl {
)
}
/** A subset of `Element`s for which we want to compute pre-order numbers. */
private class RelevantElement extends Element {
RelevantElement() {
this instanceof VariableScope or
this instanceof VariableAccessCand or
this instanceof LetStmt or
getImmediateChildAndAccessor(this, _, _) instanceof RelevantElement
}
pragma[nomagic]
private RelevantElement getChild(int index) {
result = getImmediateChildAndAccessor(this, index, _)
}
pragma[nomagic]
private RelevantElement getImmediateChildMin(int index) {
// A child may have multiple positions for different accessors,
// so always use the first
result = this.getChild(index) and
index = min(int i | result = this.getChild(i) | i)
}
pragma[nomagic]
RelevantElement getImmediateChild(int index) {
result =
rank[index + 1](Element res, int i | res = this.getImmediateChildMin(i) | res order by i)
}
pragma[nomagic]
RelevantElement getImmediateLastChild() {
exists(int last |
result = this.getImmediateChild(last) and
not exists(this.getImmediateChild(last + 1))
)
}
}
/**
* Gets the pre-order numbering of `n`, where the immediately enclosing
* variable scope of `n` is `scope`.
*/
pragma[nomagic]
private int getPreOrderNumbering(VariableScope scope, RelevantElement n) {
n = scope and
result = 0
or
exists(RelevantElement parent |
not parent instanceof VariableScope
or
parent = scope
|
// first child of a previously numbered node
result = getPreOrderNumbering(scope, parent) + 1 and
n = parent.getImmediateChild(0)
or
// non-first child of a previously numbered node
exists(RelevantElement child, int i |
result = getLastPreOrderNumbering(scope, child) + 1 and
child = parent.getImmediateChild(i) and
n = parent.getImmediateChild(i + 1)
)
)
}
/**
* Gets the pre-order numbering of the _last_ node nested under `n`, where the
* immediately enclosing variable scope of `n` (and the last node) is `scope`.
*/
pragma[nomagic]
private int getLastPreOrderNumbering(VariableScope scope, RelevantElement n) {
exists(RelevantElement leaf |
result = getPreOrderNumbering(scope, leaf) and
leaf != scope and
(
not exists(leaf.getImmediateChild(_))
or
leaf instanceof VariableScope
)
|
n = leaf
or
n.getImmediateLastChild() = leaf and
not n instanceof VariableScope
)
or
exists(RelevantElement mid |
mid = n.getImmediateLastChild() and
result = getLastPreOrderNumbering(scope, mid) and
not mid instanceof VariableScope and
not n instanceof VariableScope
)
}
/**
* Holds if `v` is named `name` and is declared inside variable scope
* `scope`, and `v` is bound starting from `(line, column)`.
* `scope`. The pre-order numbering of the binding site of `v`, amongst
* all nodes nester under `scope`, is `ord`.
*/
private predicate variableDeclInScope(
Variable v, VariableScope scope, string name, int line, int column
) {
private predicate variableDeclInScope(Variable v, VariableScope scope, string name, int ord) {
name = v.getName() and
(
parameterDeclInScope(v, scope) and
scope.getLocation().hasLocationFileInfo(_, line, column, _, _)
ord = getPreOrderNumbering(scope, scope)
or
exists(Pat pat | pat = getAVariablePatAncestor(v) |
scope =
any(MatchArmScope arm |
arm.getPat() = pat and
arm.getLocation().hasLocationFileInfo(_, line, column, _, _)
ord = getPreOrderNumbering(scope, arm)
)
or
exists(LetStmt let |
@@ -255,56 +347,53 @@ module Impl {
scope = getEnclosingScope(let) and
// for `let` statements, variables are bound _after_ the statement, i.e.
// not in the RHS
let.getLocation().hasLocationFileInfo(_, _, _, line, column)
ord = getLastPreOrderNumbering(scope, let) + 1
)
or
exists(IfExpr ie, LetExpr let |
let.getPat() = pat and
ie.getCondition() = let and
scope = ie.getThen() and
scope.getLocation().hasLocationFileInfo(_, line, column, _, _)
ord = getPreOrderNumbering(scope, scope)
)
or
exists(ForExpr fe |
fe.getPat() = pat and
scope = fe.getLoopBody() and
scope.getLocation().hasLocationFileInfo(_, line, column, _, _)
ord = getPreOrderNumbering(scope, scope)
)
or
exists(WhileExpr we, LetExpr let |
let.getPat() = pat and
we.getCondition() = let and
scope = we.getLoopBody() and
scope.getLocation().hasLocationFileInfo(_, line, column, _, _)
ord = getPreOrderNumbering(scope, scope)
)
)
)
}
/**
* Holds if `cand` may access a variable named `name` at
* `(startline, startcolumn, endline, endcolumn)` in the variable scope
* `scope`.
* Holds if `cand` may access a variable named `name` at pre-order number `ord`
* 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
VariableAccessCand cand, VariableScope scope, string name, int nestLevel, int ord
) {
name = cand.getName() and
scope = [cand.(VariableScope), getEnclosingScope(cand)] and
cand.getLocation().hasLocationFileInfo(_, startline, startcolumn, endline, endcolumn) and
ord = getPreOrderNumbering(scope, cand) and
nestLevel = 0
or
exists(VariableScope inner |
variableAccessCandInScope(cand, inner, name, nestLevel - 1, _, _, _, _) and
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
inner.getLocation().hasLocationFileInfo(_, startline, startcolumn, endline, endcolumn)
// Use the pre-order number of the inner scope as the number of the access. This allows
// us to collapse multiple accesses in inner scopes to a single entity
ord = getPreOrderNumbering(scope, inner)
)
}
@@ -375,15 +464,12 @@ module Impl {
}
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
predicate rankBy(string name, VariableScope scope, int ord, int kind) {
variableDeclInScope(this.asVariable(), scope, name, ord) and
kind = 0
or
variableAccessCandInScope(this.asVariableAccessCand(), scope, name, _, startline, startcolumn,
endline, endcolumn)
variableAccessCandInScope(this.asVariableAccessCand(), scope, name, _, ord) and
kind = 1
}
}
@@ -396,11 +482,10 @@ module Impl {
int getRank(VariableScope scope, string name, VariableOrAccessCand v) {
v =
rank[result](VariableOrAccessCand v0, int startline, int startcolumn, int endline,
int endcolumn |
v0.rankBy(name, scope, startline, startcolumn, endline, endcolumn)
rank[result](VariableOrAccessCand v0, int ord, int kind |
v0.rankBy(name, scope, ord, kind)
|
v0 order by startline, startcolumn, endline, endcolumn
v0 order by ord, kind
)
}
}
@@ -440,7 +525,7 @@ module Impl {
exists(int rnk |
variableReachesRank(scope, name, v, rnk) and
rnk = rankVariableOrAccess(scope, name, TVariableOrAccessCandVariableAccessCand(cand)) and
variableAccessCandInScope(cand, scope, name, nestLevel, _, _, _, _)
variableAccessCandInScope(cand, scope, name, nestLevel, _)
)
}

View File

@@ -1,6 +1,7 @@
models
| 1 | Summary: lang:alloc; <crate::string::String>::as_str; Argument[self]; ReturnValue; taint |
| 2 | Summary: lang:alloc; crate::fmt::format; Argument[0]; ReturnValue; taint |
| 3 | Summary: lang:core; crate::hint::must_use; Argument[0]; ReturnValue; value |
edges
| main.rs:26:9:26:9 | s | main.rs:27:19:27:25 | s[...] | provenance | |
| main.rs:26:13:26:22 | source(...) | main.rs:26:9:26:9 | s | provenance | |
@@ -27,6 +28,19 @@ edges
| main.rs:77:9:77:18 | formatted3 | main.rs:78:10:78:19 | formatted3 | provenance | |
| main.rs:77:22:77:75 | ...::format(...) | main.rs:77:9:77:18 | formatted3 | provenance | |
| main.rs:77:34:77:74 | MacroExpr | main.rs:77:22:77:75 | ...::format(...) | provenance | MaD:2 |
| main.rs:82:9:82:10 | s1 | main.rs:86:18:86:25 | MacroExpr | provenance | |
| main.rs:82:9:82:10 | s1 | main.rs:87:18:87:32 | MacroExpr | provenance | |
| main.rs:82:14:82:23 | source(...) | main.rs:82:9:82:10 | s1 | provenance | |
| main.rs:86:10:86:26 | res | main.rs:86:18:86:25 | { ... } | provenance | |
| main.rs:86:18:86:25 | ...::format(...) | main.rs:86:10:86:26 | res | provenance | |
| main.rs:86:18:86:25 | ...::must_use(...) | main.rs:86:10:86:26 | MacroExpr | provenance | |
| main.rs:86:18:86:25 | MacroExpr | main.rs:86:18:86:25 | ...::format(...) | provenance | MaD:2 |
| main.rs:86:18:86:25 | { ... } | main.rs:86:18:86:25 | ...::must_use(...) | provenance | MaD:3 |
| main.rs:87:10:87:33 | res | main.rs:87:18:87:32 | { ... } | provenance | |
| main.rs:87:18:87:32 | ...::format(...) | main.rs:87:10:87:33 | res | provenance | |
| main.rs:87:18:87:32 | ...::must_use(...) | main.rs:87:10:87:33 | MacroExpr | provenance | |
| main.rs:87:18:87:32 | MacroExpr | main.rs:87:18:87:32 | ...::format(...) | provenance | MaD:2 |
| main.rs:87:18:87:32 | { ... } | main.rs:87:18:87:32 | ...::must_use(...) | provenance | MaD:3 |
nodes
| main.rs:26:9:26:9 | s | semmle.label | s |
| main.rs:26:13:26:22 | source(...) | semmle.label | source(...) |
@@ -58,6 +72,20 @@ nodes
| main.rs:77:22:77:75 | ...::format(...) | semmle.label | ...::format(...) |
| main.rs:77:34:77:74 | MacroExpr | semmle.label | MacroExpr |
| main.rs:78:10:78:19 | formatted3 | semmle.label | formatted3 |
| main.rs:82:9:82:10 | s1 | semmle.label | s1 |
| main.rs:82:14:82:23 | source(...) | semmle.label | source(...) |
| main.rs:86:10:86:26 | MacroExpr | semmle.label | MacroExpr |
| main.rs:86:10:86:26 | res | semmle.label | res |
| main.rs:86:18:86:25 | ...::format(...) | semmle.label | ...::format(...) |
| main.rs:86:18:86:25 | ...::must_use(...) | semmle.label | ...::must_use(...) |
| main.rs:86:18:86:25 | MacroExpr | semmle.label | MacroExpr |
| main.rs:86:18:86:25 | { ... } | semmle.label | { ... } |
| main.rs:87:10:87:33 | MacroExpr | semmle.label | MacroExpr |
| main.rs:87:10:87:33 | res | semmle.label | res |
| main.rs:87:18:87:32 | ...::format(...) | semmle.label | ...::format(...) |
| main.rs:87:18:87:32 | ...::must_use(...) | semmle.label | ...::must_use(...) |
| main.rs:87:18:87:32 | MacroExpr | semmle.label | MacroExpr |
| main.rs:87:18:87:32 | { ... } | semmle.label | { ... } |
subpaths
testFailures
#select
@@ -67,3 +95,5 @@ testFailures
| main.rs:71:10:71:19 | formatted1 | main.rs:68:13:68:22 | source(...) | main.rs:71:10:71:19 | formatted1 | $@ | main.rs:68:13:68:22 | source(...) | source(...) |
| main.rs:74:10:74:19 | formatted2 | main.rs:68:13:68:22 | source(...) | main.rs:74:10:74:19 | formatted2 | $@ | main.rs:68:13:68:22 | source(...) | source(...) |
| main.rs:78:10:78:19 | formatted3 | main.rs:76:17:76:32 | source_usize(...) | main.rs:78:10:78:19 | formatted3 | $@ | main.rs:76:17:76:32 | source_usize(...) | source_usize(...) |
| main.rs:86:10:86:26 | MacroExpr | main.rs:82:14:82:23 | source(...) | main.rs:86:10:86:26 | MacroExpr | $@ | main.rs:82:14:82:23 | source(...) | source(...) |
| main.rs:87:10:87:33 | MacroExpr | main.rs:82:14:82:23 | source(...) | main.rs:87:10:87:33 | MacroExpr | $@ | main.rs:82:14:82:23 | source(...) | source(...) |

View File

@@ -83,8 +83,8 @@ fn format_macro() {
let s2 = "2";
let s3 = "3";
sink(format!("{}", s1)); // $ MISSING: hasTaintFlow=34
sink(format!("{s1} and {s3}")); // $ MISSING: hasTaintFlow=34
sink(format!("{}", s1)); // $ hasTaintFlow=34
sink(format!("{s1} and {s3}")); // $ hasTaintFlow=34
sink(format!("{s2} and {s3}"));
}

View File

@@ -1238,9 +1238,9 @@ edges
| main.rs:541:3:541:19 | ExprStmt | main.rs:541:3:541:11 | print_i64 | |
| main.rs:541:13:541:13 | a | main.rs:541:13:541:17 | a.val | |
| main.rs:541:13:541:17 | a.val | main.rs:541:3:541:18 | print_i64(...) | |
| main.rs:562:1:569:1 | enter fn macro_invocation | main.rs:563:5:564:26 | let ... = ... | |
| main.rs:562:1:569:1 | exit fn macro_invocation (normal) | main.rs:562:1:569:1 | exit fn macro_invocation | |
| main.rs:562:23:569:1 | { ... } | main.rs:562:1:569:1 | exit fn macro_invocation (normal) | |
| main.rs:562:1:572:1 | enter fn macro_invocation | main.rs:563:5:564:26 | let ... = ... | |
| main.rs:562:1:572:1 | exit fn macro_invocation (normal) | main.rs:562:1:572:1 | exit fn macro_invocation | |
| main.rs:562:23:572:1 | { ... } | main.rs:562:1:572:1 | exit fn macro_invocation (normal) | |
| main.rs:563:5:564:26 | let ... = ... | main.rs:564:23:564:24 | let ... = 37 | |
| main.rs:563:9:563:22 | var_from_macro | main.rs:565:5:565:30 | ExprStmt | match |
| main.rs:564:9:564:25 | MacroExpr | main.rs:563:9:563:22 | var_from_macro | |
@@ -1255,133 +1255,133 @@ edges
| main.rs:565:5:565:30 | ExprStmt | main.rs:565:5:565:13 | print_i64 | |
| main.rs:565:15:565:28 | var_from_macro | main.rs:565:5:565:29 | print_i64(...) | |
| main.rs:566:5:566:26 | let ... = 33 | main.rs:566:24:566:25 | 33 | |
| main.rs:566:9:566:20 | var_in_macro | main.rs:567:5:567:44 | ExprStmt | match |
| main.rs:566:9:566:20 | var_in_macro | main.rs:570:5:570:44 | ExprStmt | match |
| main.rs:566:24:566:25 | 33 | main.rs:566:9:566:20 | var_in_macro | |
| main.rs:567:5:567:13 | print_i64 | main.rs:567:15:567:42 | let ... = 0 | |
| main.rs:567:5:567:43 | print_i64(...) | main.rs:568:5:568:28 | ExprStmt | |
| main.rs:567:5:567:44 | ExprStmt | main.rs:567:5:567:13 | print_i64 | |
| main.rs:567:15:567:42 | 0 | main.rs:567:15:567:42 | var_in_macro | |
| main.rs:567:15:567:42 | MacroExpr | main.rs:567:5:567:43 | print_i64(...) | |
| main.rs:567:15:567:42 | let ... = 0 | main.rs:567:15:567:42 | 0 | |
| main.rs:567:15:567:42 | let_in_macro2!... | main.rs:567:15:567:42 | MacroExpr | |
| main.rs:567:15:567:42 | var_in_macro | main.rs:567:30:567:41 | var_in_macro | match |
| main.rs:567:30:567:41 | var_in_macro | main.rs:567:30:567:41 | { ... } | |
| main.rs:567:30:567:41 | { ... } | main.rs:567:15:567:42 | let_in_macro2!... | |
| main.rs:568:5:568:13 | print_i64 | main.rs:568:15:568:26 | var_in_macro | |
| main.rs:568:5:568:27 | print_i64(...) | main.rs:562:23:569:1 | { ... } | |
| main.rs:568:5:568:28 | ExprStmt | main.rs:568:5:568:13 | print_i64 | |
| main.rs:568:15:568:26 | var_in_macro | main.rs:568:5:568:27 | print_i64(...) | |
| main.rs:571:1:606:1 | enter fn main | main.rs:572:5:572:25 | ExprStmt | |
| main.rs:571:1:606:1 | exit fn main (normal) | main.rs:571:1:606:1 | exit fn main | |
| main.rs:571:11:606:1 | { ... } | main.rs:571:1:606:1 | exit fn main (normal) | |
| main.rs:572:5:572:22 | immutable_variable | main.rs:572:5:572:24 | immutable_variable(...) | |
| main.rs:572:5:572:24 | immutable_variable(...) | main.rs:573:5:573:23 | ExprStmt | |
| main.rs:572:5:572:25 | ExprStmt | main.rs:572:5:572:22 | immutable_variable | |
| main.rs:573:5:573:20 | mutable_variable | main.rs:573:5:573:22 | mutable_variable(...) | |
| main.rs:573:5:573:22 | mutable_variable(...) | main.rs:574:5:574:40 | ExprStmt | |
| main.rs:573:5:573:23 | ExprStmt | main.rs:573:5:573:20 | mutable_variable | |
| main.rs:574:5:574:37 | mutable_variable_immutable_borrow | main.rs:574:5:574:39 | mutable_variable_immutable_borrow(...) | |
| main.rs:574:5:574:39 | mutable_variable_immutable_borrow(...) | main.rs:575:5:575:23 | ExprStmt | |
| main.rs:574:5:574:40 | ExprStmt | main.rs:574:5:574:37 | mutable_variable_immutable_borrow | |
| main.rs:575:5:575:20 | variable_shadow1 | main.rs:575:5:575:22 | variable_shadow1(...) | |
| main.rs:575:5:575:22 | variable_shadow1(...) | main.rs:576:5:576:23 | ExprStmt | |
| main.rs:575:5:575:23 | ExprStmt | main.rs:575:5:575:20 | variable_shadow1 | |
| main.rs:576:5:576:20 | variable_shadow2 | main.rs:576:5:576:22 | variable_shadow2(...) | |
| main.rs:576:5:576:22 | variable_shadow2(...) | main.rs:577:5:577:19 | ExprStmt | |
| main.rs:576:5:576:23 | ExprStmt | main.rs:576:5:576:20 | variable_shadow2 | |
| main.rs:577:5:577:16 | let_pattern1 | main.rs:577:5:577:18 | let_pattern1(...) | |
| main.rs:577:5:577:18 | let_pattern1(...) | main.rs:578:5:578:19 | ExprStmt | |
| main.rs:577:5:577:19 | ExprStmt | main.rs:577:5:577:16 | let_pattern1 | |
| main.rs:578:5:578:16 | let_pattern2 | main.rs:578:5:578:18 | let_pattern2(...) | |
| main.rs:578:5:578:18 | let_pattern2(...) | main.rs:579:5:579:19 | ExprStmt | |
| main.rs:578:5:578:19 | ExprStmt | main.rs:578:5:578:16 | let_pattern2 | |
| main.rs:579:5:579:16 | let_pattern3 | main.rs:579:5:579:18 | let_pattern3(...) | |
| main.rs:579:5:579:18 | let_pattern3(...) | main.rs:580:5:580:19 | ExprStmt | |
| main.rs:579:5:579:19 | ExprStmt | main.rs:579:5:579:16 | let_pattern3 | |
| main.rs:580:5:580:16 | let_pattern4 | main.rs:580:5:580:18 | let_pattern4(...) | |
| main.rs:580:5:580:18 | let_pattern4(...) | main.rs:581:5:581:21 | ExprStmt | |
| main.rs:580:5:580:19 | ExprStmt | main.rs:580:5:580:16 | let_pattern4 | |
| main.rs:581:5:581:18 | match_pattern1 | main.rs:581:5:581:20 | match_pattern1(...) | |
| main.rs:581:5:581:20 | match_pattern1(...) | main.rs:582:5:582:21 | ExprStmt | |
| main.rs:581:5:581:21 | ExprStmt | main.rs:581:5:581:18 | match_pattern1 | |
| main.rs:582:5:582:18 | match_pattern2 | main.rs:582:5:582:20 | match_pattern2(...) | |
| main.rs:582:5:582:20 | match_pattern2(...) | main.rs:583:5:583:21 | ExprStmt | |
| main.rs:582:5:582:21 | ExprStmt | main.rs:582:5:582:18 | match_pattern2 | |
| main.rs:583:5:583:18 | match_pattern3 | main.rs:583:5:583:20 | match_pattern3(...) | |
| main.rs:583:5:583:20 | match_pattern3(...) | main.rs:584:5:584:21 | ExprStmt | |
| main.rs:583:5:583:21 | ExprStmt | main.rs:583:5:583:18 | match_pattern3 | |
| main.rs:584:5:584:18 | match_pattern4 | main.rs:584:5:584:20 | match_pattern4(...) | |
| main.rs:584:5:584:20 | match_pattern4(...) | main.rs:585:5:585:21 | ExprStmt | |
| main.rs:584:5:584:21 | ExprStmt | main.rs:584:5:584:18 | match_pattern4 | |
| main.rs:585:5:585:18 | match_pattern5 | main.rs:585:5:585:20 | match_pattern5(...) | |
| main.rs:585:5:585:20 | match_pattern5(...) | main.rs:586:5:586:21 | ExprStmt | |
| main.rs:585:5:585:21 | ExprStmt | main.rs:585:5:585:18 | match_pattern5 | |
| main.rs:586:5:586:18 | match_pattern6 | main.rs:586:5:586:20 | match_pattern6(...) | |
| main.rs:586:5:586:20 | match_pattern6(...) | main.rs:587:5:587:21 | ExprStmt | |
| main.rs:586:5:586:21 | ExprStmt | main.rs:586:5:586:18 | match_pattern6 | |
| main.rs:587:5:587:18 | match_pattern7 | main.rs:587:5:587:20 | match_pattern7(...) | |
| main.rs:587:5:587:20 | match_pattern7(...) | main.rs:588:5:588:21 | ExprStmt | |
| main.rs:587:5:587:21 | ExprStmt | main.rs:587:5:587:18 | match_pattern7 | |
| main.rs:588:5:588:18 | match_pattern8 | main.rs:588:5:588:20 | match_pattern8(...) | |
| main.rs:588:5:588:20 | match_pattern8(...) | main.rs:589:5:589:21 | ExprStmt | |
| main.rs:588:5:588:21 | ExprStmt | main.rs:588:5:588:18 | match_pattern8 | |
| main.rs:589:5:589:18 | match_pattern9 | main.rs:589:5:589:20 | match_pattern9(...) | |
| main.rs:589:5:589:20 | match_pattern9(...) | main.rs:590:5:590:36 | ExprStmt | |
| main.rs:589:5:589:21 | ExprStmt | main.rs:589:5:589:18 | match_pattern9 | |
| main.rs:590:5:590:18 | param_pattern1 | main.rs:590:20:590:22 | "a" | |
| main.rs:590:5:590:35 | param_pattern1(...) | main.rs:591:5:591:37 | ExprStmt | |
| main.rs:590:5:590:36 | ExprStmt | main.rs:590:5:590:18 | param_pattern1 | |
| main.rs:590:20:590:22 | "a" | main.rs:590:26:590:28 | "b" | |
| main.rs:590:25:590:34 | TupleExpr | main.rs:590:5:590:35 | param_pattern1(...) | |
| main.rs:590:26:590:28 | "b" | main.rs:590:31:590:33 | "c" | |
| main.rs:590:31:590:33 | "c" | main.rs:590:25:590:34 | TupleExpr | |
| main.rs:591:5:591:18 | param_pattern2 | main.rs:591:20:591:31 | ...::Left | |
| main.rs:591:5:591:36 | param_pattern2(...) | main.rs:592:5:592:26 | ExprStmt | |
| main.rs:591:5:591:37 | ExprStmt | main.rs:591:5:591:18 | param_pattern2 | |
| main.rs:591:20:591:31 | ...::Left | main.rs:591:33:591:34 | 45 | |
| main.rs:591:20:591:35 | ...::Left(...) | main.rs:591:5:591:36 | param_pattern2(...) | |
| main.rs:591:33:591:34 | 45 | main.rs:591:20:591:35 | ...::Left(...) | |
| main.rs:592:5:592:23 | destruct_assignment | main.rs:592:5:592:25 | destruct_assignment(...) | |
| main.rs:592:5:592:25 | destruct_assignment(...) | main.rs:593:5:593:23 | ExprStmt | |
| main.rs:592:5:592:26 | ExprStmt | main.rs:592:5:592:23 | destruct_assignment | |
| main.rs:593:5:593:20 | closure_variable | main.rs:593:5:593:22 | closure_variable(...) | |
| main.rs:593:5:593:22 | closure_variable(...) | main.rs:594:5:594:19 | ExprStmt | |
| main.rs:593:5:593:23 | ExprStmt | main.rs:593:5:593:20 | closure_variable | |
| main.rs:594:5:594:16 | for_variable | main.rs:594:5:594:18 | for_variable(...) | |
| main.rs:594:5:594:18 | for_variable(...) | main.rs:595:5:595:17 | ExprStmt | |
| main.rs:594:5:594:19 | ExprStmt | main.rs:594:5:594:16 | for_variable | |
| main.rs:595:5:595:14 | add_assign | main.rs:595:5:595:16 | add_assign(...) | |
| main.rs:595:5:595:16 | add_assign(...) | main.rs:596:5:596:13 | ExprStmt | |
| main.rs:595:5:595:17 | ExprStmt | main.rs:595:5:595:14 | add_assign | |
| main.rs:596:5:596:10 | mutate | main.rs:596:5:596:12 | mutate(...) | |
| main.rs:596:5:596:12 | mutate(...) | main.rs:597:5:597:17 | ExprStmt | |
| main.rs:596:5:596:13 | ExprStmt | main.rs:596:5:596:10 | mutate | |
| main.rs:597:5:597:14 | mutate_arg | main.rs:597:5:597:16 | mutate_arg(...) | |
| main.rs:597:5:597:16 | mutate_arg(...) | main.rs:598:5:598:12 | ExprStmt | |
| main.rs:597:5:597:17 | ExprStmt | main.rs:597:5:597:14 | mutate_arg | |
| main.rs:598:5:598:9 | alias | main.rs:598:5:598:11 | alias(...) | |
| main.rs:598:5:598:11 | alias(...) | main.rs:599:5:599:18 | ExprStmt | |
| main.rs:598:5:598:12 | ExprStmt | main.rs:598:5:598:9 | alias | |
| main.rs:599:5:599:15 | capture_mut | main.rs:599:5:599:17 | capture_mut(...) | |
| main.rs:599:5:599:17 | capture_mut(...) | main.rs:600:5:600:20 | ExprStmt | |
| main.rs:599:5:599:18 | ExprStmt | main.rs:599:5:599:15 | capture_mut | |
| main.rs:600:5:600:17 | capture_immut | main.rs:600:5:600:19 | capture_immut(...) | |
| main.rs:600:5:600:19 | capture_immut(...) | main.rs:601:5:601:26 | ExprStmt | |
| main.rs:600:5:600:20 | ExprStmt | main.rs:600:5:600:17 | capture_immut | |
| main.rs:601:5:601:23 | async_block_capture | main.rs:601:5:601:25 | async_block_capture(...) | |
| main.rs:601:5:601:25 | async_block_capture(...) | main.rs:602:5:602:14 | ExprStmt | |
| main.rs:601:5:601:26 | ExprStmt | main.rs:601:5:601:23 | async_block_capture | |
| main.rs:602:5:602:11 | structs | main.rs:602:5:602:13 | structs(...) | |
| main.rs:602:5:602:13 | structs(...) | main.rs:603:5:603:14 | ExprStmt | |
| main.rs:602:5:602:14 | ExprStmt | main.rs:602:5:602:11 | structs | |
| main.rs:603:5:603:11 | ref_arg | main.rs:603:5:603:13 | ref_arg(...) | |
| main.rs:603:5:603:13 | ref_arg(...) | main.rs:604:5:604:30 | ExprStmt | |
| main.rs:603:5:603:14 | ExprStmt | main.rs:603:5:603:11 | ref_arg | |
| main.rs:604:5:604:27 | ref_methodcall_receiver | main.rs:604:5:604:29 | ref_methodcall_receiver(...) | |
| main.rs:604:5:604:29 | ref_methodcall_receiver(...) | main.rs:605:5:605:23 | ExprStmt | |
| main.rs:604:5:604:30 | ExprStmt | main.rs:604:5:604:27 | ref_methodcall_receiver | |
| main.rs:605:5:605:20 | macro_invocation | main.rs:605:5:605:22 | macro_invocation(...) | |
| main.rs:605:5:605:22 | macro_invocation(...) | main.rs:571:11:606:1 | { ... } | |
| main.rs:605:5:605:23 | ExprStmt | main.rs:605:5:605:20 | macro_invocation | |
| main.rs:570:5:570:13 | print_i64 | main.rs:570:15:570:42 | let ... = 0 | |
| main.rs:570:5:570:43 | print_i64(...) | main.rs:571:5:571:28 | ExprStmt | |
| main.rs:570:5:570:44 | ExprStmt | main.rs:570:5:570:13 | print_i64 | |
| main.rs:570:15:570:42 | 0 | main.rs:570:15:570:42 | var_in_macro | |
| main.rs:570:15:570:42 | MacroExpr | main.rs:570:5:570:43 | print_i64(...) | |
| main.rs:570:15:570:42 | let ... = 0 | main.rs:570:15:570:42 | 0 | |
| main.rs:570:15:570:42 | let_in_macro2!... | main.rs:570:15:570:42 | MacroExpr | |
| main.rs:570:15:570:42 | var_in_macro | main.rs:570:30:570:41 | var_in_macro | match |
| main.rs:570:30:570:41 | var_in_macro | main.rs:570:30:570:41 | { ... } | |
| main.rs:570:30:570:41 | { ... } | main.rs:570:15:570:42 | let_in_macro2!... | |
| main.rs:571:5:571:13 | print_i64 | main.rs:571:15:571:26 | var_in_macro | |
| main.rs:571:5:571:27 | print_i64(...) | main.rs:562:23:572:1 | { ... } | |
| main.rs:571:5:571:28 | ExprStmt | main.rs:571:5:571:13 | print_i64 | |
| main.rs:571:15:571:26 | var_in_macro | main.rs:571:5:571:27 | print_i64(...) | |
| main.rs:574:1:609:1 | enter fn main | main.rs:575:5:575:25 | ExprStmt | |
| main.rs:574:1:609:1 | exit fn main (normal) | main.rs:574:1:609:1 | exit fn main | |
| main.rs:574:11:609:1 | { ... } | main.rs:574:1:609:1 | exit fn main (normal) | |
| main.rs:575:5:575:22 | immutable_variable | main.rs:575:5:575:24 | immutable_variable(...) | |
| main.rs:575:5:575:24 | immutable_variable(...) | main.rs:576:5:576:23 | ExprStmt | |
| main.rs:575:5:575:25 | ExprStmt | main.rs:575:5:575:22 | immutable_variable | |
| main.rs:576:5:576:20 | mutable_variable | main.rs:576:5:576:22 | mutable_variable(...) | |
| main.rs:576:5:576:22 | mutable_variable(...) | main.rs:577:5:577:40 | ExprStmt | |
| main.rs:576:5:576:23 | ExprStmt | main.rs:576:5:576:20 | mutable_variable | |
| main.rs:577:5:577:37 | mutable_variable_immutable_borrow | main.rs:577:5:577:39 | mutable_variable_immutable_borrow(...) | |
| main.rs:577:5:577:39 | mutable_variable_immutable_borrow(...) | main.rs:578:5:578:23 | ExprStmt | |
| main.rs:577:5:577:40 | ExprStmt | main.rs:577:5:577:37 | mutable_variable_immutable_borrow | |
| main.rs:578:5:578:20 | variable_shadow1 | main.rs:578:5:578:22 | variable_shadow1(...) | |
| main.rs:578:5:578:22 | variable_shadow1(...) | main.rs:579:5:579:23 | ExprStmt | |
| main.rs:578:5:578:23 | ExprStmt | main.rs:578:5:578:20 | variable_shadow1 | |
| main.rs:579:5:579:20 | variable_shadow2 | main.rs:579:5:579:22 | variable_shadow2(...) | |
| main.rs:579:5:579:22 | variable_shadow2(...) | main.rs:580:5:580:19 | ExprStmt | |
| main.rs:579:5:579:23 | ExprStmt | main.rs:579:5:579:20 | variable_shadow2 | |
| main.rs:580:5:580:16 | let_pattern1 | main.rs:580:5:580:18 | let_pattern1(...) | |
| main.rs:580:5:580:18 | let_pattern1(...) | main.rs:581:5:581:19 | ExprStmt | |
| main.rs:580:5:580:19 | ExprStmt | main.rs:580:5:580:16 | let_pattern1 | |
| main.rs:581:5:581:16 | let_pattern2 | main.rs:581:5:581:18 | let_pattern2(...) | |
| main.rs:581:5:581:18 | let_pattern2(...) | main.rs:582:5:582:19 | ExprStmt | |
| main.rs:581:5:581:19 | ExprStmt | main.rs:581:5:581:16 | let_pattern2 | |
| main.rs:582:5:582:16 | let_pattern3 | main.rs:582:5:582:18 | let_pattern3(...) | |
| main.rs:582:5:582:18 | let_pattern3(...) | main.rs:583:5:583:19 | ExprStmt | |
| main.rs:582:5:582:19 | ExprStmt | main.rs:582:5:582:16 | let_pattern3 | |
| main.rs:583:5:583:16 | let_pattern4 | main.rs:583:5:583:18 | let_pattern4(...) | |
| main.rs:583:5:583:18 | let_pattern4(...) | main.rs:584:5:584:21 | ExprStmt | |
| main.rs:583:5:583:19 | ExprStmt | main.rs:583:5:583:16 | let_pattern4 | |
| main.rs:584:5:584:18 | match_pattern1 | main.rs:584:5:584:20 | match_pattern1(...) | |
| main.rs:584:5:584:20 | match_pattern1(...) | main.rs:585:5:585:21 | ExprStmt | |
| main.rs:584:5:584:21 | ExprStmt | main.rs:584:5:584:18 | match_pattern1 | |
| main.rs:585:5:585:18 | match_pattern2 | main.rs:585:5:585:20 | match_pattern2(...) | |
| main.rs:585:5:585:20 | match_pattern2(...) | main.rs:586:5:586:21 | ExprStmt | |
| main.rs:585:5:585:21 | ExprStmt | main.rs:585:5:585:18 | match_pattern2 | |
| main.rs:586:5:586:18 | match_pattern3 | main.rs:586:5:586:20 | match_pattern3(...) | |
| main.rs:586:5:586:20 | match_pattern3(...) | main.rs:587:5:587:21 | ExprStmt | |
| main.rs:586:5:586:21 | ExprStmt | main.rs:586:5:586:18 | match_pattern3 | |
| main.rs:587:5:587:18 | match_pattern4 | main.rs:587:5:587:20 | match_pattern4(...) | |
| main.rs:587:5:587:20 | match_pattern4(...) | main.rs:588:5:588:21 | ExprStmt | |
| main.rs:587:5:587:21 | ExprStmt | main.rs:587:5:587:18 | match_pattern4 | |
| main.rs:588:5:588:18 | match_pattern5 | main.rs:588:5:588:20 | match_pattern5(...) | |
| main.rs:588:5:588:20 | match_pattern5(...) | main.rs:589:5:589:21 | ExprStmt | |
| main.rs:588:5:588:21 | ExprStmt | main.rs:588:5:588:18 | match_pattern5 | |
| main.rs:589:5:589:18 | match_pattern6 | main.rs:589:5:589:20 | match_pattern6(...) | |
| main.rs:589:5:589:20 | match_pattern6(...) | main.rs:590:5:590:21 | ExprStmt | |
| main.rs:589:5:589:21 | ExprStmt | main.rs:589:5:589:18 | match_pattern6 | |
| main.rs:590:5:590:18 | match_pattern7 | main.rs:590:5:590:20 | match_pattern7(...) | |
| main.rs:590:5:590:20 | match_pattern7(...) | main.rs:591:5:591:21 | ExprStmt | |
| main.rs:590:5:590:21 | ExprStmt | main.rs:590:5:590:18 | match_pattern7 | |
| main.rs:591:5:591:18 | match_pattern8 | main.rs:591:5:591:20 | match_pattern8(...) | |
| main.rs:591:5:591:20 | match_pattern8(...) | main.rs:592:5:592:21 | ExprStmt | |
| main.rs:591:5:591:21 | ExprStmt | main.rs:591:5:591:18 | match_pattern8 | |
| main.rs:592:5:592:18 | match_pattern9 | main.rs:592:5:592:20 | match_pattern9(...) | |
| main.rs:592:5:592:20 | match_pattern9(...) | main.rs:593:5:593:36 | ExprStmt | |
| main.rs:592:5:592:21 | ExprStmt | main.rs:592:5:592:18 | match_pattern9 | |
| main.rs:593:5:593:18 | param_pattern1 | main.rs:593:20:593:22 | "a" | |
| main.rs:593:5:593:35 | param_pattern1(...) | main.rs:594:5:594:37 | ExprStmt | |
| main.rs:593:5:593:36 | ExprStmt | main.rs:593:5:593:18 | param_pattern1 | |
| main.rs:593:20:593:22 | "a" | main.rs:593:26:593:28 | "b" | |
| main.rs:593:25:593:34 | TupleExpr | main.rs:593:5:593:35 | param_pattern1(...) | |
| main.rs:593:26:593:28 | "b" | main.rs:593:31:593:33 | "c" | |
| main.rs:593:31:593:33 | "c" | main.rs:593:25:593:34 | TupleExpr | |
| main.rs:594:5:594:18 | param_pattern2 | main.rs:594:20:594:31 | ...::Left | |
| main.rs:594:5:594:36 | param_pattern2(...) | main.rs:595:5:595:26 | ExprStmt | |
| main.rs:594:5:594:37 | ExprStmt | main.rs:594:5:594:18 | param_pattern2 | |
| main.rs:594:20:594:31 | ...::Left | main.rs:594:33:594:34 | 45 | |
| main.rs:594:20:594:35 | ...::Left(...) | main.rs:594:5:594:36 | param_pattern2(...) | |
| main.rs:594:33:594:34 | 45 | main.rs:594:20:594:35 | ...::Left(...) | |
| main.rs:595:5:595:23 | destruct_assignment | main.rs:595:5:595:25 | destruct_assignment(...) | |
| main.rs:595:5:595:25 | destruct_assignment(...) | main.rs:596:5:596:23 | ExprStmt | |
| main.rs:595:5:595:26 | ExprStmt | main.rs:595:5:595:23 | destruct_assignment | |
| main.rs:596:5:596:20 | closure_variable | main.rs:596:5:596:22 | closure_variable(...) | |
| main.rs:596:5:596:22 | closure_variable(...) | main.rs:597:5:597:19 | ExprStmt | |
| main.rs:596:5:596:23 | ExprStmt | main.rs:596:5:596:20 | closure_variable | |
| main.rs:597:5:597:16 | for_variable | main.rs:597:5:597:18 | for_variable(...) | |
| main.rs:597:5:597:18 | for_variable(...) | main.rs:598:5:598:17 | ExprStmt | |
| main.rs:597:5:597:19 | ExprStmt | main.rs:597:5:597:16 | for_variable | |
| main.rs:598:5:598:14 | add_assign | main.rs:598:5:598:16 | add_assign(...) | |
| main.rs:598:5:598:16 | add_assign(...) | main.rs:599:5:599:13 | ExprStmt | |
| main.rs:598:5:598:17 | ExprStmt | main.rs:598:5:598:14 | add_assign | |
| main.rs:599:5:599:10 | mutate | main.rs:599:5:599:12 | mutate(...) | |
| main.rs:599:5:599:12 | mutate(...) | main.rs:600:5:600:17 | ExprStmt | |
| main.rs:599:5:599:13 | ExprStmt | main.rs:599:5:599:10 | mutate | |
| main.rs:600:5:600:14 | mutate_arg | main.rs:600:5:600:16 | mutate_arg(...) | |
| main.rs:600:5:600:16 | mutate_arg(...) | main.rs:601:5:601:12 | ExprStmt | |
| main.rs:600:5:600:17 | ExprStmt | main.rs:600:5:600:14 | mutate_arg | |
| main.rs:601:5:601:9 | alias | main.rs:601:5:601:11 | alias(...) | |
| main.rs:601:5:601:11 | alias(...) | main.rs:602:5:602:18 | ExprStmt | |
| main.rs:601:5:601:12 | ExprStmt | main.rs:601:5:601:9 | alias | |
| main.rs:602:5:602:15 | capture_mut | main.rs:602:5:602:17 | capture_mut(...) | |
| main.rs:602:5:602:17 | capture_mut(...) | main.rs:603:5:603:20 | ExprStmt | |
| main.rs:602:5:602:18 | ExprStmt | main.rs:602:5:602:15 | capture_mut | |
| main.rs:603:5:603:17 | capture_immut | main.rs:603:5:603:19 | capture_immut(...) | |
| main.rs:603:5:603:19 | capture_immut(...) | main.rs:604:5:604:26 | ExprStmt | |
| main.rs:603:5:603:20 | ExprStmt | main.rs:603:5:603:17 | capture_immut | |
| main.rs:604:5:604:23 | async_block_capture | main.rs:604:5:604:25 | async_block_capture(...) | |
| main.rs:604:5:604:25 | async_block_capture(...) | main.rs:605:5:605:14 | ExprStmt | |
| main.rs:604:5:604:26 | ExprStmt | main.rs:604:5:604:23 | async_block_capture | |
| main.rs:605:5:605:11 | structs | main.rs:605:5:605:13 | structs(...) | |
| main.rs:605:5:605:13 | structs(...) | main.rs:606:5:606:14 | ExprStmt | |
| main.rs:605:5:605:14 | ExprStmt | main.rs:605:5:605:11 | structs | |
| main.rs:606:5:606:11 | ref_arg | main.rs:606:5:606:13 | ref_arg(...) | |
| main.rs:606:5:606:13 | ref_arg(...) | main.rs:607:5:607:30 | ExprStmt | |
| main.rs:606:5:606:14 | ExprStmt | main.rs:606:5:606:11 | ref_arg | |
| main.rs:607:5:607:27 | ref_methodcall_receiver | main.rs:607:5:607:29 | ref_methodcall_receiver(...) | |
| main.rs:607:5:607:29 | ref_methodcall_receiver(...) | main.rs:608:5:608:23 | ExprStmt | |
| main.rs:607:5:607:30 | ExprStmt | main.rs:607:5:607:27 | ref_methodcall_receiver | |
| main.rs:608:5:608:20 | macro_invocation | main.rs:608:5:608:22 | macro_invocation(...) | |
| main.rs:608:5:608:22 | macro_invocation(...) | main.rs:574:11:609:1 | { ... } | |
| main.rs:608:5:608:23 | ExprStmt | main.rs:608:5:608:20 | macro_invocation | |
breakTarget
continueTarget

View File

@@ -146,7 +146,9 @@ definition
| main.rs:523:9:523:9 | z | main.rs:523:9:523:9 | z |
| main.rs:532:10:532:18 | SelfParam | main.rs:532:15:532:18 | self |
| main.rs:563:9:563:22 | var_from_macro | main.rs:563:9:563:22 | var_from_macro |
| main.rs:564:9:564:25 | var_in_macro | main.rs:564:9:564:25 | var_in_macro |
| main.rs:566:9:566:20 | var_in_macro | main.rs:566:9:566:20 | var_in_macro |
| main.rs:570:15:570:42 | var_in_macro | main.rs:570:15:570:42 | var_in_macro |
read
| main.rs:3:14:3:14 | s | main.rs:3:14:3:14 | s | main.rs:4:20:4:20 | s |
| main.rs:7:14:7:14 | i | main.rs:7:14:7:14 | i | main.rs:8:20:8:20 | i |
@@ -285,8 +287,9 @@ read
| main.rs:523:9:523:9 | z | main.rs:523:9:523:9 | z | main.rs:524:20:524:20 | z |
| main.rs:532:10:532:18 | SelfParam | main.rs:532:15:532:18 | self | main.rs:533:6:533:9 | self |
| main.rs:563:9:563:22 | var_from_macro | main.rs:563:9:563:22 | var_from_macro | main.rs:565:15:565:28 | var_from_macro |
| main.rs:566:9:566:20 | var_in_macro | main.rs:566:9:566:20 | var_in_macro | main.rs:567:30:567:41 | var_in_macro |
| main.rs:566:9:566:20 | var_in_macro | main.rs:566:9:566:20 | var_in_macro | main.rs:568:15:568:26 | var_in_macro |
| main.rs:564:9:564:25 | var_in_macro | main.rs:564:9:564:25 | var_in_macro | main.rs:564:9:564:25 | var_in_macro |
| main.rs:566:9:566:20 | var_in_macro | main.rs:566:9:566:20 | var_in_macro | main.rs:571:15:571:26 | var_in_macro |
| main.rs:570:15:570:42 | var_in_macro | main.rs:570:15:570:42 | var_in_macro | main.rs:570:30:570:41 | var_in_macro |
firstRead
| main.rs:3:14:3:14 | s | main.rs:3:14:3:14 | s | main.rs:4:20:4:20 | s |
| main.rs:7:14:7:14 | i | main.rs:7:14:7:14 | i | main.rs:8:20:8:20 | i |
@@ -398,7 +401,9 @@ firstRead
| main.rs:523:9:523:9 | z | main.rs:523:9:523:9 | z | main.rs:524:20:524:20 | z |
| main.rs:532:10:532:18 | SelfParam | main.rs:532:15:532:18 | self | main.rs:533:6:533:9 | self |
| main.rs:563:9:563:22 | var_from_macro | main.rs:563:9:563:22 | var_from_macro | main.rs:565:15:565:28 | var_from_macro |
| main.rs:566:9:566:20 | var_in_macro | main.rs:566:9:566:20 | var_in_macro | main.rs:567:30:567:41 | var_in_macro |
| main.rs:564:9:564:25 | var_in_macro | main.rs:564:9:564:25 | var_in_macro | main.rs:564:9:564:25 | var_in_macro |
| main.rs:566:9:566:20 | var_in_macro | main.rs:566:9:566:20 | var_in_macro | main.rs:571:15:571:26 | var_in_macro |
| main.rs:570:15:570:42 | var_in_macro | main.rs:570:15:570:42 | var_in_macro | main.rs:570:30:570:41 | var_in_macro |
lastRead
| main.rs:3:14:3:14 | s | main.rs:3:14:3:14 | s | main.rs:4:20:4:20 | s |
| main.rs:7:14:7:14 | i | main.rs:7:14:7:14 | i | main.rs:8:20:8:20 | i |
@@ -511,7 +516,9 @@ lastRead
| main.rs:523:9:523:9 | z | main.rs:523:9:523:9 | z | main.rs:524:20:524:20 | z |
| main.rs:532:10:532:18 | SelfParam | main.rs:532:15:532:18 | self | main.rs:533:6:533:9 | self |
| main.rs:563:9:563:22 | var_from_macro | main.rs:563:9:563:22 | var_from_macro | main.rs:565:15:565:28 | var_from_macro |
| main.rs:566:9:566:20 | var_in_macro | main.rs:566:9:566:20 | var_in_macro | main.rs:568:15:568:26 | var_in_macro |
| main.rs:564:9:564:25 | var_in_macro | main.rs:564:9:564:25 | var_in_macro | main.rs:564:9:564:25 | var_in_macro |
| main.rs:566:9:566:20 | var_in_macro | main.rs:566:9:566:20 | var_in_macro | main.rs:571:15:571:26 | var_in_macro |
| main.rs:570:15:570:42 | var_in_macro | main.rs:570:15:570:42 | var_in_macro | main.rs:570:30:570:41 | var_in_macro |
adjacentReads
| main.rs:35:9:35:10 | x3 | main.rs:35:9:35:10 | x3 | main.rs:36:15:36:16 | x3 | main.rs:38:9:38:10 | x3 |
| main.rs:43:9:43:10 | x4 | main.rs:43:9:43:10 | x4 | main.rs:44:15:44:16 | x4 | main.rs:49:15:49:16 | x4 |
@@ -543,7 +550,6 @@ adjacentReads
| main.rs:510:9:510:13 | a | main.rs:510:13:510:13 | a | main.rs:511:15:511:15 | a | main.rs:512:5:512:5 | a |
| main.rs:510:9:510:13 | a | main.rs:510:13:510:13 | a | main.rs:512:5:512:5 | a | main.rs:513:15:513:15 | a |
| main.rs:519:9:519:9 | x | main.rs:519:9:519:9 | x | main.rs:520:20:520:20 | x | main.rs:521:15:521:15 | x |
| main.rs:566:9:566:20 | var_in_macro | main.rs:566:9:566:20 | var_in_macro | main.rs:567:30:567:41 | var_in_macro | main.rs:568:15:568:26 | var_in_macro |
phi
| main.rs:191:9:191:44 | [match(true)] phi | main.rs:191:9:191:44 | a3 | main.rs:191:22:191:23 | a3 |
| main.rs:191:9:191:44 | [match(true)] phi | main.rs:191:9:191:44 | a3 | main.rs:191:42:191:43 | a3 |
@@ -665,4 +671,6 @@ assigns
| main.rs:519:9:519:9 | x | main.rs:519:13:519:14 | 16 |
| main.rs:523:9:523:9 | z | main.rs:523:13:523:14 | 17 |
| main.rs:563:9:563:22 | var_from_macro | main.rs:564:9:564:25 | MacroExpr |
| main.rs:564:9:564:25 | var_in_macro | main.rs:564:23:564:24 | 37 |
| main.rs:566:9:566:20 | var_in_macro | main.rs:566:24:566:25 | 33 |
| main.rs:570:15:570:42 | var_in_macro | main.rs:570:15:570:42 | 0 |

View File

@@ -561,10 +561,13 @@ macro_rules! let_in_macro2 {
fn macro_invocation() {
let var_from_macro = // var_from_macro1
let_in_macro!(37); // $ MISSING: read_access=var_in_macro
let_in_macro!(37); // $ read_access=var_in_macro
print_i64(var_from_macro); // $ read_access=var_from_macro1
let var_in_macro = 33; // var_in_macro1
print_i64(let_in_macro2!(var_in_macro)); // $ read_access=var_in_macro1
// Our analysis does not currently respect the hygiene rules of Rust macros
// (https://veykril.github.io/tlborm/decl-macros/minutiae/hygiene.html), because
// all we have access to is the expanded AST
print_i64(let_in_macro2!(var_in_macro)); // $ MISSING: read_access=var_in_macro1 $ SPURIOUS: read_access=var_in_macro
print_i64(var_in_macro); // $ read_access=var_in_macro1
}

View File

@@ -108,7 +108,7 @@ variable
| main.rs:563:9:563:22 | var_from_macro |
| main.rs:564:9:564:25 | var_in_macro |
| main.rs:566:9:566:20 | var_in_macro |
| main.rs:567:15:567:42 | var_in_macro |
| main.rs:570:15:570:42 | var_in_macro |
variableAccess
| main.rs:4:20:4:20 | s | main.rs:3:14:3:14 | s |
| main.rs:8:20:8:20 | i | main.rs:7:14:7:14 | i |
@@ -278,9 +278,10 @@ variableAccess
| main.rs:533:6:533:9 | self | main.rs:532:15:532:18 | self |
| main.rs:539:3:539:3 | a | main.rs:538:11:538:11 | a |
| main.rs:541:13:541:13 | a | main.rs:538:11:538:11 | a |
| main.rs:564:9:564:25 | var_in_macro | main.rs:564:9:564:25 | var_in_macro |
| main.rs:565:15:565:28 | var_from_macro | main.rs:563:9:563:22 | var_from_macro |
| main.rs:567:30:567:41 | var_in_macro | main.rs:566:9:566:20 | var_in_macro |
| main.rs:568:15:568:26 | var_in_macro | main.rs:566:9:566:20 | var_in_macro |
| main.rs:570:30:570:41 | var_in_macro | main.rs:570:15:570:42 | var_in_macro |
| main.rs:571:15:571:26 | var_in_macro | main.rs:566:9:566:20 | var_in_macro |
variableWriteAccess
| main.rs:23:5:23:6 | x2 | main.rs:21:13:21:14 | x2 |
| main.rs:30:5:30:5 | x | main.rs:28:13:28:13 | x |
@@ -440,9 +441,10 @@ variableReadAccess
| main.rs:533:6:533:9 | self | main.rs:532:15:532:18 | self |
| main.rs:539:3:539:3 | a | main.rs:538:11:538:11 | a |
| main.rs:541:13:541:13 | a | main.rs:538:11:538:11 | a |
| main.rs:564:9:564:25 | var_in_macro | main.rs:564:9:564:25 | var_in_macro |
| main.rs:565:15:565:28 | var_from_macro | main.rs:563:9:563:22 | var_from_macro |
| main.rs:567:30:567:41 | var_in_macro | main.rs:566:9:566:20 | var_in_macro |
| main.rs:568:15:568:26 | var_in_macro | main.rs:566:9:566:20 | var_in_macro |
| main.rs:570:30:570:41 | var_in_macro | main.rs:570:15:570:42 | var_in_macro |
| main.rs:571:15:571:26 | var_in_macro | main.rs:566:9:566:20 | var_in_macro |
variableInitializer
| main.rs:16:9:16:10 | x1 | main.rs:16:14:16:16 | "a" |
| main.rs:21:13:21:14 | x2 | main.rs:21:18:21:18 | 4 |
@@ -499,7 +501,7 @@ variableInitializer
| main.rs:563:9:563:22 | var_from_macro | main.rs:564:9:564:25 | MacroExpr |
| main.rs:564:9:564:25 | var_in_macro | main.rs:564:23:564:24 | 37 |
| main.rs:566:9:566:20 | var_in_macro | main.rs:566:24:566:25 | 33 |
| main.rs:567:15:567:42 | var_in_macro | main.rs:567:15:567:42 | 0 |
| main.rs:570:15:570:42 | var_in_macro | main.rs:570:15:570:42 | 0 |
capturedVariable
| main.rs:400:9:400:9 | x |
| main.rs:410:13:410:13 | x |

View File

@@ -18,8 +18,9 @@ query predicate capturedAccess(VariableAccess va) { va.isCapture() }
module VariableAccessTest implements TestSig {
string getARelevantTag() { result = ["", "write_", "read_"] + "access" }
private predicate declAt(Variable v, string filepath, int line) {
v.getLocation().hasLocationInfo(filepath, _, _, line, _)
private predicate declAt(Variable v, string filepath, int line, boolean inMacro) {
v.getLocation().hasLocationInfo(filepath, _, _, line, _) and
if v.getPat().isInMacroExpansion() then inMacro = true else inMacro = false
}
private predicate commmentAt(string text, string filepath, int line) {
@@ -30,10 +31,15 @@ module VariableAccessTest implements TestSig {
}
private predicate decl(Variable v, string value) {
exists(string filepath, int line | declAt(v, filepath, line) |
commmentAt(value, filepath, line)
exists(string filepath, int line, boolean inMacro | declAt(v, filepath, line, inMacro) |
commmentAt(value, filepath, line) and
inMacro = false
or
not commmentAt(_, filepath, line) and
(
not commmentAt(_, filepath, line)
or
inMacro = true
) and
value = v.getName()
)
}

View File

@@ -15,6 +15,7 @@
| main.rs:377:9:377:9 | x | Variable $@ is assigned a value that is never used. | main.rs:377:9:377:9 | x | x |
| main.rs:385:17:385:17 | x | Variable $@ is assigned a value that is never used. | main.rs:385:17:385:17 | x | x |
| main.rs:486:9:486:9 | c | Variable $@ is assigned a value that is never used. | main.rs:486:9:486:9 | c | c |
| main.rs:519:9:519:20 | var_in_macro | Variable $@ is assigned a value that is never used. | main.rs:519:9:519:20 | var_in_macro | var_in_macro |
| more.rs:44:9:44:14 | a_ptr4 | Variable $@ is assigned a value that is never used. | more.rs:44:9:44:14 | a_ptr4 | a_ptr4 |
| more.rs:59:9:59:13 | d_ptr | Variable $@ is assigned a value that is never used. | more.rs:59:9:59:13 | d_ptr | d_ptr |
| more.rs:65:9:65:17 | f_ptr | Variable $@ is assigned a value that is never used. | more.rs:65:13:65:17 | f_ptr | f_ptr |

View File

@@ -496,8 +496,7 @@ fn references() {
pub struct my_declaration {
field1: fn(i32) -> i32,
field2: fn(x: i32) -> i32,
field3: fn(y:
fn(z: i32) -> i32) -> i32,
field3: fn(y: fn(z: i32) -> i32) -> i32,
}
type MyType = fn(x: i32) -> i32;
@@ -506,6 +505,21 @@ trait MyTrait {
fn my_func2(&self, x: i32) -> i32;
}
macro_rules! let_in_macro {
($e:expr) => {{
let var_in_macro = 0;
$e
}};
}
// Our analysis does not currently respect the hygiene rules of Rust macros
// (https://veykril.github.io/tlborm/decl-macros/minutiae/hygiene.html), because
// all we have access to is the expanded AST
fn hygiene_mismatch() {
let var_in_macro = 0; // $ SPURIOUS: Alert[rust/unused-value]
let_in_macro!(var_in_macro);
}
// --- main ---
fn main() {