diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index 2895a33d94bd4..8796e55a125fd 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -1,6 +1,6 @@ private import rust private import codeql.rust.elements.internal.generated.ParentChild -private import codeql.rust.elements.internal.PathExprImpl::Impl as PathExprImpl +private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl private import codeql.util.DenseRank module Impl { @@ -138,12 +138,12 @@ module Impl { } /** A path expression that may access a local variable. */ - private class VariableAccessCand extends PathExpr { + private class VariableAccessCand extends TVariableAccess { string name_; VariableAccessCand() { exists(Path p, PathSegment ps | - p = this.getPath() and + p = this.(PathExpr).getPath() and not p.hasQualifier() and ps = p.getPart() and not ps.hasGenericArgList() and @@ -152,9 +152,23 @@ module Impl { not ps.hasReturnTypeSyntax() and name_ = ps.getNameRef().getText() ) + or + this.(ImplicitVariableAccess).getName() = name_ } + string toString() { result = name_ } + string getName() { result = name_ } + + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + this.(PathExpr) + .getLocation() + .hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) or + this.(ImplicitVariableAccess) + .hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } } private AstNode getAnAncestorInVariableScope(AstNode n) { @@ -164,7 +178,10 @@ module Impl { n instanceof LetStmt or n instanceof VariableScope ) and - exists(AstNode n0 | result = getImmediateParent(n0) | + exists(AstNode n0 | + result = getImmediateParent(n0) or + result = n0.(ImplicitVariableAccess).getArgument().getParent().getParent() + | n0 = n or n0 = getAnAncestorInVariableScope(n) and @@ -272,7 +289,7 @@ module Impl { ) { name = cand.getName() and scope = [cand.(VariableScope), getEnclosingScope(cand)] and - cand.getLocation().hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and + cand.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and nestLevel = 0 or exists(VariableScope inner | @@ -347,8 +364,14 @@ module Impl { result = this.asVariable().toString() or result = this.asVariableAccessCand().toString() } - Location getLocation() { - result = this.asVariable().getLocation() or result = this.asVariableAccessCand().getLocation() + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + this.asVariable() + .getLocation() + .hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) or + this.asVariableAccessCand() + .hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) } pragma[nomagic] @@ -422,9 +445,12 @@ module Impl { } private import codeql.rust.controlflow.internal.Scope + private import codeql.rust.elements.internal.generated.Synth + + private class TVariableAccess = Synth::TPathExpr or Synth::TImplicitVariableAccess; /** A variable access. */ - class VariableAccess extends PathExprImpl::PathExpr instanceof VariableAccessCand { + class VariableAccess extends ExprImpl::Expr, TVariableAccess instanceof VariableAccessCand { private string name; private Variable v;