From 7b60d315c4808b3a3e4db20ccb00ae73b0eadd47 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 9 Oct 2024 15:17:58 +0200 Subject: [PATCH] wip --- .../codeql/rust/dataflow/internal/SsaImpl.qll | 62 +++-- .../rust/elements/internal/VariableImpl.qll | 118 ++++++---- .../src/queries/unusedentities/UnusedValue.ql | 15 +- .../queries/unusedentities/UnusedVariable.ql | 7 +- .../queries/unusedentities/UnusedVariable.qll | 9 + .../test/library-tests/variables/Cfg.expected | 220 ++++++++++-------- .../test/library-tests/variables/Ssa.expected | 5 + .../variables/variables.expected | 15 +- .../test/library-tests/variables/variables.rs | 27 ++- .../unusedentities/UnusedValue.expected | 32 +++ .../test/query-tests/unusedentities/main.rs | 40 ++-- 11 files changed, 361 insertions(+), 189 deletions(-) create mode 100644 rust/ql/src/queries/unusedentities/UnusedVariable.qll diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll index 42573f09f28ff..6ea8a3dea2b29 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll @@ -6,13 +6,41 @@ private import Cfg private import codeql.rust.controlflow.internal.ControlFlowGraphImpl as ControlFlowGraphImpl private import codeql.ssa.Ssa as SsaImplCommon +/** Holds if `v` is introduced like `let v : i64;`. */ +private predicate isUnitializedLet(IdentPat pat, Variable v) { + pat = v.getPat() and + exists(LetStmt let | + let = v.getLetStmt() and + not let.hasInitializer() + ) +} + +/** Holds if `write` writes to variable `v`. */ +predicate variableWrite(AstNode write, Variable v) { + exists(IdentPat pat | + pat = write and + pat = v.getPat() and + not isUnitializedLet(pat, v) + ) + or + exists(VariableAccess access | + access = write and + access.getVariable() = v + | + access instanceof VariableWriteAccess + or + access = any(CompoundAssignmentExpr cae).getLhs() + ) +} + private Expr withParens(Expr e) { result = e or result.(ParenExpr).getExpr() = withParens(e) } -private predicate isUncertainWrite(VariableAccess va) { +private predicate isRefTarget(VariableAccess va, Variable v) { + va = v.getAnAccess() and exists(RefExpr re, Expr arg | va = re.getExpr() and // todo: restrict to `mut` arg = withParens(re) @@ -24,8 +52,6 @@ private predicate isUncertainWrite(VariableAccess va) { arg = mce.getReceiver() ) ) - or - va = any(CompoundAssignmentExpr cae).getLhs() } module SsaInput implements SsaImplCommon::InputSig { @@ -45,9 +71,9 @@ module SsaInput implements SsaImplCommon::InputSig { forall(VariableAccess va | va = this.getAnAccess() | va instanceof VariableReadAccess or - va instanceof VariableWriteAccess + variableWrite(va, this) or - isUncertainWrite(va) + isRefTarget(va, this) ) } } @@ -61,16 +87,30 @@ module SsaInput implements SsaImplCommon::InputSig { certain = true or exists(VariableAccess va | - isUncertainWrite(va) and + isRefTarget(va, v) and va = bb.getNode(i).getAstNode() and - v = va.getVariable() and certain = false ) } predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) { - bb.getNode(i).getAstNode() = v.getAnAccess().(VariableReadAccess) and + exists(VariableAccess va | + bb.getNode(i).getAstNode() = va and + va = v.getAnAccess() + | + va instanceof VariableReadAccess + or + // although compound assignments, like `x += y`, may in fact not update `x`, + // it makes sense to treat them as such + va = any(CompoundAssignmentExpr cae).getLhs() + ) and certain = true + or + exists(VariableAccess va | + isRefTarget(va, v) and + va = bb.getNode(i).getAstNode() and + certain = false + ) } } @@ -185,11 +225,7 @@ private module Cached { cached predicate variableWriteActual(BasicBlock bb, int i, Variable v, CfgNode write) { bb.getNode(i) = write and - ( - write.getAstNode() = v.getPat() - or - write.getAstNode().(VariableWriteAccess).getVariable() = v - ) + variableWrite(write.getAstNode(), v) } cached diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index 99cdeba4e1b26..90d5439e99aad 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -113,16 +113,17 @@ module Impl { */ IdentPat getPat() { variableDecl(definingNode, result, name) } + /** Gets the `let` statement that introduces this variable, if any. */ + LetStmt getLetStmt() { this.getPat() = result.getPat() } + /** Gets the initial value of this variable, if any. */ - Expr getInitializer() { - exists(LetStmt let | - this.getPat() = let.getPat() and - result = let.getInitializer() - ) - } + Expr getInitializer() { result = this.getLetStmt().getInitializer() } /** Holds if this variable is captured. */ predicate isCaptured() { this.getAnAccess().isCapture() } + + /** Gets the parameter that introduces this variable, if any. */ + Param getParameter() { parameterDeclInScope(result, this, _) } } /** A path expression that may access a local variable. */ @@ -175,6 +176,27 @@ module Impl { ) } + /** + * Holds if parameter `p` introduces the variable `v` inside variable scope + * `scope`. + */ + private predicate parameterDeclInScope(Param p, Variable v, VariableScope scope) { + exists(Pat pat | + pat = getAVariablePatAncestor(v) and + p.getPat() = pat + | + exists(Function f | + f.getParamList().getAParam() = p and + scope = f.getBody() + ) + or + exists(ClosureExpr ce | + ce.getParamList().getAParam() = p and + scope = ce.getBody() + ) + ) + } + /** * Holds if `v` is named `name` and is declared inside variable scope * `scope`, and `v` is bound starting from `(line, column)`. @@ -183,51 +205,44 @@ module Impl { 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, _, _) - ) + ( + parameterDeclInScope(_, v, scope) 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, _, _) + exists(Pat pat | pat = getAVariablePatAncestor(v) | + scope = + any(MatchArmScope arm | + arm.getPat() = pat and + arm.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(WhileExpr we, LetExpr let | + let.getPat() = pat and + we.getCondition() = let and + scope = we.getLoopBody() and + scope.getLocation().hasLocationInfo(_, line, column, _, _) + ) ) ) } @@ -422,7 +437,8 @@ module Impl { exists(Expr mid | assignmentExprDescendant(mid) and getImmediateParent(e) = mid and - not mid.(PrefixExpr).getOperatorName() = "*" + not mid.(PrefixExpr).getOperatorName() = "*" and + not mid instanceof FieldExpr ) } diff --git a/rust/ql/src/queries/unusedentities/UnusedValue.ql b/rust/ql/src/queries/unusedentities/UnusedValue.ql index a224136968223..4b514c338bd11 100644 --- a/rust/ql/src/queries/unusedentities/UnusedValue.ql +++ b/rust/ql/src/queries/unusedentities/UnusedValue.ql @@ -9,7 +9,16 @@ */ import rust +import codeql.rust.controlflow.ControlFlowGraph +import codeql.rust.dataflow.Ssa +import codeql.rust.dataflow.internal.SsaImpl +import UnusedVariable -from Locatable e -where none() // TODO: implement query -select e, "Variable is assigned a value that is never used." +from AstNode write, Ssa::Variable v +where + variableWrite(write, v) and + // SSA definitions are only created for live writes + not write = any(Ssa::WriteDefinition def).getWriteAccess().getAstNode() and + // avoid overlap with the unused variable query + not isUnused(v) +select write, "Variable is assigned a value that is never used." diff --git a/rust/ql/src/queries/unusedentities/UnusedVariable.ql b/rust/ql/src/queries/unusedentities/UnusedVariable.ql index f6be18b76e15b..0162d32ff8a3a 100644 --- a/rust/ql/src/queries/unusedentities/UnusedVariable.ql +++ b/rust/ql/src/queries/unusedentities/UnusedVariable.ql @@ -9,11 +9,8 @@ */ import rust +import UnusedVariable from Variable v -where - not exists(v.getAnAccess()) and - not exists(v.getInitializer()) and - not v.getName().charAt(0) = "_" and - exists(File f | f.getBaseName() = "main.rs" | v.getLocation().getFile() = f) // temporarily severely limit results +where isUnused(v) select v, "Variable is not used." diff --git a/rust/ql/src/queries/unusedentities/UnusedVariable.qll b/rust/ql/src/queries/unusedentities/UnusedVariable.qll new file mode 100644 index 0000000000000..9bfc07b06b1d0 --- /dev/null +++ b/rust/ql/src/queries/unusedentities/UnusedVariable.qll @@ -0,0 +1,9 @@ +import rust + +/** Holds if variable `v` is unused. */ +predicate isUnused(Variable v) { + not exists(v.getAnAccess()) and + not exists(v.getInitializer()) and + not v.getName().charAt(0) = "_" and + exists(File f | f.getBaseName() = "main.rs" | v.getLocation().getFile() = f) // temporarily severely limit results +} diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected index 7202b4bc43453..eb74550cfb3b6 100644 --- a/rust/ql/test/library-tests/variables/Cfg.expected +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -836,96 +836,134 @@ edges | variables.rs:396:9:396:20 | CallExpr | variables.rs:395:12:397:5 | BlockExpr | | | variables.rs:396:9:396:21 | ExprStmt | variables.rs:396:9:396:17 | PathExpr | | | variables.rs:396:19:396:19 | x | variables.rs:396:9:396:20 | CallExpr | | -| variables.rs:400:1:428:1 | enter main | variables.rs:401:5:401:25 | ExprStmt | | -| variables.rs:400:1:428:1 | exit main (normal) | variables.rs:400:1:428:1 | exit main | | -| variables.rs:400:11:428:1 | BlockExpr | variables.rs:400:1:428:1 | exit main (normal) | | -| variables.rs:401:5:401:22 | PathExpr | variables.rs:401:5:401:24 | CallExpr | | -| variables.rs:401:5:401:24 | CallExpr | variables.rs:402:5:402:23 | ExprStmt | | -| variables.rs:401:5:401:25 | ExprStmt | variables.rs:401:5:401:22 | PathExpr | | -| variables.rs:402:5:402:20 | PathExpr | variables.rs:402:5:402:22 | CallExpr | | -| variables.rs:402:5:402:22 | CallExpr | variables.rs:403:5:403:23 | ExprStmt | | -| variables.rs:402:5:402:23 | ExprStmt | variables.rs:402:5:402:20 | PathExpr | | -| variables.rs:403:5:403:20 | PathExpr | variables.rs:403:5:403:22 | CallExpr | | -| variables.rs:403:5:403:22 | CallExpr | variables.rs:404:5:404:23 | ExprStmt | | -| variables.rs:403:5:403:23 | ExprStmt | variables.rs:403:5:403:20 | PathExpr | | -| variables.rs:404:5:404:20 | PathExpr | variables.rs:404:5:404:22 | CallExpr | | -| variables.rs:404:5:404:22 | CallExpr | variables.rs:405:5:405:19 | ExprStmt | | -| variables.rs:404:5:404:23 | ExprStmt | variables.rs:404:5:404:20 | PathExpr | | -| variables.rs:405:5:405:16 | PathExpr | variables.rs:405:5:405:18 | CallExpr | | -| variables.rs:405:5:405:18 | CallExpr | variables.rs:406:5:406:19 | ExprStmt | | -| variables.rs:405:5:405:19 | ExprStmt | variables.rs:405:5:405:16 | PathExpr | | -| variables.rs:406:5:406:16 | PathExpr | variables.rs:406:5:406:18 | CallExpr | | -| variables.rs:406:5:406:18 | CallExpr | variables.rs:407:5:407:19 | ExprStmt | | -| variables.rs:406:5:406:19 | ExprStmt | variables.rs:406:5:406:16 | PathExpr | | -| variables.rs:407:5:407:16 | PathExpr | variables.rs:407:5:407:18 | CallExpr | | -| variables.rs:407:5:407:18 | CallExpr | variables.rs:408:5:408:19 | ExprStmt | | -| variables.rs:407:5:407:19 | ExprStmt | variables.rs:407:5:407:16 | PathExpr | | -| variables.rs:408:5:408:16 | PathExpr | variables.rs:408:5:408:18 | CallExpr | | -| variables.rs:408:5:408:18 | CallExpr | variables.rs:409:5:409:21 | ExprStmt | | -| variables.rs:408:5:408:19 | ExprStmt | variables.rs:408:5:408:16 | PathExpr | | -| variables.rs:409:5:409:18 | PathExpr | variables.rs:409:5:409:20 | CallExpr | | -| variables.rs:409:5:409:20 | CallExpr | variables.rs:410:5:410:21 | ExprStmt | | -| variables.rs:409:5:409:21 | ExprStmt | variables.rs:409:5:409:18 | PathExpr | | -| variables.rs:410:5:410:18 | PathExpr | variables.rs:410:5:410:20 | CallExpr | | -| variables.rs:410:5:410:20 | CallExpr | variables.rs:411:5:411:21 | ExprStmt | | -| variables.rs:410:5:410:21 | ExprStmt | variables.rs:410:5:410:18 | PathExpr | | -| variables.rs:411:5:411:18 | PathExpr | variables.rs:411:5:411:20 | CallExpr | | -| variables.rs:411:5:411:20 | CallExpr | variables.rs:412:5:412:21 | ExprStmt | | -| variables.rs:411:5:411:21 | ExprStmt | variables.rs:411:5:411:18 | PathExpr | | -| variables.rs:412:5:412:18 | PathExpr | variables.rs:412:5:412:20 | CallExpr | | -| variables.rs:412:5:412:20 | CallExpr | variables.rs:413:5:413:21 | ExprStmt | | -| variables.rs:412:5:412:21 | ExprStmt | variables.rs:412:5:412:18 | PathExpr | | -| variables.rs:413:5:413:18 | PathExpr | variables.rs:413:5:413:20 | CallExpr | | -| variables.rs:413:5:413:20 | CallExpr | variables.rs:414:5:414:21 | ExprStmt | | -| variables.rs:413:5:413:21 | ExprStmt | variables.rs:413:5:413:18 | PathExpr | | -| variables.rs:414:5:414:18 | PathExpr | variables.rs:414:5:414:20 | CallExpr | | -| variables.rs:414:5:414:20 | CallExpr | variables.rs:415:5:415:21 | ExprStmt | | -| variables.rs:414:5:414:21 | ExprStmt | variables.rs:414:5:414:18 | PathExpr | | -| variables.rs:415:5:415:18 | PathExpr | variables.rs:415:5:415:20 | CallExpr | | -| variables.rs:415:5:415:20 | CallExpr | variables.rs:416:5:416:21 | ExprStmt | | -| variables.rs:415:5:415:21 | ExprStmt | variables.rs:415:5:415:18 | PathExpr | | -| variables.rs:416:5:416:18 | PathExpr | variables.rs:416:5:416:20 | CallExpr | | -| variables.rs:416:5:416:20 | CallExpr | variables.rs:417:5:417:21 | ExprStmt | | -| variables.rs:416:5:416:21 | ExprStmt | variables.rs:416:5:416:18 | PathExpr | | -| variables.rs:417:5:417:18 | PathExpr | variables.rs:417:5:417:20 | CallExpr | | -| variables.rs:417:5:417:20 | CallExpr | variables.rs:418:5:418:36 | ExprStmt | | -| variables.rs:417:5:417:21 | ExprStmt | variables.rs:417:5:417:18 | PathExpr | | -| variables.rs:418:5:418:18 | PathExpr | variables.rs:418:20:418:22 | "a" | | -| variables.rs:418:5:418:35 | CallExpr | variables.rs:419:5:419:37 | ExprStmt | | -| variables.rs:418:5:418:36 | ExprStmt | variables.rs:418:5:418:18 | PathExpr | | -| variables.rs:418:20:418:22 | "a" | variables.rs:418:26:418:28 | "b" | | -| variables.rs:418:25:418:34 | TupleExpr | variables.rs:418:5:418:35 | CallExpr | | -| variables.rs:418:26:418:28 | "b" | variables.rs:418:31:418:33 | "c" | | -| variables.rs:418:31:418:33 | "c" | variables.rs:418:25:418:34 | TupleExpr | | -| variables.rs:419:5:419:18 | PathExpr | variables.rs:419:20:419:31 | PathExpr | | -| variables.rs:419:5:419:36 | CallExpr | variables.rs:420:5:420:26 | ExprStmt | | -| variables.rs:419:5:419:37 | ExprStmt | variables.rs:419:5:419:18 | PathExpr | | -| variables.rs:419:20:419:31 | PathExpr | variables.rs:419:33:419:34 | 45 | | -| variables.rs:419:20:419:35 | CallExpr | variables.rs:419:5:419:36 | CallExpr | | -| variables.rs:419:33:419:34 | 45 | variables.rs:419:20:419:35 | CallExpr | | -| variables.rs:420:5:420:23 | PathExpr | variables.rs:420:5:420:25 | CallExpr | | -| variables.rs:420:5:420:25 | CallExpr | variables.rs:421:5:421:23 | ExprStmt | | -| variables.rs:420:5:420:26 | ExprStmt | variables.rs:420:5:420:23 | PathExpr | | -| variables.rs:421:5:421:20 | PathExpr | variables.rs:421:5:421:22 | CallExpr | | -| variables.rs:421:5:421:22 | CallExpr | variables.rs:422:5:422:19 | ExprStmt | | -| variables.rs:421:5:421:23 | ExprStmt | variables.rs:421:5:421:20 | PathExpr | | -| variables.rs:422:5:422:16 | PathExpr | variables.rs:422:5:422:18 | CallExpr | | -| variables.rs:422:5:422:18 | CallExpr | variables.rs:423:5:423:17 | ExprStmt | | -| variables.rs:422:5:422:19 | ExprStmt | variables.rs:422:5:422:16 | PathExpr | | -| variables.rs:423:5:423:14 | PathExpr | variables.rs:423:5:423:16 | CallExpr | | -| variables.rs:423:5:423:16 | CallExpr | variables.rs:424:5:424:13 | ExprStmt | | -| variables.rs:423:5:423:17 | ExprStmt | variables.rs:423:5:423:14 | PathExpr | | -| variables.rs:424:5:424:10 | PathExpr | variables.rs:424:5:424:12 | CallExpr | | -| variables.rs:424:5:424:12 | CallExpr | variables.rs:425:5:425:17 | ExprStmt | | -| variables.rs:424:5:424:13 | ExprStmt | variables.rs:424:5:424:10 | PathExpr | | -| variables.rs:425:5:425:14 | PathExpr | variables.rs:425:5:425:16 | CallExpr | | -| variables.rs:425:5:425:16 | CallExpr | variables.rs:426:5:426:12 | ExprStmt | | -| variables.rs:425:5:425:17 | ExprStmt | variables.rs:425:5:425:14 | PathExpr | | -| variables.rs:426:5:426:9 | PathExpr | variables.rs:426:5:426:11 | CallExpr | | -| variables.rs:426:5:426:11 | CallExpr | variables.rs:427:5:427:14 | ExprStmt | | -| variables.rs:426:5:426:12 | ExprStmt | variables.rs:426:5:426:9 | PathExpr | | -| variables.rs:427:5:427:11 | PathExpr | variables.rs:427:5:427:13 | CallExpr | | -| variables.rs:427:5:427:13 | CallExpr | variables.rs:400:11:428:1 | BlockExpr | | -| variables.rs:427:5:427:14 | ExprStmt | variables.rs:427:5:427:11 | PathExpr | | +| variables.rs:406:5:408:5 | enter my_get | variables.rs:407:9:407:24 | ExprStmt | | +| variables.rs:406:5:408:5 | exit my_get (normal) | variables.rs:406:5:408:5 | exit my_get | | +| variables.rs:407:9:407:23 | ReturnExpr | variables.rs:406:5:408:5 | exit my_get (normal) | return | +| variables.rs:407:9:407:24 | ExprStmt | variables.rs:407:16:407:19 | PathExpr | | +| variables.rs:407:16:407:19 | PathExpr | variables.rs:407:16:407:23 | FieldExpr | | +| variables.rs:407:16:407:23 | FieldExpr | variables.rs:407:9:407:23 | ReturnExpr | | +| variables.rs:411:1:418:1 | enter structs | variables.rs:412:5:412:36 | LetStmt | | +| variables.rs:411:1:418:1 | exit structs (normal) | variables.rs:411:1:418:1 | exit structs | | +| variables.rs:411:14:418:1 | BlockExpr | variables.rs:411:1:418:1 | exit structs (normal) | | +| variables.rs:412:5:412:36 | LetStmt | variables.rs:412:33:412:33 | 1 | | +| variables.rs:412:9:412:13 | a | variables.rs:413:5:413:26 | ExprStmt | match | +| variables.rs:412:17:412:35 | RecordExpr | variables.rs:412:9:412:13 | a | | +| variables.rs:412:33:412:33 | 1 | variables.rs:412:17:412:35 | RecordExpr | | +| variables.rs:413:5:413:13 | PathExpr | variables.rs:413:15:413:24 | MethodCallExpr | | +| variables.rs:413:5:413:25 | CallExpr | variables.rs:414:5:414:14 | ExprStmt | | +| variables.rs:413:5:413:26 | ExprStmt | variables.rs:413:5:413:13 | PathExpr | | +| variables.rs:413:15:413:24 | MethodCallExpr | variables.rs:413:5:413:25 | CallExpr | | +| variables.rs:414:5:414:5 | a | variables.rs:414:5:414:9 | FieldExpr | | +| variables.rs:414:5:414:9 | FieldExpr | variables.rs:414:13:414:13 | 5 | | +| variables.rs:414:5:414:13 | ... = ... | variables.rs:415:5:415:26 | ExprStmt | | +| variables.rs:414:5:414:14 | ExprStmt | variables.rs:414:5:414:5 | a | | +| variables.rs:414:13:414:13 | 5 | variables.rs:414:5:414:13 | ... = ... | | +| variables.rs:415:5:415:13 | PathExpr | variables.rs:415:15:415:24 | MethodCallExpr | | +| variables.rs:415:5:415:25 | CallExpr | variables.rs:416:5:416:28 | ExprStmt | | +| variables.rs:415:5:415:26 | ExprStmt | variables.rs:415:5:415:13 | PathExpr | | +| variables.rs:415:15:415:24 | MethodCallExpr | variables.rs:415:5:415:25 | CallExpr | | +| variables.rs:416:5:416:5 | a | variables.rs:416:25:416:25 | 2 | | +| variables.rs:416:5:416:27 | ... = ... | variables.rs:417:5:417:26 | ExprStmt | | +| variables.rs:416:5:416:28 | ExprStmt | variables.rs:416:5:416:5 | a | | +| variables.rs:416:9:416:27 | RecordExpr | variables.rs:416:5:416:27 | ... = ... | | +| variables.rs:416:25:416:25 | 2 | variables.rs:416:9:416:27 | RecordExpr | | +| variables.rs:417:5:417:13 | PathExpr | variables.rs:417:15:417:24 | MethodCallExpr | | +| variables.rs:417:5:417:25 | CallExpr | variables.rs:411:14:418:1 | BlockExpr | | +| variables.rs:417:5:417:26 | ExprStmt | variables.rs:417:5:417:13 | PathExpr | | +| variables.rs:417:15:417:24 | MethodCallExpr | variables.rs:417:5:417:25 | CallExpr | | +| variables.rs:420:1:449:1 | enter main | variables.rs:421:5:421:25 | ExprStmt | | +| variables.rs:420:1:449:1 | exit main (normal) | variables.rs:420:1:449:1 | exit main | | +| variables.rs:420:11:449:1 | BlockExpr | variables.rs:420:1:449:1 | exit main (normal) | | +| variables.rs:421:5:421:22 | PathExpr | variables.rs:421:5:421:24 | CallExpr | | +| variables.rs:421:5:421:24 | CallExpr | variables.rs:422:5:422:23 | ExprStmt | | +| variables.rs:421:5:421:25 | ExprStmt | variables.rs:421:5:421:22 | PathExpr | | +| variables.rs:422:5:422:20 | PathExpr | variables.rs:422:5:422:22 | CallExpr | | +| variables.rs:422:5:422:22 | CallExpr | variables.rs:423:5:423:23 | ExprStmt | | +| variables.rs:422:5:422:23 | ExprStmt | variables.rs:422:5:422:20 | PathExpr | | +| variables.rs:423:5:423:20 | PathExpr | variables.rs:423:5:423:22 | CallExpr | | +| variables.rs:423:5:423:22 | CallExpr | variables.rs:424:5:424:23 | ExprStmt | | +| variables.rs:423:5:423:23 | ExprStmt | variables.rs:423:5:423:20 | PathExpr | | +| variables.rs:424:5:424:20 | PathExpr | variables.rs:424:5:424:22 | CallExpr | | +| variables.rs:424:5:424:22 | CallExpr | variables.rs:425:5:425:19 | ExprStmt | | +| variables.rs:424:5:424:23 | ExprStmt | variables.rs:424:5:424:20 | PathExpr | | +| variables.rs:425:5:425:16 | PathExpr | variables.rs:425:5:425:18 | CallExpr | | +| variables.rs:425:5:425:18 | CallExpr | variables.rs:426:5:426:19 | ExprStmt | | +| variables.rs:425:5:425:19 | ExprStmt | variables.rs:425:5:425:16 | PathExpr | | +| variables.rs:426:5:426:16 | PathExpr | variables.rs:426:5:426:18 | CallExpr | | +| variables.rs:426:5:426:18 | CallExpr | variables.rs:427:5:427:19 | ExprStmt | | +| variables.rs:426:5:426:19 | ExprStmt | variables.rs:426:5:426:16 | PathExpr | | +| variables.rs:427:5:427:16 | PathExpr | variables.rs:427:5:427:18 | CallExpr | | +| variables.rs:427:5:427:18 | CallExpr | variables.rs:428:5:428:19 | ExprStmt | | +| variables.rs:427:5:427:19 | ExprStmt | variables.rs:427:5:427:16 | PathExpr | | +| variables.rs:428:5:428:16 | PathExpr | variables.rs:428:5:428:18 | CallExpr | | +| variables.rs:428:5:428:18 | CallExpr | variables.rs:429:5:429:21 | ExprStmt | | +| variables.rs:428:5:428:19 | ExprStmt | variables.rs:428:5:428:16 | PathExpr | | +| variables.rs:429:5:429:18 | PathExpr | variables.rs:429:5:429:20 | CallExpr | | +| variables.rs:429:5:429:20 | CallExpr | variables.rs:430:5:430:21 | ExprStmt | | +| variables.rs:429:5:429:21 | ExprStmt | variables.rs:429:5:429:18 | PathExpr | | +| variables.rs:430:5:430:18 | PathExpr | variables.rs:430:5:430:20 | CallExpr | | +| variables.rs:430:5:430:20 | CallExpr | variables.rs:431:5:431:21 | ExprStmt | | +| variables.rs:430:5:430:21 | ExprStmt | variables.rs:430:5:430:18 | PathExpr | | +| variables.rs:431:5:431:18 | PathExpr | variables.rs:431:5:431:20 | CallExpr | | +| variables.rs:431:5:431:20 | CallExpr | variables.rs:432:5:432:21 | ExprStmt | | +| variables.rs:431:5:431:21 | ExprStmt | variables.rs:431:5:431:18 | PathExpr | | +| variables.rs:432:5:432:18 | PathExpr | variables.rs:432:5:432:20 | CallExpr | | +| variables.rs:432:5:432:20 | CallExpr | variables.rs:433:5:433:21 | ExprStmt | | +| variables.rs:432:5:432:21 | ExprStmt | variables.rs:432:5:432:18 | PathExpr | | +| variables.rs:433:5:433:18 | PathExpr | variables.rs:433:5:433:20 | CallExpr | | +| variables.rs:433:5:433:20 | CallExpr | variables.rs:434:5:434:21 | ExprStmt | | +| variables.rs:433:5:433:21 | ExprStmt | variables.rs:433:5:433:18 | PathExpr | | +| variables.rs:434:5:434:18 | PathExpr | variables.rs:434:5:434:20 | CallExpr | | +| variables.rs:434:5:434:20 | CallExpr | variables.rs:435:5:435:21 | ExprStmt | | +| variables.rs:434:5:434:21 | ExprStmt | variables.rs:434:5:434:18 | PathExpr | | +| variables.rs:435:5:435:18 | PathExpr | variables.rs:435:5:435:20 | CallExpr | | +| variables.rs:435:5:435:20 | CallExpr | variables.rs:436:5:436:21 | ExprStmt | | +| variables.rs:435:5:435:21 | ExprStmt | variables.rs:435:5:435:18 | PathExpr | | +| variables.rs:436:5:436:18 | PathExpr | variables.rs:436:5:436:20 | CallExpr | | +| variables.rs:436:5:436:20 | CallExpr | variables.rs:437:5:437:21 | ExprStmt | | +| variables.rs:436:5:436:21 | ExprStmt | variables.rs:436:5:436:18 | PathExpr | | +| variables.rs:437:5:437:18 | PathExpr | variables.rs:437:5:437:20 | CallExpr | | +| variables.rs:437:5:437:20 | CallExpr | variables.rs:438:5:438:36 | ExprStmt | | +| variables.rs:437:5:437:21 | ExprStmt | variables.rs:437:5:437:18 | PathExpr | | +| variables.rs:438:5:438:18 | PathExpr | variables.rs:438:20:438:22 | "a" | | +| variables.rs:438:5:438:35 | CallExpr | variables.rs:439:5:439:37 | ExprStmt | | +| variables.rs:438:5:438:36 | ExprStmt | variables.rs:438:5:438:18 | PathExpr | | +| variables.rs:438:20:438:22 | "a" | variables.rs:438:26:438:28 | "b" | | +| variables.rs:438:25:438:34 | TupleExpr | variables.rs:438:5:438:35 | CallExpr | | +| variables.rs:438:26:438:28 | "b" | variables.rs:438:31:438:33 | "c" | | +| variables.rs:438:31:438:33 | "c" | variables.rs:438:25:438:34 | TupleExpr | | +| variables.rs:439:5:439:18 | PathExpr | variables.rs:439:20:439:31 | PathExpr | | +| variables.rs:439:5:439:36 | CallExpr | variables.rs:440:5:440:26 | ExprStmt | | +| variables.rs:439:5:439:37 | ExprStmt | variables.rs:439:5:439:18 | PathExpr | | +| variables.rs:439:20:439:31 | PathExpr | variables.rs:439:33:439:34 | 45 | | +| variables.rs:439:20:439:35 | CallExpr | variables.rs:439:5:439:36 | CallExpr | | +| variables.rs:439:33:439:34 | 45 | variables.rs:439:20:439:35 | CallExpr | | +| variables.rs:440:5:440:23 | PathExpr | variables.rs:440:5:440:25 | CallExpr | | +| variables.rs:440:5:440:25 | CallExpr | variables.rs:441:5:441:23 | ExprStmt | | +| variables.rs:440:5:440:26 | ExprStmt | variables.rs:440:5:440:23 | PathExpr | | +| variables.rs:441:5:441:20 | PathExpr | variables.rs:441:5:441:22 | CallExpr | | +| variables.rs:441:5:441:22 | CallExpr | variables.rs:442:5:442:19 | ExprStmt | | +| variables.rs:441:5:441:23 | ExprStmt | variables.rs:441:5:441:20 | PathExpr | | +| variables.rs:442:5:442:16 | PathExpr | variables.rs:442:5:442:18 | CallExpr | | +| variables.rs:442:5:442:18 | CallExpr | variables.rs:443:5:443:17 | ExprStmt | | +| variables.rs:442:5:442:19 | ExprStmt | variables.rs:442:5:442:16 | PathExpr | | +| variables.rs:443:5:443:14 | PathExpr | variables.rs:443:5:443:16 | CallExpr | | +| variables.rs:443:5:443:16 | CallExpr | variables.rs:444:5:444:13 | ExprStmt | | +| variables.rs:443:5:443:17 | ExprStmt | variables.rs:443:5:443:14 | PathExpr | | +| variables.rs:444:5:444:10 | PathExpr | variables.rs:444:5:444:12 | CallExpr | | +| variables.rs:444:5:444:12 | CallExpr | variables.rs:445:5:445:17 | ExprStmt | | +| variables.rs:444:5:444:13 | ExprStmt | variables.rs:444:5:444:10 | PathExpr | | +| variables.rs:445:5:445:14 | PathExpr | variables.rs:445:5:445:16 | CallExpr | | +| variables.rs:445:5:445:16 | CallExpr | variables.rs:446:5:446:12 | ExprStmt | | +| variables.rs:445:5:445:17 | ExprStmt | variables.rs:445:5:445:14 | PathExpr | | +| variables.rs:446:5:446:9 | PathExpr | variables.rs:446:5:446:11 | CallExpr | | +| variables.rs:446:5:446:11 | CallExpr | variables.rs:447:5:447:14 | ExprStmt | | +| variables.rs:446:5:446:12 | ExprStmt | variables.rs:446:5:446:9 | PathExpr | | +| variables.rs:447:5:447:11 | PathExpr | variables.rs:447:5:447:13 | CallExpr | | +| variables.rs:447:5:447:13 | CallExpr | variables.rs:448:5:448:14 | ExprStmt | | +| variables.rs:447:5:447:14 | ExprStmt | variables.rs:447:5:447:11 | PathExpr | | +| variables.rs:448:5:448:11 | PathExpr | variables.rs:448:5:448:13 | CallExpr | | +| variables.rs:448:5:448:13 | CallExpr | variables.rs:420:11:449:1 | BlockExpr | | +| variables.rs:448:5:448:14 | ExprStmt | variables.rs:448:5:448:11 | PathExpr | | breakTarget continueTarget diff --git a/rust/ql/test/library-tests/variables/Ssa.expected b/rust/ql/test/library-tests/variables/Ssa.expected index 2457bb634f4e3..b5cd58a2b566c 100644 --- a/rust/ql/test/library-tests/variables/Ssa.expected +++ b/rust/ql/test/library-tests/variables/Ssa.expected @@ -106,6 +106,7 @@ definition | variables.rs:385:13:385:14 | b1 | variables.rs:385:13:385:14 | b1 | | variables.rs:385:24:385:25 | b2 | variables.rs:385:24:385:25 | b2 | | variables.rs:386:9:386:9 | x | variables.rs:386:9:386:9 | x | +| variables.rs:412:9:412:13 | a | variables.rs:412:13:412:13 | a | read | variables.rs:12:9:12:10 | x1 | variables.rs:12:9:12:10 | x1 | variables.rs:13:15:13:16 | x1 | | variables.rs:17:9:17:14 | x2 | variables.rs:17:13:17:14 | x2 | variables.rs:18:15:18:16 | x2 | @@ -199,6 +200,7 @@ read | variables.rs:386:9:386:9 | x | variables.rs:386:9:386:9 | x | variables.rs:390:19:390:19 | x | | variables.rs:386:9:386:9 | x | variables.rs:386:9:386:9 | x | variables.rs:394:19:394:19 | x | | variables.rs:386:9:386:9 | x | variables.rs:386:9:386:9 | x | variables.rs:396:19:396:19 | x | +| variables.rs:412:9:412:13 | a | variables.rs:412:13:412:13 | a | variables.rs:414:5:414:5 | a | firstRead | variables.rs:12:9:12:10 | x1 | variables.rs:12:9:12:10 | x1 | variables.rs:13:15:13:16 | x1 | | variables.rs:17:9:17:14 | x2 | variables.rs:17:13:17:14 | x2 | variables.rs:18:15:18:16 | x2 | @@ -264,6 +266,7 @@ firstRead | variables.rs:315:9:315:10 | n2 | variables.rs:315:9:315:10 | n2 | variables.rs:317:15:317:16 | n2 | | variables.rs:321:9:321:9 | v | variables.rs:321:9:321:9 | v | variables.rs:324:12:324:12 | v | | variables.rs:323:9:323:12 | text | variables.rs:323:9:323:12 | text | variables.rs:325:19:325:22 | text | +| variables.rs:330:9:330:13 | a | variables.rs:330:13:330:13 | a | variables.rs:331:5:331:5 | a | | variables.rs:331:5:331:5 | a | variables.rs:330:13:330:13 | a | variables.rs:332:15:332:15 | a | | variables.rs:339:9:339:13 | ref_i | variables.rs:339:9:339:13 | ref_i | variables.rs:341:6:341:10 | ref_i | | variables.rs:345:17:345:17 | x | variables.rs:345:17:345:17 | x | variables.rs:346:6:346:6 | x | @@ -276,6 +279,7 @@ firstRead | variables.rs:385:24:385:25 | b2 | variables.rs:385:24:385:25 | b2 | variables.rs:393:8:393:9 | b2 | | variables.rs:386:9:386:9 | x | variables.rs:386:9:386:9 | x | variables.rs:388:19:388:19 | x | | variables.rs:386:9:386:9 | x | variables.rs:386:9:386:9 | x | variables.rs:390:19:390:19 | x | +| variables.rs:412:9:412:13 | a | variables.rs:412:13:412:13 | a | variables.rs:414:5:414:5 | a | lastRead | variables.rs:12:9:12:10 | x1 | variables.rs:12:9:12:10 | x1 | variables.rs:13:15:13:16 | x1 | | variables.rs:17:9:17:14 | x2 | variables.rs:17:13:17:14 | x2 | variables.rs:18:15:18:16 | x2 | @@ -354,6 +358,7 @@ lastRead | variables.rs:385:24:385:25 | b2 | variables.rs:385:24:385:25 | b2 | variables.rs:393:8:393:9 | b2 | | variables.rs:386:9:386:9 | x | variables.rs:386:9:386:9 | x | variables.rs:394:19:394:19 | x | | variables.rs:386:9:386:9 | x | variables.rs:386:9:386:9 | x | variables.rs:396:19:396:19 | x | +| variables.rs:412:9:412:13 | a | variables.rs:412:13:412:13 | a | variables.rs:414:5:414:5 | a | adjacentReads | variables.rs:24:9:24:10 | x3 | variables.rs:24:9:24:10 | x3 | variables.rs:25:15:25:16 | x3 | variables.rs:27:9:27:10 | x3 | | variables.rs:32:9:32:10 | x4 | variables.rs:32:9:32:10 | x4 | variables.rs:33:15:33:16 | x4 | variables.rs:38:15:38:16 | x4 | diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index e96957a62e3f8..fb840452f9c5c 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -1,7 +1,4 @@ testFailures -| variables.rs:377:8:377:8 | b | Unexpected result: read_access=b | -| variables.rs:387:8:387:9 | b1 | Unexpected result: read_access=b1 | -| variables.rs:393:8:393:9 | b2 | Unexpected result: read_access=b2 | failures variable | variables.rs:3:14:3:14 | s | @@ -84,6 +81,7 @@ variable | variables.rs:385:13:385:14 | b1 | | variables.rs:385:24:385:25 | b2 | | variables.rs:386:9:386:9 | x | +| variables.rs:412:13:412:13 | a | variableAccess | 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 | @@ -196,6 +194,11 @@ variableAccess | variables.rs:393:8:393:9 | b2 | variables.rs:385:24:385:25 | b2 | | variables.rs:394:19:394:19 | x | variables.rs:386:9:386:9 | x | | variables.rs:396:19:396:19 | x | variables.rs:386:9:386:9 | x | +| variables.rs:413:15:413:15 | a | variables.rs:412:13:412:13 | a | +| variables.rs:414:5:414:5 | a | variables.rs:412:13:412:13 | a | +| variables.rs:415:15:415:15 | a | variables.rs:412:13:412:13 | a | +| variables.rs:416:5:416:5 | a | variables.rs:412:13:412:13 | a | +| variables.rs:417:15:417:15 | a | variables.rs:412:13:412:13 | a | variableWriteAccess | 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 | @@ -203,6 +206,7 @@ variableWriteAccess | variables.rs:279:9:279:11 | a10 | variables.rs:268:13:268:15 | a10 | | variables.rs:378:9:378:9 | x | variables.rs:376:13:376:13 | x | | variables.rs:380:9:380:9 | x | variables.rs:376:13:376:13 | x | +| variables.rs:416:5:416:5 | a | variables.rs:412:13:412:13 | a | 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 | @@ -303,6 +307,10 @@ variableReadAccess | variables.rs:393:8:393:9 | b2 | variables.rs:385:24:385:25 | b2 | | variables.rs:394:19:394:19 | x | variables.rs:386:9:386:9 | x | | variables.rs:396:19:396:19 | x | variables.rs:386:9:386:9 | x | +| variables.rs:413:15:413:15 | a | variables.rs:412:13:412:13 | a | +| variables.rs:414:5:414:5 | a | variables.rs:412:13:412:13 | a | +| variables.rs:415:15:415:15 | a | variables.rs:412:13:412:13 | a | +| variables.rs:417:15:417:15 | a | variables.rs:412:13:412:13 | a | variableInitializer | 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 | @@ -338,6 +346,7 @@ variableInitializer | variables.rs:367:13:367:15 | cap | variables.rs:367:19:370:5 | ClosureExpr | | variables.rs:376:13:376:13 | x | variables.rs:376:17:376:17 | 1 | | variables.rs:386:9:386:9 | x | variables.rs:386:13:386:13 | 1 | +| variables.rs:412:13:412:13 | a | variables.rs:412:17:412:35 | RecordExpr | capturedVariable | variables.rs:366:13:366:13 | x | capturedAccess diff --git a/rust/ql/test/library-tests/variables/variables.rs b/rust/ql/test/library-tests/variables/variables.rs index c36a30a2d0bc6..28376a3d19601 100644 --- a/rust/ql/test/library-tests/variables/variables.rs +++ b/rust/ql/test/library-tests/variables/variables.rs @@ -374,7 +374,7 @@ fn capture() { fn phi(b : bool) { let mut x = 1; // x - if b { + if b { // $ read_access=b x = 2; // $ write_access=x } else { x = 3; // $ write_access=x @@ -384,19 +384,39 @@ fn phi(b : bool) { fn phi_read(b1 : bool, b2 : bool) { let x = 1; // x - if b1 { + if b1 { // $ read_access=b1 print_i64(x); // $ read_access=x } else { print_i64(x); // $ read_access=x } - if b2 { + if b2 { // $ read_access=b2 print_i64(x); // $ read_access=x } else { print_i64(x); // $ read_access=x } } +#[derive(Debug)] +struct MyStruct { + val: i64, +} + +impl MyStruct { + fn my_get(&mut self) -> i64 { + return self.val; + } +} + +fn structs() { + let mut a = MyStruct { val: 1 }; // a + print_i64(a.my_get()); // $ read_access=a + a.val = 5; // $ read_access=a + print_i64(a.my_get()); // $ read_access=a + a = MyStruct { val: 2 }; // $ write_access=a + print_i64(a.my_get()); // $ read_access=a +} + fn main() { immutable_variable(); mutable_variable(); @@ -425,4 +445,5 @@ fn main() { mutate_arg(); alias(); capture(); + structs(); } diff --git a/rust/ql/test/query-tests/unusedentities/UnusedValue.expected b/rust/ql/test/query-tests/unusedentities/UnusedValue.expected index e69de29bb2d1d..0f552c27ee37a 100644 --- a/rust/ql/test/query-tests/unusedentities/UnusedValue.expected +++ b/rust/ql/test/query-tests/unusedentities/UnusedValue.expected @@ -0,0 +1,32 @@ +| main.rs:6:9:6:9 | a | Variable is assigned a value that is never used. | +| main.rs:7:9:7:9 | b | Variable is assigned a value that is never used. | +| main.rs:8:9:8:9 | c | Variable is assigned a value that is never used. | +| main.rs:9:9:9:9 | d | Variable is assigned a value that is never used. | +| main.rs:10:9:10:9 | e | Variable is assigned a value that is never used. | +| main.rs:11:9:11:9 | f | Variable is assigned a value that is never used. | +| main.rs:35:5:35:5 | b | Variable is assigned a value that is never used. | +| main.rs:37:5:37:5 | c | Variable is assigned a value that is never used. | +| main.rs:38:5:38:5 | c | Variable is assigned a value that is never used. | +| main.rs:40:5:40:5 | c | Variable is assigned a value that is never used. | +| main.rs:42:5:42:5 | d | Variable is assigned a value that is never used. | +| main.rs:44:9:44:9 | d | Variable is assigned a value that is never used. | +| main.rs:45:9:45:9 | d | Variable is assigned a value that is never used. | +| main.rs:50:5:50:5 | e | Variable is assigned a value that is never used. | +| main.rs:52:9:52:9 | e | Variable is assigned a value that is never used. | +| main.rs:54:9:54:9 | e | Variable is assigned a value that is never used. | +| main.rs:61:5:61:5 | f | Variable is assigned a value that is never used. | +| main.rs:63:5:63:5 | f | Variable is assigned a value that is never used. | +| main.rs:65:5:65:5 | g | Variable is assigned a value that is never used. | +| main.rs:67:5:67:5 | i | Variable is assigned a value that is never used. | +| main.rs:87:9:87:9 | a | Variable is assigned a value that is never used. | +| main.rs:88:9:88:9 | b | Variable is assigned a value that is never used. | +| main.rs:89:9:89:9 | c | Variable is assigned a value that is never used. | +| main.rs:108:9:108:10 | is | Variable is assigned a value that is never used. | +| main.rs:109:9:109:10 | js | Variable is assigned a value that is never used. | +| main.rs:133:13:133:17 | total | Variable is assigned a value that is never used. | +| main.rs:142:5:142:6 | _z | Variable is assigned a value that is never used. | +| main.rs:202:9:202:16 | next | Variable is assigned a value that is never used. | +| main.rs:205:9:205:12 | next | Variable is assigned a value that is never used. | +| main.rs:208:9:208:17 | next2 | Variable is assigned a value that is never used. | +| main.rs:211:9:211:13 | next2 | Variable is assigned a value that is never used. | +| main.rs:225:13:225:17 | total | Variable is assigned a value that is never used. | diff --git a/rust/ql/test/query-tests/unusedentities/main.rs b/rust/ql/test/query-tests/unusedentities/main.rs index a34219f8a7ab9..e94f8087028c9 100644 --- a/rust/ql/test/query-tests/unusedentities/main.rs +++ b/rust/ql/test/query-tests/unusedentities/main.rs @@ -3,12 +3,12 @@ // --- 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 f = 1; + let a = 1; // BAD: unused value + let b = 1; // SPURIOUS: unused value [macros not yet supported] + let c = 1; // SPURIOUS: unused value [macros not yet supported] + let d = String::from("a"); // BAD: unused value + let e = String::from("b"); // SPURIOUS: unused value [macros not yet supported] + let f = 1; // SPURIOUS: unused value [macros not yet supported] let _ = 1; // (deliberately unused) println!("use {}", b); @@ -32,39 +32,39 @@ fn locals_2() { let h: i32; let i: i32; - b = 1; // BAD: unused value [NOT DETECTED] + b = 1; // BAD: unused value - c = 1; // BAD: unused value [NOT DETECTED] - c = 2; + c = 1; // BAD: unused value + c = 2; // SPURIOUS: unused value [macros not yet supported] println!("use {}", c); - c = 3; // BAD: unused value [NOT DETECTED] + c = 3; // BAD: unused value - d = 1; + d = 1; // SPURIOUS: unused value [macros not yet supported] if cond() { - d = 2; // BAD: unused value [NOT DETECTED] - d = 3; + d = 2; // BAD: unused value + d = 3; // SPURIOUS: unused value [macros not yet supported] } else { } println!("use {}", d); - e = 1; // BAD: unused value [NOT DETECTED] + e = 1; // BAD: unused value if cond() { - e = 2; + e = 2; // SPURIOUS: unused value [macros not yet supported] } else { - e = 3; + e = 3; // SPURIOUS: unused value [macros not yet supported] } println!("use {}", e); f = 1; f += 1; println!("use {}", f); - f += 1; // BAD: unused value [NOT DETECTED] + f += 1; // BAD: unused value f = 1; - f += 1; // BAD: unused value [NOT DETECTED] + f += 1; // BAD: unused value - g = if cond() { 1 } else { 2 }; // BAD: unused value (x2) [NOT DETECTED] + g = if cond() { 1 } else { 2 }; // BAD: unused value h = if cond() { 3 } else { 4 }; - i = if cond() { h } else { 5 }; + i = if cond() { h } else { 5 }; // SPURIOUS: unused value [macros not yet supported] println!("use {}", i); _ = 1; // (deliberately unused) [NOT DETECTED]